zod 3.22.4 → 3.23.8

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/ZodError.d.ts CHANGED
@@ -70,7 +70,7 @@ export interface ZodInvalidReturnTypeIssue extends ZodIssueBase {
70
70
  export interface ZodInvalidDateIssue extends ZodIssueBase {
71
71
  code: typeof ZodIssueCode.invalid_date;
72
72
  }
73
- export declare type StringValidation = "email" | "url" | "emoji" | "uuid" | "regex" | "cuid" | "cuid2" | "ulid" | "datetime" | "ip" | {
73
+ export declare type StringValidation = "email" | "url" | "emoji" | "uuid" | "nanoid" | "regex" | "cuid" | "cuid2" | "ulid" | "datetime" | "date" | "time" | "duration" | "ip" | "base64" | {
74
74
  includes: string;
75
75
  position?: number;
76
76
  } | {
@@ -139,6 +139,7 @@ export declare class ZodError<T = any> extends Error {
139
139
  format(): ZodFormattedError<T>;
140
140
  format<U>(mapper: (issue: ZodIssue) => U): ZodFormattedError<T, U>;
141
141
  static create: (issues: ZodIssue[]) => ZodError<any>;
142
+ static assert(value: unknown): asserts value is ZodError;
142
143
  toString(): string;
143
144
  get message(): string;
144
145
  get isEmpty(): boolean;
package/lib/ZodError.js CHANGED
@@ -98,6 +98,11 @@ class ZodError extends Error {
98
98
  processError(this);
99
99
  return fieldErrors;
100
100
  }
101
+ static assert(value) {
102
+ if (!(value instanceof ZodError)) {
103
+ throw new Error(`Not a ZodError: ${value}`);
104
+ }
105
+ }
101
106
  toString() {
102
107
  return this.message;
103
108
  }
@@ -0,0 +1,5 @@
1
+ import Benchmark from "benchmark";
2
+ declare const _default: {
3
+ suites: Benchmark.Suite[];
4
+ };
5
+ export default _default;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const benchmark_1 = __importDefault(require("benchmark"));
7
+ const datetimeValidationSuite = new benchmark_1.default.Suite("datetime");
8
+ const DATA = "2021-01-01";
9
+ const MONTHS_31 = new Set([1, 3, 5, 7, 8, 10, 12]);
10
+ const MONTHS_30 = new Set([4, 6, 9, 11]);
11
+ const simpleDatetimeRegex = /^(\d{4})-(\d{2})-(\d{2})$/;
12
+ const datetimeRegexNoLeapYearValidation = /^\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\d|2\d))$/;
13
+ const datetimeRegexWithLeapYearValidation = /^((\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\d|3[01])|(0[469]|11)-(0[1-9]|[12]\d|30)|(02)-(0[1-9]|1\d|2[0-8])))$/;
14
+ datetimeValidationSuite
15
+ .add("new Date()", () => {
16
+ return !isNaN(new Date(DATA).getTime());
17
+ })
18
+ .add("regex (no validation)", () => {
19
+ return simpleDatetimeRegex.test(DATA);
20
+ })
21
+ .add("regex (no leap year)", () => {
22
+ return datetimeRegexNoLeapYearValidation.test(DATA);
23
+ })
24
+ .add("regex (w/ leap year)", () => {
25
+ return datetimeRegexWithLeapYearValidation.test(DATA);
26
+ })
27
+ .add("capture groups + code", () => {
28
+ const match = DATA.match(simpleDatetimeRegex);
29
+ if (!match)
30
+ return false;
31
+ // Extract year, month, and day from the capture groups
32
+ const year = Number.parseInt(match[1], 10);
33
+ const month = Number.parseInt(match[2], 10); // month is 0-indexed in JavaScript Date, so subtract 1
34
+ const day = Number.parseInt(match[3], 10);
35
+ if (month === 2) {
36
+ if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
37
+ return day <= 29;
38
+ }
39
+ return day <= 28;
40
+ }
41
+ if (MONTHS_30.has(month)) {
42
+ return day <= 30;
43
+ }
44
+ if (MONTHS_31.has(month)) {
45
+ return day <= 31;
46
+ }
47
+ return false;
48
+ })
49
+ .on("cycle", (e) => {
50
+ console.log(`${datetimeValidationSuite.name}: ${e.target}`);
51
+ });
52
+ exports.default = {
53
+ suites: [datetimeValidationSuite],
54
+ };
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ const datetime_1 = __importDefault(require("./datetime"));
6
7
  const discriminatedUnion_1 = __importDefault(require("./discriminatedUnion"));
8
+ const ipv4_1 = __importDefault(require("./ipv4"));
7
9
  const object_1 = __importDefault(require("./object"));
8
10
  const primitives_1 = __importDefault(require("./primitives"));
9
11
  const realworld_1 = __importDefault(require("./realworld"));
@@ -38,9 +40,20 @@ else {
38
40
  suites.push(...union_1.default.suites);
39
41
  }
