zod 3.20.2 → 3.20.3

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/types.js CHANGED
@@ -228,28 +228,29 @@ class ZodType {
228
228
  return this._refinement(refinement);
229
229
  }
230
230
  optional() {
231
- return ZodOptional.create(this);
231
+ return ZodOptional.create(this, this._def);
232
232
  }
233
233
  nullable() {
234
- return ZodNullable.create(this);
234
+ return ZodNullable.create(this, this._def);
235
235
  }
236
236
  nullish() {
237
- return this.optional().nullable();
237
+ return this.nullable().optional();
238
238
  }
239
239
  array() {
240
- return ZodArray.create(this);
240
+ return ZodArray.create(this, this._def);
241
241
  }
242
242
  promise() {
243
- return ZodPromise.create(this);
243
+ return ZodPromise.create(this, this._def);
244
244
  }
245
245
  or(option) {
246
- return ZodUnion.create([this, option]);
246
+ return ZodUnion.create([this, option], this._def);
247
247
  }
248
248
  and(incoming) {
249
- return ZodIntersection.create(this, incoming);
249
+ return ZodIntersection.create(this, incoming, this._def);
250
250
  }
251
251
  transform(transform) {
252
252
  return new ZodEffects({
253
+ ...processCreateParams(this._def),
253
254
  schema: this,
254
255
  typeName: ZodFirstPartyTypeKind.ZodEffects,
255
256
  effect: { type: "transform", transform },
@@ -258,6 +259,7 @@ class ZodType {
258
259
  default(def) {
259
260
  const defaultValueFunc = typeof def === "function" ? def : () => def;
260
261
  return new ZodDefault({
262
+ ...processCreateParams(this._def),
261
263
  innerType: this,
262
264
  defaultValue: defaultValueFunc,
263
265
  typeName: ZodFirstPartyTypeKind.ZodDefault,
@@ -267,14 +269,15 @@ class ZodType {
267
269
  return new ZodBranded({
268
270
  typeName: ZodFirstPartyTypeKind.ZodBranded,
269
271
  type: this,
270
- ...processCreateParams(undefined),
272
+ ...processCreateParams(this._def),
271
273
  });
272
274
  }
273
275
  catch(def) {
274
- const defaultValueFunc = typeof def === "function" ? def : () => def;
276
+ const catchValueFunc = typeof def === "function" ? def : () => def;
275
277
  return new ZodCatch({
278
+ ...processCreateParams(this._def),
276
279
  innerType: this,
277
- defaultValue: defaultValueFunc,
280
+ catchValue: catchValueFunc,
278
281
  typeName: ZodFirstPartyTypeKind.ZodCatch,
279
282
  });
280
283
  }
@@ -299,12 +302,15 @@ exports.ZodType = ZodType;
299
302
  exports.Schema = ZodType;
300
303
  exports.ZodSchema = ZodType;
301
304
  const cuidRegex = /^c[^\s-]{8,}$/i;
305
+ const cuid2Regex = /^[a-z][a-z0-9]*$/;
302
306
  const uuidRegex = /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;
303
307
  // from https://stackoverflow.com/a/46181/1550155
304
308
  // old version: too slow, didn't support unicode
305
309
  // const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
310
+ //old email regex
311
+ // const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i;
306
312
  // eslint-disable-next-line
307
- const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i;
313
+ const emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|([^-]([a-zA-Z0-9-]*\.)+[a-zA-Z]{2,}))$/;
308
314
  // interface IsDateStringOptions extends StringDateOptions {
309
315
  /**
310
316
  * Match any configuration
@@ -315,7 +321,7 @@ const emailRegex = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\")
315
321
  const datetimeRegex = (args) => {
316
322
  if (args.precision) {
317
323
  if (args.offset) {
318
- return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}(([+-]\\d{2}:\\d{2})|Z)$`);
324
+ return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}(([+-]\\d{2}(:?\\d{2})?)|Z)$`);
319
325
  }
320
326
  else {
321
327
  return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}Z$`);
@@ -323,7 +329,7 @@ const datetimeRegex = (args) => {
323
329
  }
324
330
  else if (args.precision === 0) {
325
331
  if (args.offset) {
326
- return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(([+-]\\d{2}:\\d{2})|Z)$`);
332
+ return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(([+-]\\d{2}(:?\\d{2})?)|Z)$`);
327
333
  }
328
334
  else {
329
335
  return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$`);
@@ -331,7 +337,7 @@ const datetimeRegex = (args) => {
331
337
  }
332
338
  else {
333
339
  if (args.offset) {
334
- return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}:\\d{2})|Z)$`);
340
+ return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}(:?\\d{2})?)|Z)$`);
335
341
  }
336
342
  else {
337
343
  return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$`);
@@ -464,6 +470,17 @@ class ZodString extends ZodType {
464
470
  status.dirty();
465
471
  }
466
472
  }
473
+ else if (check.kind === "cuid2") {
474
+ if (!cuid2Regex.test(input.data)) {
475
+ ctx = this._getOrReturnCtx(input, ctx);
476
+ (0, parseUtil_1.addIssueToContext)(ctx, {
477
+ validation: "cuid2",
478
+ code: ZodError_1.ZodIssueCode.invalid_string,
479
+ message: check.message,
480
+ });
481
+ status.dirty();
482
+ }
483
+ }
467
484
  else if (check.kind === "url") {
468
485
  try {
469
486
  new URL(input.data);
@@ -552,6 +569,9 @@ class ZodString extends ZodType {
552
569
  cuid(message) {
553
570
  return this._addCheck({ kind: "cuid", ...errorUtil_1.errorUtil.errToObj(message) });
554
571
  }
572
+ cuid2(message) {
573
+ return this._addCheck({ kind: "cuid2", ...errorUtil_1.errorUtil.errToObj(message) });
574
+ }
555
575
  datetime(options) {
556
576
  var _a;
557
577
  if (typeof options === "string") {
@@ -626,6 +646,9 @@ class ZodString extends ZodType {
626
646
  get isCUID() {
627
647
  return !!this._def.checks.find((ch) => ch.kind === "cuid");
628
648
  }
649
+ get isCUID2() {
650
+ return !!this._def.checks.find((ch) => ch.kind === "cuid2");
651
+ }
629
652
  get minLength() {
630
653
  let min = null;
631
654
  for (const ch of this._def.checks) {
@@ -867,7 +890,27 @@ class ZodNumber extends ZodType {
867
890
  return max;
868
891
  }
869
892
  get isInt() {
870
- return !!this._def.checks.find((ch) => ch.kind === "int");
893
+ return !!this._def.checks.find((ch) => ch.kind === "int" ||
894
+ (ch.kind === "multipleOf" && util_1.util.isInteger(ch.value)));
895
+ }
896
+ get isFinite() {
897
+ let max = null, min = null;
898
+ for (const ch of this._def.checks) {
899
+ if (ch.kind === "finite" ||
900
+ ch.kind === "int" ||
901
+ ch.kind === "multipleOf") {
902
+ return true;
903
+ }
904
+ else if (ch.kind === "min") {
905
+ if (min === null || ch.value > min)
906
+ min = ch.value;
907
+ }
908
+ else if (ch.kind === "max") {
909
+ if (max === null || ch.value < max)
910
+ max = ch.value;
911
+ }
912
+ }
913
+ return Number.isFinite(min) && Number.isFinite(max);
871
914
  }
872
915
  }
873
916
  exports.ZodNumber = ZodNumber;
@@ -1239,13 +1282,13 @@ class ZodArray extends ZodType {
1239
1282
  }
1240
1283
  }
1241
1284
  if (ctx.common.async) {
1242
- return Promise.all(ctx.data.map((item, i) => {
1285
+ return Promise.all([...ctx.data].map((item, i) => {
1243
1286
  return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
1244
1287
  })).then((result) => {
1245
1288
  return parseUtil_1.ParseStatus.mergeArray(status, result);
1246
1289
  });
1247
1290
  }
1248
- const result = ctx.data.map((item, i) => {
1291
+ const result = [...ctx.data].map((item, i) => {
1249
1292
  return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
1250
1293
  });
1251
1294
  return parseUtil_1.ParseStatus.mergeArray(status, result);
@@ -1516,10 +1559,10 @@ class ZodObject extends ZodType {
1516
1559
  }
1517
1560
  pick(mask) {
1518
1561
  const shape = {};
1519
- util_1.util.objectKeys(mask).map((key) => {
1520
- // only add to shape if key corresponds to an element of the current shape
1521
- if (this.shape[key])
1562
+ util_1.util.objectKeys(mask).forEach((key) => {
1563
+ if (mask[key] && this.shape[key]) {
1522
1564
  shape[key] = this.shape[key];
1565
+ }
1523
1566
  });
1524
1567
  return new ZodObject({
1525
1568
  ...this._def,
@@ -1528,8 +1571,8 @@ class ZodObject extends ZodType {
1528
1571
  }
1529
1572
  omit(mask) {
1530
1573
  const shape = {};
1531
- util_1.util.objectKeys(this.shape).map((key) => {
1532
- if (util_1.util.objectKeys(mask).indexOf(key) === -1) {
1574
+ util_1.util.objectKeys(this.shape).forEach((key) => {
1575
+ if (!mask[key]) {
1533
1576
  shape[key] = this.shape[key];
1534
1577
  }
1535
1578
  });
@@ -1543,26 +1586,15 @@ class ZodObject extends ZodType {
1543
1586
  }
1544
1587
  partial(mask) {
1545
1588
  const newShape = {};
1546
- if (mask) {
1547
- util_1.util.objectKeys(this.shape).map((key) => {
1548
- if (util_1.util.objectKeys(mask).indexOf(key) === -1) {
1549
- newShape[key] = this.shape[key];
1550
- }
1551
- else {
1552
- newShape[key] = this.shape[key].optional();
1553
- }
1554
- });
1555
- return new ZodObject({
1556
- ...this._def,
1557
- shape: () => newShape,
1558
- });
1559
- }
1560
- else {
1561
- for (const key in this.shape) {
1562
- const fieldSchema = this.shape[key];
1589
+ util_1.util.objectKeys(this.shape).forEach((key) => {
1590
+ const fieldSchema = this.shape[key];
1591
+ if (mask && !mask[key]) {
1592
+ newShape[key] = fieldSchema;
1593
+ }
1594
+ else {
1563
1595
  newShape[key] = fieldSchema.optional();
1564
1596
  }
1565
- }
1597
+ });
1566
1598
  return new ZodObject({
1567
1599
  ...this._def,
1568
1600
  shape: () => newShape,
@@ -1570,23 +1602,11 @@ class ZodObject extends ZodType {
1570
1602
  }
1571
1603
  required(mask) {
1572
1604
  const newShape = {};
1573
- if (mask) {
1574
- util_1.util.objectKeys(this.shape).map((key) => {
1575
- if (util_1.util.objectKeys(mask).indexOf(key) === -1) {
1576
- newShape[key] = this.shape[key];
1577
- }
1578
- else {
1579
- const fieldSchema = this.shape[key];
1580
- let newField = fieldSchema;
1581
- while (newField instanceof ZodOptional) {
1582
- newField = newField._def.innerType;
1583
- }
1584
- newShape[key] = newField;
1585
- }
1586
- });
1587
- }
1588
- else {
1589
- for (const key in this.shape) {
1605
+ util_1.util.objectKeys(this.shape).forEach((key) => {
1606
+ if (mask && !mask[key]) {
1607
+ newShape[key] = this.shape[key];
1608
+ }
1609
+ else {
1590
1610
  const fieldSchema = this.shape[key];
1591
1611
  let newField = fieldSchema;
1592
1612
  while (newField instanceof ZodOptional) {
@@ -1594,7 +1614,7 @@ class ZodObject extends ZodType {
1594
1614
  }
1595
1615
  newShape[key] = newField;
1596
1616
  }
1597
- }
1617
+ });
1598
1618
  return new ZodObject({
1599
1619
  ...this._def,
1600
1620
  shape: () => newShape,
@@ -1979,7 +1999,7 @@ class ZodTuple extends ZodType {
1979
1999
  });
1980
2000
  status.dirty();
1981
2001
  }
1982
- const items = ctx.data
2002
+ const items = [...ctx.data]
1983
2003
  .map((item, itemIndex) => {
1984
2004
  const schema = this._def.items[itemIndex] || this._def.rest;
1985
2005
  if (!schema)
@@ -2365,6 +2385,7 @@ class ZodLiteral extends ZodType {
2365
2385
  if (input.data !== this._def.value) {
2366
2386
  const ctx = this._getOrReturnCtx(input);
2367
2387
  (0, parseUtil_1.addIssueToContext)(ctx, {
2388
+ received: ctx.data,
2368
2389
  code: ZodError_1.ZodIssueCode.invalid_literal,
2369
2390
  expected: this._def.value,
2370
2391
  });
@@ -2439,6 +2460,12 @@ class ZodEnum extends ZodType {
2439
2460
  }
2440
2461
  return enumValues;
2441
2462
  }
2463
+ extract(values) {
2464
+ return ZodEnum.create(values);
2465
+ }
2466
+ exclude(values) {
2467
+ return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)));
2468
+ }
2442
2469
  }
2443
2470
  exports.ZodEnum = ZodEnum;
2444
2471
  ZodEnum.create = createZodEnum;
@@ -2480,6 +2507,9 @@ ZodNativeEnum.create = (values, params) => {
2480
2507
  });
2481
2508
  };
2482
2509
  class ZodPromise extends ZodType {
2510
+ unwrap() {
2511
+ return this._def.type;
2512
+ }
2483
2513
  _parse(input) {
2484
2514
  const { ctx } = this._processInputParams(input);
2485
2515
  if (ctx.parsedType !== util_1.ZodParsedType.promise &&
@@ -2725,24 +2755,30 @@ class ZodCatch extends ZodType {
2725
2755
  const result = this._def.innerType._parse({
2726
2756
  data: ctx.data,
2727
2757
  path: ctx.path,
2728
- parent: ctx,
2758
+ parent: {
2759
+ ...ctx,
2760
+ common: {
2761
+ ...ctx.common,
2762
+ issues: [], // don't collect issues from inner type
2763
+ },
2764
+ },
2729
2765
  });
2730
2766
  if ((0, parseUtil_1.isAsync)(result)) {
2731
2767
  return result.then((result) => {
2732
2768
  return {
2733
2769
  status: "valid",
2734
- value: result.status === "valid" ? result.value : this._def.defaultValue(),
2770
+ value: result.status === "valid" ? result.value : this._def.catchValue(),
2735
2771
  };
2736
2772
  });
2737
2773
  }
2738
2774
  else {
2739
2775
  return {
2740
2776
  status: "valid",
2741
- value: result.status === "valid" ? result.value : this._def.defaultValue(),
2777
+ value: result.status === "valid" ? result.value : this._def.catchValue(),
2742
2778
  };
2743
2779
  }
2744
2780
  }
2745
- removeDefault() {
2781
+ removeCatch() {
2746
2782
  return this._def.innerType;
2747
2783
  }
2748
2784
  }
@@ -2751,9 +2787,7 @@ ZodCatch.create = (type, params) => {
2751
2787
  return new ZodCatch({
2752
2788
  innerType: type,
2753
2789
  typeName: ZodFirstPartyTypeKind.ZodCatch,
2754
- defaultValue: typeof params.default === "function"
2755
- ? params.default
2756
- : () => params.default,
2790
+ catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
2757
2791
  ...processCreateParams(params),
2758
2792
  });
2759
2793
  };
@@ -2996,7 +3030,10 @@ exports.oboolean = oboolean;
2996
3030
  exports.coerce = {
2997
3031
  string: ((arg) => ZodString.create({ ...arg, coerce: true })),
2998
3032
  number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
2999
- boolean: ((arg) => ZodBoolean.create({ ...arg, coerce: true })),
3033
+ boolean: ((arg) => ZodBoolean.create({
3034
+ ...arg,
3035
+ coerce: true,
3036
+ })),
3000
3037
  bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
3001
3038
  date: ((arg) => ZodDate.create({ ...arg, coerce: true })),
3002
3039
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod",
3
- "version": "3.20.2",
3
+ "version": "3.20.3",
4
4
  "description": "TypeScript-first schema declaration and validation library with static type inference",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./index.d.ts",
@@ -29,7 +29,7 @@
29
29
  "bugs": {
30
30
  "url": "https://github.com/colinhacks/zod/issues"
31
31
  },
32
- "homepage": "https://github.com/colinhacks/zod",
32
+ "homepage": "https://zod.dev",
33
33
  "funding": "https://github.com/sponsors/colinhacks",
34
34
  "support": {
35
35
  "backing": {
@@ -57,6 +57,7 @@
57
57
  "build:cjs": "tsc -p tsconfig.cjs.json",
58
58
  "build:types": "tsc -p tsconfig.types.json",
59
59
  "rollup": "rollup --config rollup.config.js",
60
+ "test:watch": "jest --watch",
60
61
  "test": "jest --coverage",
61
62
  "test:deno": "cd deno && deno test",
62
63
  "prepublishOnly": "npm run test && npm run build && npm run build:deno",