@zod-to-form/vite 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -0
  3. package/dist/cache.d.ts +39 -0
  4. package/dist/cache.d.ts.map +1 -0
  5. package/dist/cache.js +56 -0
  6. package/dist/cache.js.map +1 -0
  7. package/dist/config/load.d.ts +59 -0
  8. package/dist/config/load.d.ts.map +1 -0
  9. package/dist/config/load.js +117 -0
  10. package/dist/config/load.js.map +1 -0
  11. package/dist/errors.d.ts +50 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +62 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/generate-mode/babel-traverse.d.ts +5 -0
  16. package/dist/generate-mode/babel-traverse.d.ts.map +1 -0
  17. package/dist/generate-mode/babel-traverse.js +16 -0
  18. package/dist/generate-mode/babel-traverse.js.map +1 -0
  19. package/dist/generate-mode/generate-source.d.ts +51 -0
  20. package/dist/generate-mode/generate-source.d.ts.map +1 -0
  21. package/dist/generate-mode/generate-source.js +187 -0
  22. package/dist/generate-mode/generate-source.js.map +1 -0
  23. package/dist/generate-mode/resolve-schema.d.ts +43 -0
  24. package/dist/generate-mode/resolve-schema.d.ts.map +1 -0
  25. package/dist/generate-mode/resolve-schema.js +182 -0
  26. package/dist/generate-mode/resolve-schema.js.map +1 -0
  27. package/dist/generate-mode/scan-jsx.d.ts +86 -0
  28. package/dist/generate-mode/scan-jsx.d.ts.map +1 -0
  29. package/dist/generate-mode/scan-jsx.js +161 -0
  30. package/dist/generate-mode/scan-jsx.js.map +1 -0
  31. package/dist/hmr.d.ts +44 -0
  32. package/dist/hmr.d.ts.map +1 -0
  33. package/dist/hmr.js +28 -0
  34. package/dist/hmr.js.map +1 -0
  35. package/dist/index.d.ts +61 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +59 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/logger.d.ts +27 -0
  40. package/dist/logger.d.ts.map +1 -0
  41. package/dist/logger.js +46 -0
  42. package/dist/logger.js.map +1 -0
  43. package/dist/plugin.d.ts +61 -0
  44. package/dist/plugin.d.ts.map +1 -0
  45. package/dist/plugin.js +650 -0
  46. package/dist/plugin.js.map +1 -0
  47. package/dist/query-mode/parse-specifier.d.ts +23 -0
  48. package/dist/query-mode/parse-specifier.d.ts.map +1 -0
  49. package/dist/query-mode/parse-specifier.js +83 -0
  50. package/dist/query-mode/parse-specifier.js.map +1 -0
  51. package/dist/query-mode/resolve-id.d.ts +12 -0
  52. package/dist/query-mode/resolve-id.d.ts.map +1 -0
  53. package/dist/query-mode/resolve-id.js +61 -0
  54. package/dist/query-mode/resolve-id.js.map +1 -0
  55. package/dist/query-mode/transform.d.ts +33 -0
  56. package/dist/query-mode/transform.d.ts.map +1 -0
  57. package/dist/query-mode/transform.js +90 -0
  58. package/dist/query-mode/transform.js.map +1 -0
  59. package/dist/resolver-strip.d.ts +58 -0
  60. package/dist/resolver-strip.d.ts.map +1 -0
  61. package/dist/resolver-strip.js +141 -0
  62. package/dist/resolver-strip.js.map +1 -0
  63. package/dist/tsconfig.tsbuildinfo +1 -0
  64. package/dist/types.d.ts +242 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +2 -0
  67. package/dist/types.js.map +1 -0
  68. package/dist/write-guard.d.ts +26 -0
  69. package/dist/write-guard.d.ts.map +1 -0
  70. package/dist/write-guard.js +32 -0
  71. package/dist/write-guard.js.map +1 -0
  72. package/package.json +69 -0
