zod 4.5.4 → 4.6.0
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/compile.cjs +19 -0
- package/index.cjs +19 -0
- package/locales/index.cjs +19 -0
- package/mini/index.cjs +19 -0
- package/package.json +8 -7
- package/src/v3/helpers/errorUtil.ts +1 -1
- package/src/v4/classic/checks.ts +0 -1
- package/src/v4/classic/external.ts +2 -0
- package/src/v4/classic/from-json-schema.ts +248 -25
- package/src/v4/classic/schemas.ts +255 -164
- package/src/v4/classic/tests/assignability.test.ts +59 -9
- package/src/v4/classic/tests/bigint.test.ts +6 -0
- package/src/v4/classic/tests/continuability.test.ts +2 -2
- package/src/v4/classic/tests/cyclic-data.test.ts +274 -0
- package/src/v4/classic/tests/enum.test.ts +9 -0
- package/src/v4/classic/tests/error.test.ts +130 -1
- package/src/v4/classic/tests/firstparty.test.ts +4 -0
- package/src/v4/classic/tests/from-json-schema.test.ts +157 -0
- package/src/v4/classic/tests/iban.test.ts +81 -0
- package/src/v4/classic/tests/instance-footprint.test.ts +18 -2
- package/src/v4/classic/tests/instanceof.test.ts +27 -7
- package/src/v4/classic/tests/issue-schema.test.ts +88 -56
- package/src/v4/classic/tests/object.test.ts +56 -0
- package/src/v4/classic/tests/optin-ladder.test.ts +3 -2
- package/src/v4/classic/tests/properties.test.ts +225 -0
- package/src/v4/classic/tests/recursive-types.test.ts +1 -1
- package/src/v4/classic/tests/standard-schema.test.ts +19 -0
- package/src/v4/classic/tests/string.test.ts +25 -0
- package/src/v4/classic/tests/template-literal.test.ts +33 -1
- package/src/v4/classic/tests/to-json-schema.test.ts +147 -3
- package/src/v4/classic/tests/validate.test.ts +569 -0
- package/src/v4/core/api.ts +30 -6
- package/src/v4/core/checks.ts +1 -101
- package/src/v4/core/compile.ts +193 -81
- package/src/v4/core/doc.ts +6 -2
- package/src/v4/core/errors.ts +3 -6
- package/src/v4/core/json-schema-generator.ts +2 -2
- package/src/v4/core/json-schema-processors.ts +226 -68
- package/src/v4/core/memoizer.ts +78 -28
- package/src/v4/core/parse.ts +37 -16
- package/src/v4/core/regexes.ts +10 -4
- package/src/v4/core/schemas.ts +314 -83
- package/src/v4/core/tests/cached.test.ts +54 -0
- package/src/v4/core/tests/compile-generative.test.ts +445 -0
- package/src/v4/core/tests/compile.test.ts +222 -2
- package/src/v4/core/tests/email-regex.test.ts +140 -0
- package/src/v4/core/tests/polyfill-collision.test.ts +46 -0
- package/src/v4/core/to-json-schema.ts +10 -8
- package/src/v4/core/util.ts +222 -147
- package/src/v4/core/versions.ts +2 -2
- package/src/v4/core/visit.ts +11 -0
- package/src/v4/locales/ar.ts +1 -0
- package/src/v4/locales/az.ts +1 -0
- package/src/v4/locales/be.ts +1 -0
- package/src/v4/locales/bg.ts +1 -0
- package/src/v4/locales/bn.ts +1 -0
- package/src/v4/locales/ca.ts +1 -0
- package/src/v4/locales/ckb.ts +1 -0
- package/src/v4/locales/cs.ts +1 -0
- package/src/v4/locales/da.ts +1 -0
- package/src/v4/locales/de.ts +1 -0
- package/src/v4/locales/el.ts +1 -0
- package/src/v4/locales/en.ts +1 -0
- package/src/v4/locales/eo.ts +1 -0
- package/src/v4/locales/es.ts +1 -0
- package/src/v4/locales/fa.ts +1 -0
- package/src/v4/locales/fi.ts +1 -0
- package/src/v4/locales/fr-CA.ts +1 -0
- package/src/v4/locales/fr.ts +1 -0
- package/src/v4/locales/gu.ts +1 -0
- package/src/v4/locales/he.ts +1 -0
- package/src/v4/locales/hi.ts +1 -0
- package/src/v4/locales/hr.ts +1 -0
- package/src/v4/locales/hu.ts +1 -0
- package/src/v4/locales/hy.ts +1 -0
- package/src/v4/locales/id.ts +1 -0
- package/src/v4/locales/is.ts +1 -0
- package/src/v4/locales/it.ts +1 -0
- package/src/v4/locales/ja.ts +1 -0
- package/src/v4/locales/ka.ts +1 -0
- package/src/v4/locales/km.ts +1 -0
- package/src/v4/locales/kn.ts +1 -0
- package/src/v4/locales/ko.ts +1 -0
- package/src/v4/locales/lt.ts +1 -0
- package/src/v4/locales/mk.ts +1 -0
- package/src/v4/locales/ms.ts +1 -0
- package/src/v4/locales/ne.ts +1 -0
- package/src/v4/locales/nl.ts +1 -0
- package/src/v4/locales/nn.ts +1 -0
- package/src/v4/locales/no.ts +1 -0
- package/src/v4/locales/ota.ts +1 -0
- package/src/v4/locales/pl.ts +1 -0
- package/src/v4/locales/ps.ts +1 -0
- package/src/v4/locales/pt-BR.ts +1 -0
- package/src/v4/locales/pt.ts +1 -0
- package/src/v4/locales/ro.ts +1 -0
- package/src/v4/locales/ru.ts +1 -0
- package/src/v4/locales/sk.ts +1 -0
- package/src/v4/locales/sl.ts +1 -0
- package/src/v4/locales/sv.ts +1 -0
- package/src/v4/locales/ta.ts +1 -0
- package/src/v4/locales/th.ts +1 -0
- package/src/v4/locales/tk.ts +1 -0
- package/src/v4/locales/tr.ts +1 -0
- package/src/v4/locales/uk.ts +1 -0
- package/src/v4/locales/ur.ts +1 -0
- package/src/v4/locales/uz.ts +1 -0
- package/src/v4/locales/vi.ts +1 -0
- package/src/v4/locales/yo.ts +1 -0
- package/src/v4/locales/zh-CN.ts +1 -0
- package/src/v4/locales/zh-TW.ts +1 -0
- package/src/v4/mini/checks.ts +0 -1
- package/src/v4/mini/external.ts +2 -0
- package/src/v4/mini/schemas.ts +38 -2
- package/src/v4/mini/tests/checks.test.ts +1 -1
- package/src/v4/mini/tests/computed.test.ts +11 -17
- package/src/v4/mini/tests/index.test.ts +8 -0
- package/src/v4/mini/tests/string.test.ts +16 -0
- package/v3/ZodError.cjs +19 -0
- package/v3/errors.cjs +19 -0
- package/v3/external.cjs +19 -0
- package/v3/helpers/enumUtil.cjs +19 -0
- package/v3/helpers/errorUtil.cjs +20 -1
- package/v3/helpers/errorUtil.js +1 -1
- package/v3/helpers/parseUtil.cjs +19 -0
- package/v3/helpers/partialUtil.cjs +19 -0
- package/v3/helpers/typeAliases.cjs +19 -0
- package/v3/helpers/util.cjs +19 -0
- package/v3/index.cjs +19 -0
- package/v3/standard-schema.cjs +19 -0
- package/v3/types.cjs +19 -0
- package/v4/classic/checks.cjs +20 -2
- package/v4/classic/checks.d.cts +1 -1
- package/v4/classic/checks.d.ts +1 -1
- package/v4/classic/checks.js +1 -1
- package/v4/classic/coerce.cjs +19 -0
- package/v4/classic/compat.cjs +19 -0
- package/v4/classic/deep-partial.cjs +19 -0
- package/v4/classic/errors.cjs +19 -0
- package/v4/classic/external.cjs +22 -1
- package/v4/classic/external.d.cts +1 -1
- package/v4/classic/external.d.ts +1 -1
- package/v4/classic/external.js +1 -1
- package/v4/classic/from-json-schema.cjs +264 -24
- package/v4/classic/from-json-schema.js +245 -24
- package/v4/classic/in-out.cjs +19 -0
- package/v4/classic/index.cjs +19 -0
- package/v4/classic/iso.cjs +19 -0
- package/v4/classic/parse.cjs +19 -0
- package/v4/classic/schemas.cjs +100 -31
- package/v4/classic/schemas.d.cts +17 -1
- package/v4/classic/schemas.d.ts +17 -1
- package/v4/classic/schemas.js +77 -29
- package/v4/core/api.cjs +37 -2
- package/v4/core/api.d.cts +6 -4
- package/v4/core/api.d.ts +6 -4
- package/v4/core/api.js +17 -2
- package/v4/core/checks.cjs +19 -96
- package/v4/core/checks.d.cts +1 -1
- package/v4/core/checks.d.ts +1 -1
- package/v4/core/checks.js +0 -96
- package/v4/core/compile.cjs +164 -65
- package/v4/core/compile.d.cts +18 -4
- package/v4/core/compile.d.ts +18 -4
- package/v4/core/compile.js +145 -66
- package/v4/core/core.cjs +19 -0
- package/v4/core/doc.cjs +26 -2
- package/v4/core/doc.js +7 -2
- package/v4/core/errors.cjs +21 -5
- package/v4/core/errors.js +2 -5
- package/v4/core/index.cjs +19 -0
- package/v4/core/json-schema-generator.cjs +20 -1
- package/v4/core/json-schema-generator.js +2 -2
- package/v4/core/json-schema-processors.cjs +215 -63
- package/v4/core/json-schema-processors.d.cts +17 -0
- package/v4/core/json-schema-processors.d.ts +17 -0
- package/v4/core/json-schema-processors.js +195 -64
- package/v4/core/json-schema.cjs +19 -0
- package/v4/core/memoizer.cjs +114 -23
- package/v4/core/memoizer.js +72 -23
- package/v4/core/parse.cjs +56 -16
- package/v4/core/parse.js +37 -16
- package/v4/core/regexes.cjs +29 -6
- package/v4/core/regexes.d.cts +2 -0
- package/v4/core/regexes.d.ts +2 -0
- package/v4/core/regexes.js +8 -4
- package/v4/core/registries.cjs +19 -0
- package/v4/core/schemas.cjs +285 -66
- package/v4/core/schemas.d.cts +34 -3
- package/v4/core/schemas.d.ts +34 -3
- package/v4/core/schemas.js +264 -65
- package/v4/core/standard-schema.cjs +19 -0
- package/v4/core/to-json-schema.cjs +29 -7
- package/v4/core/to-json-schema.d.cts +7 -3
- package/v4/core/to-json-schema.d.ts +7 -3
- package/v4/core/to-json-schema.js +8 -7
- package/v4/core/util.cjs +181 -143
- package/v4/core/util.d.cts +25 -4
- package/v4/core/util.d.ts +25 -4
- package/v4/core/util.js +160 -143
- package/v4/core/versions.cjs +21 -2
- package/v4/core/versions.d.cts +1 -1
- package/v4/core/versions.d.ts +1 -1
- package/v4/core/versions.js +2 -2
- package/v4/core/visit.cjs +31 -0
- package/v4/core/visit.js +12 -0
- package/v4/index.cjs +19 -0
- package/v4/locales/ar.cjs +1 -0
- package/v4/locales/ar.js +1 -0
- package/v4/locales/az.cjs +1 -0
- package/v4/locales/az.js +1 -0
- package/v4/locales/be.cjs +1 -0
- package/v4/locales/be.js +1 -0
- package/v4/locales/bg.cjs +1 -0
- package/v4/locales/bg.js +1 -0
- package/v4/locales/bn.cjs +1 -0
- package/v4/locales/bn.js +1 -0
- package/v4/locales/ca.cjs +1 -0
- package/v4/locales/ca.js +1 -0
- package/v4/locales/ckb.cjs +1 -0
- package/v4/locales/ckb.js +1 -0
- package/v4/locales/cs.cjs +1 -0
- package/v4/locales/cs.js +1 -0
- package/v4/locales/da.cjs +1 -0
- package/v4/locales/da.js +1 -0
- package/v4/locales/de.cjs +1 -0
- package/v4/locales/de.js +1 -0
- package/v4/locales/el.cjs +1 -0
- package/v4/locales/el.js +1 -0
- package/v4/locales/en.cjs +1 -0
- package/v4/locales/en.js +1 -0
- package/v4/locales/eo.cjs +1 -0
- package/v4/locales/eo.js +1 -0
- package/v4/locales/es.cjs +1 -0
- package/v4/locales/es.js +1 -0
- package/v4/locales/fa.cjs +1 -0
- package/v4/locales/fa.js +1 -0
- package/v4/locales/fi.cjs +1 -0
- package/v4/locales/fi.js +1 -0
- package/v4/locales/fr-CA.cjs +1 -0
- package/v4/locales/fr-CA.js +1 -0
- package/v4/locales/fr.cjs +1 -0
- package/v4/locales/fr.js +1 -0
- package/v4/locales/gu.cjs +1 -0
- package/v4/locales/gu.js +1 -0
- package/v4/locales/he.cjs +1 -0
- package/v4/locales/he.js +1 -0
- package/v4/locales/hi.cjs +1 -0
- package/v4/locales/hi.js +1 -0
- package/v4/locales/hr.cjs +1 -0
- package/v4/locales/hr.js +1 -0
- package/v4/locales/hu.cjs +1 -0
- package/v4/locales/hu.js +1 -0
- package/v4/locales/hy.cjs +1 -0
- package/v4/locales/hy.js +1 -0
- package/v4/locales/id.cjs +1 -0
- package/v4/locales/id.js +1 -0
- package/v4/locales/index.cjs +19 -0
- package/v4/locales/is.cjs +1 -0
- package/v4/locales/is.js +1 -0
- package/v4/locales/it.cjs +1 -0
- package/v4/locales/it.js +1 -0
- package/v4/locales/ja.cjs +1 -0
- package/v4/locales/ja.js +1 -0
- package/v4/locales/ka.cjs +1 -0
- package/v4/locales/ka.js +1 -0
- package/v4/locales/km.cjs +1 -0
- package/v4/locales/km.js +1 -0
- package/v4/locales/kn.cjs +1 -0
- package/v4/locales/kn.js +1 -0
- package/v4/locales/ko.cjs +1 -0
- package/v4/locales/ko.js +1 -0
- package/v4/locales/lt.cjs +1 -0
- package/v4/locales/lt.js +1 -0
- package/v4/locales/mk.cjs +1 -0
- package/v4/locales/mk.js +1 -0
- package/v4/locales/ms.cjs +1 -0
- package/v4/locales/ms.js +1 -0
- package/v4/locales/ne.cjs +1 -0
- package/v4/locales/ne.js +1 -0
- package/v4/locales/nl.cjs +1 -0
- package/v4/locales/nl.js +1 -0
- package/v4/locales/nn.cjs +1 -0
- package/v4/locales/nn.js +1 -0
- package/v4/locales/no.cjs +1 -0
- package/v4/locales/no.js +1 -0
- package/v4/locales/ota.cjs +1 -0
- package/v4/locales/ota.js +1 -0
- package/v4/locales/pl.cjs +1 -0
- package/v4/locales/pl.js +1 -0
- package/v4/locales/ps.cjs +1 -0
- package/v4/locales/ps.js +1 -0
- package/v4/locales/pt-BR.cjs +1 -0
- package/v4/locales/pt-BR.js +1 -0
- package/v4/locales/pt.cjs +1 -0
- package/v4/locales/pt.js +1 -0
- package/v4/locales/ro.cjs +1 -0
- package/v4/locales/ro.js +1 -0
- package/v4/locales/ru.cjs +1 -0
- package/v4/locales/ru.js +1 -0
- package/v4/locales/sk.cjs +1 -0
- package/v4/locales/sk.js +1 -0
- package/v4/locales/sl.cjs +1 -0
- package/v4/locales/sl.js +1 -0
- package/v4/locales/sv.cjs +1 -0
- package/v4/locales/sv.js +1 -0
- package/v4/locales/ta.cjs +1 -0
- package/v4/locales/ta.js +1 -0
- package/v4/locales/th.cjs +1 -0
- package/v4/locales/th.js +1 -0
- package/v4/locales/tk.cjs +1 -0
- package/v4/locales/tk.js +1 -0
- package/v4/locales/tr.cjs +1 -0
- package/v4/locales/tr.js +1 -0
- package/v4/locales/uk.cjs +1 -0
- package/v4/locales/uk.js +1 -0
- package/v4/locales/ur.cjs +1 -0
- package/v4/locales/ur.js +1 -0
- package/v4/locales/uz.cjs +1 -0
- package/v4/locales/uz.js +1 -0
- package/v4/locales/vi.cjs +1 -0
- package/v4/locales/vi.js +1 -0
- package/v4/locales/yo.cjs +1 -0
- package/v4/locales/yo.js +1 -0
- package/v4/locales/zh-CN.cjs +1 -0
- package/v4/locales/zh-CN.js +1 -0
- package/v4/locales/zh-TW.cjs +1 -0
- package/v4/locales/zh-TW.js +1 -0
- package/v4/mini/checks.cjs +20 -2
- package/v4/mini/checks.d.cts +1 -1
- package/v4/mini/checks.d.ts +1 -1
- package/v4/mini/checks.js +1 -1
- package/v4/mini/coerce.cjs +19 -0
- package/v4/mini/deep-partial.cjs +19 -0
- package/v4/mini/external.cjs +22 -1
- package/v4/mini/external.d.cts +1 -1
- package/v4/mini/external.d.ts +1 -1
- package/v4/mini/external.js +1 -1
- package/v4/mini/in-out.cjs +19 -0
- package/v4/mini/index.cjs +19 -0
- package/v4/mini/iso.cjs +19 -0
- package/v4/mini/parse.cjs +19 -0
- package/v4/mini/schemas.cjs +42 -4
- package/v4/mini/schemas.d.cts +8 -0
- package/v4/mini/schemas.d.ts +8 -0
- package/v4/mini/schemas.js +19 -2
- package/v4-mini/index.cjs +19 -0
package/src/v4/core/schemas.ts
CHANGED
|
@@ -5,7 +5,7 @@ import * as core from "./core.js";
|
|
|
5
5
|
import { Doc } from "./doc.js";
|
|
6
6
|
import type * as errors from "./errors.js";
|
|
7
7
|
import type * as JSONSchema from "./json-schema.js";
|
|
8
|
-
import { parse, parseAsync
|
|
8
|
+
import { parse, parseAsync } from "./parse.js";
|
|
9
9
|
import * as regexes from "./regexes.js";
|
|
10
10
|
import type { StandardSchemaV1 } from "./standard-schema.js";
|
|
11
11
|
import type { ProcessParams, ToJSONSchemaContext } from "./to-json-schema.js";
|
|
@@ -30,6 +30,8 @@ export interface ParseContextInternal<T extends errors.$ZodIssueBase = never> ex
|
|
|
30
30
|
readonly async?: boolean | undefined;
|
|
31
31
|
readonly direction?: "forward" | "backward";
|
|
32
32
|
readonly skipChecks?: boolean;
|
|
33
|
+
/** Set only by `validate`/`validateAsync`. A container may stop before its next child, never inside one, so a map entry and a tuple's fixed items parse whole. */
|
|
34
|
+
readonly abortEarly?: boolean;
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/** Gives a container cycle support: `attach` wraps its parse, and `alloc` registers the object it builds into before any child is parsed so a reference back to the same input resolves to it. */
|
|
@@ -94,7 +96,8 @@ export interface $ZodTypeDef {
|
|
|
94
96
|
| "promise"
|
|
95
97
|
| "lazy"
|
|
96
98
|
| "function"
|
|
97
|
-
| "custom"
|
|
99
|
+
| "custom"
|
|
100
|
+
| "properties";
|
|
98
101
|
error?: errors.$ZodErrorMap<never> | undefined;
|
|
99
102
|
checks?: checks.$ZodCheck<never>[];
|
|
100
103
|
}
|
|
@@ -332,17 +335,25 @@ export const $ZodType: core.$constructor<$ZodType> = /*@__PURE__*/ core.$constru
|
|
|
332
335
|
);
|
|
333
336
|
|
|
334
337
|
/** The Standard Schema surface for `inst`. Shared so wrappers can extend it without forcing it. */
|
|
335
|
-
|
|
336
|
-
|
|
338
|
+
// a Standard Schema result only reports issues, so a failure finalizes them straight off the raw payload: no ZodError, and no lazy result to read through
|
|
339
|
+
const toStandardResult = (r: ParsePayload, ctx: ParseContextInternal) =>
|
|
340
|
+
r.issues.length ? { issues: r.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())) } : { value: r.value };
|
|
341
|
+
|
|
342
|
+
async function validateAsync(inst: $ZodType, value: unknown) {
|
|
343
|
+
const ctx: ParseContextInternal = { async: true };
|
|
344
|
+
return toStandardResult((await inst._zod.run({ value, issues: [] }, ctx)) as ParsePayload, ctx);
|
|
345
|
+
}
|
|
337
346
|
|
|
338
347
|
export function standardProps(inst: $ZodType): StandardSchemaV1.Props<any, any> {
|
|
339
348
|
return {
|
|
340
349
|
validate: (value: unknown) => {
|
|
350
|
+
const ctx: ParseContextInternal = { async: false };
|
|
341
351
|
try {
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
352
|
+
const r = inst._zod.run({ value, issues: [] }, ctx);
|
|
353
|
+
if (!(r instanceof Promise)) return toStandardResult(r, ctx);
|
|
354
|
+
} catch (_) {}
|
|
355
|
+
// async function so a synchronously throwing check rejects instead of escaping validate
|
|
356
|
+
return validateAsync(inst, value);
|
|
346
357
|
},
|
|
347
358
|
vendor: "zod",
|
|
348
359
|
version: 1 as const,
|
|
@@ -388,7 +399,8 @@ export interface $ZodString<Input = unknown> extends _$ZodType<$ZodStringInterna
|
|
|
388
399
|
|
|
389
400
|
export const $ZodString: core.$constructor<$ZodString> = /*@__PURE__*/ core.$constructor("$ZodString", (inst, def) => {
|
|
390
401
|
$ZodType.init(inst, def);
|
|
391
|
-
|
|
402
|
+
// a format's own pattern, else unbounded; a template literal derives the check-aware form itself
|
|
403
|
+
inst._zod.pattern = (def as $ZodStringFormatDef).pattern ?? regexes.anyString;
|
|
392
404
|
inst._zod.parse = (payload, _) => {
|
|
393
405
|
if (def.coerce)
|
|
394
406
|
try {
|
|
@@ -777,14 +789,6 @@ export const $ZodISODateTime: core.$constructor<$ZodISODateTime> = /*@__PURE__*/
|
|
|
777
789
|
(inst, def): void => {
|
|
778
790
|
def.pattern ??= regexes.datetime(def);
|
|
779
791
|
$ZodStringFormat.init(inst, def);
|
|
780
|
-
|
|
781
|
-
// these two drop the offset or seconds `date-time` requires — on the bag not the def, since `z.string().check(...)` lands the format on a different schema
|
|
782
|
-
if (def.local || def.precision === -1) {
|
|
783
|
-
inst._zod.bag.laxFormat = true;
|
|
784
|
-
inst._zod.onattach.push((s) => {
|
|
785
|
-
(s._zod.bag as $ZodStringInternals<unknown>["bag"]).laxFormat = true;
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
792
|
}
|
|
789
793
|
);
|
|
790
794
|
|
|
@@ -861,8 +865,6 @@ export interface $ZodIPv4 extends $ZodType {
|
|
|
861
865
|
export const $ZodIPv4: core.$constructor<$ZodIPv4> = /*@__PURE__*/ core.$constructor("$ZodIPv4", (inst, def): void => {
|
|
862
866
|
def.pattern ??= regexes.ipv4;
|
|
863
867
|
$ZodStringFormat.init(inst, def);
|
|
864
|
-
|
|
865
|
-
inst._zod.bag.format = `ipv4`;
|
|
866
868
|
});
|
|
867
869
|
|
|
868
870
|
////////////////////////////// ZodIPv6 //////////////////////////////
|
|
@@ -897,8 +899,6 @@ export const $ZodIPv6: core.$constructor<$ZodIPv6> = /*@__PURE__*/ core.$constru
|
|
|
897
899
|
def.pattern ??= regexes.ipv6;
|
|
898
900
|
$ZodStringFormat.init(inst, def);
|
|
899
901
|
|
|
900
|
-
inst._zod.bag.format = `ipv6`;
|
|
901
|
-
|
|
902
902
|
inst._zod.check = (payload) => {
|
|
903
903
|
if (!isValidIPv6(payload.value)) {
|
|
904
904
|
payload.issues.push({
|
|
@@ -928,8 +928,6 @@ export interface $ZodMAC extends $ZodType {
|
|
|
928
928
|
export const $ZodMAC: core.$constructor<$ZodMAC> = /*@__PURE__*/ core.$constructor("$ZodMAC", (inst, def): void => {
|
|
929
929
|
def.pattern ??= regexes.mac(def.delimiter);
|
|
930
930
|
$ZodStringFormat.init(inst, def);
|
|
931
|
-
|
|
932
|
-
inst._zod.bag.format = `mac`;
|
|
933
931
|
});
|
|
934
932
|
|
|
935
933
|
////////////////////////////// ZodCIDRv4 //////////////////////////////
|
|
@@ -1021,14 +1019,15 @@ export interface $ZodBase64 extends $ZodType {
|
|
|
1021
1019
|
_zod: $ZodBase64Internals;
|
|
1022
1020
|
}
|
|
1023
1021
|
|
|
1022
|
+
// lax on purpose: the quantified regexes.base64 overflows the regex stack on multi-MB input and its leading ^$| alternation leaks through template-literal composition; isValidBase64 enforces length and padding
|
|
1023
|
+
export const base64Charset: RegExp = /^[0-9a-zA-Z+/]*={0,2}$/;
|
|
1024
|
+
|
|
1024
1025
|
export const $ZodBase64: core.$constructor<$ZodBase64> = /*@__PURE__*/ core.$constructor(
|
|
1025
1026
|
"$ZodBase64",
|
|
1026
1027
|
(inst, def): void => {
|
|
1027
|
-
def.pattern ??=
|
|
1028
|
+
def.pattern ??= base64Charset;
|
|
1028
1029
|
$ZodStringFormat.init(inst, def);
|
|
1029
1030
|
|
|
1030
|
-
inst._zod.bag.contentEncoding = "base64";
|
|
1031
|
-
|
|
1032
1031
|
inst._zod.check = (payload) => {
|
|
1033
1032
|
if (isValidBase64(payload.value)) return;
|
|
1034
1033
|
|
|
@@ -1043,9 +1042,12 @@ export const $ZodBase64: core.$constructor<$ZodBase64> = /*@__PURE__*/ core.$con
|
|
|
1043
1042
|
}
|
|
1044
1043
|
);
|
|
1045
1044
|
|
|
1046
|
-
//////////////////////////////
|
|
1045
|
+
////////////////////////////// ZodBase64URL //////////////////////////////
|
|
1046
|
+
// lax on purpose: the quantified regexes.base64url overflows the regex stack on multi-MB input; isValidBase64 enforces length on the padded string
|
|
1047
|
+
export const base64urlCharset: RegExp = /^[A-Za-z0-9_-]*$/;
|
|
1048
|
+
|
|
1047
1049
|
export function isValidBase64URL(data: string): boolean {
|
|
1048
|
-
if (!
|
|
1050
|
+
if (!base64urlCharset.test(data)) return false;
|
|
1049
1051
|
const base64 = data.replace(/[-_]/g, (c) => (c === "-" ? "+" : "/"));
|
|
1050
1052
|
const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
|
|
1051
1053
|
return isValidBase64(padded);
|
|
@@ -1061,11 +1063,9 @@ export interface $ZodBase64URL extends $ZodType {
|
|
|
1061
1063
|
export const $ZodBase64URL: core.$constructor<$ZodBase64URL> = /*@__PURE__*/ core.$constructor(
|
|
1062
1064
|
"$ZodBase64URL",
|
|
1063
1065
|
(inst, def): void => {
|
|
1064
|
-
def.pattern ??=
|
|
1066
|
+
def.pattern ??= base64urlCharset;
|
|
1065
1067
|
$ZodStringFormat.init(inst, def);
|
|
1066
1068
|
|
|
1067
|
-
inst._zod.bag.contentEncoding = "base64url";
|
|
1068
|
-
|
|
1069
1069
|
inst._zod.check = (payload) => {
|
|
1070
1070
|
if (isValidBase64URL(payload.value)) return;
|
|
1071
1071
|
|
|
@@ -1104,7 +1104,7 @@ function isLuhnAlgo(digits: string): boolean {
|
|
|
1104
1104
|
let bit = 1;
|
|
1105
1105
|
let sum = 0;
|
|
1106
1106
|
while (length) {
|
|
1107
|
-
const value =
|
|
1107
|
+
const value = digits.charCodeAt(--length) - 48;
|
|
1108
1108
|
bit ^= 1;
|
|
1109
1109
|
sum += bit ? [0, 2, 4, 6, 8, 1, 3, 5, 7, 9][value]! : value;
|
|
1110
1110
|
}
|
|
@@ -1144,6 +1144,53 @@ export const $ZodCreditCard: core.$constructor<$ZodCreditCard> = /*@__PURE__*/ c
|
|
|
1144
1144
|
}
|
|
1145
1145
|
);
|
|
1146
1146
|
|
|
1147
|
+
////////////////////////////// ZodIBAN //////////////////////////////
|
|
1148
|
+
|
|
1149
|
+
// iso 7064 mod 97-10 checksum without BigInt
|
|
1150
|
+
function isIso7064Mod97(iban: string): boolean {
|
|
1151
|
+
let remainder = 0;
|
|
1152
|
+
const len = iban.length;
|
|
1153
|
+
for (let i = 4; i < len; i++) {
|
|
1154
|
+
const code = iban.charCodeAt(i);
|
|
1155
|
+
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
1156
|
+
}
|
|
1157
|
+
for (let i = 0; i < 4; i++) {
|
|
1158
|
+
const code = iban.charCodeAt(i);
|
|
1159
|
+
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
1160
|
+
}
|
|
1161
|
+
return remainder === 1;
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1164
|
+
export function isValidIBAN(input: string): boolean {
|
|
1165
|
+
if (!regexes.iban.test(input)) return false;
|
|
1166
|
+
return isIso7064Mod97(input);
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
export interface $ZodIBANDef extends $ZodStringFormatDef<"iban"> {}
|
|
1170
|
+
export interface $ZodIBANInternals extends $ZodStringFormatInternals<"iban"> {
|
|
1171
|
+
def: $ZodIBANDef;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
export interface $ZodIBAN extends $ZodType {
|
|
1175
|
+
_zod: $ZodIBANInternals;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
export const $ZodIBAN: core.$constructor<$ZodIBAN> = /*@__PURE__*/ core.$constructor("$ZodIBAN", (inst, def): void => {
|
|
1179
|
+
// shape only — checksum is not expressible as a pattern
|
|
1180
|
+
def.pattern ??= regexes.iban;
|
|
1181
|
+
$ZodStringFormat.init(inst, def);
|
|
1182
|
+
inst._zod.check = (payload) => {
|
|
1183
|
+
if (isValidIBAN(payload.value)) return;
|
|
1184
|
+
payload.issues.push({
|
|
1185
|
+
code: "invalid_format",
|
|
1186
|
+
format: "iban",
|
|
1187
|
+
input: payload.value,
|
|
1188
|
+
inst,
|
|
1189
|
+
continue: !def.abort,
|
|
1190
|
+
});
|
|
1191
|
+
};
|
|
1192
|
+
});
|
|
1193
|
+
|
|
1147
1194
|
////////////////////////////// ZodJWT //////////////////////////////
|
|
1148
1195
|
|
|
1149
1196
|
export function isValidJWT(token: string, algorithm: util.JWTAlgorithm | null = null): boolean {
|
|
@@ -1260,7 +1307,7 @@ export interface $ZodNumber<Input = unknown> extends $ZodType {
|
|
|
1260
1307
|
export const $ZodNumber: core.$constructor<$ZodNumber> = /*@__PURE__*/ core.$constructor("$ZodNumber", (inst, def) => {
|
|
1261
1308
|
$ZodType.init(inst, def);
|
|
1262
1309
|
|
|
1263
|
-
inst._zod.pattern =
|
|
1310
|
+
inst._zod.pattern = regexes.number;
|
|
1264
1311
|
inst._zod.parse = (payload, _ctx) => {
|
|
1265
1312
|
if (def.coerce)
|
|
1266
1313
|
try {
|
|
@@ -1804,6 +1851,7 @@ export const $ZodArray: core.$constructor<$ZodArray> = /*@__PURE__*/ core.$const
|
|
|
1804
1851
|
|
|
1805
1852
|
payload.value = memo ? memo.alloc(inst, payload, Array(input.length), ctx) : Array(input.length);
|
|
1806
1853
|
const proms: Promise<any>[] = [];
|
|
1854
|
+
const abortEarly = ctx?.abortEarly;
|
|
1807
1855
|
for (let i = 0; i < input.length; i++) {
|
|
1808
1856
|
const item = input[i];
|
|
1809
1857
|
const result = def.element._zod.run(
|
|
@@ -1818,6 +1866,8 @@ export const $ZodArray: core.$constructor<$ZodArray> = /*@__PURE__*/ core.$const
|
|
|
1818
1866
|
proms.push(result.then((result) => handleArrayResult(result, payload, i)));
|
|
1819
1867
|
} else {
|
|
1820
1868
|
handleArrayResult(result, payload, i);
|
|
1869
|
+
// the element's payload is authoritative here, since handleArrayResult forwards every issue; an object's is not, because it drops a failed absent optional
|
|
1870
|
+
if (abortEarly && result.issues.length !== 0 && util.aborted(result)) break;
|
|
1821
1871
|
}
|
|
1822
1872
|
}
|
|
1823
1873
|
|
|
@@ -2022,9 +2072,10 @@ function handleCatchall(
|
|
|
2022
2072
|
proms: Promise<any>[],
|
|
2023
2073
|
input: any,
|
|
2024
2074
|
payload: ParsePayload,
|
|
2025
|
-
ctx:
|
|
2075
|
+
ctx: ParseContextInternal,
|
|
2026
2076
|
def: ReturnType<typeof normalizeDef>,
|
|
2027
|
-
inst: $ZodObject
|
|
2077
|
+
inst: $ZodObject,
|
|
2078
|
+
abortEarly: boolean
|
|
2028
2079
|
) {
|
|
2029
2080
|
const unrecognized: string[] = [];
|
|
2030
2081
|
const keySet = def.keySet;
|
|
@@ -2032,7 +2083,13 @@ function handleCatchall(
|
|
|
2032
2083
|
const t = _catchall.def.type;
|
|
2033
2084
|
const optin = _catchall.optin;
|
|
2034
2085
|
const optout = _catchall.optout;
|
|
2086
|
+
// starts at 0, not the current length: the shape phase already ran and may have aborted
|
|
2087
|
+
let seen = 0;
|
|
2035
2088
|
for (const key in input) {
|
|
2089
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
2090
|
+
if (util.aborted(payload, seen)) break;
|
|
2091
|
+
seen = payload.issues.length;
|
|
2092
|
+
}
|
|
2036
2093
|
// Must precede the __proto__ branch: a declared key is not unrecognized, even though the shape loop deliberately strips __proto__ from the parsed output.
|
|
2037
2094
|
if (keySet.has(key)) continue;
|
|
2038
2095
|
// Don't copy an undeclared __proto__ into the result; assignment to a plain {} would replace the result prototype. But in strict mode it is still an unknown key, so report it before skipping.
|
|
@@ -2070,28 +2127,22 @@ function handleCatchall(
|
|
|
2070
2127
|
});
|
|
2071
2128
|
}
|
|
2072
2129
|
|
|
2073
|
-
// Whichever object a def's `shape` currently answers from: the one the caller passed until the first read, the frozen copy after it. Keyed by def, so a def rebuilt by a builder is simply absent rather than inheriting the source's. Read its keys with `Object.keys`, which does not invoke them — that is what lets a discriminated union check its discriminator without resolving an option whose getters reference the union being constructed.
|
|
2074
|
-
const propShapes = new WeakMap<object, Record<string, unknown>>();
|
|
2075
|
-
|
|
2076
2130
|
export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$constructor("$ZodObject", (inst, def) => {
|
|
2077
2131
|
// requires cast because technically $ZodObject doesn't extend
|
|
2078
2132
|
$ZodType.init(inst, def);
|
|
2079
|
-
// const sh = def.shape;
|
|
2080
2133
|
const desc = Object.getOwnPropertyDescriptor(def, "shape");
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
},
|
|
2094
|
-
});
|
|
2134
|
+
// a cloned def carries its source's accessor, which knows the shape it answers from; adopting that keeps the clone's keys readable without running it
|
|
2135
|
+
const sh = desc?.get ? (desc.get as util.ShapeGetter).raw : (def.shape ?? {});
|
|
2136
|
+
if (sh) {
|
|
2137
|
+
// Freezes the shape on first read, so its getters resolve once and every later read sees the same schemas.
|
|
2138
|
+
const get: util.ShapeGetter = () => {
|
|
2139
|
+
const newSh = { ...sh };
|
|
2140
|
+
Object.defineProperty(def, "shape", { value: newSh });
|
|
2141
|
+
get.raw = newSh;
|
|
2142
|
+
return newSh;
|
|
2143
|
+
};
|
|
2144
|
+
get.raw = sh;
|
|
2145
|
+
Object.defineProperty(def, "shape", { get });
|
|
2095
2146
|
}
|
|
2096
2147
|
|
|
2097
2148
|
const _normalized = util.cached(() => normalizeDef(def));
|
|
@@ -2137,8 +2188,14 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
|
|
|
2137
2188
|
|
|
2138
2189
|
const proms: Promise<any>[] = [];
|
|
2139
2190
|
const shape = value.shape;
|
|
2191
|
+
const abortEarly = ctx?.abortEarly;
|
|
2192
|
+
let seen = payload.issues.length;
|
|
2140
2193
|
|
|
2141
2194
|
for (const key of value.allKeys) {
|
|
2195
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
2196
|
+
if (util.aborted(payload, seen)) break;
|
|
2197
|
+
seen = payload.issues.length;
|
|
2198
|
+
}
|
|
2142
2199
|
if (key === "__proto__") continue;
|
|
2143
2200
|
const el = (shape as any)[key]!;
|
|
2144
2201
|
const optin = el._zod.optin;
|
|
@@ -2156,7 +2213,7 @@ export const $ZodObject: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$con
|
|
|
2156
2213
|
return proms.length ? Promise.all(proms).then(() => payload) : payload;
|
|
2157
2214
|
}
|
|
2158
2215
|
|
|
2159
|
-
return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);
|
|
2216
|
+
return handleCatchall(proms, input, payload, ctx, _normalized.value, inst, abortEarly === true);
|
|
2160
2217
|
};
|
|
2161
2218
|
});
|
|
2162
2219
|
|
|
@@ -2179,12 +2236,18 @@ export const $ZodObjectJIT: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$
|
|
|
2179
2236
|
|
|
2180
2237
|
const parseStr = (k: string) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
2181
2238
|
|
|
2182
|
-
//
|
|
2239
|
+
// prefixes in place, like util.prefixIssues. newResult must land before the early return: a catchall runs after this and would otherwise write onto the caller's input
|
|
2183
2240
|
const prefixStr = (id: string, k: string) => `
|
|
2241
|
+
let ${id}_ab = false;
|
|
2184
2242
|
for (let i = 0; i < ${id}.issues.length; i++) {
|
|
2185
2243
|
const iss = ${id}.issues[i];
|
|
2186
2244
|
iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
|
|
2187
2245
|
payload.issues.push(iss);
|
|
2246
|
+
if (iss.continue !== true) ${id}_ab = true;
|
|
2247
|
+
}
|
|
2248
|
+
if (${id}_ab && ctx && ctx.abortEarly) {
|
|
2249
|
+
payload.value = newResult;
|
|
2250
|
+
return payload;
|
|
2188
2251
|
}`;
|
|
2189
2252
|
|
|
2190
2253
|
doc.write(`const input = payload.value;`);
|
|
@@ -2236,6 +2299,10 @@ export const $ZodObjectJIT: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$
|
|
|
2236
2299
|
input: undefined,
|
|
2237
2300
|
path: [${k}]
|
|
2238
2301
|
});
|
|
2302
|
+
if (ctx && ctx.abortEarly) {
|
|
2303
|
+
payload.value = newResult;
|
|
2304
|
+
return payload;
|
|
2305
|
+
}
|
|
2239
2306
|
}
|
|
2240
2307
|
|
|
2241
2308
|
if (${id}_present) {
|
|
@@ -2296,7 +2363,7 @@ export const $ZodObjectJIT: core.$constructor<$ZodObject> = /*@__PURE__*/ core.$
|
|
|
2296
2363
|
payload = fastpass(payload, ctx);
|
|
2297
2364
|
|
|
2298
2365
|
if (!catchall) return payload;
|
|
2299
|
-
return handleCatchall([], input, payload, ctx, value, inst);
|
|
2366
|
+
return handleCatchall([], input, payload, ctx, value, inst, ctx?.abortEarly === true);
|
|
2300
2367
|
}
|
|
2301
2368
|
|
|
2302
2369
|
return superParse(payload, ctx);
|
|
@@ -2610,9 +2677,9 @@ export const $ZodDiscriminatedUnion: core.$constructor<$ZodDiscriminatedUnion> =
|
|
|
2610
2677
|
return propValues;
|
|
2611
2678
|
});
|
|
2612
2679
|
|
|
2613
|
-
// Checked now rather than in the lookup map below, so an option that lacks the discriminator fails at the `discriminatedUnion` call instead of on the first object parsed. Options whose shape cannot be enumerated without resolving it — pipes
|
|
2680
|
+
// Checked now rather than in the lookup map below, so an option that lacks the discriminator fails at the `discriminatedUnion` call instead of on the first object parsed. Options whose shape cannot be enumerated without resolving it — pipes and lazies — are left to the map.
|
|
2614
2681
|
def.options.forEach((option, i) => {
|
|
2615
|
-
const propShape =
|
|
2682
|
+
const propShape = util.rawShape(option._zod.def);
|
|
2616
2683
|
if (propShape && !Object.prototype.hasOwnProperty.call(propShape, def.discriminator)) {
|
|
2617
2684
|
throw new Error(`Invalid discriminated union option at index "${i}"`);
|
|
2618
2685
|
}
|
|
@@ -2959,6 +3026,9 @@ export const $ZodTuple: core.$constructor<$ZodTuple> = /*@__PURE__*/ core.$const
|
|
|
2959
3026
|
|
|
2960
3027
|
// Run every item in parallel, collecting results into an indexed array. The post-processing in `handleTupleResults` walks them in order so it can decide whether an absent optional-output error can truncate the tail or must be reported to preserve required output.
|
|
2961
3028
|
const itemResults: ParsePayload[] = new Array(items.length);
|
|
3029
|
+
// only tracked when there is a rest loop to skip
|
|
3030
|
+
const abortEarly = def.rest ? ctx?.abortEarly : undefined;
|
|
3031
|
+
let itemAborted = false;
|
|
2962
3032
|
for (let i = 0; i < items.length; i++) {
|
|
2963
3033
|
const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);
|
|
2964
3034
|
if (r instanceof Promise) {
|
|
@@ -2969,13 +3039,20 @@ export const $ZodTuple: core.$constructor<$ZodTuple> = /*@__PURE__*/ core.$const
|
|
|
2969
3039
|
);
|
|
2970
3040
|
} else {
|
|
2971
3041
|
itemResults[i] = r;
|
|
3042
|
+
if (abortEarly && !itemAborted && r.issues.length) itemAborted = util.aborted(r);
|
|
2972
3043
|
}
|
|
2973
3044
|
}
|
|
2974
3045
|
|
|
2975
|
-
|
|
3046
|
+
// sound because rest is non-empty exactly when every fixed index is present, the one case handleTupleResults cannot discard an item's issues
|
|
3047
|
+
if (def.rest && !itemAborted) {
|
|
2976
3048
|
let i = items.length - 1;
|
|
2977
3049
|
const rest = input.slice(items.length);
|
|
3050
|
+
let seen = payload.issues.length;
|
|
2978
3051
|
for (const el of rest) {
|
|
3052
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
3053
|
+
if (util.aborted(payload, seen)) break;
|
|
3054
|
+
seen = payload.issues.length;
|
|
3055
|
+
}
|
|
2979
3056
|
i++;
|
|
2980
3057
|
const result = def.rest._zod.run({ value: el, issues: [] }, ctx);
|
|
2981
3058
|
if (result instanceof Promise) {
|
|
@@ -3145,6 +3222,7 @@ export const $ZodRecord: core.$constructor<$ZodRecord> = /*@__PURE__*/ core.$con
|
|
|
3145
3222
|
return payload;
|
|
3146
3223
|
}
|
|
3147
3224
|
|
|
3225
|
+
// no guard in either loop below: a record's invalid_key aborts but an enclosing intersection can reconcile it, so a stopped loop hides keys the sibling does not own and the intersection then rejects nothing
|
|
3148
3226
|
const proms: Promise<any>[] = [];
|
|
3149
3227
|
|
|
3150
3228
|
const values = def.keyType._zod.values;
|
|
@@ -3349,8 +3427,14 @@ export const $ZodMap: core.$constructor<$ZodMap> = /*@__PURE__*/ core.$construct
|
|
|
3349
3427
|
|
|
3350
3428
|
const proms: Promise<any>[] = [];
|
|
3351
3429
|
payload.value = memo ? memo.alloc(inst, payload, new Map(), ctx) : new Map();
|
|
3430
|
+
const abortEarly = ctx?.abortEarly;
|
|
3431
|
+
let seen = payload.issues.length;
|
|
3352
3432
|
|
|
3353
3433
|
for (const [key, value] of input) {
|
|
3434
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
3435
|
+
if (util.aborted(payload, seen)) break;
|
|
3436
|
+
seen = payload.issues.length;
|
|
3437
|
+
}
|
|
3354
3438
|
const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
3355
3439
|
const valueResult = def.valueType._zod.run({ value: value, issues: [] }, ctx);
|
|
3356
3440
|
|
|
@@ -3454,7 +3538,13 @@ export const $ZodSet: core.$constructor<$ZodSet> = /*@__PURE__*/ core.$construct
|
|
|
3454
3538
|
|
|
3455
3539
|
const proms: Promise<any>[] = [];
|
|
3456
3540
|
payload.value = memo ? memo.alloc(inst, payload, new Set(), ctx) : new Set();
|
|
3541
|
+
const abortEarly = ctx?.abortEarly;
|
|
3542
|
+
let seen = payload.issues.length;
|
|
3457
3543
|
for (const item of input) {
|
|
3544
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
3545
|
+
if (util.aborted(payload, seen)) break;
|
|
3546
|
+
seen = payload.issues.length;
|
|
3547
|
+
}
|
|
3458
3548
|
const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);
|
|
3459
3549
|
if (result instanceof Promise) {
|
|
3460
3550
|
proms.push(result.then((result) => handleSetResult(result, payload)));
|
|
@@ -3513,12 +3603,13 @@ export const $ZodEnum: core.$constructor<$ZodEnum> = /*@__PURE__*/ core.$constru
|
|
|
3513
3603
|
const valuesSet = new Set<util.Primitive>(values);
|
|
3514
3604
|
inst._zod.values = valuesSet;
|
|
3515
3605
|
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3606
|
+
util.defineLazyInternal(inst, "pattern", (zod) => {
|
|
3607
|
+
const patternValues = util.getEnumValues(zod.def.entries).filter((k) => util.propertyKeyTypes.has(typeof k));
|
|
3608
|
+
// unmatchable fallback, RE2-safe: an empty alternation would compile to /^()$/, which matches ""
|
|
3609
|
+
return new RegExp(
|
|
3610
|
+
patternValues.length ? `^(${patternValues.map((o) => util.escapeRegex(o.toString())).join("|")})$` : "^[^\\s\\S]$"
|
|
3611
|
+
);
|
|
3612
|
+
});
|
|
3522
3613
|
|
|
3523
3614
|
inst._zod.parse = (payload, _ctx) => {
|
|
3524
3615
|
const input = payload.value;
|
|
@@ -3568,14 +3659,19 @@ export const $ZodLiteral: core.$constructor<$ZodLiteral> = /*@__PURE__*/ core.$c
|
|
|
3568
3659
|
const values = new Set<util.Literal>(def.values);
|
|
3569
3660
|
inst._zod.values = values;
|
|
3570
3661
|
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3662
|
+
util.defineLazyInternal(inst, "pattern", (zod) => {
|
|
3663
|
+
const vals = zod.def.values;
|
|
3664
|
+
// unmatchable fallback, RE2-safe: an empty alternation would compile to /^()$/, which matches ""
|
|
3665
|
+
return new RegExp(
|
|
3666
|
+
vals.length
|
|
3667
|
+
? `^(${vals
|
|
3668
|
+
.map((o: util.Literal) =>
|
|
3669
|
+
typeof o === "string" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o)
|
|
3670
|
+
)
|
|
3671
|
+
.join("|")})$`
|
|
3672
|
+
: "^[^\\s\\S]$"
|
|
3673
|
+
);
|
|
3674
|
+
});
|
|
3579
3675
|
|
|
3580
3676
|
inst._zod.parse = (payload, _ctx) => {
|
|
3581
3677
|
const input = payload.value;
|
|
@@ -4574,6 +4670,51 @@ export type $PartsToTemplateLiteral<Parts extends $ZodTemplateLiteralPart[]> = [
|
|
|
4574
4670
|
: never
|
|
4575
4671
|
: never;
|
|
4576
4672
|
|
|
4673
|
+
// a leaf's pattern source with its own checks folded in: the last pattern-carrying check wins, else length bounds narrow the catch-all, else an integer format narrows the number form. the fold lives here instead of on `_zod.pattern` so a bundle without template literals never pays for it
|
|
4674
|
+
function leafPattern(schema: $ZodType): string | undefined {
|
|
4675
|
+
const def = schema._zod.def as { pattern?: RegExp; format?: string; checks?: checks.$ZodCheck[] };
|
|
4676
|
+
let pattern = def.pattern;
|
|
4677
|
+
let isInt = !!def.format?.includes("int");
|
|
4678
|
+
let minimum: number | undefined;
|
|
4679
|
+
let maximum: number | undefined;
|
|
4680
|
+
for (const ch of def.checks ?? []) {
|
|
4681
|
+
const d = ch._zod.def as { pattern?: RegExp; format?: string; minimum?: number; maximum?: number; length?: number };
|
|
4682
|
+
if (d.pattern) pattern = d.pattern;
|
|
4683
|
+
isInt ||= !!d.format?.includes("int");
|
|
4684
|
+
const lo = d.minimum ?? d.length;
|
|
4685
|
+
const hi = d.maximum ?? d.length;
|
|
4686
|
+
if (lo !== undefined && (minimum === undefined || lo > minimum)) minimum = lo;
|
|
4687
|
+
if (hi !== undefined && (maximum === undefined || hi < maximum)) maximum = hi;
|
|
4688
|
+
}
|
|
4689
|
+
if (pattern) return pattern.source;
|
|
4690
|
+
// an empty range matches nothing at runtime, and `{8,5}` is not a legal quantifier
|
|
4691
|
+
if (minimum !== undefined && maximum !== undefined && minimum > maximum) return "(?!)";
|
|
4692
|
+
if (minimum !== undefined || maximum !== undefined) return regexes.string({ minimum, maximum }).source;
|
|
4693
|
+
const own = schema._zod.pattern;
|
|
4694
|
+
return (isInt && own === regexes.number ? regexes.integer : own)?.source;
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4697
|
+
// a part's pattern source. a wrapper's pattern embeds its inner pattern's source verbatim, so the folded form is substituted in place without knowing the wrapper's own composition; a union's options are joined the way the union builds its own pattern
|
|
4698
|
+
function partPattern(schema: $ZodType): string | undefined {
|
|
4699
|
+
const def = schema._zod.def as { innerType?: $ZodType; options?: $ZodType[] };
|
|
4700
|
+
const own = schema._zod.pattern?.source;
|
|
4701
|
+
// lazy resolves its inner on the internals, not the def
|
|
4702
|
+
const inner = def.innerType ?? (schema._zod as { innerType?: $ZodType }).innerType;
|
|
4703
|
+
if (inner) {
|
|
4704
|
+
const before = inner._zod.pattern?.source;
|
|
4705
|
+
const after = partPattern(inner);
|
|
4706
|
+
if (own && before && after && after !== before) {
|
|
4707
|
+
return own.replace(util.cleanRegex(before), () => util.cleanRegex(after));
|
|
4708
|
+
}
|
|
4709
|
+
return own;
|
|
4710
|
+
}
|
|
4711
|
+
if (def.options) {
|
|
4712
|
+
const sources = def.options.map(partPattern);
|
|
4713
|
+
if (sources.every(Boolean)) return `^(${sources.map((s) => util.cleanRegex(s!)).join("|")})$`;
|
|
4714
|
+
}
|
|
4715
|
+
return leafPattern(schema);
|
|
4716
|
+
}
|
|
4717
|
+
|
|
4577
4718
|
export const $ZodTemplateLiteral: core.$constructor<$ZodTemplateLiteral> = /*@__PURE__*/ core.$constructor(
|
|
4578
4719
|
"$ZodTemplateLiteral",
|
|
4579
4720
|
(inst, def) => {
|
|
@@ -4582,18 +4723,11 @@ export const $ZodTemplateLiteral: core.$constructor<$ZodTemplateLiteral> = /*@__
|
|
|
4582
4723
|
for (const part of def.parts) {
|
|
4583
4724
|
if (typeof part === "object" && part !== null) {
|
|
4584
4725
|
// is Zod schema
|
|
4585
|
-
|
|
4586
|
-
|
|
4726
|
+
const source = partPattern(part);
|
|
4727
|
+
if (!source) {
|
|
4587
4728
|
throw new Error(`Invalid template literal part, no pattern found: ${[...(part as any)._zod.traits].shift()}`);
|
|
4588
4729
|
}
|
|
4589
|
-
|
|
4590
|
-
const source = part._zod.pattern instanceof RegExp ? part._zod.pattern.source : part._zod.pattern;
|
|
4591
|
-
|
|
4592
|
-
if (!source) throw new Error(`Invalid template literal part: ${part._zod.traits}`);
|
|
4593
|
-
|
|
4594
|
-
const start = source.startsWith("^") ? 1 : 0;
|
|
4595
|
-
const end = source.endsWith("$") ? source.length - 1 : source.length;
|
|
4596
|
-
regexParts.push(source.slice(start, end));
|
|
4730
|
+
regexParts.push(util.cleanRegex(source));
|
|
4597
4731
|
} else if (part === null || util.primitiveTypes.has(typeof part)) {
|
|
4598
4732
|
regexParts.push(util.escapeRegex(`${part}`));
|
|
4599
4733
|
} else {
|
|
@@ -4956,6 +5090,101 @@ function handleRefineResult(result: unknown, payload: ParsePayload, input: unkno
|
|
|
4956
5090
|
}
|
|
4957
5091
|
}
|
|
4958
5092
|
|
|
5093
|
+
////////////////////////////////////////
|
|
5094
|
+
////////////////////////////////////////
|
|
5095
|
+
////////// //////////
|
|
5096
|
+
////////// $ZodProperties //////////
|
|
5097
|
+
////////// //////////
|
|
5098
|
+
////////////////////////////////////////
|
|
5099
|
+
////////////////////////////////////////
|
|
5100
|
+
export interface $ZodPropertiesDef<Shape extends $ZodShape = $ZodShape> extends $ZodTypeDef, checks.$ZodCheckDef {
|
|
5101
|
+
type: "properties";
|
|
5102
|
+
check: "properties";
|
|
5103
|
+
shape: Shape;
|
|
5104
|
+
}
|
|
5105
|
+
|
|
5106
|
+
// both sides infer the INPUT type: the shape is asserted and its results discarded, so a default, catch or transform inside it would make an output-typed inference a lie. The check side widens a literal to its primitive, so spreading over a `string` property still type-checks (#6520).
|
|
5107
|
+
export interface $ZodPropertiesInternals<Shape extends $ZodShape = $ZodShape>
|
|
5108
|
+
extends $ZodTypeInternals<$InferObjectInput<Shape, {}>, $InferObjectInput<Shape, {}>>,
|
|
5109
|
+
checks.$ZodCheckInternals<{ -readonly [k in keyof Shape]: util.Widen<core.input<Shape[k]>> }> {
|
|
5110
|
+
def: $ZodPropertiesDef<Shape>;
|
|
5111
|
+
isst: errors.$ZodIssueInvalidType;
|
|
5112
|
+
issc: errors.$ZodIssue;
|
|
5113
|
+
}
|
|
5114
|
+
|
|
5115
|
+
export interface $ZodProperties<Shape extends $ZodShape = $ZodShape> extends $ZodType {
|
|
5116
|
+
_zod: $ZodPropertiesInternals<Shape>;
|
|
5117
|
+
// yields the schema itself, so pre-4.6 `.check(...z.properties(shape))` spread call sites keep working
|
|
5118
|
+
[Symbol.iterator](): Iterator<this>;
|
|
5119
|
+
}
|
|
5120
|
+
|
|
5121
|
+
// asserts in place: the child result's value is discarded, matching z.property(), because a nested object or array schema rebuilds its output even when nothing transformed
|
|
5122
|
+
function handlePropertiesResult(result: ParsePayload, payload: ParsePayload, key: string | symbol): void {
|
|
5123
|
+
if (result.issues.length) {
|
|
5124
|
+
payload.issues.push(...util.prefixIssues(key, result.issues));
|
|
5125
|
+
}
|
|
5126
|
+
}
|
|
5127
|
+
|
|
5128
|
+
export const $ZodProperties: core.$constructor<$ZodProperties> = /*@__PURE__*/ core.$constructor(
|
|
5129
|
+
"$ZodProperties",
|
|
5130
|
+
(inst, def) => {
|
|
5131
|
+
// $ZodType.init prepends an instance that already carries the $ZodCheck trait to its own `checks`, which would run the shape a second time and cost the parse context. Initializing the check trait after it keeps the schema role in `parse`, where the context arrives.
|
|
5132
|
+
$ZodType.init(inst, def);
|
|
5133
|
+
checks.$ZodCheck.init(inst, def);
|
|
5134
|
+
|
|
5135
|
+
const memo = core.globalConfig.memoizer;
|
|
5136
|
+
memo?.attach(inst);
|
|
5137
|
+
|
|
5138
|
+
// key and schema snapshotted together: reading one live and the other cached lets a later mutation of the caller's shape object pair a stale key with a missing schema
|
|
5139
|
+
let entries!: [string | symbol, $ZodType][];
|
|
5140
|
+
const runShape = (payload: ParsePayload, ctx: ParseContextInternal): util.MaybeAsync<void> => {
|
|
5141
|
+
entries ??= Reflect.ownKeys(def.shape).map((key) => [key, (def.shape as any)[key] as $ZodType]);
|
|
5142
|
+
const input = payload.value as any;
|
|
5143
|
+
let proms: Promise<any>[] | undefined;
|
|
5144
|
+
for (const [key, schema] of entries) {
|
|
5145
|
+
const result = schema._zod.run({ value: input[key], issues: [] }, ctx);
|
|
5146
|
+
if (result instanceof Promise) {
|
|
5147
|
+
proms ??= [];
|
|
5148
|
+
proms.push(result.then((result) => handlePropertiesResult(result, payload, key)));
|
|
5149
|
+
} else {
|
|
5150
|
+
handlePropertiesResult(result, payload, key);
|
|
5151
|
+
}
|
|
5152
|
+
}
|
|
5153
|
+
if (proms) return Promise.all(proms).then(() => undefined);
|
|
5154
|
+
return undefined;
|
|
5155
|
+
};
|
|
5156
|
+
|
|
5157
|
+
inst._zod.parse = (payload, ctx) => {
|
|
5158
|
+
const input = payload.value;
|
|
5159
|
+
// as a schema this is the type gate, and it infers an object shape, so a primitive is a type error. A function passes: its properties read like any other object's, and z.instanceof allows one.
|
|
5160
|
+
if (input === null || (typeof input !== "object" && typeof input !== "function")) {
|
|
5161
|
+
payload.issues.push({ expected: "object", code: "invalid_type", input, inst });
|
|
5162
|
+
return payload;
|
|
5163
|
+
}
|
|
5164
|
+
// both sides declare the shape's input type, so the assertion runs forward in either direction; encoding the children backward would reject the very type this schema claims to take
|
|
5165
|
+
if (ctx.direction === "backward") ctx = { ...ctx, direction: "forward" };
|
|
5166
|
+
// the input is its own output here, so it registers as its own memo entry: a cycle re-entering this node hits the bucket instead of recursing forever
|
|
5167
|
+
if (memo) memo.alloc(inst, payload, input, ctx);
|
|
5168
|
+
const result = runShape(payload, ctx);
|
|
5169
|
+
return result instanceof Promise ? result.then(() => payload) : payload;
|
|
5170
|
+
};
|
|
5171
|
+
|
|
5172
|
+
// as a check the base schema already typed the value, so this only asserts the properties — which read on a primitive too, matching z.property() on a string's length. It gets no context of its own, so a cycle through a spread schema is not tracked.
|
|
5173
|
+
inst._zod.check = (payload) => {
|
|
5174
|
+
if (payload.value == null) {
|
|
5175
|
+
payload.issues.push({ expected: "object", code: "invalid_type", input: payload.value, inst });
|
|
5176
|
+
return undefined;
|
|
5177
|
+
}
|
|
5178
|
+
return runShape(payload, {});
|
|
5179
|
+
};
|
|
5180
|
+
},
|
|
5181
|
+
{
|
|
5182
|
+
*[Symbol.iterator]() {
|
|
5183
|
+
yield this;
|
|
5184
|
+
},
|
|
5185
|
+
}
|
|
5186
|
+
);
|
|
5187
|
+
|
|
4959
5188
|
export type $ZodTypes =
|
|
4960
5189
|
| $ZodString
|
|
4961
5190
|
| $ZodNumber
|
|
@@ -4988,6 +5217,7 @@ export type $ZodTypes =
|
|
|
4988
5217
|
| $ZodPrefault
|
|
4989
5218
|
| $ZodTemplateLiteral
|
|
4990
5219
|
| $ZodCustom
|
|
5220
|
+
| $ZodProperties
|
|
4991
5221
|
| $ZodTransform
|
|
4992
5222
|
| $ZodNonOptional
|
|
4993
5223
|
| $ZodReadonly
|
|
@@ -5022,6 +5252,7 @@ export type $ZodStringFormatTypes =
|
|
|
5022
5252
|
| $ZodBase64URL
|
|
5023
5253
|
| $ZodE164
|
|
5024
5254
|
| $ZodCreditCard
|
|
5255
|
+
| $ZodIBAN
|
|
5025
5256
|
| $ZodJWT
|
|
5026
5257
|
| $ZodCustomStringFormat<"hex">
|
|
5027
5258
|
| $ZodCustomStringFormat<util.HashFormat>
|