Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/docs/content/error-customization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ The following locales are available:
- `tr` — Türkçe
- `uk` — Ukrainian
- `ur` — Urdu
- `uz` — Uzbek
- `vi` — Tiếng Việt
- `zhCN` — Simplified Chinese
- `zhTW` — Traditional Chinese
Expand Down
106 changes: 106 additions & 0 deletions packages/zod/src/v4/core/tests/locales/uz.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { expect, test } from "vitest";
import * as z from "zod/v4";
import { parsedType } from "../../../locales/uz.js";

test("parsedType", () => {
expect(parsedType("string")).toBe("string");
expect(parsedType(1)).toBe("raqam");
expect(parsedType(true)).toBe("boolean");
expect(parsedType(null)).toBe("null");
expect(parsedType(undefined)).toBe("undefined");
expect(parsedType([])).toBe("massiv");
expect(parsedType({})).toBe("object");
expect(parsedType(new Date())).toBe("Date");
expect(parsedType(new Map())).toBe("Map");
expect(parsedType(new Set())).toBe("Set");
expect(parsedType(new Error())).toBe("Error");

const nullPrototype = Object.create(null);
expect(parsedType(nullPrototype)).toBe("object");

const doubleNullPrototype = Object.create(Object.create(null));
expect(parsedType(doubleNullPrototype)).toBe("object");

expect(parsedType(Number.NaN)).toBe("NaN");
});

test("locales - uz", () => {
z.config(z.locales.uz());

const invalidType = z.number().safeParse("a");
expect(invalidType.error!.issues[0].code).toBe("invalid_type");
expect(invalidType.error!.issues[0].message).toBe("Noto‘g‘ri kirish: kutilgan number, qabul qilingan string");

const invalidType2 = z.string().safeParse(1);
expect(invalidType2.error!.issues[0].code).toBe("invalid_type");
expect(invalidType2.error!.issues[0].message).toBe("Noto‘g‘ri kirish: kutilgan string, qabul qilingan raqam");

const invalidValue = z.enum(["a", "b"]).safeParse(1);
expect(invalidValue.error!.issues[0].code).toBe("invalid_value");
expect(invalidValue.error!.issues[0].message).toBe('Noto‘g‘ri variant: quyidagilardan biri kutilgan "a"|"b"');

const tooBig = z.number().max(10).safeParse(15);
expect(tooBig.error!.issues[0].code).toBe("too_big");
expect(tooBig.error!.issues[0].message).toBe("Juda katta: kutilgan number <=10");

const tooSmall = z.number().min(10).safeParse(5);
expect(tooSmall.error!.issues[0].code).toBe("too_small");
expect(tooSmall.error!.issues[0].message).toBe("Juda kichik: kutilgan number >=10");

const invalidFormatRegex = z.string().regex(/abcd/).safeParse("invalid-string");
expect(invalidFormatRegex.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatRegex.error!.issues[0].message).toContain("shabloniga mos kelishi kerak");

const invalidFormatStartsWith = z.string().startsWith("abcd").safeParse("invalid-string");
expect(invalidFormatStartsWith.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatStartsWith.error!.issues[0].message).toContain('"abcd" bilan boshlanishi kerak');

const notMultipleOf = z.number().multipleOf(3).safeParse(10);
expect(notMultipleOf.error!.issues[0].code).toBe("not_multiple_of");
expect(notMultipleOf.error!.issues[0].message).toContain("3 ning karralisi bo‘lishi kerak");

const unrecognizedKeys = z.object({ a: z.string(), b: z.number() }).strict().safeParse({ a: "a", b: 1, c: 2 });
expect(unrecognizedKeys.error!.issues[0].code).toBe("unrecognized_keys");
expect(unrecognizedKeys.error!.issues[0].message).toContain('Noma’lum kalit: "c"');

const invalidUnion = z.union([z.string(), z.number()]).safeParse(true);
expect(invalidUnion.error!.issues[0].code).toBe("invalid_union");
expect(invalidUnion.error!.issues[0].message).toBe("Noto‘g‘ri kirish");

const tooBigString = z.string().max(5).safeParse("too long string");
expect(tooBigString.error!.issues[0].code).toBe("too_big");
expect(tooBigString.error!.issues[0].message).toContain("belgi");
expect(tooBigString.error!.issues[0].message).toContain("bo‘lishi kerak");

const tooSmallArray = z.array(z.string()).min(3).safeParse(["a", "b"]);
expect(tooSmallArray.error!.issues[0].code).toBe("too_small");
expect(tooSmallArray.error!.issues[0].message).toContain("element");
expect(tooSmallArray.error!.issues[0].message).toContain("bo‘lishi kerak");

const invalidFormatEndsWith = z.string().endsWith("xyz").safeParse("invalid-string");
expect(invalidFormatEndsWith.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatEndsWith.error!.issues[0].message).toContain('"xyz" bilan tugashi kerak');

const invalidFormatIncludes = z.string().includes("test").safeParse("invalid-string");
expect(invalidFormatIncludes.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatIncludes.error!.issues[0].message).toContain('"test" ni o‘z ichiga olishi kerak');

const invalidFormatEmail = z.string().email().safeParse("invalid-email");
expect(invalidFormatEmail.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatEmail.error!.issues[0].message).toContain("elektron pochta manzili");

const invalidFormatUrl = z.string().url().safeParse("invalid-url");
expect(invalidFormatUrl.error!.issues[0].code).toBe("invalid_format");
expect(invalidFormatUrl.error!.issues[0].message).toContain("URL");

const unrecognizedKeysMultiple = z
.object({ a: z.string(), b: z.number() })
.strict()
.safeParse({ a: "a", b: 1, c: 2, d: 3 });
expect(unrecognizedKeysMultiple.error!.issues[0].code).toBe("unrecognized_keys");
expect(unrecognizedKeysMultiple.error!.issues[0].message).toContain("Noma’lum kalitlar");

const invalidElement = z.array(z.string()).safeParse([1, 2, 3]);
expect(invalidElement.error!.issues[0].code).toBe("invalid_type");
expect(invalidElement.error!.issues[0].message).toContain("raqam");
});
1 change: 1 addition & 0 deletions packages/zod/src/v4/locales/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export { default as tr } from "./tr.js";
export { default as ua } from "./ua.js";
export { default as uk } from "./uk.js";
export { default as ur } from "./ur.js";
export { default as uz } from "./uz.js";
export { default as vi } from "./vi.js";
export { default as zhCN } from "./zh-CN.js";
export { default as zhTW } from "./zh-TW.js";
Expand Down
124 changes: 124 additions & 0 deletions packages/zod/src/v4/locales/uz.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import type { $ZodStringFormats } from "../core/checks.js";
import type * as errors from "../core/errors.js";
import * as util from "../core/util.js";