@@ -0,0 +1,161 @@
1
+ /**
2
+ * scanJsx — find candidate `<ZodForm schema={X}>` JSX elements in a source
3
+ * file. Pure: no I/O, no plugin context. Reports both candidate sites and
4
+ * skip diagnostics so the caller can buffer them through the logger.
5
+ *
6
+ * The substring fast-path is critical: most files in a typical project
7
+ * don't contain `'ZodForm'` anywhere, so a single `indexOf` check keeps
8
+ * generate-mode's per-file cost at zero for the common case (research R3).
9
+ *
10
+ * The Babel visitor only fires on `JSXElement` nodes. The traversal still
11
+ * walks the full AST — that's how `@babel/traverse` works — but the per-
12
+ * node cost outside the visitor is just a type check, so even a 5000-line
13
+ * file with one `<ZodForm>` call site stays cheap to scan in practice.
14
+ */
15
+ import { parse } from '@babel/parser';
16
+ import { traverse } from './babel-traverse.js';
17
+ /**
18
+ * Scan a source string for `<ZodForm>` JSX elements. Returns candidates
19
+ * for further validation by `resolveSchema` plus an array of sites that
20
+ * structurally don't qualify (and thus need a DEBUG diagnostic).
21
+ *
22
+ * Returns `null` (a discriminator distinct from "scanned and found
23
+ * nothing") when the substring fast-path filtered the file out — the
24
+ * caller can short-circuit before allocating anything else.
25
+ *
26
+ * On a Babel parse failure, returns a `ScanResult` with zero candidates
27
+ * and a single skip diagnostic naming the parser error so it surfaces
28
+ * in the buildEnd summary. We deliberately don't propagate the parse
29
+ * error — Vite's main pipeline will report the user's syntax problem
30
+ * elsewhere with better context.
31
+ */
32
+ export function scanJsx(source) {
33
+ // Substring fast-path. Most files won't contain ZodForm at all.
34
+ if (source.indexOf('ZodForm') === -1)
35
+ return null;
36
+ let ast;
37
+ try {
38
+ ast = parse(source, {
39
+ sourceType: 'module',
40
+ plugins: ['jsx', 'typescript'],
41
+ errorRecovery: false
42
+ });
43
+ }
44
+ catch (err) {
45
+ // Surface the parse failure as a buffered skip so the user sees one
46
+ // line in the buildEnd generate-mode summary instead of silently
47
+ // missing the transform. The parse error itself still propagates
48
+ // through Vite's normal pipeline and the user fixes it there.
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ return {
51
+ candidates: [],
52
+ skipped: [{ loc: { line: 0, column: 0 }, reason: `babel parse failed: ${message}` }]
53
+ };
54
+ }
55
+ const candidates = [];
56
+ const skipped = [];
57
+ traverse(ast, {
58
+ JSXElement(path) {
59
+ const opening = path.node.openingElement;
60
+ const nameNode = opening.name;
61
+ // Element name MUST be a bare `JSXIdentifier`, not `JSXMemberExpression`
62
+ // or `JSXNamespacedName`. `<x.ZodForm>` and `<x:ZodForm>` are skipped.
63
+ if (nameNode.type !== 'JSXIdentifier') {
64
+ // Only flag this as a skip if the rendered text actually contains
65
+ // `ZodForm` — otherwise we'd noise up the log with every member-
66
+ // expression element in the file.
67
+ if (containsZodForm(nameNode)) {
68
+ skipped.push({
69
+ loc: locOf(path.node),
70
+ reason: 'JSX element uses member-expression name (e.g. <ns.ZodForm/>); only bare <ZodForm> is matched'
71
+ });
72
+ }
73
+ return;
74
+ }
75
+ if (nameNode.name !== 'ZodForm')
76
+ return;
77
+ const loc = locOf(path.node);
78
+ // Find the schema attribute and collect all the others.
79
+ const attributes = [];
80
+ let schemaAttr = null;
81
+ for (const attr of opening.attributes) {
82
+ const range = rangeOf(attr);
83
+ const slice = source.slice(range.start, range.end);
84
+ if (attr.type === 'JSXSpreadAttribute') {
85
+ attributes.push({ kind: 'spread', range, source: slice });
86
+ continue;
87
+ }
88
+ const jsxAttr = attr;
89
+ const attrName = jsxAttr.name.type === 'JSXIdentifier' ? jsxAttr.name.name : null;
90
+ if (attrName !== null) {
91
+ attributes.push({ kind: 'named', name: attrName, range, source: slice });
92
+ if (attrName === 'schema')
93
+ schemaAttr = jsxAttr;
94
+ }
95
+ }
96
+ if (schemaAttr === null) {
97
+ skipped.push({ loc, reason: '<ZodForm> has no schema={...} prop' });
98
+ return;
99
+ }
100
+ // schema must be a JSXExpressionContainer wrapping an Identifier.
101
+ const value = schemaAttr.value;
102
+ if (value === null || value === undefined || value.type !== 'JSXExpressionContainer') {
103
+ skipped.push({
104
+ loc,
105
+ reason: 'schema prop is not a JSXExpressionContainer (use schema={identifier})'
106
+ });
107
+ return;
108
+ }
109
+ const expr = value.expression;
110
+ if (expr.type !== 'Identifier') {
111
+ skipped.push({
112
+ loc,
113
+ reason: `schema prop expression is ${expr.type}, expected Identifier`
114
+ });
115
+ return;
116
+ }
117
+ const openingRange = rangeOf(opening);
118
+ const closingRange = path.node.closingElement === null || path.node.closingElement === undefined
119
+ ? null
120
+ : rangeOf(path.node.closingElement);
121
+ const childrenSource = closingRange === null ? '' : source.slice(openingRange.end, closingRange.start);
122
+ candidates.push({
123
+ openingRange,
124
+ closingRange,
125
+ loc,
126
+ selfClosing: opening.selfClosing,
127
+ attributes,
128
+ schemaIdentifier: expr.name,
129
+ childrenSource
130
+ });
131
+ }
132
+ });
133
+ return { candidates, skipped };
134
+ }
135
+ function rangeOf(node) {
136
+ if (node.start === null ||
137
+ node.start === undefined ||
138
+ node.end === null ||
139
+ node.end === undefined) {
140
+ throw new Error('Babel AST node missing byte range — parser was misconfigured');
141
+ }
142
+ return { start: node.start, end: node.end };
143
+ }
144
+ function locOf(node) {
145
+ const loc = node.loc;
146
+ if (loc === null || loc === undefined) {
147
+ return { line: 0, column: 0 };
148
+ }
149
+ return { line: loc.start.line, column: loc.start.column };
150
+ }
151
+ function containsZodForm(node) {
152
+ // Cheap check used to filter member-expression element names — we don't
153
+ // want every `<x.foo />` in the file to log a skip.
154
+ if (node.type === 'JSXIdentifier')
155
+ return node.name === 'ZodForm';
156
+ if (node.type === 'JSXMemberExpression') {
157
+ return containsZodForm(node.object) || containsZodForm(node.property);
158
+ }
159
+ return false;
160
+ }
161
+ //# sourceMappingURL=scan-jsx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan-jsx.js","sourceRoot":"","sources":["../../src/generate-mode/scan-jsx.ts"],"names":[],"mappings":"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"}
package/dist/hmr.d.ts ADDED
@@ -0,0 +1,44 @@
1
+ /**
2
+ * HMR helpers.
3
+ *
4
+ * `computeHmrInvalidation` is the pure side: given a changed file path,
5
+ * the cache, and the config file path, it returns the list of evicted
6
+ * cache keys (which the dispatching `handleHotUpdate` hook converts to
7
+ * Vite module ids).
8
+ *
9
+ * The hook itself lives in `plugin.ts` — it converts the result of this
10
+ * function into the array of `ModuleNode` objects Vite expects to
11
+ * invalidate.
12
+ */
13
+ import type { CompilationCache } from './cache.js';
14
+ export interface HmrInvalidationInput {
15
+ /** Absolute path of the file that just changed. */
16
+ changedFile: string;
17
+ /** Absolute path of the project's `z2f.config.ts` (or undefined if unknown). */
18
+ configFile: string | undefined;
19
+ /** The plugin's compilation cache. */
20
+ cache: CompilationCache;
21
+ }
22
+ export interface HmrInvalidationResult {
23
+ /**
24
+ * `'config'` means the config file changed and the entire cache was
25
+ * evicted. `'schema'` means a tracked schema file changed and only
26
+ * entries depending on it were evicted.
27
+ */
28
+ kind: 'config' | 'schema';
29
+ /** The cache keys that were evicted. */
30
+ evictedKeys: string[];
31
+ }
32
+ /**
33
+ * Decide what to invalidate when a file changes.
34
+ *
35
+ * Returns `null` to signal "fall through to Vite's default HMR behavior"
36
+ * — the changed file is neither the config nor a tracked schema, so the
37
+ * plugin has nothing to do.
38
+ *
39
+ * Returns a result object when the plugin DID invalidate something. The
40
+ * caller is responsible for converting the evicted keys back into Vite
41
+ * module ids (each key has the form `<schemaFile>::<variant>::<configHash>`).
42
+ */
43
+ export declare function computeHmrInvalidation(input: HmrInvalidationInput): HmrInvalidationResult | null;
44
+ //# sourceMappingURL=hmr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,sCAAsC;IACtC,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,wCAAwC;IACxC,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,GAAG,IAAI,CAiBhG"}
package/dist/hmr.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Decide what to invalidate when a file changes.
3
+ *
4
+ * Returns `null` to signal "fall through to Vite's default HMR behavior"
5
+ * — the changed file is neither the config nor a tracked schema, so the
6
+ * plugin has nothing to do.
7
+ *
8
+ * Returns a result object when the plugin DID invalidate something. The
9
+ * caller is responsible for converting the evicted keys back into Vite
10
+ * module ids (each key has the form `<schemaFile>::<variant>::<configHash>`).
11
+ */
12
+ export function computeHmrInvalidation(input) {
13
+ const { changedFile, configFile, cache } = input;
14
+ // Config file changed → wipe everything
15
+ if (configFile !== undefined && changedFile === configFile) {
16
+ const evictedKeys = cache.invalidateAll();
17
+ return { kind: 'config', evictedKeys };
18
+ }
19
+ // Schema file changed → surgical eviction
20
+ const evictedKeys = cache.invalidateByFile(changedFile);
21
+ if (evictedKeys.length === 0) {
22
+ // The cache had nothing for this file. The plugin has no business
23
+ // here; let Vite handle the file via its normal HMR machinery.
24
+ return null;
25
+ }
26
+ return { kind: 'schema', evictedKeys };
27
+ }
28
+ //# sourceMappingURL=hmr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hmr.js","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAkCA;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAA2B;IAChE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAEjD,wCAAwC;IACxC,IAAI,UAAU,KAAK,SAAS,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;QAC3D,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,EAAE,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACzC,CAAC;IAED,0CAA0C;IAC1C,MAAM,WAAW,GAAG,KAAK,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,kEAAkE;QAClE,+DAA+D;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Vite plugin for schema-driven form generation.
3
+ *
4
+ * Two modes:
5
+ * - **Query mode** (`?z2f` imports): import a schema file with a `?z2f` query
6
+ * parameter to receive a fully-generated React form component as a virtual
7
+ * module. Zero build step — the plugin compiles on demand.
8
+ * - **Generate mode** (`options.generate`): scan JSX source files for
9
+ * `<ZodForm>` call sites and replace statically-resolvable ones with
10
+ * generated form components at build time. Opt-in via `generate: {}`.
11
+ *
12
+ * Config resolution order:
13
+ * 1. `options.configPath` if explicitly provided
14
+ * 2. Auto-discovery of `z2f.config.{ts,mts,js,mjs}` in the Vite root
15
+ * 3. `DEFAULT_CONFIG` merged with `options.configOverride`
16
+ *
17
+ * @remarks
18
+ * Requires Zod v4 and `@zod-to-form/core`. The plugin uses Vite's
19
+ * `ssrLoadModule` to evaluate schema files — the same Vite resolver pipeline
20
+ * that handles your app code, so aliases and tsconfig paths all work.
21
+ *
22
+ * HMR contract: schema file changes invalidate only the affected virtual
23
+ * modules. Config file (`z2f.config.ts`) changes invalidate all cached
24
+ * compiled forms and trigger re-compilation on the next import.
25
+ *
26
+ * @useWhen
27
+ * - You want zero-config form generation directly from `import './schema?z2f'`
28
+ * - You have a Vite-based app and want to skip the CLI generate step
29
+ * - You need per-variant forms (mobile/desktop) from the same schema
30
+ * - You want HMR-aware form recompilation during development
31
+ *
32
+ * @avoidWhen
33
+ * - You are NOT using Vite (use `@zod-to-form/cli` for non-Vite builds)
34
+ * - Your schema files have cyclic type references — the `?z2f` rewriter
35
+ * recurses on Zod's type graph and will hang on cycles
36
+ * - You need SSR-safe form HTML without a client-side React bundle
37
+ * - You are on Zod v3 — the plugin only supports Zod v4 schemas
38
+ *
39
+ * @pitfalls
40
+ * - NEVER use `?z2f` on schemas with cyclic type references — the schema
41
+ * walker recurses on Zod's type graph and hits infinite recursion on cycles
42
+ * - NEVER enable `rewrite` (generate mode) with HMR simultaneously without
43
+ * testing — the in-memory compilation cache has invalidation gaps when
44
+ * source files are changed mid-session and the module graph is stale
45
+ * - NEVER assume Zod schema objects survive Vite's module graph isolation
46
+ * intact — always re-export schemas from a dedicated file so `ssrLoadModule`
47
+ * can evaluate them without pulling in unrelated runtime dependencies
48
+ * - NEVER put your `z2f.config.ts` outside the Vite root — auto-discovery
49
+ * only searches `resolvedConfig.root`; files outside that boundary are
50
+ * silently skipped and the plugin falls back to defaults
51
+ * - NEVER mix `configOverride` with a `z2f.config.ts` that overlaps the
52
+ * same keys — `configOverride` wins unconditionally (shallow merge), so
53
+ * config-file fields with the same name are silently dropped
54
+ *
55
+ * @packageDocumentation
56
+ */
57
+ export { z2fVite, default } from './plugin.js';
58
+ export type { PluginOptions, Z2FViteConfig, VariantConfigs, WriteOptions, GenerationTarget, CompilationEntry, GenerateSite, HMRInvalidationMap } from './types.js';
59
+ export { Z2FViteError, formatZ2FViteError } from './errors.js';
60
+ export type { Z2FViteErrorCode, Z2FViteErrorLocation } from './errors.js';
61
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE/C,YAAY,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Vite plugin for schema-driven form generation.
3
+ *
4
+ * Two modes:
5
+ * - **Query mode** (`?z2f` imports): import a schema file with a `?z2f` query
6
+ * parameter to receive a fully-generated React form component as a virtual
7
+ * module. Zero build step — the plugin compiles on demand.
8
+ * - **Generate mode** (`options.generate`): scan JSX source files for
9
+ * `<ZodForm>` call sites and replace statically-resolvable ones with
10
+ * generated form components at build time. Opt-in via `generate: {}`.
11
+ *
12
+ * Config resolution order:
13
+ * 1. `options.configPath` if explicitly provided
14
+ * 2. Auto-discovery of `z2f.config.{ts,mts,js,mjs}` in the Vite root
15
+ * 3. `DEFAULT_CONFIG` merged with `options.configOverride`
16
+ *
17
+ * @remarks
18
+ * Requires Zod v4 and `@zod-to-form/core`. The plugin uses Vite's
19
+ * `ssrLoadModule` to evaluate schema files — the same Vite resolver pipeline
20
+ * that handles your app code, so aliases and tsconfig paths all work.
21
+ *
22
+ * HMR contract: schema file changes invalidate only the affected virtual
23
+ * modules. Config file (`z2f.config.ts`) changes invalidate all cached
24
+ * compiled forms and trigger re-compilation on the next import.
25
+ *
26
+ * @useWhen
27
+ * - You want zero-config form generation directly from `import './schema?z2f'`
28
+ * - You have a Vite-based app and want to skip the CLI generate step
29
+ * - You need per-variant forms (mobile/desktop) from the same schema
30
+ * - You want HMR-aware form recompilation during development
31
+ *
32
+ * @avoidWhen
33
+ * - You are NOT using Vite (use `@zod-to-form/cli` for non-Vite builds)
34
+ * - Your schema files have cyclic type references — the `?z2f` rewriter
35
+ * recurses on Zod's type graph and will hang on cycles
36
+ * - You need SSR-safe form HTML without a client-side React bundle
37
+ * - You are on Zod v3 — the plugin only supports Zod v4 schemas
38
+ *
39
+ * @pitfalls
40
+ * - NEVER use `?z2f` on schemas with cyclic type references — the schema
41
+ * walker recurses on Zod's type graph and hits infinite recursion on cycles
42
+ * - NEVER enable `rewrite` (generate mode) with HMR simultaneously without
43
+ * testing — the in-memory compilation cache has invalidation gaps when
44
+ * source files are changed mid-session and the module graph is stale
45
+ * - NEVER assume Zod schema objects survive Vite's module graph isolation
46
+ * intact — always re-export schemas from a dedicated file so `ssrLoadModule`
47
+ * can evaluate them without pulling in unrelated runtime dependencies
48
+ * - NEVER put your `z2f.config.ts` outside the Vite root — auto-discovery
49
+ * only searches `resolvedConfig.root`; files outside that boundary are
50
+ * silently skipped and the plugin falls back to defaults
51
+ * - NEVER mix `configOverride` with a `z2f.config.ts` that overlaps the
52
+ * same keys — `configOverride` wins unconditionally (shallow merge), so
53
+ * config-file fields with the same name are silently dropped
54
+ *
55
+ * @packageDocumentation
56
+ */
57
+ export { z2fVite, default } from './plugin.js';
58
+ export { Z2FViteError, formatZ2FViteError } from './errors.js';
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAY/C,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Plugin logger.
3
+ *
4
+ * A small level-based logger independent of Vite's own logger. Used so the
5
+ * plugin can stay quiet by default but emit DEBUG-level diagnostics for
6
+ * generate-mode skipped sites and cache misses without polluting Vite's
7
+ * normal output.
8
+ */
9
+ export type LogLevel = 'silent' | 'warn' | 'info' | 'debug';
10
+ export interface Logger {
11
+ warn(message: string): void;
12
+ info(message: string): void;
13
+ debug(message: string): void;
14
+ /**
15
+ * Buffer a generate-mode skip diagnostic for end-of-build summary output.
16
+ * Diagnostics are flushed via `flushGenerateSummary()`.
17
+ */
18
+ bufferGenerateSkip(file: string, line: number, column: number, reason: string): void;
19
+ /**
20
+ * Emit the buffered generate-mode skip summary at INFO level (or higher),
21
+ * matching the format documented in `contracts/generate-mode.md`. Returns
22
+ * the number of skips that were summarized.
23
+ */
24
+ flushGenerateSummary(processed: number, rewritten: number): number;
25
+ }
26
+ export declare function createLogger(level?: LogLevel): Logger;
27
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAW5D,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACrF;;;;OAIG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CACpE;AASD,wBAAgB,YAAY,CAAC,KAAK,GAAE,QAAiB,GAAG,MAAM,CAoC7D"}
package/dist/logger.js ADDED
@@ -0,0 +1,46 @@
1
+ const LEVEL_RANK = {
2
+ silent: 0,
3
+ warn: 1,
4
+ info: 2,
5
+ debug: 3
6
+ };
7
+ const PREFIX = '[@zod-to-form/vite]';
8
+ export function createLogger(level = 'info') {
9
+ const rank = LEVEL_RANK[level];
10
+ const skips = [];
11
+ const shouldLog = (target) => LEVEL_RANK[target] <= rank;
12
+ return {
13
+ warn(message) {
14
+ if (shouldLog('warn'))
15
+ console.warn(`${PREFIX} ${message}`);
16
+ },
17
+ info(message) {
18
+ if (shouldLog('info'))
19
+ console.info(`${PREFIX} ${message}`);
20
+ },
21
+ debug(message) {
22
+ if (shouldLog('debug'))
23
+ console.debug(`${PREFIX} ${message}`);
24
+ },
25
+ bufferGenerateSkip(file, line, column, reason) {
26
+ skips.push({ file, line, column, reason });
27
+ },
28
+ flushGenerateSummary(processed, rewritten) {
29
+ const count = skips.length;
30
+ if (!shouldLog('info')) {
31
+ skips.length = 0;
32
+ return count;
33
+ }
34
+ const lines = [
35
+ `${PREFIX} Generate mode processed ${processed} files, rewrote ${rewritten} call sites, skipped ${count}:`
36
+ ];
37
+ for (const skip of skips) {
38
+ lines.push(` ${skip.file}:${skip.line}:${skip.column} — ${skip.reason}`);
39
+ }
40
+ console.info(lines.join('\n'));
41
+ skips.length = 0;
42
+ return count;
43
+ }
44
+ };
45
+ }
46
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAUA,MAAM,UAAU,GAA6B;IAC3C,MAAM,EAAE,CAAC;IACT,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,MAAM,MAAM,GAAG,qBAAqB,CAAC;AA0BrC,MAAM,UAAU,YAAY,CAAC,KAAK,GAAa,MAAM;IACnD,MAAM,IAAI,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,MAAM,SAAS,GAAG,CAAC,MAAgB,EAAW,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC;IAE5E,OAAO;QACL,IAAI,CAAC,OAAe;YAClB,IAAI,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,OAAe;YAClB,IAAI,SAAS,CAAC,MAAM,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,KAAK,CAAC,OAAe;YACnB,IAAI,SAAS,CAAC,OAAO,CAAC;gBAAE,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM;YAC3C,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,oBAAoB,CAAC,SAAS,EAAE,SAAS;YACvC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;YAC3B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvB,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;gBACjB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,MAAM,KAAK,GAAa;gBACtB,GAAG,MAAM,4BAA4B,SAAS,mBAAmB,SAAS,wBAAwB,KAAK,GAAG;aAC3G,CAAC;YACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5E,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YAC/B,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { type Plugin } from 'vite';
2
+ import type { PluginOptions } from './types.js';
3
+ /**
4
+ * Vite plugin factory for `@zod-to-form/vite`.
5
+ *
6
+ * Registers Vite hooks for:
7
+ * - **Query mode** (`resolveId` + `load`): intercepts `*.ts?z2f[=variant]` imports,
8
+ * evaluates the schema via `ssrLoadModule`, and returns a virtual module containing
9
+ * the generated React form component.
10
+ * - **Generate mode** (`transform`): when `options.generate` is set, scans JSX source
11
+ * files for `<ZodForm schema={X}>` and rewrites resolvable call sites with generated
12
+ * components at build time.
13
+ * - **Resolver tree-shake** (`transform`): removes `zodResolver` calls from `useZodForm`
14
+ * at build time when `validationLevel` is set, allowing bundlers to drop the
15
+ * `@hookform/resolvers` dependency.
16
+ * - **HMR** (`handleHotUpdate`): invalidates cached compiled forms when their schema or
17
+ * the `z2f.config.ts` changes.
18
+ *
19
+ * @param options - Optional plugin configuration. All fields are optional; `z2fVite()`
20
+ * with no arguments produces a working plugin using auto-discovered config.
21
+ * @returns A Vite `Plugin` object to include in `vite.config.ts`.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // vite.config.ts
26
+ * import { defineConfig } from 'vite';
27
+ * import { z2fVite } from '@zod-to-form/vite';
28
+ *
29
+ * export default defineConfig({
30
+ * plugins: [z2fVite()],
31
+ * });
32
+ * ```
33
+ *
34
+ * @useWhen
35
+ * - You want `import SignupForm from './signup.schema?z2f'` to Just Work in a Vite app
36
+ * - You want HMR-aware form recompilation when schemas change in development
37
+ * - You want to run generate mode to pre-compile forms from `<ZodForm>` call sites
38
+ *
39
+ * @avoidWhen
40
+ * - You are building with webpack, esbuild, Rollup, or any non-Vite bundler
41
+ * - Your schemas have cyclic references — the walker will recurse infinitely on them
42
+ * - You need server-side form rendering without a React runtime
43
+ *
44
+ * @pitfalls
45
+ * - NEVER use `?z2f` on schemas with cyclic type references — the schema walker
46
+ * recurses on Zod's internal type graph and hangs on cycles
47
+ * - NEVER enable `generate` mode and then rely on HMR without testing — the
48
+ * generate-mode transform cache does not integrate with Vite's standard HMR
49
+ * module invalidation for rewritten JSX files
50
+ * - NEVER assume Zod types survive Vite's module graph isolation — always export
51
+ * schemas from a dedicated `.schema.ts` file; importing from a module that
52
+ * re-exports through complex chains can fail under `ssrLoadModule`
53
+ * - NEVER configure `configPath` to point outside the Vite `root` — the plugin
54
+ * uses `ssrLoadModule` with a dev server scoped to `root`, so files outside
55
+ * that boundary may fail to resolve their own imports
56
+ *
57
+ * @category Plugin
58
+ */
59
+ export declare function z2fVite(options?: PluginOptions): Plugin;
60
+ export default z2fVite;
61
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAaA,OAAO,EAGL,KAAK,MAAM,EAGZ,MAAM,MAAM,CAAC;AAcd,OAAO,KAAK,EAAoB,aAAa,EAAiB,MAAM,YAAY,CAAC;AAyDjF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,aAAkB,GAAG,MAAM,CAiV3D;eAEc,OAAO"}