@orpc/zod 1.14.9 → 1.14.11
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 +52 -112
- package/dist/index.d.mts +251 -86
- package/dist/index.d.ts +251 -86
- package/dist/index.mjs +78 -849
- package/package.json +8 -17
- package/dist/zod4/index.d.mts +0 -314
- package/dist/zod4/index.d.ts +0 -314
- package/dist/zod4/index.mjs +0 -698
package/dist/index.mjs
CHANGED
|
@@ -1,870 +1,99 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import { isObject, guard, toArray } from '@orpc/shared';
|
|
4
|
-
import { JsonSchemaXNativeType } from '@orpc/json-schema';
|
|
5
|
-
import { JSONSchemaFormat } from '@orpc/openapi';
|
|
6
|
-
import escapeStringRegexp from 'escape-string-regexp';
|
|
1
|
+
import { JsonSchemaXNativeType, JsonSchemaFormat, encodeJsonPointerSegment } from '@orpc/json-schema';
|
|
2
|
+
import { registry, toJSONSchema, globalRegistry } from 'zod/v4/core';
|
|
7
3
|
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
function getCustomJsonSchema(def, options) {
|
|
12
|
-
if (options.strategy === "input" && CUSTOM_JSON_SCHEMA_INPUT_SYMBOL in def) {
|
|
13
|
-
return def[CUSTOM_JSON_SCHEMA_INPUT_SYMBOL];
|
|
14
|
-
}
|
|
15
|
-
if (options.strategy === "output" && CUSTOM_JSON_SCHEMA_OUTPUT_SYMBOL in def) {
|
|
16
|
-
return def[CUSTOM_JSON_SCHEMA_OUTPUT_SYMBOL];
|
|
17
|
-
}
|
|
18
|
-
if (CUSTOM_JSON_SCHEMA_SYMBOL in def) {
|
|
19
|
-
return def[CUSTOM_JSON_SCHEMA_SYMBOL];
|
|
20
|
-
}
|
|
21
|
-
return void 0;
|
|
22
|
-
}
|
|
23
|
-
function customJsonSchema(schema, custom, options = {}) {
|
|
24
|
-
const SYMBOL = options.strategy === "input" ? CUSTOM_JSON_SCHEMA_INPUT_SYMBOL : options.strategy === "output" ? CUSTOM_JSON_SCHEMA_OUTPUT_SYMBOL : CUSTOM_JSON_SCHEMA_SYMBOL;
|
|
25
|
-
const This = schema.constructor;
|
|
26
|
-
const newSchema = new This({
|
|
27
|
-
...schema._def,
|
|
28
|
-
[SYMBOL]: custom
|
|
29
|
-
});
|
|
30
|
-
return newSchema;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const CUSTOM_ZOD_DEF_SYMBOL = Symbol("ORPC_CUSTOM_ZOD_DEF");
|
|
34
|
-
function setCustomZodDef(def, custom) {
|
|
35
|
-
Object.assign(def, { [CUSTOM_ZOD_DEF_SYMBOL]: custom });
|
|
36
|
-
}
|
|
37
|
-
function getCustomZodDef(def) {
|
|
38
|
-
return def[CUSTOM_ZOD_DEF_SYMBOL];
|
|
39
|
-
}
|
|
40
|
-
function composeParams(defaultMessage, params) {
|
|
41
|
-
return (val) => {
|
|
42
|
-
const message = defaultMessage(val);
|
|
43
|
-
if (!params) {
|
|
44
|
-
return {
|
|
45
|
-
message
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
if (typeof params === "function") {
|
|
49
|
-
return {
|
|
50
|
-
message,
|
|
51
|
-
...params(val)
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
if (typeof params === "object") {
|
|
55
|
-
return {
|
|
56
|
-
message,
|
|
57
|
-
...params
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
message: params
|
|
62
|
-
};
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
function blob(params) {
|
|
67
|
-
const schema = custom(
|
|
68
|
-
(val) => val instanceof Blob,
|
|
69
|
-
composeParams(
|
|
70
|
-
() => "Input is not a blob",
|
|
71
|
-
params
|
|
72
|
-
)
|
|
73
|
-
);
|
|
74
|
-
setCustomZodDef(schema._def, { type: "blob" });
|
|
75
|
-
return schema;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function file(params) {
|
|
79
|
-
const schema = custom(
|
|
80
|
-
(val) => val instanceof File,
|
|
81
|
-
composeParams(
|
|
82
|
-
() => "Input is not a file",
|
|
83
|
-
params
|
|
84
|
-
)
|
|
85
|
-
);
|
|
86
|
-
setCustomZodDef(schema._def, { type: "file" });
|
|
87
|
-
return Object.assign(schema, {
|
|
88
|
-
type: (mimeType, params2) => {
|
|
89
|
-
const isMatch = wcmatch(mimeType);
|
|
90
|
-
const refinedSchema = schema.refine(
|
|
91
|
-
(val) => isMatch(val.type.split(";")[0]),
|
|
92
|
-
composeParams(
|
|
93
|
-
(val) => `Expected a file of type ${mimeType} but got a file of type ${val.type || "unknown"}`,
|
|
94
|
-
params2
|
|
95
|
-
)
|
|
96
|
-
);
|
|
97
|
-
setCustomZodDef(refinedSchema._def, { type: "file", mimeType });
|
|
98
|
-
return refinedSchema;
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function regexp(params) {
|
|
104
|
-
const schema = custom(
|
|
105
|
-
(val) => val instanceof RegExp,
|
|
106
|
-
composeParams(
|
|
107
|
-
() => "Input is not a regexp",
|
|
108
|
-
params
|
|
109
|
-
)
|
|
110
|
-
);
|
|
111
|
-
setCustomZodDef(schema._def, { type: "regexp" });
|
|
112
|
-
return schema;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function url(params) {
|
|
116
|
-
const schema = custom(
|
|
117
|
-
(val) => val instanceof URL,
|
|
118
|
-
composeParams(
|
|
119
|
-
() => "Input is not a URL",
|
|
120
|
-
params
|
|
121
|
-
)
|
|
122
|
-
);
|
|
123
|
-
setCustomZodDef(schema._def, { type: "url" });
|
|
124
|
-
return schema;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
class ZodSmartCoercionPlugin {
|
|
128
|
-
init(options) {
|
|
129
|
-
options.clientInterceptors ??= [];
|
|
130
|
-
options.clientInterceptors.unshift((options2) => {
|
|
131
|
-
const inputSchema = options2.procedure["~orpc"].inputSchema;
|
|
132
|
-
if (!inputSchema || inputSchema["~standard"].vendor !== "zod" || "_zod" in inputSchema) {
|
|
133
|
-
return options2.next();
|
|
134
|
-
}
|
|
135
|
-
const coercedInput = zodCoerceInternal(inputSchema, options2.input);
|
|
136
|
-
return options2.next({ ...options2, input: coercedInput });
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
function zodCoerceInternal(schema, value) {
|
|
141
|
-
const customZodDef = getCustomZodDef(schema._def);
|
|
142
|
-
switch (customZodDef?.type) {
|
|
143
|
-
case "regexp": {
|
|
144
|
-
if (typeof value === "string") {
|
|
145
|
-
return safeToRegExp(value);
|
|
146
|
-
}
|
|
147
|
-
return value;
|
|
148
|
-
}
|
|
149
|
-
case "url": {
|
|
150
|
-
if (typeof value === "string") {
|
|
151
|
-
return safeToURL(value);
|
|
152
|
-
}
|
|
153
|
-
return value;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
const typeName = schema._def.typeName;
|
|
157
|
-
switch (typeName) {
|
|
158
|
-
case ZodFirstPartyTypeKind.ZodNumber: {
|
|
159
|
-
if (typeof value === "string") {
|
|
160
|
-
return safeToNumber(value);
|
|
161
|
-
}
|
|
162
|
-
return value;
|
|
163
|
-
}
|
|
164
|
-
case ZodFirstPartyTypeKind.ZodBigInt: {
|
|
165
|
-
if (typeof value === "string") {
|
|
166
|
-
return safeToBigInt(value);
|
|
167
|
-
}
|
|
168
|
-
return value;
|
|
169
|
-
}
|
|
170
|
-
case ZodFirstPartyTypeKind.ZodBoolean: {
|
|
171
|
-
if (typeof value === "string") {
|
|
172
|
-
return safeToBoolean(value);
|
|
173
|
-
}
|
|
174
|
-
return value;
|
|
175
|
-
}
|
|
176
|
-
case ZodFirstPartyTypeKind.ZodDate: {
|
|
177
|
-
if (typeof value === "string") {
|
|
178
|
-
return safeToDate(value);
|
|
179
|
-
}
|
|
180
|
-
return value;
|
|
181
|
-
}
|
|
182
|
-
case ZodFirstPartyTypeKind.ZodLiteral: {
|
|
183
|
-
const schema_ = schema;
|
|
184
|
-
const expectedValue = schema_._def.value;
|
|
185
|
-
if (typeof value === "string" && typeof expectedValue !== "string") {
|
|
186
|
-
if (typeof expectedValue === "bigint") {
|
|
187
|
-
return safeToBigInt(value);
|
|
188
|
-
} else if (typeof expectedValue === "number") {
|
|
189
|
-
return safeToNumber(value);
|
|
190
|
-
} else if (typeof expectedValue === "boolean") {
|
|
191
|
-
return safeToBoolean(value);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return value;
|
|
195
|
-
}
|
|
196
|
-
case ZodFirstPartyTypeKind.ZodNativeEnum: {
|
|
197
|
-
const schema_ = schema;
|
|
198
|
-
if (Object.values(schema_._def.values).includes(value)) {
|
|
199
|
-
return value;
|
|
200
|
-
}
|
|
201
|
-
if (typeof value === "string") {
|
|
202
|
-
for (const expectedValue of Object.values(schema_._def.values)) {
|
|
203
|
-
if (expectedValue.toString() === value) {
|
|
204
|
-
return expectedValue;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
return value;
|
|
209
|
-
}
|
|
210
|
-
case ZodFirstPartyTypeKind.ZodObject: {
|
|
211
|
-
const schema_ = schema;
|
|
212
|
-
if (isObject(value)) {
|
|
213
|
-
const newObj = {};
|
|
214
|
-
const keys = /* @__PURE__ */ new Set([
|
|
215
|
-
...Object.keys(value),
|
|
216
|
-
...Object.keys(schema_.shape)
|
|
217
|
-
]);
|
|
218
|
-
for (const k of keys) {
|
|
219
|
-
newObj[k] = zodCoerceInternal(
|
|
220
|
-
schema_.shape[k] ?? schema_._def.catchall,
|
|
221
|
-
value[k]
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
return newObj;
|
|
225
|
-
}
|
|
226
|
-
return value;
|
|
227
|
-
}
|
|
228
|
-
case ZodFirstPartyTypeKind.ZodRecord: {
|
|
229
|
-
const schema_ = schema;
|
|
230
|
-
if (isObject(value)) {
|
|
231
|
-
const newObj = {};
|
|
232
|
-
for (const [k, v] of Object.entries(value)) {
|
|
233
|
-
const key = zodCoerceInternal(schema_._def.keyType, k);
|
|
234
|
-
const val = zodCoerceInternal(schema_._def.valueType, v);
|
|
235
|
-
newObj[key] = val;
|
|
236
|
-
}
|
|
237
|
-
return newObj;
|
|
238
|
-
}
|
|
239
|
-
return value;
|
|
240
|
-
}
|
|
241
|
-
case ZodFirstPartyTypeKind.ZodArray: {
|
|
242
|
-
const schema_ = schema;
|
|
243
|
-
if (Array.isArray(value)) {
|
|
244
|
-
return value.map((v) => zodCoerceInternal(schema_._def.type, v));
|
|
245
|
-
}
|
|
246
|
-
return value;
|
|
247
|
-
}
|
|
248
|
-
case ZodFirstPartyTypeKind.ZodTuple: {
|
|
249
|
-
const schema_ = schema;
|
|
250
|
-
if (Array.isArray(value)) {
|
|
251
|
-
return value.map((v, i) => {
|
|
252
|
-
const s = schema_._def.items[i] ?? schema_._def.rest;
|
|
253
|
-
return s ? zodCoerceInternal(s, v) : v;
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
return value;
|
|
257
|
-
}
|
|
258
|
-
case ZodFirstPartyTypeKind.ZodSet: {
|
|
259
|
-
const schema_ = schema;
|
|
260
|
-
if (Array.isArray(value)) {
|
|
261
|
-
return new Set(
|
|
262
|
-
value.map((v) => zodCoerceInternal(schema_._def.valueType, v))
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
return value;
|
|
266
|
-
}
|
|
267
|
-
case ZodFirstPartyTypeKind.ZodMap: {
|
|
268
|
-
const schema_ = schema;
|
|
269
|
-
if (Array.isArray(value) && value.every((i) => Array.isArray(i) && i.length === 2)) {
|
|
270
|
-
return new Map(
|
|
271
|
-
value.map(([k, v]) => [
|
|
272
|
-
zodCoerceInternal(schema_._def.keyType, k),
|
|
273
|
-
zodCoerceInternal(schema_._def.valueType, v)
|
|
274
|
-
])
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
return value;
|
|
278
|
-
}
|
|
279
|
-
case ZodFirstPartyTypeKind.ZodUnion:
|
|
280
|
-
case ZodFirstPartyTypeKind.ZodDiscriminatedUnion: {
|
|
281
|
-
const schema_ = schema;
|
|
282
|
-
if (schema_.safeParse(value).success) {
|
|
283
|
-
return value;
|
|
284
|
-
}
|
|
285
|
-
const results = [];
|
|
286
|
-
for (const s of schema_._def.options) {
|
|
287
|
-
const newValue = zodCoerceInternal(s, value);
|
|
288
|
-
const result = schema_.safeParse(newValue);
|
|
289
|
-
if (result.success) {
|
|
290
|
-
return newValue;
|
|
291
|
-
}
|
|
292
|
-
results.push([newValue, result.error.issues.length]);
|
|
293
|
-
}
|
|
294
|
-
if (results.length === 0) {
|
|
295
|
-
return value;
|
|
296
|
-
}
|
|
297
|
-
return results.sort((a, b) => a[1] - b[1])[0][0];
|
|
298
|
-
}
|
|
299
|
-
case ZodFirstPartyTypeKind.ZodIntersection: {
|
|
300
|
-
const schema_ = schema;
|
|
301
|
-
return zodCoerceInternal(
|
|
302
|
-
schema_._def.right,
|
|
303
|
-
zodCoerceInternal(schema_._def.left, value)
|
|
304
|
-
);
|
|
305
|
-
}
|
|
306
|
-
case ZodFirstPartyTypeKind.ZodReadonly: {
|
|
307
|
-
const schema_ = schema;
|
|
308
|
-
return zodCoerceInternal(schema_._def.innerType, value);
|
|
309
|
-
}
|
|
310
|
-
case ZodFirstPartyTypeKind.ZodPipeline: {
|
|
311
|
-
const schema_ = schema;
|
|
312
|
-
return zodCoerceInternal(schema_._def.in, value);
|
|
313
|
-
}
|
|
314
|
-
case ZodFirstPartyTypeKind.ZodEffects: {
|
|
315
|
-
const schema_ = schema;
|
|
316
|
-
return zodCoerceInternal(schema_._def.schema, value);
|
|
317
|
-
}
|
|
318
|
-
case ZodFirstPartyTypeKind.ZodBranded: {
|
|
319
|
-
const schema_ = schema;
|
|
320
|
-
return zodCoerceInternal(schema_._def.type, value);
|
|
321
|
-
}
|
|
322
|
-
case ZodFirstPartyTypeKind.ZodCatch: {
|
|
323
|
-
const schema_ = schema;
|
|
324
|
-
return zodCoerceInternal(schema_._def.innerType, value);
|
|
325
|
-
}
|
|
326
|
-
case ZodFirstPartyTypeKind.ZodDefault: {
|
|
327
|
-
const schema_ = schema;
|
|
328
|
-
return zodCoerceInternal(schema_._def.innerType, value);
|
|
329
|
-
}
|
|
330
|
-
case ZodFirstPartyTypeKind.ZodNullable: {
|
|
331
|
-
if (value === null) {
|
|
332
|
-
return null;
|
|
333
|
-
}
|
|
334
|
-
const schema_ = schema;
|
|
335
|
-
return zodCoerceInternal(schema_._def.innerType, value);
|
|
336
|
-
}
|
|
337
|
-
case ZodFirstPartyTypeKind.ZodOptional: {
|
|
338
|
-
if (value === void 0) {
|
|
339
|
-
return void 0;
|
|
340
|
-
}
|
|
341
|
-
const schema_ = schema;
|
|
342
|
-
return zodCoerceInternal(schema_._def.innerType, value);
|
|
343
|
-
}
|
|
344
|
-
case ZodFirstPartyTypeKind.ZodLazy: {
|
|
345
|
-
const schema_ = schema;
|
|
346
|
-
if (value !== void 0) {
|
|
347
|
-
return zodCoerceInternal(schema_._def.getter(), value);
|
|
348
|
-
}
|
|
349
|
-
return value;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return value;
|
|
353
|
-
}
|
|
354
|
-
function safeToBigInt(value) {
|
|
355
|
-
return guard(() => BigInt(value)) ?? value;
|
|
356
|
-
}
|
|
357
|
-
function safeToNumber(value) {
|
|
358
|
-
const num = Number(value);
|
|
359
|
-
return Number.isNaN(num) || num.toString() !== value ? value : num;
|
|
360
|
-
}
|
|
361
|
-
function safeToBoolean(value) {
|
|
362
|
-
const lower = value.toLowerCase();
|
|
363
|
-
if (lower === "false" || lower === "off" || lower === "f") {
|
|
364
|
-
return false;
|
|
365
|
-
}
|
|
366
|
-
if (lower === "true" || lower === "on" || lower === "t") {
|
|
367
|
-
return true;
|
|
368
|
-
}
|
|
369
|
-
return value;
|
|
370
|
-
}
|
|
371
|
-
function safeToRegExp(value) {
|
|
372
|
-
if (value.startsWith("/")) {
|
|
373
|
-
const match = value.match(/^\/(.*)\/([a-z]*)$/);
|
|
374
|
-
if (match) {
|
|
375
|
-
const [, pattern, flags] = match;
|
|
376
|
-
return new RegExp(pattern, flags);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return value;
|
|
380
|
-
}
|
|
381
|
-
function safeToURL(value) {
|
|
382
|
-
return guard(() => new URL(value)) ?? value;
|
|
383
|
-
}
|
|
384
|
-
function safeToDate(value) {
|
|
385
|
-
const date = new Date(value);
|
|
386
|
-
if (!Number.isNaN(date.getTime()) && date.toISOString().startsWith(value)) {
|
|
387
|
-
return date;
|
|
388
|
-
}
|
|
389
|
-
return value;
|
|
390
|
-
}
|
|
4
|
+
const JSON_SCHEMA_REGISTRY = registry();
|
|
5
|
+
const JSON_SCHEMA_INPUT_REGISTRY = registry();
|
|
6
|
+
const JSON_SCHEMA_OUTPUT_REGISTRY = registry();
|
|
391
7
|
|
|
392
8
|
class ZodToJsonSchemaConverter {
|
|
393
|
-
maxLazyDepth;
|
|
394
|
-
maxStructureDepth;
|
|
395
|
-
unsupportedJsonSchema;
|
|
396
|
-
anyJsonSchema;
|
|
397
9
|
constructor(options = {}) {
|
|
398
|
-
this.
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
);
|
|
441
|
-
return [required, { ...json, ...customJSONSchema }];
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
const customSchema = this.#handleCustomZodDef(def);
|
|
445
|
-
if (customSchema) {
|
|
446
|
-
return [true, customSchema];
|
|
447
|
-
}
|
|
448
|
-
const typeName = this.#getZodTypeName(def);
|
|
449
|
-
switch (typeName) {
|
|
450
|
-
case ZodFirstPartyTypeKind.ZodString: {
|
|
451
|
-
const schema_ = schema;
|
|
452
|
-
const json = { type: "string" };
|
|
453
|
-
for (const check of schema_._def.checks) {
|
|
454
|
-
switch (check.kind) {
|
|
455
|
-
case "base64":
|
|
456
|
-
json.contentEncoding = "base64";
|
|
457
|
-
break;
|
|
458
|
-
case "cuid":
|
|
459
|
-
json.pattern = "^[0-9A-HJKMNP-TV-Z]{26}$";
|
|
460
|
-
break;
|
|
461
|
-
case "email":
|
|
462
|
-
json.format = JSONSchemaFormat.Email;
|
|
463
|
-
break;
|
|
464
|
-
case "url":
|
|
465
|
-
json.format = JSONSchemaFormat.URI;
|
|
466
|
-
break;
|
|
467
|
-
case "uuid":
|
|
468
|
-
json.format = JSONSchemaFormat.UUID;
|
|
469
|
-
break;
|
|
470
|
-
case "regex":
|
|
471
|
-
json.pattern = check.regex.source;
|
|
472
|
-
break;
|
|
473
|
-
case "min":
|
|
474
|
-
json.minLength = check.value;
|
|
475
|
-
break;
|
|
476
|
-
case "max":
|
|
477
|
-
json.maxLength = check.value;
|
|
478
|
-
break;
|
|
479
|
-
case "length":
|
|
480
|
-
json.minLength = check.value;
|
|
481
|
-
json.maxLength = check.value;
|
|
482
|
-
break;
|
|
483
|
-
case "includes":
|
|
484
|
-
json.pattern = escapeStringRegexp(check.value);
|
|
485
|
-
break;
|
|
486
|
-
case "startsWith":
|
|
487
|
-
json.pattern = `^${escapeStringRegexp(check.value)}`;
|
|
488
|
-
break;
|
|
489
|
-
case "endsWith":
|
|
490
|
-
json.pattern = `${escapeStringRegexp(check.value)}$`;
|
|
491
|
-
break;
|
|
492
|
-
case "emoji":
|
|
493
|
-
json.pattern = "^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";
|
|
494
|
-
break;
|
|
495
|
-
case "nanoid":
|
|
496
|
-
json.pattern = "^[a-zA-Z0-9_-]{21}$";
|
|
497
|
-
break;
|
|
498
|
-
case "cuid2":
|
|
499
|
-
json.pattern = "^[0-9a-z]+$";
|
|
500
|
-
break;
|
|
501
|
-
case "ulid":
|
|
502
|
-
json.pattern = "^[0-9A-HJKMNP-TV-Z]{26}$";
|
|
503
|
-
break;
|
|
504
|
-
case "datetime":
|
|
505
|
-
json.format = JSONSchemaFormat.DateTime;
|
|
506
|
-
break;
|
|
507
|
-
case "date":
|
|
508
|
-
json.format = JSONSchemaFormat.Date;
|
|
509
|
-
break;
|
|
510
|
-
case "time":
|
|
511
|
-
json.format = JSONSchemaFormat.Time;
|
|
512
|
-
break;
|
|
513
|
-
case "duration":
|
|
514
|
-
json.format = JSONSchemaFormat.Duration;
|
|
515
|
-
break;
|
|
516
|
-
case "ip": {
|
|
517
|
-
if (check.version === "v4") {
|
|
518
|
-
json.format = JSONSchemaFormat.IPv4;
|
|
519
|
-
} else if (check.version === "v6") {
|
|
520
|
-
json.format = JSONSchemaFormat.IPv6;
|
|
521
|
-
} else {
|
|
522
|
-
json.anyOf = [
|
|
523
|
-
{ format: JSONSchemaFormat.IPv4 },
|
|
524
|
-
{ format: JSONSchemaFormat.IPv6 }
|
|
525
|
-
];
|
|
526
|
-
}
|
|
527
|
-
break;
|
|
528
|
-
}
|
|
529
|
-
case "jwt":
|
|
530
|
-
json.pattern = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*$";
|
|
531
|
-
break;
|
|
532
|
-
case "base64url":
|
|
533
|
-
json.pattern = "^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$";
|
|
534
|
-
break;
|
|
535
|
-
default: {
|
|
536
|
-
check.kind;
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
|
-
return [true, json];
|
|
541
|
-
}
|
|
542
|
-
case ZodFirstPartyTypeKind.ZodNumber: {
|
|
543
|
-
const schema_ = schema;
|
|
544
|
-
const json = { type: "number" };
|
|
545
|
-
for (const check of schema_._def.checks) {
|
|
546
|
-
switch (check.kind) {
|
|
547
|
-
case "int":
|
|
548
|
-
json.type = "integer";
|
|
549
|
-
break;
|
|
550
|
-
case "min":
|
|
551
|
-
json.minimum = check.value;
|
|
552
|
-
break;
|
|
553
|
-
case "max":
|
|
554
|
-
json.maximum = check.value;
|
|
555
|
-
break;
|
|
556
|
-
case "multipleOf":
|
|
557
|
-
json.multipleOf = check.value;
|
|
558
|
-
break;
|
|
559
|
-
default: {
|
|
560
|
-
check.kind;
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
return [true, json];
|
|
565
|
-
}
|
|
566
|
-
case ZodFirstPartyTypeKind.ZodBigInt: {
|
|
567
|
-
const json = {
|
|
568
|
-
"type": "string",
|
|
569
|
-
"pattern": "^-?[0-9]+$",
|
|
570
|
-
"x-native-type": JsonSchemaXNativeType.BigInt
|
|
571
|
-
};
|
|
572
|
-
return [true, json];
|
|
573
|
-
}
|
|
574
|
-
case ZodFirstPartyTypeKind.ZodNaN: {
|
|
575
|
-
return options.strategy === "input" ? [true, this.unsupportedJsonSchema] : [true, { type: "null" }];
|
|
576
|
-
}
|
|
577
|
-
case ZodFirstPartyTypeKind.ZodBoolean: {
|
|
578
|
-
return [true, { type: "boolean" }];
|
|
579
|
-
}
|
|
580
|
-
case ZodFirstPartyTypeKind.ZodDate: {
|
|
581
|
-
const schema2 = {
|
|
582
|
-
"type": "string",
|
|
583
|
-
"format": JSONSchemaFormat.DateTime,
|
|
584
|
-
"x-native-type": JsonSchemaXNativeType.Date
|
|
585
|
-
};
|
|
586
|
-
return [true, schema2];
|
|
587
|
-
}
|
|
588
|
-
case ZodFirstPartyTypeKind.ZodNull: {
|
|
589
|
-
return [true, { type: "null" }];
|
|
590
|
-
}
|
|
591
|
-
case ZodFirstPartyTypeKind.ZodLiteral: {
|
|
592
|
-
const schema_ = schema;
|
|
593
|
-
if (schema_._def.value === void 0) {
|
|
594
|
-
return [false, this.unsupportedJsonSchema];
|
|
595
|
-
}
|
|
596
|
-
return [true, { const: schema_._def.value }];
|
|
597
|
-
}
|
|
598
|
-
case ZodFirstPartyTypeKind.ZodVoid:
|
|
599
|
-
case ZodFirstPartyTypeKind.ZodUndefined: {
|
|
600
|
-
return [false, this.unsupportedJsonSchema];
|
|
601
|
-
}
|
|
602
|
-
case ZodFirstPartyTypeKind.ZodUnknown:
|
|
603
|
-
case ZodFirstPartyTypeKind.ZodAny: {
|
|
604
|
-
return [false, this.anyJsonSchema];
|
|
605
|
-
}
|
|
606
|
-
case ZodFirstPartyTypeKind.ZodEnum: {
|
|
607
|
-
const schema_ = schema;
|
|
608
|
-
const values = schema_._def.values;
|
|
609
|
-
const json = { enum: values, type: "string" };
|
|
610
|
-
return [true, json];
|
|
611
|
-
}
|
|
612
|
-
case ZodFirstPartyTypeKind.ZodNativeEnum: {
|
|
613
|
-
const schema_ = schema;
|
|
614
|
-
const values = getEnumValues(schema_._def.values);
|
|
615
|
-
const json = { enum: values };
|
|
616
|
-
if (values.every((v) => typeof v === "string")) {
|
|
617
|
-
json.type = "string";
|
|
618
|
-
} else if (values.every((v) => Number.isFinite(v))) {
|
|
619
|
-
json.type = "number";
|
|
620
|
-
}
|
|
621
|
-
return [true, json];
|
|
622
|
-
}
|
|
623
|
-
case ZodFirstPartyTypeKind.ZodArray: {
|
|
624
|
-
const schema_ = schema;
|
|
625
|
-
const def2 = schema_._def;
|
|
626
|
-
const json = { type: "array" };
|
|
627
|
-
const [itemRequired, itemJson] = this.convert(def2.type, options, lazyDepth, false, false, structureDepth + 1);
|
|
628
|
-
json.items = this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy);
|
|
629
|
-
if (def2.exactLength) {
|
|
630
|
-
json.maxItems = def2.exactLength.value;
|
|
631
|
-
json.minItems = def2.exactLength.value;
|
|
632
|
-
}
|
|
633
|
-
if (def2.minLength) {
|
|
634
|
-
json.minItems = def2.minLength.value;
|
|
635
|
-
}
|
|
636
|
-
if (def2.maxLength) {
|
|
637
|
-
json.maxItems = def2.maxLength.value;
|
|
638
|
-
}
|
|
639
|
-
return [true, json];
|
|
640
|
-
}
|
|
641
|
-
case ZodFirstPartyTypeKind.ZodTuple: {
|
|
642
|
-
const schema_ = schema;
|
|
643
|
-
const prefixItems = [];
|
|
644
|
-
const json = { type: "array" };
|
|
645
|
-
for (const item of schema_._def.items) {
|
|
646
|
-
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false, structureDepth + 1);
|
|
647
|
-
prefixItems.push(
|
|
648
|
-
this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy)
|
|
649
|
-
);
|
|
650
|
-
}
|
|
651
|
-
if (prefixItems?.length) {
|
|
652
|
-
json.prefixItems = prefixItems;
|
|
653
|
-
}
|
|
654
|
-
if (schema_._def.rest) {
|
|
655
|
-
const [itemRequired, itemJson] = this.convert(schema_._def.rest, options, lazyDepth, false, false, structureDepth + 1);
|
|
656
|
-
json.items = this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy);
|
|
657
|
-
}
|
|
658
|
-
return [true, json];
|
|
659
|
-
}
|
|
660
|
-
case ZodFirstPartyTypeKind.ZodObject: {
|
|
661
|
-
const schema_ = schema;
|
|
662
|
-
const json = { type: "object" };
|
|
663
|
-
const properties = {};
|
|
664
|
-
const required = [];
|
|
665
|
-
for (const [key, value] of Object.entries(schema_.shape)) {
|
|
666
|
-
const [itemRequired, itemJson] = this.convert(value, options, lazyDepth, false, false, structureDepth + 1);
|
|
667
|
-
properties[key] = itemJson;
|
|
668
|
-
if (itemRequired) {
|
|
669
|
-
required.push(key);
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
if (Object.keys(properties).length) {
|
|
673
|
-
json.properties = properties;
|
|
674
|
-
}
|
|
675
|
-
if (required.length) {
|
|
676
|
-
json.required = required;
|
|
677
|
-
}
|
|
678
|
-
const catchAllTypeName = this.#getZodTypeName(schema_._def.catchall._def);
|
|
679
|
-
if (catchAllTypeName === ZodFirstPartyTypeKind.ZodNever) {
|
|
680
|
-
if (schema_._def.unknownKeys === "strict") {
|
|
681
|
-
json.additionalProperties = false;
|
|
682
|
-
}
|
|
683
|
-
} else {
|
|
684
|
-
const [_, addJson] = this.convert(schema_._def.catchall, options, lazyDepth, false, false, structureDepth + 1);
|
|
685
|
-
json.additionalProperties = addJson;
|
|
686
|
-
}
|
|
687
|
-
return [true, json];
|
|
688
|
-
}
|
|
689
|
-
case ZodFirstPartyTypeKind.ZodRecord: {
|
|
690
|
-
const schema_ = schema;
|
|
691
|
-
const json = { type: "object" };
|
|
692
|
-
const [__, keyJson] = this.convert(schema_._def.keyType, options, lazyDepth, false, false, structureDepth + 1);
|
|
693
|
-
if (Object.entries(keyJson).some(([k, v]) => k !== "type" || v !== "string")) {
|
|
694
|
-
json.propertyNames = keyJson;
|
|
695
|
-
}
|
|
696
|
-
const [_, itemJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false, structureDepth + 1);
|
|
697
|
-
json.additionalProperties = itemJson;
|
|
698
|
-
return [true, json];
|
|
699
|
-
}
|
|
700
|
-
case ZodFirstPartyTypeKind.ZodSet: {
|
|
701
|
-
const schema_ = schema;
|
|
702
|
-
const json = {
|
|
703
|
-
"type": "array",
|
|
704
|
-
"uniqueItems": true,
|
|
705
|
-
"x-native-type": JsonSchemaXNativeType.Set
|
|
706
|
-
};
|
|
707
|
-
const [itemRequired, itemJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false, structureDepth + 1);
|
|
708
|
-
json.items = this.#toArrayItemJsonSchema(itemRequired, itemJson, options.strategy);
|
|
709
|
-
return [true, json];
|
|
710
|
-
}
|
|
711
|
-
case ZodFirstPartyTypeKind.ZodMap: {
|
|
712
|
-
const schema_ = schema;
|
|
713
|
-
const [keyRequired, keyJson] = this.convert(schema_._def.keyType, options, lazyDepth, false, false, structureDepth + 1);
|
|
714
|
-
const [valueRequired, valueJson] = this.convert(schema_._def.valueType, options, lazyDepth, false, false, structureDepth + 1);
|
|
715
|
-
const json = {
|
|
716
|
-
"type": "array",
|
|
717
|
-
"items": {
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
condition(schema, _direction) {
|
|
13
|
+
return schema?.["~standard"].vendor === "zod";
|
|
14
|
+
}
|
|
15
|
+
convert(schema, direction) {
|
|
16
|
+
const zodSchema = schema;
|
|
17
|
+
const jsonSchema = this.convertZod(zodSchema, direction);
|
|
18
|
+
let optional = false;
|
|
19
|
+
try {
|
|
20
|
+
const result = zodSchema["~standard"].validate(void 0);
|
|
21
|
+
if (!(result instanceof Promise) && !result.issues) {
|
|
22
|
+
optional = direction === "input" ? true : result.value === void 0;
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
return [jsonSchema, optional];
|
|
27
|
+
}
|
|
28
|
+
convertZod(schema, direction) {
|
|
29
|
+
const jsonSchema = toJSONSchema(schema, {
|
|
30
|
+
unrepresentable: "any",
|
|
31
|
+
...this.options,
|
|
32
|
+
target: "draft-2020-12",
|
|
33
|
+
io: direction,
|
|
34
|
+
override: (ctx) => {
|
|
35
|
+
const def = ctx.zodSchema._zod.def;
|
|
36
|
+
if (def.type === "bigint") {
|
|
37
|
+
ctx.jsonSchema.type = "string";
|
|
38
|
+
ctx.jsonSchema.pattern = "^-?[0-9]+$";
|
|
39
|
+
ctx.jsonSchema["x-native-type"] = JsonSchemaXNativeType.BigInt;
|
|
40
|
+
} else if (def.type === "date") {
|
|
41
|
+
ctx.jsonSchema.type = "string";
|
|
42
|
+
ctx.jsonSchema.format = JsonSchemaFormat.DateTime;
|
|
43
|
+
ctx.jsonSchema["x-native-type"] = JsonSchemaXNativeType.Date;
|
|
44
|
+
} else if (def.type === "set") {
|
|
45
|
+
ctx.jsonSchema.type = "array";
|
|
46
|
+
ctx.jsonSchema.uniqueItems = true;
|
|
47
|
+
ctx.jsonSchema.items = this.convertZod(def.valueType, direction);
|
|
48
|
+
ctx.jsonSchema["x-native-type"] = JsonSchemaXNativeType.Set;
|
|
49
|
+
} else if (def.type === "map") {
|
|
50
|
+
ctx.jsonSchema.type = "array";
|
|
51
|
+
ctx.jsonSchema.items = {
|
|
718
52
|
type: "array",
|
|
719
53
|
prefixItems: [
|
|
720
|
-
this
|
|
721
|
-
this
|
|
54
|
+
this.convertZod(def.keyType, direction),
|
|
55
|
+
this.convertZod(def.valueType, direction)
|
|
722
56
|
],
|
|
723
57
|
maxItems: 2,
|
|
724
58
|
minItems: 2
|
|
725
|
-
}
|
|
726
|
-
"x-native-type"
|
|
727
|
-
};
|
|
728
|
-
return [true, json];
|
|
729
|
-
}
|
|
730
|
-
case ZodFirstPartyTypeKind.ZodUnion:
|
|
731
|
-
case ZodFirstPartyTypeKind.ZodDiscriminatedUnion: {
|
|
732
|
-
const schema_ = schema;
|
|
733
|
-
const anyOf = [];
|
|
734
|
-
let required = true;
|
|
735
|
-
for (const item of schema_._def.options) {
|
|
736
|
-
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false, structureDepth + 1);
|
|
737
|
-
if (!itemRequired) {
|
|
738
|
-
required = false;
|
|
739
|
-
if (itemJson !== this.unsupportedJsonSchema) {
|
|
740
|
-
anyOf.push(itemJson);
|
|
741
|
-
}
|
|
742
|
-
} else {
|
|
743
|
-
anyOf.push(itemJson);
|
|
744
|
-
}
|
|
59
|
+
};
|
|
60
|
+
ctx.jsonSchema["x-native-type"] = JsonSchemaXNativeType.Map;
|
|
745
61
|
}
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
const schema_ = schema;
|
|
750
|
-
const allOf = [];
|
|
751
|
-
let required = false;
|
|
752
|
-
for (const item of [schema_._def.left, schema_._def.right]) {
|
|
753
|
-
const [itemRequired, itemJson] = this.convert(item, options, lazyDepth, false, false, structureDepth + 1);
|
|
754
|
-
allOf.push(itemJson);
|
|
755
|
-
if (itemRequired) {
|
|
756
|
-
required = true;
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
return [required, { allOf }];
|
|
760
|
-
}
|
|
761
|
-
case ZodFirstPartyTypeKind.ZodLazy: {
|
|
762
|
-
const currentLazyDepth = lazyDepth + 1;
|
|
763
|
-
if (currentLazyDepth > this.maxLazyDepth) {
|
|
764
|
-
return [false, this.anyJsonSchema];
|
|
62
|
+
const customJsonSchema = this.getCustomJsonSchema(ctx.zodSchema, direction);
|
|
63
|
+
if (customJsonSchema) {
|
|
64
|
+
Object.assign(ctx.jsonSchema, customJsonSchema);
|
|
765
65
|
}
|
|
766
|
-
|
|
767
|
-
return this.convert(schema_._def.getter(), options, currentLazyDepth, false, false, structureDepth);
|
|
66
|
+
this.options.override?.(ctx);
|
|
768
67
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
case ZodFirstPartyTypeKind.ZodDefault: {
|
|
780
|
-
const schema_ = schema;
|
|
781
|
-
const [_, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
|
782
|
-
return [false, { default: schema_._def.defaultValue(), ...json }];
|
|
68
|
+
});
|
|
69
|
+
const { $schema, ...rest } = jsonSchema;
|
|
70
|
+
const registry = this.options.metadata ?? globalRegistry;
|
|
71
|
+
const { id } = registry.get(schema) || {};
|
|
72
|
+
if (typeof id === "string" && rest.$ref === void 0) {
|
|
73
|
+
const { $defs = {}, ...restWithoutDefs } = rest;
|
|
74
|
+
let defName = id;
|
|
75
|
+
let index = 0;
|
|
76
|
+
while (defName in $defs) {
|
|
77
|
+
defName = `${defName}__${index++}`;
|
|
783
78
|
}
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
79
|
+
return {
|
|
80
|
+
$ref: `#/$defs/${encodeJsonPointerSegment(defName)}`,
|
|
81
|
+
$defs: {
|
|
82
|
+
...$defs,
|
|
83
|
+
[defName]: restWithoutDefs
|
|
788
84
|
}
|
|
789
|
-
|
|
790
|
-
}
|
|
791
|
-
case ZodFirstPartyTypeKind.ZodCatch: {
|
|
792
|
-
const schema_ = schema;
|
|
793
|
-
return this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
|
794
|
-
}
|
|
795
|
-
case ZodFirstPartyTypeKind.ZodBranded: {
|
|
796
|
-
const schema_ = schema;
|
|
797
|
-
return this.convert(schema_._def.type, options, lazyDepth, false, false, structureDepth);
|
|
798
|
-
}
|
|
799
|
-
case ZodFirstPartyTypeKind.ZodPipeline: {
|
|
800
|
-
const schema_ = schema;
|
|
801
|
-
return this.convert(
|
|
802
|
-
options.strategy === "input" ? schema_._def.in : schema_._def.out,
|
|
803
|
-
options,
|
|
804
|
-
lazyDepth,
|
|
805
|
-
false,
|
|
806
|
-
false,
|
|
807
|
-
structureDepth
|
|
808
|
-
);
|
|
809
|
-
}
|
|
810
|
-
case ZodFirstPartyTypeKind.ZodNullable: {
|
|
811
|
-
const schema_ = schema;
|
|
812
|
-
const [required, json] = this.convert(schema_._def.innerType, options, lazyDepth, false, false, structureDepth);
|
|
813
|
-
return [required, { anyOf: [json, { type: "null" }] }];
|
|
814
|
-
}
|
|
85
|
+
};
|
|
815
86
|
}
|
|
816
|
-
return
|
|
87
|
+
return rest;
|
|
817
88
|
}
|
|
818
|
-
|
|
819
|
-
const
|
|
820
|
-
|
|
89
|
+
getCustomJsonSchema(schema, direction) {
|
|
90
|
+
const general = JSON_SCHEMA_REGISTRY.get(schema);
|
|
91
|
+
const directional = direction === "input" ? JSON_SCHEMA_INPUT_REGISTRY.get(schema) : JSON_SCHEMA_OUTPUT_REGISTRY.get(schema);
|
|
92
|
+
if (general === void 0 && directional === void 0) {
|
|
821
93
|
return void 0;
|
|
822
94
|
}
|
|
823
|
-
|
|
824
|
-
case "blob": {
|
|
825
|
-
return { type: "string", contentMediaType: "*/*" };
|
|
826
|
-
}
|
|
827
|
-
case "file": {
|
|
828
|
-
return { type: "string", contentMediaType: customZodDef.mimeType ?? "*/*" };
|
|
829
|
-
}
|
|
830
|
-
case "regexp": {
|
|
831
|
-
return {
|
|
832
|
-
"type": "string",
|
|
833
|
-
"pattern": "^\\/(.*)\\/([a-z]*)$",
|
|
834
|
-
"x-native-type": JsonSchemaXNativeType.RegExp
|
|
835
|
-
};
|
|
836
|
-
}
|
|
837
|
-
case "url": {
|
|
838
|
-
return {
|
|
839
|
-
"type": "string",
|
|
840
|
-
"format": JSONSchemaFormat.URI,
|
|
841
|
-
"x-native-type": JsonSchemaXNativeType.Url
|
|
842
|
-
};
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
#getZodTypeName(def) {
|
|
847
|
-
return def.typeName;
|
|
848
|
-
}
|
|
849
|
-
#toArrayItemJsonSchema(required, schema, strategy) {
|
|
850
|
-
if (required) {
|
|
851
|
-
return schema;
|
|
852
|
-
}
|
|
853
|
-
return strategy === "input" ? { anyOf: [schema, this.unsupportedJsonSchema] } : { anyOf: [schema, { type: "null" }] };
|
|
95
|
+
return { ...general, ...directional };
|
|
854
96
|
}
|
|
855
97
|
}
|
|
856
|
-
function getEnumValues(entries) {
|
|
857
|
-
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
858
|
-
const values = Object.entries(entries).filter(([k, _]) => !numericValues.includes(+k)).map(([_, v]) => v);
|
|
859
|
-
return values;
|
|
860
|
-
}
|
|
861
|
-
|
|
862
|
-
const oz = {
|
|
863
|
-
file,
|
|
864
|
-
blob,
|
|
865
|
-
url,
|
|
866
|
-
regexp,
|
|
867
|
-
openapi: customJsonSchema
|
|
868
|
-
};
|
|
869
98
|
|
|
870
|
-
export {
|
|
99
|
+
export { JSON_SCHEMA_INPUT_REGISTRY, JSON_SCHEMA_OUTPUT_REGISTRY, JSON_SCHEMA_REGISTRY, ZodToJsonSchemaConverter };
|