zod 3.25.31 → 3.25.32

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.
@@ -412,9 +412,12 @@ exports.$ZodCheckStringFormat = core.$constructor("$ZodCheckStringFormat", (inst
412
412
  var _a;
413
413
  exports.$ZodCheck.init(inst, def);
414
414
  inst._zod.onattach.push((inst) => {
415
- inst._zod.bag.format = def.format;
416
- if (def.pattern)
417
- inst._zod.bag.pattern = def.pattern;
415
+ const bag = inst._zod.bag;
416
+ bag.format = def.format;
417
+ if (def.pattern) {
418
+ bag.patterns ?? (bag.patterns = new Set());
419
+ bag.patterns.add(def.pattern);
420
+ }
418
421
  });
419
422
  (_a = inst._zod).check ?? (_a.check = (payload) => {
420
423
  if (!def.pattern)
@@ -463,7 +466,9 @@ exports.$ZodCheckIncludes = core.$constructor("$ZodCheckIncludes", (inst, def) =
463
466
  const pattern = new RegExp(util.escapeRegex(def.includes));
464
467
  def.pattern = pattern;
465
468
  inst._zod.onattach.push((inst) => {
466
- inst._zod.bag.pattern = pattern;
469
+ const bag = inst._zod.bag;
470
+ bag.patterns ?? (bag.patterns = new Set());
471
+ bag.patterns.add(pattern);
467
472
  });
468
473
  inst._zod.check = (payload) => {
469
474
  if (payload.value.includes(def.includes, def.position))
@@ -484,7 +489,9 @@ exports.$ZodCheckStartsWith = core.$constructor("$ZodCheckStartsWith", (inst, de
484
489
  const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);
485
490
  def.pattern ?? (def.pattern = pattern);
486
491
  inst._zod.onattach.push((inst) => {
487
- inst._zod.bag.pattern = pattern;
492
+ const bag = inst._zod.bag;
493
+ bag.patterns ?? (bag.patterns = new Set());
494
+ bag.patterns.add(pattern);
488
495
  });
489
496
  inst._zod.check = (payload) => {
490
497
  if (payload.value.startsWith(def.prefix))
@@ -505,7 +512,9 @@ exports.$ZodCheckEndsWith = core.$constructor("$ZodCheckEndsWith", (inst, def) =
505
512
  const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
506
513
  def.pattern ?? (def.pattern = pattern);
507
514
  inst._zod.onattach.push((inst) => {
508
- inst._zod.bag.pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
515
+ const bag = inst._zod.bag;
516
+ bag.patterns ?? (bag.patterns = new Set());
517
+ bag.patterns.add(pattern);
509
518
  });
510
519
  inst._zod.check = (payload) => {
511
520
  if (payload.value.endsWith(def.suffix))
@@ -134,7 +134,7 @@ var util_js_1 = require("./util.js");
134
134
  Object.defineProperty(exports, "clone", { enumerable: true, get: function () { return util_js_1.clone; } });
135
135
  exports.$ZodString = core.$constructor("$ZodString", (inst, def) => {
136
136
  exports.$ZodType.init(inst, def);
137
- inst._zod.pattern = inst?._zod.bag?.pattern ?? regexes.string(inst._zod.bag);
137
+ inst._zod.pattern = [...(inst?._zod.bag?.patterns ?? [])].pop() ?? regexes.string(inst._zod.bag);
138
138
  inst._zod.parse = (payload, _) => {
139
139
  if (def.coerce)
140
140
  try {
@@ -277,14 +277,16 @@ exports.$ZodIPv4 = core.$constructor("$ZodIPv4", (inst, def) => {
277
277
  def.pattern ?? (def.pattern = regexes.ipv4);
278
278
  exports.$ZodStringFormat.init(inst, def);
279
279
  inst._zod.onattach.push((inst) => {
280
- inst._zod.bag.format = `ipv4`;
280
+ const bag = inst._zod.bag;
281
+ bag.format = `ipv4`;
281
282
  });
282
283
  });
283
284
  exports.$ZodIPv6 = core.$constructor("$ZodIPv6", (inst, def) => {
284
285
  def.pattern ?? (def.pattern = regexes.ipv6);
285
286
  exports.$ZodStringFormat.init(inst, def);
286
287
  inst._zod.onattach.push((inst) => {
287
- inst._zod.bag.format = `ipv6`;
288
+ const bag = inst._zod.bag;
289
+ bag.format = `ipv6`;
288
290
  });
289
291
  inst._zod.check = (payload) => {
290
292
  try {
@@ -818,7 +820,7 @@ exports.$ZodObject = core.$constructor("$ZodObject", (inst, def) => {
818
820
  // });
819
821
  // }
820
822
  const r = el._zod.run({ value: input[key], issues: [] }, ctx);
821
- const isOptional = el._zod.optin === "optional";
823
+ const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
822
824
  if (r instanceof Promise) {
823
825
  proms.push(r.then((r) => isOptional ? handleOptionalObjectResult(r, payload, key, input) : handleObjectResult(r, payload, key)));
824
826
  }
@@ -8,6 +8,7 @@ const formatMap = {
8
8
  url: "uri",
9
9
  datetime: "date-time",
10
10
  json_string: "json-string",
11
+ regex: "", // do not set
11
12
  };
12
13
  class JSONSchemaGenerator {
13
14
  constructor(params) {
@@ -71,7 +72,8 @@ class JSONSchemaGenerator {
71
72
  case "string": {
72
73
  const json = _json;
73
74
  json.type = "string";
74
- const { minimum, maximum, format, pattern, contentEncoding } = schema._zod.bag;
75
+ const { minimum, maximum, format, patterns, contentEncoding } = schema._zod
76
+ .bag;
75
77
  if (typeof minimum === "number")
76
78
  json.minLength = minimum;
77
79
  if (typeof maximum === "number")
@@ -79,12 +81,24 @@ class JSONSchemaGenerator {
79
81
  // custom pattern overrides format
80
82
  if (format) {
81
83
  json.format = formatMap[format] ?? format;
82
- }
83
- if (pattern) {
84
- json.pattern = pattern.source;
84
+ if (json.format === "")
85
+ delete json.format; // empty format is not valid
85
86
  }
86
87
  if (contentEncoding)
87
88
  json.contentEncoding = contentEncoding;
89
+ if (patterns && patterns.size > 0) {
90
+ const regexes = [...patterns];
91
+ if (regexes.length === 1)
92
+ json.pattern = regexes[0].source;
93
+ else if (regexes.length > 1) {
94
+ result.schema.allOf = [
95
+ ...regexes.map((regex) => ({
96
+ ...(this.target === "draft-7" ? { type: "string" } : {}),
97
+ pattern: regex.source,
98
+ })),
99
+ ];
100
+ }
101
+ }
88
102
  break;
89
103
  }
90
104
  case "number": {
@@ -602,7 +616,17 @@ class JSONSchemaGenerator {
602
616
  for (const entry of [...this.seen.entries()].reverse()) {
603
617
  flattenRef(entry[0], { target: this.target });
604
618
  }
605
- const result = { ...root.def };
619
+ const result = {};
620
+ if (this.target === "draft-2020-12") {
621
+ result.$schema = "https://json-schema.org/draft/2020-12/schema";
622
+ }
623
+ else if (this.target === "draft-7") {
624
+ result.$schema = "http://json-schema.org/draft-07/schema#";
625
+ }
626
+ else {
627
+ console.warn(`Invalid target: ${this.target}`);
628
+ }
629
+ Object.assign(result, root.def);
606
630
  const defs = params.external?.defs ?? {};
607
631
  for (const entry of this.seen.entries()) {
608
632
  const seen = entry[1];
@@ -619,15 +643,6 @@ class JSONSchemaGenerator {
619
643
  result.definitions = defs;
620
644
  }
621
645
  }
622
- if (this.target === "draft-2020-12") {
623
- result.$schema = "https://json-schema.org/draft/2020-12/schema";
624
- }
625
- else if (this.target === "draft-7") {
626
- result.$schema = "http://json-schema.org/draft-07/schema#";
627
- }
628
- else {
629
- console.warn(`Invalid target: ${this.target}`);
630
- }
631
646
  try {
632
647
  // this "finalizes" this schema and ensures all cycles are removed
633
648
  // each call to .emit() is functionally independent
@@ -295,7 +295,7 @@ function stringifyPrimitive(value) {
295
295
  }
296
296
  function optionalKeys(shape) {
297
297
  return Object.keys(shape).filter((k) => {
298
- return shape[k]._zod.optin === "optional";
298
+ return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
299
299
  });
300
300
  }
301
301
  exports.NUMBER_FORMAT_RANGES = {
@@ -386,9 +386,12 @@ export const $ZodCheckStringFormat = /*@__PURE__*/ core.$constructor("$ZodCheckS
386
386
  var _a;
387
387
  $ZodCheck.init(inst, def);
388
388
  inst._zod.onattach.push((inst) => {
389
- inst._zod.bag.format = def.format;
390
- if (def.pattern)
391
- inst._zod.bag.pattern = def.pattern;
389
+ const bag = inst._zod.bag;
390
+ bag.format = def.format;
391
+ if (def.pattern) {
392
+ bag.patterns ?? (bag.patterns = new Set());
393
+ bag.patterns.add(def.pattern);
394
+ }
392
395
  });
393
396
  (_a = inst._zod).check ?? (_a.check = (payload) => {
394
397
  if (!def.pattern)
@@ -437,7 +440,9 @@ export const $ZodCheckIncludes = /*@__PURE__*/ core.$constructor("$ZodCheckInclu
437
440
  const pattern = new RegExp(util.escapeRegex(def.includes));
438
441
  def.pattern = pattern;
439
442
  inst._zod.onattach.push((inst) => {
440
- inst._zod.bag.pattern = pattern;
443
+ const bag = inst._zod.bag;
444
+ bag.patterns ?? (bag.patterns = new Set());
445
+ bag.patterns.add(pattern);
441
446
  });
442
447
  inst._zod.check = (payload) => {
443
448
  if (payload.value.includes(def.includes, def.position))
@@ -458,7 +463,9 @@ export const $ZodCheckStartsWith = /*@__PURE__*/ core.$constructor("$ZodCheckSta
458
463
  const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);
459
464
  def.pattern ?? (def.pattern = pattern);
460
465
  inst._zod.onattach.push((inst) => {
461
- inst._zod.bag.pattern = pattern;
466
+ const bag = inst._zod.bag;
467
+ bag.patterns ?? (bag.patterns = new Set());
468
+ bag.patterns.add(pattern);
462
469
  });
463
470
  inst._zod.check = (payload) => {
464
471
  if (payload.value.startsWith(def.prefix))
@@ -479,7 +486,9 @@ export const $ZodCheckEndsWith = /*@__PURE__*/ core.$constructor("$ZodCheckEndsW
479
486
  const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
480
487
  def.pattern ?? (def.pattern = pattern);
481
488
  inst._zod.onattach.push((inst) => {
482
- inst._zod.bag.pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
489
+ const bag = inst._zod.bag;
490
+ bag.patterns ?? (bag.patterns = new Set());
491
+ bag.patterns.add(pattern);
483
492
  });
484
493
  inst._zod.check = (payload) => {
485
494
  if (payload.value.endsWith(def.suffix))
@@ -103,7 +103,7 @@ export const $ZodType = /*@__PURE__*/ core.$constructor("$ZodType", (inst, def)
103
103
  export { clone } from "./util.js";
104
104
  export const $ZodString = /*@__PURE__*/ core.$constructor("$ZodString", (inst, def) => {
105
105
  $ZodType.init(inst, def);
106
- inst._zod.pattern = inst?._zod.bag?.pattern ?? regexes.string(inst._zod.bag);
106
+ inst._zod.pattern = [...(inst?._zod.bag?.patterns ?? [])].pop() ?? regexes.string(inst._zod.bag);
107
107
  inst._zod.parse = (payload, _) => {
108
108
  if (def.coerce)
109
109
  try {
@@ -246,14 +246,16 @@ export const $ZodIPv4 = /*@__PURE__*/ core.$constructor("$ZodIPv4", (inst, def)
246
246
  def.pattern ?? (def.pattern = regexes.ipv4);
247
247
  $ZodStringFormat.init(inst, def);
248
248
  inst._zod.onattach.push((inst) => {
249
- inst._zod.bag.format = `ipv4`;
249
+ const bag = inst._zod.bag;
250
+ bag.format = `ipv4`;
250
251
  });
251
252
  });
252
253
  export const $ZodIPv6 = /*@__PURE__*/ core.$constructor("$ZodIPv6", (inst, def) => {
253
254
  def.pattern ?? (def.pattern = regexes.ipv6);
254
255
  $ZodStringFormat.init(inst, def);
255
256
  inst._zod.onattach.push((inst) => {
256
- inst._zod.bag.format = `ipv6`;
257
+ const bag = inst._zod.bag;
258
+ bag.format = `ipv6`;
257
259
  });
258
260
  inst._zod.check = (payload) => {
259
261
  try {
@@ -787,7 +789,7 @@ export const $ZodObject = /*@__PURE__*/ core.$constructor("$ZodObject", (inst, d
787
789
  // });
788
790
  // }
789
791
  const r = el._zod.run({ value: input[key], issues: [] }, ctx);
790
- const isOptional = el._zod.optin === "optional";
792
+ const isOptional = el._zod.optin === "optional" && el._zod.optout === "optional";
791
793
  if (r instanceof Promise) {
792
794
  proms.push(r.then((r) => isOptional ? handleOptionalObjectResult(r, payload, key, input) : handleObjectResult(r, payload, key)));
793
795
  }
@@ -4,6 +4,7 @@ const formatMap = {
4
4
  url: "uri",
5
5
  datetime: "date-time",
6
6
  json_string: "json-string",
7
+ regex: "", // do not set
7
8
  };
8
9
  export class JSONSchemaGenerator {
9
10
  constructor(params) {
@@ -67,7 +68,8 @@ export class JSONSchemaGenerator {
67
68
  case "string": {
68
69
  const json = _json;
69
70
  json.type = "string";
70
- const { minimum, maximum, format, pattern, contentEncoding } = schema._zod.bag;
71
+ const { minimum, maximum, format, patterns, contentEncoding } = schema._zod
72
+ .bag;
71
73
  if (typeof minimum === "number")
72
74
  json.minLength = minimum;
73
75
  if (typeof maximum === "number")
@@ -75,12 +77,24 @@ export class JSONSchemaGenerator {
75
77
  // custom pattern overrides format
76
78
  if (format) {
77
79
  json.format = formatMap[format] ?? format;
78
- }
79
- if (pattern) {
80
- json.pattern = pattern.source;
80
+ if (json.format === "")
81
+ delete json.format; // empty format is not valid
81
82
  }
82
83
  if (contentEncoding)
83
84
  json.contentEncoding = contentEncoding;
85
+ if (patterns && patterns.size > 0) {
86
+ const regexes = [...patterns];
87
+ if (regexes.length === 1)
88
+ json.pattern = regexes[0].source;
89
+ else if (regexes.length > 1) {
90
+ result.schema.allOf = [
91
+ ...regexes.map((regex) => ({
92
+ ...(this.target === "draft-7" ? { type: "string" } : {}),
93
+ pattern: regex.source,
94
+ })),
95
+ ];
96
+ }
97
+ }
84
98
  break;
85
99
  }
86
100
  case "number": {
@@ -598,7 +612,17 @@ export class JSONSchemaGenerator {
598
612
  for (const entry of [...this.seen.entries()].reverse()) {
599
613
  flattenRef(entry[0], { target: this.target });
600
614
  }
601
- const result = { ...root.def };
615
+ const result = {};
616
+ if (this.target === "draft-2020-12") {
617
+ result.$schema = "https://json-schema.org/draft/2020-12/schema";
618
+ }
619
+ else if (this.target === "draft-7") {
620
+ result.$schema = "http://json-schema.org/draft-07/schema#";
621
+ }
622
+ else {
623
+ console.warn(`Invalid target: ${this.target}`);
624
+ }
625
+ Object.assign(result, root.def);
602
626
  const defs = params.external?.defs ?? {};
603
627
  for (const entry of this.seen.entries()) {
604
628
  const seen = entry[1];
@@ -615,15 +639,6 @@ export class JSONSchemaGenerator {
615
639
  result.definitions = defs;
616
640
  }
617
641
  }
618
- if (this.target === "draft-2020-12") {
619
- result.$schema = "https://json-schema.org/draft/2020-12/schema";
620
- }
621
- else if (this.target === "draft-7") {
622
- result.$schema = "http://json-schema.org/draft-07/schema#";
623
- }
624
- else {
625
- console.warn(`Invalid target: ${this.target}`);
626
- }
627
642
  try {
628
643
  // this "finalizes" this schema and ensures all cycles are removed
629
644
  // each call to .emit() is functionally independent
@@ -250,7 +250,7 @@ export function stringifyPrimitive(value) {
250
250
  }
251
251
  export function optionalKeys(shape) {
252
252
  return Object.keys(shape).filter((k) => {
253
- return shape[k]._zod.optin === "optional";
253
+ return shape[k]._zod.optin === "optional" && shape[k]._zod.optout === "optional";
254
254
  });
255
255
  }
256
256
  export const NUMBER_FORMAT_RANGES = {
@@ -93,8 +93,9 @@ export interface $ZodStringInternals<Input> extends $ZodTypeInternals<string, In
93
93
  bag: util.LoosePartial<{
94
94
  minimum: number;
95
95
  maximum: number;
96
- pattern: RegExp;
96
+ patterns: Set<RegExp>;
97
97
  format: string;
98
+ contentEncoding: string;
98
99
  }>;
99
100
  }
100
101
  export interface $ZodString<Input = unknown> extends $ZodType {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.25.31",
3
+ "version": "3.25.32",
4
4
  "type": "module",
5
5
  "author": "Colin McDonnell <zod@colinhacks.com>",
6
6
  "description": "TypeScript-first schema declaration and validation library with static type inference",