#!/usr/bin/env node /** * @zod-to-form/cli — Build-time CLI for generating React form components from Zod v4 schemas. * * Drives the full code generation pipeline: loads a schema file, walks the Zod internal * type tree via `@zod-to-form/core`, applies per-field overrides from `z2f.config.ts`, * and emits static `.tsx` form components — optionally alongside a Next.js server action * and a schema-lite file for optimized client-side validation. * * @remarks * Before using the CLI, decide: are you scripting (use `runGenerate`) or interacting * (use `npx zod-to-form`)? For config authoring, always use `defineConfig` for type inference. * * @useWhen * - You want a one-shot CLI command to generate a typed React form from a Zod schema — no runtime overhead, static output * - You need watch-mode codegen that regenerates on schema file changes — `--watch` keeps the output in sync automatically * - You want programmatic codegen from a Node.js script without spawning a child process — import `runGenerate` directly instead of using the CLI binary * * @avoidWhen * - Runtime form rendering — use `@zod-to-form/react`; the CLI only emits static `.tsx` files, it does not render at runtime * - Browser environments — this package uses Node.js `fs` and `path` APIs not available in browsers * - Vite-based projects that want HMR — use `@zod-to-form/vite` instead; the Vite plugin has per-import invalidation that the CLI watcher lacks * * @never * - NEVER rely on generated file content without checking `wroteFile` — when `overwrite` * is false and the output file already exists, `runGenerate` returns `wroteFile: false` * and leaves the existing file unchanged without throwing; FIX: check `result.wroteFile` * before treating `result.code` as fresh output * - NEVER mix CLI-generated components with components managed by the Vite plugin * in the same module — the import paths and registry expectations differ; FIX: choose * one code-generation strategy per module boundary * * @packageDocumentation */ import { Command } from 'commander'; import { defineConfig, validateConfig, type ComponentOverride, type FieldConfig, type ZodFormsConfig } from '@zod-to-form/core'; export { defineConfig, validateConfig }; export type { ComponentOverride, FieldConfig, ZodFormsConfig }; type GenerateOptions = { config: string; schema: string; export?: string; mode?: 'submit' | 'auto-save'; out?: string; name?: string; ui?: 'shadcn' | 'html'; dryRun?: boolean; serverAction?: boolean; watch?: boolean; /** Pre-loaded config to avoid redundant file loads */ _loadedConfig?: ZodFormsConfig>; }; /** * Executes the code generation pipeline for a single Zod schema export. * * Loads the config and schema, resolves field overrides, walks the Zod type * tree to produce an intermediate `FormField[]` representation, and writes a * React form component (plus optional server action and schema-lite files) to * disk. When `options.dryRun` is true the generated code is printed to stdout * instead of being written. * * @param options - Generation options including paths for config, schema, and output. * @returns Resolved output paths and the generated code string. * * @useWhen * - You need programmatic codegen from a Node.js script or build tool (not just the CLI) * - You are writing tests for the code generation pipeline end-to-end * - You need `dryRun` output for preview/diffing without touching the filesystem * * @avoidWhen * - Interactive use — run `npx zod-to-form generate` (via `createProgram()`) instead * - Browser environments — this function uses Node.js `fs` and `path` APIs * * @never * - NEVER treat `result.code` as the on-disk file content when `overwrite` is false — if * the output file already exists, `runGenerate` returns `wroteFile: false` and the * existing file is unchanged without throwing; FIX: check `result.wroteFile` before * assuming the file was updated, or set `defaults.overwrite: true` explicitly * - NEVER use `--watch` mode on schemas that re-export types from other modules — the * watcher tracks only the top-level file, so a change in an imported schema file * does not trigger regeneration; FIX: run `runGenerate` manually from a parent file * watcher (e.g. chokidar) that covers the full import tree * * @throws When the schema file cannot be loaded, the export is missing, or the export is not a Zod schema. * @throws When the output file exists and cannot be read (permissions or unexpected I/O error). * * @example * ```ts * const result = await runGenerate({ * config: './z2f.config.ts', * schema: './src/schemas/user.ts', * export: 'UserSchema', * out: './src/forms', * }); * if (result.wroteFile) { * console.log('Generated:', result.outputPath); * } * ``` * * @category CLI */ export declare function runGenerate(options: GenerateOptions): Promise<{ outputPath: string; code: string; wroteFile: boolean; actionPath?: string; actionCode?: string; }>; /** * Creates the Commander.js CLI program for `zod-to-form`. * * Registers the `generate` and `init` sub-commands with all their options and * action handlers. Consumers can pass the returned `Command` to `.parseAsync()` * to run the CLI, or use it for testing without spawning a child process. * * @returns A fully configured `Command` instance ready to be parsed. * * @useWhen * - Testing CLI commands programmatically without spawning a child process * - Extending the CLI with custom sub-commands in a wrapper tool * * @avoidWhen * - You just want to generate a form from a script — use `runGenerate()` directly * - End-user invocation — use `npx zod-to-form` (the binary entry point) instead * * @never * - NEVER call `program.parse()` (synchronous) in ESM environments — Commander's * synchronous parse returns before async action handlers complete in ESM because * it cannot await top-level async actions; FIX: always use `.parseAsync(process.argv)` * * @example * ```ts * const program = createProgram(); * await program.parseAsync(['node', 'z2f', 'generate', * '--config', 'z2f.config.ts', * '--schema', 'src/schemas/user.ts', * '--export', 'UserSchema', * ]); * ``` * * @category CLI */ export declare function createProgram(): Command; //# sourceMappingURL=index.d.ts.map