@schemashift/zod-valibot 0.7.0

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.
package/README.md ADDED
@@ -0,0 +1,200 @@
1
+ # @schemashift/zod-valibot
2
+
3
+ Zod to Valibot transformer for SchemaShift. Converts Zod's fluent method chain API to Valibot's pipe-based API with AST-based transformations.
4
+
5
+ **Tier:** Pro
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @schemashift/zod-valibot
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```typescript
16
+ import { createZodToValibotHandler } from '@schemashift/zod-valibot';
17
+ import { TransformEngine } from '@schemashift/core';
18
+
19
+ const engine = new TransformEngine();
20
+ engine.registerHandler('zod', 'valibot', createZodToValibotHandler());
21
+ ```
22
+
23
+ ## API Model Difference
24
+
25
+ Zod uses a fluent **method chain** API:
26
+
27
+ ```typescript
28
+ z.string().email().min(5).max(100)
29
+ ```
30
+
31
+ Valibot uses a **pipe-based** API where validations are arguments to `v.pipe()`:
32
+
33
+ ```typescript
34
+ v.pipe(v.string(), v.email(), v.minLength(5), v.maxLength(100))
35
+ ```
36
+
37
+ Modifiers like `.optional()` and `.nullable()` become wrapping functions:
38
+
39
+ ```typescript
40
+ // Zod
41
+ z.string().optional()
42
+
43
+ // Valibot
44
+ v.optional(v.string())
45
+ ```
46
+
47
+ ## Transformation Mappings
48
+
49
+ ### Imports
50
+
51
+ | Zod | Valibot |
52
+ |-----|---------|
53
+ | `import { z } from 'zod'` | `import * as v from 'valibot'` |
54
+ | `import * as z from 'zod'` | `import * as v from 'valibot'` |
55
+
56
+ ### Factory Methods
57
+
58
+ | Zod | Valibot |
59
+ |-----|---------|
60
+ | `z.string()` | `v.string()` |
61
+ | `z.number()` | `v.number()` |
62
+ | `z.boolean()` | `v.boolean()` |
63
+ | `z.date()` | `v.date()` |
64
+ | `z.bigint()` | `v.bigint()` |
65
+ | `z.symbol()` | `v.symbol()` |
66
+ | `z.undefined()` | `v.undefined_()` |
67
+ | `z.null()` | `v.null_()` |
68
+ | `z.void()` | `v.void_()` |
69
+ | `z.any()` | `v.any()` |
70
+ | `z.unknown()` | `v.unknown()` |
71
+ | `z.never()` | `v.never()` |
72
+ | `z.nan()` | `v.nan()` |
73
+ | `z.literal(val)` | `v.literal(val)` |
74
+ | `z.enum([...])` | `v.picklist([...])` |
75
+ | `z.nativeEnum(E)` | `v.enum_(E)` |
76
+ | `z.array(s)` | `v.array(s)` |
77
+ | `z.object({...})` | `v.object({...})` |
78
+ | `z.record(k, v)` | `v.record(k, v)` |
79
+ | `z.tuple([...])` | `v.tuple([...])` |
80
+ | `z.union([...])` | `v.union([...])` |
81
+ | `z.discriminatedUnion(d, [...])` | `v.variant(d, [...])` |
82
+ | `z.intersection(a, b)` | `v.intersect(a, b)` |
83
+ | `z.lazy(() => s)` | `v.lazy(() => s)` |
84
+ | `z.promise(s)` | `v.promise(s)` |
85
+ | `z.instanceof(C)` | `v.instance(C)` |
86
+
87
+ ### String Validations (Pipe)
88
+
89
+ | Zod | Valibot |
90
+ |-----|---------|
91
+ | `.email()` | `v.email()` |
92
+ | `.url()` | `v.url()` |
93
+ | `.uuid()` | `v.uuid()` |
94
+ | `.regex(r)` | `v.regex(r)` |
95
+ | `.ip()` | `v.ip()` |
96
+ | `.min(n)` | `v.minLength(n)` |
97
+ | `.max(n)` | `v.maxLength(n)` |
98
+ | `.length(n)` | `v.length(n)` |
99
+ | `.trim()` | `v.trim()` |
100
+ | `.toLowerCase()` | `v.toLowerCase()` |
101
+ | `.toUpperCase()` | `v.toUpperCase()` |
102
+ | `.includes(s)` | `v.includes(s)` |
103
+ | `.startsWith(s)` | `v.startsWith(s)` |
104
+ | `.endsWith(s)` | `v.endsWith(s)` |
105
+ | `.datetime()` | `v.isoDateTime()` |
106
+ | `.date()` | `v.isoDate()` |
107
+ | `.time()` | `v.isoTime()` |
108
+ | `.emoji()` | `v.emoji()` |
109
+
110
+ ### Number Validations (Pipe)
111
+
112
+ | Zod | Valibot |
113
+ |-----|---------|
114
+ | `.min(n)` | `v.minValue(n)` |
115
+ | `.max(n)` | `v.maxValue(n)` |
116
+ | `.gt(n)` | `v.minValue(n + 1)` |
117
+ | `.lt(n)` | `v.maxValue(n - 1)` |
118
+ | `.gte(n)` | `v.minValue(n)` |
119
+ | `.lte(n)` | `v.maxValue(n)` |
120
+ | `.int()` | `v.integer()` |
121
+ | `.positive()` | `v.minValue(1)` |
122
+ | `.negative()` | `v.maxValue(-1)` |
123
+ | `.nonnegative()` | `v.minValue(0)` |
124
+ | `.nonpositive()` | `v.maxValue(0)` |
125
+ | `.multipleOf(n)` | `v.multipleOf(n)` |
126
+ | `.finite()` | `v.finite()` |
127
+ | `.safe()` | `v.safeInteger()` |
128
+
129
+ ### Array Validations
130
+
131
+ | Zod | Valibot |
132
+ |-----|---------|
133
+ | `.min(n)` | `v.minLength(n)` |
134
+ | `.max(n)` | `v.maxLength(n)` |
135
+ | `.nonempty()` | `v.nonEmpty()` |
136
+
137
+ ### Modifiers (Wrapping)
138
+
139
+ | Zod | Valibot |
140
+ |-----|---------|
141
+ | `.optional()` | `v.optional(schema)` |
142
+ | `.nullable()` | `v.nullable(schema)` |
143
+ | `.nullish()` | `v.nullish(schema)` |
144
+ | `.default(val)` | `v.optional(schema, val)` |
145
+ | `.catch(val)` | `v.fallback(schema, val)` |
146
+ | `.readonly()` | `v.readonly(schema)` |
147
+ | `.transform(fn)` | `v.pipe(schema, v.transform(fn))` |
148
+ | `.refine(fn, msg)` | `v.pipe(schema, v.check(fn, msg))` |
149
+ | `.brand(name)` | `v.pipe(schema, v.brand(name))` |
150
+ | `.describe(msg)` | (removed — Valibot has no equivalent) |
151
+
152
+ ### Object Methods (Wrapping)
153
+
154
+ | Zod | Valibot |
155
+ |-----|---------|
156
+ | `.partial()` | `v.partial(schema)` |
157
+ | `.required()` | `v.required(schema)` |
158
+ | `.pick({...})` | `v.pick(schema, {...})` |
159
+ | `.omit({...})` | `v.omit(schema, {...})` |
160
+ | `.extend(other)` | `v.merge([schema, other])` |
161
+ | `.merge(other)` | `v.merge([schema, other])` |
162
+ | `.strict()` | `v.strict(schema)` |
163
+ | `.passthrough()` | (no-op — Valibot objects are loose by default) |
164
+ | `.strip()` | (no-op — Valibot strips unknown by default with v.object) |
165
+
166
+ ### Type Helpers
167
+
168
+ | Zod | Valibot |
169
+ |-----|---------|
170
+ | `z.infer<typeof s>` | `v.InferOutput<typeof s>` |
171
+ | `z.input<typeof s>` | `v.InferInput<typeof s>` |
172
+ | `z.output<typeof s>` | `v.InferOutput<typeof s>` |
173
+
174
+ ## Patterns Requiring Manual Review
175
+
176
+ ### `.superRefine()`
177
+
178
+ `.superRefine()` is converted with a warning since Valibot's custom validation has a different API:
179
+
180
+ ```typescript
181
+ // Zod
182
+ z.object({...}).superRefine((data, ctx) => {
183
+ ctx.addIssue({ code: 'custom', message: '...' });
184
+ });
185
+
186
+ // Valibot (needs manual conversion)
187
+ v.pipe(v.object({...}), /* TODO: superRefine -> custom validation */ v.check(...))
188
+ ```
189
+
190
+ ### `.catchall()`
191
+
192
+ Zod's `.catchall()` for extra properties requires manual conversion to Valibot's `v.record()` or custom validation.
193
+
194
+ ### `.keyof()`
195
+
196
+ Zod's `.keyof()` requires manual conversion to `v.picklist(Object.keys(...))`.
197
+
198
+ ## License
199
+
200
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,487 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ FACTORY_MAPPINGS: () => FACTORY_MAPPINGS,
24
+ MODIFIER_METHODS: () => MODIFIER_METHODS,
25
+ NUMBER_VALIDATION_MAPPINGS: () => NUMBER_VALIDATION_MAPPINGS,
26
+ OBJECT_METHODS: () => OBJECT_METHODS,
27
+ VALIDATION_MAPPINGS: () => VALIDATION_MAPPINGS,
28
+ ZodToValibotTransformer: () => ZodToValibotTransformer,
29
+ createZodToValibotHandler: () => createZodToValibotHandler
30
+ });
31
+ module.exports = __toCommonJS(index_exports);
32
+
33
+ // src/transformer.ts
34
+ var import_core = require("@schemashift/core");
35
+ var import_ts_morph = require("ts-morph");
36
+
37
+ // src/mappings.ts
38
+ var FACTORY_MAPPINGS = {
39
+ string: "v.string",
40
+ number: "v.number",
41
+ boolean: "v.boolean",
42
+ date: "v.date",
43
+ bigint: "v.bigint",
44
+ symbol: "v.symbol",
45
+ undefined: "v.undefined_",
46
+ null: "v.null_",
47
+ void: "v.void_",
48
+ any: "v.any",
49
+ unknown: "v.unknown",
50
+ never: "v.never",
51
+ nan: "v.nan",
52
+ literal: "v.literal",
53
+ enum: "v.picklist",
54
+ nativeEnum: "v.enum_",
55
+ array: "v.array",
56
+ object: "v.object",
57
+ record: "v.record",
58
+ tuple: "v.tuple",
59
+ union: "v.union",
60
+ discriminatedUnion: "v.variant",
61
+ intersection: "v.intersect",
62
+ lazy: "v.lazy",
63
+ promise: "v.promise",
64
+ instanceof: "v.instance"
65
+ };
66
+ var VALIDATION_MAPPINGS = {
67
+ // String validations
68
+ email: "v.email",
69
+ url: "v.url",
70
+ uuid: "v.uuid",
71
+ cuid: "v.cuid2",
72
+ cuid2: "v.cuid2",
73
+ ulid: "v.ulid",
74
+ regex: "v.regex",
75
+ ip: "v.ip",
76
+ datetime: "v.isoDateTime",
77
+ date: "v.isoDate",
78
+ time: "v.isoTime",
79
+ emoji: "v.emoji",
80
+ includes: "v.includes",
81
+ startsWith: "v.startsWith",
82
+ endsWith: "v.endsWith",
83
+ trim: "v.trim",
84
+ toLowerCase: "v.toLowerCase",
85
+ toUpperCase: "v.toUpperCase",
86
+ // Shared validations (string/number/array/date)
87
+ min: "v.minLength",
88
+ // Will be context-sensitive
89
+ max: "v.maxLength",
90
+ // Will be context-sensitive
91
+ length: "v.length",
92
+ // Number validations
93
+ gt: "v.minValue",
94
+ gte: "v.minValue",
95
+ lt: "v.maxValue",
96
+ lte: "v.maxValue",
97
+ int: "v.integer",
98
+ positive: "v.minValue",
99
+ negative: "v.maxValue",
100
+ nonnegative: "v.minValue",
101
+ nonpositive: "v.maxValue",
102
+ multipleOf: "v.multipleOf",
103
+ finite: "v.finite",
104
+ safe: "v.safeInteger",
105
+ // Array validations
106
+ nonempty: "v.nonEmpty",
107
+ // Schema modifiers (not pipe validators)
108
+ optional: null,
109
+ // Handled specially
110
+ nullable: null,
111
+ // Handled specially
112
+ nullish: null,
113
+ // Handled specially
114
+ default: null,
115
+ // Handled specially
116
+ catch: null,
117
+ // Handled specially
118
+ transform: null,
119
+ // Handled specially
120
+ refine: null,
121
+ // Handled specially
122
+ superRefine: null,
123
+ // Handled specially
124
+ brand: null,
125
+ // Handled specially
126
+ readonly: null,
127
+ // Handled specially
128
+ pipe: null,
129
+ // Handled specially
130
+ describe: null,
131
+ // Handled specially
132
+ // Object methods
133
+ partial: null,
134
+ // Handled specially
135
+ required: null,
136
+ // Handled specially
137
+ pick: null,
138
+ // Handled specially
139
+ omit: null,
140
+ // Handled specially
141
+ extend: null,
142
+ // Handled specially
143
+ merge: null,
144
+ // Handled specially
145
+ passthrough: null,
146
+ // Handled specially
147
+ strict: null,
148
+ // Handled specially
149
+ strip: null,
150
+ // Handled specially
151
+ catchall: null,
152
+ // Handled specially
153
+ keyof: null,
154
+ // Handled specially
155
+ // Array methods
156
+ element: null
157
+ // Part of factory
158
+ };
159
+ var NUMBER_VALIDATION_MAPPINGS = {
160
+ min: { name: "v.minValue", args: (a) => a },
161
+ max: { name: "v.maxValue", args: (a) => a },
162
+ gt: { name: "v.minValue", args: (a) => a.length > 0 ? [String(Number(a[0]) + 1)] : a },
163
+ lt: { name: "v.maxValue", args: (a) => a.length > 0 ? [String(Number(a[0]) - 1)] : a },
164
+ gte: { name: "v.minValue", args: (a) => a },
165
+ lte: { name: "v.maxValue", args: (a) => a },
166
+ positive: { name: "v.minValue", args: () => ["1"] },
167
+ negative: { name: "v.maxValue", args: () => ["-1"] },
168
+ nonnegative: { name: "v.minValue", args: () => ["0"] },
169
+ nonpositive: { name: "v.maxValue", args: () => ["0"] }
170
+ };
171
+ var MODIFIER_METHODS = /* @__PURE__ */ new Set([
172
+ "optional",
173
+ "nullable",
174
+ "nullish",
175
+ "default",
176
+ "catch",
177
+ "readonly",
178
+ "brand",
179
+ "describe",
180
+ "transform",
181
+ "refine",
182
+ "superRefine",
183
+ "pipe"
184
+ ]);
185
+ var OBJECT_METHODS = /* @__PURE__ */ new Set([
186
+ "partial",
187
+ "required",
188
+ "pick",
189
+ "omit",
190
+ "extend",
191
+ "merge",
192
+ "passthrough",
193
+ "strict",
194
+ "strip",
195
+ "catchall",
196
+ "keyof"
197
+ ]);
198
+
199
+ // src/transformer.ts
200
+ var ZodToValibotTransformer = class {
201
+ errors = [];
202
+ warnings = [];
203
+ transform(sourceFile) {
204
+ this.errors = [];
205
+ this.warnings = [];
206
+ const filePath = sourceFile.getFilePath();
207
+ const originalCode = sourceFile.getFullText();
208
+ try {
209
+ this.updateImports(sourceFile);
210
+ this.transformTypeHelpers(sourceFile);
211
+ this.transformSchemaExpressions(sourceFile);
212
+ return {
213
+ success: this.errors.length === 0,
214
+ filePath,
215
+ originalCode,
216
+ transformedCode: sourceFile.getFullText(),
217
+ errors: this.errors,
218
+ warnings: this.warnings
219
+ };
220
+ } catch (error) {
221
+ this.errors.push({
222
+ message: error instanceof Error ? error.message : "Unknown error"
223
+ });
224
+ return {
225
+ success: false,
226
+ filePath,
227
+ originalCode,
228
+ errors: this.errors,
229
+ warnings: this.warnings
230
+ };
231
+ }
232
+ }
233
+ updateImports(sourceFile) {
234
+ const zodImports = sourceFile.getImportDeclarations().filter((imp) => imp.getModuleSpecifierValue() === "zod");
235
+ for (const imp of zodImports) {
236
+ imp.setModuleSpecifier("valibot");
237
+ const namespaceImport = imp.getNamespaceImport();
238
+ const defaultImport = imp.getDefaultImport();
239
+ const namedImports = imp.getNamedImports();
240
+ if (namespaceImport) imp.removeNamespaceImport();
241
+ if (defaultImport) imp.removeDefaultImport();
242
+ if (namedImports.length > 0) imp.removeNamedImports();
243
+ imp.setNamespaceImport("v");
244
+ }
245
+ }
246
+ transformTypeHelpers(sourceFile) {
247
+ const fullText = sourceFile.getFullText();
248
+ let newText = fullText;
249
+ newText = newText.replace(/\bz\.infer</g, "v.InferOutput<");
250
+ newText = newText.replace(/\bz\.input</g, "v.InferInput<");
251
+ newText = newText.replace(/\bz\.output</g, "v.InferOutput<");
252
+ if (newText !== fullText) {
253
+ sourceFile.replaceWithText(newText);
254
+ }
255
+ }
256
+ transformSchemaExpressions(sourceFile) {
257
+ const nodesToTransform = [];
258
+ sourceFile.forEachDescendant((node) => {
259
+ if (import_ts_morph.Node.isCallExpression(node)) {
260
+ if ((0, import_core.isInsideStringLiteral)(node)) return;
261
+ const text = node.getText();
262
+ if (text.startsWith("z.")) {
263
+ nodesToTransform.push(node);
264
+ }
265
+ }
266
+ });
267
+ const outermost = this.filterOutermostNodes(nodesToTransform);
268
+ outermost.sort((a, b) => b.getStart() - a.getStart());
269
+ for (const node of outermost) {
270
+ this.transformCallChain(node);
271
+ }
272
+ }
273
+ filterOutermostNodes(nodes) {
274
+ const result = [];
275
+ for (const node of nodes) {
276
+ let isChild = false;
277
+ for (const other of nodes) {
278
+ if (other === node) continue;
279
+ if (other.getStart() <= node.getStart() && other.getEnd() >= node.getEnd()) {
280
+ isChild = true;
281
+ break;
282
+ }
283
+ }
284
+ if (!isChild) result.push(node);
285
+ }
286
+ return result;
287
+ }
288
+ transformCallChain(node) {
289
+ const chain = (0, import_core.parseCallChain)(node);
290
+ if (!chain) {
291
+ this.transformCallChainFallback(node);
292
+ return;
293
+ }
294
+ if (chain.base !== "z") return;
295
+ const filePath = node.getSourceFile().getFilePath();
296
+ const lineNumber = node.getStartLineNumber();
297
+ const factoryMapping = FACTORY_MAPPINGS[chain.factoryMethod];
298
+ if (!factoryMapping) {
299
+ this.warnings.push(
300
+ `${filePath}:${lineNumber}: Unknown Zod factory z.${chain.factoryMethod}() \u2014 kept as-is`
301
+ );
302
+ return;
303
+ }
304
+ const factoryType = chain.factoryMethod;
305
+ const pipeValidators = [];
306
+ const modifiers = [];
307
+ const objectMethods = [];
308
+ for (const method of chain.methods) {
309
+ const result2 = this.categorizeMethod(method, factoryType, filePath, lineNumber);
310
+ if (result2.type === "pipe") {
311
+ pipeValidators.push(result2.code);
312
+ } else if (result2.type === "modifier") {
313
+ modifiers.push({ name: result2.name, args: result2.args });
314
+ } else if (result2.type === "object") {
315
+ objectMethods.push({ name: result2.name, args: result2.args });
316
+ }
317
+ }
318
+ let result;
319
+ const factoryCall = `${factoryMapping}(${chain.factoryArgs.join(", ")})`;
320
+ if (pipeValidators.length > 0) {
321
+ result = `v.pipe(${factoryCall}, ${pipeValidators.join(", ")})`;
322
+ } else {
323
+ result = factoryCall;
324
+ }
325
+ for (const objMethod of objectMethods) {
326
+ result = this.applyObjectMethod(objMethod.name, objMethod.args, result, filePath, lineNumber);
327
+ }
328
+ for (const modifier of modifiers) {
329
+ result = this.applyModifier(modifier.name, modifier.args, result, filePath, lineNumber);
330
+ }
331
+ result = this.transformNestedZodReferences(result);
332
+ node.replaceWithText(result);
333
+ }
334
+ transformNestedZodReferences(text) {
335
+ let result = text;
336
+ for (const [zodName, valibotName] of Object.entries(FACTORY_MAPPINGS)) {
337
+ const regex = new RegExp(`\\bz\\.${zodName}\\(`, "g");
338
+ result = result.replace(regex, `${valibotName}(`);
339
+ }
340
+ return result;
341
+ }
342
+ categorizeMethod(method, factoryType, filePath, lineNumber) {
343
+ const { name, args } = method;
344
+ if (MODIFIER_METHODS.has(name)) {
345
+ return { type: "modifier", name, args };
346
+ }
347
+ if (OBJECT_METHODS.has(name)) {
348
+ return { type: "object", name, args };
349
+ }
350
+ if ((factoryType === "number" || factoryType === "bigint") && NUMBER_VALIDATION_MAPPINGS[name]) {
351
+ const mapping = NUMBER_VALIDATION_MAPPINGS[name];
352
+ if (!mapping) return { type: "skip" };
353
+ const mappedArgs = mapping.args(args);
354
+ return { type: "pipe", code: `${mapping.name}(${mappedArgs.join(", ")})` };
355
+ }
356
+ if (factoryType === "string" || factoryType === "array") {
357
+ if (name === "min") {
358
+ const vName = factoryType === "string" ? "v.minLength" : "v.minLength";
359
+ return { type: "pipe", code: `${vName}(${args.join(", ")})` };
360
+ }
361
+ if (name === "max") {
362
+ const vName = factoryType === "string" ? "v.maxLength" : "v.maxLength";
363
+ return { type: "pipe", code: `${vName}(${args.join(", ")})` };
364
+ }
365
+ }
366
+ const validationMapping = VALIDATION_MAPPINGS[name];
367
+ if (validationMapping === null) {
368
+ return { type: "skip" };
369
+ }
370
+ if (validationMapping) {
371
+ return { type: "pipe", code: `${validationMapping}(${args.join(", ")})` };
372
+ }
373
+ this.warnings.push(
374
+ `${filePath}:${lineNumber}: Unknown Zod method .${name}() \u2014 kept as-is in pipe`
375
+ );
376
+ return { type: "pipe", code: `/* TODO: .${name}(${args.join(", ")}) */` };
377
+ }
378
+ applyModifier(name, args, inner, filePath, lineNumber) {
379
+ switch (name) {
380
+ case "optional":
381
+ return `v.optional(${inner})`;
382
+ case "nullable":
383
+ return `v.nullable(${inner})`;
384
+ case "nullish":
385
+ return `v.nullish(${inner})`;
386
+ case "default":
387
+ return `v.optional(${inner}, ${args.join(", ")})`;
388
+ case "catch":
389
+ return `v.fallback(${inner}, ${args.join(", ")})`;
390
+ case "readonly":
391
+ return `v.readonly(${inner})`;
392
+ case "transform":
393
+ return `v.pipe(${inner}, v.transform(${args.join(", ")}))`;
394
+ case "refine":
395
+ if (args.length >= 2) {
396
+ return `v.pipe(${inner}, v.check(${args[0]}, ${args.slice(1).join(", ")}))`;
397
+ }
398
+ return `v.pipe(${inner}, v.check(${args.join(", ")}))`;
399
+ case "superRefine":
400
+ this.warnings.push(
401
+ `${filePath}:${lineNumber}: .superRefine() requires manual conversion to Valibot custom validation`
402
+ );
403
+ return `v.pipe(${inner}, /* TODO: superRefine -> custom validation */ v.check(${args.join(", ")}))`;
404
+ case "brand":
405
+ return `v.pipe(${inner}, v.brand(${args.join(", ")}))`;
406
+ case "describe":
407
+ return inner;
408
+ case "pipe":
409
+ return `v.pipe(${inner}, ${args.join(", ")})`;
410
+ default:
411
+ return inner;
412
+ }
413
+ }
414
+ applyObjectMethod(name, args, inner, filePath, lineNumber) {
415
+ switch (name) {
416
+ case "partial":
417
+ return `v.partial(${inner})`;
418
+ case "required":
419
+ return `v.required(${inner})`;
420
+ case "pick":
421
+ return `v.pick(${inner}, ${args.join(", ")})`;
422
+ case "omit":
423
+ return `v.omit(${inner}, ${args.join(", ")})`;
424
+ case "extend":
425
+ case "merge":
426
+ return `v.merge([${inner}, ${args.join(", ")}])`;
427
+ case "passthrough":
428
+ this.warnings.push(
429
+ `${filePath}:${lineNumber}: .passthrough() \u2014 Valibot objects are loose by default, no action needed`
430
+ );
431
+ return inner;
432
+ case "strict":
433
+ return `v.strict(${inner})`;
434
+ case "strip":
435
+ return inner;
436
+ // Valibot strips unknown by default when using v.object
437
+ case "catchall":
438
+ this.warnings.push(
439
+ `${filePath}:${lineNumber}: .catchall() requires manual conversion to Valibot record or custom validation`
440
+ );
441
+ return inner;
442
+ case "keyof":
443
+ this.warnings.push(
444
+ `${filePath}:${lineNumber}: .keyof() requires manual conversion to v.picklist(Object.keys(...))`
445
+ );
446
+ return inner;
447
+ default:
448
+ return inner;
449
+ }
450
+ }
451
+ transformCallChainFallback(node) {
452
+ const text = node.getText();
453
+ const filePath = node.getSourceFile().getFilePath();
454
+ const lineNumber = node.getStartLineNumber();
455
+ let transformed = text;
456
+ transformed = transformed.replace(/^z\./, "v.");
457
+ for (const [zodName, valibotName] of Object.entries(FACTORY_MAPPINGS)) {
458
+ const regex = new RegExp(`\\bv\\.${zodName}\\(`, "g");
459
+ transformed = transformed.replace(regex, `${valibotName}(`);
460
+ }
461
+ this.warnings.push(
462
+ `${filePath}:${lineNumber}: Complex Zod expression used fallback conversion \u2014 manual review recommended`
463
+ );
464
+ node.replaceWithText(transformed);
465
+ }
466
+ };
467
+
468
+ // src/handler.ts
469
+ function createZodToValibotHandler() {
470
+ const transformer = new ZodToValibotTransformer();
471
+ return {
472
+ transform(sourceFile, _options) {
473
+ return transformer.transform(sourceFile);
474
+ }
475
+ };
476
+ }
477
+ // Annotate the CommonJS export names for ESM import in node:
478
+ 0 && (module.exports = {
479
+ FACTORY_MAPPINGS,
480
+ MODIFIER_METHODS,
481
+ NUMBER_VALIDATION_MAPPINGS,
482
+ OBJECT_METHODS,
483
+ VALIDATION_MAPPINGS,
484
+ ZodToValibotTransformer,
485
+ createZodToValibotHandler
486
+ });
487
+ //# sourceMappingURL=index.cjs.map