export const parsedType = (data: any): string => {
const t = typeof data;

switch (t) {
case "number": {
return Number.isNaN(data) ? "NaN" : "raqam";
}
case "object": {
if (Array.isArray(data)) {
return "massiv";
}
if (data === null) {
return "null";
}

if (Object.getPrototypeOf(data) !== Object.prototype && data.constructor) {
return data.constructor.name;
}
}
}
return t;
};

const error: () => errors.$ZodErrorMap = () => {
const Sizable: Record<string, { unit: string; verb: string }> = {
string: { unit: "belgi", verb: "bo‘lishi kerak" },
file: { unit: "bayt", verb: "bo‘lishi kerak" },
array: { unit: "element", verb: "bo‘lishi kerak" },
set: { unit: "element", verb: "bo‘lishi kerak" },
};

function getSizing(origin: string): { unit: string; verb: string } | null {
return Sizable[origin] ?? null;
}

const Nouns: {
[k in $ZodStringFormats | (string & {})]?: string;
} = {
regex: "kirish",
email: "elektron pochta manzili",
url: "URL",
emoji: "emoji",
uuid: "UUID",
uuidv4: "UUIDv4",
uuidv6: "UUIDv6",
nanoid: "nanoid",
guid: "GUID",
cuid: "cuid",
cuid2: "cuid2",
ulid: "ULID",
xid: "XID",
ksuid: "KSUID",
datetime: "ISO sana va vaqti",
date: "ISO sana",
time: "ISO vaqt",
duration: "ISO davomiylik",
ipv4: "IPv4 manzil",
ipv6: "IPv6 manzil",
mac: "MAC manzil",
cidrv4: "IPv4 diapazon",
cidrv6: "IPv6 diapazon",
base64: "base64 kodlangan satr",
base64url: "base64url kodlangan satr",
json_string: "JSON satr",
e164: "E.164 raqam",
jwt: "JWT",
template_literal: "kirish",
};

return (issue) => {
switch (issue.code) {
case "invalid_type":
return `Noto‘g‘ri kirish: kutilgan ${issue.expected}, qabul qilingan ${parsedType(issue.input)}`;
case "invalid_value":
if (issue.values.length === 1) return `Noto‘g‘ri kirish: kutilgan ${util.stringifyPrimitive(issue.values[0])}`;
return `Noto‘g‘ri variant: quyidagilardan biri kutilgan ${util.joinValues(issue.values, "|")}`;
case "too_big": {
const adj = issue.inclusive ? "<=" : "<";
const sizing = getSizing(issue.origin);
if (sizing)
return `Juda katta: kutilgan ${issue.origin ?? "qiymat"} ${adj}${issue.maximum.toString()} ${sizing.unit} ${sizing.verb}`;
return `Juda katta: kutilgan ${issue.origin ?? "qiymat"} ${adj}${issue.maximum.toString()}`;
}
case "too_small": {
const adj = issue.inclusive ? ">=" : ">";
const sizing = getSizing(issue.origin);
if (sizing) {
return `Juda kichik: kutilgan ${issue.origin} ${adj}${issue.minimum.toString()} ${sizing.unit} ${sizing.verb}`;
}
return `Juda kichik: kutilgan ${issue.origin} ${adj}${issue.minimum.toString()}`;
}
case "invalid_format": {
const _issue = issue as errors.$ZodStringFormatIssues;
if (_issue.format === "starts_with") return `Noto‘g‘ri satr: "${_issue.prefix}" bilan boshlanishi kerak`;
if (_issue.format === "ends_with") return `Noto‘g‘ri satr: "${_issue.suffix}" bilan tugashi kerak`;
if (_issue.format === "includes") return `Noto‘g‘ri satr: "${_issue.includes}" ni o‘z ichiga olishi kerak`;
if (_issue.format === "regex") return `Noto‘g‘ri satr: ${_issue.pattern} shabloniga mos kelishi kerak`;
return `Noto'g'ri ${Nouns[_issue.format] ?? issue.format}`;
}
case "not_multiple_of":
return `Noto‘g‘ri raqam: ${issue.divisor} ning karralisi bo‘lishi kerak`;
case "unrecognized_keys":
return `Noma’lum kalit${issue.keys.length > 1 ? "lar" : ""}: ${util.joinValues(issue.keys, ", ")}`;
case "invalid_key":
return `${issue.origin} dagi kalit noto‘g‘ri`;
case "invalid_union":
return "Noto‘g‘ri kirish";
case "invalid_element":
return `${issue.origin} da noto‘g‘ri qiymat`;
default:
return `Noto‘g‘ri kirish`;
}
};
};

export default function (): { localeError: errors.$ZodErrorMap } {
return {
localeError: error(),
};
}