40
42
  if (argv.includes("--discriminatedUnion")) {
41
- suites.push(...discriminatedUnion_1.default.suites);
43
+ suites.push(...datetime_1.default.suites);
44
+ }
45
+ if (argv.includes("--datetime")) {
46
+ suites.push(...datetime_1.default.suites);
47
+ }
48
+ if (argv.includes("--ipv4")) {
49
+ suites.push(...ipv4_1.default.suites);
42
50
  }
43
51
  }
44
52
  for (const suite of suites) {
45
- suite.run();
53
+ suite.run({});
46
54
  }
55
+ // exit on Ctrl-C
56
+ process.on("SIGINT", function () {
57
+ console.log("Exiting...");
58
+ process.exit();
59
+ });
@@ -0,0 +1,5 @@
1
+ import Benchmark from "benchmark";
2
+ declare const _default: {
3
+ suites: Benchmark.Suite[];
4
+ };
5
+ export default _default;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const benchmark_1 = __importDefault(require("benchmark"));
7
+ const suite = new benchmark_1.default.Suite("ipv4");
8
+ const DATA = "127.0.0.1";
9
+ const ipv4RegexA = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/;
10
+ const ipv4RegexB = /^(?:(?:(?=(25[0-5]))\1|(?=(2[0-4][0-9]))\2|(?=(1[0-9]{2}))\3|(?=([0-9]{1,2}))\4)\.){3}(?:(?=(25[0-5]))\5|(?=(2[0-4][0-9]))\6|(?=(1[0-9]{2}))\7|(?=([0-9]{1,2}))\8)$/;
11
+ const ipv4RegexC = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
12
+ const ipv4RegexD = /^(\b25[0-5]|\b2[0-4][0-9]|\b[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/;
13
+ const ipv4RegexE = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.){3}(25[0-5]|(2[0-4]|1\d|[1-9]|)\d)$/;
14
+ const ipv4RegexF = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
15
+ const ipv4RegexG = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)(\.(?!$)|$)){4}$/;
16
+ const ipv4RegexH = /^((25[0-5]|(2[0-4]|1[0-9]|[1-9]|)[0-9])(\.(?!$)|$)){4}$/;
17
+ const ipv4RegexI = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
18
+ suite
19
+ .add("A", () => {
20
+ return ipv4RegexA.test(DATA);
21
+ })
22
+ .add("B", () => {
23
+ return ipv4RegexB.test(DATA);
24
+ })
25
+ .add("C", () => {
26
+ return ipv4RegexC.test(DATA);
27
+ })
28
+ .add("D", () => {
29
+ return ipv4RegexD.test(DATA);
30
+ })
31
+ .add("E", () => {
32
+ return ipv4RegexE.test(DATA);
33
+ })
34
+ .add("F", () => {
35
+ return ipv4RegexF.test(DATA);
36
+ })
37
+ .add("G", () => {
38
+ return ipv4RegexG.test(DATA);
39
+ })
40
+ .add("H", () => {
41
+ return ipv4RegexH.test(DATA);
42
+ })
43
+ .add("I", () => {
44
+ return ipv4RegexI.test(DATA);
45
+ })
46
+ .on("cycle", (e) => {
47
+ console.log(`${suite.name}: ${e.target}`);
48
+ });
49
+ exports.default = {
50
+ suites: [suite],
51
+ };
52
+ if (require.main === module) {
53
+ suite.run();
54
+ }
@@ -22,6 +22,39 @@ enumSuite
22
22
  .on("cycle", (e) => {
23
23
  console.log(`z.enum: ${e.target}`);
24
24
  });
25
+ const longEnumSuite = new benchmark_1.default.Suite("long z.enum");
26
+ const longEnumSchema = index_1.z.enum([
27
+ "one",
28
+ "two",
29
+ "three",
30
+ "four",
31
+ "five",
32
+ "six",
33
+ "seven",
34
+ "eight",
35
+ "nine",
36
+ "ten",
37
+ "eleven",
38
+ "twelve",
39
+ "thirteen",
40
+ "fourteen",
41
+ "fifteen",
42
+ "sixteen",
43
+ "seventeen",
44
+ ]);
45
+ longEnumSuite
46
+ .add("valid", () => {
47
+ longEnumSchema.parse("five");
48
+ })
49
+ .add("invalid", () => {
50
+ try {
51
+ longEnumSchema.parse("invalid");
52
+ }
53
+ catch (e) { }
54
+ })
55
+ .on("cycle", (e) => {
56
+ console.log(`long z.enum: ${e.target}`);
57
+ });
25
58
  const undefinedSuite = new benchmark_1.default.Suite("z.undefined");
26
59
  const undefinedSchema = index_1.z.undefined();
27
60
  undefinedSuite
