zod 4.6.2 → 4.6.4
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/README.md +2 -2
- package/package.json +1 -1
- package/src/v4/classic/checks.ts +1 -0
- package/src/v4/classic/schemas.ts +12 -29
- package/src/v4/classic/tests/assignability.test.ts +1 -0
- package/src/v4/classic/tests/cyclic-data.test.ts +2 -11
- package/src/v4/classic/tests/firstparty.test.ts +0 -4
- package/src/v4/classic/tests/instance-footprint.test.ts +22 -0
- package/src/v4/classic/tests/instanceof.test.ts +1 -1
- package/src/v4/classic/tests/number.test.ts +39 -0
- package/src/v4/classic/tests/properties.test.ts +34 -137
- package/src/v4/classic/tests/string.test.ts +70 -1
- package/src/v4/classic/tests/to-json-schema.test.ts +87 -35
- package/src/v4/core/api.ts +21 -29
- package/src/v4/core/checks.ts +61 -1
- package/src/v4/core/compile.ts +35 -24
- package/src/v4/core/core.ts +1 -3
- package/src/v4/core/json-schema-processors.ts +9 -63
- package/src/v4/core/memoizer.ts +2 -5
- package/src/v4/core/regexes.ts +4 -0
- package/src/v4/core/schemas.ts +36 -109
- package/src/v4/core/tests/compile-differential.test.ts +35 -0
- package/src/v4/core/tests/compile.test.ts +177 -0
- package/src/v4/core/tests/url-no-canparse.test.ts +118 -16
- package/src/v4/core/to-json-schema.ts +1 -1
- package/src/v4/core/util.ts +0 -4
- package/src/v4/core/versions.ts +1 -1
- package/src/v4/core/visit.ts +0 -11
- 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/tg.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 +1 -0
- package/src/v4/mini/schemas.ts +12 -23
- package/src/v4/mini/tests/index.test.ts +56 -0
- package/src/v4/mini/tests/string.test.ts +7 -0
- package/v4/classic/checks.cjs +2 -1
- 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/schemas.cjs +11 -15
- package/v4/classic/schemas.d.cts +2 -6
- package/v4/classic/schemas.d.ts +2 -6
- package/v4/classic/schemas.js +9 -13
- package/v4/core/api.cjs +11 -23
- package/v4/core/api.d.cts +8 -4
- package/v4/core/api.d.ts +8 -4
- package/v4/core/api.js +11 -23
- package/v4/core/checks.cjs +32 -1
- package/v4/core/checks.d.cts +16 -0
- package/v4/core/checks.d.ts +16 -0
- package/v4/core/checks.js +31 -0
- package/v4/core/compile.cjs +12 -17
- package/v4/core/compile.js +13 -18
- package/v4/core/core.cjs +1 -1
- package/v4/core/core.js +1 -1
- package/v4/core/json-schema-processors.cjs +8 -44
- package/v4/core/json-schema-processors.d.cts +0 -1
- package/v4/core/json-schema-processors.d.ts +0 -1
- package/v4/core/json-schema-processors.js +8 -43
- package/v4/core/memoizer.cjs +2 -5
- package/v4/core/memoizer.js +2 -5
- package/v4/core/regexes.cjs +4 -2
- package/v4/core/regexes.d.cts +1 -0
- package/v4/core/regexes.d.ts +1 -0
- package/v4/core/regexes.js +2 -0
- package/v4/core/schemas.cjs +33 -73
- package/v4/core/schemas.d.cts +7 -22
- package/v4/core/schemas.d.ts +7 -22
- package/v4/core/schemas.js +30 -72
- package/v4/core/to-json-schema.cjs +0 -1
- package/v4/core/to-json-schema.d.cts +0 -3
- package/v4/core/to-json-schema.d.ts +0 -3
- package/v4/core/to-json-schema.js +1 -1
- package/v4/core/util.cjs +0 -4
- package/v4/core/util.js +0 -4
- package/v4/core/versions.cjs +1 -1
- package/v4/core/versions.js +1 -1
- package/v4/core/visit.cjs +0 -12
- package/v4/core/visit.js +0 -12
- 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/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/tg.cjs +1 -0
- package/v4/locales/tg.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 +2 -1
- 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/schemas.cjs +11 -13
- package/v4/mini/schemas.d.cts +1 -4
- package/v4/mini/schemas.d.ts +1 -4
- package/v4/mini/schemas.js +9 -11
package/v4/core/checks.js
CHANGED
|
@@ -462,6 +462,37 @@ export const $ZodCheckProperty = /*@__PURE__*/ core.$constructor("$ZodCheckPrope
|
|
|
462
462
|
return;
|
|
463
463
|
};
|
|
464
464
|
});
|
|
465
|
+
export const $ZodCheckProperties = /*@__PURE__*/ core.$constructor("$ZodCheckProperties", (inst, def) => {
|
|
466
|
+
$ZodCheck.init(inst, def);
|
|
467
|
+
util.hide(inst, Symbol.iterator, function* () {
|
|
468
|
+
yield inst;
|
|
469
|
+
});
|
|
470
|
+
// 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
|
|
471
|
+
let entries;
|
|
472
|
+
inst._zod.check = (payload) => {
|
|
473
|
+
// the base schema already typed the value, so only a nullish one is rejected here: the properties read on a primitive too, matching z.property() on a string's length
|
|
474
|
+
if (payload.value == null) {
|
|
475
|
+
payload.issues.push({ expected: "object", code: "invalid_type", input: payload.value, inst });
|
|
476
|
+
return undefined;
|
|
477
|
+
}
|
|
478
|
+
entries ?? (entries = Reflect.ownKeys(def.shape).map((key) => [key, def.shape[key]]));
|
|
479
|
+
const input = payload.value;
|
|
480
|
+
let proms;
|
|
481
|
+
for (const [key, schema] of entries) {
|
|
482
|
+
const result = schema._zod.run({ value: input[key], issues: [] }, {});
|
|
483
|
+
if (result instanceof Promise) {
|
|
484
|
+
proms ?? (proms = []);
|
|
485
|
+
proms.push(result.then((result) => handleCheckPropertyResult(result, payload, key)));
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
handleCheckPropertyResult(result, payload, key);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
if (proms)
|
|
492
|
+
return Promise.all(proms).then(() => undefined);
|
|
493
|
+
return undefined;
|
|
494
|
+
};
|
|
495
|
+
});
|
|
465
496
|
export const $ZodCheckMimeType = /*@__PURE__*/ core.$constructor("$ZodCheckMimeType", (inst, def) => {
|
|
466
497
|
$ZodCheck.init(inst, def);
|
|
467
498
|
const mimeSet = new Set(def.mime);
|
package/v4/core/compile.cjs
CHANGED
|
@@ -361,7 +361,7 @@ function generateChecks(doc, ctx, schema, accessor) {
|
|
|
361
361
|
generatePropertyCheck(doc, ctx, def, currentAccessor);
|
|
362
362
|
break;
|
|
363
363
|
case "properties":
|
|
364
|
-
generatePropertiesChecks(doc, ctx, def, currentAccessor
|
|
364
|
+
generatePropertiesChecks(doc, ctx, def, currentAccessor);
|
|
365
365
|
break;
|
|
366
366
|
case "overwrite": {
|
|
367
367
|
// Overwrite transforms the value - create new variable for transformed result
|
|
@@ -489,15 +489,13 @@ function generateMimeTypeCheck(doc, ctx, def, accessor) {
|
|
|
489
489
|
}
|
|
490
490
|
}
|
|
491
491
|
// asserts each named property in place; children compile assert-only because z.properties never rebuilds its input
|
|
492
|
-
function generatePropertiesChecks(doc, ctx, def, accessor
|
|
493
|
-
// a custom `when` gates the assertion at runtime; inside a union a wrongly-run branch is absorbed as a branch failure rather than falling back, so refuse at codegen
|
|
492
|
+
function generatePropertiesChecks(doc, ctx, def, accessor) {
|
|
493
|
+
// a custom `when` gates the assertion at runtime; inside a union a wrongly-run branch is absorbed as a branch failure rather than falling back, so refuse at codegen
|
|
494
494
|
if (def.when) {
|
|
495
495
|
throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
|
|
496
496
|
}
|
|
497
|
-
// matches the runtime gate
|
|
498
|
-
doc.write(
|
|
499
|
-
? `if (${accessor} === null || (typeof ${accessor} !== "object" && typeof ${accessor} !== "function")) return INVALID;`
|
|
500
|
-
: `if (${accessor} == null) return INVALID;`);
|
|
497
|
+
// matches the runtime gate: the base schema already typed the value, so only a nullish one is rejected
|
|
498
|
+
doc.write(`if (${accessor} == null) return INVALID;`);
|
|
501
499
|
const shape = def.shape;
|
|
502
500
|
for (const key of Reflect.ownKeys(shape)) {
|
|
503
501
|
// a symbol has no source literal, so it is hoisted as a constant
|
|
@@ -610,8 +608,7 @@ const PATTERN_IS_COMPLETE = new Set([
|
|
|
610
608
|
"uuid",
|
|
611
609
|
"xid",
|
|
612
610
|
]);
|
|
613
|
-
|
|
614
|
-
function generateStringFormatCheck(doc, ctx, def, accessor) {
|
|
611
|
+
function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
615
612
|
// Some string formats do runtime validation beyond their advertised pattern. For cheap pure utility checks, hoist the runtime function and call it so the fast path stays correct without cloning the utility logic into codegen.
|
|
616
613
|
const fmt = def.format;
|
|
617
614
|
if (fmt === "base64") {
|
|
@@ -657,7 +654,7 @@ function generateStringFormatCheck(doc, ctx, def, accessor) {
|
|
|
657
654
|
formatDef.hostname !== undefined ||
|
|
658
655
|
formatDef.protocol !== undefined) {
|
|
659
656
|
// Same three predicates the runtime calls, in the same order, so there is no second URL implementation to drift. Which options exist is known now, so the calls the runtime makes conditionally are emitted conditionally instead.
|
|
660
|
-
const parseConst = addConstant(ctx, schemas_js_1.
|
|
657
|
+
const parseConst = addConstant(ctx, schemas_js_1.validateURL);
|
|
661
658
|
const defConst = addConstant(ctx, def);
|
|
662
659
|
const trimVar = newVar(ctx);
|
|
663
660
|
const urlVar = newVar(ctx);
|
|
@@ -672,6 +669,8 @@ function generateStringFormatCheck(doc, ctx, def, accessor) {
|
|
|
672
669
|
const protocolConst = addConstant(ctx, schemas_js_1.urlProtocolOk);
|
|
673
670
|
doc.write(`if (!${protocolConst}(${urlVar}, ${defConst}.protocol)) return INVALID;`);
|
|
674
671
|
}
|
|
672
|
+
if (!needsValue)
|
|
673
|
+
return null;
|
|
675
674
|
const outputVar = newVar(ctx);
|
|
676
675
|
const outputExpr = formatDef.normalize ? `${urlVar}.href` : `${addConstant(ctx, schemas_js_1.stripTabAndNewline)}(${trimVar})`;
|
|
677
676
|
doc.write(`const ${outputVar} = ${outputExpr};`);
|
|
@@ -736,7 +735,7 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
736
735
|
let typeAccessor;
|
|
737
736
|
switch (type) {
|
|
738
737
|
case "string":
|
|
739
|
-
typeAccessor = generateStringCheck(doc, ctx, schema, accessor);
|
|
738
|
+
typeAccessor = generateStringCheck(doc, ctx, schema, accessor, buildsValue);
|
|
740
739
|
break;
|
|
741
740
|
case "number":
|
|
742
741
|
typeAccessor = generateNumberCheck(doc, schema, accessor);
|
|
@@ -848,10 +847,6 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
848
847
|
case "custom":
|
|
849
848
|
typeAccessor = generateCustomCheck(doc, ctx, schema, accessor);
|
|
850
849
|
break;
|
|
851
|
-
case "properties":
|
|
852
|
-
generatePropertiesChecks(doc, ctx, schema._zod.def, accessor, true);
|
|
853
|
-
typeAccessor = accessor;
|
|
854
|
-
break;
|
|
855
850
|
case "transform":
|
|
856
851
|
typeAccessor = generateTransformCheck(doc, ctx, schema, accessor);
|
|
857
852
|
break;
|
|
@@ -869,13 +864,13 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
869
864
|
// Generate checks after the type-specific validation (may transform value)
|
|
870
865
|
return generateChecks(doc, ctx, schema, typeAccessor);
|
|
871
866
|
}
|
|
872
|
-
function generateStringCheck(doc, ctx, schema, accessor) {
|
|
867
|
+
function generateStringCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
873
868
|
doc.write(`if (typeof ${accessor} !== "string") return INVALID;`);
|
|
874
869
|
// z.email() carries its format on the def, z.string().email() in def.checks; both route here so the format table has no second copy to drift from.
|
|
875
870
|
const def = schema._zod.def;
|
|
876
871
|
if (def.format === undefined)
|
|
877
872
|
return accessor;
|
|
878
|
-
return generateStringFormatCheck(doc, ctx, def, accessor);
|
|
873
|
+
return generateStringFormatCheck(doc, ctx, def, accessor, needsValue);
|
|
879
874
|
}
|
|
880
875
|
function generateNumberCheck(doc, schema, accessor) {
|
|
881
876
|
// Runtime z.number() rejects NaN and ±Infinity. Number.isFinite covers both.
|
package/v4/core/compile.js
CHANGED
|
@@ -2,7 +2,7 @@ import { $ZodAsyncError } from "./core.js";
|
|
|
2
2
|
import { Doc } from "./doc.js";
|
|
3
3
|
import { isBackEdge, isRecursiveSchema } from "./memoizer.js";
|
|
4
4
|
import * as regexes from "./regexes.js";
|
|
5
|
-
import { isValidBase64, isValidBase64URL, isValidCIDRv6, isValidCreditCard, isValidIBAN, isValidIPv6, isValidJWT, mergeValues,
|
|
5
|
+
import { isValidBase64, isValidBase64URL, isValidCIDRv6, isValidCreditCard, isValidIBAN, isValidIPv6, isValidJWT, mergeValues, stripTabAndNewline, urlHostnameOk, urlProtocolOk, validateURL, } from "./schemas.js";
|
|
6
6
|
import * as util from "./util.js";
|
|
7
7
|
/** @internal Sentinel the compiled fast path returns when validation fails. */
|
|
8
8
|
export const INVALID = Symbol.for("zod.compile.invalid");
|
|
@@ -330,7 +330,7 @@ function generateChecks(doc, ctx, schema, accessor) {
|
|
|
330
330
|
generatePropertyCheck(doc, ctx, def, currentAccessor);
|
|
331
331
|
break;
|
|
332
332
|
case "properties":
|
|
333
|
-
generatePropertiesChecks(doc, ctx, def, currentAccessor
|
|
333
|
+
generatePropertiesChecks(doc, ctx, def, currentAccessor);
|
|
334
334
|
break;
|
|
335
335
|
case "overwrite": {
|
|
336
336
|
// Overwrite transforms the value - create new variable for transformed result
|
|
@@ -458,15 +458,13 @@ function generateMimeTypeCheck(doc, ctx, def, accessor) {
|
|
|
458
458
|
}
|
|
459
459
|
}
|
|
460
460
|
// asserts each named property in place; children compile assert-only because z.properties never rebuilds its input
|
|
461
|
-
function generatePropertiesChecks(doc, ctx, def, accessor
|
|
462
|
-
// a custom `when` gates the assertion at runtime; inside a union a wrongly-run branch is absorbed as a branch failure rather than falling back, so refuse at codegen
|
|
461
|
+
function generatePropertiesChecks(doc, ctx, def, accessor) {
|
|
462
|
+
// a custom `when` gates the assertion at runtime; inside a union a wrongly-run branch is absorbed as a branch failure rather than falling back, so refuse at codegen
|
|
463
463
|
if (def.when) {
|
|
464
464
|
throw new ZodCompileUnsupportedError(`check with a custom "when" condition`);
|
|
465
465
|
}
|
|
466
|
-
// matches the runtime gate
|
|
467
|
-
doc.write(
|
|
468
|
-
? `if (${accessor} === null || (typeof ${accessor} !== "object" && typeof ${accessor} !== "function")) return INVALID;`
|
|
469
|
-
: `if (${accessor} == null) return INVALID;`);
|
|
466
|
+
// matches the runtime gate: the base schema already typed the value, so only a nullish one is rejected
|
|
467
|
+
doc.write(`if (${accessor} == null) return INVALID;`);
|
|
470
468
|
const shape = def.shape;
|
|
471
469
|
for (const key of Reflect.ownKeys(shape)) {
|
|
472
470
|
// a symbol has no source literal, so it is hoisted as a constant
|
|
@@ -579,8 +577,7 @@ const PATTERN_IS_COMPLETE = new Set([
|
|
|
579
577
|
"uuid",
|
|
580
578
|
"xid",
|
|
581
579
|
]);
|
|
582
|
-
|
|
583
|
-
function generateStringFormatCheck(doc, ctx, def, accessor) {
|
|
580
|
+
function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
584
581
|
// Some string formats do runtime validation beyond their advertised pattern. For cheap pure utility checks, hoist the runtime function and call it so the fast path stays correct without cloning the utility logic into codegen.
|
|
585
582
|
const fmt = def.format;
|
|
586
583
|
if (fmt === "base64") {
|
|
@@ -626,7 +623,7 @@ function generateStringFormatCheck(doc, ctx, def, accessor) {
|
|
|
626
623
|
formatDef.hostname !== undefined ||
|
|
627
624
|
formatDef.protocol !== undefined) {
|
|
628
625
|
// Same three predicates the runtime calls, in the same order, so there is no second URL implementation to drift. Which options exist is known now, so the calls the runtime makes conditionally are emitted conditionally instead.
|
|
629
|
-
const parseConst = addConstant(ctx,
|
|
626
|
+
const parseConst = addConstant(ctx, validateURL);
|
|
630
627
|
const defConst = addConstant(ctx, def);
|
|
631
628
|
const trimVar = newVar(ctx);
|
|
632
629
|
const urlVar = newVar(ctx);
|
|
@@ -641,6 +638,8 @@ function generateStringFormatCheck(doc, ctx, def, accessor) {
|
|
|
641
638
|
const protocolConst = addConstant(ctx, urlProtocolOk);
|
|
642
639
|
doc.write(`if (!${protocolConst}(${urlVar}, ${defConst}.protocol)) return INVALID;`);
|
|
643
640
|
}
|
|
641
|
+
if (!needsValue)
|
|
642
|
+
return null;
|
|
644
643
|
const outputVar = newVar(ctx);
|
|
645
644
|
const outputExpr = formatDef.normalize ? `${urlVar}.href` : `${addConstant(ctx, stripTabAndNewline)}(${trimVar})`;
|
|
646
645
|
doc.write(`const ${outputVar} = ${outputExpr};`);
|
|
@@ -705,7 +704,7 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
705
704
|
let typeAccessor;
|
|
706
705
|
switch (type) {
|
|
707
706
|
case "string":
|
|
708
|
-
typeAccessor = generateStringCheck(doc, ctx, schema, accessor);
|
|
707
|
+
typeAccessor = generateStringCheck(doc, ctx, schema, accessor, buildsValue);
|
|
709
708
|
break;
|
|
710
709
|
case "number":
|
|
711
710
|
typeAccessor = generateNumberCheck(doc, schema, accessor);
|
|
@@ -817,10 +816,6 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
817
816
|
case "custom":
|
|
818
817
|
typeAccessor = generateCustomCheck(doc, ctx, schema, accessor);
|
|
819
818
|
break;
|
|
820
|
-
case "properties":
|
|
821
|
-
generatePropertiesChecks(doc, ctx, schema._zod.def, accessor, true);
|
|
822
|
-
typeAccessor = accessor;
|
|
823
|
-
break;
|
|
824
819
|
case "transform":
|
|
825
820
|
typeAccessor = generateTransformCheck(doc, ctx, schema, accessor);
|
|
826
821
|
break;
|
|
@@ -838,13 +833,13 @@ function generateCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
|
838
833
|
// Generate checks after the type-specific validation (may transform value)
|
|
839
834
|
return generateChecks(doc, ctx, schema, typeAccessor);
|
|
840
835
|
}
|
|
841
|
-
function generateStringCheck(doc, ctx, schema, accessor) {
|
|
836
|
+
function generateStringCheck(doc, ctx, schema, accessor, needsValue = true) {
|
|
842
837
|
doc.write(`if (typeof ${accessor} !== "string") return INVALID;`);
|
|
843
838
|
// z.email() carries its format on the def, z.string().email() in def.checks; both route here so the format table has no second copy to drift from.
|
|
844
839
|
const def = schema._zod.def;
|
|
845
840
|
if (def.format === undefined)
|
|
846
841
|
return accessor;
|
|
847
|
-
return generateStringFormatCheck(doc, ctx, def, accessor);
|
|
842
|
+
return generateStringFormatCheck(doc, ctx, def, accessor, needsValue);
|
|
848
843
|
}
|
|
849
844
|
function generateNumberCheck(doc, schema, accessor) {
|
|
850
845
|
// Runtime z.number() rejects NaN and ±Infinity. Number.isFinite covers both.
|
package/v4/core/core.cjs
CHANGED
package/v4/core/core.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.allProcessors = exports.lazyProcessor = exports.optionalProcessor = exports.promiseProcessor = exports.readonlyProcessor = exports.pipeProcessor = exports.catchProcessor = exports.prefaultProcessor = exports.defaultProcessor = exports.nonoptionalProcessor = exports.nullableProcessor = exports.recordProcessor = exports.tupleProcessor = exports.intersectionProcessor = exports.unionProcessor = exports.
|
|
26
|
+
exports.allProcessors = exports.lazyProcessor = exports.optionalProcessor = exports.promiseProcessor = exports.readonlyProcessor = exports.pipeProcessor = exports.catchProcessor = exports.prefaultProcessor = exports.defaultProcessor = exports.nonoptionalProcessor = exports.nullableProcessor = exports.recordProcessor = exports.tupleProcessor = exports.intersectionProcessor = exports.unionProcessor = exports.objectProcessor = exports.arrayProcessor = exports.setProcessor = exports.mapProcessor = exports.transformProcessor = exports.functionProcessor = exports.customProcessor = exports.successProcessor = exports.fileProcessor = exports.templateLiteralProcessor = exports.nanProcessor = exports.literalProcessor = exports.enumProcessor = exports.dateProcessor = exports.unknownProcessor = exports.anyProcessor = exports.neverProcessor = exports.voidProcessor = exports.undefinedProcessor = exports.nullProcessor = exports.symbolProcessor = exports.bigintProcessor = exports.booleanProcessor = exports.numberProcessor = exports.stringProcessor = void 0;
|
|
27
27
|
exports.aggregateChecks = aggregateChecks;
|
|
28
28
|
exports.toJSONSchema = toJSONSchema;
|
|
29
29
|
const regexes = __importStar(require("./regexes.cjs"));
|
|
@@ -447,18 +447,15 @@ const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
447
447
|
}));
|
|
448
448
|
}
|
|
449
449
|
// required keys
|
|
450
|
-
const
|
|
451
|
-
const
|
|
450
|
+
const requiredKeys = [];
|
|
451
|
+
for (const key of Object.keys(shape)) {
|
|
452
452
|
const field = def.shape[key];
|
|
453
|
-
if (ctx.io === "input") {
|
|
454
|
-
|
|
453
|
+
if (ctx.io === "input" ? inputOptin(field) === undefined : field._zod.optout === undefined) {
|
|
454
|
+
requiredKeys.push(key);
|
|
455
455
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
}));
|
|
460
|
-
if (requiredKeys.size > 0) {
|
|
461
|
-
json.required = Array.from(requiredKeys);
|
|
456
|
+
}
|
|
457
|
+
if (requiredKeys.length > 0) {
|
|
458
|
+
json.required = requiredKeys;
|
|
462
459
|
}
|
|
463
460
|
// catchall
|
|
464
461
|
if (def.catchall?._zod.def.type === "never") {
|
|
@@ -478,38 +475,6 @@ const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
478
475
|
}
|
|
479
476
|
};
|
|
480
477
|
exports.objectProcessor = objectProcessor;
|
|
481
|
-
// asserts named properties in place and passes everything else through, so no additionalProperties constraint is emitted
|
|
482
|
-
const propertiesProcessor = (schema, ctx, _json, params) => {
|
|
483
|
-
const json = _json;
|
|
484
|
-
const def = schema._zod.def;
|
|
485
|
-
// dropping a symbol key silently would emit a schema that asserts less than this one does
|
|
486
|
-
if (Object.getOwnPropertySymbols(def.shape).length &&
|
|
487
|
-
(0, to_json_schema_js_1.handleUnrepresentable)(schema, ctx, json, params, "Symbol keys cannot be represented in JSON Schema")) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
// the parsed value is the input, so an output-mode emission would describe a transformed value this schema never returns
|
|
491
|
-
if (ctx.io === "output") {
|
|
492
|
-
for (const key in def.shape) {
|
|
493
|
-
if ((0, to_json_schema_js_1.isTransforming)(def.shape[key]) &&
|
|
494
|
-
(0, to_json_schema_js_1.handleUnrepresentable)(schema, ctx, json, params, `z.properties() returns its input, so the output of a transforming schema at key "${key}" cannot be represented in JSON Schema`)) {
|
|
495
|
-
return;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
json.type = "object";
|
|
500
|
-
json.properties = {};
|
|
501
|
-
for (const key in def.shape) {
|
|
502
|
-
(0, util_js_1.assignProp)(json.properties, key, (0, to_json_schema_js_1.processSchema)(def.shape[key], ctx, {
|
|
503
|
-
...params,
|
|
504
|
-
path: [...params.path, "properties", key],
|
|
505
|
-
}));
|
|
506
|
-
}
|
|
507
|
-
// input-side optionality in both modes: the parsed value is the input, so a defaulted key that stays absent must not be required of the output either
|
|
508
|
-
const required = Object.keys(def.shape).filter((key) => inputOptin(def.shape[key]) === undefined);
|
|
509
|
-
if (required.length > 0)
|
|
510
|
-
json.required = required;
|
|
511
|
-
};
|
|
512
|
-
exports.propertiesProcessor = propertiesProcessor;
|
|
513
478
|
const unionProcessor = (schema, ctx, json, params) => {
|
|
514
479
|
const def = schema._zod.def;
|
|
515
480
|
// Exclusive unions (inclusive === false) use oneOf (exactly one match) instead of anyOf (one or more matches). This includes both z.xor() and discriminated unions
|
|
@@ -883,7 +848,6 @@ exports.allProcessors = {
|
|
|
883
848
|
file: exports.fileProcessor,
|
|
884
849
|
success: exports.successProcessor,
|
|
885
850
|
custom: exports.customProcessor,
|
|
886
|
-
properties: exports.propertiesProcessor,
|
|
887
851
|
function: exports.functionProcessor,
|
|
888
852
|
transform: exports.transformProcessor,
|
|
889
853
|
map: exports.mapProcessor,
|
|
@@ -41,7 +41,6 @@ export declare const mapProcessor: Processor<schemas.$ZodMap>;
|
|
|
41
41
|
export declare const setProcessor: Processor<schemas.$ZodSet>;
|
|
42
42
|
export declare const arrayProcessor: Processor<schemas.$ZodArray>;
|
|
43
43
|
export declare const objectProcessor: Processor<schemas.$ZodObject>;
|
|
44
|
-
export declare const propertiesProcessor: Processor<schemas.$ZodProperties>;
|
|
45
44
|
export declare const unionProcessor: Processor<schemas.$ZodUnion>;
|
|
46
45
|
export declare const intersectionProcessor: Processor<schemas.$ZodIntersection>;
|
|
47
46
|
export declare const tupleProcessor: Processor<schemas.$ZodTuple>;
|
|
@@ -41,7 +41,6 @@ export declare const mapProcessor: Processor<schemas.$ZodMap>;
|
|
|
41
41
|
export declare const setProcessor: Processor<schemas.$ZodSet>;
|
|
42
42
|
export declare const arrayProcessor: Processor<schemas.$ZodArray>;
|
|
43
43
|
export declare const objectProcessor: Processor<schemas.$ZodObject>;
|
|
44
|
-
export declare const propertiesProcessor: Processor<schemas.$ZodProperties>;
|
|
45
44
|
export declare const unionProcessor: Processor<schemas.$ZodUnion>;
|
|
46
45
|
export declare const intersectionProcessor: Processor<schemas.$ZodIntersection>;
|
|
47
46
|
export declare const tupleProcessor: Processor<schemas.$ZodTuple>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as regexes from "./regexes.js";
|
|
2
2
|
import { base64Charset, base64urlCharset } from "./schemas.js";
|
|
3
|
-
import { extractDefs, finalize, handleUnrepresentable, initializeContext,
|
|
3
|
+
import { extractDefs, finalize, handleUnrepresentable, initializeContext, processSchema, } from "./to-json-schema.js";
|
|
4
4
|
import { BIGINT_FORMAT_RANGES, NUMBER_FORMAT_RANGES, assignProp, getEnumValues } from "./util.js";
|
|
5
5
|
const narrowMin = (agg, key, value) => {
|
|
6
6
|
if (agg[key] === undefined || value > agg[key])
|
|
@@ -395,18 +395,15 @@ export const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
395
395
|
}));
|
|
396
396
|
}
|
|
397
397
|
// required keys
|
|
398
|
-
const
|
|
399
|
-
const
|
|
398
|
+
const requiredKeys = [];
|
|
399
|
+
for (const key of Object.keys(shape)) {
|
|
400
400
|
const field = def.shape[key];
|
|
401
|
-
if (ctx.io === "input") {
|
|
402
|
-
|
|
401
|
+
if (ctx.io === "input" ? inputOptin(field) === undefined : field._zod.optout === undefined) {
|
|
402
|
+
requiredKeys.push(key);
|
|
403
403
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
}));
|
|
408
|
-
if (requiredKeys.size > 0) {
|
|
409
|
-
json.required = Array.from(requiredKeys);
|
|
404
|
+
}
|
|
405
|
+
if (requiredKeys.length > 0) {
|
|
406
|
+
json.required = requiredKeys;
|
|
410
407
|
}
|
|
411
408
|
// catchall
|
|
412
409
|
if (def.catchall?._zod.def.type === "never") {
|
|
@@ -425,37 +422,6 @@ export const objectProcessor = (schema, ctx, _json, params) => {
|
|
|
425
422
|
});
|
|
426
423
|
}
|
|
427
424
|
};
|
|
428
|
-
// asserts named properties in place and passes everything else through, so no additionalProperties constraint is emitted
|
|
429
|
-
export const propertiesProcessor = (schema, ctx, _json, params) => {
|
|
430
|
-
const json = _json;
|
|
431
|
-
const def = schema._zod.def;
|
|
432
|
-
// dropping a symbol key silently would emit a schema that asserts less than this one does
|
|
433
|
-
if (Object.getOwnPropertySymbols(def.shape).length &&
|
|
434
|
-
handleUnrepresentable(schema, ctx, json, params, "Symbol keys cannot be represented in JSON Schema")) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
// the parsed value is the input, so an output-mode emission would describe a transformed value this schema never returns
|
|
438
|
-
if (ctx.io === "output") {
|
|
439
|
-
for (const key in def.shape) {
|
|
440
|
-
if (isTransforming(def.shape[key]) &&
|
|
441
|
-
handleUnrepresentable(schema, ctx, json, params, `z.properties() returns its input, so the output of a transforming schema at key "${key}" cannot be represented in JSON Schema`)) {
|
|
442
|
-
return;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
json.type = "object";
|
|
447
|
-
json.properties = {};
|
|
448
|
-
for (const key in def.shape) {
|
|
449
|
-
assignProp(json.properties, key, processSchema(def.shape[key], ctx, {
|
|
450
|
-
...params,
|
|
451
|
-
path: [...params.path, "properties", key],
|
|
452
|
-
}));
|
|
453
|
-
}
|
|
454
|
-
// input-side optionality in both modes: the parsed value is the input, so a defaulted key that stays absent must not be required of the output either
|
|
455
|
-
const required = Object.keys(def.shape).filter((key) => inputOptin(def.shape[key]) === undefined);
|
|
456
|
-
if (required.length > 0)
|
|
457
|
-
json.required = required;
|
|
458
|
-
};
|
|
459
425
|
export const unionProcessor = (schema, ctx, json, params) => {
|
|
460
426
|
const def = schema._zod.def;
|
|
461
427
|
// Exclusive unions (inclusive === false) use oneOf (exactly one match) instead of anyOf (one or more matches). This includes both z.xor() and discriminated unions
|
|
@@ -815,7 +781,6 @@ export const allProcessors = {
|
|
|
815
781
|
file: fileProcessor,
|
|
816
782
|
success: successProcessor,
|
|
817
783
|
custom: customProcessor,
|
|
818
|
-
properties: propertiesProcessor,
|
|
819
784
|
function: functionProcessor,
|
|
820
785
|
transform: transformProcessor,
|
|
821
786
|
map: mapProcessor,
|
package/v4/core/memoizer.cjs
CHANGED
|
@@ -38,9 +38,9 @@ exports.$ZodCyclicError = $ZodCyclicError;
|
|
|
38
38
|
/** Keyed off the context object every schema in one parse call already shares. */
|
|
39
39
|
const STATE = "~memo";
|
|
40
40
|
const NO_ISSUES = [];
|
|
41
|
-
// a value a cycle can close through
|
|
41
|
+
// a value a cycle can close through
|
|
42
42
|
function isRef(value) {
|
|
43
|
-
return value !== null &&
|
|
43
|
+
return value !== null && typeof value === "object";
|
|
44
44
|
}
|
|
45
45
|
// Receivers prefix paths in place, so the cache and every hand-out need their own copies.
|
|
46
46
|
function cloneIssues(issues) {
|
|
@@ -97,9 +97,6 @@ function isRecursive(inst, stack, resolve) {
|
|
|
97
97
|
check(def.catchall);
|
|
98
98
|
break;
|
|
99
99
|
}
|
|
100
|
-
case "properties":
|
|
101
|
-
merge(shape(def.shape, false));
|
|
102
|
-
break;
|
|
103
100
|
case "array":
|
|
104
101
|
check(def.element);
|
|
105
102
|
break;
|
package/v4/core/memoizer.js
CHANGED
|
@@ -8,9 +8,9 @@ export class $ZodCyclicError extends Error {
|
|
|
8
8
|
/** Keyed off the context object every schema in one parse call already shares. */
|
|
9
9
|
const STATE = "~memo";
|
|
10
10
|
const NO_ISSUES = [];
|
|
11
|
-
// a value a cycle can close through
|
|
11
|
+
// a value a cycle can close through
|
|
12
12
|
function isRef(value) {
|
|
13
|
-
return value !== null &&
|
|
13
|
+
return value !== null && typeof value === "object";
|
|
14
14
|
}
|
|
15
15
|
// Receivers prefix paths in place, so the cache and every hand-out need their own copies.
|
|
16
16
|
function cloneIssues(issues) {
|
|
@@ -67,9 +67,6 @@ function isRecursive(inst, stack, resolve) {
|
|
|
67
67
|
check(def.catchall);
|
|
68
68
|
break;
|
|
69
69
|
}
|
|
70
|
-
case "properties":
|
|
71
|
-
merge(shape(def.shape, false));
|
|
72
|
-
break;
|
|
73
70
|
case "array":
|
|
74
71
|
check(def.element);
|
|
75
72
|
break;
|
package/v4/core/regexes.cjs
CHANGED
|
@@ -23,8 +23,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.
|
|
27
|
-
exports.sha512_base64url = exports.sha512_base64 = exports.sha512_hex = exports.sha384_base64url = exports.sha384_base64 = exports.sha384_hex = exports.sha256_base64url = exports.sha256_base64 = exports.sha256_hex = void 0;
|
|
26
|
+
exports.sha1_base64 = exports.sha1_hex = exports.md5_base64url = exports.md5_base64 = exports.md5_hex = exports.hex = exports.uppercase = exports.lowercase = exports.undefined = exports.null = exports.boolean = exports.number = exports.integer = exports.bigint = exports.string = exports.anyString = exports.date = exports.iban = exports.currencyCode = exports.creditCard = exports.e164 = exports.httpProtocol = exports.domain = exports.hostname = exports.base64url = exports.base64 = exports.cidrv6 = exports.cidrv4 = exports.mac = exports.ipv6 = exports.ipv4 = exports.browserEmail = exports.idnEmail = exports.unicodeEmail = exports.rfc5322Email = exports.html5Email = exports.email = exports.uuid7 = exports.uuid6 = exports.uuid4 = exports.uuid = exports.guid = exports.extendedDuration = exports.duration = exports.nanoid = exports.ksuid = exports.xid = exports.ulid = exports.cuid2 = exports.cuid = void 0;
|
|
27
|
+
exports.sha512_base64url = exports.sha512_base64 = exports.sha512_hex = exports.sha384_base64url = exports.sha384_base64 = exports.sha384_hex = exports.sha256_base64url = exports.sha256_base64 = exports.sha256_hex = exports.sha1_base64url = void 0;
|
|
28
28
|
exports.nanoidOfLength = nanoidOfLength;
|
|
29
29
|
exports.emoji = emoji;
|
|
30
30
|
exports.time = time;
|
|
@@ -99,6 +99,8 @@ exports.httpProtocol = /^https?$/;
|
|
|
99
99
|
exports.e164 = /^\+[1-9]\d{6,14}$/;
|
|
100
100
|
// Credit card shape: 12–19 digits, optionally separated by single spaces or single hyphens. ISO/IEC 7812 caps the PAN at 19 digits; 12 is the shortest issued length (Maestro).
|
|
101
101
|
exports.creditCard = /^\d(?:[ -]?\d){11,18}$/;
|
|
102
|
+
// ISO 4217 alpha codes from the SIX list, regenerated by scripts/update-iso-4217.ts
|
|
103
|
+
exports.currencyCode = /^(?:AED|AFN|ALL|AMD|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BHD|BIF|BMD|BND|BOB|BOV|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHE|CHF|CHW|CLF|CLP|CNY|COP|COU|CRC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MXV|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|USN|UYI|UYU|UYW|UZS|VED|VES|VND|VUV|WST|XAD|XAF|XAG|XAU|XBA|XBB|XBC|XBD|XCD|XCG|XDR|XOF|XPD|XPF|XPT|XSU|XTS|XUA|XXX|YER|ZAR|ZMW|ZWG)$/;
|
|
102
104
|
// iban electronic format: 2-letter country, check digits 02-98 (the only values `98 - remainder` can produce), 11-30 bban characters
|
|
103
105
|
exports.iban = /^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/;
|
|
104
106
|
const dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
|
package/v4/core/regexes.d.cts
CHANGED
|
@@ -46,6 +46,7 @@ export declare const domain: RegExp;
|
|
|
46
46
|
export declare const httpProtocol: RegExp;
|
|
47
47
|
export declare const e164: RegExp;
|
|
48
48
|
export declare const creditCard: RegExp;
|
|
49
|
+
export declare const currencyCode: RegExp;
|
|
49
50
|
export declare const iban: RegExp;
|
|
50
51
|
export declare const date: RegExp;
|
|
51
52
|
export declare function time(args: {
|
package/v4/core/regexes.d.ts
CHANGED
|
@@ -46,6 +46,7 @@ export declare const domain: RegExp;
|
|
|
46
46
|
export declare const httpProtocol: RegExp;
|
|
47
47
|
export declare const e164: RegExp;
|
|
48
48
|
export declare const creditCard: RegExp;
|
|
49
|
+
export declare const currencyCode: RegExp;
|
|
49
50
|
export declare const iban: RegExp;
|
|
50
51
|
export declare const date: RegExp;
|
|
51
52
|
export declare function time(args: {
|
package/v4/core/regexes.js
CHANGED
|
@@ -66,6 +66,8 @@ export const httpProtocol = /^https?$/;
|
|
|
66
66
|
export const e164 = /^\+[1-9]\d{6,14}$/;
|
|
67
67
|
// Credit card shape: 12–19 digits, optionally separated by single spaces or single hyphens. ISO/IEC 7812 caps the PAN at 19 digits; 12 is the shortest issued length (Maestro).
|
|
68
68
|
export const creditCard = /^\d(?:[ -]?\d){11,18}$/;
|
|
69
|
+
// ISO 4217 alpha codes from the SIX list, regenerated by scripts/update-iso-4217.ts
|
|
70
|
+
export const currencyCode = /^(?:AED|AFN|ALL|AMD|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BHD|BIF|BMD|BND|BOB|BOV|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHE|CHF|CHW|CLF|CLP|CNY|COP|COU|CRC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MXV|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|USN|UYI|UYU|UYW|UZS|VED|VES|VND|VUV|WST|XAD|XAF|XAG|XAU|XBA|XBB|XBC|XBD|XCD|XCG|XDR|XOF|XPD|XPF|XPT|XSU|XTS|XUA|XXX|YER|ZAR|ZMW|ZWG)$/;
|
|
69
71
|
// iban electronic format: 2-letter country, check digits 02-98 (the only values `98 - remainder` can produce), 11-30 bban characters
|
|
70
72
|
export const iban = /^[A-Z]{2}(?!00|01|99)\d{2}[A-Z0-9]{11,30}$/;
|
|
71
73
|
const dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`;
|