@orpc/zod 0.0.0-next.775667a → 0.0.0-next.77e421e
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 +135 -21
- package/dist/index.d.mts +16 -7
- package/dist/index.d.ts +16 -7
- package/dist/index.mjs +94 -46
- package/dist/zod4/index.d.mts +30 -18
- package/dist/zod4/index.d.ts +30 -18
- package/dist/zod4/index.mjs +162 -117
- package/package.json +11 -24
package/dist/zod4/index.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { isObject, guard, intercept } from '@orpc/shared';
|
|
1
|
+
import { isObject, guard, intercept, toArray } from '@orpc/shared';
|
|
2
|
+
import { JsonSchemaXNativeType } from '@orpc/json-schema';
|
|
2
3
|
import { JSONSchemaFormat, JSONSchemaContentEncoding } from '@orpc/openapi';
|
|
3
|
-
import { registry, globalRegistry } from '
|
|
4
|
+
import { registry, globalRegistry } from 'zod/v4/core';
|
|
4
5
|
|
|
5
6
|
class experimental_ZodSmartCoercionPlugin {
|
|
6
7
|
init(options) {
|
|
7
8
|
options.clientInterceptors ??= [];
|
|
8
9
|
options.clientInterceptors.unshift((options2) => {
|
|
9
10
|
const inputSchema = options2.procedure["~orpc"].inputSchema;
|
|
10
|
-
if (!inputSchema || inputSchema["~standard"].vendor !== "zod") {
|
|
11
|
+
if (!inputSchema || inputSchema["~standard"].vendor !== "zod" || !("_zod" in inputSchema)) {
|
|
11
12
|
return options2.next();
|
|
12
13
|
}
|
|
13
14
|
const coercedInput = this.#coerce(inputSchema, options2.input);
|
|
@@ -100,8 +101,7 @@ class experimental_ZodSmartCoercionPlugin {
|
|
|
100
101
|
}
|
|
101
102
|
return value;
|
|
102
103
|
}
|
|
103
|
-
case "object":
|
|
104
|
-
case "interface": {
|
|
104
|
+
case "object": {
|
|
105
105
|
const object = schema;
|
|
106
106
|
if (value === void 0) {
|
|
107
107
|
return {};
|
|
@@ -165,9 +165,21 @@ class experimental_ZodSmartCoercionPlugin {
|
|
|
165
165
|
return this.#coerce(union._zod.def.options[0], value);
|
|
166
166
|
}
|
|
167
167
|
if (isObject(value)) {
|
|
168
|
+
const discriminator = "discriminator" in union._zod.def && typeof union._zod.def.discriminator === "string" ? union._zod.def.discriminator : void 0;
|
|
168
169
|
for (const option of union._zod.def.options) {
|
|
169
|
-
if (option._zod.
|
|
170
|
-
|
|
170
|
+
if (!option._zod.propValues) {
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (discriminator !== void 0) {
|
|
174
|
+
if (option._zod.propValues[discriminator]?.has(value[discriminator])) {
|
|
175
|
+
return this.#coerce(option, value);
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
for (const key in option._zod.propValues) {
|
|
179
|
+
if (option._zod.propValues[key]?.has(value[key])) {
|
|
180
|
+
return this.#coerce(option, value);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
171
183
|
}
|
|
172
184
|
}
|
|
173
185
|
}
|
|
@@ -207,10 +219,17 @@ class experimental_ZodSmartCoercionPlugin {
|
|
|
207
219
|
return this.#coerce(pipe._zod.def.in, value);
|
|
208
220
|
}
|
|
209
221
|
case "default":
|
|
210
|
-
case "
|
|
222
|
+
case "prefault": {
|
|
211
223
|
const default_ = schema;
|
|
224
|
+
if (value === void 0) {
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
212
227
|
return this.#coerce(default_._zod.def.innerType, value);
|
|
213
228
|
}
|
|
229
|
+
case "catch": {
|
|
230
|
+
const catch_ = schema;
|
|
231
|
+
return this.#coerce(catch_._zod.def.innerType, value);
|
|
232
|
+
}
|
|
214
233
|
case "lazy": {
|
|
215
234
|
const lazy = schema;
|
|
216
235
|
if (value !== void 0) {
|
|
@@ -248,64 +267,53 @@ class experimental_ZodSmartCoercionPlugin {
|
|
|
248
267
|
}
|
|
249
268
|
return value;
|
|
250
269
|
}
|
|
251
|
-
/**
|
|
252
|
-
* This function is inspired from Zod, because it's not exported
|
|
253
|
-
* https://github.com/colinhacks/zod/blob/v4/packages/core/src/schemas.ts#L1903C1-L1921C2
|
|
254
|
-
*/
|
|
255
|
-
#matchDiscriminators(input, discs) {
|
|
256
|
-
for (const [key, value] of discs) {
|
|
257
|
-
const data = input[key];
|
|
258
|
-
if (value.values.size && !value.values.has(data)) {
|
|
259
|
-
return false;
|
|
260
|
-
}
|
|
261
|
-
if (value.maps.length === 0) {
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
if (!isObject(data)) {
|
|
265
|
-
return false;
|
|
266
|
-
}
|
|
267
|
-
for (const m of value.maps) {
|
|
268
|
-
if (!this.#matchDiscriminators(data, m)) {
|
|
269
|
-
return false;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return true;
|
|
274
|
-
}
|
|
275
270
|
}
|
|
276
271
|
|
|
277
|
-
const
|
|
278
|
-
const
|
|
279
|
-
const
|
|
272
|
+
const JSON_SCHEMA_REGISTRY = registry();
|
|
273
|
+
const JSON_SCHEMA_INPUT_REGISTRY = registry();
|
|
274
|
+
const JSON_SCHEMA_OUTPUT_REGISTRY = registry();
|
|
280
275
|
|
|
281
|
-
class
|
|
276
|
+
class ZodToJsonSchemaConverter {
|
|
282
277
|
maxLazyDepth;
|
|
278
|
+
maxStructureDepth;
|
|
283
279
|
anyJsonSchema;
|
|
284
280
|
unsupportedJsonSchema;
|
|
285
281
|
undefinedJsonSchema;
|
|
286
282
|
interceptors;
|
|
287
283
|
constructor(options = {}) {
|
|
288
284
|
this.maxLazyDepth = options.maxLazyDepth ?? 2;
|
|
285
|
+
this.maxStructureDepth = options.maxStructureDepth ?? 10;
|
|
289
286
|
this.anyJsonSchema = options.anyJsonSchema ?? {};
|
|
290
287
|
this.unsupportedJsonSchema = options.unsupportedJsonSchema ?? { not: {} };
|
|
291
288
|
this.undefinedJsonSchema = options.undefinedJsonSchema ?? { not: {} };
|
|
292
289
|
this.interceptors = options.interceptors ?? [];
|
|
293
290
|
}
|
|
294
291
|
condition(schema) {
|
|
295
|
-
return schema !== void 0 && schema["~standard"].vendor === "zod";
|
|
292
|
+
return schema !== void 0 && schema["~standard"].vendor === "zod" && "_zod" in schema;
|
|
296
293
|
}
|
|
297
294
|
convert(schema, options) {
|
|
298
|
-
return this.#convert(schema, options, 0);
|
|
295
|
+
return this.#convert(schema, options, 0, 0);
|
|
299
296
|
}
|
|
300
|
-
#convert(schema, options, lazyDepth, isHandledCustomJSONSchema = false) {
|
|
297
|
+
#convert(schema, options, lazyDepth, structureDepth, isHandledCustomJSONSchema = false) {
|
|
301
298
|
return intercept(
|
|
302
299
|
this.interceptors,
|
|
303
300
|
{ schema, options, lazyDepth, isHandledCustomJSONSchema },
|
|
304
|
-
|
|
301
|
+
({ schema: schema2, options: options2, lazyDepth: lazyDepth2, isHandledCustomJSONSchema: isHandledCustomJSONSchema2 }) => {
|
|
302
|
+
if (structureDepth > this.maxStructureDepth) {
|
|
303
|
+
return [false, this.anyJsonSchema];
|
|
304
|
+
}
|
|
305
|
+
if (!options2.minStructureDepthForRef || options2.minStructureDepthForRef <= structureDepth) {
|
|
306
|
+
const components = toArray(options2.components);
|
|
307
|
+
for (const component of components) {
|
|
308
|
+
if (component.schema === schema2 && component.allowedStrategies.includes(options2.strategy)) {
|
|
309
|
+
return [component.required, { $ref: component.ref }];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
305
313
|
if (!isHandledCustomJSONSchema2) {
|
|
306
314
|
const customJSONSchema = this.#getCustomJsonSchema(schema2, options2);
|
|
307
315
|
if (customJSONSchema) {
|
|
308
|
-
const [required, json] =
|
|
316
|
+
const [required, json] = this.#convert(schema2, options2, lazyDepth2, structureDepth, true);
|
|
309
317
|
return [required, { ...json, ...customJSONSchema }];
|
|
310
318
|
}
|
|
311
319
|
}
|
|
@@ -313,21 +321,28 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
313
321
|
case "string": {
|
|
314
322
|
const string = schema2;
|
|
315
323
|
const json = { type: "string" };
|
|
316
|
-
const { minimum, maximum, format,
|
|
317
|
-
if (minimum
|
|
324
|
+
const { minimum, maximum, format, patterns, contentEncoding } = string._zod.bag;
|
|
325
|
+
if (typeof minimum === "number") {
|
|
318
326
|
json.minLength = minimum;
|
|
319
327
|
}
|
|
320
|
-
if (maximum
|
|
328
|
+
if (typeof maximum === "number") {
|
|
321
329
|
json.maxLength = maximum;
|
|
322
330
|
}
|
|
323
|
-
if (contentEncoding
|
|
331
|
+
if (typeof contentEncoding === "string") {
|
|
324
332
|
json.contentEncoding = this.#handleContentEncoding(contentEncoding);
|
|
325
333
|
}
|
|
326
|
-
if (format
|
|
334
|
+
if (typeof format === "string" && format !== "regex" && json.contentEncoding === void 0) {
|
|
327
335
|
json.format = this.#handleStringFormat(format);
|
|
328
336
|
}
|
|
329
|
-
if (
|
|
330
|
-
|
|
337
|
+
if (patterns instanceof Set && json.contentEncoding === void 0 && json.format === void 0) {
|
|
338
|
+
for (const pattern of patterns) {
|
|
339
|
+
if (json.pattern === void 0) {
|
|
340
|
+
json.pattern = pattern.source;
|
|
341
|
+
} else {
|
|
342
|
+
json.allOf ??= [];
|
|
343
|
+
json.allOf.push({ pattern: pattern.source });
|
|
344
|
+
}
|
|
345
|
+
}
|
|
331
346
|
}
|
|
332
347
|
if (format === "jwt" && json.contentEncoding === void 0 && json.format === void 0 && json.pattern === void 0) {
|
|
333
348
|
json.pattern = /^[\w-]+\.[\w-]+\.[\w-]+$/.source;
|
|
@@ -337,25 +352,23 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
337
352
|
case "number": {
|
|
338
353
|
const number = schema2;
|
|
339
354
|
const json = { type: "number" };
|
|
340
|
-
const { minimum, maximum, format, multipleOf,
|
|
341
|
-
if (format?.includes("int")) {
|
|
355
|
+
const { minimum, maximum, format, multipleOf, exclusiveMaximum, exclusiveMinimum } = number._zod.bag;
|
|
356
|
+
if (typeof format === "string" && format?.includes("int")) {
|
|
342
357
|
json.type = "integer";
|
|
343
358
|
}
|
|
344
|
-
if (minimum
|
|
345
|
-
|
|
346
|
-
json.minimum = minimum;
|
|
347
|
-
} else {
|
|
348
|
-
json.exclusiveMinimum = minimum;
|
|
349
|
-
}
|
|
359
|
+
if (typeof minimum === "number") {
|
|
360
|
+
json.minimum = minimum;
|
|
350
361
|
}
|
|
351
|
-
if (maximum
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
362
|
+
if (typeof maximum === "number") {
|
|
363
|
+
json.maximum = maximum;
|
|
364
|
+
}
|
|
365
|
+
if (typeof exclusiveMinimum === "number") {
|
|
366
|
+
json.exclusiveMinimum = exclusiveMinimum;
|
|
357
367
|
}
|
|
358
|
-
if (
|
|
368
|
+
if (typeof exclusiveMaximum === "number") {
|
|
369
|
+
json.exclusiveMaximum = exclusiveMaximum;
|
|
370
|
+
}
|
|
371
|
+
if (typeof multipleOf === "number") {
|
|
359
372
|
json.multipleOf = multipleOf;
|
|
360
373
|
}
|
|
361
374
|
return [true, json];
|
|
@@ -364,10 +377,18 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
364
377
|
return [true, { type: "boolean" }];
|
|
365
378
|
}
|
|
366
379
|
case "bigint": {
|
|
367
|
-
return [true, {
|
|
380
|
+
return [true, {
|
|
381
|
+
"type": "string",
|
|
382
|
+
"pattern": "^-?[0-9]+$",
|
|
383
|
+
"x-native-type": JsonSchemaXNativeType.BigInt
|
|
384
|
+
}];
|
|
368
385
|
}
|
|
369
386
|
case "date": {
|
|
370
|
-
return [true, {
|
|
387
|
+
return [true, {
|
|
388
|
+
"type": "string",
|
|
389
|
+
"format": JSONSchemaFormat.DateTime,
|
|
390
|
+
"x-native-type": JsonSchemaXNativeType.Date
|
|
391
|
+
}];
|
|
371
392
|
}
|
|
372
393
|
case "null": {
|
|
373
394
|
return [true, { type: "null" }];
|
|
@@ -388,21 +409,21 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
388
409
|
case "array": {
|
|
389
410
|
const array = schema2;
|
|
390
411
|
const json = { type: "array" };
|
|
391
|
-
const { minimum, maximum } = array._zod.
|
|
392
|
-
if (minimum
|
|
412
|
+
const { minimum, maximum } = array._zod.bag;
|
|
413
|
+
if (typeof minimum === "number") {
|
|
393
414
|
json.minItems = minimum;
|
|
394
415
|
}
|
|
395
|
-
if (maximum
|
|
416
|
+
if (typeof maximum === "number") {
|
|
396
417
|
json.maxItems = maximum;
|
|
397
418
|
}
|
|
398
|
-
json.items = this.#handleArrayItemJsonSchema(
|
|
419
|
+
json.items = this.#handleArrayItemJsonSchema(this.#convert(array._zod.def.element, options2, lazyDepth2, structureDepth + 1), options2);
|
|
399
420
|
return [true, json];
|
|
400
421
|
}
|
|
401
422
|
case "object": {
|
|
402
423
|
const object = schema2;
|
|
403
424
|
const json = { type: "object" };
|
|
404
425
|
for (const [key, value] of Object.entries(object._zod.def.shape)) {
|
|
405
|
-
const [itemRequired, itemJson] =
|
|
426
|
+
const [itemRequired, itemJson] = this.#convert(value, options2, lazyDepth2, structureDepth + 1);
|
|
406
427
|
json.properties ??= {};
|
|
407
428
|
json.properties[key] = itemJson;
|
|
408
429
|
if (itemRequired) {
|
|
@@ -414,7 +435,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
414
435
|
if (object._zod.def.catchall._zod.def.type === "never") {
|
|
415
436
|
json.additionalProperties = false;
|
|
416
437
|
} else {
|
|
417
|
-
const [_, addJson] =
|
|
438
|
+
const [_, addJson] = this.#convert(object._zod.def.catchall, options2, lazyDepth2, structureDepth + 1);
|
|
418
439
|
json.additionalProperties = addJson;
|
|
419
440
|
}
|
|
420
441
|
}
|
|
@@ -425,7 +446,7 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
425
446
|
const anyOf = [];
|
|
426
447
|
let required = true;
|
|
427
448
|
for (const item of union._zod.def.options) {
|
|
428
|
-
const [itemRequired, itemJson] =
|
|
449
|
+
const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2, structureDepth + 1);
|
|
429
450
|
if (!itemRequired) {
|
|
430
451
|
required = false;
|
|
431
452
|
}
|
|
@@ -439,14 +460,14 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
439
460
|
}
|
|
440
461
|
}
|
|
441
462
|
}
|
|
442
|
-
return [required,
|
|
463
|
+
return [required, { anyOf }];
|
|
443
464
|
}
|
|
444
465
|
case "intersection": {
|
|
445
466
|
const intersection = schema2;
|
|
446
467
|
const json = { allOf: [] };
|
|
447
468
|
let required = false;
|
|
448
469
|
for (const item of [intersection._zod.def.left, intersection._zod.def.right]) {
|
|
449
|
-
const [itemRequired, itemJson] =
|
|
470
|
+
const [itemRequired, itemJson] = this.#convert(item, options2, lazyDepth2, structureDepth + 1);
|
|
450
471
|
json.allOf.push(itemJson);
|
|
451
472
|
if (itemRequired) {
|
|
452
473
|
required = true;
|
|
@@ -458,16 +479,16 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
458
479
|
const tuple = schema2;
|
|
459
480
|
const json = { type: "array", prefixItems: [] };
|
|
460
481
|
for (const item of tuple._zod.def.items) {
|
|
461
|
-
json.prefixItems.push(this.#handleArrayItemJsonSchema(
|
|
482
|
+
json.prefixItems.push(this.#handleArrayItemJsonSchema(this.#convert(item, options2, lazyDepth2, structureDepth + 1), options2));
|
|
462
483
|
}
|
|
463
484
|
if (tuple._zod.def.rest) {
|
|
464
|
-
json.items = this.#handleArrayItemJsonSchema(
|
|
485
|
+
json.items = this.#handleArrayItemJsonSchema(this.#convert(tuple._zod.def.rest, options2, lazyDepth2, structureDepth + 1), options2);
|
|
465
486
|
}
|
|
466
|
-
const { minimum, maximum } = tuple._zod.
|
|
467
|
-
if (minimum
|
|
487
|
+
const { minimum, maximum } = tuple._zod.bag;
|
|
488
|
+
if (typeof minimum === "number") {
|
|
468
489
|
json.minItems = minimum;
|
|
469
490
|
}
|
|
470
|
-
if (maximum
|
|
491
|
+
if (typeof maximum === "number") {
|
|
471
492
|
json.maxItems = maximum;
|
|
472
493
|
}
|
|
473
494
|
return [true, json];
|
|
@@ -475,36 +496,45 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
475
496
|
case "record": {
|
|
476
497
|
const record = schema2;
|
|
477
498
|
const json = { type: "object" };
|
|
478
|
-
json.propertyNames =
|
|
479
|
-
json.additionalProperties =
|
|
499
|
+
json.propertyNames = this.#convert(record._zod.def.keyType, options2, lazyDepth2, structureDepth + 1)[1];
|
|
500
|
+
json.additionalProperties = this.#convert(record._zod.def.valueType, options2, lazyDepth2, structureDepth + 1)[1];
|
|
480
501
|
return [true, json];
|
|
481
502
|
}
|
|
482
503
|
case "map": {
|
|
483
504
|
const map = schema2;
|
|
484
505
|
return [true, {
|
|
485
|
-
type: "array",
|
|
486
|
-
items: {
|
|
506
|
+
"type": "array",
|
|
507
|
+
"items": {
|
|
487
508
|
type: "array",
|
|
488
509
|
prefixItems: [
|
|
489
|
-
this.#handleArrayItemJsonSchema(
|
|
490
|
-
this.#handleArrayItemJsonSchema(
|
|
510
|
+
this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.keyType, options2, lazyDepth2, structureDepth + 1), options2),
|
|
511
|
+
this.#handleArrayItemJsonSchema(this.#convert(map._zod.def.valueType, options2, lazyDepth2, structureDepth + 1), options2)
|
|
491
512
|
],
|
|
492
513
|
maxItems: 2,
|
|
493
514
|
minItems: 2
|
|
494
|
-
}
|
|
515
|
+
},
|
|
516
|
+
"x-native-type": JsonSchemaXNativeType.Map
|
|
495
517
|
}];
|
|
496
518
|
}
|
|
497
519
|
case "set": {
|
|
498
520
|
const set = schema2;
|
|
499
521
|
return [true, {
|
|
500
|
-
type: "array",
|
|
501
|
-
uniqueItems: true,
|
|
502
|
-
items: this.#handleArrayItemJsonSchema(
|
|
522
|
+
"type": "array",
|
|
523
|
+
"uniqueItems": true,
|
|
524
|
+
"items": this.#handleArrayItemJsonSchema(this.#convert(set._zod.def.valueType, options2, lazyDepth2, structureDepth + 1), options2),
|
|
525
|
+
"x-native-type": JsonSchemaXNativeType.Set
|
|
503
526
|
}];
|
|
504
527
|
}
|
|
505
528
|
case "enum": {
|
|
506
529
|
const enum_ = schema2;
|
|
507
|
-
|
|
530
|
+
const values = getEnumValues(enum_._zod.def.entries);
|
|
531
|
+
const json = { enum: values };
|
|
532
|
+
if (values.every((v) => typeof v === "string")) {
|
|
533
|
+
json.type = "string";
|
|
534
|
+
} else if (values.every((v) => Number.isFinite(v))) {
|
|
535
|
+
json.type = "number";
|
|
536
|
+
}
|
|
537
|
+
return [true, json];
|
|
508
538
|
}
|
|
509
539
|
case "literal": {
|
|
510
540
|
const literal = schema2;
|
|
@@ -523,12 +553,14 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
523
553
|
case "file": {
|
|
524
554
|
const file = schema2;
|
|
525
555
|
const oneOf = [];
|
|
526
|
-
const { mime } = file._zod.
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
556
|
+
const { mime } = file._zod.bag;
|
|
557
|
+
if (mime === void 0 || Array.isArray(mime) && mime.every((m) => typeof m === "string")) {
|
|
558
|
+
for (const type of mime ?? ["*/*"]) {
|
|
559
|
+
oneOf.push({
|
|
560
|
+
type: "string",
|
|
561
|
+
contentMediaType: type
|
|
562
|
+
});
|
|
563
|
+
}
|
|
532
564
|
}
|
|
533
565
|
return [true, oneOf.length === 1 ? oneOf[0] : { anyOf: oneOf }];
|
|
534
566
|
}
|
|
@@ -537,40 +569,46 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
537
569
|
}
|
|
538
570
|
case "nullable": {
|
|
539
571
|
const nullable = schema2;
|
|
540
|
-
const [required, json] =
|
|
572
|
+
const [required, json] = this.#convert(nullable._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
|
541
573
|
return [required, { anyOf: [json, { type: "null" }] }];
|
|
542
574
|
}
|
|
543
575
|
case "nonoptional": {
|
|
544
576
|
const nonoptional = schema2;
|
|
545
|
-
const [, json] =
|
|
577
|
+
const [, json] = this.#convert(nonoptional._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
|
546
578
|
return [true, json];
|
|
547
579
|
}
|
|
548
580
|
case "success": {
|
|
549
581
|
return [true, { type: "boolean" }];
|
|
550
582
|
}
|
|
551
|
-
case "default":
|
|
583
|
+
case "default":
|
|
584
|
+
case "prefault": {
|
|
552
585
|
const default_ = schema2;
|
|
553
|
-
const [, json] =
|
|
586
|
+
const [, json] = this.#convert(default_._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
|
554
587
|
return [false, {
|
|
555
588
|
...json,
|
|
556
|
-
default: default_._zod.def.defaultValue
|
|
589
|
+
default: default_._zod.def.defaultValue
|
|
557
590
|
}];
|
|
558
591
|
}
|
|
559
592
|
case "catch": {
|
|
560
593
|
const catch_ = schema2;
|
|
561
|
-
|
|
562
|
-
return [false, json];
|
|
594
|
+
return this.#convert(catch_._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
|
563
595
|
}
|
|
564
596
|
case "nan": {
|
|
565
597
|
return [true, options2.strategy === "input" ? this.unsupportedJsonSchema : { type: "null" }];
|
|
566
598
|
}
|
|
567
599
|
case "pipe": {
|
|
568
600
|
const pipe = schema2;
|
|
569
|
-
return
|
|
601
|
+
return this.#convert(
|
|
602
|
+
// prefer out schema when in schema is preprocess/transform
|
|
603
|
+
options2.strategy === "input" && pipe._zod.def.in._zod.def.type !== "transform" ? pipe._zod.def.in : pipe._zod.def.out,
|
|
604
|
+
options2,
|
|
605
|
+
lazyDepth2,
|
|
606
|
+
structureDepth
|
|
607
|
+
);
|
|
570
608
|
}
|
|
571
609
|
case "readonly": {
|
|
572
610
|
const readonly_ = schema2;
|
|
573
|
-
const [required, json] =
|
|
611
|
+
const [required, json] = this.#convert(readonly_._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
|
574
612
|
return [required, { ...json, readOnly: true }];
|
|
575
613
|
}
|
|
576
614
|
case "template_literal": {
|
|
@@ -582,15 +620,16 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
582
620
|
}
|
|
583
621
|
case "optional": {
|
|
584
622
|
const optional = schema2;
|
|
585
|
-
const [, json] =
|
|
623
|
+
const [, json] = this.#convert(optional._zod.def.innerType, options2, lazyDepth2, structureDepth);
|
|
586
624
|
return [false, json];
|
|
587
625
|
}
|
|
588
626
|
case "lazy": {
|
|
589
627
|
const lazy = schema2;
|
|
590
|
-
|
|
628
|
+
const currentLazyDepth = lazyDepth2 + 1;
|
|
629
|
+
if (currentLazyDepth > this.maxLazyDepth) {
|
|
591
630
|
return [false, this.anyJsonSchema];
|
|
592
631
|
}
|
|
593
|
-
return
|
|
632
|
+
return this.#convert(lazy._zod.def.getter(), options2, currentLazyDepth, structureDepth);
|
|
594
633
|
}
|
|
595
634
|
default: {
|
|
596
635
|
schema2._zod.def.type;
|
|
@@ -601,25 +640,26 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
601
640
|
);
|
|
602
641
|
}
|
|
603
642
|
#getCustomJsonSchema(schema, options) {
|
|
604
|
-
if (options.strategy === "input" &&
|
|
605
|
-
return
|
|
643
|
+
if (options.strategy === "input" && JSON_SCHEMA_INPUT_REGISTRY.has(schema)) {
|
|
644
|
+
return JSON_SCHEMA_INPUT_REGISTRY.get(schema);
|
|
606
645
|
}
|
|
607
|
-
if (options.strategy === "output" &&
|
|
608
|
-
return
|
|
646
|
+
if (options.strategy === "output" && JSON_SCHEMA_OUTPUT_REGISTRY.has(schema)) {
|
|
647
|
+
return JSON_SCHEMA_OUTPUT_REGISTRY.get(schema);
|
|
609
648
|
}
|
|
610
|
-
if (
|
|
611
|
-
return
|
|
649
|
+
if (JSON_SCHEMA_REGISTRY.has(schema)) {
|
|
650
|
+
return JSON_SCHEMA_REGISTRY.get(schema);
|
|
612
651
|
}
|
|
613
652
|
const global = globalRegistry.get(schema);
|
|
614
653
|
if (global) {
|
|
615
654
|
return {
|
|
655
|
+
title: global.title,
|
|
616
656
|
description: global.description,
|
|
617
|
-
examples: global.examples
|
|
657
|
+
examples: Array.isArray(global.examples) ? global.examples : void 0
|
|
618
658
|
};
|
|
619
659
|
}
|
|
620
660
|
}
|
|
621
661
|
#handleArrayItemJsonSchema([required, schema], options) {
|
|
622
|
-
if (required || options.strategy === "input") {
|
|
662
|
+
if (required || options.strategy === "input" || schema.default !== void 0) {
|
|
623
663
|
return schema;
|
|
624
664
|
}
|
|
625
665
|
if (schema === this.undefinedJsonSchema) {
|
|
@@ -649,5 +689,10 @@ class experimental_ZodToJsonSchemaConverter {
|
|
|
649
689
|
return Object.values(JSONSchemaContentEncoding).includes(contentEncoding) ? contentEncoding : void 0;
|
|
650
690
|
}
|
|
651
691
|
}
|
|
692
|
+
function getEnumValues(entries) {
|
|
693
|
+
const numericValues = Object.values(entries).filter((v) => typeof v === "number");
|
|
694
|
+
const values = Object.entries(entries).filter(([k, _]) => !numericValues.includes(+k)).map(([_, v]) => v);
|
|
695
|
+
return values;
|
|
696
|
+
}
|
|
652
697
|
|
|
653
|
-
export {
|
|
698
|
+
export { JSON_SCHEMA_INPUT_REGISTRY, JSON_SCHEMA_OUTPUT_REGISTRY, JSON_SCHEMA_REGISTRY, ZodToJsonSchemaConverter, experimental_ZodSmartCoercionPlugin };
|
package/package.json
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/zod",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.0-next.
|
|
4
|
+
"version": "0.0.0-next.77e421e",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"homepage": "https://orpc.
|
|
6
|
+
"homepage": "https://orpc.dev",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "git+https://github.com/
|
|
9
|
+
"url": "git+https://github.com/middleapi/orpc.git",
|
|
10
10
|
"directory": "packages/zod"
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
|
-
"unnoq",
|
|
14
13
|
"orpc"
|
|
15
14
|
],
|
|
16
15
|
"exports": {
|
|
@@ -29,31 +28,19 @@
|
|
|
29
28
|
"dist"
|
|
30
29
|
],
|
|
31
30
|
"peerDependencies": {
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"@orpc/
|
|
35
|
-
"@orpc/server": "0.0.0-next.775667a"
|
|
36
|
-
},
|
|
37
|
-
"peerDependenciesMeta": {
|
|
38
|
-
"@zod/core": {
|
|
39
|
-
"optional": true
|
|
40
|
-
},
|
|
41
|
-
"zod": {
|
|
42
|
-
"optional": true
|
|
43
|
-
}
|
|
31
|
+
"zod": ">=3.25.0",
|
|
32
|
+
"@orpc/contract": "0.0.0-next.77e421e",
|
|
33
|
+
"@orpc/server": "0.0.0-next.77e421e"
|
|
44
34
|
},
|
|
45
35
|
"dependencies": {
|
|
46
36
|
"escape-string-regexp": "^5.0.0",
|
|
47
|
-
"wildcard-match": "^5.1.
|
|
48
|
-
"@orpc/openapi": "0.0.0-next.
|
|
49
|
-
"@orpc/
|
|
37
|
+
"wildcard-match": "^5.1.4",
|
|
38
|
+
"@orpc/openapi": "0.0.0-next.77e421e",
|
|
39
|
+
"@orpc/json-schema": "0.0.0-next.77e421e",
|
|
40
|
+
"@orpc/shared": "0.0.0-next.77e421e"
|
|
50
41
|
},
|
|
51
42
|
"devDependencies": {
|
|
52
|
-
"
|
|
53
|
-
"@zod/mini": "^4.0.0-beta.20250505T012514",
|
|
54
|
-
"zod": "^3.24.2",
|
|
55
|
-
"zod-to-json-schema": "^3.24.5",
|
|
56
|
-
"zod4": "npm:zod@^4.0.0-beta.20250505T012514"
|
|
43
|
+
"zod": "^4.3.6"
|
|
57
44
|
},
|
|
58
45
|
"scripts": {
|
|
59
46
|
"build": "unbuild",
|