zod 4.1.12 → 4.1.13
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/package.json +1 -1
- package/src/v4/classic/checks.ts +1 -0
- package/src/v4/classic/schemas.ts +20 -0
- package/src/v4/classic/tests/continuability.test.ts +22 -0
- package/src/v4/classic/tests/describe-meta-checks.test.ts +27 -0
- package/src/v4/classic/tests/index.test.ts +55 -1
- package/src/v4/classic/tests/promise.test.ts +1 -1
- package/src/v4/classic/tests/readonly.test.ts +1 -1
- package/src/v4/classic/tests/record.test.ts +141 -9
- package/src/v4/classic/tests/registries.test.ts +5 -1
- package/src/v4/classic/tests/string.test.ts +72 -0
- package/src/v4/classic/tests/template-literal.test.ts +8 -0
- package/src/v4/classic/tests/to-json-schema.test.ts +97 -0
- package/src/v4/classic/tests/tuple.test.ts +18 -0
- package/src/v4/classic/tests/url.test.ts +13 -0
- package/src/v4/core/api.ts +45 -0
- package/src/v4/core/core.ts +22 -9
- package/src/v4/core/regexes.ts +6 -1
- package/src/v4/core/registries.ts +12 -1
- package/src/v4/core/schemas.ts +50 -33
- package/src/v4/core/tests/extend.test.ts +42 -1
- package/src/v4/core/tests/locales/he.test.ts +379 -0
- package/src/v4/core/tests/locales/nl.test.ts +46 -0
- package/src/v4/core/tests/record-constructor.test.ts +67 -0
- package/src/v4/core/tests/recursive-tuples.test.ts +45 -0
- package/src/v4/core/to-json-schema.ts +55 -91
- package/src/v4/core/util.ts +11 -0
- package/src/v4/core/versions.ts +1 -1
- package/src/v4/locales/en.ts +1 -0
- package/src/v4/locales/he.ts +202 -71
- package/src/v4/locales/nl.ts +10 -10
- package/src/v4/mini/iso.ts +4 -4
- package/src/v4/mini/schemas.ts +17 -0
- package/src/v4/mini/tests/functions.test.ts +0 -38
- package/src/v4/mini/tests/index.test.ts +24 -1
- package/src/v4/mini/tests/string.test.ts +32 -0
- package/v3/ZodError.d.cts +1 -1
- package/v3/ZodError.d.ts +1 -1
- 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 +15 -2
- package/v4/classic/schemas.d.cts +8 -0
- package/v4/classic/schemas.d.ts +8 -0
- package/v4/classic/schemas.js +12 -0
- package/v4/core/api.cjs +40 -0
- package/v4/core/api.d.cts +7 -0
- package/v4/core/api.d.ts +7 -0
- package/v4/core/api.js +36 -0
- package/v4/core/core.cjs +20 -11
- package/v4/core/core.js +20 -11
- package/v4/core/regexes.cjs +31 -2
- package/v4/core/regexes.d.cts +1 -0
- package/v4/core/regexes.d.ts +1 -0
- package/v4/core/regexes.js +5 -0
- package/v4/core/registries.cjs +3 -1
- package/v4/core/registries.js +3 -1
- package/v4/core/schemas.cjs +32 -33
- package/v4/core/schemas.d.cts +12 -2
- package/v4/core/schemas.d.ts +12 -2
- package/v4/core/schemas.js +30 -31
- package/v4/core/to-json-schema.cjs +55 -92
- package/v4/core/to-json-schema.js +55 -92
- package/v4/core/util.cjs +11 -0
- package/v4/core/util.d.cts +1 -0
- package/v4/core/util.d.ts +1 -0
- package/v4/core/util.js +10 -0
- package/v4/core/versions.cjs +1 -1
- package/v4/core/versions.js +1 -1
- package/v4/locales/en.cjs +1 -0
- package/v4/locales/en.js +1 -0
- package/v4/locales/he.cjs +177 -66
- package/v4/locales/he.js +177 -66
- package/v4/locales/nl.cjs +8 -8
- package/v4/locales/nl.js +8 -8
- package/v4/mini/iso.cjs +4 -4
- package/v4/mini/iso.js +4 -4
- package/v4/mini/schemas.cjs +13 -2
- package/v4/mini/schemas.d.cts +6 -0
- package/v4/mini/schemas.d.ts +6 -0
- package/v4/mini/schemas.js +10 -0
|
@@ -330,13 +330,20 @@ export class JSONSchemaGenerator {
|
|
|
330
330
|
}
|
|
331
331
|
case "union": {
|
|
332
332
|
const json: JSONSchema.BaseSchema = _json as any;
|
|
333
|
+
// Discriminated unions use oneOf (exactly one match) instead of anyOf (one or more matches)
|
|
334
|
+
// because the discriminator field ensures mutual exclusivity between options in JSON Schema
|
|
335
|
+
const isDiscriminated = (def as any).discriminator !== undefined;
|
|
333
336
|
const options = def.options.map((x, i) =>
|
|
334
337
|
this.process(x, {
|
|
335
338
|
...params,
|
|
336
|
-
path: [...params.path, "anyOf", i],
|
|
339
|
+
path: [...params.path, isDiscriminated ? "oneOf" : "anyOf", i],
|
|
337
340
|
})
|
|
338
341
|
);
|
|
339
|
-
|
|
342
|
+
if (isDiscriminated) {
|
|
343
|
+
json.oneOf = options;
|
|
344
|
+
} else {
|
|
345
|
+
json.anyOf = options;
|
|
346
|
+
}
|
|
340
347
|
break;
|
|
341
348
|
}
|
|
342
349
|
case "intersection": {
|
|
@@ -947,98 +954,55 @@ function isTransforming(
|
|
|
947
954
|
if (ctx.seen.has(_schema)) return false;
|
|
948
955
|
ctx.seen.add(_schema);
|
|
949
956
|
|
|
950
|
-
const
|
|
951
|
-
const def = schema._zod.def;
|
|
952
|
-
switch (def.type) {
|
|
953
|
-
case "string":
|
|
954
|
-
case "number":
|
|
955
|
-
case "bigint":
|
|
956
|
-
case "boolean":
|
|
957
|
-
case "date":
|
|
958
|
-
case "symbol":
|
|
959
|
-
case "undefined":
|
|
960
|
-
case "null":
|
|
961
|
-
case "any":
|
|
962
|
-
case "unknown":
|
|
963
|
-
case "never":
|
|
964
|
-
case "void":
|
|
965
|
-
case "literal":
|
|
966
|
-
case "enum":
|
|
967
|
-
case "nan":
|
|
968
|
-
case "file":
|
|
969
|
-
case "template_literal":
|
|
970
|
-
return false;
|
|
971
|
-
case "array": {
|
|
972
|
-
return isTransforming(def.element, ctx);
|
|
973
|
-
}
|
|
974
|
-
case "object": {
|
|
975
|
-
for (const key in def.shape) {
|
|
976
|
-
if (isTransforming(def.shape[key]!, ctx)) return true;
|
|
977
|
-
}
|
|
978
|
-
return false;
|
|
979
|
-
}
|
|
980
|
-
case "union": {
|
|
981
|
-
for (const option of def.options) {
|
|
982
|
-
if (isTransforming(option, ctx)) return true;
|
|
983
|
-
}
|
|
984
|
-
return false;
|
|
985
|
-
}
|
|
986
|
-
case "intersection": {
|
|
987
|
-
return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);
|
|
988
|
-
}
|
|
989
|
-
case "tuple": {
|
|
990
|
-
for (const item of def.items) {
|
|
991
|
-
if (isTransforming(item, ctx)) return true;
|
|
992
|
-
}
|
|
993
|
-
if (def.rest && isTransforming(def.rest, ctx)) return true;
|
|
994
|
-
return false;
|
|
995
|
-
}
|
|
996
|
-
case "record": {
|
|
997
|
-
return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
998
|
-
}
|
|
999
|
-
case "map": {
|
|
1000
|
-
return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
1001
|
-
}
|
|
1002
|
-
case "set": {
|
|
1003
|
-
return isTransforming(def.valueType, ctx);
|
|
1004
|
-
}
|
|
957
|
+
const def = (_schema as schemas.$ZodTypes)._zod.def;
|
|
1005
958
|
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
959
|
+
if (def.type === "transform") return true;
|
|
960
|
+
|
|
961
|
+
if (def.type === "array") return isTransforming(def.element, ctx);
|
|
962
|
+
if (def.type === "set") return isTransforming(def.valueType, ctx);
|
|
963
|
+
if (def.type === "lazy") return isTransforming(def.getter(), ctx);
|
|
964
|
+
|
|
965
|
+
if (
|
|
966
|
+
def.type === "promise" ||
|
|
967
|
+
def.type === "optional" ||
|
|
968
|
+
def.type === "nonoptional" ||
|
|
969
|
+
def.type === "nullable" ||
|
|
970
|
+
def.type === "readonly" ||
|
|
971
|
+
def.type === "default" ||
|
|
972
|
+
def.type === "prefault"
|
|
973
|
+
) {
|
|
974
|
+
return isTransforming(def.innerType, ctx);
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
if (def.type === "intersection") {
|
|
978
|
+
return isTransforming(def.left, ctx) || isTransforming(def.right, ctx);
|
|
979
|
+
}
|
|
980
|
+
if (def.type === "record" || def.type === "map") {
|
|
981
|
+
return isTransforming(def.keyType, ctx) || isTransforming(def.valueType, ctx);
|
|
982
|
+
}
|
|
983
|
+
if (def.type === "pipe") {
|
|
984
|
+
return isTransforming(def.in, ctx) || isTransforming(def.out, ctx);
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
if (def.type === "object") {
|
|
988
|
+
for (const key in def.shape) {
|
|
989
|
+
if (isTransforming(def.shape[key]!, ctx)) return true;
|
|
1032
990
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
991
|
+
return false;
|
|
992
|
+
}
|
|
993
|
+
if (def.type === "union") {
|
|
994
|
+
for (const option of def.options) {
|
|
995
|
+
if (isTransforming(option, ctx)) return true;
|
|
1035
996
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
997
|
+
return false;
|
|
998
|
+
}
|
|
999
|
+
if (def.type === "tuple") {
|
|
1000
|
+
for (const item of def.items) {
|
|
1001
|
+
if (isTransforming(item, ctx)) return true;
|
|
1038
1002
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
def satisfies never;
|
|
1003
|
+
if (def.rest && isTransforming(def.rest, ctx)) return true;
|
|
1004
|
+
return false;
|
|
1042
1005
|
}
|
|
1043
|
-
|
|
1006
|
+
|
|
1007
|
+
return false;
|
|
1044
1008
|
}
|
package/src/v4/core/util.ts
CHANGED
|
@@ -351,6 +351,15 @@ export function esc(str: string): string {
|
|
|
351
351
|
return JSON.stringify(str);
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
+
export function slugify(input: string): string {
|
|
355
|
+
return input
|
|
356
|
+
.toLowerCase()
|
|
357
|
+
.trim()
|
|
358
|
+
.replace(/[^\w\s-]/g, "")
|
|
359
|
+
.replace(/[\s_-]+/g, "-")
|
|
360
|
+
.replace(/^-+|-+$/g, "");
|
|
361
|
+
}
|
|
362
|
+
|
|
354
363
|
export const captureStackTrace: (targetObject: object, constructorOpt?: Function) => void = (
|
|
355
364
|
"captureStackTrace" in Error ? Error.captureStackTrace : (..._args: any[]) => {}
|
|
356
365
|
) as any;
|
|
@@ -381,6 +390,8 @@ export function isPlainObject(o: any): o is Record<PropertyKey, unknown> {
|
|
|
381
390
|
const ctor = o.constructor;
|
|
382
391
|
if (ctor === undefined) return true;
|
|
383
392
|
|
|
393
|
+
if (typeof ctor !== "function") return true;
|
|
394
|
+
|
|
384
395
|
// modified prototype
|
|
385
396
|
const prot = ctor.prototype;
|
|
386
397
|
if (isObject(prot) === false) return false;
|
package/src/v4/core/versions.ts
CHANGED
package/src/v4/locales/en.ts
CHANGED
package/src/v4/locales/he.ts
CHANGED
|
@@ -3,115 +3,246 @@ import type * as errors from "../core/errors.js";
|
|
|
3
3
|
import * as util from "../core/util.js";
|
|
4
4
|
|
|
5
5
|
const error: () => errors.$ZodErrorMap = () => {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
// Hebrew labels + grammatical gender
|
|
7
|
+
const TypeNames: Record<string, { label: string; gender: "m" | "f" }> = {
|
|
8
|
+
string: { label: "מחרוזת", gender: "f" },
|
|
9
|
+
number: { label: "מספר", gender: "m" },
|
|
10
|
+
boolean: { label: "ערך בוליאני", gender: "m" },
|
|
11
|
+
bigint: { label: "BigInt", gender: "m" },
|
|
12
|
+
date: { label: "תאריך", gender: "m" },
|
|
13
|
+
array: { label: "מערך", gender: "m" },
|
|
14
|
+
object: { label: "אובייקט", gender: "m" },
|
|
15
|
+
null: { label: "ערך ריק (null)", gender: "m" },
|
|
16
|
+
undefined: { label: "ערך לא מוגדר (undefined)", gender: "m" },
|
|
17
|
+
symbol: { label: "סימבול (Symbol)", gender: "m" },
|
|
18
|
+
function: { label: "פונקציה", gender: "f" },
|
|
19
|
+
map: { label: "מפה (Map)", gender: "f" },
|
|
20
|
+
set: { label: "קבוצה (Set)", gender: "f" },
|
|
21
|
+
file: { label: "קובץ", gender: "m" },
|
|
22
|
+
promise: { label: "Promise", gender: "m" },
|
|
23
|
+
NaN: { label: "NaN", gender: "m" },
|
|
24
|
+
unknown: { label: "ערך לא ידוע", gender: "m" },
|
|
25
|
+
value: { label: "ערך", gender: "m" },
|
|
11
26
|
};
|
|
12
27
|
|
|
13
|
-
|
|
28
|
+
// Sizing units for size-related messages + localized origin labels
|
|
29
|
+
const Sizable: Record<string, { unit: string; shortLabel?: string; longLabel?: string }> = {
|
|
30
|
+
string: { unit: "תווים", shortLabel: "קצר", longLabel: "ארוך" },
|
|
31
|
+
file: { unit: "בייטים", shortLabel: "קטן", longLabel: "גדול" },
|
|
32
|
+
array: { unit: "פריטים", shortLabel: "קטן", longLabel: "גדול" },
|
|
33
|
+
set: { unit: "פריטים", shortLabel: "קטן", longLabel: "גדול" },
|
|
34
|
+
number: { unit: "", shortLabel: "קטן", longLabel: "גדול" }, // no unit
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Helpers — labels, articles, and verbs
|
|
38
|
+
const typeEntry = (t?: string | null) => (t ? TypeNames[t] : undefined);
|
|
39
|
+
|
|
40
|
+
const typeLabel = (t?: string | null): string => {
|
|
41
|
+
const e = typeEntry(t);
|
|
42
|
+
if (e) return e.label;
|
|
43
|
+
// fallback: show raw string if unknown
|
|
44
|
+
return t ?? TypeNames.unknown.label;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const withDefinite = (t?: string | null): string => `ה${typeLabel(t)}`;
|
|
48
|
+
|
|
49
|
+
const verbFor = (t?: string | null): string => {
|
|
50
|
+
const e = typeEntry(t);
|
|
51
|
+
const gender = e?.gender ?? "m";
|
|
52
|
+
return gender === "f" ? "צריכה להיות" : "צריך להיות";
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const getSizing = (origin?: string | null) => {
|
|
56
|
+
if (!origin) return null;
|
|
14
57
|
return Sizable[origin] ?? null;
|
|
15
|
-
}
|
|
58
|
+
};
|
|
16
59
|
|
|
60
|
+
// Robust type parser for "received" — returns a key we understand or a constructor name
|
|
17
61
|
const parsedType = (data: any): string => {
|
|
18
62
|
const t = typeof data;
|
|
19
|
-
|
|
20
63
|
switch (t) {
|
|
21
|
-
case "number":
|
|
64
|
+
case "number":
|
|
22
65
|
return Number.isNaN(data) ? "NaN" : "number";
|
|
23
|
-
}
|
|
24
66
|
case "object": {
|
|
25
|
-
if (Array.isArray(data))
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
if (data === null) {
|
|
29
|
-
return "null";
|
|
30
|
-
}
|
|
31
|
-
|
|
67
|
+
if (Array.isArray(data)) return "array";
|
|
68
|
+
if (data === null) return "null";
|
|
32
69
|
if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
|
|
33
|
-
return data.constructor.name;
|
|
70
|
+
return data.constructor.name; // keep as-is (e.g., "Date")
|
|
34
71
|
}
|
|
72
|
+
return "object";
|
|
35
73
|
}
|
|
74
|
+
default:
|
|
75
|
+
return t;
|
|
36
76
|
}
|
|
37
|
-
return t;
|
|
38
77
|
};
|
|
39
78
|
|
|
40
79
|
const Nouns: {
|
|
41
|
-
[k in $ZodStringFormats
|
|
80
|
+
[k in $ZodStringFormats]: { label: string; gender: "m" | "f" };
|
|
42
81
|
} = {
|
|
43
|
-
regex: "קלט",
|
|
44
|
-
email: "כתובת אימייל",
|
|
45
|
-
url: "כתובת רשת",
|
|
46
|
-
emoji: "אימוג'י",
|
|
47
|
-
uuid: "UUID",
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
82
|
+
regex: { label: "קלט", gender: "m" },
|
|
83
|
+
email: { label: "כתובת אימייל", gender: "f" },
|
|
84
|
+
url: { label: "כתובת רשת", gender: "f" },
|
|
85
|
+
emoji: { label: "אימוג'י", gender: "m" },
|
|
86
|
+
uuid: { label: "UUID", gender: "m" },
|
|
87
|
+
nanoid: { label: "nanoid", gender: "m" },
|
|
88
|
+
guid: { label: "GUID", gender: "m" },
|
|
89
|
+
cuid: { label: "cuid", gender: "m" },
|
|
90
|
+
cuid2: { label: "cuid2", gender: "m" },
|
|
91
|
+
ulid: { label: "ULID", gender: "m" },
|
|
92
|
+
xid: { label: "XID", gender: "m" },
|
|
93
|
+
ksuid: { label: "KSUID", gender: "m" },
|
|
94
|
+
datetime: { label: "תאריך וזמן ISO", gender: "m" },
|
|
95
|
+
date: { label: "תאריך ISO", gender: "m" },
|
|
96
|
+
time: { label: "זמן ISO", gender: "m" },
|
|
97
|
+
duration: { label: "משך זמן ISO", gender: "m" },
|
|
98
|
+
ipv4: { label: "כתובת IPv4", gender: "f" },
|
|
99
|
+
ipv6: { label: "כתובת IPv6", gender: "f" },
|
|
100
|
+
cidrv4: { label: "טווח IPv4", gender: "m" },
|
|
101
|
+
cidrv6: { label: "טווח IPv6", gender: "m" },
|
|
102
|
+
base64: { label: "מחרוזת בבסיס 64", gender: "f" },
|
|
103
|
+
base64url: { label: "מחרוזת בבסיס 64 לכתובות רשת", gender: "f" },
|
|
104
|
+
json_string: { label: "מחרוזת JSON", gender: "f" },
|
|
105
|
+
e164: { label: "מספר E.164", gender: "m" },
|
|
106
|
+
jwt: { label: "JWT", gender: "m" },
|
|
107
|
+
ends_with: { label: "קלט", gender: "m" },
|
|
108
|
+
includes: { label: "קלט", gender: "m" },
|
|
109
|
+
lowercase: { label: "קלט", gender: "m" },
|
|
110
|
+
starts_with: { label: "קלט", gender: "m" },
|
|
111
|
+
uppercase: { label: "קלט", gender: "m" },
|
|
71
112
|
};
|
|
72
113
|
|
|
73
114
|
return (issue) => {
|
|
74
115
|
switch (issue.code) {
|
|
75
|
-
case "invalid_type":
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
116
|
+
case "invalid_type": {
|
|
117
|
+
// Expected type: show without definite article for clearer Hebrew
|
|
118
|
+
const expectedKey = issue.expected as string | undefined;
|
|
119
|
+
const expected = typeLabel(expectedKey);
|
|
120
|
+
// Received: show localized label if known, otherwise constructor/raw
|
|
121
|
+
const receivedKey = parsedType(issue.input);
|
|
122
|
+
const received = TypeNames[receivedKey]?.label ?? receivedKey;
|
|
123
|
+
return `קלט לא תקין: צריך להיות ${expected}, התקבל ${received}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
case "invalid_value": {
|
|
127
|
+
if (issue.values.length === 1) {
|
|
128
|
+
return `ערך לא תקין: הערך חייב להיות ${util.stringifyPrimitive(issue.values[0])}`;
|
|
129
|
+
}
|
|
130
|
+
// Join values with proper Hebrew formatting
|
|
131
|
+
const stringified = issue.values.map((v) => util.stringifyPrimitive(v));
|
|
132
|
+
if (issue.values.length === 2) {
|
|
133
|
+
return `ערך לא תקין: האפשרויות המתאימות הן ${stringified[0]} או ${stringified[1]}`;
|
|
134
|
+
}
|
|
135
|
+
// For 3+ values: "a", "b" או "c"
|
|
136
|
+
const lastValue = stringified[stringified.length - 1];
|
|
137
|
+
const restValues = stringified.slice(0, -1).join(", ");
|
|
138
|
+
return `ערך לא תקין: האפשרויות המתאימות הן ${restValues} או ${lastValue}`;
|
|
139
|
+
}
|
|
140
|
+
|
|
81
141
|
case "too_big": {
|
|
82
|
-
const adj = issue.inclusive ? "<=" : "<";
|
|
83
142
|
const sizing = getSizing(issue.origin);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
143
|
+
const subject = withDefinite(issue.origin ?? "value");
|
|
144
|
+
|
|
145
|
+
if (issue.origin === "string") {
|
|
146
|
+
// Special handling for strings - more natural Hebrew
|
|
147
|
+
return `${sizing?.longLabel ?? "ארוך"} מדי: ${subject} צריכה להכיל ${issue.maximum.toString()} ${sizing?.unit ?? ""} ${issue.inclusive ? "או פחות" : "לכל היותר"}`.trim();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (issue.origin === "number") {
|
|
151
|
+
// Natural Hebrew for numbers
|
|
152
|
+
const comparison = issue.inclusive ? `קטן או שווה ל-${issue.maximum}` : `קטן מ-${issue.maximum}`;
|
|
153
|
+
return `גדול מדי: ${subject} צריך להיות ${comparison}`;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (issue.origin === "array" || issue.origin === "set") {
|
|
157
|
+
// Natural Hebrew for arrays and sets
|
|
158
|
+
const verb = issue.origin === "set" ? "צריכה" : "צריך";
|
|
159
|
+
const comparison = issue.inclusive
|
|
160
|
+
? `${issue.maximum} ${sizing?.unit ?? ""} או פחות`
|
|
161
|
+
: `פחות מ-${issue.maximum} ${sizing?.unit ?? ""}`;
|
|
162
|
+
return `גדול מדי: ${subject} ${verb} להכיל ${comparison}`.trim();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const adj = issue.inclusive ? "<=" : "<";
|
|
166
|
+
const be = verbFor(issue.origin ?? "value");
|
|
167
|
+
if (sizing?.unit) {
|
|
168
|
+
return `${sizing.longLabel} מדי: ${subject} ${be} ${adj}${issue.maximum.toString()} ${sizing.unit}`;
|
|
169
|
+
}
|
|
170
|
+
return `${sizing?.longLabel ?? "גדול"} מדי: ${subject} ${be} ${adj}${issue.maximum.toString()}`;
|
|
87
171
|
}
|
|
172
|
+
|
|
88
173
|
case "too_small": {
|
|
89
|
-
const adj = issue.inclusive ? ">=" : ">";
|
|
90
174
|
const sizing = getSizing(issue.origin);
|
|
91
|
-
|
|
92
|
-
|
|
175
|
+
const subject = withDefinite(issue.origin ?? "value");
|
|
176
|
+
|
|
177
|
+
if (issue.origin === "string") {
|
|
178
|
+
// Special handling for strings - more natural Hebrew
|
|
179
|
+
return `${sizing?.shortLabel ?? "קצר"} מדי: ${subject} צריכה להכיל ${issue.minimum.toString()} ${sizing?.unit ?? ""} ${issue.inclusive ? "או יותר" : "לפחות"}`.trim();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (issue.origin === "number") {
|
|
183
|
+
// Natural Hebrew for numbers
|
|
184
|
+
const comparison = issue.inclusive ? `גדול או שווה ל-${issue.minimum}` : `גדול מ-${issue.minimum}`;
|
|
185
|
+
return `קטן מדי: ${subject} צריך להיות ${comparison}`;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (issue.origin === "array" || issue.origin === "set") {
|
|
189
|
+
// Natural Hebrew for arrays and sets
|
|
190
|
+
const verb = issue.origin === "set" ? "צריכה" : "צריך";
|
|
191
|
+
|
|
192
|
+
// Special case for singular (minimum === 1)
|
|
193
|
+
if (issue.minimum === 1 && issue.inclusive) {
|
|
194
|
+
const singularPhrase = issue.origin === "set" ? "לפחות פריט אחד" : "לפחות פריט אחד";
|
|
195
|
+
return `קטן מדי: ${subject} ${verb} להכיל ${singularPhrase}`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const comparison = issue.inclusive
|
|
199
|
+
? `${issue.minimum} ${sizing?.unit ?? ""} או יותר`
|
|
200
|
+
: `יותר מ-${issue.minimum} ${sizing?.unit ?? ""}`;
|
|
201
|
+
return `קטן מדי: ${subject} ${verb} להכיל ${comparison}`.trim();
|
|
93
202
|
}
|
|
94
203
|
|
|
95
|
-
|
|
204
|
+
const adj = issue.inclusive ? ">=" : ">";
|
|
205
|
+
const be = verbFor(issue.origin ?? "value");
|
|
206
|
+
if (sizing?.unit) {
|
|
207
|
+
return `${sizing.shortLabel} מדי: ${subject} ${be} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
|
|
208
|
+
}
|
|
209
|
+
return `${sizing?.shortLabel ?? "קטן"} מדי: ${subject} ${be} ${adj}${issue.minimum.toString()}`;
|
|
96
210
|
}
|
|
211
|
+
|
|
97
212
|
case "invalid_format": {
|
|
98
213
|
const _issue = issue as errors.$ZodStringFormatIssues;
|
|
99
|
-
|
|
100
|
-
if (_issue.format === "
|
|
101
|
-
if (_issue.format === "
|
|
102
|
-
if (_issue.format === "
|
|
103
|
-
|
|
214
|
+
// These apply to strings — use feminine grammar + ה׳ הידיעה
|
|
215
|
+
if (_issue.format === "starts_with") return `המחרוזת חייבת להתחיל ב "${_issue.prefix}"`;
|
|
216
|
+
if (_issue.format === "ends_with") return `המחרוזת חייבת להסתיים ב "${_issue.suffix}"`;
|
|
217
|
+
if (_issue.format === "includes") return `המחרוזת חייבת לכלול "${_issue.includes}"`;
|
|
218
|
+
if (_issue.format === "regex") return `המחרוזת חייבת להתאים לתבנית ${_issue.pattern}`;
|
|
219
|
+
|
|
220
|
+
// Handle gender agreement for formats
|
|
221
|
+
const nounEntry = Nouns[_issue.format];
|
|
222
|
+
const noun = nounEntry?.label ?? _issue.format;
|
|
223
|
+
const gender = nounEntry?.gender ?? "m";
|
|
224
|
+
const adjective = gender === "f" ? "תקינה" : "תקין";
|
|
225
|
+
return `${noun} לא ${adjective}`;
|
|
104
226
|
}
|
|
227
|
+
|
|
105
228
|
case "not_multiple_of":
|
|
106
229
|
return `מספר לא תקין: חייב להיות מכפלה של ${issue.divisor}`;
|
|
230
|
+
|
|
107
231
|
case "unrecognized_keys":
|
|
108
232
|
return `מפתח${issue.keys.length > 1 ? "ות" : ""} לא מזוה${issue.keys.length > 1 ? "ים" : "ה"}: ${util.joinValues(issue.keys, ", ")}`;
|
|
109
|
-
|
|
110
|
-
|
|
233
|
+
|
|
234
|
+
case "invalid_key": {
|
|
235
|
+
return `שדה לא תקין באובייקט`;
|
|
236
|
+
}
|
|
237
|
+
|
|
111
238
|
case "invalid_union":
|
|
112
239
|
return "קלט לא תקין";
|
|
113
|
-
|
|
114
|
-
|
|
240
|
+
|
|
241
|
+
case "invalid_element": {
|
|
242
|
+
const place = withDefinite(issue.origin ?? "array");
|
|
243
|
+
return `ערך לא תקין ב${place}`;
|
|
244
|
+
}
|
|
245
|
+
|
|
115
246
|
default:
|
|
116
247
|
return `קלט לא תקין`;
|
|
117
248
|
}
|
package/src/v4/locales/nl.ts
CHANGED
|
@@ -3,14 +3,14 @@ import type * as errors from "../core/errors.js";
|
|
|
3
3
|
import * as util from "../core/util.js";
|
|
4
4
|
|
|
5
5
|
const error: () => errors.$ZodErrorMap = () => {
|
|
6
|
-
const Sizable: Record<string, { unit: string }> = {
|
|
7
|
-
string: { unit: "tekens" },
|
|
8
|
-
file: { unit: "bytes" },
|
|
9
|
-
array: { unit: "elementen" },
|
|
10
|
-
set: { unit: "elementen" },
|
|
6
|
+
const Sizable: Record<string, { unit: string; verb: string }> = {
|
|
7
|
+
string: { unit: "tekens", verb: "te hebben" },
|
|
8
|
+
file: { unit: "bytes", verb: "te hebben" },
|
|
9
|
+
array: { unit: "elementen", verb: "te hebben" },
|
|
10
|
+
set: { unit: "elementen", verb: "te hebben" },
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
function getSizing(origin: string): { unit: string } | null {
|
|
13
|
+
function getSizing(origin: string): { unit: string; verb: string } | null {
|
|
14
14
|
return Sizable[origin] ?? null;
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -81,17 +81,17 @@ const error: () => errors.$ZodErrorMap = () => {
|
|
|
81
81
|
const adj = issue.inclusive ? "<=" : "<";
|
|
82
82
|
const sizing = getSizing(issue.origin);
|
|
83
83
|
if (sizing)
|
|
84
|
-
return `Te
|
|
85
|
-
return `Te
|
|
84
|
+
return `Te groot: verwacht dat ${issue.origin ?? "waarde"} ${sizing.verb} ${adj}${issue.maximum.toString()} ${sizing.unit ?? "elementen"}`;
|
|
85
|
+
return `Te groot: verwacht dat ${issue.origin ?? "waarde"} ${adj}${issue.maximum.toString()} is`;
|
|
86
86
|
}
|
|
87
87
|
case "too_small": {
|
|
88
88
|
const adj = issue.inclusive ? ">=" : ">";
|
|
89
89
|
const sizing = getSizing(issue.origin);
|
|
90
90
|
if (sizing) {
|
|
91
|
-
return `Te
|
|
91
|
+
return `Te klein: verwacht dat ${issue.origin} ${sizing.verb} ${adj}${issue.minimum.toString()} ${sizing.unit}`;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
return `Te
|
|
94
|
+
return `Te klein: verwacht dat ${issue.origin} ${adj}${issue.minimum.toString()} is`;
|
|
95
95
|
}
|
|
96
96
|
case "invalid_format": {
|
|
97
97
|
const _issue = issue as errors.$ZodStringFormatIssues;
|
package/src/v4/mini/iso.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface ZodMiniISODateTime extends schemas.ZodMiniStringFormat<"datetim
|
|
|
6
6
|
_zod: core.$ZodISODateTimeInternals;
|
|
7
7
|
}
|
|
8
8
|
export const ZodMiniISODateTime: core.$constructor<ZodMiniISODateTime> = /*@__PURE__*/ core.$constructor(
|
|
9
|
-
"
|
|
9
|
+
"ZodMiniISODateTime",
|
|
10
10
|
(inst, def) => {
|
|
11
11
|
core.$ZodISODateTime.init(inst, def);
|
|
12
12
|
schemas.ZodMiniStringFormat.init(inst, def);
|
|
@@ -21,7 +21,7 @@ export interface ZodMiniISODate extends schemas.ZodMiniStringFormat<"date"> {
|
|
|
21
21
|
_zod: core.$ZodISODateInternals;
|
|
22
22
|
}
|
|
23
23
|
export const ZodMiniISODate: core.$constructor<ZodMiniISODate> = /*@__PURE__*/ core.$constructor(
|
|
24
|
-
"
|
|
24
|
+
"ZodMiniISODate",
|
|
25
25
|
(inst, def) => {
|
|
26
26
|
core.$ZodISODate.init(inst, def);
|
|
27
27
|
schemas.ZodMiniStringFormat.init(inst, def);
|
|
@@ -36,7 +36,7 @@ export interface ZodMiniISOTime extends schemas.ZodMiniStringFormat<"time"> {
|
|
|
36
36
|
_zod: core.$ZodISOTimeInternals;
|
|
37
37
|
}
|
|
38
38
|
export const ZodMiniISOTime: core.$constructor<ZodMiniISOTime> = /*@__PURE__*/ core.$constructor(
|
|
39
|
-
"
|
|
39
|
+
"ZodMiniISOTime",
|
|
40
40
|
(inst, def) => {
|
|
41
41
|
core.$ZodISOTime.init(inst, def);
|
|
42
42
|
schemas.ZodMiniStringFormat.init(inst, def);
|
|
@@ -51,7 +51,7 @@ export interface ZodMiniISODuration extends schemas.ZodMiniStringFormat<"duratio
|
|
|
51
51
|
_zod: core.$ZodISODurationInternals;
|
|
52
52
|
}
|
|
53
53
|
export const ZodMiniISODuration: core.$constructor<ZodMiniISODuration> = /*@__PURE__*/ core.$constructor(
|
|
54
|
-
"
|
|
54
|
+
"ZodMiniISODuration",
|
|
55
55
|
(inst, def) => {
|
|
56
56
|
core.$ZodISODuration.init(inst, def);
|
|
57
57
|
schemas.ZodMiniStringFormat.init(inst, def);
|
package/src/v4/mini/schemas.ts
CHANGED
|
@@ -366,6 +366,19 @@ export function cidrv6(params?: string | core.$ZodCIDRv6Params): ZodMiniCIDRv6 {
|
|
|
366
366
|
return core._cidrv6(ZodMiniCIDRv6, params);
|
|
367
367
|
}
|
|
368
368
|
|
|
369
|
+
// ZodMiniMAC
|
|
370
|
+
export interface ZodMiniMAC extends _ZodMiniString<core.$ZodMACInternals> {
|
|
371
|
+
// _zod: core.$ZodMACInternals;
|
|
372
|
+
}
|
|
373
|
+
export const ZodMiniMAC: core.$constructor<ZodMiniMAC> = /*@__PURE__*/ core.$constructor("ZodMiniMAC", (inst, def) => {
|
|
374
|
+
core.$ZodMAC.init(inst, def);
|
|
375
|
+
ZodMiniStringFormat.init(inst, def);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
export function mac(params?: string | core.$ZodMACParams): ZodMiniMAC {
|
|
379
|
+
return core._mac(ZodMiniMAC, params);
|
|
380
|
+
}
|
|
381
|
+
|
|
369
382
|
// ZodMiniBase64
|
|
370
383
|
export interface ZodMiniBase64 extends _ZodMiniString<core.$ZodBase64Internals> {
|
|
371
384
|
// _zod: core.$ZodBase64Internals;
|
|
@@ -1601,6 +1614,10 @@ export function superRefine<T>(
|
|
|
1601
1614
|
return core._superRefine(fn);
|
|
1602
1615
|
}
|
|
1603
1616
|
|
|
1617
|
+
// Re-export describe and meta from core
|
|
1618
|
+
export const describe = core.describe;
|
|
1619
|
+
export const meta = core.meta;
|
|
1620
|
+
|
|
1604
1621
|
// instanceof
|
|
1605
1622
|
abstract class Class {
|
|
1606
1623
|
constructor(..._args: any[]) {}
|