Files
skills/docs/communication/messaging/imessage-adapter/src/schemas/schemas.md
2026-05-29 08:20:56 +01:00

2.6 KiB

Config schemas

(no submodules)

Purpose

Provides Zod boundary schemas for IMessageWatcherConfig and IMessageAdapterConfig, plus the parseWatcherConfig / parseAdapterConfig helpers that callers use to validate untrusted input before constructing a watcher or adapter. Both schemas are strict — extra keys are rejected — so consumers cannot silently smuggle additional fields past the boundary.

Features

  • Strict object validation (.strict()) — unknown properties are rejected at the boundary, preventing prototype-pollution-style smuggling.
  • pollIntervalMs constrained to positive integers; sinceDate required to be a Date instance (no millisecond-since-epoch numbers); chatFilter constrained to string arrays.
  • Custom SqliteReaderSchema confirms the optional injected sqliteReader exposes a callable open() member.
  • Failures throw IMessageInvalidConfigError (IMESSAGE.INVALID_CONFIG) carrying a serialisable issues array in context so problem+json responders can surface the Zod path + reason without re-running the schema.

Usage: Basic

import { parseWatcherConfig } from "@suaveplan/imessage-adapter/schemas";

const config = parseWatcherConfig({ pollIntervalMs: 5000 });

Usage: Advanced

import {
    parseWatcherConfig,
    IMessageInvalidConfigError,
} from "@suaveplan/imessage-adapter";

try {
    parseWatcherConfig({ pollIntervalMs: -1, oops: true });
} catch (err) {
    if (err instanceof IMessageInvalidConfigError) {
        return Response.json(
            { issues: err.context["issues"] },
            { status: 400 },
        );
    }
    throw err;
}

API Reference

  • IMessageWatcherConfigSchema: z.ZodObject — validates watcher config.
  • IMessageAdapterConfigSchema — alias for the watcher schema.
  • SqliteReaderSchema: z.ZodType<unknown> — structural check for SqliteReader.
  • parseWatcherConfig(input: unknown): IMessageWatcherConfig — throws IMessageInvalidConfigError on failure.
  • parseAdapterConfig(input: unknown): IMessageAdapterConfig — throws IMessageInvalidConfigError on failure.

Implementation Notes

The schemas use z.custom for the SqliteReader slot because the reader is a structural type — there is no Zod-expressible shape that captures every legal implementation. The check confirms the presence of a function-typed open member, which is enough to surface mistakes (passing a stray object or null) without inspecting the reader's behaviour. Issue arrays are projected through toIssues which strips Zod's internal symbols so the resulting record is safe to JSON-serialise.