@forklaunch/validator 0.7.6 → 0.7.7
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/lib/__test__/utils/mockSchemaValidator.d.mts +2 -2
- package/lib/__test__/utils/mockSchemaValidator.d.ts +2 -2
- package/lib/index.d.mts +3 -3
- package/lib/index.d.ts +3 -3
- package/lib/{schema.types-xFskiFwY.d.mts → schema.types-C3S1yoja.d.mts} +2 -2
- package/lib/{schema.types-xFskiFwY.d.ts → schema.types-C3S1yoja.d.ts} +2 -2
- package/lib/shims/zod-v3-openapi/zod-extensions.d.mts +15 -0
- package/lib/shims/zod-v3-openapi/zod-extensions.d.ts +15 -0
- package/lib/shims/zod-v3-openapi/zod-extensions.js +53 -0
- package/lib/shims/zod-v3-openapi/zod-extensions.mjs +26 -0
- package/lib/src/typebox/index.d.mts +3 -3
- package/lib/src/typebox/index.d.ts +3 -3
- package/lib/src/zod/index.d.mts +3 -3
- package/lib/src/zod/index.d.ts +3 -3
- package/lib/src/zod/index.js +616 -36
- package/lib/src/zod/index.mjs +613 -33
- package/package.json +5 -5
package/lib/src/zod/index.mjs
CHANGED
|
@@ -1,47 +1,627 @@
|
|
|
1
1
|
// src/zod/zodSchemaValidator.ts
|
|
2
|
-
import { extendZodWithOpenApi, generateSchema } from "@anatine/zod-openapi";
|
|
3
2
|
import {
|
|
4
|
-
z,
|
|
3
|
+
z as z2,
|
|
5
4
|
ZodType
|
|
6
|
-
} from "zod";
|
|
7
|
-
|
|
5
|
+
} from "zod/v3";
|
|
6
|
+
|
|
7
|
+
// shims/zod-v3-openapi/zod-openapi.ts
|
|
8
|
+
import { merge } from "ts-deepmerge";
|
|
9
|
+
import { z } from "zod/v3";
|
|
10
|
+
function extendApi(schema, schemaObject = {}) {
|
|
11
|
+
const This = schema.constructor;
|
|
12
|
+
const newSchema = new This(schema._def);
|
|
13
|
+
newSchema.metaOpenApi = Object.assign(
|
|
14
|
+
{},
|
|
15
|
+
schema.metaOpenApi || {},
|
|
16
|
+
schemaObject
|
|
17
|
+
);
|
|
18
|
+
return newSchema;
|
|
19
|
+
}
|
|
20
|
+
function iterateZodObject({
|
|
21
|
+
zodRef,
|
|
22
|
+
useOutput,
|
|
23
|
+
hideDefinitions,
|
|
24
|
+
openApiVersion
|
|
25
|
+
}) {
|
|
26
|
+
const reduced = Object.keys(zodRef.shape).filter((key) => hideDefinitions?.includes(key) === false).reduce(
|
|
27
|
+
(carry, key) => ({
|
|
28
|
+
...carry,
|
|
29
|
+
[key]: generateSchema(zodRef.shape[key], useOutput, openApiVersion)
|
|
30
|
+
}),
|
|
31
|
+
{}
|
|
32
|
+
);
|
|
33
|
+
return reduced;
|
|
34
|
+
}
|
|
35
|
+
function typeFormat(type2, openApiVersion) {
|
|
36
|
+
return openApiVersion === "3.0" ? type2 : [type2];
|
|
37
|
+
}
|
|
38
|
+
function parseTransformation({
|
|
39
|
+
zodRef,
|
|
40
|
+
schemas,
|
|
41
|
+
useOutput,
|
|
42
|
+
openApiVersion
|
|
43
|
+
}) {
|
|
44
|
+
const input = generateSchema(zodRef._def.schema, useOutput, openApiVersion);
|
|
45
|
+
let output = "undefined";
|
|
46
|
+
if (useOutput && zodRef._def.effect) {
|
|
47
|
+
const effect = zodRef._def.effect.type === "transform" ? zodRef._def.effect : null;
|
|
48
|
+
if (effect && "transform" in effect) {
|
|
49
|
+
try {
|
|
50
|
+
const type2 = Array.isArray(input.type) ? input.type[0] : input.type;
|
|
51
|
+
output = typeof effect.transform(
|
|
52
|
+
["integer", "number"].includes(`${type2}`) ? 0 : "string" === type2 ? "" : "boolean" === type2 ? false : "object" === type2 ? {} : "null" === type2 ? null : "array" === type2 ? [] : void 0,
|
|
53
|
+
{ addIssue: () => void 0, path: [] }
|
|
54
|
+
// TODO: Discover if context is necessary here
|
|
55
|
+
);
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const outputType = output;
|
|
61
|
+
return merge(
|
|
62
|
+
{
|
|
63
|
+
...zodRef.description ? { description: zodRef.description } : {},
|
|
64
|
+
...input,
|
|
65
|
+
...["number", "string", "boolean", "null"].includes(output) ? {
|
|
66
|
+
type: typeFormat(outputType, openApiVersion)
|
|
67
|
+
} : {}
|
|
68
|
+
},
|
|
69
|
+
...schemas
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
function parseString({
|
|
73
|
+
zodRef,
|
|
74
|
+
schemas,
|
|
75
|
+
openApiVersion
|
|
76
|
+
}) {
|
|
77
|
+
const baseSchema = {
|
|
78
|
+
type: typeFormat("string", openApiVersion)
|
|
79
|
+
};
|
|
80
|
+
const { checks = [] } = zodRef._def;
|
|
81
|
+
checks.forEach((item) => {
|
|
82
|
+
switch (item.kind) {
|
|
83
|
+
case "email":
|
|
84
|
+
baseSchema.format = "email";
|
|
85
|
+
break;
|
|
86
|
+
case "uuid":
|
|
87
|
+
baseSchema.format = "uuid";
|
|
88
|
+
break;
|
|
89
|
+
case "cuid":
|
|
90
|
+
baseSchema.format = "cuid";
|
|
91
|
+
break;
|
|
92
|
+
case "url":
|
|
93
|
+
baseSchema.format = "uri";
|
|
94
|
+
break;
|
|
95
|
+
case "datetime":
|
|
96
|
+
baseSchema.format = "date-time";
|
|
97
|
+
break;
|
|
98
|
+
case "length":
|
|
99
|
+
baseSchema.minLength = item.value;
|
|
100
|
+
baseSchema.maxLength = item.value;
|
|
101
|
+
break;
|
|
102
|
+
case "max":
|
|
103
|
+
baseSchema.maxLength = item.value;
|
|
104
|
+
break;
|
|
105
|
+
case "min":
|
|
106
|
+
baseSchema.minLength = item.value;
|
|
107
|
+
break;
|
|
108
|
+
case "regex":
|
|
109
|
+
baseSchema.pattern = item.regex.source;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
return merge(
|
|
114
|
+
baseSchema,
|
|
115
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
116
|
+
...schemas
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function parseNumber({
|
|
120
|
+
zodRef,
|
|
121
|
+
schemas,
|
|
122
|
+
openApiVersion
|
|
123
|
+
}) {
|
|
124
|
+
const baseSchema = {
|
|
125
|
+
type: typeFormat("number", openApiVersion)
|
|
126
|
+
};
|
|
127
|
+
const { checks = [] } = zodRef._def;
|
|
128
|
+
checks.forEach((item) => {
|
|
129
|
+
switch (item.kind) {
|
|
130
|
+
case "max":
|
|
131
|
+
if (item.inclusive || openApiVersion === "3.0") {
|
|
132
|
+
baseSchema.maximum = item.value;
|
|
133
|
+
}
|
|
134
|
+
if (!item.inclusive) {
|
|
135
|
+
if (openApiVersion === "3.0") {
|
|
136
|
+
baseSchema.exclusiveMaximum = true;
|
|
137
|
+
} else {
|
|
138
|
+
baseSchema.exclusiveMaximum = item.value;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
case "min":
|
|
143
|
+
if (item.inclusive || openApiVersion === "3.0") {
|
|
144
|
+
baseSchema.minimum = item.value;
|
|
145
|
+
}
|
|
146
|
+
if (!item.inclusive) {
|
|
147
|
+
if (openApiVersion === "3.0") {
|
|
148
|
+
baseSchema.exclusiveMinimum = true;
|
|
149
|
+
} else {
|
|
150
|
+
baseSchema.exclusiveMinimum = item.value;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
case "int":
|
|
155
|
+
baseSchema.type = typeFormat("integer", openApiVersion);
|
|
156
|
+
break;
|
|
157
|
+
case "multipleOf":
|
|
158
|
+
baseSchema.multipleOf = item.value;
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
return merge(
|
|
163
|
+
baseSchema,
|
|
164
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
165
|
+
...schemas
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
function getExcludedDefinitionsFromSchema(schemas) {
|
|
169
|
+
const excludedDefinitions = [];
|
|
170
|
+
for (const schema of schemas) {
|
|
171
|
+
if (Array.isArray(schema.hideDefinitions)) {
|
|
172
|
+
excludedDefinitions.push(...schema.hideDefinitions);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return excludedDefinitions;
|
|
176
|
+
}
|
|
177
|
+
function parseObject({
|
|
178
|
+
zodRef,
|
|
179
|
+
schemas,
|
|
180
|
+
useOutput,
|
|
181
|
+
hideDefinitions,
|
|
182
|
+
openApiVersion
|
|
183
|
+
}) {
|
|
184
|
+
let additionalProperties;
|
|
185
|
+
if (!(zodRef._def.catchall instanceof z.ZodNever || zodRef._def.catchall?._def.typeName === "ZodNever"))
|
|
186
|
+
additionalProperties = generateSchema(
|
|
187
|
+
zodRef._def.catchall,
|
|
188
|
+
useOutput,
|
|
189
|
+
openApiVersion
|
|
190
|
+
);
|
|
191
|
+
else if (zodRef._def.unknownKeys === "passthrough")
|
|
192
|
+
additionalProperties = true;
|
|
193
|
+
else if (zodRef._def.unknownKeys === "strict") additionalProperties = false;
|
|
194
|
+
additionalProperties = additionalProperties != null ? { additionalProperties } : {};
|
|
195
|
+
const requiredProperties = Object.keys(
|
|
196
|
+
zodRef.shape
|
|
197
|
+
).filter((key) => {
|
|
198
|
+
const item = zodRef.shape[key];
|
|
199
|
+
return !(item.isOptional() || item instanceof z.ZodDefault || item._def.typeName === "ZodDefault") && !(item instanceof z.ZodNever || item._def.typeName === "ZodDefault");
|
|
200
|
+
});
|
|
201
|
+
const required = requiredProperties.length > 0 ? { required: requiredProperties } : {};
|
|
202
|
+
return merge(
|
|
203
|
+
{
|
|
204
|
+
type: typeFormat("object", openApiVersion),
|
|
205
|
+
properties: iterateZodObject({
|
|
206
|
+
zodRef,
|
|
207
|
+
schemas,
|
|
208
|
+
useOutput,
|
|
209
|
+
hideDefinitions: getExcludedDefinitionsFromSchema(schemas),
|
|
210
|
+
openApiVersion
|
|
211
|
+
}),
|
|
212
|
+
...required,
|
|
213
|
+
...additionalProperties,
|
|
214
|
+
...hideDefinitions
|
|
215
|
+
},
|
|
216
|
+
zodRef.description ? { description: zodRef.description, hideDefinitions } : {},
|
|
217
|
+
...schemas
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
function parseRecord({
|
|
221
|
+
zodRef,
|
|
222
|
+
schemas,
|
|
223
|
+
useOutput,
|
|
224
|
+
openApiVersion
|
|
225
|
+
}) {
|
|
226
|
+
return merge(
|
|
227
|
+
{
|
|
228
|
+
type: typeFormat("object", openApiVersion),
|
|
229
|
+
additionalProperties: zodRef._def.valueType instanceof z.ZodUnknown ? {} : generateSchema(zodRef._def.valueType, useOutput, openApiVersion)
|
|
230
|
+
},
|
|
231
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
232
|
+
...schemas
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
function parseBigInt({
|
|
236
|
+
zodRef,
|
|
237
|
+
schemas,
|
|
238
|
+
openApiVersion
|
|
239
|
+
}) {
|
|
240
|
+
return merge(
|
|
241
|
+
{
|
|
242
|
+
type: typeFormat("integer", openApiVersion),
|
|
243
|
+
format: "int64"
|
|
244
|
+
},
|
|
245
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
246
|
+
...schemas
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
function parseBoolean({
|
|
250
|
+
zodRef,
|
|
251
|
+
schemas,
|
|
252
|
+
openApiVersion
|
|
253
|
+
}) {
|
|
254
|
+
return merge(
|
|
255
|
+
{ type: typeFormat("boolean", openApiVersion) },
|
|
256
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
257
|
+
...schemas
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
function parseDate({
|
|
261
|
+
zodRef,
|
|
262
|
+
schemas,
|
|
263
|
+
openApiVersion
|
|
264
|
+
}) {
|
|
265
|
+
return merge(
|
|
266
|
+
{
|
|
267
|
+
type: typeFormat("string", openApiVersion),
|
|
268
|
+
format: "date-time"
|
|
269
|
+
},
|
|
270
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
271
|
+
...schemas
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
function parseNull({
|
|
275
|
+
zodRef,
|
|
276
|
+
schemas,
|
|
277
|
+
openApiVersion
|
|
278
|
+
}) {
|
|
279
|
+
return merge(
|
|
280
|
+
openApiVersion === "3.0" ? { type: "null" } : {
|
|
281
|
+
type: ["string", "null"],
|
|
282
|
+
enum: ["null"]
|
|
283
|
+
},
|
|
284
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
285
|
+
...schemas
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
function parseOptional({
|
|
289
|
+
schemas,
|
|
290
|
+
zodRef,
|
|
291
|
+
useOutput,
|
|
292
|
+
openApiVersion
|
|
293
|
+
}) {
|
|
294
|
+
return merge(
|
|
295
|
+
generateSchema(zodRef.unwrap(), useOutput, openApiVersion),
|
|
296
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
297
|
+
...schemas
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
function parseNullable({
|
|
301
|
+
schemas,
|
|
302
|
+
zodRef,
|
|
303
|
+
useOutput,
|
|
304
|
+
openApiVersion
|
|
305
|
+
}) {
|
|
306
|
+
const schema = generateSchema(zodRef.unwrap(), useOutput, openApiVersion);
|
|
307
|
+
return merge(
|
|
308
|
+
schema,
|
|
309
|
+
openApiVersion === "3.0" ? { nullable: true } : { type: typeFormat("null", openApiVersion) },
|
|
310
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
311
|
+
...schemas
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
function parseDefault({
|
|
315
|
+
schemas,
|
|
316
|
+
zodRef,
|
|
317
|
+
useOutput,
|
|
318
|
+
openApiVersion
|
|
319
|
+
}) {
|
|
320
|
+
return merge(
|
|
321
|
+
{
|
|
322
|
+
default: zodRef._def.defaultValue(),
|
|
323
|
+
...generateSchema(zodRef._def.innerType, useOutput, openApiVersion)
|
|
324
|
+
},
|
|
325
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
326
|
+
...schemas
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
function parseArray({
|
|
330
|
+
schemas,
|
|
331
|
+
zodRef,
|
|
332
|
+
useOutput,
|
|
333
|
+
openApiVersion
|
|
334
|
+
}) {
|
|
335
|
+
const constraints = {};
|
|
336
|
+
if (zodRef._def.exactLength != null) {
|
|
337
|
+
constraints.minItems = zodRef._def.exactLength.value;
|
|
338
|
+
constraints.maxItems = zodRef._def.exactLength.value;
|
|
339
|
+
}
|
|
340
|
+
if (zodRef._def.minLength != null)
|
|
341
|
+
constraints.minItems = zodRef._def.minLength.value;
|
|
342
|
+
if (zodRef._def.maxLength != null)
|
|
343
|
+
constraints.maxItems = zodRef._def.maxLength.value;
|
|
344
|
+
return merge(
|
|
345
|
+
{
|
|
346
|
+
type: typeFormat("array", openApiVersion),
|
|
347
|
+
items: generateSchema(zodRef.element, useOutput, openApiVersion),
|
|
348
|
+
...constraints
|
|
349
|
+
},
|
|
350
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
351
|
+
...schemas
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
function parseLiteral({
|
|
355
|
+
schemas,
|
|
356
|
+
zodRef,
|
|
357
|
+
openApiVersion
|
|
358
|
+
}) {
|
|
359
|
+
const type2 = typeof zodRef._def.value;
|
|
360
|
+
return merge(
|
|
361
|
+
{
|
|
362
|
+
type: typeFormat(type2, openApiVersion),
|
|
363
|
+
enum: [zodRef._def.value]
|
|
364
|
+
},
|
|
365
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
366
|
+
...schemas
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
function parseEnum({
|
|
370
|
+
schemas,
|
|
371
|
+
zodRef,
|
|
372
|
+
openApiVersion
|
|
373
|
+
}) {
|
|
374
|
+
const type2 = typeof Object.values(zodRef._def.values)[0];
|
|
375
|
+
return merge(
|
|
376
|
+
{
|
|
377
|
+
type: typeFormat(type2, openApiVersion),
|
|
378
|
+
enum: Object.values(zodRef._def.values)
|
|
379
|
+
},
|
|
380
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
381
|
+
...schemas
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
function parseIntersection({
|
|
385
|
+
schemas,
|
|
386
|
+
zodRef,
|
|
387
|
+
useOutput,
|
|
388
|
+
openApiVersion
|
|
389
|
+
}) {
|
|
390
|
+
return merge(
|
|
391
|
+
{
|
|
392
|
+
allOf: [
|
|
393
|
+
generateSchema(zodRef._def.left, useOutput, openApiVersion),
|
|
394
|
+
generateSchema(zodRef._def.right, useOutput, openApiVersion)
|
|
395
|
+
]
|
|
396
|
+
},
|
|
397
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
398
|
+
...schemas
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
function parseUnion({
|
|
402
|
+
schemas,
|
|
403
|
+
zodRef,
|
|
404
|
+
useOutput,
|
|
405
|
+
openApiVersion
|
|
406
|
+
}) {
|
|
407
|
+
const contents = zodRef._def.options;
|
|
408
|
+
if (contents.reduce(
|
|
409
|
+
(prev, content) => prev && content._def.typeName === "ZodLiteral",
|
|
410
|
+
true
|
|
411
|
+
)) {
|
|
412
|
+
const literals = contents;
|
|
413
|
+
const type2 = literals.reduce(
|
|
414
|
+
(prev, content) => !prev || prev === typeof content._def.value ? typeof content._def.value : null,
|
|
415
|
+
null
|
|
416
|
+
);
|
|
417
|
+
if (type2) {
|
|
418
|
+
return merge(
|
|
419
|
+
{
|
|
420
|
+
type: typeFormat(type2, openApiVersion),
|
|
421
|
+
enum: literals.map((literal2) => literal2._def.value)
|
|
422
|
+
},
|
|
423
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
424
|
+
...schemas
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
const oneOfContents = openApiVersion === "3.0" ? contents.filter((content) => content._def.typeName !== "ZodNull") : contents;
|
|
429
|
+
const contentsHasNull = contents.length != oneOfContents.length;
|
|
430
|
+
return merge(
|
|
431
|
+
{
|
|
432
|
+
oneOf: oneOfContents.map(
|
|
433
|
+
(schema) => generateSchema(schema, useOutput, openApiVersion)
|
|
434
|
+
)
|
|
435
|
+
},
|
|
436
|
+
contentsHasNull ? { nullable: true } : {},
|
|
437
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
438
|
+
...schemas
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
function parseDiscriminatedUnion({
|
|
442
|
+
schemas,
|
|
443
|
+
zodRef,
|
|
444
|
+
useOutput,
|
|
445
|
+
openApiVersion
|
|
446
|
+
}) {
|
|
447
|
+
return merge(
|
|
448
|
+
{
|
|
449
|
+
discriminator: {
|
|
450
|
+
propertyName: zodRef._def.discriminator
|
|
451
|
+
},
|
|
452
|
+
oneOf: Array.from(
|
|
453
|
+
zodRef._def.options.values()
|
|
454
|
+
).map((schema) => generateSchema(schema, useOutput, openApiVersion))
|
|
455
|
+
},
|
|
456
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
457
|
+
...schemas
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
function parseNever({
|
|
461
|
+
zodRef,
|
|
462
|
+
schemas
|
|
463
|
+
}) {
|
|
464
|
+
return merge(
|
|
465
|
+
{ readOnly: true },
|
|
466
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
467
|
+
...schemas
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
function parseBranded({
|
|
471
|
+
schemas,
|
|
472
|
+
zodRef,
|
|
473
|
+
useOutput,
|
|
474
|
+
openApiVersion
|
|
475
|
+
}) {
|
|
476
|
+
return merge(
|
|
477
|
+
generateSchema(zodRef._def.type, useOutput, openApiVersion),
|
|
478
|
+
...schemas
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
function catchAllParser({
|
|
482
|
+
zodRef,
|
|
483
|
+
schemas
|
|
484
|
+
}) {
|
|
485
|
+
return merge(
|
|
486
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
487
|
+
...schemas
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
function parsePipeline({
|
|
491
|
+
schemas,
|
|
492
|
+
zodRef,
|
|
493
|
+
useOutput,
|
|
494
|
+
openApiVersion
|
|
495
|
+
}) {
|
|
496
|
+
return merge(
|
|
497
|
+
generateSchema(
|
|
498
|
+
useOutput ? zodRef._def.out : zodRef._def.in,
|
|
499
|
+
useOutput,
|
|
500
|
+
openApiVersion
|
|
501
|
+
),
|
|
502
|
+
...schemas
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
function parseReadonly({
|
|
506
|
+
zodRef,
|
|
507
|
+
useOutput,
|
|
508
|
+
schemas,
|
|
509
|
+
openApiVersion
|
|
510
|
+
}) {
|
|
511
|
+
return merge(
|
|
512
|
+
generateSchema(zodRef._def.innerType, useOutput, openApiVersion),
|
|
513
|
+
zodRef.description ? { description: zodRef.description } : {},
|
|
514
|
+
...schemas
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
var workerMap = {
|
|
518
|
+
ZodObject: parseObject,
|
|
519
|
+
ZodRecord: parseRecord,
|
|
520
|
+
ZodString: parseString,
|
|
521
|
+
ZodNumber: parseNumber,
|
|
522
|
+
ZodBigInt: parseBigInt,
|
|
523
|
+
ZodBoolean: parseBoolean,
|
|
524
|
+
ZodDate: parseDate,
|
|
525
|
+
ZodNull: parseNull,
|
|
526
|
+
ZodOptional: parseOptional,
|
|
527
|
+
ZodNullable: parseNullable,
|
|
528
|
+
ZodDefault: parseDefault,
|
|
529
|
+
ZodArray: parseArray,
|
|
530
|
+
ZodLiteral: parseLiteral,
|
|
531
|
+
ZodEnum: parseEnum,
|
|
532
|
+
ZodNativeEnum: parseEnum,
|
|
533
|
+
ZodTransformer: parseTransformation,
|
|
534
|
+
ZodEffects: parseTransformation,
|
|
535
|
+
ZodIntersection: parseIntersection,
|
|
536
|
+
ZodUnion: parseUnion,
|
|
537
|
+
ZodDiscriminatedUnion: parseDiscriminatedUnion,
|
|
538
|
+
ZodNever: parseNever,
|
|
539
|
+
ZodBranded: parseBranded,
|
|
540
|
+
// TODO Transform the rest to schemas
|
|
541
|
+
ZodUndefined: catchAllParser,
|
|
542
|
+
// TODO: `prefixItems` is allowed in OpenAPI 3.1 which can be used to create tuples
|
|
543
|
+
ZodTuple: catchAllParser,
|
|
544
|
+
ZodMap: catchAllParser,
|
|
545
|
+
ZodFunction: catchAllParser,
|
|
546
|
+
ZodLazy: catchAllParser,
|
|
547
|
+
ZodPromise: catchAllParser,
|
|
548
|
+
ZodAny: catchAllParser,
|
|
549
|
+
ZodUnknown: catchAllParser,
|
|
550
|
+
ZodVoid: catchAllParser,
|
|
551
|
+
ZodPipeline: parsePipeline,
|
|
552
|
+
ZodReadonly: parseReadonly
|
|
553
|
+
};
|
|
554
|
+
function generateSchema(zodRef, useOutput = false, openApiVersion = "3.1") {
|
|
555
|
+
const { metaOpenApi = {} } = zodRef;
|
|
556
|
+
const schemas = [
|
|
557
|
+
...Array.isArray(metaOpenApi) ? metaOpenApi : [metaOpenApi]
|
|
558
|
+
];
|
|
559
|
+
try {
|
|
560
|
+
const typeName = zodRef._def.typeName;
|
|
561
|
+
if (typeName in workerMap) {
|
|
562
|
+
return workerMap[typeName]({
|
|
563
|
+
zodRef,
|
|
564
|
+
schemas,
|
|
565
|
+
useOutput,
|
|
566
|
+
openApiVersion
|
|
567
|
+
});
|
|
568
|
+
}
|
|
569
|
+
return catchAllParser({ zodRef, schemas, openApiVersion });
|
|
570
|
+
} catch (err) {
|
|
571
|
+
console.error(err);
|
|
572
|
+
return catchAllParser({ zodRef, schemas, openApiVersion });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// shims/zod-v3-openapi/zod-extensions.ts
|
|
577
|
+
function extendZodWithOpenApi(zod, forceOverride = false) {
|
|
578
|
+
if (!forceOverride && typeof zod.ZodSchema.prototype.openapi !== "undefined") {
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
zod.ZodSchema.prototype.openapi = function(metadata) {
|
|
582
|
+
return extendApi(this, metadata);
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/zod/zodSchemaValidator.ts
|
|
587
|
+
extendZodWithOpenApi(z2);
|
|
8
588
|
var ZodSchemaValidator = class {
|
|
9
589
|
_Type = "Zod";
|
|
10
590
|
_SchemaCatchall;
|
|
11
591
|
_ValidSchemaObject;
|
|
12
|
-
string =
|
|
592
|
+
string = z2.string().openapi({
|
|
13
593
|
title: "String",
|
|
14
594
|
example: "a string"
|
|
15
595
|
});
|
|
16
|
-
uuid =
|
|
596
|
+
uuid = z2.string().uuid().openapi({
|
|
17
597
|
title: "UUID",
|
|
18
598
|
format: "uuid",
|
|
19
599
|
pattern: "^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$",
|
|
20
600
|
example: "a8b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6"
|
|
21
601
|
});
|
|
22
|
-
email =
|
|
602
|
+
email = z2.string().email().openapi({
|
|
23
603
|
title: "Email",
|
|
24
604
|
format: "email",
|
|
25
605
|
pattern: `(?:[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*|"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)])`,
|
|
26
606
|
example: "a@b.com"
|
|
27
607
|
});
|
|
28
|
-
uri =
|
|
608
|
+
uri = z2.string().url().openapi({
|
|
29
609
|
title: "URI",
|
|
30
610
|
format: "uri",
|
|
31
611
|
pattern: "^[a-zA-Z][a-zA-Z\\d+-.]*:[^\\s]*$",
|
|
32
612
|
example: "https://forklaunch.com"
|
|
33
613
|
});
|
|
34
|
-
number =
|
|
614
|
+
number = z2.preprocess((value) => {
|
|
35
615
|
try {
|
|
36
616
|
return Number(value);
|
|
37
617
|
} catch {
|
|
38
618
|
return value;
|
|
39
619
|
}
|
|
40
|
-
},
|
|
620
|
+
}, z2.number()).openapi({
|
|
41
621
|
title: "Number",
|
|
42
622
|
example: 123
|
|
43
623
|
});
|
|
44
|
-
bigint =
|
|
624
|
+
bigint = z2.preprocess((value) => {
|
|
45
625
|
try {
|
|
46
626
|
if (value instanceof Date) {
|
|
47
627
|
return BigInt(value.getTime());
|
|
@@ -58,23 +638,23 @@ var ZodSchemaValidator = class {
|
|
|
58
638
|
} catch {
|
|
59
639
|
return value;
|
|
60
640
|
}
|
|
61
|
-
},
|
|
641
|
+
}, z2.bigint()).openapi({
|
|
62
642
|
title: "BigInt",
|
|
63
643
|
type: "integer",
|
|
64
644
|
format: "int64",
|
|
65
645
|
example: 123n
|
|
66
646
|
});
|
|
67
|
-
boolean =
|
|
647
|
+
boolean = z2.preprocess((val) => {
|
|
68
648
|
if (typeof val === "string") {
|
|
69
649
|
if (val.toLowerCase() === "true") return true;
|
|
70
650
|
if (val.toLowerCase() === "false") return false;
|
|
71
651
|
}
|
|
72
652
|
return val;
|
|
73
|
-
},
|
|
653
|
+
}, z2.boolean()).openapi({
|
|
74
654
|
title: "Boolean",
|
|
75
655
|
example: true
|
|
76
656
|
});
|
|
77
|
-
date =
|
|
657
|
+
date = z2.preprocess((value) => {
|
|
78
658
|
try {
|
|
79
659
|
switch (typeof value) {
|
|
80
660
|
case "string":
|
|
@@ -87,58 +667,58 @@ var ZodSchemaValidator = class {
|
|
|
87
667
|
} catch {
|
|
88
668
|
return value;
|
|
89
669
|
}
|
|
90
|
-
},
|
|
670
|
+
}, z2.date()).openapi({
|
|
91
671
|
title: "Date",
|
|
92
672
|
type: "string",
|
|
93
673
|
format: "date-time",
|
|
94
674
|
example: "2025-05-16T21:13:04.123Z"
|
|
95
675
|
});
|
|
96
|
-
symbol =
|
|
676
|
+
symbol = z2.symbol().openapi({
|
|
97
677
|
title: "Symbol",
|
|
98
678
|
example: Symbol("symbol")
|
|
99
679
|
});
|
|
100
|
-
nullish =
|
|
680
|
+
nullish = z2.union([z2.void(), z2.null(), z2.undefined()]).openapi({
|
|
101
681
|
title: "Nullish",
|
|
102
682
|
type: "null",
|
|
103
683
|
example: null
|
|
104
684
|
});
|
|
105
|
-
void =
|
|
685
|
+
void = z2.void().openapi({
|
|
106
686
|
title: "Void",
|
|
107
687
|
type: "null",
|
|
108
688
|
example: void 0
|
|
109
689
|
});
|
|
110
|
-
null =
|
|
690
|
+
null = z2.null().openapi({
|
|
111
691
|
title: "Null",
|
|
112
692
|
type: "null",
|
|
113
693
|
example: null
|
|
114
694
|
});
|
|
115
|
-
undefined =
|
|
695
|
+
undefined = z2.undefined().openapi({
|
|
116
696
|
title: "Undefined",
|
|
117
697
|
type: "null",
|
|
118
698
|
example: void 0
|
|
119
699
|
});
|
|
120
|
-
any =
|
|
700
|
+
any = z2.any().openapi({
|
|
121
701
|
title: "Any",
|
|
122
702
|
type: "object",
|
|
123
703
|
example: "any"
|
|
124
704
|
});
|
|
125
|
-
unknown =
|
|
705
|
+
unknown = z2.unknown().openapi({
|
|
126
706
|
title: "Unknown",
|
|
127
707
|
type: "object",
|
|
128
708
|
example: "unknown"
|
|
129
709
|
});
|
|
130
|
-
never =
|
|
710
|
+
never = z2.never().openapi({
|
|
131
711
|
title: "Never",
|
|
132
712
|
type: "null",
|
|
133
713
|
example: "never"
|
|
134
714
|
});
|
|
135
|
-
binary =
|
|
715
|
+
binary = z2.string().transform((v) => new TextEncoder().encode(v)).openapi({
|
|
136
716
|
title: "Binary",
|
|
137
717
|
type: "string",
|
|
138
718
|
format: "binary",
|
|
139
719
|
example: "a utf-8 encodable string"
|
|
140
720
|
});
|
|
141
|
-
file =
|
|
721
|
+
file = z2.string().transform((val) => {
|
|
142
722
|
return new Blob([val]);
|
|
143
723
|
}).openapi({
|
|
144
724
|
title: "File",
|
|
@@ -163,7 +743,7 @@ var ZodSchemaValidator = class {
|
|
|
163
743
|
*/
|
|
164
744
|
schemify(schema) {
|
|
165
745
|
if (typeof schema === "string" || typeof schema === "number" || typeof schema === "boolean") {
|
|
166
|
-
return
|
|
746
|
+
return z2.literal(schema);
|
|
167
747
|
}
|
|
168
748
|
if (schema instanceof ZodType) {
|
|
169
749
|
return schema;
|
|
@@ -176,7 +756,7 @@ var ZodSchemaValidator = class {
|
|
|
176
756
|
newSchema[key] = this.schemify(schema[key]);
|
|
177
757
|
}
|
|
178
758
|
});
|
|
179
|
-
return
|
|
759
|
+
return z2.object(newSchema);
|
|
180
760
|
}
|
|
181
761
|
/**
|
|
182
762
|
* Make a schema optional.
|
|
@@ -203,7 +783,7 @@ var ZodSchemaValidator = class {
|
|
|
203
783
|
*/
|
|
204
784
|
union(schemas) {
|
|
205
785
|
const resolvedSchemas = schemas.map((schema) => this.schemify(schema));
|
|
206
|
-
return
|
|
786
|
+
return z2.union(
|
|
207
787
|
resolvedSchemas
|
|
208
788
|
);
|
|
209
789
|
}
|
|
@@ -213,7 +793,7 @@ var ZodSchemaValidator = class {
|
|
|
213
793
|
* @returns {ZodLiteral<ZodResolve<T>>} The literal schema.
|
|
214
794
|
*/
|
|
215
795
|
literal(value) {
|
|
216
|
-
return
|
|
796
|
+
return z2.literal(value);
|
|
217
797
|
}
|
|
218
798
|
/**
|
|
219
799
|
* Create an enum schema.
|
|
@@ -234,7 +814,7 @@ var ZodSchemaValidator = class {
|
|
|
234
814
|
function_(args, returnType) {
|
|
235
815
|
const schemaArgs = args.map((schema) => this.schemify(schema));
|
|
236
816
|
const schemaReturnType = this.schemify(returnType);
|
|
237
|
-
return
|
|
817
|
+
return z2.function(z2.tuple(schemaArgs), schemaReturnType);
|
|
238
818
|
}
|
|
239
819
|
/**
|
|
240
820
|
* Create a record schema.
|
|
@@ -245,7 +825,7 @@ var ZodSchemaValidator = class {
|
|
|
245
825
|
record(key, value) {
|
|
246
826
|
const keySchema = this.schemify(key);
|
|
247
827
|
const valueSchema = this.schemify(value);
|
|
248
|
-
return
|
|
828
|
+
return z2.record(keySchema, valueSchema);
|
|
249
829
|
}
|
|
250
830
|
/**
|
|
251
831
|
* Create a promise schema.
|
|
@@ -253,7 +833,7 @@ var ZodSchemaValidator = class {
|
|
|
253
833
|
* @returns {ZodPromise<ZodResolve<T>>} The promise schema.
|
|
254
834
|
*/
|
|
255
835
|
promise(schema) {
|
|
256
|
-
return
|
|
836
|
+
return z2.promise(this.schemify(schema));
|
|
257
837
|
}
|
|
258
838
|
/**
|
|
259
839
|
* Checks if a value is a Zod schema.
|