# `options.ts` — Zod schema for `EventBusPluginOptions` ## Purpose Boundary Zod schema validated by `createEventBusPlugin(options)` at the factory entry point. Invalid input produces an `EventBusError(EVENT_BUS.INVALID_INPUT)` carrying the underlying `ZodError` as `cause` — callers always see a typed failure, never an `unknown` parse error from upstream code paths. Schema is `.strict()` so unknown keys fail loudly (typos in option names surface immediately rather than producing silent no-ops). ## Features - Single schema (`EventBusPluginOptionsSchema`) covering the full option surface with sane defaults applied. - Sub-schemas exported for downstream reuse: `BackpressureOptionsSchema`, `IdempotencyOptionsSchema`. - Schema produces a fully-resolved `EventBusPluginOptionsResolved` type (defaults applied) suitable for passing as `PluginDescriptor.defaults`. - Strict mode prevents typo classes like `applySchema: true` (the wrong package's option) from silently being ignored. ## Usage: Basic ```ts import { EventBusPluginOptionsSchema } from "@suaveplan/api-plugin-event-bus/schemas/options"; const resolved = EventBusPluginOptionsSchema.parse({}); console.log(resolved.routePrefix); // "/event-bus" console.log(resolved.backpressure.policy); // "drop-oldest" ``` ## Usage: Advanced ```ts import { EventBusPluginOptionsSchema, type EventBusPluginOptionsInput, } from "@suaveplan/api-plugin-event-bus/schemas/options"; const input: EventBusPluginOptionsInput = { backpressure: { capacity: 32, policy: "throw" }, idempotency: { enabled: true, cacheCapacity: 8192 }, routePrefix: "/bus", mountRoutes: false, requireAuthForRoutes: false, tenantIsolation: false, interceptors: [ async (env, next) => { console.log("emit", env.type); return next(); }, ], }; const resolved = EventBusPluginOptionsSchema.parse(input); ``` ## API Reference ### `EventBusPluginOptionsSchema` Strict object schema producing `EventBusPluginOptionsResolved`. Fields: - `interceptors: Interceptor[]` (default `[]`). - `backpressure: { capacity: number; policy: QueuePolicy }`. - `idempotency: { enabled: boolean; cacheCapacity: number }`. - `routePrefix: string` (default `"/event-bus"`). - `mountRoutes: boolean` (default `true`). - `requireAuthForRoutes: boolean` (default `true`). - `tenantIsolation: boolean` (default `true`). - `maxTopicLength: number` (default `256`). - `logger?: LoggerLike` (optional override). ### `BackpressureOptionsSchema` Stand-alone sub-schema. Exported so consumers building custom plugin factories can reuse the same shape. ### `IdempotencyOptionsSchema` Stand-alone sub-schema. ### `type EventBusPluginOptionsInput` `z.input` of the top-level schema — what callers pass in. ### `type EventBusPluginOptionsResolved` `z.output` of the top-level schema — what the descriptor stores as `defaults` after parsing. ## Implementation Notes - The `interceptors` array uses `z.custom` (`typeof val === "function"`) rather than `z.function(...)` because Zod 4's `z.function` is builder-style and does not return a `ZodType` directly compatible with `z.array`. - The `routePrefix` regex matches `/auth`'s rule verbatim — start with `/`, no trailing `/` (the literal root `/` is allowed). Sharing the rule across the plugin family means routes mount predictably. - The schema is `.strict()` because the cost of catching typos at the factory boundary far outweighs the convenience of forward-compatible passthrough.