@@ -127,6 +160,7 @@ symbolSuite
127
160
  exports.default = {
128
161
  suites: [
129
162
  enumSuite,
163
+ longEnumSuite,
130
164
  undefinedSuite,
131
165
  literalSuite,
132
166
  numberSuite,
@@ -74,5 +74,5 @@ export declare type AsyncParseReturnType<T> = Promise<SyncParseReturnType<T>>;
74
74
  export declare type ParseReturnType<T> = SyncParseReturnType<T> | AsyncParseReturnType<T>;
75
75
  export declare const isAborted: (x: ParseReturnType<any>) => x is INVALID;
76
76
  export declare const isDirty: <T>(x: ParseReturnType<T>) => x is OK<T> | DIRTY<T>;
77
- export declare const isValid: <T>(x: ParseReturnType<T>) => x is OK<T> | DIRTY<T>;
77
+ export declare const isValid: <T>(x: ParseReturnType<T>) => x is OK<T>;
78
78
  export declare const isAsync: <T>(x: ParseReturnType<T>) => x is AsyncParseReturnType<T>;
@@ -13,6 +13,13 @@ const makeIssue = (params) => {
13
13
  ...issueData,
14
14
  path: fullPath,
15
15
  };
16
+ if (issueData.message !== undefined) {
17
+ return {
18
+ ...issueData,
19
+ path: fullPath,
20
+ message: issueData.message,
21
+ };
22
+ }
16
23
  let errorMessage = "";
17
24
  const maps = errorMaps
18
25
  .filter((m) => !!m)
@@ -24,12 +31,13 @@ const makeIssue = (params) => {
24
31
  return {
25
32
  ...issueData,
26
33
  path: fullPath,
27
- message: issueData.message || errorMessage,
34
+ message: errorMessage,
28
35
  };
29
36
  };
30
37
  exports.makeIssue = makeIssue;
31
38
  exports.EMPTY_PATH = [];
32
39
  function addIssueToContext(ctx, issueData) {
40
+ const overrideMap = (0, errors_1.getErrorMap)();
33
41
  const issue = (0, exports.makeIssue)({
34
42
  issueData: issueData,
35
43
  data: ctx.data,
@@ -37,8 +45,8 @@ function addIssueToContext(ctx, issueData) {
37
45
  errorMaps: [
38
46
  ctx.common.contextualErrorMap,
39
47
  ctx.schemaErrorMap,
40
- (0, errors_1.getErrorMap)(),
41
- en_1.default, // then global default map
48
+ overrideMap,
49
+ overrideMap === en_1.default ? undefined : en_1.default, // then global default map
42
50
  ].filter((x) => !!x),
43
51
  });
44
52
  ctx.common.issues.push(issue);
@@ -70,9 +78,11 @@ class ParseStatus {
70
78
  static async mergeObjectAsync(status, pairs) {
71
79
  const syncPairs = [];
72
80
  for (const pair of pairs) {
81
+ const key = await pair.key;
82
+ const value = await pair.value;
73
83
  syncPairs.push({
74
- key: await pair.key,
75
- value: await pair.value,
84
+ key,
85
+ value,
76
86
  });
77
87
  }
78
88
  return ParseStatus.mergeObjectSync(status, syncPairs);
@@ -7,6 +7,7 @@ export declare namespace util {
7
7
  export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
8
8
  export type OmitKeys<T, K extends string> = Pick<T, Exclude<keyof T, K>>;
9
9
  export type MakePartial<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
10
+ export type Exactly<T, X> = T & Record<Exclude<keyof X, keyof T>, never>;
10
11
  export const arrayToEnum: <T extends string, U extends [T, ...T[]]>(items: U) => { [k in U[number]]: k; };
11
12
  export const getValidEnumValues: (obj: any) => any[];
12
13
  export const objectValues: (obj: any) => any[];
@@ -24,10 +25,19 @@ export declare namespace objectUtil {
24
25
  export type MergeShapes<U, V> = {
25
26
  [k in Exclude<keyof U, keyof V>]: U[k];
26
27
  } & V;
28
+ type optionalKeys<T extends object> = {
29
+ [k in keyof T]: undefined extends T[k] ? k : never;
30
+ }[keyof T];
27
31
  type requiredKeys<T extends object> = {
28
32
  [k in keyof T]: undefined extends T[k] ? never : k;
29
33
  }[keyof T];
30
- export type addQuestionMarks<T extends object, R extends keyof T = requiredKeys<T>> = Pick<Required<T>, R> & Partial<T>;
34
+ export type addQuestionMarks<T extends object, _O = any> = {
35
+ [K in requiredKeys<T>]: T[K];
36
+ } & {
37
+ [K in optionalKeys<T>]?: T[K];
38
+ } & {
39
+ [k in keyof T]?: unknown;
40
+ };
31
41
  export type identity<T> = T;
32
42
  export type flatten<T> = identity<{
33
43
  [k in keyof T]: T[k];
@@ -39,7 +49,11 @@ export declare namespace objectUtil {
39
49
  [k in noNeverKeys<T>]: k extends keyof T ? T[k] : never;
40
50
  }>;
41
51
  export const mergeShapes: <U, T>(first: U, second: T) => T & U;
42
- export type extendShape<A, B> = flatten<Omit<A, keyof B> & B>;
52
+ export type extendShape<A extends object, B extends object> = {
53
+ [K in keyof A as K extends keyof B ? never : K]: A[K];
54
+ } & {
55
+ [K in keyof B]: B[K];
56
+ };
43
57
  export {};
44
58
  }
45
59
  export declare const ZodParsedType: {