@es-joy/jsoe 0.26.1 → 0.27.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/.gitignore +10 -0
- package/.npmignore +9 -0
- package/CHANGES.md +43 -0
- package/README.md +3 -3
- package/badges/coverage-badge.svg +1 -1
- package/dist/formats/schema.d.ts.map +1 -1
- package/dist/fundamentalTypes/arrayType.d.ts.map +1 -1
- package/dist/fundamentalTypes/stringType.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/typeChoices.d.ts.map +1 -1
- package/dist/types.d.ts.map +1 -1
- package/eslint.config.js +36 -27
- package/package.json +12 -11
- package/pnpm-workspace.yaml +3 -2
- package/src/formats/schema.js +35 -6
- package/src/fundamentalTypes/arrayType.js +30 -6
- package/src/fundamentalTypes/stringType.js +5 -0
- package/src/typeChoices.js +3 -1
- package/src/types.js +7 -0
- package/vendor/typeson-registry/dist/index.js +83 -10
- package/vendor/zod/classic/checks.d.ts +1 -1
- package/vendor/zod/classic/checks.js +1 -1
- package/vendor/zod/classic/external.d.ts +1 -1
- package/vendor/zod/classic/external.js +1 -1
- package/vendor/zod/classic/from-json-schema.js +245 -24
- package/vendor/zod/classic/schemas.d.ts +17 -1
- package/vendor/zod/classic/schemas.js +77 -29
- package/vendor/zod/core/api.d.ts +6 -4
- package/vendor/zod/core/api.js +17 -2
- package/vendor/zod/core/checks.d.ts +1 -1
- package/vendor/zod/core/checks.js +0 -96
- package/vendor/zod/core/compile.d.ts +18 -4
- package/vendor/zod/core/compile.js +146 -67
- package/vendor/zod/core/doc.js +7 -2
- package/vendor/zod/core/errors.js +2 -5
- package/vendor/zod/core/json-schema-generator.js +2 -2
- package/vendor/zod/core/json-schema-processors.d.ts +17 -0
- package/vendor/zod/core/json-schema-processors.js +195 -64
- package/vendor/zod/core/memoizer.js +72 -23
- package/vendor/zod/core/parse.js +37 -16
- package/vendor/zod/core/regexes.d.ts +2 -0
- package/vendor/zod/core/regexes.js +8 -4
- package/vendor/zod/core/schemas.d.ts +42 -7
- package/vendor/zod/core/schemas.js +301 -94
- package/vendor/zod/core/to-json-schema.d.ts +7 -3
- package/vendor/zod/core/to-json-schema.js +8 -7
- package/vendor/zod/core/util.d.ts +25 -4
- package/vendor/zod/core/util.js +160 -143
- package/vendor/zod/core/versions.d.ts +1 -1
- package/vendor/zod/core/versions.js +2 -2
- package/vendor/zod/core/visit.js +12 -0
- package/vendor/zod/locales/ar.js +1 -0
- package/vendor/zod/locales/az.js +1 -0
- package/vendor/zod/locales/be.js +1 -0
- package/vendor/zod/locales/bg.js +1 -0
- package/vendor/zod/locales/bn.js +1 -0
- package/vendor/zod/locales/ca.js +1 -0
- package/vendor/zod/locales/ckb.js +1 -0
- package/vendor/zod/locales/cs.js +1 -0
- package/vendor/zod/locales/da.js +1 -0
- package/vendor/zod/locales/de.js +1 -0
- package/vendor/zod/locales/el.js +1 -0
- package/vendor/zod/locales/en.js +1 -0
- package/vendor/zod/locales/eo.js +1 -0
- package/vendor/zod/locales/es.js +1 -0
- package/vendor/zod/locales/fa.js +1 -0
- package/vendor/zod/locales/fi.js +1 -0
- package/vendor/zod/locales/fr-CA.js +1 -0
- package/vendor/zod/locales/fr.js +1 -0
- package/vendor/zod/locales/gu.js +1 -0
- package/vendor/zod/locales/he.js +1 -0
- package/vendor/zod/locales/hi.js +1 -0
- package/vendor/zod/locales/hr.js +1 -0
- package/vendor/zod/locales/hu.js +1 -0
- package/vendor/zod/locales/hy.js +1 -0
- package/vendor/zod/locales/id.js +1 -0
- package/vendor/zod/locales/index.d.ts +1 -0
- package/vendor/zod/locales/index.js +1 -0
- package/vendor/zod/locales/is.js +1 -0
- package/vendor/zod/locales/it.js +1 -0
- package/vendor/zod/locales/ja.js +1 -0
- package/vendor/zod/locales/ka.js +1 -0
- package/vendor/zod/locales/km.js +1 -0
- package/vendor/zod/locales/kn.js +1 -0
- package/vendor/zod/locales/ko.js +1 -0
- package/vendor/zod/locales/lt.js +1 -0
- package/vendor/zod/locales/mk.js +1 -0
- package/vendor/zod/locales/ms.js +1 -0
- package/vendor/zod/locales/ne.js +1 -0
- package/vendor/zod/locales/nl.js +1 -0
- package/vendor/zod/locales/nn.js +1 -0
- package/vendor/zod/locales/no.js +1 -0
- package/vendor/zod/locales/ota.js +1 -0
- package/vendor/zod/locales/pl.js +1 -0
- package/vendor/zod/locales/ps.js +1 -0
- package/vendor/zod/locales/pt-BR.js +1 -0
- package/vendor/zod/locales/pt.js +1 -0
- package/vendor/zod/locales/ro.js +1 -0
- package/vendor/zod/locales/ru.js +1 -0
- package/vendor/zod/locales/sk.js +1 -0
- package/vendor/zod/locales/sl.js +1 -0
- package/vendor/zod/locales/sv.js +1 -0
- package/vendor/zod/locales/ta.js +1 -0
- package/vendor/zod/locales/tg.d.ts +4 -0
- package/vendor/zod/locales/tg.js +116 -0
- package/vendor/zod/locales/th.js +1 -0
- package/vendor/zod/locales/tk.js +1 -0
- package/vendor/zod/locales/tr.js +1 -0
- package/vendor/zod/locales/uk.js +1 -0
- package/vendor/zod/locales/ur.js +1 -0
- package/vendor/zod/locales/uz.js +1 -0
- package/vendor/zod/locales/vi.js +1 -0
- package/vendor/zod/locales/yo.js +1 -0
- package/vendor/zod/locales/zh-CN.js +1 -0
- package/vendor/zod/locales/zh-TW.js +1 -0
- package/vendor/zod/mini/checks.d.ts +1 -1
- package/vendor/zod/mini/checks.js +1 -1
- package/vendor/zod/mini/external.d.ts +1 -1
- package/vendor/zod/mini/external.js +1 -1
- package/vendor/zod/mini/schemas.d.ts +8 -0
- package/vendor/zod/mini/schemas.js +19 -2
- package/vendor/zodexy/dist/esm/index.js +34 -1
- package/vendor/zodexy/dist/schema.zodexy.json +18 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as checks from "./checks.js";
|
|
2
2
|
import * as core from "./core.js";
|
|
3
3
|
import { Doc } from "./doc.js";
|
|
4
|
-
import { parse, parseAsync
|
|
4
|
+
import { parse, parseAsync } from "./parse.js";
|
|
5
5
|
import * as regexes from "./regexes.js";
|
|
6
6
|
import * as util from "./util.js";
|
|
7
7
|
import { version } from "./versions.js";
|
|
@@ -128,16 +128,24 @@ export const $ZodType = /*@__PURE__*/ core.$constructor("$ZodType", (inst, def)
|
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
130
|
/** The Standard Schema surface for `inst`. Shared so wrappers can extend it without forcing it. */
|
|
131
|
-
|
|
131
|
+
// 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
|
|
132
|
+
const toStandardResult = (r, ctx) => r.issues.length ? { issues: r.issues.map((iss) => util.finalizeIssue(iss, ctx, core.config())) } : { value: r.value };
|
|
133
|
+
async function validateAsync(inst, value) {
|
|
134
|
+
const ctx = { async: true };
|
|
135
|
+
return toStandardResult((await inst._zod.run({ value, issues: [] }, ctx)), ctx);
|
|
136
|
+
}
|
|
132
137
|
export function standardProps(inst) {
|
|
133
138
|
return {
|
|
134
139
|
validate: (value) => {
|
|
140
|
+
const ctx = { async: false };
|
|
135
141
|
try {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
return safeParseAsync(inst, value).then(toStandardResult);
|
|
142
|
+
const r = inst._zod.run({ value, issues: [] }, ctx);
|
|
143
|
+
if (!(r instanceof Promise))
|
|
144
|
+
return toStandardResult(r, ctx);
|
|
140
145
|
}
|
|
146
|
+
catch (_) { }
|
|
147
|
+
// async function so a synchronously throwing check rejects instead of escaping validate
|
|
148
|
+
return validateAsync(inst, value);
|
|
141
149
|
},
|
|
142
150
|
vendor: "zod",
|
|
143
151
|
version: 1,
|
|
@@ -146,7 +154,8 @@ export function standardProps(inst) {
|
|
|
146
154
|
export { clone } from "./util.js";
|
|
147
155
|
export const $ZodString = /*@__PURE__*/ core.$constructor("$ZodString", (inst, def) => {
|
|
148
156
|
$ZodType.init(inst, def);
|
|
149
|
-
|
|
157
|
+
// a format's own pattern, else unbounded; a template literal derives the check-aware form itself
|
|
158
|
+
inst._zod.pattern = def.pattern ?? regexes.anyString;
|
|
150
159
|
inst._zod.parse = (payload, _) => {
|
|
151
160
|
if (def.coerce)
|
|
152
161
|
try {
|
|
@@ -332,13 +341,6 @@ export const $ZodKSUID = /*@__PURE__*/ core.$constructor("$ZodKSUID", (inst, def
|
|
|
332
341
|
export const $ZodISODateTime = /*@__PURE__*/ core.$constructor("$ZodISODateTime", (inst, def) => {
|
|
333
342
|
def.pattern ?? (def.pattern = regexes.datetime(def));
|
|
334
343
|
$ZodStringFormat.init(inst, def);
|
|
335
|
-
// 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
|
|
336
|
-
if (def.local || def.precision === -1) {
|
|
337
|
-
inst._zod.bag.laxFormat = true;
|
|
338
|
-
inst._zod.onattach.push((s) => {
|
|
339
|
-
s._zod.bag.laxFormat = true;
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
344
|
});
|
|
343
345
|
export const $ZodISODate = /*@__PURE__*/ core.$constructor("$ZodISODate", (inst, def) => {
|
|
344
346
|
def.pattern ?? (def.pattern = regexes.date);
|
|
@@ -355,7 +357,6 @@ export const $ZodISODuration = /*@__PURE__*/ core.$constructor("$ZodISODuration"
|
|
|
355
357
|
export const $ZodIPv4 = /*@__PURE__*/ core.$constructor("$ZodIPv4", (inst, def) => {
|
|
356
358
|
def.pattern ?? (def.pattern = regexes.ipv4);
|
|
357
359
|
$ZodStringFormat.init(inst, def);
|
|
358
|
-
inst._zod.bag.format = `ipv4`;
|
|
359
360
|
});
|
|
360
361
|
/** An IPv6 address is written with hex digits, colons and dots, and nothing else. The guard is what makes the check below an IPv6 check: `new URL("http://[...]")` parses an authority, not an address, so `@` and `\` re-delimit it and `"::@1\\"` validates against the host `0.0.0.1`. The URL parser also deletes ASCII tab, LF and CR rather than failing, which is how `"::1\n"` validated as `::1`. */
|
|
361
362
|
const ipv6Alphabet = /^[0-9a-fA-F:.]+$/;
|
|
@@ -374,7 +375,6 @@ export function isValidIPv6(value) {
|
|
|
374
375
|
export const $ZodIPv6 = /*@__PURE__*/ core.$constructor("$ZodIPv6", (inst, def) => {
|
|
375
376
|
def.pattern ?? (def.pattern = regexes.ipv6);
|
|
376
377
|
$ZodStringFormat.init(inst, def);
|
|
377
|
-
inst._zod.bag.format = `ipv6`;
|
|
378
378
|
inst._zod.check = (payload) => {
|
|
379
379
|
if (!isValidIPv6(payload.value)) {
|
|
380
380
|
payload.issues.push({
|
|
@@ -390,7 +390,6 @@ export const $ZodIPv6 = /*@__PURE__*/ core.$constructor("$ZodIPv6", (inst, def)
|
|
|
390
390
|
export const $ZodMAC = /*@__PURE__*/ core.$constructor("$ZodMAC", (inst, def) => {
|
|
391
391
|
def.pattern ?? (def.pattern = regexes.mac(def.delimiter));
|
|
392
392
|
$ZodStringFormat.init(inst, def);
|
|
393
|
-
inst._zod.bag.format = `mac`;
|
|
394
393
|
});
|
|
395
394
|
export const $ZodCIDRv4 = /*@__PURE__*/ core.$constructor("$ZodCIDRv4", (inst, def) => {
|
|
396
395
|
def.pattern ?? (def.pattern = regexes.cidrv4);
|
|
@@ -443,10 +442,11 @@ export function isValidBase64(data) {
|
|
|
443
442
|
return false;
|
|
444
443
|
}
|
|
445
444
|
}
|
|
445
|
+
// 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
|
|
446
|
+
export const base64Charset = /^[0-9a-zA-Z+/]*={0,2}$/;
|
|
446
447
|
export const $ZodBase64 = /*@__PURE__*/ core.$constructor("$ZodBase64", (inst, def) => {
|
|
447
|
-
def.pattern ?? (def.pattern =
|
|
448
|
+
def.pattern ?? (def.pattern = base64Charset);
|
|
448
449
|
$ZodStringFormat.init(inst, def);
|
|
449
|
-
inst._zod.bag.contentEncoding = "base64";
|
|
450
450
|
inst._zod.check = (payload) => {
|
|
451
451
|
if (isValidBase64(payload.value))
|
|
452
452
|
return;
|
|
@@ -459,18 +459,19 @@ export const $ZodBase64 = /*@__PURE__*/ core.$constructor("$ZodBase64", (inst, d
|
|
|
459
459
|
});
|
|
460
460
|
};
|
|
461
461
|
});
|
|
462
|
-
//////////////////////////////
|
|
462
|
+
////////////////////////////// ZodBase64URL //////////////////////////////
|
|
463
|
+
// lax on purpose: the quantified regexes.base64url overflows the regex stack on multi-MB input; isValidBase64 enforces length on the padded string
|
|
464
|
+
export const base64urlCharset = /^[A-Za-z0-9_-]*$/;
|
|
463
465
|
export function isValidBase64URL(data) {
|
|
464
|
-
if (!
|
|
466
|
+
if (!base64urlCharset.test(data))
|
|
465
467
|
return false;
|
|
466
468
|
const base64 = data.replace(/[-_]/g, (c) => (c === "-" ? "+" : "/"));
|
|
467
469
|
const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
|
|
468
470
|
return isValidBase64(padded);
|
|
469
471
|
}
|
|
470
472
|
export const $ZodBase64URL = /*@__PURE__*/ core.$constructor("$ZodBase64URL", (inst, def) => {
|
|
471
|
-
def.pattern ?? (def.pattern =
|
|
473
|
+
def.pattern ?? (def.pattern = base64urlCharset);
|
|
472
474
|
$ZodStringFormat.init(inst, def);
|
|
473
|
-
inst._zod.bag.contentEncoding = "base64url";
|
|
474
475
|
inst._zod.check = (payload) => {
|
|
475
476
|
if (isValidBase64URL(payload.value))
|
|
476
477
|
return;
|
|
@@ -495,7 +496,7 @@ function isLuhnAlgo(digits) {
|
|
|
495
496
|
let bit = 1;
|
|
496
497
|
let sum = 0;
|
|
497
498
|
while (length) {
|
|
498
|
-
const value =
|
|
499
|
+
const value = digits.charCodeAt(--length) - 48;
|
|
499
500
|
bit ^= 1;
|
|
500
501
|
sum += bit ? [0, 2, 4, 6, 8, 1, 3, 5, 7, 9][value] : value;
|
|
501
502
|
}
|
|
@@ -522,6 +523,42 @@ export const $ZodCreditCard = /*@__PURE__*/ core.$constructor("$ZodCreditCard",
|
|
|
522
523
|
});
|
|
523
524
|
};
|
|
524
525
|
});
|
|
526
|
+
////////////////////////////// ZodIBAN //////////////////////////////
|
|
527
|
+
// iso 7064 mod 97-10 checksum without BigInt
|
|
528
|
+
function isIso7064Mod97(iban) {
|
|
529
|
+
let remainder = 0;
|
|
530
|
+
const len = iban.length;
|
|
531
|
+
for (let i = 4; i < len; i++) {
|
|
532
|
+
const code = iban.charCodeAt(i);
|
|
533
|
+
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
534
|
+
}
|
|
535
|
+
for (let i = 0; i < 4; i++) {
|
|
536
|
+
const code = iban.charCodeAt(i);
|
|
537
|
+
remainder = (code >= 65 ? remainder * 100 + (code - 55) : remainder * 10 + (code - 48)) % 97;
|
|
538
|
+
}
|
|
539
|
+
return remainder === 1;
|
|
540
|
+
}
|
|
541
|
+
export function isValidIBAN(input) {
|
|
542
|
+
if (!regexes.iban.test(input))
|
|
543
|
+
return false;
|
|
544
|
+
return isIso7064Mod97(input);
|
|
545
|
+
}
|
|
546
|
+
export const $ZodIBAN = /*@__PURE__*/ core.$constructor("$ZodIBAN", (inst, def) => {
|
|
547
|
+
// shape only — checksum is not expressible as a pattern
|
|
548
|
+
def.pattern ?? (def.pattern = regexes.iban);
|
|
549
|
+
$ZodStringFormat.init(inst, def);
|
|
550
|
+
inst._zod.check = (payload) => {
|
|
551
|
+
if (isValidIBAN(payload.value))
|
|
552
|
+
return;
|
|
553
|
+
payload.issues.push({
|
|
554
|
+
code: "invalid_format",
|
|
555
|
+
format: "iban",
|
|
556
|
+
input: payload.value,
|
|
557
|
+
inst,
|
|
558
|
+
continue: !def.abort,
|
|
559
|
+
});
|
|
560
|
+
};
|
|
561
|
+
});
|
|
525
562
|
////////////////////////////// ZodJWT //////////////////////////////
|
|
526
563
|
export function isValidJWT(token, algorithm = null) {
|
|
527
564
|
try {
|
|
@@ -575,7 +612,7 @@ export const $ZodCustomStringFormat = /*@__PURE__*/ core.$constructor("$ZodCusto
|
|
|
575
612
|
});
|
|
576
613
|
export const $ZodNumber = /*@__PURE__*/ core.$constructor("$ZodNumber", (inst, def) => {
|
|
577
614
|
$ZodType.init(inst, def);
|
|
578
|
-
inst._zod.pattern =
|
|
615
|
+
inst._zod.pattern = regexes.number;
|
|
579
616
|
inst._zod.parse = (payload, _ctx) => {
|
|
580
617
|
if (def.coerce)
|
|
581
618
|
try {
|
|
@@ -783,6 +820,7 @@ export const $ZodArray = /*@__PURE__*/ core.$constructor("$ZodArray", (inst, def
|
|
|
783
820
|
}
|
|
784
821
|
payload.value = memo ? memo.alloc(inst, payload, Array(input.length), ctx) : Array(input.length);
|
|
785
822
|
const proms = [];
|
|
823
|
+
const abortEarly = ctx?.abortEarly;
|
|
786
824
|
for (let i = 0; i < input.length; i++) {
|
|
787
825
|
const item = input[i];
|
|
788
826
|
const result = def.element._zod.run({
|
|
@@ -794,6 +832,9 @@ export const $ZodArray = /*@__PURE__*/ core.$constructor("$ZodArray", (inst, def
|
|
|
794
832
|
}
|
|
795
833
|
else {
|
|
796
834
|
handleArrayResult(result, payload, i);
|
|
835
|
+
// the element's payload is authoritative here, since handleArrayResult forwards every issue; an object's is not, because it drops a failed absent optional
|
|
836
|
+
if (abortEarly && result.issues.length !== 0 && util.aborted(result))
|
|
837
|
+
break;
|
|
797
838
|
}
|
|
798
839
|
}
|
|
799
840
|
if (proms.length) {
|
|
@@ -860,14 +901,21 @@ function normalizeDef(def) {
|
|
|
860
901
|
optionalKeys: new Set(okeys),
|
|
861
902
|
};
|
|
862
903
|
}
|
|
863
|
-
function handleCatchall(proms, input, payload, ctx, def, inst) {
|
|
904
|
+
function handleCatchall(proms, input, payload, ctx, def, inst, abortEarly) {
|
|
864
905
|
const unrecognized = [];
|
|
865
906
|
const keySet = def.keySet;
|
|
866
907
|
const _catchall = def.catchall._zod;
|
|
867
908
|
const t = _catchall.def.type;
|
|
868
909
|
const optin = _catchall.optin;
|
|
869
910
|
const optout = _catchall.optout;
|
|
911
|
+
// starts at 0, not the current length: the shape phase already ran and may have aborted
|
|
912
|
+
let seen = 0;
|
|
870
913
|
for (const key in input) {
|
|
914
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
915
|
+
if (util.aborted(payload, seen))
|
|
916
|
+
break;
|
|
917
|
+
seen = payload.issues.length;
|
|
918
|
+
}
|
|
871
919
|
// Must precede the __proto__ branch: a declared key is not unrecognized, even though the shape loop deliberately strips __proto__ from the parsed output.
|
|
872
920
|
if (keySet.has(key))
|
|
873
921
|
continue;
|
|
@@ -905,26 +953,22 @@ function handleCatchall(proms, input, payload, ctx, def, inst) {
|
|
|
905
953
|
return payload;
|
|
906
954
|
});
|
|
907
955
|
}
|
|
908
|
-
// 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.
|
|
909
|
-
const propShapes = new WeakMap();
|
|
910
956
|
export const $ZodObject = /*@__PURE__*/ core.$constructor("$ZodObject", (inst, def) => {
|
|
911
957
|
// requires cast because technically $ZodObject doesn't extend
|
|
912
958
|
$ZodType.init(inst, def);
|
|
913
|
-
// const sh = def.shape;
|
|
914
959
|
const desc = Object.getOwnPropertyDescriptor(def, "shape");
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
});
|
|
960
|
+
// 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
|
|
961
|
+
const sh = desc?.get ? desc.get.raw : (def.shape ?? {});
|
|
962
|
+
if (sh) {
|
|
963
|
+
// Freezes the shape on first read, so its getters resolve once and every later read sees the same schemas.
|
|
964
|
+
const get = () => {
|
|
965
|
+
const newSh = { ...sh };
|
|
966
|
+
Object.defineProperty(def, "shape", { value: newSh });
|
|
967
|
+
get.raw = newSh;
|
|
968
|
+
return newSh;
|
|
969
|
+
};
|
|
970
|
+
get.raw = sh;
|
|
971
|
+
Object.defineProperty(def, "shape", { get });
|
|
928
972
|
}
|
|
929
973
|
const _normalized = util.cached(() => normalizeDef(def));
|
|
930
974
|
util.defineLazyInternal(inst, "propValues", (zod) => {
|
|
@@ -965,7 +1009,14 @@ export const $ZodObject = /*@__PURE__*/ core.$constructor("$ZodObject", (inst, d
|
|
|
965
1009
|
payload.value = memo ? memo.alloc(inst, payload, {}, ctx) : {};
|
|
966
1010
|
const proms = [];
|
|
967
1011
|
const shape = value.shape;
|
|
1012
|
+
const abortEarly = ctx?.abortEarly;
|
|
1013
|
+
let seen = payload.issues.length;
|
|
968
1014
|
for (const key of value.allKeys) {
|
|
1015
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
1016
|
+
if (util.aborted(payload, seen))
|
|
1017
|
+
break;
|
|
1018
|
+
seen = payload.issues.length;
|
|
1019
|
+
}
|
|
969
1020
|
if (key === "__proto__")
|
|
970
1021
|
continue;
|
|
971
1022
|
const el = shape[key];
|
|
@@ -982,7 +1033,7 @@ export const $ZodObject = /*@__PURE__*/ core.$constructor("$ZodObject", (inst, d
|
|
|
982
1033
|
if (!catchall) {
|
|
983
1034
|
return proms.length ? Promise.all(proms).then(() => payload) : payload;
|
|
984
1035
|
}
|
|
985
|
-
return handleCatchall(proms, input, payload, ctx, _normalized.value, inst);
|
|
1036
|
+
return handleCatchall(proms, input, payload, ctx, _normalized.value, inst, abortEarly === true);
|
|
986
1037
|
};
|
|
987
1038
|
});
|
|
988
1039
|
export const $ZodObjectJIT = /*@__PURE__*/ core.$constructor("$ZodObjectJIT", (inst, def) => {
|
|
@@ -997,12 +1048,18 @@ export const $ZodObjectJIT = /*@__PURE__*/ core.$constructor("$ZodObjectJIT", (i
|
|
|
997
1048
|
// a symbol has no source literal, so it is read as `syms[i]` off the closed-over scope
|
|
998
1049
|
const doc = new Doc(["payload", "ctx"], { shape, inst, memo, syms });
|
|
999
1050
|
const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
|
|
1000
|
-
//
|
|
1051
|
+
// 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
|
|
1001
1052
|
const prefixStr = (id, k) => `
|
|
1053
|
+
let ${id}_ab = false;
|
|
1002
1054
|
for (let i = 0; i < ${id}.issues.length; i++) {
|
|
1003
1055
|
const iss = ${id}.issues[i];
|
|
1004
1056
|
iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
|
|
1005
1057
|
payload.issues.push(iss);
|
|
1058
|
+
if (iss.continue !== true) ${id}_ab = true;
|
|
1059
|
+
}
|
|
1060
|
+
if (${id}_ab && ctx && ctx.abortEarly) {
|
|
1061
|
+
payload.value = newResult;
|
|
1062
|
+
return payload;
|
|
1006
1063
|
}`;
|
|
1007
1064
|
doc.write(`const input = payload.value;`);
|
|
1008
1065
|
const ids = Object.create(null);
|
|
@@ -1051,6 +1108,10 @@ export const $ZodObjectJIT = /*@__PURE__*/ core.$constructor("$ZodObjectJIT", (i
|
|
|
1051
1108
|
input: undefined,
|
|
1052
1109
|
path: [${k}]
|
|
1053
1110
|
});
|
|
1111
|
+
if (ctx && ctx.abortEarly) {
|
|
1112
|
+
payload.value = newResult;
|
|
1113
|
+
return payload;
|
|
1114
|
+
}
|
|
1054
1115
|
}
|
|
1055
1116
|
|
|
1056
1117
|
if (${id}_present) {
|
|
@@ -1106,7 +1167,7 @@ export const $ZodObjectJIT = /*@__PURE__*/ core.$constructor("$ZodObjectJIT", (i
|
|
|
1106
1167
|
payload = fastpass(payload, ctx);
|
|
1107
1168
|
if (!catchall)
|
|
1108
1169
|
return payload;
|
|
1109
|
-
return handleCatchall([], input, payload, ctx, value, inst);
|
|
1170
|
+
return handleCatchall([], input, payload, ctx, value, inst, ctx?.abortEarly === true);
|
|
1110
1171
|
}
|
|
1111
1172
|
return superParse(payload, ctx);
|
|
1112
1173
|
};
|
|
@@ -1243,22 +1304,38 @@ export const $ZodXor = /*@__PURE__*/ core.$constructor("$ZodXor", (inst, def) =>
|
|
|
1243
1304
|
});
|
|
1244
1305
|
};
|
|
1245
1306
|
});
|
|
1246
|
-
/** Returns the option
|
|
1307
|
+
/** Returns the option whose discriminator claims `value`, or throws if ambiguous. */
|
|
1247
1308
|
export function getDiscriminatedOption(union, value) {
|
|
1248
1309
|
const internals = union._zod;
|
|
1249
1310
|
let map = internals.bag.optionsMap;
|
|
1250
1311
|
if (!map) {
|
|
1251
|
-
map =
|
|
1252
|
-
const { options, discriminator } = internals.def;
|
|
1253
|
-
for (const option of options) {
|
|
1254
|
-
// First declaration wins, matching the order the parse path resolves a duplicate in.
|
|
1255
|
-
for (const v of option._zod.propValues?.[discriminator] ?? [])
|
|
1256
|
-
if (!map.has(v))
|
|
1257
|
-
map.set(v, option);
|
|
1258
|
-
}
|
|
1312
|
+
map = discriminatorMap(internals.def);
|
|
1259
1313
|
internals.bag.optionsMap = map;
|
|
1260
1314
|
}
|
|
1261
|
-
|
|
1315
|
+
const option = map.get(value);
|
|
1316
|
+
if (option === null)
|
|
1317
|
+
throw new Error(`Ambiguous discriminator value "${String(value)}"`);
|
|
1318
|
+
return option;
|
|
1319
|
+
}
|
|
1320
|
+
function discriminatorMap(def) {
|
|
1321
|
+
const map = new Map();
|
|
1322
|
+
for (const option of def.options) {
|
|
1323
|
+
const values = option._zod.propValues?.[def.discriminator];
|
|
1324
|
+
if (!values || values.size === 0)
|
|
1325
|
+
throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(option)}"`);
|
|
1326
|
+
for (const value of values) {
|
|
1327
|
+
if (map.has(value)) {
|
|
1328
|
+
if (value !== undefined)
|
|
1329
|
+
throw new Error(`Duplicate discriminator value "${String(value)}"`);
|
|
1330
|
+
// keep the collision marked so a later member cannot reclaim it
|
|
1331
|
+
map.set(value, null);
|
|
1332
|
+
}
|
|
1333
|
+
else {
|
|
1334
|
+
map.set(value, option);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
return map;
|
|
1262
1339
|
}
|
|
1263
1340
|
export const $ZodDiscriminatedUnion =
|
|
1264
1341
|
/*@__PURE__*/
|
|
@@ -1268,10 +1345,13 @@ core.$constructor("$ZodDiscriminatedUnion", (inst, def) => {
|
|
|
1268
1345
|
const _super = inst._zod.parse;
|
|
1269
1346
|
util.defineLazyInternal(inst, "propValues", (zod) => {
|
|
1270
1347
|
const propValues = {};
|
|
1348
|
+
let undefinedCount = 0;
|
|
1271
1349
|
for (const option of zod.def.options) {
|
|
1272
1350
|
const pv = option._zod.propValues;
|
|
1273
1351
|
if (!pv || Object.keys(pv).length === 0)
|
|
1274
1352
|
throw new Error(`Invalid discriminated union option at index "${zod.def.options.indexOf(option)}"`);
|
|
1353
|
+
if (pv[zod.def.discriminator]?.has(undefined))
|
|
1354
|
+
undefinedCount++;
|
|
1275
1355
|
for (const [k, v] of Object.entries(pv)) {
|
|
1276
1356
|
if (!Object.prototype.hasOwnProperty.call(propValues, k)) {
|
|
1277
1357
|
util.assignProp(propValues, k, new Set());
|
|
@@ -1281,31 +1361,18 @@ core.$constructor("$ZodDiscriminatedUnion", (inst, def) => {
|
|
|
1281
1361
|
}
|
|
1282
1362
|
}
|
|
1283
1363
|
}
|
|
1364
|
+
if (!zod.def.unionFallback && undefinedCount > 1)
|
|
1365
|
+
propValues[zod.def.discriminator]?.delete(undefined);
|
|
1284
1366
|
return propValues;
|
|
1285
1367
|
});
|
|
1286
|
-
// 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
|
|
1368
|
+
// 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.
|
|
1287
1369
|
def.options.forEach((option, i) => {
|
|
1288
|
-
const propShape =
|
|
1370
|
+
const propShape = util.rawShape(option._zod.def);
|
|
1289
1371
|
if (propShape && !Object.prototype.hasOwnProperty.call(propShape, def.discriminator)) {
|
|
1290
1372
|
throw new Error(`Invalid discriminated union option at index "${i}"`);
|
|
1291
1373
|
}
|
|
1292
1374
|
});
|
|
1293
|
-
const disc = util.cached(() =>
|
|
1294
|
-
const opts = def.options;
|
|
1295
|
-
const map = new Map();
|
|
1296
|
-
for (const o of opts) {
|
|
1297
|
-
const values = o._zod.propValues?.[def.discriminator];
|
|
1298
|
-
if (!values || values.size === 0)
|
|
1299
|
-
throw new Error(`Invalid discriminated union option at index "${def.options.indexOf(o)}"`);
|
|
1300
|
-
for (const v of values) {
|
|
1301
|
-
if (map.has(v)) {
|
|
1302
|
-
throw new Error(`Duplicate discriminator value "${String(v)}"`);
|
|
1303
|
-
}
|
|
1304
|
-
map.set(v, o);
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
return map;
|
|
1308
|
-
});
|
|
1375
|
+
const disc = util.cached(() => discriminatorMap(def));
|
|
1309
1376
|
inst._zod.parse = (payload, ctx) => {
|
|
1310
1377
|
const input = payload.value;
|
|
1311
1378
|
if (!util.isObject(input)) {
|
|
@@ -1317,8 +1384,10 @@ core.$constructor("$ZodDiscriminatedUnion", (inst, def) => {
|
|
|
1317
1384
|
});
|
|
1318
1385
|
return payload;
|
|
1319
1386
|
}
|
|
1320
|
-
const
|
|
1321
|
-
|
|
1387
|
+
const value = input?.[def.discriminator];
|
|
1388
|
+
const opt = disc.value.get(value);
|
|
1389
|
+
// forward metadata cannot choose an encoder for an absent tag
|
|
1390
|
+
if (opt && (value !== undefined || ctx.direction !== "backward")) {
|
|
1322
1391
|
return opt._zod.run(payload, ctx);
|
|
1323
1392
|
}
|
|
1324
1393
|
// Fall back to union matching when the fast discriminator path fails:
|
|
@@ -1333,7 +1402,7 @@ core.$constructor("$ZodDiscriminatedUnion", (inst, def) => {
|
|
|
1333
1402
|
errors: [],
|
|
1334
1403
|
note: "No matching discriminator",
|
|
1335
1404
|
discriminator: def.discriminator,
|
|
1336
|
-
options: Array.from(disc.value.keys()),
|
|
1405
|
+
options: Array.from(disc.value.keys()).filter((value) => disc.value.get(value) !== null),
|
|
1337
1406
|
input,
|
|
1338
1407
|
path: [def.discriminator],
|
|
1339
1408
|
inst,
|
|
@@ -1506,6 +1575,9 @@ export const $ZodTuple = /*@__PURE__*/ core.$constructor("$ZodTuple", (inst, def
|
|
|
1506
1575
|
}
|
|
1507
1576
|
// 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.
|
|
1508
1577
|
const itemResults = new Array(items.length);
|
|
1578
|
+
// only tracked when there is a rest loop to skip
|
|
1579
|
+
const abortEarly = def.rest ? ctx?.abortEarly : undefined;
|
|
1580
|
+
let itemAborted = false;
|
|
1509
1581
|
for (let i = 0; i < items.length; i++) {
|
|
1510
1582
|
const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);
|
|
1511
1583
|
if (r instanceof Promise) {
|
|
@@ -1515,12 +1587,21 @@ export const $ZodTuple = /*@__PURE__*/ core.$constructor("$ZodTuple", (inst, def
|
|
|
1515
1587
|
}
|
|
1516
1588
|
else {
|
|
1517
1589
|
itemResults[i] = r;
|
|
1590
|
+
if (abortEarly && !itemAborted && r.issues.length)
|
|
1591
|
+
itemAborted = util.aborted(r);
|
|
1518
1592
|
}
|
|
1519
1593
|
}
|
|
1520
|
-
|
|
1594
|
+
// sound because rest is non-empty exactly when every fixed index is present, the one case handleTupleResults cannot discard an item's issues
|
|
1595
|
+
if (def.rest && !itemAborted) {
|
|
1521
1596
|
let i = items.length - 1;
|
|
1522
1597
|
const rest = input.slice(items.length);
|
|
1598
|
+
let seen = payload.issues.length;
|
|
1523
1599
|
for (const el of rest) {
|
|
1600
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
1601
|
+
if (util.aborted(payload, seen))
|
|
1602
|
+
break;
|
|
1603
|
+
seen = payload.issues.length;
|
|
1604
|
+
}
|
|
1524
1605
|
i++;
|
|
1525
1606
|
const result = def.rest._zod.run({ value: el, issues: [] }, ctx);
|
|
1526
1607
|
if (result instanceof Promise) {
|
|
@@ -1602,6 +1683,7 @@ export const $ZodRecord = /*@__PURE__*/ core.$constructor("$ZodRecord", (inst, d
|
|
|
1602
1683
|
});
|
|
1603
1684
|
return payload;
|
|
1604
1685
|
}
|
|
1686
|
+
// 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
|
|
1605
1687
|
const proms = [];
|
|
1606
1688
|
const values = def.keyType._zod.values;
|
|
1607
1689
|
if (values && !def.partial) {
|
|
@@ -1773,7 +1855,14 @@ export const $ZodMap = /*@__PURE__*/ core.$constructor("$ZodMap", (inst, def) =>
|
|
|
1773
1855
|
}
|
|
1774
1856
|
const proms = [];
|
|
1775
1857
|
payload.value = memo ? memo.alloc(inst, payload, new Map(), ctx) : new Map();
|
|
1858
|
+
const abortEarly = ctx?.abortEarly;
|
|
1859
|
+
let seen = payload.issues.length;
|
|
1776
1860
|
for (const [key, value] of input) {
|
|
1861
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
1862
|
+
if (util.aborted(payload, seen))
|
|
1863
|
+
break;
|
|
1864
|
+
seen = payload.issues.length;
|
|
1865
|
+
}
|
|
1777
1866
|
const keyResult = def.keyType._zod.run({ value: key, issues: [] }, ctx);
|
|
1778
1867
|
const valueResult = def.valueType._zod.run({ value: value, issues: [] }, ctx);
|
|
1779
1868
|
if (keyResult instanceof Promise || valueResult instanceof Promise) {
|
|
@@ -1839,7 +1928,14 @@ export const $ZodSet = /*@__PURE__*/ core.$constructor("$ZodSet", (inst, def) =>
|
|
|
1839
1928
|
}
|
|
1840
1929
|
const proms = [];
|
|
1841
1930
|
payload.value = memo ? memo.alloc(inst, payload, new Set(), ctx) : new Set();
|
|
1931
|
+
const abortEarly = ctx?.abortEarly;
|
|
1932
|
+
let seen = payload.issues.length;
|
|
1842
1933
|
for (const item of input) {
|
|
1934
|
+
if (abortEarly && payload.issues.length !== seen) {
|
|
1935
|
+
if (util.aborted(payload, seen))
|
|
1936
|
+
break;
|
|
1937
|
+
seen = payload.issues.length;
|
|
1938
|
+
}
|
|
1843
1939
|
const result = def.valueType._zod.run({ value: item, issues: [] }, ctx);
|
|
1844
1940
|
if (result instanceof Promise) {
|
|
1845
1941
|
proms.push(result.then((result) => handleSetResult(result, payload)));
|
|
@@ -1863,9 +1959,11 @@ export const $ZodEnum = /*@__PURE__*/ core.$constructor("$ZodEnum", (inst, def)
|
|
|
1863
1959
|
const values = util.getEnumValues(def.entries);
|
|
1864
1960
|
const valuesSet = new Set(values);
|
|
1865
1961
|
inst._zod.values = valuesSet;
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1962
|
+
util.defineLazyInternal(inst, "pattern", (zod) => {
|
|
1963
|
+
const patternValues = util.getEnumValues(zod.def.entries).filter((k) => util.propertyKeyTypes.has(typeof k));
|
|
1964
|
+
// unmatchable fallback, RE2-safe: an empty alternation would compile to /^()$/, which matches ""
|
|
1965
|
+
return new RegExp(patternValues.length ? `^(${patternValues.map((o) => util.escapeRegex(o.toString())).join("|")})$` : "^[^\\s\\S]$");
|
|
1966
|
+
});
|
|
1869
1967
|
inst._zod.parse = (payload, _ctx) => {
|
|
1870
1968
|
const input = payload.value;
|
|
1871
1969
|
if (valuesSet.has(input)) {
|
|
@@ -1884,12 +1982,15 @@ export const $ZodLiteral = /*@__PURE__*/ core.$constructor("$ZodLiteral", (inst,
|
|
|
1884
1982
|
$ZodType.init(inst, def);
|
|
1885
1983
|
const values = new Set(def.values);
|
|
1886
1984
|
inst._zod.values = values;
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1985
|
+
util.defineLazyInternal(inst, "pattern", (zod) => {
|
|
1986
|
+
const vals = zod.def.values;
|
|
1987
|
+
// unmatchable fallback, RE2-safe: an empty alternation would compile to /^()$/, which matches ""
|
|
1988
|
+
return new RegExp(vals.length
|
|
1989
|
+
? `^(${vals
|
|
1990
|
+
.map((o) => typeof o === "string" ? util.escapeRegex(o) : o ? util.escapeRegex(o.toString()) : String(o))
|
|
1991
|
+
.join("|")})$`
|
|
1992
|
+
: "^[^\\s\\S]$");
|
|
1993
|
+
});
|
|
1893
1994
|
inst._zod.parse = (payload, _ctx) => {
|
|
1894
1995
|
const input = payload.value;
|
|
1895
1996
|
if (values.has(input)) {
|
|
@@ -2253,22 +2354,67 @@ function handleReadonlyResult(payload) {
|
|
|
2253
2354
|
payload.value = Object.freeze(payload.value);
|
|
2254
2355
|
return payload;
|
|
2255
2356
|
}
|
|
2357
|
+
// 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
|
|
2358
|
+
function leafPattern(schema) {
|
|
2359
|
+
const def = schema._zod.def;
|
|
2360
|
+
let pattern = def.pattern;
|
|
2361
|
+
let isInt = !!def.format?.includes("int");
|
|
2362
|
+
let minimum;
|
|
2363
|
+
let maximum;
|
|
2364
|
+
for (const ch of def.checks ?? []) {
|
|
2365
|
+
const d = ch._zod.def;
|
|
2366
|
+
if (d.pattern)
|
|
2367
|
+
pattern = d.pattern;
|
|
2368
|
+
isInt || (isInt = !!d.format?.includes("int"));
|
|
2369
|
+
const lo = d.minimum ?? d.length;
|
|
2370
|
+
const hi = d.maximum ?? d.length;
|
|
2371
|
+
if (lo !== undefined && (minimum === undefined || lo > minimum))
|
|
2372
|
+
minimum = lo;
|
|
2373
|
+
if (hi !== undefined && (maximum === undefined || hi < maximum))
|
|
2374
|
+
maximum = hi;
|
|
2375
|
+
}
|
|
2376
|
+
if (pattern)
|
|
2377
|
+
return pattern.source;
|
|
2378
|
+
// an empty range matches nothing at runtime, and `{8,5}` is not a legal quantifier
|
|
2379
|
+
if (minimum !== undefined && maximum !== undefined && minimum > maximum)
|
|
2380
|
+
return "(?!)";
|
|
2381
|
+
if (minimum !== undefined || maximum !== undefined)
|
|
2382
|
+
return regexes.string({ minimum, maximum }).source;
|
|
2383
|
+
const own = schema._zod.pattern;
|
|
2384
|
+
return (isInt && own === regexes.number ? regexes.integer : own)?.source;
|
|
2385
|
+
}
|
|
2386
|
+
// 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
|
|
2387
|
+
function partPattern(schema) {
|
|
2388
|
+
const def = schema._zod.def;
|
|
2389
|
+
const own = schema._zod.pattern?.source;
|
|
2390
|
+
// lazy resolves its inner on the internals, not the def
|
|
2391
|
+
const inner = def.innerType ?? schema._zod.innerType;
|
|
2392
|
+
if (inner) {
|
|
2393
|
+
const before = inner._zod.pattern?.source;
|
|
2394
|
+
const after = partPattern(inner);
|
|
2395
|
+
if (own && before && after && after !== before) {
|
|
2396
|
+
return own.replace(util.cleanRegex(before), () => util.cleanRegex(after));
|
|
2397
|
+
}
|
|
2398
|
+
return own;
|
|
2399
|
+
}
|
|
2400
|
+
if (def.options) {
|
|
2401
|
+
const sources = def.options.map(partPattern);
|
|
2402
|
+
if (sources.every(Boolean))
|
|
2403
|
+
return `^(${sources.map((s) => util.cleanRegex(s)).join("|")})$`;
|
|
2404
|
+
}
|
|
2405
|
+
return leafPattern(schema);
|
|
2406
|
+
}
|
|
2256
2407
|
export const $ZodTemplateLiteral = /*@__PURE__*/ core.$constructor("$ZodTemplateLiteral", (inst, def) => {
|
|
2257
2408
|
$ZodType.init(inst, def);
|
|
2258
2409
|
const regexParts = [];
|
|
2259
2410
|
for (const part of def.parts) {
|
|
2260
2411
|
if (typeof part === "object" && part !== null) {
|
|
2261
2412
|
// is Zod schema
|
|
2262
|
-
|
|
2263
|
-
|
|
2413
|
+
const source = partPattern(part);
|
|
2414
|
+
if (!source) {
|
|
2264
2415
|
throw new Error(`Invalid template literal part, no pattern found: ${[...part._zod.traits].shift()}`);
|
|
2265
2416
|
}
|
|
2266
|
-
|
|
2267
|
-
if (!source)
|
|
2268
|
-
throw new Error(`Invalid template literal part: ${part._zod.traits}`);
|
|
2269
|
-
const start = source.startsWith("^") ? 1 : 0;
|
|
2270
|
-
const end = source.endsWith("$") ? source.length - 1 : source.length;
|
|
2271
|
-
regexParts.push(source.slice(start, end));
|
|
2417
|
+
regexParts.push(util.cleanRegex(source));
|
|
2272
2418
|
}
|
|
2273
2419
|
else if (part === null || util.primitiveTypes.has(typeof part)) {
|
|
2274
2420
|
regexParts.push(util.escapeRegex(`${part}`));
|
|
@@ -2438,3 +2584,64 @@ function handleRefineResult(result, payload, input, inst) {
|
|
|
2438
2584
|
payload.issues.push(util.issue(_iss));
|
|
2439
2585
|
}
|
|
2440
2586
|
}
|
|
2587
|
+
// 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
|
|
2588
|
+
function handlePropertiesResult(result, payload, key) {
|
|
2589
|
+
if (result.issues.length) {
|
|
2590
|
+
payload.issues.push(...util.prefixIssues(key, result.issues));
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
export const $ZodProperties = /*@__PURE__*/ core.$constructor("$ZodProperties", (inst, def) => {
|
|
2594
|
+
// $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.
|
|
2595
|
+
$ZodType.init(inst, def);
|
|
2596
|
+
checks.$ZodCheck.init(inst, def);
|
|
2597
|
+
const memo = core.globalConfig.memoizer;
|
|
2598
|
+
memo?.attach(inst);
|
|
2599
|
+
// 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
|
|
2600
|
+
let entries;
|
|
2601
|
+
const runShape = (payload, ctx) => {
|
|
2602
|
+
entries ?? (entries = Reflect.ownKeys(def.shape).map((key) => [key, def.shape[key]]));
|
|
2603
|
+
const input = payload.value;
|
|
2604
|
+
let proms;
|
|
2605
|
+
for (const [key, schema] of entries) {
|
|
2606
|
+
const result = schema._zod.run({ value: input[key], issues: [] }, ctx);
|
|
2607
|
+
if (result instanceof Promise) {
|
|
2608
|
+
proms ?? (proms = []);
|
|
2609
|
+
proms.push(result.then((result) => handlePropertiesResult(result, payload, key)));
|
|
2610
|
+
}
|
|
2611
|
+
else {
|
|
2612
|
+
handlePropertiesResult(result, payload, key);
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
if (proms)
|
|
2616
|
+
return Promise.all(proms).then(() => undefined);
|
|
2617
|
+
return undefined;
|
|
2618
|
+
};
|
|
2619
|
+
inst._zod.parse = (payload, ctx) => {
|
|
2620
|
+
const input = payload.value;
|
|
2621
|
+
// 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.
|
|
2622
|
+
if (input === null || (typeof input !== "object" && typeof input !== "function")) {
|
|
2623
|
+
payload.issues.push({ expected: "object", code: "invalid_type", input, inst });
|
|
2624
|
+
return payload;
|
|
2625
|
+
}
|
|
2626
|
+
// 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
|
|
2627
|
+
if (ctx.direction === "backward")
|
|
2628
|
+
ctx = { ...ctx, direction: "forward" };
|
|
2629
|
+
// 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
|
|
2630
|
+
if (memo)
|
|
2631
|
+
memo.alloc(inst, payload, input, ctx);
|
|
2632
|
+
const result = runShape(payload, ctx);
|
|
2633
|
+
return result instanceof Promise ? result.then(() => payload) : payload;
|
|
2634
|
+
};
|
|
2635
|
+
// 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.
|
|
2636
|
+
inst._zod.check = (payload) => {
|
|
2637
|
+
if (payload.value == null) {
|
|
2638
|
+
payload.issues.push({ expected: "object", code: "invalid_type", input: payload.value, inst });
|
|
2639
|
+
return undefined;
|
|
2640
|
+
}
|
|
2641
|
+
return runShape(payload, {});
|
|
2642
|
+
};
|
|
2643
|
+
}, {
|
|
2644
|
+
*[Symbol.iterator]() {
|
|
2645
|
+
yield this;
|
|
2646
|
+
},
|
|
2647
|
+
});
|