# templates.schemas _(no submodules)_ ## Purpose Provides Zod schemas for runtime validation of `TemplateEngine` and `parse` configuration objects. Rather than relying on TypeScript types alone — which provide no runtime guarantees — these schemas let consumer code validate user-supplied configuration at the boundary before constructing an engine or calling parse. The schemas also serve as the single source of truth for what constitutes a valid options object, making it easier to write property-based tests against the validated surface. ## Features - `PluginPrioritySchema` — validates a plugin priority as an integer in the range 0–100. - `TemplateEngineOptionsSchema` — validates the full set of constructor options for `TemplateEngine`. - `ParseOptionsSchema` — validates per-call options passed to `parse()` or `parseAsync()`. - Inferred TypeScript types (`TemplateEngineOptionsInput`, `ParseOptionsInput`) derived from the schemas for use in typed consumer code. - All schemas carry `.describe()` annotations for documentation generation. ## Usage: Basic Example ```ts import { TemplateEngineOptionsSchema, ParseOptionsSchema, PluginPrioritySchema, } from "@suaveplan/templates"; // Validate engine options at a configuration boundary const opts = TemplateEngineOptionsSchema.parse({ maxDepth: 5, throwOnError: true, enableCache: false, }); // opts is typed as { maxDepth?: number; throwOnError?: boolean; enableCache?: boolean; onError?: Function } // Validate an individual priority value PluginPrioritySchema.parse(80); // ok PluginPrioritySchema.parse(101); // throws ZodError (> 100) PluginPrioritySchema.parse(1.5); // throws ZodError (not integer) ``` ## Usage: Advanced Example ```ts import { TemplateEngineOptionsSchema, ParseOptionsSchema, } from "@suaveplan/templates"; import type { TemplateEngineOptionsInput, ParseOptionsInput, } from "@suaveplan/templates"; function buildEngine(rawOpts: unknown): TemplateEngine { // Throws ZodError on invalid input — fail fast at the boundary const opts: TemplateEngineOptionsInput = TemplateEngineOptionsSchema.parse(rawOpts); return new TemplateEngine(opts); } // ParseOptionsSchema for per-call validation function safeParse(engine: TemplateEngine, template: string, ctx: unknown, rawOpts: unknown) { const opts: ParseOptionsInput = ParseOptionsSchema.parse(rawOpts); return engine.parse(template, ctx as Record, opts); } ``` ## API Reference ### `PluginPrioritySchema` `z.number().int().min(0).max(100)` — Accepts any integer from 0 to 100 inclusive. ### `TemplateEngineOptionsSchema` `z.object({ ... })` with the following fields (all optional): | Field | Schema | Description | |-------|--------|-------------| | `maxDepth` | `z.number().int().positive()` | Maximum render recursion depth | | `throwOnError` | `z.boolean()` | Re-throw errors instead of swallowing | | `enableCache` | `z.boolean()` | Enable template parse-result caching | | `onError` | `z.function()` | Error callback invoked on plugin failure | ### `ParseOptionsSchema` `z.object({ ... })` with the following fields (all optional): | Field | Schema | Description | |-------|--------|-------------| | `maxDepth` | `z.number().int().positive()` | Per-call depth override | | `async` | `z.boolean()` | Force async rendering path | ### `TemplateEngineOptionsInput` `z.input` — TypeScript input type inferred from the schema. ### `ParseOptionsInput` `z.input` — TypeScript input type inferred from the schema. ## Implementation Notes - Using `z.input<>` rather than `z.infer<>` preserves optionality for fields that have defaults — the input type reflects what the caller provides, while the output type would reflect what Zod outputs after applying defaults. Since no `.default()` calls are present here, `z.input` and `z.infer` are equivalent, but the `Input` suffix signals intent. - The `onError` field uses `z.function()` without argument/return schemas to avoid coupling the Zod schema to the internal `PluginError` type. Callers are responsible for typing their own callback correctly via TypeScript generics on `TemplateEngine`. - `PluginPrioritySchema` uses `.int()` before `.min()/.max()` because Zod's number refinements are applied left to right; placing `.int()` first makes the integer check run before the range check, producing a clearer error message for fractional inputs.