v1.0 with SW PWA enabled
This commit is contained in:
26
frontend/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts
generated
vendored
Normal file
26
frontend/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("check any inference", () => {
|
||||
const t1 = z.any();
|
||||
t1.optional();
|
||||
t1.nullable();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
expectTypeOf<t1>().toEqualTypeOf<any>();
|
||||
});
|
||||
|
||||
test("check unknown inference", () => {
|
||||
const t1 = z.unknown();
|
||||
t1.optional();
|
||||
t1.nullable();
|
||||
type t1 = z.infer<typeof t1>;
|
||||
expectTypeOf<t1>().toEqualTypeOf<unknown>();
|
||||
});
|
||||
|
||||
test("check never inference", () => {
|
||||
const t1 = z.never();
|
||||
expect(() => t1.parse(undefined)).toThrow();
|
||||
expect(() => t1.parse("asdf")).toThrow();
|
||||
expect(() => t1.parse(null)).toThrow();
|
||||
});
|
||||
264
frontend/node_modules/zod/src/v4/classic/tests/array.test.ts
generated
vendored
Normal file
264
frontend/node_modules/zod/src/v4/classic/tests/array.test.ts
generated
vendored
Normal file
@ -0,0 +1,264 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("type inference", () => {
|
||||
const schema = z.string().array();
|
||||
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<string[]>();
|
||||
});
|
||||
|
||||
test("array min/max", async () => {
|
||||
const schema = z.array(z.string()).min(2).max(2);
|
||||
const r1 = await schema.safeParse(["asdf"]);
|
||||
expect(r1.success).toEqual(false);
|
||||
expect(r1.error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected array to have >=2 items",
|
||||
"minimum": 2,
|
||||
"origin": "array",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
||||
const r2 = await schema.safeParse(["asdf", "asdf", "asdf"]);
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": true,
|
||||
"maximum": 2,
|
||||
"message": "Too big: expected array to have <=2 items",
|
||||
"origin": "array",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test("array length", async () => {
|
||||
const schema = z.array(z.string()).length(2);
|
||||
schema.parse(["asdf", "asdf"]);
|
||||
|
||||
const r1 = await schema.safeParse(["asdf"]);
|
||||
expect(r1.success).toEqual(false);
|
||||
expect(r1.error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"exact": true,
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected array to have >=2 items",
|
||||
"minimum": 2,
|
||||
"origin": "array",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
||||
const r2 = await schema.safeParse(["asdf", "asdf", "asdf"]);
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"exact": true,
|
||||
"inclusive": true,
|
||||
"maximum": 2,
|
||||
"message": "Too big: expected array to have <=2 items",
|
||||
"origin": "array",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test("array.nonempty()", () => {
|
||||
const schema = z.string().array().nonempty();
|
||||
schema.parse(["a"]);
|
||||
expect(() => schema.parse([])).toThrow();
|
||||
});
|
||||
|
||||
test("array.nonempty().max()", () => {
|
||||
const schema = z.string().array().nonempty().max(2);
|
||||
schema.parse(["a"]);
|
||||
expect(() => schema.parse([])).toThrow();
|
||||
expect(() => schema.parse(["a", "a", "a"])).toThrow();
|
||||
});
|
||||
|
||||
test("parse empty array in nonempty", () => {
|
||||
expect(() =>
|
||||
z
|
||||
.array(z.string())
|
||||
.nonempty()
|
||||
.parse([] as any)
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
test("get element", () => {
|
||||
const schema = z.string().array();
|
||||
schema.element.parse("asdf");
|
||||
expect(() => schema.element.parse(12)).toThrow();
|
||||
});
|
||||
|
||||
test("continue parsing despite array size error", () => {
|
||||
const schema = z.object({
|
||||
people: z.string().array().min(2),
|
||||
});
|
||||
|
||||
const result = schema.safeParse({
|
||||
people: [123],
|
||||
});
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"people",
|
||||
0
|
||||
],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
},
|
||||
{
|
||||
"origin": "array",
|
||||
"code": "too_small",
|
||||
"minimum": 2,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"people"
|
||||
],
|
||||
"message": "Too small: expected array to have >=2 items"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("parse should fail given sparse array", () => {
|
||||
const schema = z.array(z.string()).nonempty().min(1).max(3);
|
||||
const result = schema.safeParse(new Array(3));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
0
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
1
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
2
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
// const unique = z.string().array().unique();
|
||||
// const uniqueArrayOfObjects = z.array(z.object({ name: z.string() })).unique({ identifier: (item) => item.name });
|
||||
|
||||
// test("passing unique validation", () => {
|
||||
// unique.parse(["a", "b", "c"]);
|
||||
// uniqueArrayOfObjects.parse([{ name: "Leo" }, { name: "Joe" }]);
|
||||
// });
|
||||
|
||||
// test("failing unique validation", () => {
|
||||
// expect(() => unique.parse(["a", "a", "b"])).toThrow();
|
||||
// expect(() => uniqueArrayOfObjects.parse([{ name: "Leo" }, { name: "Leo" }])).toThrow();
|
||||
// });
|
||||
|
||||
// test("continue parsing despite array of primitives uniqueness error", () => {
|
||||
// const schema = z.number().array().unique();
|
||||
|
||||
// const result = schema.safeParse([1, 1, 2, 2, 3]);
|
||||
|
||||
// expect(result.success).toEqual(false);
|
||||
// if (!result.success) {
|
||||
// const issue = result.error.issues.find(({ code }) => code === "not_unique");
|
||||
// expect(issue?.message).toEqual("Values must be unique");
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("continue parsing despite array of objects not_unique error", () => {
|
||||
// const schema = z.array(z.object({ name: z.string() })).unique({
|
||||
// identifier: (item) => item.name,
|
||||
// showDuplicates: true,
|
||||
// });
|
||||
|
||||
// const result = schema.safeParse([
|
||||
// { name: "Leo" },
|
||||
// { name: "Joe" },
|
||||
// { name: "Leo" },
|
||||
// ]);
|
||||
|
||||
// expect(result.success).toEqual(false);
|
||||
// if (!result.success) {
|
||||
// const issue = result.error.issues.find(({ code }) => code === "not_unique");
|
||||
// expect(issue?.message).toEqual("Element(s): 'Leo' not unique");
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("returns custom error message without duplicate elements", () => {
|
||||
// const schema = z.number().array().unique({ message: "Custom message" });
|
||||
|
||||
// const result = schema.safeParse([1, 1, 2, 2, 3]);
|
||||
|
||||
// expect(result.success).toEqual(false);
|
||||
// if (!result.success) {
|
||||
// const issue = result.error.issues.find(({ code }) => code === "not_unique");
|
||||
// expect(issue?.message).toEqual("Custom message");
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("returns error message with duplicate elements", () => {
|
||||
// const schema = z.number().array().unique({ showDuplicates: true });
|
||||
|
||||
// const result = schema.safeParse([1, 1, 2, 2, 3]);
|
||||
|
||||
// expect(result.success).toEqual(false);
|
||||
// if (!result.success) {
|
||||
// const issue = result.error.issues.find(({ code }) => code === "not_unique");
|
||||
// expect(issue?.message).toEqual("Element(s): '1,2' not unique");
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("returns custom error message with duplicate elements", () => {
|
||||
// const schema = z
|
||||
// .number()
|
||||
// .array()
|
||||
// .unique({
|
||||
// message: (item) => `Custom message: '${item}' are not unique`,
|
||||
// showDuplicates: true,
|
||||
// });
|
||||
|
||||
// const result = schema.safeParse([1, 1, 2, 2, 3]);
|
||||
|
||||
// expect(result.success).toEqual(false);
|
||||
// if (!result.success) {
|
||||
// const issue = result.error.issues.find(({ code }) => code === "not_unique");
|
||||
// expect(issue?.message).toEqual("Custom message: '1,2' are not unique");
|
||||
// }
|
||||
// });
|
||||
210
frontend/node_modules/zod/src/v4/classic/tests/assignability.test.ts
generated
vendored
Normal file
210
frontend/node_modules/zod/src/v4/classic/tests/assignability.test.ts
generated
vendored
Normal file
@ -0,0 +1,210 @@
|
||||
import { expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("assignability", () => {
|
||||
// $ZodString
|
||||
z.string() satisfies z.core.$ZodString;
|
||||
z.string() satisfies z.ZodString;
|
||||
|
||||
// $ZodNumber
|
||||
z.number() satisfies z.core.$ZodNumber;
|
||||
z.number() satisfies z.ZodNumber;
|
||||
|
||||
// $ZodBigInt
|
||||
z.bigint() satisfies z.core.$ZodBigInt;
|
||||
z.bigint() satisfies z.ZodBigInt;
|
||||
|
||||
// $ZodBoolean
|
||||
z.boolean() satisfies z.core.$ZodBoolean;
|
||||
z.boolean() satisfies z.ZodBoolean;
|
||||
|
||||
// $ZodDate
|
||||
z.date() satisfies z.core.$ZodDate;
|
||||
z.date() satisfies z.ZodDate;
|
||||
|
||||
// $ZodSymbol
|
||||
z.symbol() satisfies z.core.$ZodSymbol;
|
||||
z.symbol() satisfies z.ZodSymbol;
|
||||
|
||||
// $ZodUndefined
|
||||
z.undefined() satisfies z.core.$ZodUndefined;
|
||||
z.undefined() satisfies z.ZodUndefined;
|
||||
|
||||
// $ZodNullable
|
||||
z.string().nullable() satisfies z.core.$ZodNullable;
|
||||
z.string().nullable() satisfies z.ZodNullable;
|
||||
|
||||
// $ZodNull
|
||||
z.null() satisfies z.core.$ZodNull;
|
||||
z.null() satisfies z.ZodNull;
|
||||
|
||||
// $ZodAny
|
||||
z.any() satisfies z.core.$ZodAny;
|
||||
z.any() satisfies z.ZodAny;
|
||||
|
||||
// $ZodUnknown
|
||||
z.unknown() satisfies z.core.$ZodUnknown;
|
||||
z.unknown() satisfies z.ZodUnknown;
|
||||
|
||||
// $ZodNever
|
||||
z.never() satisfies z.core.$ZodNever;
|
||||
z.never() satisfies z.ZodNever;
|
||||
|
||||
// $ZodVoid
|
||||
z.void() satisfies z.core.$ZodVoid;
|
||||
z.void() satisfies z.ZodVoid;
|
||||
|
||||
// $ZodArray
|
||||
z.array(z.string()) satisfies z.core.$ZodArray;
|
||||
z.array(z.string()) satisfies z.ZodArray;
|
||||
z.array(z.string()) satisfies z.ZodType<Array<unknown>>;
|
||||
|
||||
// $ZodObject
|
||||
z.object({ key: z.string() }) satisfies z.core.$ZodObject;
|
||||
z.object({ key: z.string() }) satisfies z.ZodObject<{ key: z.ZodType }>;
|
||||
z.object({ key: z.string() }) satisfies z.ZodType<{ key: string }>;
|
||||
|
||||
// $ZodUnion
|
||||
z.union([z.string(), z.number()]) satisfies z.core.$ZodUnion;
|
||||
z.union([z.string(), z.number()]) satisfies z.ZodUnion;
|
||||
z.union([z.string(), z.number()]) satisfies z.ZodType<string | number>;
|
||||
|
||||
// $ZodIntersection
|
||||
z.intersection(z.string(), z.number()) satisfies z.core.$ZodIntersection;
|
||||
z.intersection(z.string(), z.number()) satisfies z.ZodIntersection;
|
||||
|
||||
// $ZodTuple
|
||||
z.tuple([z.string(), z.number()]) satisfies z.core.$ZodTuple;
|
||||
z.tuple([z.string(), z.number()]) satisfies z.ZodTuple;
|
||||
|
||||
// $ZodRecord
|
||||
z.record(z.string(), z.number()) satisfies z.core.$ZodRecord;
|
||||
z.record(z.string(), z.number()) satisfies z.ZodRecord;
|
||||
|
||||
// $ZodMap
|
||||
z.map(z.string(), z.number()) satisfies z.core.$ZodMap;
|
||||
z.map(z.string(), z.number()) satisfies z.ZodMap;
|
||||
|
||||
// $ZodSet
|
||||
z.set(z.string()) satisfies z.core.$ZodSet;
|
||||
z.set(z.string()) satisfies z.ZodSet;
|
||||
|
||||
// $ZodLiteral
|
||||
z.literal("example") satisfies z.core.$ZodLiteral;
|
||||
z.literal("example") satisfies z.ZodLiteral;
|
||||
|
||||
// $ZodEnum
|
||||
z.enum(["a", "b", "c"]) satisfies z.core.$ZodEnum;
|
||||
z.enum(["a", "b", "c"]) satisfies z.ZodEnum;
|
||||
|
||||
// $ZodPromise
|
||||
z.promise(z.string()) satisfies z.core.$ZodPromise;
|
||||
z.promise(z.string()) satisfies z.ZodPromise;
|
||||
|
||||
// $ZodLazy
|
||||
const lazySchema = z.lazy(() => z.string());
|
||||
lazySchema satisfies z.core.$ZodLazy;
|
||||
lazySchema satisfies z.ZodLazy;
|
||||
|
||||
// $ZodOptional
|
||||
z.string().optional() satisfies z.core.$ZodOptional;
|
||||
z.string().optional() satisfies z.ZodOptional;
|
||||
|
||||
// $ZodDefault
|
||||
z.string().default("default") satisfies z.core.$ZodDefault;
|
||||
z.string().default("default") satisfies z.ZodDefault;
|
||||
|
||||
// $ZodTemplateLiteral
|
||||
z.templateLiteral([z.literal("a"), z.literal("b")]) satisfies z.core.$ZodTemplateLiteral;
|
||||
z.templateLiteral([z.literal("a"), z.literal("b")]) satisfies z.ZodTemplateLiteral;
|
||||
|
||||
// $ZodCustom
|
||||
z.custom<string>((val) => typeof val === "string") satisfies z.core.$ZodCustom;
|
||||
z.custom<string>((val) => typeof val === "string") satisfies z.ZodCustom;
|
||||
|
||||
// $ZodTransform
|
||||
z.transform((val) => val as string) satisfies z.core.$ZodTransform;
|
||||
z.transform((val) => val as string) satisfies z.ZodTransform;
|
||||
|
||||
// $ZodNonOptional
|
||||
z.string().optional().nonoptional() satisfies z.core.$ZodNonOptional;
|
||||
z.string().optional().nonoptional() satisfies z.ZodNonOptional;
|
||||
|
||||
// $ZodReadonly
|
||||
z.object({ key: z.string() }).readonly() satisfies z.core.$ZodReadonly;
|
||||
z.object({ key: z.string() }).readonly() satisfies z.ZodReadonly;
|
||||
|
||||
// $ZodNaN
|
||||
z.nan() satisfies z.core.$ZodNaN;
|
||||
z.nan() satisfies z.ZodNaN;
|
||||
|
||||
// $ZodPipe
|
||||
z.unknown().pipe(z.number()) satisfies z.core.$ZodPipe;
|
||||
z.unknown().pipe(z.number()) satisfies z.ZodPipe;
|
||||
|
||||
// $ZodSuccess
|
||||
z.success(z.string()) satisfies z.core.$ZodSuccess;
|
||||
z.success(z.string()) satisfies z.ZodSuccess;
|
||||
|
||||
// $ZodCatch
|
||||
z.string().catch("fallback") satisfies z.core.$ZodCatch;
|
||||
z.string().catch("fallback") satisfies z.ZodCatch;
|
||||
|
||||
// $ZodFile
|
||||
z.file() satisfies z.core.$ZodFile;
|
||||
z.file() satisfies z.ZodFile;
|
||||
});
|
||||
|
||||
test("checks", () => {
|
||||
const _a: z.core.$ZodCheck = {} as any as z.core.$ZodChecks;
|
||||
const _b: z.core.$ZodCheck = {} as any as z.core.$ZodStringFormatChecks;
|
||||
const _c: z.core.$ZodType = {} as any as z.core.$ZodTypes;
|
||||
const _d: z.core.$ZodType = {} as any as z.core.$ZodStringFormatTypes;
|
||||
});
|
||||
|
||||
test("assignability to $ZodType", () => {
|
||||
z.string() satisfies z.ZodType;
|
||||
z.number() satisfies z.ZodType;
|
||||
z.boolean() satisfies z.ZodType;
|
||||
z.object({ key: z.string() }) satisfies z.ZodType;
|
||||
z.object({ key: z.string() }) satisfies z.ZodType<{ key: string }>;
|
||||
z.array(z.string()) satisfies z.ZodType;
|
||||
z.union([z.string(), z.number()]) satisfies z.ZodType;
|
||||
z.intersection(z.string(), z.number()) satisfies z.ZodType;
|
||||
z.tuple([z.string(), z.number()]) satisfies z.ZodType;
|
||||
z.record(z.string(), z.number()) satisfies z.ZodType;
|
||||
z.map(z.string(), z.number()) satisfies z.ZodType;
|
||||
z.set(z.string()) satisfies z.ZodType;
|
||||
z.literal("example") satisfies z.ZodType;
|
||||
|
||||
expectTypeOf<z.ZodType extends z.core.$ZodType ? true : false>().toEqualTypeOf<true>();
|
||||
});
|
||||
|
||||
test("assignability with narrowing", () => {
|
||||
type _RefinedSchema<T extends z.ZodType<object> | z.ZodUnion> = T extends z.ZodUnion
|
||||
? RefinedUnionSchema<T> // <-- Type instantiation is excessively deep and possibly infinite.
|
||||
: T extends z.ZodType<object>
|
||||
? RefinedTypeSchema<z.output<T>> // <-- Type instantiation is excessively deep and possibly infinite.
|
||||
: never;
|
||||
|
||||
type RefinedTypeSchema<T extends object> = T;
|
||||
|
||||
type RefinedUnionSchema<T extends z.ZodUnion> = T;
|
||||
});
|
||||
|
||||
test("generic assignability in objects", () => {
|
||||
interface SortItem<T extends string> {
|
||||
key: T;
|
||||
order: string;
|
||||
}
|
||||
|
||||
const createSortItemSchema = <T extends z.ZodType<string>>(sortKeySchema: T) =>
|
||||
z.object({
|
||||
key: sortKeySchema,
|
||||
order: z.string(),
|
||||
});
|
||||
|
||||
<T extends z.ZodType<string>>(sortKeySchema: T, defaultSortBy: SortItem<z.output<T>>[] = []) =>
|
||||
createSortItemSchema(sortKeySchema).array().default(defaultSortBy);
|
||||
});
|
||||
381
frontend/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts
generated
vendored
Normal file
381
frontend/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts
generated
vendored
Normal file
@ -0,0 +1,381 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
/// string
|
||||
const stringSchema = z.string();
|
||||
|
||||
test("string async parse", async () => {
|
||||
const goodData = "XXX";
|
||||
const badData = 12;
|
||||
|
||||
const goodResult = await stringSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await stringSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// number
|
||||
const numberSchema = z.number();
|
||||
test("number async parse", async () => {
|
||||
const goodData = 1234.2353;
|
||||
const badData = "1234";
|
||||
|
||||
const goodResult = await numberSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await numberSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// bigInt
|
||||
const bigIntSchema = z.bigint();
|
||||
test("bigInt async parse", async () => {
|
||||
const goodData = BigInt(145);
|
||||
const badData = 134;
|
||||
|
||||
const goodResult = await bigIntSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await bigIntSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// boolean
|
||||
const booleanSchema = z.boolean();
|
||||
test("boolean async parse", async () => {
|
||||
const goodData = true;
|
||||
const badData = 1;
|
||||
|
||||
const goodResult = await booleanSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await booleanSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// date
|
||||
const dateSchema = z.date();
|
||||
test("date async parse", async () => {
|
||||
const goodData = new Date();
|
||||
const badData = new Date().toISOString();
|
||||
|
||||
const goodResult = await dateSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await dateSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// undefined
|
||||
const undefinedSchema = z.undefined();
|
||||
test("undefined async parse", async () => {
|
||||
const goodData = undefined;
|
||||
const badData = "XXX";
|
||||
|
||||
const goodResult = await undefinedSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(undefined);
|
||||
|
||||
const badResult = await undefinedSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// null
|
||||
const nullSchema = z.null();
|
||||
test("null async parse", async () => {
|
||||
const goodData = null;
|
||||
const badData = undefined;
|
||||
|
||||
const goodResult = await nullSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await nullSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// any
|
||||
const anySchema = z.any();
|
||||
test("any async parse", async () => {
|
||||
const goodData = [{}];
|
||||
// const badData = 'XXX';
|
||||
|
||||
const goodResult = await anySchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
// const badResult = await anySchema.safeParseAsync(badData);
|
||||
// expect(badResult.success).toBe(false);
|
||||
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// unknown
|
||||
const unknownSchema = z.unknown();
|
||||
test("unknown async parse", async () => {
|
||||
const goodData = ["asdf", 124, () => {}];
|
||||
// const badData = 'XXX';
|
||||
|
||||
const goodResult = await unknownSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
// const badResult = await unknownSchema.safeParseAsync(badData);
|
||||
// expect(badResult.success).toBe(false);
|
||||
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// void
|
||||
const voidSchema = z.void();
|
||||
test("void async parse", async () => {
|
||||
const goodData = undefined;
|
||||
const badData = 0;
|
||||
|
||||
const goodResult = await voidSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await voidSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// array
|
||||
const arraySchema = z.array(z.string());
|
||||
test("array async parse", async () => {
|
||||
const goodData = ["XXX"];
|
||||
const badData = "XXX";
|
||||
|
||||
const goodResult = await arraySchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await arraySchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// object
|
||||
const objectSchema = z.object({ string: z.string() });
|
||||
test("object async parse", async () => {
|
||||
const goodData = { string: "XXX" };
|
||||
const badData = { string: 12 };
|
||||
|
||||
const goodResult = await objectSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await objectSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// union
|
||||
const unionSchema = z.union([z.string(), z.undefined()]);
|
||||
test("union async parse", async () => {
|
||||
const goodData = undefined;
|
||||
const badData = null;
|
||||
|
||||
const goodResult = await unionSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await unionSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// record
|
||||
const recordSchema = z.record(z.string(), z.object({}));
|
||||
test("record async parse", async () => {
|
||||
const goodData = { adsf: {}, asdf: {} };
|
||||
const badData = [{}];
|
||||
|
||||
const goodResult = await recordSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await recordSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// function
|
||||
// const functionSchema = z.function();
|
||||
// test("function async parse", async () => {
|
||||
// const goodData = () => {};
|
||||
// const badData = "XXX";
|
||||
|
||||
// const goodResult = await functionSchema.safeParseAsync(goodData);
|
||||
// expect(goodResult.success).toBe(true);
|
||||
// if (goodResult.success) expect(typeof goodResult.data).toEqual("function");
|
||||
|
||||
// const badResult = await functionSchema.safeParseAsync(badData);
|
||||
// expect(badResult.success).toBe(false);
|
||||
// if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
// });
|
||||
|
||||
/// literal
|
||||
const literalSchema = z.literal("asdf");
|
||||
test("literal async parse", async () => {
|
||||
const goodData = "asdf";
|
||||
const badData = "asdff";
|
||||
|
||||
const goodResult = await literalSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await literalSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// enum
|
||||
const enumSchema = z.enum(["fish", "whale"]);
|
||||
test("enum async parse", async () => {
|
||||
const goodData = "whale";
|
||||
const badData = "leopard";
|
||||
|
||||
const goodResult = await enumSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await enumSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// nativeEnum
|
||||
enum nativeEnumTest {
|
||||
asdf = "qwer",
|
||||
}
|
||||
// @ts-ignore
|
||||
const nativeEnumSchema = z.nativeEnum(nativeEnumTest);
|
||||
test("nativeEnum async parse", async () => {
|
||||
const goodData = nativeEnumTest.asdf;
|
||||
const badData = "asdf";
|
||||
|
||||
const goodResult = await nativeEnumSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
if (goodResult.success) expect(goodResult.data).toEqual(goodData);
|
||||
|
||||
const badResult = await nativeEnumSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
if (!badResult.success) expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
/// promise
|
||||
const promiseSchema = z.promise(z.number());
|
||||
test("promise async parse good", async () => {
|
||||
const goodData = Promise.resolve(123);
|
||||
|
||||
const goodResult = await promiseSchema.safeParseAsync(goodData);
|
||||
expect(goodResult.success).toBe(true);
|
||||
expect(typeof goodResult.data).toEqual("number");
|
||||
expect(goodResult.data).toEqual(123);
|
||||
});
|
||||
|
||||
test("promise async parse bad", async () => {
|
||||
const badData = Promise.resolve("XXX");
|
||||
const badResult = await promiseSchema.safeParseAsync(badData);
|
||||
expect(badResult.success).toBe(false);
|
||||
expect(badResult.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
test("async validation non-empty strings", async () => {
|
||||
const base = z.object({
|
||||
hello: z.string().refine((x) => x && x.length > 0),
|
||||
foo: z.string().refine((x) => x && x.length > 0),
|
||||
});
|
||||
|
||||
const testval = { hello: "", foo: "" };
|
||||
const result1 = base.safeParse(testval);
|
||||
const result2 = base.safeParseAsync(testval);
|
||||
|
||||
const r1 = result1;
|
||||
await result2.then((r2) => {
|
||||
expect(r1.error!.issues.length).toBe(r2.error!.issues.length);
|
||||
});
|
||||
});
|
||||
|
||||
test("async validation multiple errors 1", async () => {
|
||||
const base = z.object({
|
||||
hello: z.string(),
|
||||
foo: z.number(),
|
||||
});
|
||||
|
||||
const testval = { hello: 3, foo: "hello" };
|
||||
const result1 = base.safeParse(testval);
|
||||
const result2 = base.safeParseAsync(testval);
|
||||
|
||||
await result2.then((result2) => {
|
||||
expect(result2.error!.issues.length).toBe(result1.error!.issues.length);
|
||||
});
|
||||
});
|
||||
|
||||
test("async validation multiple errors 2", async () => {
|
||||
const base = (is_async?: boolean) =>
|
||||
z.object({
|
||||
hello: z.string(),
|
||||
foo: z.object({
|
||||
bar: z.number().refine(
|
||||
is_async
|
||||
? async () =>
|
||||
new Promise((resolve) => {
|
||||
setTimeout(() => resolve(false), 500);
|
||||
})
|
||||
: () => false
|
||||
),
|
||||
}),
|
||||
});
|
||||
|
||||
const testval = { hello: 3, foo: { bar: 4 } };
|
||||
const result1 = base().safeParse(testval);
|
||||
const result2 = base(true).safeParseAsync(testval);
|
||||
|
||||
await result2.then((result2) => {
|
||||
expect(result1.error!.issues.length).toBe(result2.error!.issues.length);
|
||||
});
|
||||
});
|
||||
|
||||
test("ensure early async failure prevents follow-up refinement checks", async () => {
|
||||
let count = 0;
|
||||
const base = z.object({
|
||||
hello: z.string(),
|
||||
foo: z
|
||||
.number()
|
||||
.refine(async () => {
|
||||
count++;
|
||||
return true;
|
||||
})
|
||||
.refine(async () => {
|
||||
count++;
|
||||
return true;
|
||||
}, "Good"),
|
||||
});
|
||||
|
||||
const testval = { hello: "bye", foo: 3 };
|
||||
const result = await base.safeParseAsync(testval);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toBe(1);
|
||||
expect(count).toBe(1);
|
||||
}
|
||||
|
||||
// await result.then((r) => {
|
||||
// if (r.success === false) expect(r.error.issues.length).toBe(1);
|
||||
// expect(count).toBe(2);
|
||||
// });
|
||||
});
|
||||
68
frontend/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts
generated
vendored
Normal file
68
frontend/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("async refine .parse()", async () => {
|
||||
// throws ZodAsyncError
|
||||
const s1 = z.string().refine(async (_val) => true);
|
||||
expect(() => s1.safeParse("asdf")).toThrow();
|
||||
});
|
||||
|
||||
test("async refine", async () => {
|
||||
const s1 = z.string().refine(async (_val) => true);
|
||||
const r1 = await s1.parseAsync("asdf");
|
||||
expect(r1).toEqual("asdf");
|
||||
|
||||
const s2 = z.string().refine(async (_val) => false);
|
||||
const r2 = await s2.safeParseAsync("asdf");
|
||||
expect(r2.success).toBe(false);
|
||||
expect(r2).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("async refine with Promises", async () => {
|
||||
// expect.assertions(2);
|
||||
|
||||
const schema1 = z.string().refine((_val) => Promise.resolve(true));
|
||||
const v1 = await schema1.parseAsync("asdf");
|
||||
expect(v1).toEqual("asdf");
|
||||
|
||||
const schema2 = z.string().refine((_val) => Promise.resolve(false));
|
||||
await expect(schema2.parseAsync("asdf")).rejects.toBeDefined();
|
||||
|
||||
const schema3 = z.string().refine((_val) => Promise.resolve(true));
|
||||
await expect(schema3.parseAsync("asdf")).resolves.toEqual("asdf");
|
||||
return await expect(schema3.parseAsync("qwer")).resolves.toEqual("qwer");
|
||||
});
|
||||
|
||||
test("async refine that uses value", async () => {
|
||||
const schema1 = z.string().refine(async (val) => {
|
||||
return val.length > 5;
|
||||
});
|
||||
|
||||
const r1 = await schema1.safeParseAsync("asdf");
|
||||
expect(r1.success).toBe(false);
|
||||
expect(r1.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const r2 = await schema1.safeParseAsync("asdf123");
|
||||
expect(r2.success).toBe(true);
|
||||
expect(r2.data).toEqual("asdf123");
|
||||
});
|
||||
7
frontend/node_modules/zod/src/v4/classic/tests/base.test.ts
generated
vendored
Normal file
7
frontend/node_modules/zod/src/v4/classic/tests/base.test.ts
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("test this binding", () => {
|
||||
const parse = z.string().parse;
|
||||
expect(parse("asdf")).toBe("asdf");
|
||||
});
|
||||
54
frontend/node_modules/zod/src/v4/classic/tests/bigint.test.ts
generated
vendored
Normal file
54
frontend/node_modules/zod/src/v4/classic/tests/bigint.test.ts
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const gtFive = z.bigint().gt(BigInt(5));
|
||||
const gteFive = z.bigint().gte(BigInt(5));
|
||||
const ltFive = z.bigint().lt(BigInt(5));
|
||||
const lteFive = z.bigint().lte(BigInt(5));
|
||||
const positive = z.bigint().positive();
|
||||
const negative = z.bigint().negative();
|
||||
const nonnegative = z.bigint().nonnegative();
|
||||
const nonpositive = z.bigint().nonpositive();
|
||||
const multipleOfFive = z.bigint().multipleOf(BigInt(5));
|
||||
|
||||
test("passing validations", () => {
|
||||
z.bigint().parse(BigInt(1));
|
||||
z.bigint().parse(BigInt(0));
|
||||
z.bigint().parse(BigInt(-1));
|
||||
gtFive.parse(BigInt(6));
|
||||
gteFive.parse(BigInt(5));
|
||||
gteFive.parse(BigInt(6));
|
||||
ltFive.parse(BigInt(4));
|
||||
lteFive.parse(BigInt(5));
|
||||
lteFive.parse(BigInt(4));
|
||||
positive.parse(BigInt(3));
|
||||
negative.parse(BigInt(-2));
|
||||
nonnegative.parse(BigInt(0));
|
||||
nonnegative.parse(BigInt(7));
|
||||
nonpositive.parse(BigInt(0));
|
||||
nonpositive.parse(BigInt(-12));
|
||||
multipleOfFive.parse(BigInt(15));
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => gtFive.parse(BigInt(5))).toThrow();
|
||||
expect(() => gteFive.parse(BigInt(4))).toThrow();
|
||||
expect(() => ltFive.parse(BigInt(5))).toThrow();
|
||||
expect(() => lteFive.parse(BigInt(6))).toThrow();
|
||||
expect(() => positive.parse(BigInt(0))).toThrow();
|
||||
expect(() => positive.parse(BigInt(-2))).toThrow();
|
||||
expect(() => negative.parse(BigInt(0))).toThrow();
|
||||
expect(() => negative.parse(BigInt(3))).toThrow();
|
||||
expect(() => nonnegative.parse(BigInt(-1))).toThrow();
|
||||
expect(() => nonpositive.parse(BigInt(1))).toThrow();
|
||||
expect(() => multipleOfFive.parse(BigInt(13))).toThrow();
|
||||
});
|
||||
|
||||
test("min max getters", () => {
|
||||
expect(z.bigint().min(BigInt(5)).minValue).toEqual(BigInt(5));
|
||||
expect(z.bigint().min(BigInt(5)).min(BigInt(10)).minValue).toEqual(BigInt(10));
|
||||
|
||||
expect(z.bigint().max(BigInt(5)).maxValue).toEqual(BigInt(5));
|
||||
expect(z.bigint().max(BigInt(5)).max(BigInt(1)).maxValue).toEqual(BigInt(1));
|
||||
});
|
||||
63
frontend/node_modules/zod/src/v4/classic/tests/brand.test.ts
generated
vendored
Normal file
63
frontend/node_modules/zod/src/v4/classic/tests/brand.test.ts
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
import { expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("branded types", () => {
|
||||
const mySchema = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
})
|
||||
.brand<"superschema">();
|
||||
|
||||
// simple branding
|
||||
type MySchema = z.infer<typeof mySchema>;
|
||||
|
||||
expectTypeOf<MySchema>().toEqualTypeOf<{ name: string } & z.$brand<"superschema">>();
|
||||
|
||||
const doStuff = (arg: MySchema) => arg;
|
||||
doStuff(mySchema.parse({ name: "hello there" }));
|
||||
|
||||
// inheritance
|
||||
const extendedSchema = mySchema.brand<"subschema">();
|
||||
type ExtendedSchema = z.infer<typeof extendedSchema>;
|
||||
expectTypeOf<ExtendedSchema>().toEqualTypeOf<{ name: string } & z.BRAND<"superschema"> & z.BRAND<"subschema">>();
|
||||
|
||||
doStuff(extendedSchema.parse({ name: "hello again" }));
|
||||
|
||||
// number branding
|
||||
const numberSchema = z.number().brand<42>();
|
||||
type NumberSchema = z.infer<typeof numberSchema>;
|
||||
expectTypeOf<NumberSchema>().toEqualTypeOf<number & { [z.$brand]: { 42: true } }>();
|
||||
|
||||
// symbol branding
|
||||
const MyBrand: unique symbol = Symbol("hello");
|
||||
type MyBrand = typeof MyBrand;
|
||||
const symbolBrand = z.number().brand<"sup">().brand<typeof MyBrand>();
|
||||
type SymbolBrand = z.infer<typeof symbolBrand>;
|
||||
// number & { [z.BRAND]: { sup: true, [MyBrand]: true } }
|
||||
expectTypeOf<SymbolBrand>().toEqualTypeOf<number & z.BRAND<"sup"> & z.BRAND<MyBrand>>();
|
||||
|
||||
// keeping brands out of input types
|
||||
const age = z.number().brand<"age">();
|
||||
|
||||
type Age = z.infer<typeof age>;
|
||||
type AgeInput = z.input<typeof age>;
|
||||
|
||||
expectTypeOf<AgeInput>().not.toEqualTypeOf<Age>();
|
||||
expectTypeOf<number>().toEqualTypeOf<AgeInput>();
|
||||
expectTypeOf<number & z.BRAND<"age">>().toEqualTypeOf<Age>();
|
||||
|
||||
// @ts-expect-error
|
||||
doStuff({ name: "hello there!" });
|
||||
});
|
||||
|
||||
test("$branded", () => {
|
||||
const a = z.string().brand<"a">();
|
||||
|
||||
expectTypeOf<typeof a>().toEqualTypeOf<z.core.$ZodBranded<z.ZodString, "a">>();
|
||||
});
|
||||
|
||||
test("branded record", () => {
|
||||
const recordWithBrandedNumberKeys = z.record(z.string().brand("SomeBrand"), z.number());
|
||||
type recordWithBrandedNumberKeys = z.infer<typeof recordWithBrandedNumberKeys>;
|
||||
expectTypeOf<recordWithBrandedNumberKeys>().toEqualTypeOf<Record<string & z.core.$brand<"SomeBrand">, number>>();
|
||||
});
|
||||
252
frontend/node_modules/zod/src/v4/classic/tests/catch.test.ts
generated
vendored
Normal file
252
frontend/node_modules/zod/src/v4/classic/tests/catch.test.ts
generated
vendored
Normal file
@ -0,0 +1,252 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import { z } from "zod/v4";
|
||||
import type { util } from "zod/v4/core";
|
||||
|
||||
test("basic catch", () => {
|
||||
expect(z.string().catch("default").parse(undefined)).toBe("default");
|
||||
});
|
||||
|
||||
test("catch fn does not run when parsing succeeds", () => {
|
||||
let isCalled = false;
|
||||
const cb = () => {
|
||||
isCalled = true;
|
||||
return "asdf";
|
||||
};
|
||||
expect(z.string().catch(cb).parse("test")).toBe("test");
|
||||
expect(isCalled).toEqual(false);
|
||||
});
|
||||
|
||||
test("basic catch async", async () => {
|
||||
const result = await z.string().catch("default").parseAsync(1243);
|
||||
expect(result).toBe("default");
|
||||
});
|
||||
|
||||
test("catch replace wrong types", () => {
|
||||
expect(z.string().catch("default").parse(true)).toBe("default");
|
||||
expect(z.string().catch("default").parse(true)).toBe("default");
|
||||
expect(z.string().catch("default").parse(15)).toBe("default");
|
||||
expect(z.string().catch("default").parse([])).toBe("default");
|
||||
expect(z.string().catch("default").parse(new Map())).toBe("default");
|
||||
expect(z.string().catch("default").parse(new Set())).toBe("default");
|
||||
expect(z.string().catch("default").parse({})).toBe("default");
|
||||
});
|
||||
|
||||
test("catch with transform", () => {
|
||||
const stringWithDefault = z
|
||||
.string()
|
||||
.transform((val) => val.toUpperCase())
|
||||
.catch("default");
|
||||
|
||||
expect(stringWithDefault.parse(undefined)).toBe("default");
|
||||
expect(stringWithDefault.parse(15)).toBe("default");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodCatch);
|
||||
expect(stringWithDefault.unwrap()).toBeInstanceOf(z.ZodPipe);
|
||||
expect(stringWithDefault.unwrap().in).toBeInstanceOf(z.ZodString);
|
||||
expect(stringWithDefault.unwrap().out).toBeInstanceOf(z.ZodTransform);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | util.Whatever>();
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("catch on existing optional", () => {
|
||||
const stringWithDefault = z.string().optional().catch("asdf");
|
||||
expect(stringWithDefault.parse(undefined)).toBe(undefined);
|
||||
expect(stringWithDefault.parse(15)).toBe("asdf");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodCatch);
|
||||
expect(stringWithDefault.unwrap()).toBeInstanceOf(z.ZodOptional);
|
||||
expect(stringWithDefault.unwrap().unwrap()).toBeInstanceOf(z.ZodString);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | undefined | util.Whatever>();
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string | undefined>();
|
||||
});
|
||||
|
||||
test("optional on catch", () => {
|
||||
const stringWithDefault = z.string().catch("asdf").optional();
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | util.Whatever>();
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string | undefined>();
|
||||
});
|
||||
|
||||
test("complex chain example", () => {
|
||||
const complex = z
|
||||
.string()
|
||||
.catch("asdf")
|
||||
.transform((val) => `${val}!`)
|
||||
.transform((val) => val.toUpperCase())
|
||||
.catch("qwer")
|
||||
.unwrap()
|
||||
.optional()
|
||||
.catch("asdfasdf");
|
||||
|
||||
expect(complex.parse("qwer")).toBe("QWER!");
|
||||
expect(complex.parse(15)).toBe("ASDF!");
|
||||
expect(complex.parse(true)).toBe("ASDF!");
|
||||
});
|
||||
|
||||
test("removeCatch", () => {
|
||||
const stringWithRemovedDefault = z.string().catch("asdf").unwrap();
|
||||
|
||||
type out = z.output<typeof stringWithRemovedDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("nested", () => {
|
||||
const inner = z.string().catch("asdf");
|
||||
const outer = z.object({ inner }).catch({
|
||||
inner: "asdf",
|
||||
});
|
||||
type input = z.input<typeof outer>;
|
||||
expectTypeOf<input>().toEqualTypeOf<{ inner: string | util.Whatever } | util.Whatever>();
|
||||
type out = z.output<typeof outer>;
|
||||
|
||||
expectTypeOf<out>().toEqualTypeOf<{ inner: string }>();
|
||||
expect(outer.parse(undefined)).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({})).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({ inner: undefined })).toEqual({ inner: "asdf" });
|
||||
});
|
||||
|
||||
test("chained catch", () => {
|
||||
const stringWithDefault = z.string().catch("inner").catch("outer");
|
||||
const result = stringWithDefault.parse(undefined);
|
||||
expect(result).toEqual("inner");
|
||||
const resultDiff = stringWithDefault.parse(5);
|
||||
expect(resultDiff).toEqual("inner");
|
||||
});
|
||||
|
||||
test("native enum", () => {
|
||||
enum Fruits {
|
||||
apple = "apple",
|
||||
orange = "orange",
|
||||
}
|
||||
|
||||
const schema = z.object({
|
||||
fruit: z.nativeEnum(Fruits).catch(Fruits.apple),
|
||||
});
|
||||
|
||||
expect(schema.parse({})).toEqual({ fruit: Fruits.apple });
|
||||
expect(schema.parse({ fruit: 15 })).toEqual({ fruit: Fruits.apple });
|
||||
});
|
||||
|
||||
test("enum", () => {
|
||||
const schema = z.object({
|
||||
fruit: z.enum(["apple", "orange"]).catch("apple"),
|
||||
});
|
||||
|
||||
expect(schema.parse({})).toEqual({ fruit: "apple" });
|
||||
expect(schema.parse({ fruit: true })).toEqual({ fruit: "apple" });
|
||||
expect(schema.parse({ fruit: 15 })).toEqual({ fruit: "apple" });
|
||||
});
|
||||
|
||||
test("reported issues with nested usage", () => {
|
||||
const schema = z.object({
|
||||
string: z.string(),
|
||||
obj: z.object({
|
||||
sub: z.object({
|
||||
lit: z.literal("a"),
|
||||
subCatch: z.number().catch(23),
|
||||
}),
|
||||
midCatch: z.number().catch(42),
|
||||
}),
|
||||
number: z.number().catch(0),
|
||||
bool: z.boolean(),
|
||||
});
|
||||
|
||||
try {
|
||||
schema.parse({
|
||||
string: {},
|
||||
obj: {
|
||||
sub: {
|
||||
lit: "b",
|
||||
subCatch: "24",
|
||||
},
|
||||
midCatch: 444,
|
||||
},
|
||||
number: "",
|
||||
bool: "yes",
|
||||
});
|
||||
} catch (error) {
|
||||
const issues = (error as z.ZodError).issues;
|
||||
|
||||
expect(issues.length).toEqual(3);
|
||||
expect(issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received object",
|
||||
"path": [
|
||||
"string",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"message": "Invalid input: expected "a"",
|
||||
"path": [
|
||||
"obj",
|
||||
"sub",
|
||||
"lit",
|
||||
],
|
||||
"values": [
|
||||
"a",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "boolean",
|
||||
"message": "Invalid input: expected boolean, received string",
|
||||
"path": [
|
||||
"bool",
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
// expect(issues[0].message).toMatch("string");
|
||||
// expect(issues[1].message).toMatch("literal");
|
||||
// expect(issues[2].message).toMatch("boolean");
|
||||
}
|
||||
});
|
||||
|
||||
test("catch error", () => {
|
||||
const schema = z.object({
|
||||
age: z.number(),
|
||||
name: z.string().catch((ctx) => {
|
||||
ctx.issues;
|
||||
// issues = ctx.issues;
|
||||
|
||||
return "John Doe";
|
||||
}),
|
||||
});
|
||||
|
||||
const result = schema.safeParse({
|
||||
age: null,
|
||||
name: null,
|
||||
});
|
||||
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"age"
|
||||
],
|
||||
"message": "Invalid input: expected number, received null"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("ctx.input", () => {
|
||||
const schema = z.string().catch((ctx) => {
|
||||
return String(ctx.input);
|
||||
});
|
||||
|
||||
expect(schema.parse(123)).toEqual("123");
|
||||
});
|
||||
20
frontend/node_modules/zod/src/v4/classic/tests/coalesce.test.ts
generated
vendored
Normal file
20
frontend/node_modules/zod/src/v4/classic/tests/coalesce.test.ts
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
test("coalesce", () => {
|
||||
expect(true).toBe(true);
|
||||
});
|
||||
|
||||
// test("nonoptional with default", () => {
|
||||
// const schema = z.string().optional().coalesce("hi");
|
||||
// expectTypeOf<typeof schema._input>().toEqualTypeOf<string | undefined>();
|
||||
// expectTypeOf<typeof schema._output>().toEqualTypeOf<string>();
|
||||
// expect(schema.parse(undefined)).toBe("hi");
|
||||
// });
|
||||
|
||||
// test("nonoptional in object", () => {
|
||||
// const schema = z.object({ hi: z.string().optional().nonoptional("hi") });
|
||||
|
||||
// expectTypeOf<typeof schema._input>().toEqualTypeOf<{ hi: string | undefined }>();
|
||||
// expectTypeOf<typeof schema._output>().toEqualTypeOf<{ hi: string }>();
|
||||
// expect(schema.parse(undefined)).toBe("hi");
|
||||
// });
|
||||
160
frontend/node_modules/zod/src/v4/classic/tests/coerce.test.ts
generated
vendored
Normal file
160
frontend/node_modules/zod/src/v4/classic/tests/coerce.test.ts
generated
vendored
Normal file
@ -0,0 +1,160 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("string coercion", () => {
|
||||
const schema = z.coerce.string();
|
||||
expect(schema.parse("sup")).toEqual("sup");
|
||||
expect(schema.parse("")).toEqual("");
|
||||
expect(schema.parse(12)).toEqual("12");
|
||||
expect(schema.parse(0)).toEqual("0");
|
||||
expect(schema.parse(-12)).toEqual("-12");
|
||||
expect(schema.parse(3.14)).toEqual("3.14");
|
||||
expect(schema.parse(BigInt(15))).toEqual("15");
|
||||
expect(schema.parse(Number.NaN)).toEqual("NaN");
|
||||
expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual("Infinity");
|
||||
expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual("-Infinity");
|
||||
expect(schema.parse(true)).toEqual("true");
|
||||
expect(schema.parse(false)).toEqual("false");
|
||||
expect(schema.parse(null)).toEqual("null");
|
||||
expect(schema.parse(undefined)).toEqual("undefined");
|
||||
expect(schema.parse({ hello: "world!" })).toEqual("[object Object]");
|
||||
expect(schema.parse(["item", "another_item"])).toEqual("item,another_item");
|
||||
expect(schema.parse([])).toEqual("");
|
||||
expect(schema.parse(new Date("2022-01-01T00:00:00.000Z"))).toEqual(new Date("2022-01-01T00:00:00.000Z").toString());
|
||||
});
|
||||
|
||||
test("number coercion", () => {
|
||||
const schema = z.coerce.number();
|
||||
expect(schema.parse("12")).toEqual(12);
|
||||
expect(schema.parse("0")).toEqual(0);
|
||||
expect(schema.parse("-12")).toEqual(-12);
|
||||
expect(schema.parse("3.14")).toEqual(3.14);
|
||||
expect(schema.parse("")).toEqual(0);
|
||||
expect(() => schema.parse("NOT_A_NUMBER")).toThrow(); // z.ZodError
|
||||
expect(schema.parse(12)).toEqual(12);
|
||||
expect(schema.parse(0)).toEqual(0);
|
||||
expect(schema.parse(-12)).toEqual(-12);
|
||||
expect(schema.parse(3.14)).toEqual(3.14);
|
||||
expect(schema.parse(BigInt(15))).toEqual(15);
|
||||
expect(() => schema.parse(Number.NaN)).toThrow(); // z.ZodError
|
||||
// expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual(Number.POSITIVE_INFINITY);
|
||||
// expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual(Number.NEGATIVE_INFINITY);
|
||||
expect(schema.parse(true)).toEqual(1);
|
||||
expect(schema.parse(false)).toEqual(0);
|
||||
expect(schema.parse(null)).toEqual(0);
|
||||
expect(() => schema.parse(undefined)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse({ hello: "world!" })).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(["item", "another_item"])).toThrow(); // z.ZodError
|
||||
expect(schema.parse([])).toEqual(0);
|
||||
expect(schema.parse(new Date(1670139203496))).toEqual(1670139203496);
|
||||
});
|
||||
|
||||
test("boolean coercion", () => {
|
||||
const schema = z.coerce.boolean();
|
||||
expect(schema.parse("true")).toEqual(true);
|
||||
expect(schema.parse("false")).toEqual(true);
|
||||
expect(schema.parse("0")).toEqual(true);
|
||||
expect(schema.parse("1")).toEqual(true);
|
||||
expect(schema.parse("")).toEqual(false);
|
||||
expect(schema.parse(1)).toEqual(true);
|
||||
expect(schema.parse(0)).toEqual(false);
|
||||
expect(schema.parse(-1)).toEqual(true);
|
||||
expect(schema.parse(3.14)).toEqual(true);
|
||||
expect(schema.parse(BigInt(15))).toEqual(true);
|
||||
expect(schema.parse(Number.NaN)).toEqual(false);
|
||||
expect(schema.parse(Number.POSITIVE_INFINITY)).toEqual(true);
|
||||
expect(schema.parse(Number.NEGATIVE_INFINITY)).toEqual(true);
|
||||
expect(schema.parse(true)).toEqual(true);
|
||||
expect(schema.parse(false)).toEqual(false);
|
||||
expect(schema.parse(null)).toEqual(false);
|
||||
expect(schema.parse(undefined)).toEqual(false);
|
||||
expect(schema.parse({ hello: "world!" })).toEqual(true);
|
||||
expect(schema.parse(["item", "another_item"])).toEqual(true);
|
||||
expect(schema.parse([])).toEqual(true);
|
||||
expect(schema.parse(new Date(1670139203496))).toEqual(true);
|
||||
});
|
||||
|
||||
test("bigint coercion", () => {
|
||||
const schema = z.coerce.bigint();
|
||||
expect(schema.parse("5")).toEqual(BigInt(5));
|
||||
expect(schema.parse("0")).toEqual(BigInt(0));
|
||||
expect(schema.parse("-5")).toEqual(BigInt(-5));
|
||||
expect(() => schema.parse("3.14")).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse("")).toEqual(BigInt(0));
|
||||
expect(() => schema.parse("NOT_A_NUMBER")).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse(5)).toEqual(BigInt(5));
|
||||
expect(schema.parse(0)).toEqual(BigInt(0));
|
||||
expect(schema.parse(-5)).toEqual(BigInt(-5));
|
||||
expect(() => schema.parse(3.14)).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse(BigInt(5))).toEqual(BigInt(5));
|
||||
expect(() => schema.parse(Number.NaN)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(Number.POSITIVE_INFINITY)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(Number.NEGATIVE_INFINITY)).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse(true)).toEqual(BigInt(1));
|
||||
expect(schema.parse(false)).toEqual(BigInt(0));
|
||||
expect(() => schema.parse(null)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(undefined)).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse({ hello: "world!" })).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(["item", "another_item"])).toThrow(); // not a z.ZodError!
|
||||
expect(schema.parse([])).toEqual(BigInt(0));
|
||||
expect(schema.parse(new Date(1670139203496))).toEqual(BigInt(1670139203496));
|
||||
});
|
||||
|
||||
test("date coercion", () => {
|
||||
const schema = z.coerce.date();
|
||||
expect(schema.parse(new Date().toDateString())).toBeInstanceOf(Date);
|
||||
expect(schema.parse(new Date().toISOString())).toBeInstanceOf(Date);
|
||||
expect(schema.parse(new Date().toUTCString())).toBeInstanceOf(Date);
|
||||
expect(schema.parse("5")).toBeInstanceOf(Date);
|
||||
expect(schema.parse("2000-01-01")).toBeInstanceOf(Date);
|
||||
// expect(schema.parse("0")).toBeInstanceOf(Date);
|
||||
// expect(schema.parse("-5")).toBeInstanceOf(Date);
|
||||
// expect(schema.parse("3.14")).toBeInstanceOf(Date);
|
||||
expect(() => schema.parse("")).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse("NOT_A_DATE")).toThrow(); // z.ZodError
|
||||
expect(schema.parse(5)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(0)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(-5)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(3.14)).toBeInstanceOf(Date);
|
||||
expect(() => schema.parse(BigInt(5))).toThrow(); // not a z.ZodError!
|
||||
expect(() => schema.parse(Number.NaN)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(Number.POSITIVE_INFINITY)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(Number.NEGATIVE_INFINITY)).toThrow(); // z.ZodError
|
||||
expect(schema.parse(true)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(false)).toBeInstanceOf(Date);
|
||||
expect(schema.parse(null)).toBeInstanceOf(Date);
|
||||
expect(() => schema.parse(undefined)).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse({ hello: "world!" })).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse(["item", "another_item"])).toThrow(); // z.ZodError
|
||||
expect(() => schema.parse([])).toThrow(); // z.ZodError
|
||||
expect(schema.parse(new Date())).toBeInstanceOf(Date);
|
||||
});
|
||||
|
||||
// test("template literal coercion", () => {
|
||||
// const schema = z.coerce
|
||||
// .templateLiteral()
|
||||
// .interpolated(z.number().finite())
|
||||
// .interpolated(
|
||||
// z.enum(["px", "em", "rem", "vh", "vw", "vmin", "vmax"]).optional()
|
||||
// );
|
||||
// expect(schema.parse(300)).toEqual("300");
|
||||
// expect(schema.parse(BigInt(300))).toEqual("300");
|
||||
// expect(schema.parse("300")).toEqual("300");
|
||||
// expect(schema.parse("300px")).toEqual("300px");
|
||||
// expect(schema.parse("300em")).toEqual("300em");
|
||||
// expect(schema.parse("300rem")).toEqual("300rem");
|
||||
// expect(schema.parse("300vh")).toEqual("300vh");
|
||||
// expect(schema.parse("300vw")).toEqual("300vw");
|
||||
// expect(schema.parse("300vmin")).toEqual("300vmin");
|
||||
// expect(schema.parse("300vmax")).toEqual("300vmax");
|
||||
// expect(schema.parse(["300px"])).toEqual("300px");
|
||||
// });
|
||||
|
||||
test("override input type", () => {
|
||||
const a = z.coerce.string<any>();
|
||||
type input = z.input<typeof a>;
|
||||
expectTypeOf<input>().toEqualTypeOf<any>();
|
||||
type output = z.infer<typeof a>;
|
||||
expectTypeOf<output>().toEqualTypeOf<string>();
|
||||
});
|
||||
352
frontend/node_modules/zod/src/v4/classic/tests/continuability.test.ts
generated
vendored
Normal file
352
frontend/node_modules/zod/src/v4/classic/tests/continuability.test.ts
generated
vendored
Normal file
@ -0,0 +1,352 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("continuability", () => {
|
||||
/**
|
||||
* | $ZodGUID
|
||||
| $ZodUUID
|
||||
| $ZodEmail
|
||||
| $ZodURL
|
||||
| $ZodEmoji
|
||||
| $ZodNanoID
|
||||
| $ZodCUID
|
||||
| $ZodCUID2
|
||||
| $ZodULID
|
||||
| $ZodXID
|
||||
| $ZodKSUID
|
||||
| $ZodISODateTime
|
||||
| $ZodISODate
|
||||
| $ZodISOTime
|
||||
| $ZodISODuration
|
||||
| $ZodIPv4
|
||||
| $ZodIPv6
|
||||
| $ZodCIDRv4
|
||||
| $ZodCIDRv6
|
||||
| $ZodBase64
|
||||
| $ZodBase64URL
|
||||
| $ZodE164
|
||||
| $ZodJWT;
|
||||
*/
|
||||
expect(
|
||||
z
|
||||
.email()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "email",
|
||||
"message": "Invalid email address",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.uuid()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "uuid",
|
||||
"message": "Invalid UUID",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.url()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "url",
|
||||
"message": "Invalid URL",
|
||||
"path": [],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.jwt()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "jwt",
|
||||
"message": "Invalid JWT",
|
||||
"path": [],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.cidrv4()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "cidrv4",
|
||||
"message": "Invalid IPv4 range",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\/([0-9]|[1-2][0-9]|3[0-2])$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.cidrv6()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "cidrv6",
|
||||
"message": "Invalid IPv6 range",
|
||||
"path": [],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.ipv4()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "ipv4",
|
||||
"message": "Invalid IPv4 address",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.ipv6()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "ipv6",
|
||||
"message": "Invalid IPv6 address",
|
||||
"path": [],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.emoji()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "emoji",
|
||||
"message": "Invalid emoji",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$/u",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.nanoid()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "nanoid",
|
||||
"message": "Invalid nanoid",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^[a-zA-Z0-9_-]{21}$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.cuid()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "cuid",
|
||||
"message": "Invalid cuid",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^[cC][^\\s-]{8,}$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.cuid2()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "cuid2",
|
||||
"message": "Invalid cuid2",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^[0-9a-z]+$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.ulid()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "ulid",
|
||||
"message": "Invalid ULID",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.xid()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "xid",
|
||||
"message": "Invalid XID",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^[0-9a-vA-V]{20}$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
expect(
|
||||
z
|
||||
.ksuid()
|
||||
.refine(() => false)
|
||||
.safeParse("invalid_value").error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "ksuid",
|
||||
"message": "Invalid KSUID",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
"pattern": "/^[A-Za-z0-9]{27}$/",
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
40
frontend/node_modules/zod/src/v4/classic/tests/custom.test.ts
generated
vendored
Normal file
40
frontend/node_modules/zod/src/v4/classic/tests/custom.test.ts
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("passing validations", () => {
|
||||
const example1 = z.custom<number>((x) => typeof x === "number");
|
||||
example1.parse(1234);
|
||||
expect(() => example1.parse({})).toThrow();
|
||||
});
|
||||
|
||||
test("string params", () => {
|
||||
const example1 = z.custom<number>((x) => typeof x !== "number", "customerr");
|
||||
const result = example1.safeParse(1234);
|
||||
expect(result.success).toEqual(false);
|
||||
expect(JSON.stringify(result.error).includes("customerr")).toEqual(true);
|
||||
});
|
||||
|
||||
test("instanceof", () => {
|
||||
const fn = (value: string) => Uint8Array.from(Buffer.from(value, "base64"));
|
||||
|
||||
// Argument of type 'ZodCustom<Uint8Array<ArrayBuffer>, unknown>' is not assignable to parameter of type '$ZodType<any, Uint8Array<ArrayBuffer>>'.
|
||||
z.string().transform(fn).pipe(z.instanceof(Uint8Array));
|
||||
});
|
||||
|
||||
test("non-continuable by default", () => {
|
||||
const A = z
|
||||
.custom<string>((val) => typeof val === "string")
|
||||
.transform((_) => {
|
||||
throw new Error("Invalid input");
|
||||
});
|
||||
expect(A.safeParse(123).error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
31
frontend/node_modules/zod/src/v4/classic/tests/date.test.ts
generated
vendored
Normal file
31
frontend/node_modules/zod/src/v4/classic/tests/date.test.ts
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const beforeBenchmarkDate = new Date(2022, 10, 4);
|
||||
const benchmarkDate = new Date(2022, 10, 5);
|
||||
const afterBenchmarkDate = new Date(2022, 10, 6);
|
||||
|
||||
const minCheck = z.date().min(benchmarkDate);
|
||||
const maxCheck = z.date().max(benchmarkDate);
|
||||
|
||||
test("passing validations", () => {
|
||||
minCheck.parse(benchmarkDate);
|
||||
minCheck.parse(afterBenchmarkDate);
|
||||
|
||||
maxCheck.parse(benchmarkDate);
|
||||
maxCheck.parse(beforeBenchmarkDate);
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => minCheck.parse(beforeBenchmarkDate)).toThrow();
|
||||
expect(() => maxCheck.parse(afterBenchmarkDate)).toThrow();
|
||||
});
|
||||
|
||||
test("min max getters", () => {
|
||||
expect(minCheck.minDate).toEqual(benchmarkDate);
|
||||
expect(minCheck.min(afterBenchmarkDate).minDate).toEqual(afterBenchmarkDate);
|
||||
|
||||
expect(maxCheck.maxDate).toEqual(benchmarkDate);
|
||||
expect(maxCheck.max(beforeBenchmarkDate).maxDate).toEqual(beforeBenchmarkDate);
|
||||
});
|
||||
296
frontend/node_modules/zod/src/v4/classic/tests/datetime.test.ts
generated
vendored
Normal file
296
frontend/node_modules/zod/src/v4/classic/tests/datetime.test.ts
generated
vendored
Normal file
@ -0,0 +1,296 @@
|
||||
import { checkSync } from "recheck";
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("basic datetime parsing", () => {
|
||||
const datetime = z.string().datetime();
|
||||
datetime.parse("1970-01-01T00:00:00.000Z");
|
||||
datetime.parse("2022-10-13T09:52:31.816Z");
|
||||
datetime.parse("2022-10-13T09:52:31.8162314Z");
|
||||
datetime.parse("1970-01-01T00:00:00Z");
|
||||
datetime.parse("2022-10-13T09:52:31Z");
|
||||
expect(() => datetime.parse("")).toThrow();
|
||||
expect(() => datetime.parse("foo")).toThrow();
|
||||
expect(() => datetime.parse("2020-10-14")).toThrow();
|
||||
expect(() => datetime.parse("T18:45:12.123")).toThrow();
|
||||
expect(() => datetime.parse("2020-10-14T17:42:29+00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with precision -1", () => {
|
||||
const datetimeNoMs = z.string().datetime({ precision: -1, offset: true, local: true });
|
||||
datetimeNoMs.parse("1970-01-01T00:00Z");
|
||||
datetimeNoMs.parse("2022-10-13T09:52Z");
|
||||
datetimeNoMs.parse("2022-10-13T09:52+02:00");
|
||||
|
||||
datetimeNoMs.parse("2022-10-13T09:52");
|
||||
expect(() => datetimeNoMs.parse("tuna")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("2022-10-13T09:52+02")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with precision 0", () => {
|
||||
const datetimeNoMs = z.string().datetime({ precision: 0 });
|
||||
datetimeNoMs.parse("1970-01-01T00:00:00Z");
|
||||
datetimeNoMs.parse("2022-10-13T09:52:31Z");
|
||||
expect(() => datetimeNoMs.parse("tuna")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("1970-01-01T00:00:00.Z")).toThrow();
|
||||
expect(() => datetimeNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with precision 3", () => {
|
||||
const datetime3Ms = z.string().datetime({ precision: 3 });
|
||||
datetime3Ms.parse("1970-01-01T00:00:00.000Z");
|
||||
datetime3Ms.parse("2022-10-13T09:52:31.123Z");
|
||||
expect(() => datetime3Ms.parse("tuna")).toThrow();
|
||||
expect(() => datetime3Ms.parse("1970-01-01T00:00:00.1Z")).toThrow();
|
||||
expect(() => datetime3Ms.parse("1970-01-01T00:00:00.12Z")).toThrow();
|
||||
expect(() => datetime3Ms.parse("2022-10-13T09:52:31Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with offset", () => {
|
||||
const datetimeOffset = z.string().datetime({ offset: true });
|
||||
datetimeOffset.parse("1970-01-01T00:00:00.000Z");
|
||||
datetimeOffset.parse("2022-10-13T09:52:31.816234134Z");
|
||||
datetimeOffset.parse("1970-01-01T00:00:00Z");
|
||||
datetimeOffset.parse("2022-10-13T09:52:31.4Z");
|
||||
datetimeOffset.parse("2020-10-14T17:42:29+00:00");
|
||||
datetimeOffset.parse("2020-10-14T17:42:29+03:15");
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+0315")).toThrow();
|
||||
expect(() => datetimeOffset.parse("2020-10-14T17:42:29+03")).toThrow();
|
||||
expect(() => datetimeOffset.parse("tuna")).toThrow();
|
||||
expect(() => datetimeOffset.parse("2022-10-13T09:52:31.Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with offset and precision 0", () => {
|
||||
const datetimeOffsetNoMs = z.string().datetime({ offset: true, precision: 0 });
|
||||
datetimeOffsetNoMs.parse("1970-01-01T00:00:00Z");
|
||||
datetimeOffsetNoMs.parse("2022-10-13T09:52:31Z");
|
||||
datetimeOffsetNoMs.parse("2020-10-14T17:42:29+00:00");
|
||||
expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29+0000")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29+00")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("tuna")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("1970-01-01T00:00:00.000Z")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("1970-01-01T00:00:00.Z")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("2022-10-13T09:52:31.816Z")).toThrow();
|
||||
expect(() => datetimeOffsetNoMs.parse("2020-10-14T17:42:29.124+00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with offset and precision 4", () => {
|
||||
const datetimeOffset4Ms = z.string().datetime({ offset: true, precision: 4 });
|
||||
datetimeOffset4Ms.parse("1970-01-01T00:00:00.1234Z");
|
||||
datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+00:00");
|
||||
expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+0000")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.1234+00")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("tuna")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("1970-01-01T00:00:00.123Z")).toThrow();
|
||||
expect(() => datetimeOffset4Ms.parse("2020-10-14T17:42:29.124+00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime offset normalization", () => {
|
||||
const a = z.iso.datetime({ offset: true });
|
||||
|
||||
expect(a.safeParse("2020-10-14T17:42:29+02")).toMatchObject({ success: false });
|
||||
expect(a.safeParse("2020-10-14T17:42:29+0200")).toMatchObject({ success: false });
|
||||
a.safeParse("2020-10-14T17:42:29+02:00");
|
||||
});
|
||||
|
||||
test("datetime parsing with local option", () => {
|
||||
const a = z.string().datetime({ local: true });
|
||||
|
||||
expect(a.safeParse("1970-01-01T00:00")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("1970-01-01T00:00:00")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("2022-10-13T09:52:31.816")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("1970-01-01T00:00:00.000")).toMatchObject({ success: true });
|
||||
expect(a.safeParse("1970-01-01T00")).toMatchObject({ success: false });
|
||||
|
||||
// Should reject timezone indicators and invalid formats
|
||||
|
||||
expect(() => a.parse("2022-10-13T09:52:31+00:00")).toThrow();
|
||||
expect(() => a.parse("2022-10-13 09:52:31")).toThrow();
|
||||
expect(() => a.parse("2022-10-13T24:52:31")).toThrow();
|
||||
expect(() => a.parse("2022-10-13T24:52")).toThrow();
|
||||
expect(() => a.parse("2022-10-13T24:52Z")).toThrow();
|
||||
});
|
||||
|
||||
test("datetime parsing with local and offset", () => {
|
||||
const a = z.string().datetime({ local: true, offset: true });
|
||||
|
||||
// expect(a.parse("2022-10-13T12:52")).toEqual("2022-10-13T12:52:00");
|
||||
a.parse("2022-10-13T12:52:00");
|
||||
a.parse("2022-10-13T12:52:00Z");
|
||||
a.parse("2022-10-13T12:52Z");
|
||||
a.parse("2022-10-13T12:52");
|
||||
a.parse("2022-10-13T12:52+02:00");
|
||||
expect(() => a.parse("2022-10-13T12:52:00+02")).toThrow();
|
||||
// expect(() => a.parse("2022-10-13T12:52Z")).toThrow();
|
||||
// expect(() => a.parse("2022-10-13T12:52+02:00")).toThrow();
|
||||
});
|
||||
|
||||
test("date parsing", () => {
|
||||
const date = z.string().date();
|
||||
date.parse("1970-01-01");
|
||||
date.parse("2022-01-31");
|
||||
date.parse("2022-03-31");
|
||||
date.parse("2022-04-30");
|
||||
date.parse("2022-05-31");
|
||||
date.parse("2022-06-30");
|
||||
date.parse("2022-07-31");
|
||||
date.parse("2022-08-31");
|
||||
date.parse("2022-09-30");
|
||||
date.parse("2022-10-31");
|
||||
date.parse("2022-11-30");
|
||||
date.parse("2022-12-31");
|
||||
|
||||
date.parse("2000-02-29");
|
||||
date.parse("2400-02-29");
|
||||
expect(() => date.parse("2022-02-29")).toThrow();
|
||||
expect(() => date.parse("2100-02-29")).toThrow();
|
||||
expect(() => date.parse("2200-02-29")).toThrow();
|
||||
expect(() => date.parse("2300-02-29")).toThrow();
|
||||
expect(() => date.parse("2500-02-29")).toThrow();
|
||||
|
||||
expect(() => date.parse("")).toThrow();
|
||||
expect(() => date.parse("foo")).toThrow();
|
||||
expect(() => date.parse("200-01-01")).toThrow();
|
||||
expect(() => date.parse("20000-01-01")).toThrow();
|
||||
expect(() => date.parse("2000-0-01")).toThrow();
|
||||
expect(() => date.parse("2000-011-01")).toThrow();
|
||||
expect(() => date.parse("2000-01-0")).toThrow();
|
||||
expect(() => date.parse("2000-01-011")).toThrow();
|
||||
expect(() => date.parse("2000/01/01")).toThrow();
|
||||
expect(() => date.parse("01-01-2022")).toThrow();
|
||||
expect(() => date.parse("01/01/2022")).toThrow();
|
||||
expect(() => date.parse("2000-01-01 00:00:00Z")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29+00:00")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29Z")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29")).toThrow();
|
||||
expect(() => date.parse("2020-10-14T17:42:29.123Z")).toThrow();
|
||||
|
||||
expect(() => date.parse("2000-00-12")).toThrow();
|
||||
expect(() => date.parse("2000-12-00")).toThrow();
|
||||
expect(() => date.parse("2000-01-32")).toThrow();
|
||||
expect(() => date.parse("2000-13-01")).toThrow();
|
||||
expect(() => date.parse("2000-21-01")).toThrow();
|
||||
|
||||
expect(() => date.parse("2000-02-30")).toThrow();
|
||||
expect(() => date.parse("2000-02-31")).toThrow();
|
||||
expect(() => date.parse("2000-04-31")).toThrow();
|
||||
expect(() => date.parse("2000-06-31")).toThrow();
|
||||
expect(() => date.parse("2000-09-31")).toThrow();
|
||||
expect(() => date.parse("2000-11-31")).toThrow();
|
||||
});
|
||||
|
||||
test("time parsing", () => {
|
||||
const time = z.string().time();
|
||||
time.parse("00:00:00");
|
||||
time.parse("23:00:00");
|
||||
time.parse("00:59:00");
|
||||
time.parse("00:00:59");
|
||||
time.parse("23:59:59");
|
||||
time.parse("09:52:31");
|
||||
time.parse("23:59:59.9999999");
|
||||
time.parse("00:00");
|
||||
expect(() => time.parse("")).toThrow();
|
||||
expect(() => time.parse("foo")).toThrow();
|
||||
expect(() => time.parse("00:00:00Z")).toThrow();
|
||||
expect(() => time.parse("0:00:00")).toThrow();
|
||||
expect(() => time.parse("00:0:00")).toThrow();
|
||||
expect(() => time.parse("00:00:0")).toThrow();
|
||||
expect(() => time.parse("00:00:00.000+00:00")).toThrow();
|
||||
expect(() => time.parse("24:00:00")).toThrow();
|
||||
expect(() => time.parse("00:60:00")).toThrow();
|
||||
expect(() => time.parse("00:00:60")).toThrow();
|
||||
expect(() => time.parse("24:60:60")).toThrow();
|
||||
|
||||
const time2 = z.string().time({ precision: 2 });
|
||||
time2.parse("00:00:00.00");
|
||||
time2.parse("09:52:31.12");
|
||||
time2.parse("23:59:59.99");
|
||||
expect(() => time2.parse("")).toThrow();
|
||||
expect(() => time2.parse("foo")).toThrow();
|
||||
expect(() => time2.parse("00:00:00")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.00Z")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.0")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.000")).toThrow();
|
||||
expect(() => time2.parse("00:00:00.00+00:00")).toThrow();
|
||||
|
||||
const time3 = z.string().time({ precision: z.TimePrecision.Minute });
|
||||
time3.parse("00:00");
|
||||
expect(() => time3.parse("00:00:00")).toThrow();
|
||||
});
|
||||
|
||||
test("duration", () => {
|
||||
const duration = z.string().duration();
|
||||
|
||||
const validDurations = [
|
||||
"P3Y6M4DT12H30M5S",
|
||||
"P2Y9M3DT12H31M8.001S",
|
||||
// "+P3Y6M4DT12H30M5S",
|
||||
// "-PT0.001S",
|
||||
// "+PT0.001S",
|
||||
"PT0,001S",
|
||||
"PT12H30M5S",
|
||||
// "-P2M1D",
|
||||
// "P-2M-1D",
|
||||
// "-P5DT10H",
|
||||
// "P-5DT-10H",
|
||||
"P1Y",
|
||||
"P2MT30M",
|
||||
"PT6H",
|
||||
"P5W",
|
||||
// "P0.5Y",
|
||||
// "P0,5Y",
|
||||
// "P42YT7.004M",
|
||||
];
|
||||
|
||||
const invalidDurations = [
|
||||
"foo bar",
|
||||
"",
|
||||
" ",
|
||||
"P",
|
||||
"PT",
|
||||
"P1Y2MT",
|
||||
"T1H",
|
||||
"P0.5Y1D",
|
||||
"P0,5Y6M",
|
||||
"P1YT",
|
||||
"P-2M-1D",
|
||||
"P-5DT-10H",
|
||||
"P1W2D",
|
||||
"-P1D",
|
||||
];
|
||||
|
||||
for (const val of validDurations) {
|
||||
const result = duration.safeParse(val);
|
||||
if (!result.success) {
|
||||
throw Error(`Valid duration could not be parsed: ${val}`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const val of invalidDurations) {
|
||||
const result = duration.safeParse(val);
|
||||
|
||||
if (result.success) {
|
||||
throw Error(`Invalid duration was successful parsed: ${val}`);
|
||||
}
|
||||
|
||||
expect(result.error.issues[0].message).toEqual("Invalid ISO duration");
|
||||
}
|
||||
});
|
||||
|
||||
test("redos checker", () => {
|
||||
const a = z.iso.datetime();
|
||||
const b = z.string().datetime({ offset: true });
|
||||
const c = z.string().datetime({ local: true });
|
||||
const d = z.string().datetime({ local: true, offset: true, precision: 3 });
|
||||
const e = z.string().date();
|
||||
const f = z.string().time();
|
||||
const g = z.string().duration();
|
||||
for (const schema of [a, b, c, d, e, f, g]) {
|
||||
const result = checkSync(schema._zod.pattern.source, "");
|
||||
if (result.status !== "safe") throw Error("ReDoS issue");
|
||||
}
|
||||
});
|
||||
313
frontend/node_modules/zod/src/v4/classic/tests/default.test.ts
generated
vendored
Normal file
313
frontend/node_modules/zod/src/v4/classic/tests/default.test.ts
generated
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
test("basic defaults", () => {
|
||||
expect(z.string().default("default").parse(undefined)).toBe("default");
|
||||
});
|
||||
|
||||
test("default with optional", () => {
|
||||
const schema = z.string().optional().default("default");
|
||||
expect(schema.parse(undefined)).toBe("default");
|
||||
expect(schema.unwrap().parse(undefined)).toBe(undefined);
|
||||
});
|
||||
|
||||
test("default with transform", () => {
|
||||
const stringWithDefault = z
|
||||
.string()
|
||||
.transform((val) => val.toUpperCase())
|
||||
.default("default");
|
||||
expect(stringWithDefault.parse(undefined)).toBe("default");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodDefault);
|
||||
expect(stringWithDefault.unwrap()).toBeInstanceOf(z.ZodPipe);
|
||||
expect(stringWithDefault.unwrap().in).toBeInstanceOf(z.ZodString);
|
||||
expect(stringWithDefault.unwrap().out).toBeInstanceOf(z.ZodTransform);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | undefined>();
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("default on existing optional", () => {
|
||||
const stringWithDefault = z.string().optional().default("asdf");
|
||||
expect(stringWithDefault.parse(undefined)).toBe("asdf");
|
||||
expect(stringWithDefault).toBeInstanceOf(z.ZodDefault);
|
||||
expect(stringWithDefault.unwrap()).toBeInstanceOf(z.ZodOptional);
|
||||
expect(stringWithDefault.unwrap().unwrap()).toBeInstanceOf(z.ZodString);
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | undefined>();
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("optional on default", () => {
|
||||
const stringWithDefault = z.string().default("asdf").optional();
|
||||
|
||||
type inp = z.input<typeof stringWithDefault>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | undefined>();
|
||||
type out = z.output<typeof stringWithDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string | undefined>();
|
||||
|
||||
expect(stringWithDefault.parse(undefined)).toBe("asdf");
|
||||
});
|
||||
|
||||
// test("complex chain example", () => {
|
||||
// const complex = z
|
||||
// .string()
|
||||
// .default("asdf")
|
||||
// .transform((val) => val.toUpperCase())
|
||||
// .default("qwer")
|
||||
// .unwrap()
|
||||
// .optional()
|
||||
// .default("asdfasdf");
|
||||
|
||||
// expect(complex.parse(undefined)).toBe("asdfasdf");
|
||||
// });
|
||||
|
||||
test("removeDefault", () => {
|
||||
const stringWithRemovedDefault = z.string().default("asdf").removeDefault();
|
||||
|
||||
type out = z.output<typeof stringWithRemovedDefault>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("apply default at output", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.transform((_) => (Math.random() > 0 ? undefined : _))
|
||||
.default("asdf");
|
||||
expect(schema.parse("")).toEqual("asdf");
|
||||
});
|
||||
|
||||
test("nested", () => {
|
||||
const inner = z.string().default("asdf");
|
||||
const outer = z.object({ inner }).default({
|
||||
inner: "qwer",
|
||||
});
|
||||
type input = z.input<typeof outer>;
|
||||
expectTypeOf<input>().toEqualTypeOf<{ inner?: string | undefined } | undefined>();
|
||||
type out = z.output<typeof outer>;
|
||||
expectTypeOf<out>().toEqualTypeOf<{ inner: string }>();
|
||||
expect(outer.parse(undefined)).toEqual({ inner: "qwer" });
|
||||
expect(outer.parse({})).toEqual({ inner: "asdf" });
|
||||
expect(outer.parse({ inner: undefined })).toEqual({ inner: "asdf" });
|
||||
});
|
||||
|
||||
test("chained defaults", () => {
|
||||
const stringWithDefault = z.string().default("inner").default("outer");
|
||||
const result = stringWithDefault.parse(undefined);
|
||||
expect(result).toEqual("outer");
|
||||
});
|
||||
|
||||
test("object optionality", () => {
|
||||
const schema = z.object({
|
||||
hi: z.string().default("hi"),
|
||||
});
|
||||
type schemaInput = z.input<typeof schema>;
|
||||
type schemaOutput = z.output<typeof schema>;
|
||||
expectTypeOf<schemaInput>().toEqualTypeOf<{ hi?: string | undefined }>();
|
||||
expectTypeOf<schemaOutput>().toEqualTypeOf<{ hi: string }>();
|
||||
expect(schema.parse({})).toEqual({
|
||||
hi: "hi",
|
||||
});
|
||||
});
|
||||
|
||||
test("nested prefault/default", () => {
|
||||
const a = z
|
||||
.string()
|
||||
.default("a")
|
||||
.refine((val) => val.startsWith("a"));
|
||||
const b = z
|
||||
.string()
|
||||
.refine((val) => val.startsWith("b"))
|
||||
.default("b");
|
||||
const c = z
|
||||
.string()
|
||||
.prefault("c")
|
||||
.refine((val) => val.startsWith("c"));
|
||||
const d = z
|
||||
.string()
|
||||
.refine((val) => val.startsWith("d"))
|
||||
.prefault("d");
|
||||
|
||||
const obj = z.object({
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
});
|
||||
|
||||
expect(obj.safeParse({ a: "a1", b: "b1", c: "c1", d: "d1" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": {
|
||||
"a": "a1",
|
||||
"b": "b1",
|
||||
"c": "c1",
|
||||
"d": "d1",
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(obj.safeParse({ a: "f", b: "f", c: "f", d: "f" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"a"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"b"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"c"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"d"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(obj.safeParse({})).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": {
|
||||
"a": "a",
|
||||
"b": "b",
|
||||
"c": "c",
|
||||
"d": "d",
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(obj.safeParse({ a: undefined, b: undefined, c: undefined, d: undefined })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": {
|
||||
"a": "a",
|
||||
"b": "b",
|
||||
"c": "c",
|
||||
"d": "d",
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`);
|
||||
|
||||
const obj2 = z.object({
|
||||
a: a.optional(),
|
||||
b: b.optional(),
|
||||
c: c.optional(),
|
||||
d: d.optional(),
|
||||
});
|
||||
expect(obj2.safeParse({ a: undefined, b: undefined, c: undefined, d: undefined })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": {
|
||||
"a": "a",
|
||||
"b": "b",
|
||||
"c": "c",
|
||||
"d": "d",
|
||||
},
|
||||
"success": true,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(a.parse(undefined)).toBe("a");
|
||||
expect(b.parse(undefined)).toBe("b");
|
||||
expect(c.parse(undefined)).toBe("c");
|
||||
expect(d.parse(undefined)).toBe("d");
|
||||
});
|
||||
|
||||
test("failing default", () => {
|
||||
const a = z
|
||||
.string()
|
||||
.default("z")
|
||||
.refine((val) => val.startsWith("a"));
|
||||
const b = z
|
||||
.string()
|
||||
.refine((val) => val.startsWith("b"))
|
||||
.default("z");
|
||||
const c = z
|
||||
.string()
|
||||
.prefault("z")
|
||||
.refine((val) => val.startsWith("c"));
|
||||
const d = z
|
||||
.string()
|
||||
.refine((val) => val.startsWith("d"))
|
||||
.prefault("z");
|
||||
|
||||
const obj = z.object({
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
});
|
||||
|
||||
expect(
|
||||
obj.safeParse({
|
||||
a: undefined,
|
||||
b: undefined,
|
||||
c: undefined,
|
||||
d: undefined,
|
||||
}).error!.issues
|
||||
).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [
|
||||
"a",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [
|
||||
"c",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [
|
||||
"d",
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
test("partial should not clobber defaults", () => {
|
||||
const objWithDefaults = z.object({
|
||||
a: z.string().default("defaultA"),
|
||||
b: z.string().default("defaultB"),
|
||||
c: z.string().default("defaultC"),
|
||||
});
|
||||
|
||||
const objPartialWithOneRequired = objWithDefaults.partial(); //.required({ a: true });
|
||||
|
||||
const test = objPartialWithOneRequired.parse({});
|
||||
expect(test).toMatchInlineSnapshot(`
|
||||
{
|
||||
"a": "defaultA",
|
||||
"b": "defaultB",
|
||||
"c": "defaultC",
|
||||
}
|
||||
`);
|
||||
});
|
||||
32
frontend/node_modules/zod/src/v4/classic/tests/description.test.ts
generated
vendored
Normal file
32
frontend/node_modules/zod/src/v4/classic/tests/description.test.ts
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const description = "a description";
|
||||
|
||||
// test("passing `description` to schema should add a description", () => {
|
||||
// expect(z.string({ description }).description).toEqual(description);
|
||||
// expect(z.number({ description }).description).toEqual(description);
|
||||
// expect(z.boolean({ description }).description).toEqual(description);
|
||||
// });
|
||||
|
||||
test(".describe", () => {
|
||||
expect(z.string().describe(description).description).toEqual(description);
|
||||
expect(z.number().describe(description).description).toEqual(description);
|
||||
expect(z.boolean().describe(description).description).toEqual(description);
|
||||
});
|
||||
|
||||
test("adding description with z.globalRegistry", () => {
|
||||
const schema = z.string();
|
||||
z.core.globalRegistry.add(schema, { description });
|
||||
z.core.globalRegistry.get(schema);
|
||||
expect(schema.description).toEqual(description);
|
||||
});
|
||||
|
||||
// in Zod 4 descriptions are not inherited
|
||||
// test("description should carry over to chained schemas", () => {
|
||||
// const schema = z.string().describe(description);
|
||||
// expect(schema.description).toEqual(description);
|
||||
// expect(schema.optional().description).toEqual(description);
|
||||
// expect(schema.optional().nullable().default("default").description).toEqual(description);
|
||||
// });
|
||||
619
frontend/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts
generated
vendored
Normal file
619
frontend/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts
generated
vendored
Normal file
@ -0,0 +1,619 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("_values", () => {
|
||||
expect(z.string()._zod.values).toEqual(undefined);
|
||||
expect(z.enum(["a", "b"])._zod.values).toEqual(new Set(["a", "b"]));
|
||||
expect(z.nativeEnum({ a: "A", b: "B" })._zod.values).toEqual(new Set(["A", "B"]));
|
||||
expect(z.literal("test")._zod.values).toEqual(new Set(["test"]));
|
||||
expect(z.literal(123)._zod.values).toEqual(new Set([123]));
|
||||
expect(z.literal(true)._zod.values).toEqual(new Set([true]));
|
||||
expect(z.literal(BigInt(123))._zod.values).toEqual(new Set([BigInt(123)]));
|
||||
expect(z.undefined()._zod.values).toEqual(new Set([undefined]));
|
||||
expect(z.null()._zod.values).toEqual(new Set([null]));
|
||||
|
||||
const t = z.literal("test");
|
||||
expect(t.optional()._zod.values).toEqual(new Set(["test", undefined]));
|
||||
expect(t.nullable()._zod.values).toEqual(new Set(["test", null]));
|
||||
expect(t.default("test")._zod.values).toEqual(new Set(["test"]));
|
||||
expect(t.catch("test")._zod.values).toEqual(new Set(["test"]));
|
||||
|
||||
const pre = z.preprocess((val) => String(val), z.string()).pipe(z.literal("test"));
|
||||
expect(pre._zod.values).toEqual(undefined);
|
||||
|
||||
const post = z.literal("test").transform((_) => Math.random());
|
||||
expect(post._zod.values).toEqual(new Set(["test"]));
|
||||
|
||||
// Test that readonly literals pass through their values property
|
||||
expect(z.literal("test").readonly()._zod.values).toEqual(new Set(["test"]));
|
||||
});
|
||||
|
||||
test("valid parse - object", () => {
|
||||
expect(
|
||||
z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
])
|
||||
.parse({ type: "a", a: "abc" })
|
||||
).toEqual({ type: "a", a: "abc" });
|
||||
});
|
||||
|
||||
test("valid - include discriminator key (deprecated)", () => {
|
||||
expect(
|
||||
z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
])
|
||||
.parse({ type: "a", a: "abc" })
|
||||
).toEqual({ type: "a", a: "abc" });
|
||||
});
|
||||
|
||||
test("valid - optional discriminator (object)", () => {
|
||||
const schema = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a").optional(), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
]);
|
||||
expect(schema.parse({ type: "a", a: "abc" })).toEqual({ type: "a", a: "abc" });
|
||||
expect(schema.parse({ a: "abc" })).toEqual({ a: "abc" });
|
||||
});
|
||||
|
||||
test("valid - discriminator value of various primitive types", () => {
|
||||
const schema = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("1"), val: z.string() }),
|
||||
z.object({ type: z.literal(1), val: z.string() }),
|
||||
z.object({ type: z.literal(BigInt(1)), val: z.string() }),
|
||||
z.object({ type: z.literal("true"), val: z.string() }),
|
||||
z.object({ type: z.literal(true), val: z.string() }),
|
||||
z.object({ type: z.literal("null"), val: z.string() }),
|
||||
z.object({ type: z.null(), val: z.string() }),
|
||||
z.object({ type: z.literal("undefined"), val: z.string() }),
|
||||
z.object({ type: z.undefined(), val: z.string() }),
|
||||
]);
|
||||
|
||||
expect(schema.parse({ type: "1", val: "val" })).toEqual({ type: "1", val: "val" });
|
||||
expect(schema.parse({ type: 1, val: "val" })).toEqual({ type: 1, val: "val" });
|
||||
expect(schema.parse({ type: BigInt(1), val: "val" })).toEqual({
|
||||
type: BigInt(1),
|
||||
val: "val",
|
||||
});
|
||||
expect(schema.parse({ type: "true", val: "val" })).toEqual({
|
||||
type: "true",
|
||||
val: "val",
|
||||
});
|
||||
expect(schema.parse({ type: true, val: "val" })).toEqual({
|
||||
type: true,
|
||||
val: "val",
|
||||
});
|
||||
expect(schema.parse({ type: "null", val: "val" })).toEqual({
|
||||
type: "null",
|
||||
val: "val",
|
||||
});
|
||||
expect(schema.parse({ type: null, val: "val" })).toEqual({
|
||||
type: null,
|
||||
val: "val",
|
||||
});
|
||||
expect(schema.parse({ type: "undefined", val: "val" })).toEqual({
|
||||
type: "undefined",
|
||||
val: "val",
|
||||
});
|
||||
expect(schema.parse({ type: undefined, val: "val" })).toEqual({
|
||||
type: undefined,
|
||||
val: "val",
|
||||
});
|
||||
|
||||
const fail = schema.safeParse({
|
||||
type: "not_a_key",
|
||||
val: "val",
|
||||
});
|
||||
expect(fail.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
test("invalid - null", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
]).parse(null);
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
// [
|
||||
// {
|
||||
// code: z.ZodIssueCode.invalid_type,
|
||||
// expected: z.ZodParsedType.object,
|
||||
// input: null,
|
||||
// message: "Expected object, received null",
|
||||
// received: z.ZodParsedType.null,
|
||||
// path: [],
|
||||
// },
|
||||
// ];
|
||||
expect(e.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "object",
|
||||
"message": "Invalid input: expected object, received null",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("invalid discriminator value", () => {
|
||||
const result = z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
])
|
||||
.safeParse({ type: "x", a: "abc" });
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_union",
|
||||
"errors": [],
|
||||
"note": "No matching discriminator",
|
||||
"path": [
|
||||
"type"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("invalid discriminator value - unionFallback", () => {
|
||||
const result = z
|
||||
.discriminatedUnion(
|
||||
"type",
|
||||
[z.object({ type: z.literal("a"), a: z.string() }), z.object({ type: z.literal("b"), b: z.string() })],
|
||||
{ unionFallback: true }
|
||||
)
|
||||
.safeParse({ type: "x", a: "abc" });
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_union",
|
||||
"errors": [
|
||||
[
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"a"
|
||||
],
|
||||
"path": [
|
||||
"type"
|
||||
],
|
||||
"message": "Invalid input: expected \\"a\\""
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"b"
|
||||
],
|
||||
"path": [
|
||||
"type"
|
||||
],
|
||||
"message": "Invalid input: expected \\"b\\""
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"b"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("valid discriminator value, invalid data", () => {
|
||||
const result = z
|
||||
.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.string() }),
|
||||
])
|
||||
.safeParse({ type: "a", b: "abc" });
|
||||
|
||||
// [
|
||||
// {
|
||||
// code: z.ZodIssueCode.invalid_type,
|
||||
// expected: z.ZodParsedType.string,
|
||||
// message: "Required",
|
||||
// path: ["a"],
|
||||
// received: z.ZodParsedType.undefined,
|
||||
// },
|
||||
// ];
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"a"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("wrong schema - missing discriminator", () => {
|
||||
try {
|
||||
z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a"), a: z.string() }),
|
||||
z.object({ b: z.string() }) as any,
|
||||
])._zod.propValues;
|
||||
throw new Error();
|
||||
} catch (e: any) {
|
||||
expect(e.message.includes("Invalid discriminated union option")).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
// removed to account for unions of unions
|
||||
// test("wrong schema - duplicate discriminator values", () => {
|
||||
// try {
|
||||
// z.discriminatedUnion("type",[
|
||||
// z.object({ type: z.literal("a"), a: z.string() }),
|
||||
// z.object({ type: z.literal("a"), b: z.string() }),
|
||||
// ]);
|
||||
// throw new Error();
|
||||
// } catch (e: any) {
|
||||
// expect(e.message.includes("Duplicate discriminator value")).toEqual(true);
|
||||
// }
|
||||
// });
|
||||
|
||||
test("async - valid", async () => {
|
||||
const schema = await z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("a"),
|
||||
a: z
|
||||
.string()
|
||||
.refine(async () => true)
|
||||
.transform(async (val) => Number(val)),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("b"),
|
||||
b: z.string(),
|
||||
}),
|
||||
]);
|
||||
const data = { type: "a", a: "1" };
|
||||
const result = await schema.safeParseAsync(data);
|
||||
expect(result.data).toEqual({ type: "a", a: 1 });
|
||||
});
|
||||
|
||||
test("async - invalid", async () => {
|
||||
// try {
|
||||
const a = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("a"),
|
||||
a: z
|
||||
.string()
|
||||
.refine(async () => true)
|
||||
.transform(async (val) => val),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("b"),
|
||||
b: z.string(),
|
||||
}),
|
||||
]);
|
||||
const result = await a.safeParseAsync({ type: "a", a: 1 });
|
||||
|
||||
// expect(JSON.parse(e.message)).toEqual([
|
||||
// {
|
||||
// code: "invalid_type",
|
||||
// expected: "string",
|
||||
// input: 1,
|
||||
// received: "number",
|
||||
// path: ["a"],
|
||||
// message: "Expected string, received number",
|
||||
// },
|
||||
// ]);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"a"
|
||||
],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("valid - literals with .default or .pipe", () => {
|
||||
const schema = z.discriminatedUnion("type", [
|
||||
z.object({
|
||||
type: z.literal("foo").default("foo"),
|
||||
a: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("custom"),
|
||||
method: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal("bar").transform((val) => val),
|
||||
c: z.string(),
|
||||
}),
|
||||
]);
|
||||
expect(schema.parse({ type: "foo", a: "foo" })).toEqual({
|
||||
type: "foo",
|
||||
a: "foo",
|
||||
});
|
||||
});
|
||||
|
||||
test("enum and nativeEnum", () => {
|
||||
enum MyEnum {
|
||||
d = 0,
|
||||
e = "e",
|
||||
}
|
||||
|
||||
const schema = z.discriminatedUnion("key", [
|
||||
z.object({
|
||||
key: z.literal("a"),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
z.object({
|
||||
key: z.enum(["b", "c"]),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
z.object({
|
||||
key: z.nativeEnum(MyEnum),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
]);
|
||||
|
||||
type schema = z.infer<typeof schema>;
|
||||
expectTypeOf<schema>().toEqualTypeOf<{ key: "a" } | { key: "b" | "c" } | { key: MyEnum.d | MyEnum.e }>();
|
||||
|
||||
schema.parse({ key: "a" });
|
||||
schema.parse({ key: "b" });
|
||||
schema.parse({ key: "c" });
|
||||
schema.parse({ key: MyEnum.d });
|
||||
schema.parse({ key: MyEnum.e });
|
||||
schema.parse({ key: "e" });
|
||||
});
|
||||
|
||||
test("branded", () => {
|
||||
const schema = z.discriminatedUnion("key", [
|
||||
z.object({
|
||||
key: z.literal("a"),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
z.object({
|
||||
key: z.literal("b").brand<"asdfasdf">(),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
]);
|
||||
|
||||
type schema = z.infer<typeof schema>;
|
||||
expectTypeOf<schema>().toEqualTypeOf<{ key: "a" } | { key: "b" & z.core.$brand<"asdfasdf"> }>();
|
||||
|
||||
schema.parse({ key: "a" });
|
||||
schema.parse({ key: "b" });
|
||||
expect(() => {
|
||||
schema.parse({ key: "c" });
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test("optional and nullable", () => {
|
||||
const schema = z.discriminatedUnion("key", [
|
||||
z.object({
|
||||
key: z.literal("a").optional(),
|
||||
a: z.literal(true),
|
||||
}),
|
||||
z.object({
|
||||
key: z.literal("b").nullable(),
|
||||
b: z.literal(true),
|
||||
// Add other properties specific to this option
|
||||
}),
|
||||
]);
|
||||
|
||||
type schema = z.infer<typeof schema>;
|
||||
expectTypeOf<schema>().toEqualTypeOf<{ key?: "a" | undefined; a: true } | { key: "b" | null; b: true }>();
|
||||
|
||||
schema.parse({ key: "a", a: true });
|
||||
schema.parse({ key: undefined, a: true });
|
||||
schema.parse({ key: "b", b: true });
|
||||
schema.parse({ key: null, b: true });
|
||||
expect(() => {
|
||||
schema.parse({ key: null, a: true });
|
||||
}).toThrow();
|
||||
expect(() => {
|
||||
schema.parse({ key: "b", a: true });
|
||||
}).toThrow();
|
||||
|
||||
const value = schema.parse({ key: null, b: true });
|
||||
|
||||
if (!("key" in value)) value.a;
|
||||
if (value.key === undefined) value.a;
|
||||
if (value.key === "a") value.a;
|
||||
if (value.key === "b") value.b;
|
||||
if (value.key === null) value.b;
|
||||
});
|
||||
|
||||
test("multiple discriminators", () => {
|
||||
const FreeConfig = z.object({
|
||||
type: z.literal("free"),
|
||||
min_cents: z.null(),
|
||||
});
|
||||
|
||||
// console.log(FreeConfig.shape.type);
|
||||
const PricedConfig = z.object({
|
||||
type: z.literal("fiat-price"),
|
||||
// min_cents: z.int().nullable(),
|
||||
min_cents: z.null(),
|
||||
});
|
||||
|
||||
const Config = z.discriminatedUnion("type", [FreeConfig, PricedConfig]);
|
||||
|
||||
Config.parse({
|
||||
min_cents: null,
|
||||
type: "fiat-price",
|
||||
name: "Standard",
|
||||
});
|
||||
|
||||
expect(() => {
|
||||
Config.parse({
|
||||
min_cents: null,
|
||||
type: "not real",
|
||||
name: "Standard",
|
||||
});
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test("single element union", () => {
|
||||
const schema = z.object({
|
||||
a: z.literal("discKey"),
|
||||
b: z.enum(["apple", "banana"]),
|
||||
c: z.object({ id: z.string() }),
|
||||
});
|
||||
|
||||
const input = {
|
||||
a: "discKey",
|
||||
b: "apple",
|
||||
c: {}, // Invalid, as schema requires `id` property
|
||||
};
|
||||
|
||||
// Validation must fail here, but it doesn't
|
||||
|
||||
const u = z.discriminatedUnion("a", [schema]);
|
||||
const result = u.safeParse(input);
|
||||
expect(result).toMatchObject({ success: false });
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"c",
|
||||
"id"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(u.options.length).toEqual(1);
|
||||
});
|
||||
|
||||
test("nested discriminated unions", () => {
|
||||
const BaseError = z.object({ status: z.literal("failed"), message: z.string() });
|
||||
const MyErrors = z.discriminatedUnion("code", [
|
||||
BaseError.extend({ code: z.literal(400) }),
|
||||
BaseError.extend({ code: z.literal(401) }),
|
||||
BaseError.extend({ code: z.literal(500) }),
|
||||
]);
|
||||
|
||||
const MyResult = z.discriminatedUnion("status", [
|
||||
z.object({ status: z.literal("success"), data: z.string() }),
|
||||
MyErrors,
|
||||
]);
|
||||
|
||||
expect(MyErrors._zod.propValues).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": Set {
|
||||
400,
|
||||
401,
|
||||
500,
|
||||
},
|
||||
"status": Set {
|
||||
"failed",
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(MyResult._zod.propValues).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": Set {
|
||||
400,
|
||||
401,
|
||||
500,
|
||||
},
|
||||
"status": Set {
|
||||
"success",
|
||||
"failed",
|
||||
},
|
||||
}
|
||||
`);
|
||||
|
||||
const result = MyResult.parse({ status: "success", data: "hello" });
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": "hello",
|
||||
"status": "success",
|
||||
}
|
||||
`);
|
||||
const result2 = MyResult.parse({ status: "failed", code: 400, message: "bad request" });
|
||||
expect(result2).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": 400,
|
||||
"message": "bad request",
|
||||
"status": "failed",
|
||||
}
|
||||
`);
|
||||
const result3 = MyResult.parse({ status: "failed", code: 401, message: "unauthorized" });
|
||||
expect(result3).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": 401,
|
||||
"message": "unauthorized",
|
||||
"status": "failed",
|
||||
}
|
||||
`);
|
||||
const result4 = MyResult.parse({ status: "failed", code: 500, message: "internal server error" });
|
||||
expect(result4).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": 500,
|
||||
"message": "internal server error",
|
||||
"status": "failed",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("readonly literal discriminator", () => {
|
||||
const discUnion = z.discriminatedUnion("type", [
|
||||
z.object({ type: z.literal("a").readonly(), a: z.string() }),
|
||||
z.object({ type: z.literal("b"), b: z.number() }),
|
||||
]);
|
||||
|
||||
// Test that both discriminator values are correctly included in propValues
|
||||
const propValues = discUnion._zod.propValues;
|
||||
expect(propValues?.type?.has("a")).toBe(true);
|
||||
expect(propValues?.type?.has("b")).toBe(true);
|
||||
|
||||
// Test that the discriminated union works correctly
|
||||
const result1 = discUnion.parse({ type: "a", a: "hello" });
|
||||
expect(result1).toEqual({ type: "a", a: "hello" });
|
||||
|
||||
const result2 = discUnion.parse({ type: "b", b: 42 });
|
||||
expect(result2).toEqual({ type: "b", b: 42 });
|
||||
|
||||
// Test that invalid discriminator values are rejected
|
||||
expect(() => {
|
||||
discUnion.parse({ type: "c", a: "hello" });
|
||||
}).toThrow();
|
||||
});
|
||||
285
frontend/node_modules/zod/src/v4/classic/tests/enum.test.ts
generated
vendored
Normal file
285
frontend/node_modules/zod/src/v4/classic/tests/enum.test.ts
generated
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("enum from string array", () => {
|
||||
const MyEnum = z.enum(["Red", "Green", "Blue"]);
|
||||
expect(MyEnum.enum.Red).toEqual("Red");
|
||||
|
||||
type MyEnum = z.infer<typeof MyEnum>;
|
||||
expectTypeOf<MyEnum>().toEqualTypeOf<"Red" | "Green" | "Blue">();
|
||||
});
|
||||
|
||||
test("enum from const object", () => {
|
||||
const Fruits: { Apple: "apple"; Banana: "banana" } = {
|
||||
Apple: "apple",
|
||||
Banana: "banana",
|
||||
};
|
||||
const fruitEnum = z.nativeEnum(Fruits);
|
||||
type fruitEnum = z.infer<typeof fruitEnum>;
|
||||
fruitEnum.parse("apple");
|
||||
fruitEnum.parse("banana");
|
||||
fruitEnum.parse(Fruits.Apple);
|
||||
fruitEnum.parse(Fruits.Banana);
|
||||
expectTypeOf<fruitEnum>().toEqualTypeOf<"apple" | "banana">();
|
||||
});
|
||||
|
||||
test("enum from native enum", () => {
|
||||
enum Fruits {
|
||||
Apple = "apple",
|
||||
Banana = "banana",
|
||||
Orange = 3,
|
||||
}
|
||||
// @ts-ignore
|
||||
const fruitEnum = z.nativeEnum(Fruits);
|
||||
type fruitEnum = z.infer<typeof fruitEnum>;
|
||||
fruitEnum.parse("apple");
|
||||
fruitEnum.parse("banana");
|
||||
fruitEnum.parse(Fruits.Apple);
|
||||
fruitEnum.parse(Fruits.Banana);
|
||||
|
||||
expect(fruitEnum.safeParse("Apple").success).toEqual(false);
|
||||
expect(fruitEnum.safeParse("Cantaloupe").success).toEqual(false);
|
||||
|
||||
expectTypeOf<fruitEnum>().toMatchTypeOf<Fruits>();
|
||||
expectTypeOf<Fruits>().toMatchTypeOf<fruitEnum>();
|
||||
});
|
||||
|
||||
test("enum from native enum with numeric keys", () => {
|
||||
const FruitValues = {
|
||||
Apple: 10,
|
||||
Banana: 20,
|
||||
// @ts-ignore
|
||||
} as const;
|
||||
const fruitEnum = z.nativeEnum(FruitValues);
|
||||
type fruitEnum = z.infer<typeof fruitEnum>;
|
||||
fruitEnum.parse(10);
|
||||
fruitEnum.parse(20);
|
||||
fruitEnum.parse(FruitValues.Apple);
|
||||
fruitEnum.parse(FruitValues.Banana);
|
||||
expectTypeOf<fruitEnum>().toEqualTypeOf<10 | 20>();
|
||||
});
|
||||
|
||||
test("issue metadata", () => {
|
||||
const schema = z.enum(["Red", "Green", "Blue"]);
|
||||
const result = schema.safeParse("Yellow");
|
||||
expect(result.error!.issues[0]).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"message": "Invalid option: expected one of "Red"|"Green"|"Blue"",
|
||||
"path": [],
|
||||
"values": [
|
||||
"Red",
|
||||
"Green",
|
||||
"Blue",
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("enum from non-const inputs", () => {
|
||||
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"];
|
||||
const FoodEnum = z.enum(foods);
|
||||
|
||||
expectTypeOf<z.infer<typeof FoodEnum>>().toEqualTypeOf<string>();
|
||||
expect(FoodEnum.safeParse("Pasta").success).toEqual(true);
|
||||
expect(FoodEnum.safeParse("Cucumbers").success).toEqual(false);
|
||||
});
|
||||
|
||||
test("get options", () => {
|
||||
expect(z.enum(["tuna", "trout"]).options).toEqual(["tuna", "trout"]);
|
||||
});
|
||||
|
||||
test("readonly enum", () => {
|
||||
const HTTP_SUCCESS = ["200", "201"] as const;
|
||||
const arg = z.enum(HTTP_SUCCESS);
|
||||
type arg = z.infer<typeof arg>;
|
||||
expectTypeOf<arg>().toEqualTypeOf<"200" | "201">();
|
||||
|
||||
arg.parse("201");
|
||||
expect(() => arg.parse("202")).toThrow();
|
||||
});
|
||||
|
||||
test("error map", () => {
|
||||
const result = z
|
||||
.enum(["test"], { error: (iss) => (iss.input === undefined ? "REQUIRED" : undefined) })
|
||||
.safeParse(undefined);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].message).toEqual("REQUIRED");
|
||||
}
|
||||
});
|
||||
|
||||
test("type signatures", () => {
|
||||
const a = z.enum(["a", "b", "c"]);
|
||||
const b = z.enum(a.options);
|
||||
expectTypeOf(a).toEqualTypeOf(b);
|
||||
|
||||
const c = z.enum({ a: 1, b: 2 } as const);
|
||||
expectTypeOf(c.enum).toEqualTypeOf<{
|
||||
readonly a: 1;
|
||||
readonly b: 2;
|
||||
}>();
|
||||
|
||||
enum Fruit {
|
||||
Apple = "apple",
|
||||
Banana = "banana",
|
||||
Orange = "orange",
|
||||
}
|
||||
const d = z.enum(Fruit);
|
||||
expectTypeOf(d.enum).toEqualTypeOf(Fruit);
|
||||
|
||||
const e = z.enum({ a: 1, b: 2 });
|
||||
expectTypeOf(e.enum).toEqualTypeOf<{
|
||||
readonly a: 1;
|
||||
readonly b: 2;
|
||||
}>();
|
||||
});
|
||||
|
||||
test("extract", () => {
|
||||
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const;
|
||||
const FoodEnum = z.enum(foods);
|
||||
const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]);
|
||||
|
||||
expect(ItalianEnum.safeParse("Pasta").success).toEqual(true);
|
||||
expect(ItalianEnum.safeParse("Tacos").success).toEqual(false);
|
||||
|
||||
expectTypeOf<z.infer<typeof ItalianEnum>>().toEqualTypeOf<"Pasta" | "Pizza">();
|
||||
});
|
||||
|
||||
test("exclude", () => {
|
||||
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const;
|
||||
const FoodEnum = z.enum(foods);
|
||||
const UnhealthyEnum = FoodEnum.exclude(["Salad"]);
|
||||
|
||||
expect(UnhealthyEnum.safeParse("Pasta").success).toEqual(true);
|
||||
expect(UnhealthyEnum.safeParse("Salad").success).toEqual(false);
|
||||
expectTypeOf<z.infer<typeof UnhealthyEnum>>().toEqualTypeOf<"Pasta" | "Pizza" | "Tacos" | "Burgers">();
|
||||
|
||||
const EmptyFoodEnum = FoodEnum.exclude(foods);
|
||||
expectTypeOf<typeof EmptyFoodEnum>().toEqualTypeOf<z.ZodEnum<{}>>();
|
||||
expectTypeOf<z.infer<typeof EmptyFoodEnum>>().toEqualTypeOf<never>();
|
||||
});
|
||||
|
||||
test("error map inheritance", () => {
|
||||
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"] as const;
|
||||
const FoodEnum = z.enum(foods, { error: () => "This is not food!" });
|
||||
const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]);
|
||||
|
||||
const foodsError = FoodEnum.safeParse("Cucumbers");
|
||||
const italianError = ItalianEnum.safeParse("Tacos");
|
||||
|
||||
expect(foodsError.error!.issues[0].message).toEqual(italianError.error!.issues[0].message);
|
||||
|
||||
const UnhealthyEnum = FoodEnum.exclude(["Salad"], {
|
||||
error: () => ({ message: "This is not healthy food!" }),
|
||||
});
|
||||
const unhealthyError = UnhealthyEnum.safeParse("Salad");
|
||||
if (!unhealthyError.success) {
|
||||
expect(unhealthyError.error.issues[0].message).toEqual("This is not healthy food!");
|
||||
}
|
||||
});
|
||||
|
||||
test("readonly in ZodEnumDef", () => {
|
||||
type _a = z.ZodEnum<{ readonly a: "a"; readonly b: "b" }>;
|
||||
type _b = z.ZodEnum<{ a: "a"; b: "b" }>;
|
||||
});
|
||||
|
||||
test("enum error message, invalid enum elementstring", () => {
|
||||
const result = z.enum(["Tuna", "Trout"]).safeParse("Salmon");
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"Tuna",
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid option: expected one of \\"Tuna\\"|\\"Trout\\""
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("enum error message, invalid type", () => {
|
||||
const result = z.enum(["Tuna", "Trout"]).safeParse(12);
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
// expect(result.error!.issues[0].message).toEqual('Invalid input: expected one of "Tuna"|"Trout"');
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"Tuna",
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid option: expected one of \\"Tuna\\"|\\"Trout\\""
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("nativeEnum default error message", () => {
|
||||
enum Fish {
|
||||
Tuna = "Tuna",
|
||||
Trout = "Trout",
|
||||
}
|
||||
const result = z.nativeEnum(Fish).safeParse("Salmon");
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
// expect(result.error!.issues[0].message).toEqual('Invalid input: expected one of "Tuna"|"Trout"');
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"Tuna",
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid option: expected one of \\"Tuna\\"|\\"Trout\\""
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("enum with message returns the custom error message", () => {
|
||||
const schema = z.enum(["apple", "banana"], {
|
||||
message: "the value provided is invalid",
|
||||
});
|
||||
|
||||
const result1 = schema.safeParse("berries");
|
||||
expect(result1.success).toEqual(false);
|
||||
if (!result1.success) {
|
||||
expect(result1.error.issues[0].message).toEqual("the value provided is invalid");
|
||||
}
|
||||
|
||||
const result2 = schema.safeParse(undefined);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result2.success) {
|
||||
expect(result2.error.issues[0].message).toEqual("the value provided is invalid");
|
||||
}
|
||||
|
||||
const result3 = schema.safeParse("banana");
|
||||
expect(result3.success).toEqual(true);
|
||||
|
||||
const result4 = schema.safeParse(null);
|
||||
expect(result4.success).toEqual(false);
|
||||
if (!result4.success) {
|
||||
expect(result4.error.issues[0].message).toEqual("the value provided is invalid");
|
||||
}
|
||||
});
|
||||
|
||||
test("enum with diagonal keys", () => {
|
||||
const schema_02 = z.enum({
|
||||
A: 1,
|
||||
B: "A",
|
||||
});
|
||||
|
||||
expect(schema_02.safeParse("A")).toMatchObject({ success: true });
|
||||
});
|
||||
527
frontend/node_modules/zod/src/v4/classic/tests/error-utils.test.ts
generated
vendored
Normal file
527
frontend/node_modules/zod/src/v4/classic/tests/error-utils.test.ts
generated
vendored
Normal file
@ -0,0 +1,527 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
declare const iss: z.core.$ZodIssueCode;
|
||||
|
||||
const Test = z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().optional(),
|
||||
f3: z.string().nullable(),
|
||||
f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })),
|
||||
});
|
||||
// type TestFlattenedErrors = core.inferFlattenedErrors<typeof Test, { message: string; code: number }>;
|
||||
// type TestFormErrors = core.inferFlattenedErrors<typeof Test>;
|
||||
const parsed = Test.safeParse({});
|
||||
|
||||
test("regular error", () => {
|
||||
expect(parsed).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"f1"
|
||||
],
|
||||
"message": "Invalid input: expected number, received undefined"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"f3"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
},
|
||||
{
|
||||
"expected": "array",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"f4"
|
||||
],
|
||||
"message": "Invalid input: expected array, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(".flatten()", () => {
|
||||
const flattened = parsed.error!.flatten();
|
||||
// flattened.
|
||||
expectTypeOf(flattened).toMatchTypeOf<{
|
||||
formErrors: string[];
|
||||
fieldErrors: {
|
||||
f2?: string[];
|
||||
f1?: string[];
|
||||
f3?: string[];
|
||||
f4?: string[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(flattened).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"f1": [
|
||||
"Invalid input: expected number, received undefined",
|
||||
],
|
||||
"f3": [
|
||||
"Invalid input: expected string, received undefined",
|
||||
],
|
||||
"f4": [
|
||||
"Invalid input: expected array, received undefined",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("custom .flatten()", () => {
|
||||
type ErrorType = { message: string; code: number };
|
||||
const flattened = parsed.error!.flatten((iss) => ({ message: iss.message, code: 1234 }));
|
||||
expectTypeOf(flattened).toMatchTypeOf<{
|
||||
formErrors: ErrorType[];
|
||||
fieldErrors: {
|
||||
f2?: ErrorType[];
|
||||
f1?: ErrorType[];
|
||||
f3?: ErrorType[];
|
||||
f4?: ErrorType[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(flattened).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"f1": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected number, received undefined",
|
||||
},
|
||||
],
|
||||
"f3": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected string, received undefined",
|
||||
},
|
||||
],
|
||||
"f4": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected array, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(".format()", () => {
|
||||
const formatted = parsed.error!.format();
|
||||
expectTypeOf(formatted).toMatchTypeOf<{
|
||||
_errors: string[];
|
||||
f2?: { _errors: string[] };
|
||||
f1?: { _errors: string[] };
|
||||
f3?: { _errors: string[] };
|
||||
f4?: {
|
||||
[x: number]: {
|
||||
_errors: string[];
|
||||
t?: {
|
||||
_errors: string[];
|
||||
};
|
||||
};
|
||||
_errors: string[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(formatted).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"f1": {
|
||||
"_errors": [
|
||||
"Invalid input: expected number, received undefined",
|
||||
],
|
||||
},
|
||||
"f3": {
|
||||
"_errors": [
|
||||
"Invalid input: expected string, received undefined",
|
||||
],
|
||||
},
|
||||
"f4": {
|
||||
"_errors": [
|
||||
"Invalid input: expected array, received undefined",
|
||||
],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("custom .format()", () => {
|
||||
type ErrorType = { message: string; code: number };
|
||||
const formatted = parsed.error!.format((iss) => ({ message: iss.message, code: 1234 }));
|
||||
expectTypeOf(formatted).toMatchTypeOf<{
|
||||
_errors: ErrorType[];
|
||||
f2?: { _errors: ErrorType[] };
|
||||
f1?: { _errors: ErrorType[] };
|
||||
f3?: { _errors: ErrorType[] };
|
||||
f4?: {
|
||||
[x: number]: {
|
||||
_errors: ErrorType[];
|
||||
t?: {
|
||||
_errors: ErrorType[];
|
||||
};
|
||||
};
|
||||
_errors: ErrorType[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(formatted).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"f1": {
|
||||
"_errors": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected number, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
"f3": {
|
||||
"_errors": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected string, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
"f4": {
|
||||
"_errors": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected array, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("all errors", () => {
|
||||
const propertySchema = z.string();
|
||||
const schema = z
|
||||
.object({
|
||||
a: propertySchema,
|
||||
b: propertySchema,
|
||||
})
|
||||
.refine(
|
||||
(val) => {
|
||||
return val.a === val.b;
|
||||
},
|
||||
{ message: "Must be equal" }
|
||||
);
|
||||
|
||||
const r1 = schema.safeParse({
|
||||
a: "asdf",
|
||||
b: "qwer",
|
||||
});
|
||||
|
||||
expect(z.core.flattenError(r1.error!)).toEqual({
|
||||
formErrors: ["Must be equal"],
|
||||
fieldErrors: {},
|
||||
});
|
||||
|
||||
const r2 = schema.safeParse({
|
||||
a: null,
|
||||
b: null,
|
||||
});
|
||||
|
||||
// const error = _error as z.ZodError;
|
||||
expect(z.core.flattenError(r2.error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
"Invalid input: expected string, received null",
|
||||
],
|
||||
"b": [
|
||||
"Invalid input: expected string, received null",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
|
||||
expect(z.core.flattenError(r2.error!, (iss) => iss.message.toUpperCase())).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
"INVALID INPUT: EXPECTED STRING, RECEIVED NULL",
|
||||
],
|
||||
"b": [
|
||||
"INVALID INPUT: EXPECTED STRING, RECEIVED NULL",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
// Test identity
|
||||
|
||||
expect(z.core.flattenError(r2.error!, (i: z.ZodIssue) => i)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received null",
|
||||
"path": [
|
||||
"a",
|
||||
],
|
||||
},
|
||||
],
|
||||
"b": [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received null",
|
||||
"path": [
|
||||
"b",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
|
||||
// Test mapping
|
||||
const f1 = z.core.flattenError(r2.error!, (i: z.ZodIssue) => i.message.length);
|
||||
expect(f1).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
45,
|
||||
],
|
||||
"b": [
|
||||
45,
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
// expect(f1.fieldErrors.a![0]).toEqual("Invalid input: expected string".length);
|
||||
// expect(f1).toMatchObject({
|
||||
// formErrors: [],
|
||||
// fieldErrors: {
|
||||
// a: ["Invalid input: expected string".length],
|
||||
// b: ["Invalid input: expected string".length],
|
||||
// },
|
||||
// });
|
||||
});
|
||||
|
||||
const schema = z.strictObject({
|
||||
username: z.string(),
|
||||
favoriteNumbers: z.array(z.number()),
|
||||
nesting: z.object({
|
||||
a: z.string(),
|
||||
}),
|
||||
});
|
||||
const result = schema.safeParse({
|
||||
username: 1234,
|
||||
favoriteNumbers: [1234, "4567"],
|
||||
nesting: {
|
||||
a: 123,
|
||||
},
|
||||
extra: 1234,
|
||||
});
|
||||
|
||||
test("z.treeifyError", () => {
|
||||
expect(z.treeifyError(result.error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"errors": [
|
||||
"Unrecognized key: "extra"",
|
||||
],
|
||||
"properties": {
|
||||
"favoriteNumbers": {
|
||||
"errors": [],
|
||||
"items": [
|
||||
,
|
||||
{
|
||||
"errors": [
|
||||
"Invalid input: expected number, received string",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"nesting": {
|
||||
"errors": [],
|
||||
"properties": {
|
||||
"a": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received number",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"username": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received number",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.treeifyError 2", () => {
|
||||
const schema = z.strictObject({
|
||||
name: z.string(),
|
||||
logLevel: z.union([z.string(), z.number()]),
|
||||
env: z.literal(["production", "development"]),
|
||||
});
|
||||
|
||||
const data = {
|
||||
name: 1000,
|
||||
logLevel: false,
|
||||
extra: 1000,
|
||||
};
|
||||
|
||||
const result = schema.safeParse(data);
|
||||
const err = z.treeifyError(result.error!);
|
||||
expect(err).toMatchInlineSnapshot(`
|
||||
{
|
||||
"errors": [
|
||||
"Unrecognized key: "extra"",
|
||||
],
|
||||
"properties": {
|
||||
"env": {
|
||||
"errors": [
|
||||
"Invalid option: expected one of "production"|"development"",
|
||||
],
|
||||
},
|
||||
"logLevel": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received boolean",
|
||||
"Invalid input: expected number, received boolean",
|
||||
],
|
||||
},
|
||||
"name": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received number",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.prettifyError", () => {
|
||||
expect(z.prettifyError(result.error!)).toMatchInlineSnapshot(`
|
||||
"✖ Unrecognized key: "extra"
|
||||
✖ Invalid input: expected string, received number
|
||||
→ at username
|
||||
✖ Invalid input: expected number, received string
|
||||
→ at favoriteNumbers[1]
|
||||
✖ Invalid input: expected string, received number
|
||||
→ at nesting.a"
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.toDotPath", () => {
|
||||
expect(z.core.toDotPath(["a", "b", 0, "c"])).toMatchInlineSnapshot(`"a.b[0].c"`);
|
||||
|
||||
expect(z.core.toDotPath(["a", Symbol("b"), 0, "c"])).toMatchInlineSnapshot(`"a["Symbol(b)"][0].c"`);
|
||||
|
||||
// Test with periods in keys
|
||||
expect(z.core.toDotPath(["user.name", "first.last"])).toMatchInlineSnapshot(`"["user.name"]["first.last"]"`);
|
||||
|
||||
// Test with special characters
|
||||
expect(z.core.toDotPath(["user", "$special", Symbol("#symbol")])).toMatchInlineSnapshot(
|
||||
`"user.$special["Symbol(#symbol)"]"`
|
||||
);
|
||||
|
||||
// Test with dots and quotes
|
||||
expect(z.core.toDotPath(["search", `query("foo.bar"="abc")`])).toMatchInlineSnapshot(
|
||||
`"search["query(\\"foo.bar\\"=\\"abc\\")"]"`
|
||||
);
|
||||
|
||||
// Test with newlines
|
||||
expect(z.core.toDotPath(["search", `foo\nbar`])).toMatchInlineSnapshot(`"search["foo\\nbar"]"`);
|
||||
|
||||
// Test with empty strings
|
||||
expect(z.core.toDotPath(["", "empty"])).toMatchInlineSnapshot(`".empty"`);
|
||||
|
||||
// Test with array indices
|
||||
expect(z.core.toDotPath(["items", 0, 1, 2])).toMatchInlineSnapshot(`"items[0][1][2]"`);
|
||||
|
||||
// Test with mixed path elements
|
||||
expect(z.core.toDotPath(["users", "user.config", 0, "settings.theme"])).toMatchInlineSnapshot(
|
||||
`"users["user.config"][0]["settings.theme"]"`
|
||||
);
|
||||
|
||||
// Test with square brackets in keys
|
||||
expect(z.core.toDotPath(["data[0]", "value"])).toMatchInlineSnapshot(`"["data[0]"].value"`);
|
||||
|
||||
// Test with empty path
|
||||
expect(z.core.toDotPath([])).toMatchInlineSnapshot(`""`);
|
||||
});
|
||||
|
||||
test("inheritance", () => {
|
||||
const e1 = new z.ZodError([]);
|
||||
expect(e1).toBeInstanceOf(z.core.$ZodError);
|
||||
expect(e1).toBeInstanceOf(z.ZodError);
|
||||
// expect(e1).not.toBeInstanceOf(Error);
|
||||
|
||||
const e2 = new z.ZodRealError([]);
|
||||
expect(e2).toBeInstanceOf(z.ZodError);
|
||||
expect(e2).toBeInstanceOf(z.ZodRealError);
|
||||
expect(e2).toBeInstanceOf(Error);
|
||||
});
|
||||
|
||||
test("disc union treeify/format", () => {
|
||||
const schema = z.discriminatedUnion(
|
||||
"foo",
|
||||
[
|
||||
z.object({
|
||||
foo: z.literal("x"),
|
||||
x: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
foo: z.literal("y"),
|
||||
y: z.string(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
error: "Invalid discriminator",
|
||||
}
|
||||
);
|
||||
|
||||
const error = schema.safeParse({ foo: "invalid" }).error;
|
||||
expect(z.treeifyError(error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"errors": [],
|
||||
"properties": {
|
||||
"foo": {
|
||||
"errors": [
|
||||
"Invalid discriminator",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(z.prettifyError(error!)).toMatchInlineSnapshot(`
|
||||
"✖ Invalid discriminator
|
||||
→ at foo"
|
||||
`);
|
||||
expect(z.formatError(error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"foo": {
|
||||
"_errors": [
|
||||
"Invalid discriminator",
|
||||
],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
711
frontend/node_modules/zod/src/v4/classic/tests/error.test.ts
generated
vendored
Normal file
711
frontend/node_modules/zod/src/v4/classic/tests/error.test.ts
generated
vendored
Normal file
@ -0,0 +1,711 @@
|
||||
import { inspect } from "node:util";
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("error creation", () => {
|
||||
const err1 = new z.ZodError([]);
|
||||
|
||||
err1.issues.push({
|
||||
code: "invalid_type",
|
||||
expected: "object",
|
||||
path: [],
|
||||
message: "",
|
||||
input: "adf",
|
||||
});
|
||||
err1.isEmpty;
|
||||
|
||||
const err2 = new z.ZodError(err1.issues);
|
||||
const err3 = new z.ZodError([]);
|
||||
err3.addIssues(err1.issues);
|
||||
err3.addIssue(err1.issues[0]);
|
||||
err1.message;
|
||||
err2.message;
|
||||
err3.message;
|
||||
});
|
||||
|
||||
test("do not allow error and message together", () => {
|
||||
expect(() =>
|
||||
z.string().refine((_) => true, {
|
||||
message: "override",
|
||||
error: (iss) => (iss.input === undefined ? "asdf" : null),
|
||||
})
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
const errorMap: z.ZodErrorMap = (issue) => {
|
||||
if (issue.code === "invalid_type") {
|
||||
if (issue.expected === "string") {
|
||||
return { message: "bad type!" };
|
||||
}
|
||||
}
|
||||
if (issue.code === "custom") {
|
||||
return { message: `less-than-${issue.params?.minimum}` };
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
test("type error with custom error map", () => {
|
||||
const result = z.string().safeParse(234, { error: errorMap });
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "bad type!"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("refinement fail with params", () => {
|
||||
const result = z
|
||||
.number()
|
||||
.refine((val) => val >= 3, {
|
||||
params: { minimum: 3 },
|
||||
})
|
||||
.safeParse(2, { error: errorMap });
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"params": {
|
||||
"minimum": 3
|
||||
},
|
||||
"message": "less-than-3"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("hard coded error with custom errormap", () => {
|
||||
const result = z
|
||||
.string()
|
||||
.refine((val) => val.length > 12, {
|
||||
params: { minimum: 13 },
|
||||
message: "override",
|
||||
})
|
||||
.safeParse("asdf", { error: () => "contextual" });
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"params": {
|
||||
"minimum": 13
|
||||
},
|
||||
"message": "override"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("default error message", () => {
|
||||
const result = z
|
||||
.number()
|
||||
.refine((x) => x > 3)
|
||||
.safeParse(2);
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("override error in refine", () => {
|
||||
const result = z
|
||||
.number()
|
||||
.refine((x) => x > 3, "override")
|
||||
.safeParse(2);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "override"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("override error in refinement", () => {
|
||||
const result = z
|
||||
.number()
|
||||
.refine((x) => x > 3, {
|
||||
message: "override",
|
||||
})
|
||||
.safeParse(2);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "override"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("array minimum", () => {
|
||||
let result = z.array(z.string()).min(3, "tooshort").safeParse(["asdf", "qwer"]);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues[0].code).toEqual("too_small");
|
||||
expect(result.error!.issues[0].message).toEqual("tooshort");
|
||||
|
||||
result = z.array(z.string()).min(3).safeParse(["asdf", "qwer"]);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues[0].code).toEqual("too_small");
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"origin": "array",
|
||||
"code": "too_small",
|
||||
"minimum": 3,
|
||||
"inclusive": true,
|
||||
"path": [],
|
||||
"message": "Too small: expected array to have >=3 items"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("literal bigint default error message", () => {
|
||||
const result = z.literal(BigInt(12)).safeParse(BigInt(13));
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"12"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid input: expected 12n"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("custom path in custom error map", () => {
|
||||
const schema = z.object({
|
||||
items: z.array(z.string()).refine((data) => data.length > 3, {
|
||||
path: ["items-too-few"],
|
||||
}),
|
||||
});
|
||||
|
||||
const errorMap: z.ZodErrorMap = (issue) => {
|
||||
expect((issue.path ?? []).length).toBe(2);
|
||||
return { message: "doesnt matter" };
|
||||
};
|
||||
const result = schema.safeParse({ items: ["first"] }, { error: errorMap });
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"items",
|
||||
"items-too-few"
|
||||
],
|
||||
"message": "doesnt matter"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
// test("error metadata from value", () => {
|
||||
// const dynamicRefine = z.string().refine(
|
||||
// (val) => val === val.toUpperCase(),
|
||||
// (val) => ({ params: { val } })
|
||||
// );
|
||||
|
||||
// const result = dynamicRefine.safeParse("asdf");
|
||||
// expect(result.success).toEqual(false);
|
||||
// if (!result.success) {
|
||||
// const sub = result.error.issues[0];
|
||||
// expect(result.error.issues[0].code).toEqual("custom");
|
||||
// if (sub.code === "custom") {
|
||||
// expect(sub.params?.val).toEqual("asdf");
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("don't call refine after validation failed", () => {
|
||||
// const asdf = z
|
||||
// .union([
|
||||
// z.number(),
|
||||
// z.string().transform(z.number(), (val) => {
|
||||
// return parseFloat(val);
|
||||
// }),
|
||||
// ])
|
||||
// .refine((v) => v >= 1);
|
||||
|
||||
// expect(() => asdf.safeParse("foo")).not.toThrow();
|
||||
// });
|
||||
|
||||
test("root level formatting", () => {
|
||||
const schema = z.string().email();
|
||||
const result = schema.safeParse("asdfsdf");
|
||||
expect(result.success).toBe(false);
|
||||
|
||||
expect(result.error!.format()).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [
|
||||
"Invalid email address",
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("custom path", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
password: z.string(),
|
||||
confirm: z.string(),
|
||||
})
|
||||
.refine((val) => val.confirm === val.password, { path: ["confirm"] });
|
||||
|
||||
const result = schema.safeParse({
|
||||
password: "peanuts",
|
||||
confirm: "qeanuts",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
const error = result.error!.format();
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.password?._errors).toEqual(undefined);
|
||||
expect(error.confirm?._errors).toEqual(["Invalid input"]);
|
||||
});
|
||||
|
||||
test("custom path", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
password: z.string().min(6),
|
||||
confirm: z.string().min(6),
|
||||
})
|
||||
.refine((val) => val.confirm === val.password);
|
||||
|
||||
const result = schema.safeParse({
|
||||
password: "qwer",
|
||||
confirm: "asdf",
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues.length).toEqual(3);
|
||||
});
|
||||
|
||||
const schema = z.object({
|
||||
inner: z.object({
|
||||
name: z
|
||||
.string()
|
||||
.refine((val) => val.length > 5)
|
||||
.array()
|
||||
.refine((val) => val.length <= 1),
|
||||
}),
|
||||
});
|
||||
|
||||
test("no abort early on refinements", () => {
|
||||
const invalidItem = {
|
||||
inner: { name: ["aasd", "asdfasdfasfd"] },
|
||||
};
|
||||
|
||||
const result1 = schema.safeParse(invalidItem);
|
||||
expect(result1.success).toBe(false);
|
||||
expect(result1.error!.issues.length).toEqual(2);
|
||||
});
|
||||
|
||||
test("detect issue with input fallback", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.transform((val) => val.length)
|
||||
.refine(() => false, { message: "always fails" })
|
||||
.refine(
|
||||
(val) => {
|
||||
if (typeof val !== "number") throw new Error();
|
||||
return (val ^ 2) > 10;
|
||||
} // should be number but it's a string
|
||||
);
|
||||
expect(() => schema.parse("hello")).toThrow(z.ZodError);
|
||||
});
|
||||
|
||||
test("formatting", () => {
|
||||
const invalidItem = {
|
||||
inner: { name: ["aasd", "asdfasdfasfd"] },
|
||||
};
|
||||
const invalidArray = {
|
||||
inner: { name: ["asdfasdf", "asdfasdfasfd"] },
|
||||
};
|
||||
const result1 = schema.safeParse(invalidItem);
|
||||
const result2 = schema.safeParse(invalidArray);
|
||||
|
||||
expect(result1.success).toBe(false);
|
||||
expect(result2.success).toBe(false);
|
||||
const error1 = result1.error!.format();
|
||||
expect(error1._errors).toEqual([]);
|
||||
expect(error1.inner?._errors).toEqual([]);
|
||||
expect(error1.inner?.name?.[1]).toEqual(undefined);
|
||||
|
||||
type FormattedError = z.inferFormattedError<typeof schema>;
|
||||
const error2: FormattedError = result2.error!.format();
|
||||
expect(error2._errors).toEqual([]);
|
||||
expect(error2.inner?._errors).toEqual([]);
|
||||
expect(error2.inner?.name?._errors).toEqual(["Invalid input"]);
|
||||
expect(error2.inner?.name?.[0]).toEqual(undefined);
|
||||
expect(error2.inner?.name?.[1]).toEqual(undefined);
|
||||
expect(error2.inner?.name?.[2]).toEqual(undefined);
|
||||
|
||||
// test custom mapper
|
||||
type FormattedErrorWithNumber = z.inferFormattedError<typeof schema, number>;
|
||||
const errorWithNumber: FormattedErrorWithNumber = result2.error!.format(() => 5);
|
||||
expect(errorWithNumber._errors).toEqual([]);
|
||||
expect(errorWithNumber.inner?._errors).toEqual([]);
|
||||
expect(errorWithNumber.inner?.name?._errors).toEqual([5]);
|
||||
});
|
||||
|
||||
test("formatting with nullable and optional fields", () => {
|
||||
const nameSchema = z.string().refine((val) => val.length > 5);
|
||||
const schema = z.object({
|
||||
nullableObject: z.object({ name: nameSchema }).nullable(),
|
||||
nullableArray: z.array(nameSchema).nullable(),
|
||||
nullableTuple: z.tuple([nameSchema, nameSchema, z.number()]).nullable(),
|
||||
optionalObject: z.object({ name: nameSchema }).optional(),
|
||||
optionalArray: z.array(nameSchema).optional(),
|
||||
optionalTuple: z.tuple([nameSchema, nameSchema, z.number()]).optional(),
|
||||
});
|
||||
const invalidItem = {
|
||||
nullableObject: { name: "abcd" },
|
||||
nullableArray: ["abcd"],
|
||||
nullableTuple: ["abcd", "abcd", 1],
|
||||
optionalObject: { name: "abcd" },
|
||||
optionalArray: ["abcd"],
|
||||
optionalTuple: ["abcd", "abcd", 1],
|
||||
};
|
||||
const result = schema.safeParse(invalidItem);
|
||||
expect(result.success).toBe(false);
|
||||
const error: z.inferFormattedError<typeof schema> = result.error!.format();
|
||||
expect(error._errors).toEqual([]);
|
||||
expect(error.nullableObject?._errors).toEqual([]);
|
||||
expect(error.nullableObject?.name?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.nullableArray?._errors).toEqual([]);
|
||||
expect(error.nullableArray?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.nullableTuple?._errors).toEqual([]);
|
||||
expect(error.nullableTuple?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.nullableTuple?.[1]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalObject?._errors).toEqual([]);
|
||||
expect(error.optionalObject?.name?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalArray?._errors).toEqual([]);
|
||||
expect(error.optionalArray?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalTuple?._errors).toEqual([]);
|
||||
expect(error.optionalTuple?.[0]?._errors).toEqual(["Invalid input"]);
|
||||
expect(error.optionalTuple?.[1]?._errors).toEqual(["Invalid input"]);
|
||||
|
||||
expect(error).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"nullableArray": {
|
||||
"0": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
"_errors": [],
|
||||
},
|
||||
"nullableObject": {
|
||||
"_errors": [],
|
||||
"name": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
},
|
||||
"nullableTuple": {
|
||||
"0": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
"1": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
"_errors": [],
|
||||
},
|
||||
"optionalArray": {
|
||||
"0": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
"_errors": [],
|
||||
},
|
||||
"optionalObject": {
|
||||
"_errors": [],
|
||||
"name": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
},
|
||||
"optionalTuple": {
|
||||
"0": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
"1": {
|
||||
"_errors": [
|
||||
"Invalid input",
|
||||
],
|
||||
},
|
||||
"_errors": [],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("inferFlattenedErrors", () => {
|
||||
const schemaWithTransform = z.object({ foo: z.string() }).transform((o) => ({ bar: o.foo }));
|
||||
|
||||
const result = schemaWithTransform.safeParse({});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
type ValidationErrors = z.inferFlattenedErrors<typeof schemaWithTransform>;
|
||||
const error: ValidationErrors = result.error!.flatten();
|
||||
expect(error).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"foo": [
|
||||
"Invalid input: expected string, received undefined",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
const stringWithCustomError = z.string({
|
||||
error: () => "bound",
|
||||
});
|
||||
|
||||
test("schema-bound error map", () => {
|
||||
const result = stringWithCustomError.safeParse(1234);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues[0].message).toEqual("bound");
|
||||
});
|
||||
|
||||
test("bound error map overrides contextual", () => {
|
||||
// support contextual override
|
||||
const result = stringWithCustomError.safeParse(undefined, {
|
||||
error: () => ({ message: "override" }),
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues[0].message).toEqual("bound");
|
||||
});
|
||||
|
||||
test("z.config customError ", () => {
|
||||
// support overrideErrorMap
|
||||
|
||||
z.config({ customError: () => ({ message: "override" }) });
|
||||
const result = stringWithCustomError.min(10).safeParse("tooshort");
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 10,
|
||||
"inclusive": true,
|
||||
"path": [],
|
||||
"message": "override"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
expect(result.error!.issues[0].message).toEqual("override");
|
||||
z.config({ customError: undefined });
|
||||
});
|
||||
|
||||
// test("invalid and required", () => {
|
||||
// const str = z.string({
|
||||
// invalid_type_error: "Invalid name",
|
||||
// required_error: "Name is required",
|
||||
// });
|
||||
// const result1 = str.safeParse(1234);
|
||||
// expect(result1.success).toBe(false);
|
||||
// if (!result1.success) {
|
||||
// expect(result1.error.issues[0].message).toEqual("Invalid name");
|
||||
// }
|
||||
// const result2 = str.safeParse(undefined);
|
||||
// expect(result2.success).toBe(false);
|
||||
// if (!result2.success) {
|
||||
// expect(result2.error.issues[0].message).toEqual("Name is required");
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("Fallback to default required error", () => {
|
||||
// const str = z.string({
|
||||
// invalid_type_error: "Invalid name",
|
||||
// // required_error: "Name is required",
|
||||
// });
|
||||
|
||||
// const result2 = str.safeParse(undefined);
|
||||
// expect(result2.success).toBe(false);
|
||||
// if (!result2.success) {
|
||||
// expect(result2.error.issues[0].message).toEqual("Required");
|
||||
// }
|
||||
// });
|
||||
|
||||
// test("invalid and required and errorMap", () => {
|
||||
// expect(() => {
|
||||
// return z.string({
|
||||
// invalid_type_error: "Invalid name",
|
||||
// required_error: "Name is required",
|
||||
// errorMap: () => ({ message: "override" }),
|
||||
// });
|
||||
// }).toThrow();
|
||||
// });
|
||||
|
||||
// test("strict error message", () => {
|
||||
// const errorMsg = "Invalid object";
|
||||
// const obj = z.object({ x: z.string() }).strict(errorMsg);
|
||||
// const result = obj.safeParse({ x: "a", y: "b" });
|
||||
// expect(result.success).toBe(false);
|
||||
// if (!result.success) {
|
||||
// expect(result.error.issues[0].message).toEqual(errorMsg);
|
||||
// }
|
||||
// });
|
||||
|
||||
test("empty string error message", () => {
|
||||
const schema = z.string().max(1, { message: "" });
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error!.issues[0].message).toEqual("");
|
||||
});
|
||||
|
||||
test("dont short circuit on continuable errors", () => {
|
||||
const user = z
|
||||
.object({
|
||||
password: z.string().min(6),
|
||||
confirm: z.string(),
|
||||
})
|
||||
.refine((data) => data.password === data.confirm, {
|
||||
message: "Passwords don't match",
|
||||
path: ["confirm"],
|
||||
});
|
||||
const result = user.safeParse({ password: "asdf", confirm: "qwer" });
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 6,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"password"
|
||||
],
|
||||
"message": "Too small: expected string to have >=6 characters"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"confirm"
|
||||
],
|
||||
"message": "Passwords don't match"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
// expect(result.error!.issues.length).toEqual(2);
|
||||
});
|
||||
|
||||
test("string error params", () => {
|
||||
const a = z.string("Bad!");
|
||||
expect(a.safeParse(123).error!.issues[0].message).toBe("Bad!");
|
||||
|
||||
const b = z.string().min(5, "Too short!");
|
||||
expect(b.safeParse("abc").error!.issues[0].message).toBe("Too short!");
|
||||
|
||||
const c = z.uuid("Bad UUID!");
|
||||
expect(c.safeParse("not-a-uuid").error!.issues[0].message).toBe("Bad UUID!");
|
||||
|
||||
const d = z.string().datetime({ message: "Bad date!" });
|
||||
expect(d.safeParse("not-a-date").error!.issues[0].message).toBe("Bad date!");
|
||||
|
||||
const e = z.array(z.string(), "Bad array!");
|
||||
expect(e.safeParse("not-an-array").error!.issues[0].message).toBe("Bad array!");
|
||||
|
||||
const f = z.array(z.string()).min(5, "Too few items!");
|
||||
expect(f.safeParse(["a", "b"]).error!.issues[0].message).toBe("Too few items!");
|
||||
|
||||
const g = z.set(z.string(), "Bad set!");
|
||||
expect(g.safeParse("not-a-set").error!.issues[0].message).toBe("Bad set!");
|
||||
|
||||
const h = z.array(z.string(), "Bad array!");
|
||||
expect(h.safeParse(123).error!.issues[0].message).toBe("Bad array!");
|
||||
|
||||
const i = z.set(z.string(), "Bad set!");
|
||||
expect(i.safeParse(123).error!.issues[0].message).toBe("Bad set!");
|
||||
|
||||
const j = z.array(z.string(), "Bad array!");
|
||||
expect(j.safeParse(null).error!.issues[0].message).toBe("Bad array!");
|
||||
});
|
||||
|
||||
test("error inheritance", () => {
|
||||
const e1 = z.string().safeParse(123).error!;
|
||||
expect(e1).toBeInstanceOf(z.core.$ZodError);
|
||||
expect(e1).toBeInstanceOf(z.ZodError);
|
||||
expect(e1).toBeInstanceOf(z.ZodRealError);
|
||||
// expect(e1).not.toBeInstanceOf(Error);
|
||||
|
||||
try {
|
||||
z.string().parse(123);
|
||||
} catch (e2) {
|
||||
expect(e1).toBeInstanceOf(z.core.$ZodError);
|
||||
expect(e2).toBeInstanceOf(z.ZodError);
|
||||
expect(e2).toBeInstanceOf(z.ZodRealError);
|
||||
// expect(e2).toBeInstanceOf(Error);
|
||||
}
|
||||
});
|
||||
|
||||
test("error serialization", () => {
|
||||
try {
|
||||
z.string().parse(123);
|
||||
} catch (e) {
|
||||
expect(e).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
expect(inspect(e).split("\n").slice(0, 8).join("\n")).toMatchInlineSnapshot(`
|
||||
"ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]"
|
||||
`);
|
||||
}
|
||||
});
|
||||
91
frontend/node_modules/zod/src/v4/classic/tests/file.test.ts
generated
vendored
Normal file
91
frontend/node_modules/zod/src/v4/classic/tests/file.test.ts
generated
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
// @ts-ignore
|
||||
import { File as WebFile } from "@web-std/file";
|
||||
|
||||
import { afterEach, beforeEach, expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const minCheck = z.file().min(5);
|
||||
const maxCheck = z.file().max(8);
|
||||
const mimeCheck = z.file().mime(["text/plain", "application/json"]);
|
||||
|
||||
const originalFile = global.File;
|
||||
beforeEach(async () => {
|
||||
if (!globalThis.File) globalThis.File = WebFile;
|
||||
});
|
||||
afterEach(() => {
|
||||
if (globalThis.File !== originalFile) {
|
||||
globalThis.File = originalFile;
|
||||
}
|
||||
});
|
||||
|
||||
test("passing validations", () => {
|
||||
minCheck.safeParse(new File(["12345"], "test.txt"));
|
||||
maxCheck.safeParse(new File(["12345678"], "test.txt"));
|
||||
mimeCheck.safeParse(new File([""], "test.csv", { type: "text/plain" }));
|
||||
expect(() => mimeCheck.parse(new File([""], "test.txt"))).toThrow();
|
||||
expect(() => mimeCheck.parse(new File([""], "test.txt", { type: "text/csv" }))).toThrow();
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(minCheck.safeParse(new File(["1234"], "test.txt"))).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "file",
|
||||
"code": "too_small",
|
||||
"minimum": 5,
|
||||
"path": [],
|
||||
"message": "Too small: expected file to have >5 bytes"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(maxCheck.safeParse(new File(["123456789"], "test.txt"))).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "file",
|
||||
"code": "too_big",
|
||||
"maximum": 8,
|
||||
"path": [],
|
||||
"message": "Too big: expected file to have <8 bytes"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(mimeCheck.safeParse(new File([""], "test.csv"))).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"text/plain",
|
||||
"application/json"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid option: expected one of \\"text/plain\\"|\\"application/json\\""
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(mimeCheck.safeParse(new File([""], "test.csv", { type: "text/csv" }))).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"text/plain",
|
||||
"application/json"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid option: expected one of \\"text/plain\\"|\\"application/json\\""
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
175
frontend/node_modules/zod/src/v4/classic/tests/firstparty.test.ts
generated
vendored
Normal file
175
frontend/node_modules/zod/src/v4/classic/tests/firstparty.test.ts
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
import { expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
import type * as core from "zod/v4/core";
|
||||
|
||||
test("first party switch", () => {
|
||||
const myType = z.string() as core.$ZodTypes;
|
||||
const def = myType._zod.def;
|
||||
switch (def.type) {
|
||||
case "string":
|
||||
break;
|
||||
case "number":
|
||||
break;
|
||||
case "bigint":
|
||||
break;
|
||||
case "boolean":
|
||||
break;
|
||||
case "date":
|
||||
break;
|
||||
case "symbol":
|
||||
break;
|
||||
case "undefined":
|
||||
break;
|
||||
case "null":
|
||||
break;
|
||||
case "any":
|
||||
break;
|
||||
case "unknown":
|
||||
break;
|
||||
case "never":
|
||||
break;
|
||||
case "void":
|
||||
break;
|
||||
case "array":
|
||||
break;
|
||||
case "object":
|
||||
break;
|
||||
case "union":
|
||||
break;
|
||||
case "intersection":
|
||||
break;
|
||||
case "tuple":
|
||||
break;
|
||||
case "record":
|
||||
break;
|
||||
case "map":
|
||||
break;
|
||||
case "set":
|
||||
break;
|
||||
case "literal":
|
||||
break;
|
||||
case "enum":
|
||||
break;
|
||||
case "promise":
|
||||
break;
|
||||
case "optional":
|
||||
break;
|
||||
case "nonoptional":
|
||||
break;
|
||||
case "nullable":
|
||||
break;
|
||||
case "default":
|
||||
break;
|
||||
case "prefault":
|
||||
break;
|
||||
case "template_literal":
|
||||
break;
|
||||
case "custom":
|
||||
break;
|
||||
case "transform":
|
||||
break;
|
||||
case "readonly":
|
||||
break;
|
||||
case "nan":
|
||||
break;
|
||||
case "pipe":
|
||||
break;
|
||||
case "success":
|
||||
break;
|
||||
case "catch":
|
||||
break;
|
||||
case "file":
|
||||
break;
|
||||
case "lazy":
|
||||
break;
|
||||
default:
|
||||
expectTypeOf(def).toEqualTypeOf<never>();
|
||||
}
|
||||
});
|
||||
|
||||
test("$ZodSchemaTypes", () => {
|
||||
const type = "string" as core.$ZodTypeDef["type"];
|
||||
switch (type) {
|
||||
case "string":
|
||||
break;
|
||||
case "number":
|
||||
break;
|
||||
case "int":
|
||||
break;
|
||||
case "bigint":
|
||||
break;
|
||||
case "boolean":
|
||||
break;
|
||||
case "date":
|
||||
break;
|
||||
case "symbol":
|
||||
break;
|
||||
case "undefined":
|
||||
break;
|
||||
case "null":
|
||||
break;
|
||||
case "any":
|
||||
break;
|
||||
case "unknown":
|
||||
break;
|
||||
case "never":
|
||||
break;
|
||||
case "void":
|
||||
break;
|
||||
case "array":
|
||||
break;
|
||||
case "object":
|
||||
break;
|
||||
case "union":
|
||||
break;
|
||||
case "intersection":
|
||||
break;
|
||||
case "tuple":
|
||||
break;
|
||||
case "record":
|
||||
break;
|
||||
case "map":
|
||||
break;
|
||||
case "set":
|
||||
break;
|
||||
case "literal":
|
||||
break;
|
||||
case "enum":
|
||||
break;
|
||||
case "promise":
|
||||
break;
|
||||
case "optional":
|
||||
break;
|
||||
case "nonoptional":
|
||||
break;
|
||||
case "nullable":
|
||||
break;
|
||||
case "default":
|
||||
break;
|
||||
case "prefault":
|
||||
break;
|
||||
case "template_literal":
|
||||
break;
|
||||
case "custom":
|
||||
break;
|
||||
case "transform":
|
||||
break;
|
||||
case "readonly":
|
||||
break;
|
||||
case "nan":
|
||||
break;
|
||||
case "pipe":
|
||||
break;
|
||||
case "success":
|
||||
break;
|
||||
case "catch":
|
||||
break;
|
||||
case "file":
|
||||
break;
|
||||
case "lazy":
|
||||
break;
|
||||
|
||||
default:
|
||||
expectTypeOf(type).toEqualTypeOf<never>();
|
||||
}
|
||||
});
|
||||
268
frontend/node_modules/zod/src/v4/classic/tests/function.test.ts
generated
vendored
Normal file
268
frontend/node_modules/zod/src/v4/classic/tests/function.test.ts
generated
vendored
Normal file
@ -0,0 +1,268 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const args1 = z.tuple([z.string()]);
|
||||
const returns1 = z.number();
|
||||
const func1 = z.function({
|
||||
input: args1,
|
||||
|
||||
output: returns1,
|
||||
});
|
||||
|
||||
test("function parsing", () => {
|
||||
const parsed = func1.implement((arg: any) => arg.length);
|
||||
const result = parsed("asdf");
|
||||
expect(result).toBe(4);
|
||||
});
|
||||
|
||||
test("parsed function fail 1", () => {
|
||||
// @ts-expect-error
|
||||
const parsed = func1.implement((x: string) => x);
|
||||
expect(() => parsed("asdf")).toThrow();
|
||||
});
|
||||
|
||||
test("parsed function fail 2", () => {
|
||||
// @ts-expect-error
|
||||
const parsed = func1.implement((x: string) => x);
|
||||
expect(() => parsed(13 as any)).toThrow();
|
||||
});
|
||||
|
||||
test("function inference 1", () => {
|
||||
type func1 = (typeof func1)["_input"];
|
||||
expectTypeOf<func1>().toEqualTypeOf<(k: string) => number>();
|
||||
});
|
||||
|
||||
// test("method parsing", () => {
|
||||
// const methodObject = z.object({
|
||||
// property: z.number(),
|
||||
// method: z
|
||||
// .function()
|
||||
// .input(z.tuple([z.string()]))
|
||||
// .output(z.number()),
|
||||
// });
|
||||
// const methodInstance = {
|
||||
// property: 3,
|
||||
// method: function (s: string) {
|
||||
// return s.length + this.property;
|
||||
// },
|
||||
// };
|
||||
// const parsed = methodObject.parse(methodInstance);
|
||||
// expect(parsed.method("length=8")).toBe(11); // 8 length + 3 property
|
||||
// });
|
||||
|
||||
// test("async method parsing", async () => {
|
||||
// const methodObject = z.object({
|
||||
// property: z.number(),
|
||||
// method: z.function().input(z.string()).output(z.promise(z.number())),
|
||||
// });
|
||||
// const methodInstance = {
|
||||
// property: 3,
|
||||
// method: async function (s: string) {
|
||||
// return s.length + this.property;
|
||||
// },
|
||||
// };
|
||||
// const parsed = methodObject.parse(methodInstance);
|
||||
// expect(await parsed.method("length=8")).toBe(11); // 8 length + 3 property
|
||||
// });
|
||||
|
||||
test("args method", () => {
|
||||
const t1 = z.function();
|
||||
type t1 = (typeof t1)["_input"];
|
||||
expectTypeOf<t1>().toEqualTypeOf<(...args_1: never[]) => unknown>();
|
||||
t1._input;
|
||||
|
||||
const t2args = z.tuple([z.string()], z.unknown());
|
||||
|
||||
const t2 = t1.input(t2args);
|
||||
type t2 = (typeof t2)["_input"];
|
||||
expectTypeOf<t2>().toEqualTypeOf<(arg: string, ...args_1: unknown[]) => unknown>();
|
||||
|
||||
const t3 = t2.output(z.boolean());
|
||||
type t3 = (typeof t3)["_input"];
|
||||
expectTypeOf<t3>().toEqualTypeOf<(arg: string, ...args_1: unknown[]) => boolean>();
|
||||
});
|
||||
|
||||
// test("custom args", () => {
|
||||
// const fn = z.function().implement((_a: string, _b: number) => {
|
||||
// return new Date();
|
||||
// });
|
||||
|
||||
// expectTypeOf(fn).toEqualTypeOf<(a: string, b: number) => Date>();
|
||||
// });
|
||||
|
||||
const args2 = z.tuple([
|
||||
z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().nullable(),
|
||||
f3: z.array(z.boolean().optional()).optional(),
|
||||
}),
|
||||
]);
|
||||
const returns2 = z.union([z.string(), z.number()]);
|
||||
|
||||
const func2 = z.function({
|
||||
input: args2,
|
||||
output: returns2,
|
||||
});
|
||||
|
||||
test("function inference 2", () => {
|
||||
type func2 = (typeof func2)["_input"];
|
||||
|
||||
expectTypeOf<func2>().toEqualTypeOf<
|
||||
(arg: {
|
||||
f3?: (boolean | undefined)[] | undefined;
|
||||
f1: number;
|
||||
f2: string | null;
|
||||
}) => string | number
|
||||
>();
|
||||
});
|
||||
|
||||
test("valid function run", () => {
|
||||
const validFunc2Instance = func2.implement((_x) => {
|
||||
_x.f2;
|
||||
_x.f3![0];
|
||||
return "adf" as any;
|
||||
});
|
||||
|
||||
validFunc2Instance({
|
||||
f1: 21,
|
||||
f2: "asdf",
|
||||
f3: [true, false],
|
||||
});
|
||||
});
|
||||
|
||||
test("input validation error", () => {
|
||||
const schema = z.function({
|
||||
input: z.tuple([z.string()]),
|
||||
output: z.void(),
|
||||
});
|
||||
const fn = schema.implement(() => 1234 as any);
|
||||
|
||||
// @ts-expect-error
|
||||
const checker = () => fn();
|
||||
|
||||
try {
|
||||
checker();
|
||||
} catch (e: any) {
|
||||
expect(e.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received undefined",
|
||||
"path": [
|
||||
0,
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("array inputs", () => {
|
||||
const a = z.function({
|
||||
input: [
|
||||
z.object({
|
||||
name: z.string(),
|
||||
age: z.number().int(),
|
||||
}),
|
||||
],
|
||||
output: z.string(),
|
||||
});
|
||||
|
||||
a.implement((args) => {
|
||||
return `${args.age}`;
|
||||
});
|
||||
|
||||
const b = z.function({
|
||||
input: [
|
||||
z.object({
|
||||
name: z.string(),
|
||||
age: z.number().int(),
|
||||
}),
|
||||
],
|
||||
});
|
||||
b.implement((args) => {
|
||||
return `${args.age}`;
|
||||
});
|
||||
});
|
||||
|
||||
test("output validation error", () => {
|
||||
const schema = z.function({
|
||||
input: z.tuple([]),
|
||||
output: z.string(),
|
||||
});
|
||||
const fn = schema.implement(() => 1234 as any);
|
||||
try {
|
||||
fn();
|
||||
} catch (e: any) {
|
||||
expect(e.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("function with async refinements", async () => {
|
||||
const schema = z
|
||||
.function()
|
||||
.input([z.string().refine(async (val) => val.length > 10)])
|
||||
.output(z.promise(z.number().refine(async (val) => val > 10)));
|
||||
|
||||
const func = schema.implementAsync(async (val) => {
|
||||
return val.length;
|
||||
});
|
||||
const results = [];
|
||||
try {
|
||||
await func("asdfasdf");
|
||||
results.push("success");
|
||||
} catch (_) {
|
||||
results.push("fail");
|
||||
}
|
||||
try {
|
||||
await func("asdflkjasdflkjsf");
|
||||
results.push("success");
|
||||
} catch (_) {
|
||||
results.push("fail");
|
||||
}
|
||||
|
||||
expect(results).toEqual(["fail", "success"]);
|
||||
});
|
||||
|
||||
test("non async function with async refinements should fail", async () => {
|
||||
const func = z
|
||||
.function()
|
||||
.input([z.string().refine(async (val) => val.length > 10)])
|
||||
.output(z.number().refine(async (val) => val > 10))
|
||||
.implement((val) => {
|
||||
return val.length;
|
||||
});
|
||||
|
||||
const results = [];
|
||||
try {
|
||||
await func("asdasdfasdffasdf");
|
||||
results.push("success");
|
||||
} catch (_) {
|
||||
results.push("fail");
|
||||
}
|
||||
|
||||
expect(results).toEqual(["fail"]);
|
||||
});
|
||||
|
||||
test("extra parameters with rest", () => {
|
||||
const maxLength5 = z
|
||||
.function()
|
||||
.input([z.string()], z.unknown())
|
||||
.output(z.boolean())
|
||||
.implement((str, _arg, _qewr) => {
|
||||
return str.length <= 5;
|
||||
});
|
||||
|
||||
const filteredList = ["apple", "orange", "pear", "banana", "strawberry"].filter(maxLength5);
|
||||
expect(filteredList.length).toEqual(2);
|
||||
});
|
||||
72
frontend/node_modules/zod/src/v4/classic/tests/generics.test.ts
generated
vendored
Normal file
72
frontend/node_modules/zod/src/v4/classic/tests/generics.test.ts
generated
vendored
Normal file
@ -0,0 +1,72 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
function nest<TData extends z.ZodType>(schema: TData) {
|
||||
return z.object({
|
||||
nested: schema,
|
||||
});
|
||||
}
|
||||
|
||||
test("generics", () => {
|
||||
const a = nest(z.object({ a: z.string() }));
|
||||
type a = z.infer<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<{ nested: { a: string } }>();
|
||||
|
||||
const b = nest(z.object({ a: z.string().optional() }));
|
||||
type b = z.infer<typeof b>;
|
||||
expectTypeOf<b>().toEqualTypeOf<{ nested: { a?: string | undefined } }>();
|
||||
});
|
||||
|
||||
test("generics with optional", () => {
|
||||
async function stripOuter<TData extends z.ZodType>(schema: TData, data: unknown) {
|
||||
return z
|
||||
.object({
|
||||
nested: schema.optional(),
|
||||
})
|
||||
.transform((data) => {
|
||||
return data.nested;
|
||||
})
|
||||
.parse({ nested: data });
|
||||
}
|
||||
|
||||
const result = stripOuter(z.object({ a: z.string() }), { a: "asdf" });
|
||||
expectTypeOf<typeof result>().toEqualTypeOf<Promise<{ a: string } | undefined>>();
|
||||
});
|
||||
|
||||
// test("assignability", () => {
|
||||
// const createSchemaAndParse = <K extends string, VS extends z.ZodString>(key: K, valueSchema: VS, data: unknown) => {
|
||||
// const schema = z.object({
|
||||
// [key]: valueSchema,
|
||||
// });
|
||||
// // return { [key]: valueSchema };
|
||||
// const parsed = schema.parse(data);
|
||||
// return parsed;
|
||||
// // const inferred: z.infer<z.ZodObject<{ [k in K]: VS }>> = parsed;
|
||||
// // return inferred;
|
||||
// };
|
||||
// const parsed = createSchemaAndParse("foo", z.string(), { foo: "" });
|
||||
// expectTypeOf<typeof parsed>().toEqualTypeOf<{ foo: string }>();
|
||||
// });
|
||||
|
||||
test("nested no undefined", () => {
|
||||
const inner = z.string().or(z.array(z.string()));
|
||||
const outer = z.object({ inner });
|
||||
type outerSchema = z.infer<typeof outer>;
|
||||
expectTypeOf<outerSchema>().toEqualTypeOf<{ inner: string | string[] }>();
|
||||
|
||||
expect(outer.safeParse({ inner: undefined }).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("generic on output type", () => {
|
||||
const createV4Schema = <Output>(opts: {
|
||||
schema: z.ZodType<Output>;
|
||||
}) => {
|
||||
return opts.schema;
|
||||
};
|
||||
|
||||
createV4Schema({
|
||||
schema: z.object({
|
||||
name: z.string(),
|
||||
}),
|
||||
})?._zod?.output?.name;
|
||||
});
|
||||
829
frontend/node_modules/zod/src/v4/classic/tests/index.test.ts
generated
vendored
Normal file
829
frontend/node_modules/zod/src/v4/classic/tests/index.test.ts
generated
vendored
Normal file
@ -0,0 +1,829 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
import type { util } from "zod/v4/core";
|
||||
|
||||
test("z.boolean", () => {
|
||||
const a = z.boolean();
|
||||
expect(z.parse(a, true)).toEqual(true);
|
||||
expect(z.parse(a, false)).toEqual(false);
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
expect(() => z.parse(a, "true")).toThrow();
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<boolean>();
|
||||
});
|
||||
|
||||
test("z.bigint", () => {
|
||||
const a = z.bigint();
|
||||
expect(z.parse(a, BigInt(123))).toEqual(BigInt(123));
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
expect(() => z.parse(a, "123")).toThrow();
|
||||
});
|
||||
|
||||
test("z.symbol", () => {
|
||||
const a = z.symbol();
|
||||
const sym = Symbol();
|
||||
expect(z.parse(a, sym)).toEqual(sym);
|
||||
expect(() => z.parse(a, "symbol")).toThrow();
|
||||
});
|
||||
|
||||
test("z.date", () => {
|
||||
const a = z.date();
|
||||
const date = new Date();
|
||||
expect(z.parse(a, date)).toEqual(date);
|
||||
expect(() => z.parse(a, "date")).toThrow();
|
||||
});
|
||||
|
||||
test("z.coerce.string", () => {
|
||||
const a = z.coerce.string();
|
||||
expect(z.parse(a, 123)).toEqual("123");
|
||||
expect(z.parse(a, true)).toEqual("true");
|
||||
expect(z.parse(a, null)).toEqual("null");
|
||||
expect(z.parse(a, undefined)).toEqual("undefined");
|
||||
});
|
||||
|
||||
test("z.coerce.number", () => {
|
||||
const a = z.coerce.number();
|
||||
expect(z.parse(a, "123")).toEqual(123);
|
||||
expect(z.parse(a, "123.45")).toEqual(123.45);
|
||||
expect(z.parse(a, true)).toEqual(1);
|
||||
expect(z.parse(a, false)).toEqual(0);
|
||||
expect(() => z.parse(a, "abc")).toThrow();
|
||||
});
|
||||
|
||||
test("z.coerce.boolean", () => {
|
||||
const a = z.coerce.boolean();
|
||||
// test booleans
|
||||
expect(z.parse(a, true)).toEqual(true);
|
||||
expect(z.parse(a, false)).toEqual(false);
|
||||
expect(z.parse(a, "true")).toEqual(true);
|
||||
expect(z.parse(a, "false")).toEqual(true);
|
||||
expect(z.parse(a, 1)).toEqual(true);
|
||||
expect(z.parse(a, 0)).toEqual(false);
|
||||
expect(z.parse(a, {})).toEqual(true);
|
||||
expect(z.parse(a, [])).toEqual(true);
|
||||
expect(z.parse(a, undefined)).toEqual(false);
|
||||
expect(z.parse(a, null)).toEqual(false);
|
||||
expect(z.parse(a, "")).toEqual(false);
|
||||
});
|
||||
|
||||
test("z.coerce.bigint", () => {
|
||||
const a = z.coerce.bigint();
|
||||
expect(z.parse(a, "123")).toEqual(BigInt(123));
|
||||
expect(z.parse(a, 123)).toEqual(BigInt(123));
|
||||
expect(() => z.parse(a, "abc")).toThrow();
|
||||
});
|
||||
|
||||
test("z.coerce.date", () => {
|
||||
const a = z.coerce.date();
|
||||
const date = new Date();
|
||||
expect(z.parse(a, date.toISOString())).toEqual(date);
|
||||
expect(z.parse(a, date.getTime())).toEqual(date);
|
||||
expect(() => z.parse(a, "invalid date")).toThrow();
|
||||
});
|
||||
|
||||
test("z.iso.datetime", () => {
|
||||
const d1 = "2021-01-01T00:00:00Z";
|
||||
const d2 = "2021-01-01T00:00:00.123Z";
|
||||
const d3 = "2021-01-01T00:00:00";
|
||||
const d4 = "2021-01-01T00:00:00+07:00";
|
||||
const d5 = "bad data";
|
||||
|
||||
// local: false, offset: false, precision: null
|
||||
const a = z.iso.datetime();
|
||||
expect(z.safeParse(a, d1).success).toEqual(true);
|
||||
expect(z.safeParse(a, d2).success).toEqual(true);
|
||||
expect(z.safeParse(a, d3).success).toEqual(false);
|
||||
expect(z.safeParse(a, d4).success).toEqual(false);
|
||||
expect(z.safeParse(a, d5).success).toEqual(false);
|
||||
|
||||
const b = z.iso.datetime({ local: true });
|
||||
expect(z.safeParse(b, d1).success).toEqual(true);
|
||||
expect(z.safeParse(b, d2).success).toEqual(true);
|
||||
expect(z.safeParse(b, d3).success).toEqual(true);
|
||||
expect(z.safeParse(b, d4).success).toEqual(false);
|
||||
expect(z.safeParse(b, d5).success).toEqual(false);
|
||||
|
||||
const c = z.iso.datetime({ offset: true });
|
||||
expect(z.safeParse(c, d1).success).toEqual(true);
|
||||
expect(z.safeParse(c, d2).success).toEqual(true);
|
||||
expect(z.safeParse(c, d3).success).toEqual(false);
|
||||
expect(z.safeParse(c, d4).success).toEqual(true);
|
||||
expect(z.safeParse(c, d5).success).toEqual(false);
|
||||
|
||||
const d = z.iso.datetime({ precision: 3 });
|
||||
expect(z.safeParse(d, d1).success).toEqual(false);
|
||||
expect(z.safeParse(d, d2).success).toEqual(true);
|
||||
expect(z.safeParse(d, d3).success).toEqual(false);
|
||||
expect(z.safeParse(d, d4).success).toEqual(false);
|
||||
expect(z.safeParse(d, d5).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("z.iso.date", () => {
|
||||
const d1 = "2021-01-01";
|
||||
const d2 = "bad data";
|
||||
|
||||
const a = z.iso.date();
|
||||
expect(z.safeParse(a, d1).success).toEqual(true);
|
||||
expect(z.safeParse(a, d2).success).toEqual(false);
|
||||
|
||||
const b = z.string().check(z.iso.date());
|
||||
expect(z.safeParse(b, d1).success).toEqual(true);
|
||||
expect(z.safeParse(b, d2).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("z.iso.time", () => {
|
||||
const d1 = "00:00:00";
|
||||
const d2 = "00:00:00.123";
|
||||
const d3 = "bad data";
|
||||
|
||||
const a = z.iso.time();
|
||||
expect(z.safeParse(a, d1).success).toEqual(true);
|
||||
expect(z.safeParse(a, d2).success).toEqual(true);
|
||||
expect(z.safeParse(a, d3).success).toEqual(false);
|
||||
|
||||
const b = z.iso.time({ precision: 3 });
|
||||
expect(z.safeParse(b, d1).success).toEqual(false);
|
||||
expect(z.safeParse(b, d2).success).toEqual(true);
|
||||
expect(z.safeParse(b, d3).success).toEqual(false);
|
||||
|
||||
const c = z.string().check(z.iso.time());
|
||||
expect(z.safeParse(c, d1).success).toEqual(true);
|
||||
expect(z.safeParse(c, d2).success).toEqual(true);
|
||||
expect(z.safeParse(c, d3).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("z.iso.duration", () => {
|
||||
const d1 = "P3Y6M4DT12H30M5S";
|
||||
const d2 = "bad data";
|
||||
|
||||
const a = z.iso.duration();
|
||||
expect(z.safeParse(a, d1).success).toEqual(true);
|
||||
expect(z.safeParse(a, d2).success).toEqual(false);
|
||||
|
||||
const b = z.string().check(z.iso.duration());
|
||||
expect(z.safeParse(b, d1).success).toEqual(true);
|
||||
expect(z.safeParse(b, d2).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("z.undefined", () => {
|
||||
const a = z.undefined();
|
||||
expect(z.parse(a, undefined)).toEqual(undefined);
|
||||
expect(() => z.parse(a, "undefined")).toThrow();
|
||||
});
|
||||
|
||||
test("z.null", () => {
|
||||
const a = z.null();
|
||||
expect(z.parse(a, null)).toEqual(null);
|
||||
expect(() => z.parse(a, "null")).toThrow();
|
||||
});
|
||||
|
||||
test("z.any", () => {
|
||||
const a = z.any();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, 123)).toEqual(123);
|
||||
expect(z.parse(a, true)).toEqual(true);
|
||||
expect(z.parse(a, null)).toEqual(null);
|
||||
expect(z.parse(a, undefined)).toEqual(undefined);
|
||||
z.parse(a, {});
|
||||
z.parse(a, []);
|
||||
z.parse(a, Symbol());
|
||||
z.parse(a, new Date());
|
||||
});
|
||||
|
||||
test("z.unknown", () => {
|
||||
const a = z.unknown();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, 123)).toEqual(123);
|
||||
expect(z.parse(a, true)).toEqual(true);
|
||||
expect(z.parse(a, null)).toEqual(null);
|
||||
expect(z.parse(a, undefined)).toEqual(undefined);
|
||||
z.parse(a, {});
|
||||
z.parse(a, []);
|
||||
z.parse(a, Symbol());
|
||||
z.parse(a, new Date());
|
||||
});
|
||||
|
||||
test("z.never", () => {
|
||||
const a = z.never();
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
});
|
||||
|
||||
test("z.void", () => {
|
||||
const a = z.void();
|
||||
expect(z.parse(a, undefined)).toEqual(undefined);
|
||||
expect(() => z.parse(a, null)).toThrow();
|
||||
});
|
||||
|
||||
test("z.array", () => {
|
||||
const a = z.array(z.string());
|
||||
expect(z.parse(a, ["hello", "world"])).toEqual(["hello", "world"]);
|
||||
expect(() => z.parse(a, [123])).toThrow();
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
});
|
||||
|
||||
test("z.union", () => {
|
||||
const a = z.union([z.string(), z.number()]);
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, 123)).toEqual(123);
|
||||
expect(() => z.parse(a, true)).toThrow();
|
||||
});
|
||||
|
||||
test("z.intersection", () => {
|
||||
const a = z.intersection(z.object({ a: z.string() }), z.object({ b: z.number() }));
|
||||
expect(z.parse(a, { a: "hello", b: 123 })).toEqual({ a: "hello", b: 123 });
|
||||
expect(() => z.parse(a, { a: "hello" })).toThrow();
|
||||
expect(() => z.parse(a, { b: 123 })).toThrow();
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
});
|
||||
|
||||
test("z.tuple", () => {
|
||||
const a = z.tuple([z.string(), z.number()]);
|
||||
expect(z.parse(a, ["hello", 123])).toEqual(["hello", 123]);
|
||||
expect(() => z.parse(a, ["hello", "world"])).toThrow();
|
||||
expect(() => z.parse(a, [123, 456])).toThrow();
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
|
||||
// tuple with rest
|
||||
const b = z.tuple([z.string(), z.number(), z.optional(z.string())], z.boolean());
|
||||
type b = z.output<typeof b>;
|
||||
|
||||
expectTypeOf<b>().toEqualTypeOf<[string, number, string?, ...boolean[]]>();
|
||||
const datas = [
|
||||
["hello", 123],
|
||||
["hello", 123, "world"],
|
||||
["hello", 123, "world", true],
|
||||
["hello", 123, "world", true, false, true],
|
||||
];
|
||||
for (const data of datas) {
|
||||
expect(z.parse(b, data)).toEqual(data);
|
||||
}
|
||||
|
||||
expect(() => z.parse(b, ["hello", 123, 123])).toThrow();
|
||||
expect(() => z.parse(b, ["hello", 123, "world", 123])).toThrow();
|
||||
|
||||
// tuple with readonly args
|
||||
const cArgs = [z.string(), z.number(), z.optional(z.string())] as const;
|
||||
const c = z.tuple(cArgs, z.boolean());
|
||||
type c = z.output<typeof c>;
|
||||
expectTypeOf<c>().toEqualTypeOf<[string, number, string?, ...boolean[]]>();
|
||||
// type c = z.output<typeof c>;
|
||||
});
|
||||
|
||||
test("z.record", () => {
|
||||
// record schema with enum keys
|
||||
const a = z.record(z.string(), z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<Record<string, string>>();
|
||||
|
||||
const b = z.record(z.union([z.string(), z.number(), z.symbol()]), z.string());
|
||||
type b = z.output<typeof b>;
|
||||
expectTypeOf<b>().toEqualTypeOf<Record<string | number | symbol, string>>();
|
||||
expect(z.parse(b, { a: "hello", 1: "world", [Symbol.for("asdf")]: "symbol" })).toEqual({
|
||||
a: "hello",
|
||||
1: "world",
|
||||
[Symbol.for("asdf")]: "symbol",
|
||||
});
|
||||
|
||||
// enum keys
|
||||
const c = z.record(z.enum(["a", "b", "c"]), z.string());
|
||||
type c = z.output<typeof c>;
|
||||
expectTypeOf<c>().toEqualTypeOf<Record<"a" | "b" | "c", string>>();
|
||||
expect(z.parse(c, { a: "hello", b: "world", c: "world" })).toEqual({
|
||||
a: "hello",
|
||||
b: "world",
|
||||
c: "world",
|
||||
});
|
||||
// missing keys
|
||||
expect(() => z.parse(c, { a: "hello", b: "world" })).toThrow();
|
||||
// extra keys
|
||||
expect(() => z.parse(c, { a: "hello", b: "world", c: "world", d: "world" })).toThrow();
|
||||
|
||||
// partial enum
|
||||
const d = z.record(z.enum(["a", "b"]).or(z.never()), z.string());
|
||||
type d = z.output<typeof d>;
|
||||
expectTypeOf<d>().toEqualTypeOf<Record<"a" | "b", string>>();
|
||||
});
|
||||
|
||||
test("z.map", () => {
|
||||
const a = z.map(z.string(), z.number());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<Map<string, number>>();
|
||||
expect(z.parse(a, new Map([["hello", 123]]))).toEqual(new Map([["hello", 123]]));
|
||||
expect(() => z.parse(a, new Map([["hello", "world"]]))).toThrow();
|
||||
expect(() => z.parse(a, new Map([[1243, "world"]]))).toThrow();
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
|
||||
const r1 = z.safeParse(a, new Map([[123, 123]]));
|
||||
expect(r1.error?.issues[0].code).toEqual("invalid_type");
|
||||
expect(r1.error?.issues[0].path).toEqual([123]);
|
||||
|
||||
const r2: any = z.safeParse(a, new Map([[BigInt(123), 123]]));
|
||||
expect(r2.error!.issues[0].code).toEqual("invalid_key");
|
||||
expect(r2.error!.issues[0].path).toEqual([]);
|
||||
|
||||
const r3: any = z.safeParse(a, new Map([["hello", "world"]]));
|
||||
expect(r3.error!.issues[0].code).toEqual("invalid_type");
|
||||
expect(r3.error!.issues[0].path).toEqual(["hello"]);
|
||||
});
|
||||
|
||||
test("z.map invalid_element", () => {
|
||||
const a = z.map(z.bigint(), z.number());
|
||||
const r1 = z.safeParse(a, new Map([[BigInt(123), BigInt(123)]]));
|
||||
|
||||
expect(r1.error!.issues[0].code).toEqual("invalid_element");
|
||||
expect(r1.error!.issues[0].path).toEqual([]);
|
||||
});
|
||||
|
||||
test("z.map async", async () => {
|
||||
const a = z.map(z.string().check(z.refine(async () => true)), z.number().check(z.refine(async () => true)));
|
||||
const d1 = new Map([["hello", 123]]);
|
||||
expect(await z.parseAsync(a, d1)).toEqual(d1);
|
||||
|
||||
await expect(z.parseAsync(a, new Map([[123, 123]]))).rejects.toThrow();
|
||||
await expect(z.parseAsync(a, new Map([["hi", "world"]]))).rejects.toThrow();
|
||||
await expect(z.parseAsync(a, new Map([[1243, "world"]]))).rejects.toThrow();
|
||||
await expect(z.parseAsync(a, "hello")).rejects.toThrow();
|
||||
|
||||
const r = await z.safeParseAsync(a, new Map([[123, 123]]));
|
||||
expect(r.success).toEqual(false);
|
||||
expect(r.error!.issues[0].code).toEqual("invalid_type");
|
||||
expect(r.error!.issues[0].path).toEqual([123]);
|
||||
});
|
||||
|
||||
test("z.set", () => {
|
||||
const a = z.set(z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<Set<string>>();
|
||||
expect(z.parse(a, new Set(["hello", "world"]))).toEqual(new Set(["hello", "world"]));
|
||||
expect(() => z.parse(a, new Set([123]))).toThrow();
|
||||
expect(() => z.parse(a, ["hello", "world"])).toThrow();
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
|
||||
const b = z.set(z.number());
|
||||
expect(z.parse(b, new Set([1, 2, 3]))).toEqual(new Set([1, 2, 3]));
|
||||
expect(() => z.parse(b, new Set(["hello"]))).toThrow();
|
||||
expect(() => z.parse(b, [1, 2, 3])).toThrow();
|
||||
expect(() => z.parse(b, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.enum", () => {
|
||||
const a = z.enum(["A", "B", "C"]);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<"A" | "B" | "C">();
|
||||
expect(z.parse(a, "A")).toEqual("A");
|
||||
expect(z.parse(a, "B")).toEqual("B");
|
||||
expect(z.parse(a, "C")).toEqual("C");
|
||||
expect(() => z.parse(a, "D")).toThrow();
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
|
||||
expect(a.enum.A).toEqual("A");
|
||||
expect(a.enum.B).toEqual("B");
|
||||
expect(a.enum.C).toEqual("C");
|
||||
expect((a.enum as any).D).toEqual(undefined);
|
||||
});
|
||||
|
||||
test("z.enum - native", () => {
|
||||
enum NativeEnum {
|
||||
A = "A",
|
||||
B = "B",
|
||||
C = "C",
|
||||
}
|
||||
const a = z.enum(NativeEnum);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<NativeEnum>();
|
||||
expect(z.parse(a, NativeEnum.A)).toEqual(NativeEnum.A);
|
||||
expect(z.parse(a, NativeEnum.B)).toEqual(NativeEnum.B);
|
||||
expect(z.parse(a, NativeEnum.C)).toEqual(NativeEnum.C);
|
||||
expect(() => z.parse(a, "D")).toThrow();
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
|
||||
// test a.enum
|
||||
a;
|
||||
expect(a.enum.A).toEqual(NativeEnum.A);
|
||||
expect(a.enum.B).toEqual(NativeEnum.B);
|
||||
expect(a.enum.C).toEqual(NativeEnum.C);
|
||||
});
|
||||
|
||||
test("z.nativeEnum", () => {
|
||||
enum NativeEnum {
|
||||
A = "A",
|
||||
B = "B",
|
||||
C = "C",
|
||||
}
|
||||
const a = z.nativeEnum(NativeEnum);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<NativeEnum>();
|
||||
expect(z.parse(a, NativeEnum.A)).toEqual(NativeEnum.A);
|
||||
expect(z.parse(a, NativeEnum.B)).toEqual(NativeEnum.B);
|
||||
expect(z.parse(a, NativeEnum.C)).toEqual(NativeEnum.C);
|
||||
expect(() => z.parse(a, "D")).toThrow();
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
|
||||
// test a.enum
|
||||
a;
|
||||
expect(a.enum.A).toEqual(NativeEnum.A);
|
||||
expect(a.enum.B).toEqual(NativeEnum.B);
|
||||
expect(a.enum.C).toEqual(NativeEnum.C);
|
||||
});
|
||||
|
||||
test("z.literal", () => {
|
||||
const a = z.literal("hello");
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<"hello">();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(() => z.parse(a, "world")).toThrow();
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.file", () => {
|
||||
const a = z.file();
|
||||
const file = new File(["content"], "filename.txt", { type: "text/plain" });
|
||||
expect(z.parse(a, file)).toEqual(file);
|
||||
expect(() => z.parse(a, "file")).toThrow();
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.transform", () => {
|
||||
const a = z.pipe(
|
||||
z.string(),
|
||||
z.transform((val) => val.toUpperCase())
|
||||
);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
expect(z.parse(a, "hello")).toEqual("HELLO");
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.transform async", async () => {
|
||||
const a = z.pipe(
|
||||
z.string(),
|
||||
z.transform(async (val) => val.toUpperCase())
|
||||
);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
expect(await z.parseAsync(a, "hello")).toEqual("HELLO");
|
||||
await expect(() => z.parseAsync(a, 123)).rejects.toThrow();
|
||||
});
|
||||
|
||||
test("z.preprocess", () => {
|
||||
const a = z.pipe(
|
||||
z.transform((val) => String(val).toUpperCase()),
|
||||
z.string()
|
||||
);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
expect(z.parse(a, 123)).toEqual("123");
|
||||
expect(z.parse(a, true)).toEqual("TRUE");
|
||||
expect(z.parse(a, BigInt(1234))).toEqual("1234");
|
||||
// expect(() => z.parse(a, Symbol("asdf"))).toThrow();
|
||||
});
|
||||
|
||||
// test("z.preprocess async", () => {
|
||||
// const a = z.preprocess(async (val) => String(val), z.string());
|
||||
// type a = z.output<typeof a>;
|
||||
// expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
// expect(z.parse(a, 123)).toEqual("123");
|
||||
// expect(z.parse(a, true)).toEqual("true");
|
||||
// expect(() => z.parse(a, {})).toThrow();
|
||||
// });
|
||||
|
||||
test("z.optional", () => {
|
||||
const a = z.optional(z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string | undefined>();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, undefined)).toEqual(undefined);
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.nullable", () => {
|
||||
const a = z.nullable(z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string | null>();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, null)).toEqual(null);
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.default", () => {
|
||||
const a = z._default(z.string(), "default");
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
expect(z.parse(a, undefined)).toEqual("default");
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
|
||||
const b = z._default(z.string(), () => "default");
|
||||
expect(z.parse(b, undefined)).toEqual("default");
|
||||
expect(z.parse(b, "hello")).toEqual("hello");
|
||||
expect(() => z.parse(b, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.catch", () => {
|
||||
const a = z.catch(z.string(), "default");
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, 123)).toEqual("default");
|
||||
|
||||
const b = z.catch(z.string(), () => "default");
|
||||
expect(z.parse(b, "hello")).toEqual("hello");
|
||||
expect(z.parse(b, 123)).toEqual("default");
|
||||
|
||||
const c = z.catch(z.string(), (ctx) => {
|
||||
return `${ctx.error.issues.length}issues`;
|
||||
});
|
||||
expect(z.parse(c, 1234)).toEqual("1issues");
|
||||
});
|
||||
|
||||
test("z.nan", () => {
|
||||
const a = z.nan();
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<number>();
|
||||
expect(z.parse(a, Number.NaN)).toEqual(Number.NaN);
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
expect(() => z.parse(a, "NaN")).toThrow();
|
||||
});
|
||||
|
||||
test("z.pipe", () => {
|
||||
const a = z.pipe(
|
||||
z.pipe(
|
||||
z.string(),
|
||||
z.transform((val) => val.length)
|
||||
),
|
||||
z.number()
|
||||
);
|
||||
type a_in = z.input<typeof a>;
|
||||
expectTypeOf<a_in>().toEqualTypeOf<string>();
|
||||
type a_out = z.output<typeof a>;
|
||||
expectTypeOf<a_out>().toEqualTypeOf<number>();
|
||||
|
||||
expect(z.parse(a, "123")).toEqual(3);
|
||||
expect(z.parse(a, "hello")).toEqual(5);
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.readonly", () => {
|
||||
const a = z.readonly(z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<Readonly<string>>();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.templateLiteral", () => {
|
||||
const a = z.templateLiteral([z.string(), z.number()]);
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<`${string}${number}`>();
|
||||
expect(z.parse(a, "hello123")).toEqual("hello123");
|
||||
expect(() => z.parse(a, "hello")).toThrow();
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
|
||||
// multipart
|
||||
const b = z.templateLiteral([z.string(), z.number(), z.string()]);
|
||||
type b = z.output<typeof b>;
|
||||
expectTypeOf<b>().toEqualTypeOf<`${string}${number}${string}`>();
|
||||
expect(z.parse(b, "hello123world")).toEqual("hello123world");
|
||||
expect(z.parse(b, "123")).toEqual("123");
|
||||
expect(() => z.parse(b, "hello")).toThrow();
|
||||
expect(() => z.parse(b, 123)).toThrow();
|
||||
|
||||
// include boolean
|
||||
const c = z.templateLiteral([z.string(), z.boolean()]);
|
||||
type c = z.output<typeof c>;
|
||||
expectTypeOf<c>().toEqualTypeOf<`${string}${boolean}`>();
|
||||
expect(z.parse(c, "hellotrue")).toEqual("hellotrue");
|
||||
expect(z.parse(c, "hellofalse")).toEqual("hellofalse");
|
||||
expect(() => z.parse(c, "hello")).toThrow();
|
||||
expect(() => z.parse(c, 123)).toThrow();
|
||||
|
||||
// include literal prefix
|
||||
const d = z.templateLiteral([z.literal("hello"), z.number()]);
|
||||
type d = z.output<typeof d>;
|
||||
expectTypeOf<d>().toEqualTypeOf<`hello${number}`>();
|
||||
expect(z.parse(d, "hello123")).toEqual("hello123");
|
||||
expect(() => z.parse(d, 123)).toThrow();
|
||||
expect(() => z.parse(d, "world123")).toThrow();
|
||||
|
||||
// include literal union
|
||||
const e = z.templateLiteral([z.literal(["aa", "bb"]), z.number()]);
|
||||
type e = z.output<typeof e>;
|
||||
expectTypeOf<e>().toEqualTypeOf<`aa${number}` | `bb${number}`>();
|
||||
expect(z.parse(e, "aa123")).toEqual("aa123");
|
||||
expect(z.parse(e, "bb123")).toEqual("bb123");
|
||||
expect(() => z.parse(e, "cc123")).toThrow();
|
||||
expect(() => z.parse(e, 123)).toThrow();
|
||||
});
|
||||
|
||||
// this returns both a schema and a check
|
||||
test("z.custom schema", () => {
|
||||
const a = z.custom((val) => {
|
||||
return typeof val === "string";
|
||||
});
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
test("z.custom check", () => {
|
||||
// @ts-expect-error Inference not possible, use z.refine()
|
||||
z.date().check(z.custom((val) => val.getTime() > 0));
|
||||
});
|
||||
|
||||
test("z.check", () => {
|
||||
// this is a more flexible version of z.custom that accepts an arbitrary _parse logic
|
||||
// the function should return base.$ZodResult
|
||||
const a = z.any().check(
|
||||
z.check<string>((ctx) => {
|
||||
if (typeof ctx.value === "string") return;
|
||||
ctx.issues.push({
|
||||
code: "custom",
|
||||
origin: "custom",
|
||||
message: "Expected a string",
|
||||
input: ctx.value,
|
||||
});
|
||||
})
|
||||
);
|
||||
expect(z.safeParse(a, "hello")).toMatchObject({
|
||||
success: true,
|
||||
data: "hello",
|
||||
});
|
||||
expect(z.safeParse(a, 123)).toMatchObject({
|
||||
success: false,
|
||||
error: { issues: [{ code: "custom", message: "Expected a string" }] },
|
||||
});
|
||||
});
|
||||
|
||||
test("z.instanceof", () => {
|
||||
class A {}
|
||||
|
||||
const a = z.instanceof(A);
|
||||
expect(z.parse(a, new A())).toBeInstanceOf(A);
|
||||
expect(() => z.parse(a, {})).toThrow();
|
||||
});
|
||||
|
||||
test("z.refine", () => {
|
||||
const a = z.number().check(
|
||||
z.refine((val) => val > 3),
|
||||
z.refine((val) => val < 10)
|
||||
);
|
||||
expect(z.parse(a, 5)).toEqual(5);
|
||||
expect(() => z.parse(a, 2)).toThrow();
|
||||
expect(() => z.parse(a, 11)).toThrow();
|
||||
expect(() => z.parse(a, "hi")).toThrow();
|
||||
});
|
||||
|
||||
// test("z.superRefine", () => {
|
||||
// const a = z.number([
|
||||
// z.superRefine((val, ctx) => {
|
||||
// if (val < 3) {
|
||||
// return ctx.addIssue({
|
||||
// code: "custom",
|
||||
// origin: "custom",
|
||||
// message: "Too small",
|
||||
// input: val,
|
||||
// });
|
||||
// }
|
||||
// if (val > 10) {
|
||||
// return ctx.addIssue("Too big");
|
||||
// }
|
||||
// }),
|
||||
// ]);
|
||||
|
||||
// expect(z.parse(a, 5)).toEqual(5);
|
||||
// expect(() => z.parse(a, 2)).toThrow();
|
||||
// expect(() => z.parse(a, 11)).toThrow();
|
||||
// expect(() => z.parse(a, "hi")).toThrow();
|
||||
// });
|
||||
|
||||
test("z.transform", () => {
|
||||
const a = z.transform((val: number) => {
|
||||
return `${val}`;
|
||||
});
|
||||
type a_in = z.input<typeof a>;
|
||||
expectTypeOf<a_in>().toEqualTypeOf<number>();
|
||||
type a_out = z.output<typeof a>;
|
||||
expectTypeOf<a_out>().toEqualTypeOf<string>();
|
||||
expect(z.parse(a, 123)).toEqual("123");
|
||||
});
|
||||
|
||||
test("z.$brand()", () => {
|
||||
const a = z.string().brand<"my-brand">();
|
||||
type a = z.output<typeof a>;
|
||||
const branded = (_: a) => {};
|
||||
// @ts-expect-error
|
||||
branded("asdf");
|
||||
});
|
||||
|
||||
test("z.lazy", () => {
|
||||
const a = z.lazy(() => z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(() => z.parse(a, 123)).toThrow();
|
||||
});
|
||||
|
||||
// schema that validates JSON-like data
|
||||
test("z.json", () => {
|
||||
const a = z.json();
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<util.JSONType>();
|
||||
|
||||
expect(z.parse(a, "hello")).toEqual("hello");
|
||||
expect(z.parse(a, 123)).toEqual(123);
|
||||
expect(z.parse(a, true)).toEqual(true);
|
||||
expect(z.parse(a, null)).toEqual(null);
|
||||
expect(z.parse(a, {})).toEqual({});
|
||||
expect(z.parse(a, { a: "hello" })).toEqual({ a: "hello" });
|
||||
expect(z.parse(a, [1, 2, 3])).toEqual([1, 2, 3]);
|
||||
expect(z.parse(a, [{ a: "hello" }])).toEqual([{ a: "hello" }]);
|
||||
|
||||
// fail cases
|
||||
expect(() => z.parse(a, new Date())).toThrow();
|
||||
expect(() => z.parse(a, Symbol())).toThrow();
|
||||
expect(() => z.parse(a, { a: new Date() })).toThrow();
|
||||
expect(() => z.parse(a, undefined)).toThrow();
|
||||
expect(() => z.parse(a, { a: undefined })).toThrow();
|
||||
});
|
||||
|
||||
// promise
|
||||
test("z.promise", async () => {
|
||||
const a = z.promise(z.string());
|
||||
type a = z.output<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<string>();
|
||||
|
||||
expect(await z.safeParseAsync(a, Promise.resolve("hello"))).toMatchObject({
|
||||
success: true,
|
||||
data: "hello",
|
||||
});
|
||||
expect(await z.safeParseAsync(a, Promise.resolve(123))).toMatchObject({
|
||||
success: false,
|
||||
});
|
||||
|
||||
const b = z.string();
|
||||
expect(() => z.parse(b, Promise.resolve("hello"))).toThrow();
|
||||
});
|
||||
// test("type assertions", () => {
|
||||
// const schema = z.pipe(
|
||||
// z.string(),
|
||||
// z.transform((val) => val.length)
|
||||
// );
|
||||
// schema.assertInput<string>();
|
||||
// // @ts-expect-error
|
||||
// schema.assertInput<number>();
|
||||
|
||||
// schema.assertOutput<number>();
|
||||
// // @ts-expect-error
|
||||
// schema.assertOutput<string>();
|
||||
// });
|
||||
|
||||
test("isPlainObject", () => {
|
||||
expect(z.core.util.isPlainObject({})).toEqual(true);
|
||||
expect(z.core.util.isPlainObject(Object.create(null))).toEqual(true);
|
||||
expect(z.core.util.isPlainObject([])).toEqual(false);
|
||||
expect(z.core.util.isPlainObject(new Date())).toEqual(false);
|
||||
expect(z.core.util.isPlainObject(null)).toEqual(false);
|
||||
expect(z.core.util.isPlainObject(undefined)).toEqual(false);
|
||||
expect(z.core.util.isPlainObject("string")).toEqual(false);
|
||||
expect(z.core.util.isPlainObject(123)).toEqual(false);
|
||||
expect(z.core.util.isPlainObject(Symbol())).toEqual(false);
|
||||
});
|
||||
|
||||
test("def typing", () => {
|
||||
z.string().def.type satisfies "string";
|
||||
z.number().def.type satisfies "number";
|
||||
z.bigint().def.type satisfies "bigint";
|
||||
z.boolean().def.type satisfies "boolean";
|
||||
z.date().def.type satisfies "date";
|
||||
z.symbol().def.type satisfies "symbol";
|
||||
z.undefined().def.type satisfies "undefined";
|
||||
z.string().nullable().def.type satisfies "nullable";
|
||||
z.null().def.type satisfies "null";
|
||||
z.any().def.type satisfies "any";
|
||||
z.unknown().def.type satisfies "unknown";
|
||||
z.never().def.type satisfies "never";
|
||||
z.void().def.type satisfies "void";
|
||||
z.array(z.string()).def.type satisfies "array";
|
||||
z.object({ key: z.string() }).def.type satisfies "object";
|
||||
z.union([z.string(), z.number()]).def.type satisfies "union";
|
||||
z.intersection(z.string(), z.number()).def.type satisfies "intersection";
|
||||
z.tuple([z.string(), z.number()]).def.type satisfies "tuple";
|
||||
z.record(z.string(), z.number()).def.type satisfies "record";
|
||||
z.map(z.string(), z.number()).def.type satisfies "map";
|
||||
z.set(z.string()).def.type satisfies "set";
|
||||
z.literal("example").def.type satisfies "literal";
|
||||
z.enum(["a", "b", "c"]).def.type satisfies "enum";
|
||||
z.promise(z.string()).def.type satisfies "promise";
|
||||
z.lazy(() => z.string()).def.type satisfies "lazy";
|
||||
z.string().optional().def.type satisfies "optional";
|
||||
z.string().default("default").def.type satisfies "default";
|
||||
z.templateLiteral([z.literal("a"), z.literal("b")]).def.type satisfies "template_literal";
|
||||
z.custom<string>((val) => typeof val === "string").def.type satisfies "custom";
|
||||
z.transform((val) => val as string).def.type satisfies "transform";
|
||||
z.string().optional().nonoptional().def.type satisfies "nonoptional";
|
||||
z.object({ key: z.string() }).readonly().def.type satisfies "readonly";
|
||||
z.nan().def.type satisfies "nan";
|
||||
z.unknown().pipe(z.number()).def.type satisfies "pipe";
|
||||
z.success(z.string()).def.type satisfies "success";
|
||||
z.string().catch("fallback").def.type satisfies "catch";
|
||||
z.file().def.type satisfies "file";
|
||||
});
|
||||
34
frontend/node_modules/zod/src/v4/classic/tests/instanceof.test.ts
generated
vendored
Normal file
34
frontend/node_modules/zod/src/v4/classic/tests/instanceof.test.ts
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("instanceof", async () => {
|
||||
class Test {}
|
||||
class Subtest extends Test {}
|
||||
abstract class AbstractBar {
|
||||
constructor(public val: string) {}
|
||||
}
|
||||
class Bar extends AbstractBar {}
|
||||
|
||||
const TestSchema = z.instanceof(Test);
|
||||
const SubtestSchema = z.instanceof(Subtest);
|
||||
const AbstractSchema = z.instanceof(AbstractBar);
|
||||
const BarSchema = z.instanceof(Bar);
|
||||
|
||||
TestSchema.parse(new Test());
|
||||
TestSchema.parse(new Subtest());
|
||||
SubtestSchema.parse(new Subtest());
|
||||
AbstractSchema.parse(new Bar("asdf"));
|
||||
const bar = BarSchema.parse(new Bar("asdf"));
|
||||
expect(bar.val).toEqual("asdf");
|
||||
|
||||
await expect(() => SubtestSchema.parse(new Test())).toThrow();
|
||||
await expect(() => TestSchema.parse(12)).toThrow();
|
||||
|
||||
expectTypeOf<Test>().toEqualTypeOf<z.infer<typeof TestSchema>>();
|
||||
});
|
||||
|
||||
test("instanceof fatal", () => {
|
||||
const schema = z.instanceof(Date).refine((d) => d.toString());
|
||||
const res = schema.safeParse(null);
|
||||
expect(res.success).toBe(false);
|
||||
});
|
||||
171
frontend/node_modules/zod/src/v4/classic/tests/intersection.test.ts
generated
vendored
Normal file
171
frontend/node_modules/zod/src/v4/classic/tests/intersection.test.ts
generated
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import type { util } from "zod/v4/core";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("object intersection", () => {
|
||||
const A = z.object({ a: z.string() });
|
||||
const B = z.object({ b: z.string() });
|
||||
|
||||
const C = z.intersection(A, B); // BaseC.merge(HasID);
|
||||
type C = z.infer<typeof C>;
|
||||
expectTypeOf<C>().toEqualTypeOf<{ a: string } & { b: string }>();
|
||||
const data = { a: "foo", b: "foo" };
|
||||
expect(C.parse(data)).toEqual(data);
|
||||
expect(() => C.parse({ a: "foo" })).toThrow();
|
||||
});
|
||||
|
||||
test("object intersection: loose", () => {
|
||||
const A = z.looseObject({ a: z.string() });
|
||||
const B = z.object({ b: z.string() });
|
||||
|
||||
const C = z.intersection(A, B); // BaseC.merge(HasID);
|
||||
type C = z.infer<typeof C>;
|
||||
expectTypeOf<C>().toEqualTypeOf<{ a: string; [x: string]: unknown } & { b: string }>();
|
||||
const data = { a: "foo", b: "foo", c: "extra" };
|
||||
expect(C.parse(data)).toEqual(data);
|
||||
expect(() => C.parse({ a: "foo" })).toThrow();
|
||||
});
|
||||
|
||||
test("object intersection: strict", () => {
|
||||
const A = z.strictObject({ a: z.string() });
|
||||
const B = z.object({ b: z.string() });
|
||||
|
||||
const C = z.intersection(A, B); // BaseC.merge(HasID);
|
||||
type C = z.infer<typeof C>;
|
||||
expectTypeOf<C>().toEqualTypeOf<{ a: string } & { b: string }>();
|
||||
const data = { a: "foo", b: "foo", c: "extra" };
|
||||
|
||||
const result = C.safeParse(data);
|
||||
expect(result.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("deep intersection", () => {
|
||||
const Animal = z.object({
|
||||
properties: z.object({
|
||||
is_animal: z.boolean(),
|
||||
}),
|
||||
});
|
||||
const Cat = z.intersection(
|
||||
z.object({
|
||||
properties: z.object({
|
||||
jumped: z.boolean(),
|
||||
}),
|
||||
}),
|
||||
Animal
|
||||
);
|
||||
|
||||
type Cat = util.Flatten<z.infer<typeof Cat>>;
|
||||
expectTypeOf<Cat>().toEqualTypeOf<{ properties: { is_animal: boolean } & { jumped: boolean } }>();
|
||||
const a = Cat.safeParse({ properties: { is_animal: true, jumped: true } });
|
||||
expect(a.data!.properties).toEqual({ is_animal: true, jumped: true });
|
||||
});
|
||||
|
||||
test("deep intersection of arrays", async () => {
|
||||
const Author = z.object({
|
||||
posts: z.array(
|
||||
z.object({
|
||||
post_id: z.number(),
|
||||
})
|
||||
),
|
||||
});
|
||||
const Registry = z.intersection(
|
||||
Author,
|
||||
z.object({
|
||||
posts: z.array(
|
||||
z.object({
|
||||
title: z.string(),
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
const posts = [
|
||||
{ post_id: 1, title: "Novels" },
|
||||
{ post_id: 2, title: "Fairy tales" },
|
||||
];
|
||||
const cat = Registry.parse({ posts });
|
||||
expect(cat.posts).toEqual(posts);
|
||||
const asyncCat = await Registry.parseAsync({ posts });
|
||||
expect(asyncCat.posts).toEqual(posts);
|
||||
});
|
||||
|
||||
test("invalid intersection types", async () => {
|
||||
const numberIntersection = z.intersection(
|
||||
z.number(),
|
||||
z.number().transform((x) => x + 1)
|
||||
);
|
||||
|
||||
expect(() => {
|
||||
numberIntersection.parse(1234);
|
||||
}).toThrowErrorMatchingInlineSnapshot(`[Error: Unmergable intersection. Error path: []]`);
|
||||
});
|
||||
|
||||
test("invalid array merge (incompatible lengths)", async () => {
|
||||
const stringArrInt = z.intersection(
|
||||
z.string().array(),
|
||||
z
|
||||
.string()
|
||||
.array()
|
||||
.transform((val) => [...val, "asdf"])
|
||||
);
|
||||
|
||||
expect(() => stringArrInt.safeParse(["asdf", "qwer"])).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Unmergable intersection. Error path: []]`
|
||||
);
|
||||
});
|
||||
|
||||
test("invalid array merge (incompatible elements)", async () => {
|
||||
const stringArrInt = z.intersection(
|
||||
z.string().array(),
|
||||
z
|
||||
.string()
|
||||
.array()
|
||||
.transform((val) => [...val.slice(0, -1), "asdf"])
|
||||
);
|
||||
|
||||
expect(() => stringArrInt.safeParse(["asdf", "qwer"])).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Unmergable intersection. Error path: [1]]`
|
||||
);
|
||||
});
|
||||
|
||||
test("invalid object merge", async () => {
|
||||
const Cat = z.object({
|
||||
phrase: z.string().transform((val) => `${val} Meow`),
|
||||
});
|
||||
const Dog = z.object({
|
||||
phrase: z.string().transform((val) => `${val} Woof`),
|
||||
});
|
||||
const CatDog = z.intersection(Cat, Dog);
|
||||
|
||||
expect(() => CatDog.parse({ phrase: "Hello, my name is CatDog." })).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Unmergable intersection. Error path: ["phrase"]]`
|
||||
);
|
||||
});
|
||||
|
||||
test("invalid deep merge of object and array combination", async () => {
|
||||
const University = z.object({
|
||||
students: z.array(
|
||||
z.object({
|
||||
name: z.string().transform((val) => `Student name: ${val}`),
|
||||
})
|
||||
),
|
||||
});
|
||||
const Registry = z.intersection(
|
||||
University,
|
||||
z.object({
|
||||
students: z.array(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
surname: z.string(),
|
||||
})
|
||||
),
|
||||
})
|
||||
);
|
||||
|
||||
const students = [{ name: "John", surname: "Doe" }];
|
||||
|
||||
expect(() => Registry.parse({ students })).toThrowErrorMatchingInlineSnapshot(
|
||||
`[Error: Unmergable intersection. Error path: ["students",0,"name"]]`
|
||||
);
|
||||
});
|
||||
108
frontend/node_modules/zod/src/v4/classic/tests/json.test.ts
generated
vendored
Normal file
108
frontend/node_modules/zod/src/v4/classic/tests/json.test.ts
generated
vendored
Normal file
@ -0,0 +1,108 @@
|
||||
import { test } from "vitest";
|
||||
// import * as z from "zod/v4";
|
||||
|
||||
test(() => {});
|
||||
// test("overload types", () => {
|
||||
// const schema = z.string().json();
|
||||
// util.assertEqual<typeof schema, z.ZodString>(true);
|
||||
// const schema2 = z.string().json(z.number());
|
||||
// util.assertEqual<typeof schema2, z.ZodPipe<z.ZodTransform<any, string>, z.ZodNumber>>(true);
|
||||
// const r2 = schema2.parse("12");
|
||||
// util.assertEqual<number, typeof r2>(true);
|
||||
// });
|
||||
// test("parse string to json", async () => {
|
||||
// const Env = z.object({
|
||||
// myJsonConfig: z.string().jsonString(z.object({ foo: z.number() })),
|
||||
// someOtherValue: z.string(),
|
||||
// });
|
||||
|
||||
// expect(
|
||||
// Env.parse({
|
||||
// myJsonConfig: '{ "foo": 123 }',
|
||||
// someOtherValue: "abc",
|
||||
// })
|
||||
// ).toEqual({
|
||||
// myJsonConfig: { foo: 123 },
|
||||
// someOtherValue: "abc",
|
||||
// });
|
||||
|
||||
// const invalidValues = Env.safeParse({
|
||||
// myJsonConfig: '{"foo": "not a number!"}',
|
||||
// someOtherValue: null,
|
||||
// });
|
||||
// expect(JSON.parse(JSON.stringify(invalidValues))).toEqual({
|
||||
// success: false,
|
||||
// error: {
|
||||
// name: "ZodError",
|
||||
// issues: [
|
||||
// {
|
||||
// code: "invalid_type",
|
||||
// expected: "number",
|
||||
// input: "not a number!",
|
||||
// received: "string",
|
||||
// path: ["myJsonConfig", "foo"],
|
||||
// message: "Expected number, received string",
|
||||
// },
|
||||
// {
|
||||
// code: "invalid_type",
|
||||
// expected: "string",
|
||||
// input: null,
|
||||
// received: "null",
|
||||
// path: ["someOtherValue"],
|
||||
// message: "Expected string, received null",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// });
|
||||
|
||||
// const invalidJsonSyntax = Env.safeParse({
|
||||
// myJsonConfig: "This is not valid json",
|
||||
// someOtherValue: null,
|
||||
// });
|
||||
// expect(JSON.parse(JSON.stringify(invalidJsonSyntax))).toMatchObject({
|
||||
// success: false,
|
||||
// error: {
|
||||
// name: "ZodError",
|
||||
// issues: [
|
||||
// {
|
||||
// code: "invalid_string",
|
||||
// input: {
|
||||
// _def: {
|
||||
// catchall: {
|
||||
// _def: {
|
||||
// typeName: "ZodNever",
|
||||
// },
|
||||
// },
|
||||
// typeName: "ZodObject",
|
||||
// unknownKeys: "strip",
|
||||
// },
|
||||
// },
|
||||
// validation: "json",
|
||||
// message: "Invalid json",
|
||||
// path: ["myJsonConfig"],
|
||||
// },
|
||||
// {
|
||||
// code: "invalid_type",
|
||||
// expected: "string",
|
||||
// input: null,
|
||||
// received: "null",
|
||||
// path: ["someOtherValue"],
|
||||
// message: "Expected string, received null",
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
|
||||
// test("no argument", () => {
|
||||
// const schema = z.string().json();
|
||||
// util.assertEqual<typeof schema, z.ZodString>(true);
|
||||
// z.string().json().parse(`{}`);
|
||||
// z.string().json().parse(`null`);
|
||||
// z.string().json().parse(`12`);
|
||||
// z.string().json().parse(`{ "test": "test"}`);
|
||||
// expect(() => z.string().json().parse(`asdf`)).toThrow();
|
||||
// expect(() => z.string().json().parse(`{ "test": undefined }`)).toThrow();
|
||||
// expect(() => z.string().json().parse(`{ "test": 12n }`)).toThrow();
|
||||
// expect(() => z.string().json().parse(`{ test: "test" }`)).toThrow();
|
||||
// });
|
||||
227
frontend/node_modules/zod/src/v4/classic/tests/lazy.test.ts
generated
vendored
Normal file
227
frontend/node_modules/zod/src/v4/classic/tests/lazy.test.ts
generated
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("opt passthrough", () => {
|
||||
const object = z.object({
|
||||
a: z.lazy(() => z.string()),
|
||||
b: z.lazy(() => z.string().optional()),
|
||||
c: z.lazy(() => z.string().default("default")),
|
||||
});
|
||||
|
||||
type ObjectTypeIn = z.input<typeof object>;
|
||||
expectTypeOf<ObjectTypeIn>().toEqualTypeOf<{
|
||||
a: string;
|
||||
b?: string | undefined;
|
||||
c?: string | undefined;
|
||||
}>();
|
||||
|
||||
type ObjectTypeOut = z.output<typeof object>;
|
||||
expectTypeOf<ObjectTypeOut>().toEqualTypeOf<{
|
||||
a: string;
|
||||
b?: string | undefined;
|
||||
c: string;
|
||||
}>();
|
||||
|
||||
const result = object.parse(
|
||||
{
|
||||
a: "hello",
|
||||
b: undefined,
|
||||
},
|
||||
{ jitless: true }
|
||||
);
|
||||
expect(result).toEqual({
|
||||
a: "hello",
|
||||
// b: undefined,
|
||||
c: "default",
|
||||
});
|
||||
|
||||
expect(z.lazy(() => z.string())._zod.optin).toEqual(undefined);
|
||||
expect(z.lazy(() => z.string())._zod.optout).toEqual(undefined);
|
||||
|
||||
expect(z.lazy(() => z.string().optional())._zod.optin).toEqual("optional");
|
||||
expect(z.lazy(() => z.string().optional())._zod.optout).toEqual("optional");
|
||||
|
||||
expect(z.lazy(() => z.string().default("asdf"))._zod.optin).toEqual("optional");
|
||||
expect(z.lazy(() => z.string().default("asdf"))._zod.optout).toEqual(undefined);
|
||||
});
|
||||
|
||||
////////////// LAZY //////////////
|
||||
|
||||
test("schema getter", () => {
|
||||
z.lazy(() => z.string()).parse("asdf");
|
||||
});
|
||||
|
||||
test("lazy proxy", () => {
|
||||
const schema = z.lazy(() => z.string())._zod.innerType.min(6);
|
||||
schema.parse("123456");
|
||||
expect(schema.safeParse("12345").success).toBe(false);
|
||||
});
|
||||
|
||||
interface Category {
|
||||
name: string;
|
||||
subcategories: Category[];
|
||||
}
|
||||
|
||||
const testCategory: Category = {
|
||||
name: "I",
|
||||
subcategories: [
|
||||
{
|
||||
name: "A",
|
||||
subcategories: [
|
||||
{
|
||||
name: "1",
|
||||
subcategories: [
|
||||
{
|
||||
name: "a",
|
||||
subcategories: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
test("recursion with z.lazy", () => {
|
||||
const Category: z.ZodType<Category> = z.lazy(() =>
|
||||
z.object({
|
||||
name: z.string(),
|
||||
subcategories: z.array(Category),
|
||||
})
|
||||
);
|
||||
Category.parse(testCategory);
|
||||
});
|
||||
|
||||
type LinkedList = null | { value: number; next: LinkedList };
|
||||
|
||||
const linkedListExample = {
|
||||
value: 1,
|
||||
next: {
|
||||
value: 2,
|
||||
next: {
|
||||
value: 3,
|
||||
next: {
|
||||
value: 4,
|
||||
next: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
test("recursive union wit z.lazy", () => {
|
||||
const LinkedListSchema: z.ZodType<LinkedList> = z.lazy(() =>
|
||||
z.union([
|
||||
z.null(),
|
||||
z.object({
|
||||
value: z.number(),
|
||||
next: LinkedListSchema,
|
||||
}),
|
||||
])
|
||||
);
|
||||
LinkedListSchema.parse(linkedListExample);
|
||||
});
|
||||
|
||||
interface A {
|
||||
val: number;
|
||||
b: B;
|
||||
}
|
||||
|
||||
interface B {
|
||||
val: number;
|
||||
a?: A | undefined;
|
||||
}
|
||||
|
||||
test("mutual recursion with lazy", () => {
|
||||
const Alazy: z.ZodType<A> = z.lazy(() =>
|
||||
z.object({
|
||||
val: z.number(),
|
||||
b: Blazy,
|
||||
})
|
||||
);
|
||||
|
||||
const Blazy: z.ZodType<B> = z.lazy(() =>
|
||||
z.object({
|
||||
val: z.number(),
|
||||
a: Alazy.optional(),
|
||||
})
|
||||
);
|
||||
|
||||
const testData = {
|
||||
val: 1,
|
||||
b: {
|
||||
val: 5,
|
||||
a: {
|
||||
val: 3,
|
||||
b: {
|
||||
val: 4,
|
||||
a: {
|
||||
val: 2,
|
||||
b: {
|
||||
val: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Alazy.parse(testData);
|
||||
Blazy.parse(testData.b);
|
||||
|
||||
expect(() => Alazy.parse({ val: "asdf" })).toThrow();
|
||||
});
|
||||
|
||||
// TODO
|
||||
test("mutual recursion with cyclical data", () => {
|
||||
const a: any = { val: 1 };
|
||||
const b: any = { val: 2 };
|
||||
a.b = b;
|
||||
b.a = a;
|
||||
});
|
||||
|
||||
test("complicated self-recursion", () => {
|
||||
const Category = z.object({
|
||||
name: z.string(),
|
||||
age: z.optional(z.number()),
|
||||
get nullself() {
|
||||
return Category.nullable();
|
||||
},
|
||||
get optself() {
|
||||
return Category.optional();
|
||||
},
|
||||
get self() {
|
||||
return Category;
|
||||
},
|
||||
get subcategories() {
|
||||
return z.array(Category);
|
||||
},
|
||||
nested: z.object({
|
||||
get sub() {
|
||||
return Category;
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
type _Category = z.output<typeof Category>;
|
||||
});
|
||||
|
||||
test("lazy initialization", () => {
|
||||
const a: any = z.lazy(() => a).optional();
|
||||
const b: any = z.lazy(() => b).nullable();
|
||||
const c: any = z.lazy(() => c).default({} as any);
|
||||
const d: any = z.lazy(() => d).prefault({} as any);
|
||||
const e: any = z.lazy(() => e).nonoptional();
|
||||
const f: any = z.lazy(() => f).catch({} as any);
|
||||
const g: any = z.lazy(() => z.object({ g })).readonly();
|
||||
|
||||
const baseCategorySchema = z.object({
|
||||
name: z.string(),
|
||||
});
|
||||
type Category = z.infer<typeof baseCategorySchema> & {
|
||||
subcategories: Category[];
|
||||
};
|
||||
const categorySchema: z.ZodType<Category> = baseCategorySchema.extend({
|
||||
subcategories: z.lazy(() => categorySchema.array()),
|
||||
});
|
||||
});
|
||||
92
frontend/node_modules/zod/src/v4/classic/tests/literal.test.ts
generated
vendored
Normal file
92
frontend/node_modules/zod/src/v4/classic/tests/literal.test.ts
generated
vendored
Normal file
@ -0,0 +1,92 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const literalTuna = z.literal("tuna");
|
||||
const literalTunaCustomMessage = z.literal("tuna", {
|
||||
message: "That's not a tuna",
|
||||
});
|
||||
const literalFortyTwo = z.literal(42);
|
||||
const literalTrue = z.literal(true);
|
||||
|
||||
test("passing validations", () => {
|
||||
literalTuna.parse("tuna");
|
||||
literalFortyTwo.parse(42);
|
||||
literalTrue.parse(true);
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => literalTuna.parse("shark")).toThrow();
|
||||
expect(() => literalFortyTwo.parse(43)).toThrow();
|
||||
expect(() => literalTrue.parse(false)).toThrow();
|
||||
});
|
||||
|
||||
test("invalid_literal should have `input` field with data", () => {
|
||||
const data = "shark";
|
||||
const result = literalTuna.safeParse(data);
|
||||
|
||||
const issue = result.error!.issues[0];
|
||||
expect(issue.code).toBe("invalid_value");
|
||||
expect(issue).toMatchInlineSnapshot(`
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"message": "Invalid input: expected "tuna"",
|
||||
"path": [],
|
||||
"values": [
|
||||
"tuna",
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("invalid_literal should return default message", () => {
|
||||
const data = "shark";
|
||||
const result = literalTuna.safeParse(data);
|
||||
|
||||
const issue = result.error!.issues[0];
|
||||
expect(issue.message).toEqual(`Invalid input: expected \"tuna\"`);
|
||||
});
|
||||
|
||||
test("invalid_literal should return custom message", () => {
|
||||
const data = "shark";
|
||||
const result = literalTunaCustomMessage.safeParse(data);
|
||||
|
||||
const issue = result.error!.issues[0];
|
||||
expect(issue.message).toEqual(`That's not a tuna`);
|
||||
});
|
||||
|
||||
test("literal default error message", () => {
|
||||
const result = z.literal("Tuna").safeParse("Trout");
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_value",
|
||||
"values": [
|
||||
"Tuna"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Invalid input: expected \\"Tuna\\""
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("literal bigint default error message", () => {
|
||||
const result = z.literal(BigInt(12)).safeParse(BigInt(13));
|
||||
expect(result.success).toBe(false);
|
||||
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error!.issues[0].message).toEqual(`Invalid input: expected 12n`);
|
||||
});
|
||||
|
||||
test(".value getter", () => {
|
||||
expect(z.literal("tuna").value).toEqual("tuna");
|
||||
expect(() => z.literal([1, 2, 3]).value).toThrow();
|
||||
});
|
||||
|
||||
test("readonly", () => {
|
||||
const a = ["asdf"] as const;
|
||||
z.literal(a);
|
||||
});
|
||||
196
frontend/node_modules/zod/src/v4/classic/tests/map.test.ts
generated
vendored
Normal file
196
frontend/node_modules/zod/src/v4/classic/tests/map.test.ts
generated
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const stringMap = z.map(z.string(), z.string());
|
||||
type stringMap = z.infer<typeof stringMap>;
|
||||
|
||||
test("type inference", () => {
|
||||
expectTypeOf<stringMap>().toEqualTypeOf<Map<string, string>>();
|
||||
});
|
||||
|
||||
test("valid parse", () => {
|
||||
const result = stringMap.safeParse(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(true);
|
||||
expect(result.data).toMatchInlineSnapshot(`
|
||||
Map {
|
||||
"first" => "foo",
|
||||
"second" => "bar",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("valid parse async", async () => {
|
||||
const asyncMap = z.map(
|
||||
z.string().refine(async () => false, "bad key"),
|
||||
z.string().refine(async () => false, "bad value")
|
||||
);
|
||||
const result = await asyncMap.safeParseAsync(new Map([["first", "foo"]]));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"first"
|
||||
],
|
||||
"message": "bad key"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"first"
|
||||
],
|
||||
"message": "bad value"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("throws when a Set is given", () => {
|
||||
const result = stringMap.safeParse(new Set([]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
expect(result.error.issues[0].code).toEqual("invalid_type");
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when the given map has invalid key and invalid input", () => {
|
||||
const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
42
|
||||
],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
42
|
||||
],
|
||||
"message": "Invalid input: expected string, received symbol"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("throws when the given map has multiple invalid entries", () => {
|
||||
// const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
|
||||
const result = stringMap.safeParse(
|
||||
new Map([
|
||||
[1, "foo"],
|
||||
["bar", 2],
|
||||
] as [any, any][]) as Map<any, any>
|
||||
);
|
||||
|
||||
// const result = stringMap.safeParse(new Map([[42, Symbol()]]));
|
||||
expect(result.success).toEqual(false);
|
||||
if (result.success === false) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received number",
|
||||
"path": [
|
||||
1,
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received number",
|
||||
"path": [
|
||||
"bar",
|
||||
],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("dirty", async () => {
|
||||
const map = z.map(
|
||||
z.string().refine((val) => val === val.toUpperCase(), {
|
||||
message: "Keys must be uppercase",
|
||||
}),
|
||||
z.string()
|
||||
);
|
||||
const result = await map.spa(
|
||||
new Map([
|
||||
["first", "foo"],
|
||||
["second", "bar"],
|
||||
])
|
||||
);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"first"
|
||||
],
|
||||
"message": "Keys must be uppercase"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"second"
|
||||
],
|
||||
"message": "Keys must be uppercase"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("map with object keys", () => {
|
||||
const map = z.map(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
}),
|
||||
z.string()
|
||||
);
|
||||
const data = new Map([
|
||||
[{ name: "John", age: 30 }, "foo"],
|
||||
[{ name: "Jane", age: 25 }, "bar"],
|
||||
]);
|
||||
const result = map.safeParse(data);
|
||||
expect(result.success).toEqual(true);
|
||||
expect(result.data!).toEqual(data);
|
||||
|
||||
const badData = new Map([["bad", "foo"]]);
|
||||
const badResult = map.safeParse(badData);
|
||||
expect(badResult.success).toEqual(false);
|
||||
expect(badResult.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "object",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"bad"
|
||||
],
|
||||
"message": "Invalid input: expected object, received string"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
21
frontend/node_modules/zod/src/v4/classic/tests/nan.test.ts
generated
vendored
Normal file
21
frontend/node_modules/zod/src/v4/classic/tests/nan.test.ts
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const schema = z.nan();
|
||||
|
||||
test("passing validations", () => {
|
||||
schema.parse(Number.NaN);
|
||||
schema.parse(Number("Not a number"));
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<number>();
|
||||
});
|
||||
|
||||
test("failing validations", () => {
|
||||
expect(() => schema.parse(5)).toThrow();
|
||||
expect(() => schema.parse("John")).toThrow();
|
||||
expect(() => schema.parse(true)).toThrow();
|
||||
expect(() => schema.parse(null)).toThrow();
|
||||
expect(() => schema.parse(undefined)).toThrow();
|
||||
expect(() => schema.parse({})).toThrow();
|
||||
expect(() => schema.parse([])).toThrow();
|
||||
});
|
||||
168
frontend/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts
generated
vendored
Normal file
168
frontend/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts
generated
vendored
Normal file
@ -0,0 +1,168 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("nested refinements", () => {
|
||||
const zodSchema = z
|
||||
.object({
|
||||
password: z.string().min(1),
|
||||
nested: z
|
||||
.object({
|
||||
confirm: z
|
||||
.string()
|
||||
.min(1)
|
||||
.refine((value) => value.length > 2, {
|
||||
message: "Confirm length should be > 2",
|
||||
}),
|
||||
})
|
||||
.refine(
|
||||
(data) => {
|
||||
return data.confirm === "bar";
|
||||
},
|
||||
{
|
||||
path: ["confirm"],
|
||||
error: 'Value must be "bar"',
|
||||
}
|
||||
),
|
||||
})
|
||||
.refine(
|
||||
(data) => {
|
||||
return data.nested.confirm === data.password;
|
||||
},
|
||||
{
|
||||
path: ["nested", "confirm"],
|
||||
error: "Password and confirm must match",
|
||||
}
|
||||
);
|
||||
|
||||
const DATA = {
|
||||
password: "bar",
|
||||
nested: { confirm: "" },
|
||||
};
|
||||
expect(zodSchema.safeParse(DATA)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 1,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Too small: expected string to have >=1 characters"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Confirm length should be > 2"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Value must be \\"bar\\""
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Password and confirm must match"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(zodSchema.safeParse(DATA, { jitless: true })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 1,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Too small: expected string to have >=1 characters"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Confirm length should be > 2"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Value must be \\"bar\\""
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm"
|
||||
],
|
||||
"message": "Password and confirm must match"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(zodSchema["~standard"].validate(DATA)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"issues": [
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected string to have >=1 characters",
|
||||
"minimum": 1,
|
||||
"origin": "string",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Confirm length should be > 2",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Value must be "bar"",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm",
|
||||
],
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Password and confirm must match",
|
||||
"path": [
|
||||
"nested",
|
||||
"confirm",
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
86
frontend/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts
generated
vendored
Normal file
86
frontend/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
test("nonoptional", () => {
|
||||
const schema = z.string().nonoptional();
|
||||
expectTypeOf<typeof schema._input>().toEqualTypeOf<string>();
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<string>();
|
||||
|
||||
const result = schema.safeParse(undefined);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("nonoptional with default", () => {
|
||||
const schema = z.string().optional().nonoptional();
|
||||
expectTypeOf<typeof schema._input>().toEqualTypeOf<string>();
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<string>();
|
||||
|
||||
const result = schema.safeParse(undefined);
|
||||
expect(result.success).toBe(false);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "nonoptional",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected nonoptional, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("nonoptional in object", () => {
|
||||
const schema = z.object({ hi: z.string().optional().nonoptional() });
|
||||
|
||||
expectTypeOf<typeof schema._input>().toEqualTypeOf<{ hi: string }>();
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<{ hi: string }>();
|
||||
const r1 = schema.safeParse({ hi: "asdf" });
|
||||
expect(r1.success).toEqual(true);
|
||||
|
||||
const r2 = schema.safeParse({ hi: undefined });
|
||||
// expect(schema.safeParse({ hi: undefined }).success).toEqual(false);
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "nonoptional",
|
||||
"path": [
|
||||
"hi"
|
||||
],
|
||||
"message": "Invalid input: expected nonoptional, received undefined"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const r3 = schema.safeParse({});
|
||||
expect(r3.success).toEqual(false);
|
||||
expect(r3.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "nonoptional",
|
||||
"path": [
|
||||
"hi"
|
||||
],
|
||||
"message": "Invalid input: expected nonoptional, received undefined"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
22
frontend/node_modules/zod/src/v4/classic/tests/nullable.test.ts
generated
vendored
Normal file
22
frontend/node_modules/zod/src/v4/classic/tests/nullable.test.ts
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test(".nullable()", () => {
|
||||
const nullable = z.string().nullable();
|
||||
expect(nullable.parse(null)).toBe(null);
|
||||
expect(nullable.parse("asdf")).toBe("asdf");
|
||||
expect(() => nullable.parse(123)).toThrow();
|
||||
});
|
||||
|
||||
test(".nullable unwrap", () => {
|
||||
const schema = z.string().nullable();
|
||||
expect(schema).toBeInstanceOf(z.ZodNullable);
|
||||
expect(schema.unwrap()).toBeInstanceOf(z.ZodString);
|
||||
});
|
||||
|
||||
test("z.null", () => {
|
||||
const n = z.null();
|
||||
expect(n.parse(null)).toBe(null);
|
||||
expect(() => n.parse("asdf")).toThrow();
|
||||
});
|
||||
247
frontend/node_modules/zod/src/v4/classic/tests/number.test.ts
generated
vendored
Normal file
247
frontend/node_modules/zod/src/v4/classic/tests/number.test.ts
generated
vendored
Normal file
@ -0,0 +1,247 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("z.number() basic validation", () => {
|
||||
const schema = z.number();
|
||||
expect(schema.parse(1234)).toEqual(1234);
|
||||
});
|
||||
|
||||
test("NaN validation", () => {
|
||||
const schema = z.number();
|
||||
expect(() => schema.parse(Number.NaN)).toThrow();
|
||||
});
|
||||
|
||||
test("Infinity validation", () => {
|
||||
const schema = z.number();
|
||||
expect(schema.safeParse(Number.POSITIVE_INFINITY)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"received": "Infinity",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected number, received number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse(Number.NEGATIVE_INFINITY)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"received": "Infinity",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected number, received number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(".gt() validation", () => {
|
||||
const schema = z.number().gt(0).gt(5);
|
||||
expect(schema.parse(6)).toEqual(6);
|
||||
expect(() => schema.parse(5)).toThrow();
|
||||
});
|
||||
|
||||
test(".gte() validation", () => {
|
||||
const schema = z.number().gt(0).gte(1).gte(5);
|
||||
expect(schema.parse(5)).toEqual(5);
|
||||
expect(() => schema.parse(4)).toThrow();
|
||||
});
|
||||
|
||||
test(".min() validation", () => {
|
||||
const schema = z.number().min(0).min(5);
|
||||
expect(schema.parse(5)).toEqual(5);
|
||||
expect(() => schema.parse(4)).toThrow();
|
||||
});
|
||||
|
||||
test(".lt() validation", () => {
|
||||
const schema = z.number().lte(10).lt(5);
|
||||
expect(schema.parse(4)).toEqual(4);
|
||||
expect(() => schema.parse(5)).toThrow();
|
||||
});
|
||||
|
||||
test(".lte() validation", () => {
|
||||
const schema = z.number().lte(10).lte(5);
|
||||
expect(schema.parse(5)).toEqual(5);
|
||||
expect(() => schema.parse(6)).toThrow();
|
||||
});
|
||||
|
||||
test(".max() validation", () => {
|
||||
const schema = z.number().max(10).max(5);
|
||||
expect(schema.parse(5)).toEqual(5);
|
||||
expect(() => schema.parse(6)).toThrow();
|
||||
});
|
||||
|
||||
test(".int() validation", () => {
|
||||
const schema = z.number().int();
|
||||
expect(schema.parse(4)).toEqual(4);
|
||||
expect(() => schema.parse(3.14)).toThrow();
|
||||
});
|
||||
|
||||
test(".positive() validation", () => {
|
||||
const schema = z.number().positive();
|
||||
expect(schema.parse(1)).toEqual(1);
|
||||
expect(() => schema.parse(0)).toThrow();
|
||||
expect(() => schema.parse(-1)).toThrow();
|
||||
});
|
||||
|
||||
test(".negative() validation", () => {
|
||||
const schema = z.number().negative();
|
||||
expect(schema.parse(-1)).toEqual(-1);
|
||||
expect(() => schema.parse(0)).toThrow();
|
||||
expect(() => schema.parse(1)).toThrow();
|
||||
});
|
||||
|
||||
test(".nonpositive() validation", () => {
|
||||
const schema = z.number().nonpositive();
|
||||
expect(schema.parse(0)).toEqual(0);
|
||||
expect(schema.parse(-1)).toEqual(-1);
|
||||
expect(() => schema.parse(1)).toThrow();
|
||||
});
|
||||
|
||||
test(".nonnegative() validation", () => {
|
||||
const schema = z.number().nonnegative();
|
||||
expect(schema.parse(0)).toEqual(0);
|
||||
expect(schema.parse(1)).toEqual(1);
|
||||
expect(() => schema.parse(-1)).toThrow();
|
||||
});
|
||||
|
||||
test(".multipleOf() with positive divisor", () => {
|
||||
const schema = z.number().multipleOf(5);
|
||||
expect(schema.parse(15)).toEqual(15);
|
||||
expect(schema.parse(-15)).toEqual(-15);
|
||||
expect(() => schema.parse(7.5)).toThrow();
|
||||
expect(() => schema.parse(-7.5)).toThrow();
|
||||
});
|
||||
|
||||
test(".multipleOf() with negative divisor", () => {
|
||||
const schema = z.number().multipleOf(-5);
|
||||
expect(schema.parse(-15)).toEqual(-15);
|
||||
expect(schema.parse(15)).toEqual(15);
|
||||
expect(() => schema.parse(-7.5)).toThrow();
|
||||
expect(() => schema.parse(7.5)).toThrow();
|
||||
});
|
||||
|
||||
test(".step() validation", () => {
|
||||
const schemaPointOne = z.number().step(0.1);
|
||||
const schemaPointZeroZeroZeroOne = z.number().step(0.0001);
|
||||
const schemaSixPointFour = z.number().step(6.4);
|
||||
|
||||
expect(schemaPointOne.parse(6)).toEqual(6);
|
||||
expect(schemaPointOne.parse(6.1)).toEqual(6.1);
|
||||
expect(schemaSixPointFour.parse(12.8)).toEqual(12.8);
|
||||
expect(schemaPointZeroZeroZeroOne.parse(3.01)).toEqual(3.01);
|
||||
expect(() => schemaPointOne.parse(6.11)).toThrow();
|
||||
expect(() => schemaPointOne.parse(6.1000000001)).toThrow();
|
||||
expect(() => schemaSixPointFour.parse(6.41)).toThrow();
|
||||
});
|
||||
|
||||
test(".finite() validation", () => {
|
||||
const schema = z.number().finite();
|
||||
expect(schema.parse(123)).toEqual(123);
|
||||
expect(schema.safeParse(Number.POSITIVE_INFINITY)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"received": "Infinity",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected number, received number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse(Number.NEGATIVE_INFINITY)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"received": "Infinity",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected number, received number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(".safe() validation", () => {
|
||||
const schema = z.number().safe();
|
||||
expect(schema.parse(Number.MIN_SAFE_INTEGER)).toEqual(Number.MIN_SAFE_INTEGER);
|
||||
expect(schema.parse(Number.MAX_SAFE_INTEGER)).toEqual(Number.MAX_SAFE_INTEGER);
|
||||
expect(() => schema.parse(Number.MIN_SAFE_INTEGER - 1)).toThrow();
|
||||
expect(() => schema.parse(Number.MAX_SAFE_INTEGER + 1)).toThrow();
|
||||
});
|
||||
|
||||
test("min value getters", () => {
|
||||
expect(z.number().minValue).toBeNull;
|
||||
expect(z.number().lt(5).minValue).toBeNull;
|
||||
expect(z.number().lte(5).minValue).toBeNull;
|
||||
expect(z.number().max(5).minValue).toBeNull;
|
||||
expect(z.number().negative().minValue).toBeNull;
|
||||
expect(z.number().nonpositive().minValue).toBeNull;
|
||||
expect(z.number().int().minValue).toBeNull;
|
||||
expect(z.number().multipleOf(5).minValue).toBeNull;
|
||||
expect(z.number().finite().minValue).toBeNull;
|
||||
expect(z.number().gt(5).minValue).toEqual(5);
|
||||
expect(z.number().gte(5).minValue).toEqual(5);
|
||||
expect(z.number().min(5).minValue).toEqual(5);
|
||||
expect(z.number().min(5).min(10).minValue).toEqual(10);
|
||||
expect(z.number().positive().minValue).toEqual(0);
|
||||
expect(z.number().nonnegative().minValue).toEqual(0);
|
||||
expect(z.number().safe().minValue).toEqual(Number.MIN_SAFE_INTEGER);
|
||||
});
|
||||
|
||||
test("max value getters", () => {
|
||||
expect(z.number().maxValue).toBeNull;
|
||||
expect(z.number().gt(5).maxValue).toBeNull;
|
||||
expect(z.number().gte(5).maxValue).toBeNull;
|
||||
expect(z.number().min(5).maxValue).toBeNull;
|
||||
expect(z.number().positive().maxValue).toBeNull;
|
||||
expect(z.number().nonnegative().maxValue).toBeNull;
|
||||
expect(z.number().int().minValue).toBeNull;
|
||||
expect(z.number().multipleOf(5).minValue).toBeNull;
|
||||
expect(z.number().finite().minValue).toBeNull;
|
||||
expect(z.number().lt(5).maxValue).toEqual(5);
|
||||
expect(z.number().lte(5).maxValue).toEqual(5);
|
||||
expect(z.number().max(5).maxValue).toEqual(5);
|
||||
expect(z.number().max(5).max(1).maxValue).toEqual(1);
|
||||
expect(z.number().negative().maxValue).toEqual(0);
|
||||
expect(z.number().nonpositive().maxValue).toEqual(0);
|
||||
expect(z.number().safe().maxValue).toEqual(Number.MAX_SAFE_INTEGER);
|
||||
});
|
||||
|
||||
test("int getter", () => {
|
||||
expect(z.number().isInt).toEqual(false);
|
||||
expect(z.number().int().isInt).toEqual(true);
|
||||
expect(z.number().safe().isInt).toEqual(true);
|
||||
expect(z.number().multipleOf(5).isInt).toEqual(true);
|
||||
});
|
||||
|
||||
/** In Zod 4, number schemas don't accept infinite values. */
|
||||
test("finite getter", () => {
|
||||
expect(z.number().isFinite).toEqual(true);
|
||||
});
|
||||
|
||||
test("string format methods", () => {
|
||||
const a = z.int32().min(5);
|
||||
expect(a.parse(6)).toEqual(6);
|
||||
expect(() => a.parse(1)).toThrow();
|
||||
});
|
||||
|
||||
test("error customization", () => {
|
||||
z.number().gte(5, { error: (iss) => "Min: " + iss.minimum.valueOf() });
|
||||
z.number().lte(5, { error: (iss) => "Max: " + iss.maximum.valueOf() });
|
||||
});
|
||||
563
frontend/node_modules/zod/src/v4/classic/tests/object.test.ts
generated
vendored
Normal file
563
frontend/node_modules/zod/src/v4/classic/tests/object.test.ts
generated
vendored
Normal file
@ -0,0 +1,563 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
import * as core from "zod/v4/core";
|
||||
|
||||
const Test = z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().optional(),
|
||||
f3: z.string().nullable(),
|
||||
f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })),
|
||||
});
|
||||
|
||||
test("object type inference", () => {
|
||||
type TestType = {
|
||||
f1: number;
|
||||
f2?: string | undefined;
|
||||
f3: string | null;
|
||||
f4: { t: string | boolean }[];
|
||||
};
|
||||
|
||||
expectTypeOf<z.TypeOf<typeof Test>>().toEqualTypeOf<TestType>();
|
||||
});
|
||||
|
||||
test("unknown throw", () => {
|
||||
const asdf: unknown = 35;
|
||||
expect(() => Test.parse(asdf)).toThrow();
|
||||
});
|
||||
|
||||
test("shape() should return schema of particular key", () => {
|
||||
const f1Schema = Test.shape.f1;
|
||||
const f2Schema = Test.shape.f2;
|
||||
const f3Schema = Test.shape.f3;
|
||||
const f4Schema = Test.shape.f4;
|
||||
|
||||
expect(f1Schema).toBeInstanceOf(z.ZodNumber);
|
||||
expect(f2Schema).toBeInstanceOf(z.ZodOptional);
|
||||
expect(f3Schema).toBeInstanceOf(z.ZodNullable);
|
||||
expect(f4Schema).toBeInstanceOf(z.ZodArray);
|
||||
});
|
||||
|
||||
test("correct parsing", () => {
|
||||
Test.parse({
|
||||
f1: 12,
|
||||
f2: "string",
|
||||
f3: "string",
|
||||
f4: [
|
||||
{
|
||||
t: "string",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
Test.parse({
|
||||
f1: 12,
|
||||
f3: null,
|
||||
f4: [
|
||||
{
|
||||
t: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
test("nonstrict by default", () => {
|
||||
z.object({ points: z.number() }).parse({
|
||||
points: 2314,
|
||||
unknown: "asdf",
|
||||
});
|
||||
});
|
||||
|
||||
test("parse optional keys ", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().optional(),
|
||||
});
|
||||
expect(schema.parse({ a: "asdf" })).toEqual({ a: "asdf" });
|
||||
});
|
||||
|
||||
test("empty object", () => {
|
||||
const schema = z.object({});
|
||||
expect(schema.parse({})).toEqual({});
|
||||
expect(schema.parse({ name: "asdf" })).toEqual({});
|
||||
expect(schema.safeParse(null).success).toEqual(false);
|
||||
expect(schema.safeParse("asdf").success).toEqual(false);
|
||||
expectTypeOf<z.output<typeof schema>>().toEqualTypeOf<Record<string, never>>();
|
||||
});
|
||||
|
||||
const data = {
|
||||
points: 2314,
|
||||
unknown: "asdf",
|
||||
};
|
||||
|
||||
test("strip by default", () => {
|
||||
const val = z.object({ points: z.number() }).parse(data);
|
||||
expect(val).toEqual({ points: 2314 });
|
||||
});
|
||||
|
||||
test("unknownkeys override", () => {
|
||||
const val = z.object({ points: z.number() }).strict().passthrough().strip().passthrough().parse(data);
|
||||
|
||||
expect(val).toEqual(data);
|
||||
});
|
||||
|
||||
test("passthrough unknown", () => {
|
||||
const val = z.object({ points: z.number() }).passthrough().parse(data);
|
||||
|
||||
expect(val).toEqual(data);
|
||||
});
|
||||
|
||||
test("strip unknown", () => {
|
||||
const val = z.object({ points: z.number() }).strip().parse(data);
|
||||
|
||||
expect(val).toEqual({ points: 2314 });
|
||||
});
|
||||
|
||||
test("strict", () => {
|
||||
const val = z.object({ points: z.number() }).strict().safeParse(data);
|
||||
|
||||
expect(val.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("catchall inference", () => {
|
||||
const o1 = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
})
|
||||
.catchall(z.number());
|
||||
|
||||
const d1 = o1.parse({ first: "asdf", num: 1243 });
|
||||
// expectTypeOf<(typeof d1)["asdf"]>().toEqualTypeOf<number>();
|
||||
expectTypeOf<(typeof d1)["first"]>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("catchall overrides strict", () => {
|
||||
const o1 = z.object({ first: z.string().optional() }).strict().catchall(z.number());
|
||||
|
||||
// should run fine
|
||||
// setting a catchall overrides the unknownKeys behavior
|
||||
o1.parse({
|
||||
asdf: 1234,
|
||||
});
|
||||
|
||||
// should only run catchall validation
|
||||
// against unknown keys
|
||||
o1.parse({
|
||||
first: "asdf",
|
||||
asdf: 1234,
|
||||
});
|
||||
});
|
||||
|
||||
test("catchall overrides strict", () => {
|
||||
const o1 = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
})
|
||||
.strict()
|
||||
.catchall(z.number());
|
||||
|
||||
// should run fine
|
||||
// setting a catchall overrides the unknownKeys behavior
|
||||
o1.parse({
|
||||
first: "asdf",
|
||||
asdf: 1234,
|
||||
});
|
||||
});
|
||||
|
||||
test("optional keys are unset", async () => {
|
||||
const SNamedEntity = z.object({
|
||||
id: z.string(),
|
||||
set: z.string().optional(),
|
||||
unset: z.string().optional(),
|
||||
});
|
||||
const result = await SNamedEntity.parse({
|
||||
id: "asdf",
|
||||
set: undefined,
|
||||
});
|
||||
expect(Object.keys(result)).toEqual(["id", "set"]);
|
||||
});
|
||||
|
||||
test("catchall parsing", async () => {
|
||||
const result = z.object({ name: z.string() }).catchall(z.number()).parse({ name: "Foo", validExtraKey: 61 });
|
||||
|
||||
expect(result).toEqual({ name: "Foo", validExtraKey: 61 });
|
||||
|
||||
const result2 = z
|
||||
.object({ name: z.string() })
|
||||
.catchall(z.number())
|
||||
.safeParse({ name: "Foo", validExtraKey: 61, invalid: "asdf" });
|
||||
|
||||
expect(result2.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("nonexistent keys", async () => {
|
||||
const Schema = z.union([z.object({ a: z.string() }), z.object({ b: z.number() })]);
|
||||
const obj = { a: "A" };
|
||||
const result = await Schema.spa(obj); // Works with 1.11.10, breaks with 2.0.0-beta.21
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
test("test async union", async () => {
|
||||
const Schema2 = z.union([
|
||||
z.object({
|
||||
ty: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
ty: z.number(),
|
||||
}),
|
||||
]);
|
||||
|
||||
const obj = { ty: "A" };
|
||||
const result = await Schema2.spa(obj); // Works with 1.11.10, breaks with 2.0.0-beta.21
|
||||
expect(result.success).toEqual(true);
|
||||
});
|
||||
|
||||
test("test inferred merged type", async () => {
|
||||
const asdf = z.object({ a: z.string() }).merge(z.object({ a: z.number() }));
|
||||
type asdf = z.infer<typeof asdf>;
|
||||
|
||||
expectTypeOf<asdf>().toEqualTypeOf<{ a: number }>();
|
||||
});
|
||||
|
||||
test("inferred type with Record shape", () => {
|
||||
type A = z.ZodObject<Record<string, z.ZodType<string, number>>>;
|
||||
expectTypeOf<z.infer<A>>().toEqualTypeOf<Record<string, string>>();
|
||||
expectTypeOf<z.input<A>>().toEqualTypeOf<Record<string, number>>();
|
||||
|
||||
type B = z.ZodObject;
|
||||
expectTypeOf<z.infer<B>>().toEqualTypeOf<Record<string, unknown>>();
|
||||
expectTypeOf<z.input<B>>().toEqualTypeOf<Record<string, unknown>>();
|
||||
});
|
||||
|
||||
test("inferred merged object type with optional properties", async () => {
|
||||
const Merged = z
|
||||
.object({ a: z.string(), b: z.string().optional() })
|
||||
.merge(z.object({ a: z.string().optional(), b: z.string() }));
|
||||
type Merged = z.infer<typeof Merged>;
|
||||
expectTypeOf<Merged>().toEqualTypeOf<{ a?: string; b: string }>();
|
||||
expectTypeOf<Merged>().toEqualTypeOf<{ a?: string; b: string }>();
|
||||
});
|
||||
|
||||
test("inferred unioned object type with optional properties", async () => {
|
||||
const Unioned = z.union([
|
||||
z.object({ a: z.string(), b: z.string().optional() }),
|
||||
z.object({ a: z.string().optional(), b: z.string() }),
|
||||
]);
|
||||
type Unioned = z.infer<typeof Unioned>;
|
||||
expectTypeOf<Unioned>().toEqualTypeOf<{ a: string; b?: string } | { a?: string; b: string }>();
|
||||
});
|
||||
|
||||
test("inferred enum type", async () => {
|
||||
const Enum = z.object({ a: z.string(), b: z.string().optional() }).keyof();
|
||||
|
||||
expect(Enum.enum).toEqual({
|
||||
a: "a",
|
||||
b: "b",
|
||||
});
|
||||
|
||||
expect(Enum._zod.def.entries).toEqual({
|
||||
a: "a",
|
||||
b: "b",
|
||||
});
|
||||
type Enum = z.infer<typeof Enum>;
|
||||
expectTypeOf<Enum>().toEqualTypeOf<"a" | "b">();
|
||||
});
|
||||
|
||||
test("inferred partial object type with optional properties", async () => {
|
||||
const Partial = z.object({ a: z.string(), b: z.string().optional() }).partial();
|
||||
type Partial = z.infer<typeof Partial>;
|
||||
expectTypeOf<Partial>().toEqualTypeOf<{ a?: string; b?: string }>();
|
||||
});
|
||||
|
||||
test("inferred picked object type with optional properties", async () => {
|
||||
const Picked = z.object({ a: z.string(), b: z.string().optional() }).pick({ b: true });
|
||||
type Picked = z.infer<typeof Picked>;
|
||||
expectTypeOf<Picked>().toEqualTypeOf<{ b?: string }>();
|
||||
});
|
||||
|
||||
test("inferred type for unknown/any keys", () => {
|
||||
const myType = z.object({
|
||||
anyOptional: z.any().optional(),
|
||||
anyRequired: z.any(),
|
||||
unknownOptional: z.unknown().optional(),
|
||||
unknownRequired: z.unknown(),
|
||||
});
|
||||
type myType = z.infer<typeof myType>;
|
||||
expectTypeOf<myType>().toEqualTypeOf<{
|
||||
anyOptional?: any;
|
||||
anyRequired: any;
|
||||
unknownOptional?: unknown;
|
||||
unknownRequired: unknown;
|
||||
}>();
|
||||
});
|
||||
|
||||
test("strictObject", async () => {
|
||||
const strictObj = z.strictObject({
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
const syncResult = strictObj.safeParse({ name: "asdf", unexpected: 13 });
|
||||
expect(syncResult.success).toEqual(false);
|
||||
|
||||
const asyncResult = await strictObj.spa({ name: "asdf", unexpected: 13 });
|
||||
expect(asyncResult.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("object with refine", async () => {
|
||||
const schema = z
|
||||
.object({
|
||||
a: z.string().default("foo"),
|
||||
b: z.number(),
|
||||
})
|
||||
.refine(() => true);
|
||||
expect(schema.parse({ b: 5 })).toEqual({ b: 5, a: "foo" });
|
||||
const result = await schema.parseAsync({ b: 5 });
|
||||
expect(result).toEqual({ b: 5, a: "foo" });
|
||||
});
|
||||
|
||||
test("intersection of object with date", async () => {
|
||||
const schema = z.object({
|
||||
a: z.date(),
|
||||
});
|
||||
expect(z.intersection(schema, schema).parse({ a: new Date(1637353595983) })).toEqual({
|
||||
a: new Date(1637353595983),
|
||||
});
|
||||
const result = await schema.parseAsync({ a: new Date(1637353595983) });
|
||||
expect(result).toEqual({ a: new Date(1637353595983) });
|
||||
});
|
||||
|
||||
test("intersection of object with refine with date", async () => {
|
||||
const schema = z
|
||||
.object({
|
||||
a: z.date(),
|
||||
})
|
||||
.refine(() => true);
|
||||
expect(z.intersection(schema, schema).parse({ a: new Date(1637353595983) })).toEqual({
|
||||
a: new Date(1637353595983),
|
||||
});
|
||||
const result = await schema.parseAsync({ a: new Date(1637353595983) });
|
||||
expect(result).toEqual({ a: new Date(1637353595983) });
|
||||
});
|
||||
|
||||
test("constructor key", () => {
|
||||
const person = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
expect(() =>
|
||||
person.parse({
|
||||
name: "bob dylan",
|
||||
constructor: 61,
|
||||
})
|
||||
).toThrow();
|
||||
});
|
||||
|
||||
test("constructor key", () => {
|
||||
const Example = z.object({
|
||||
prop: z.string(),
|
||||
opt: z.number().optional(),
|
||||
arr: z.string().array(),
|
||||
});
|
||||
|
||||
type Example = z.infer<typeof Example>;
|
||||
expectTypeOf<keyof Example>().toEqualTypeOf<"prop" | "opt" | "arr">();
|
||||
});
|
||||
|
||||
test("catchall", () => {
|
||||
const a = z.object({});
|
||||
expect(a._zod.def.catchall).toBeUndefined();
|
||||
|
||||
const b = z.strictObject({});
|
||||
expect(b._zod.def.catchall).toBeInstanceOf(core.$ZodNever);
|
||||
|
||||
const c = z.looseObject({});
|
||||
expect(c._zod.def.catchall).toBeInstanceOf(core.$ZodUnknown);
|
||||
|
||||
const d = z.object({}).catchall(z.number());
|
||||
expect(d._zod.def.catchall).toBeInstanceOf(core.$ZodNumber);
|
||||
});
|
||||
|
||||
test("unknownkeys merging", () => {
|
||||
// This one is "strict"
|
||||
const a = z.looseObject({
|
||||
a: z.string(),
|
||||
});
|
||||
|
||||
const b = z.strictObject({ b: z.string() });
|
||||
|
||||
// incoming object overrides
|
||||
const c = a.merge(b);
|
||||
expect(c._zod.def.catchall).toBeInstanceOf(core.$ZodNever);
|
||||
});
|
||||
|
||||
const personToExtend = z.object({
|
||||
firstName: z.string(),
|
||||
lastName: z.string(),
|
||||
});
|
||||
|
||||
test("extend() should return schema with new key", () => {
|
||||
const PersonWithNickname = personToExtend.extend({ nickName: z.string() });
|
||||
type PersonWithNickname = z.infer<typeof PersonWithNickname>;
|
||||
|
||||
const expected = { firstName: "f", nickName: "n", lastName: "l" };
|
||||
const actual = PersonWithNickname.parse(expected);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
expectTypeOf<keyof PersonWithNickname>().toEqualTypeOf<"firstName" | "lastName" | "nickName">();
|
||||
expectTypeOf<PersonWithNickname>().toEqualTypeOf<{ firstName: string; lastName: string; nickName: string }>();
|
||||
});
|
||||
|
||||
test("extend() should have power to override existing key", () => {
|
||||
const PersonWithNumberAsLastName = personToExtend.extend({
|
||||
lastName: z.number(),
|
||||
});
|
||||
type PersonWithNumberAsLastName = z.infer<typeof PersonWithNumberAsLastName>;
|
||||
|
||||
const expected = { firstName: "f", lastName: 42 };
|
||||
const actual = PersonWithNumberAsLastName.parse(expected);
|
||||
|
||||
expect(actual).toEqual(expected);
|
||||
expectTypeOf<PersonWithNumberAsLastName>().toEqualTypeOf<{ firstName: string; lastName: number }>();
|
||||
});
|
||||
|
||||
test("passthrough index signature", () => {
|
||||
const a = z.object({ a: z.string() });
|
||||
type a = z.infer<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<{ a: string }>();
|
||||
const b = a.passthrough();
|
||||
type b = z.infer<typeof b>;
|
||||
expectTypeOf<b>().toEqualTypeOf<{ a: string; [k: string]: unknown }>();
|
||||
});
|
||||
|
||||
// test("xor", () => {
|
||||
// type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
|
||||
// type XOR<T, U> = T extends object ? (U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : U) : T;
|
||||
|
||||
// type A = { name: string; a: number };
|
||||
// type B = { name: string; b: number };
|
||||
// type C = XOR<A, B>;
|
||||
// type Outer = { data: C };
|
||||
// const Outer = z.object({
|
||||
// data: z.union([z.object({ name: z.string(), a: z.number() }), z.object({ name: z.string(), b: z.number() })]),
|
||||
// }) satisfies z.ZodType<Outer, any>;
|
||||
// });
|
||||
|
||||
test("assignability", () => {
|
||||
z.object({ a: z.string() }) satisfies z.ZodObject<{ a: z.ZodString }>;
|
||||
z.object({ a: z.string() }).catchall(z.number()) satisfies z.ZodObject<{ a: z.ZodString }>;
|
||||
z.object({ a: z.string() }).strict() satisfies z.ZodObject;
|
||||
z.object({}) satisfies z.ZodObject;
|
||||
|
||||
z.looseObject({ name: z.string() }) satisfies z.ZodObject<
|
||||
{
|
||||
name: z.ZodString;
|
||||
},
|
||||
z.core.$loose
|
||||
>;
|
||||
z.looseObject({ name: z.string() }) satisfies z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
}>;
|
||||
z.strictObject({ name: z.string() }) satisfies z.ZodObject<
|
||||
{
|
||||
name: z.ZodString;
|
||||
},
|
||||
z.core.$loose
|
||||
>;
|
||||
z.strictObject({ name: z.string() }) satisfies z.ZodObject<
|
||||
{
|
||||
name: z.ZodString;
|
||||
},
|
||||
z.core.$strict
|
||||
>;
|
||||
z.object({ name: z.string() }) satisfies z.ZodObject<{
|
||||
name: z.ZodString;
|
||||
}>;
|
||||
z.object({
|
||||
a: z.string(),
|
||||
b: z.number(),
|
||||
c: z.boolean(),
|
||||
}) satisfies z.core.$ZodObject;
|
||||
});
|
||||
|
||||
test("null prototype", () => {
|
||||
const schema = z.object({ a: z.string() });
|
||||
const obj = Object.create(null);
|
||||
obj.a = "foo";
|
||||
expect(schema.parse(obj)).toEqual({ a: "foo" });
|
||||
});
|
||||
|
||||
test("empty objects", () => {
|
||||
const A = z.looseObject({});
|
||||
type Ain = z.input<typeof A>;
|
||||
expectTypeOf<Ain>().toEqualTypeOf<Record<string, unknown>>();
|
||||
type Aout = z.output<typeof A>;
|
||||
expectTypeOf<Aout>().toEqualTypeOf<Record<string, unknown>>();
|
||||
|
||||
const B = z.object({});
|
||||
type Bout = z.output<typeof B>;
|
||||
expectTypeOf<Bout>().toEqualTypeOf<Record<string, never>>();
|
||||
type Bin = z.input<typeof B>;
|
||||
expectTypeOf<Bin>().toEqualTypeOf<Record<string, never>>();
|
||||
|
||||
const C = z.strictObject({});
|
||||
type Cout = z.output<typeof C>;
|
||||
expectTypeOf<Cout>().toEqualTypeOf<Record<string, never>>();
|
||||
type Cin = z.input<typeof C>;
|
||||
expectTypeOf<Cin>().toEqualTypeOf<Record<string, never>>();
|
||||
});
|
||||
|
||||
test("preserve key order", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().optional(),
|
||||
b: z.string(),
|
||||
});
|
||||
const r1 = schema.safeParse({ a: "asdf", b: "qwer" });
|
||||
const r2 = schema.safeParse({ a: "asdf", b: "qwer" }, { jitless: true });
|
||||
|
||||
expect(Object.keys(r1.data!)).toMatchInlineSnapshot(`
|
||||
[
|
||||
"a",
|
||||
"b",
|
||||
]
|
||||
`);
|
||||
expect(Object.keys(r1.data!)).toEqual(Object.keys(r2.data!));
|
||||
});
|
||||
|
||||
test("empty shape", () => {
|
||||
const a = z.object({});
|
||||
|
||||
a.parse({});
|
||||
a.parse({}, { jitless: true });
|
||||
a.parse(Object.create(null));
|
||||
a.parse(Object.create(null), { jitless: true });
|
||||
|
||||
expect(() => a.parse([])).toThrow();
|
||||
expect(() => a.parse([], { jitless: true })).toThrow();
|
||||
});
|
||||
|
||||
test("zodtype assignability", () => {
|
||||
// Does not error
|
||||
z.object({ hello: z.string().optional() }) satisfies z.ZodType<{ hello?: string | undefined }>;
|
||||
z.object({ hello: z.string() }) satisfies z.ZodType<{ hello?: string | undefined }>;
|
||||
// @ts-expect-error
|
||||
z.object({}) satisfies z.ZodType<{ hello: string | undefined }>;
|
||||
// @ts-expect-error
|
||||
z.object({ hello: z.string().optional() }) satisfies z.ZodType<{ hello: string | undefined }>;
|
||||
// @ts-expect-error
|
||||
z.object({ hello: z.string().optional() }) satisfies z.ZodType<{ hello: string }>;
|
||||
// @ts-expect-error
|
||||
z.object({ hello: z.number() }) satisfies z.ZodType<{ hello?: string | undefined }>;
|
||||
});
|
||||
|
||||
test("index signature in shape", () => {
|
||||
function makeZodObj<const T extends string>(key: T) {
|
||||
return z.looseObject({
|
||||
[key]: z.string(),
|
||||
});
|
||||
}
|
||||
|
||||
const schema = makeZodObj("foo");
|
||||
type schema = z.infer<typeof schema>;
|
||||
|
||||
expectTypeOf<schema>().toEqualTypeOf<Record<string, string>>();
|
||||
});
|
||||
123
frontend/node_modules/zod/src/v4/classic/tests/optional.test.ts
generated
vendored
Normal file
123
frontend/node_modules/zod/src/v4/classic/tests/optional.test.ts
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
// @ts-ignore TS6133
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test(".optional()", () => {
|
||||
const schema = z.string().optional();
|
||||
expect(schema.parse("adsf")).toEqual("adsf");
|
||||
expect(schema.parse(undefined)).toEqual(undefined);
|
||||
expect(schema.safeParse(null).success).toEqual(false);
|
||||
|
||||
expectTypeOf<typeof schema._output>().toEqualTypeOf<string | undefined>();
|
||||
});
|
||||
|
||||
test("unwrap", () => {
|
||||
const unwrapped = z.string().optional().unwrap();
|
||||
expect(unwrapped).toBeInstanceOf(z.ZodString);
|
||||
});
|
||||
|
||||
test("optionality", () => {
|
||||
const a = z.string();
|
||||
expect(a._zod.optin).toEqual(undefined);
|
||||
expect(a._zod.optout).toEqual(undefined);
|
||||
|
||||
const b = z.string().optional();
|
||||
expect(b._zod.optin).toEqual("optional");
|
||||
expect(b._zod.optout).toEqual("optional");
|
||||
|
||||
const c = z.string().default("asdf");
|
||||
expect(c._zod.optin).toEqual("optional");
|
||||
expect(c._zod.optout).toEqual(undefined);
|
||||
|
||||
const d = z.string().optional().nullable();
|
||||
expect(d._zod.optin).toEqual("optional");
|
||||
expect(d._zod.optout).toEqual("optional");
|
||||
|
||||
const e = z.string().default("asdf").nullable();
|
||||
expect(e._zod.optin).toEqual("optional");
|
||||
expect(e._zod.optout).toEqual(undefined);
|
||||
|
||||
// z.undefined should NOT be optional
|
||||
const f = z.undefined();
|
||||
expect(f._zod.optin).toEqual("optional");
|
||||
expect(f._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof f._zod.optin>().toEqualTypeOf<"optional" | undefined>();
|
||||
expectTypeOf<typeof f._zod.optout>().toEqualTypeOf<"optional" | undefined>();
|
||||
|
||||
// z.union should be optional if any of the types are optional
|
||||
const g = z.union([z.string(), z.undefined()]);
|
||||
expect(g._zod.optin).toEqual("optional");
|
||||
expect(g._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof g._zod.optin>().toEqualTypeOf<"optional" | undefined>();
|
||||
expectTypeOf<typeof g._zod.optout>().toEqualTypeOf<"optional" | undefined>();
|
||||
|
||||
const h = z.union([z.string(), z.optional(z.string())]);
|
||||
expect(h._zod.optin).toEqual("optional");
|
||||
expect(h._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof h._zod.optin>().toEqualTypeOf<"optional">();
|
||||
expectTypeOf<typeof h._zod.optout>().toEqualTypeOf<"optional">();
|
||||
});
|
||||
|
||||
test("pipe optionality", () => {
|
||||
z.string().optional()._zod.optin;
|
||||
const a = z.string().optional().pipe(z.string());
|
||||
expect(a._zod.optin).toEqual("optional");
|
||||
expect(a._zod.optout).toEqual(undefined);
|
||||
expectTypeOf<typeof a._zod.optin>().toEqualTypeOf<"optional">();
|
||||
expectTypeOf<typeof a._zod.optout>().toEqualTypeOf<"optional" | undefined>();
|
||||
|
||||
const b = z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().optional());
|
||||
expect(b._zod.optin).toEqual(undefined);
|
||||
expect(b._zod.optout).toEqual("optional");
|
||||
expectTypeOf<typeof b._zod.optin>().toEqualTypeOf<"optional" | undefined>();
|
||||
expectTypeOf<typeof b._zod.optout>().toEqualTypeOf<"optional">();
|
||||
|
||||
const c = z.string().default("asdf").pipe(z.string());
|
||||
expect(c._zod.optin).toEqual("optional");
|
||||
expect(c._zod.optout).toEqual(undefined);
|
||||
|
||||
const d = z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().default("asdf"));
|
||||
expect(d._zod.optin).toEqual(undefined);
|
||||
expect(d._zod.optout).toEqual(undefined);
|
||||
});
|
||||
|
||||
test("pipe optionality inside objects", () => {
|
||||
const schema = z.object({
|
||||
a: z.string().optional(),
|
||||
b: z.string().optional().pipe(z.string()),
|
||||
c: z.string().default("asdf").pipe(z.string()),
|
||||
d: z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().optional()),
|
||||
e: z
|
||||
.string()
|
||||
.transform((val) => (Math.random() ? val : undefined))
|
||||
.pipe(z.string().default("asdf")),
|
||||
});
|
||||
|
||||
type SchemaIn = z.input<typeof schema>;
|
||||
expectTypeOf<SchemaIn>().toEqualTypeOf<{
|
||||
a?: string | undefined;
|
||||
b?: string | undefined;
|
||||
c?: string | undefined;
|
||||
d: string;
|
||||
e: string;
|
||||
}>();
|
||||
|
||||
type SchemaOut = z.output<typeof schema>;
|
||||
expectTypeOf<SchemaOut>().toEqualTypeOf<{
|
||||
a?: string | undefined;
|
||||
b: string;
|
||||
c: string;
|
||||
d?: string | undefined;
|
||||
e: string;
|
||||
}>();
|
||||
});
|
||||
147
frontend/node_modules/zod/src/v4/classic/tests/partial.test.ts
generated
vendored
Normal file
147
frontend/node_modules/zod/src/v4/classic/tests/partial.test.ts
generated
vendored
Normal file
@ -0,0 +1,147 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const nested = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
outer: z.object({
|
||||
inner: z.string(),
|
||||
}),
|
||||
array: z.array(z.object({ asdf: z.string() })),
|
||||
});
|
||||
|
||||
test("shallow inference", () => {
|
||||
const shallow = nested.partial();
|
||||
type shallow = z.infer<typeof shallow>;
|
||||
|
||||
expectTypeOf<shallow>().toEqualTypeOf<{
|
||||
name?: string | undefined;
|
||||
age?: number | undefined;
|
||||
outer?: { inner: string } | undefined;
|
||||
array?: { asdf: string }[] | undefined;
|
||||
}>();
|
||||
});
|
||||
|
||||
test("shallow partial parse", () => {
|
||||
const shallow = nested.partial();
|
||||
shallow.parse({});
|
||||
shallow.parse({
|
||||
name: "asdf",
|
||||
age: 23143,
|
||||
});
|
||||
});
|
||||
|
||||
test("required", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
nullableField: z.number().nullable(),
|
||||
nullishField: z.string().nullish(),
|
||||
});
|
||||
|
||||
const requiredObject = object.required();
|
||||
expect(requiredObject.shape.name).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.name.unwrap()).toBeInstanceOf(z.ZodString);
|
||||
expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.age.unwrap()).toBeInstanceOf(z.ZodOptional);
|
||||
expect(requiredObject.shape.field).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.field.unwrap()).toBeInstanceOf(z.ZodDefault);
|
||||
expect(requiredObject.shape.nullableField).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.nullableField.unwrap()).toBeInstanceOf(z.ZodNullable);
|
||||
expect(requiredObject.shape.nullishField).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.nullishField.unwrap()).toBeInstanceOf(z.ZodOptional);
|
||||
expect(requiredObject.shape.nullishField.unwrap().unwrap()).toBeInstanceOf(z.ZodNullable);
|
||||
});
|
||||
|
||||
test("required inference", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
nullableField: z.number().nullable(),
|
||||
nullishField: z.string().nullish(),
|
||||
});
|
||||
|
||||
const requiredObject = object.required();
|
||||
|
||||
type required = z.infer<typeof requiredObject>;
|
||||
type expected = {
|
||||
name: string;
|
||||
age: number;
|
||||
field: string;
|
||||
nullableField: number | null;
|
||||
nullishField: string | null;
|
||||
};
|
||||
expectTypeOf<expected>().toEqualTypeOf<required>();
|
||||
});
|
||||
|
||||
test("required with mask", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string().optional(),
|
||||
});
|
||||
|
||||
const requiredObject = object.required({ age: true });
|
||||
expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString);
|
||||
expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional);
|
||||
});
|
||||
|
||||
test("required with mask -- ignore falsy values", () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string().optional(),
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
const requiredObject = object.required({ age: true, country: false });
|
||||
expect(requiredObject.shape.name).toBeInstanceOf(z.ZodString);
|
||||
expect(requiredObject.shape.age).toBeInstanceOf(z.ZodNonOptional);
|
||||
expect(requiredObject.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(requiredObject.shape.country).toBeInstanceOf(z.ZodOptional);
|
||||
});
|
||||
|
||||
test("partial with mask", async () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string(),
|
||||
});
|
||||
|
||||
const masked = object.partial({ age: true, field: true, name: true }).strict();
|
||||
|
||||
expect(masked.shape.name).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.age).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.field).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.country).toBeInstanceOf(z.ZodString);
|
||||
|
||||
masked.parse({ country: "US" });
|
||||
await masked.parseAsync({ country: "US" });
|
||||
});
|
||||
|
||||
test("partial with mask -- ignore falsy values", async () => {
|
||||
const object = z.object({
|
||||
name: z.string(),
|
||||
age: z.number().optional(),
|
||||
field: z.string().optional().default("asdf"),
|
||||
country: z.string(),
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
const masked = object.partial({ name: true, country: false }).strict();
|
||||
|
||||
expect(masked.shape.name).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.age).toBeInstanceOf(z.ZodOptional);
|
||||
expect(masked.shape.field).toBeInstanceOf(z.ZodDefault);
|
||||
expect(masked.shape.country).toBeInstanceOf(z.ZodString);
|
||||
|
||||
masked.parse({ country: "US" });
|
||||
await masked.parseAsync({ country: "US" });
|
||||
});
|
||||
127
frontend/node_modules/zod/src/v4/classic/tests/pickomit.test.ts
generated
vendored
Normal file
127
frontend/node_modules/zod/src/v4/classic/tests/pickomit.test.ts
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const fish = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
nested: z.object({}),
|
||||
});
|
||||
|
||||
test("pick type inference", () => {
|
||||
const nameonlyFish = fish.pick({ name: true });
|
||||
type nameonlyFish = z.infer<typeof nameonlyFish>;
|
||||
expectTypeOf<nameonlyFish>().toEqualTypeOf<{ name: string }>();
|
||||
});
|
||||
|
||||
test("pick parse - success", () => {
|
||||
const nameonlyFish = fish.pick({ name: true });
|
||||
nameonlyFish.parse({ name: "bob" });
|
||||
|
||||
// @ts-expect-error checking runtime picks `name` only.
|
||||
const anotherNameonlyFish = fish.pick({ name: true, age: false });
|
||||
anotherNameonlyFish.parse({ name: "bob" });
|
||||
});
|
||||
|
||||
test("pick parse - fail", () => {
|
||||
fish.pick({ name: true }).parse({ name: "12" } as any);
|
||||
fish.pick({ name: true }).parse({ name: "bob", age: 12 } as any);
|
||||
fish.pick({ age: true }).parse({ age: 12 } as any);
|
||||
|
||||
const nameonlyFish = fish.pick({ name: true }).strict();
|
||||
const bad1 = () => nameonlyFish.parse({ name: 12 } as any);
|
||||
const bad2 = () => nameonlyFish.parse({ name: "bob", age: 12 } as any);
|
||||
const bad3 = () => nameonlyFish.parse({ age: 12 } as any);
|
||||
|
||||
// @ts-expect-error checking runtime picks `name` only.
|
||||
const anotherNameonlyFish = fish.pick({ name: true, age: false }).strict();
|
||||
const bad4 = () => anotherNameonlyFish.parse({ name: "bob", age: 12 } as any);
|
||||
|
||||
expect(bad1).toThrow();
|
||||
expect(bad2).toThrow();
|
||||
expect(bad3).toThrow();
|
||||
expect(bad4).toThrow();
|
||||
});
|
||||
|
||||
test("pick - remove optional", () => {
|
||||
const schema = z.object({ a: z.string(), b: z.string().optional() });
|
||||
expect("a" in schema._zod.def.shape).toEqual(true);
|
||||
expect("b" in schema._zod.def.shape!).toEqual(true);
|
||||
const picked = schema.pick({ a: true });
|
||||
expect("a" in picked._zod.def.shape).toEqual(true);
|
||||
expect("b" in picked._zod.def.shape!).toEqual(false);
|
||||
});
|
||||
|
||||
test("omit type inference", () => {
|
||||
const nonameFish = fish.omit({ name: true });
|
||||
type nonameFish = z.infer<typeof nonameFish>;
|
||||
|
||||
expectTypeOf<nonameFish>().toEqualTypeOf<{ age: number; nested: Record<string, never> }>();
|
||||
});
|
||||
|
||||
test("omit parse - success", () => {
|
||||
const nonameFish = fish.omit({ name: true });
|
||||
nonameFish.parse({ age: 12, nested: {} });
|
||||
|
||||
// @ts-expect-error checking runtime omits `name` only.
|
||||
const anotherNonameFish = fish.omit({ name: true, age: false });
|
||||
anotherNonameFish.parse({ age: 12, nested: {} });
|
||||
});
|
||||
|
||||
test("omit parse - fail", () => {
|
||||
const nonameFish = fish.omit({ name: true });
|
||||
const bad1 = () => nonameFish.parse({ name: 12 } as any);
|
||||
const bad2 = () => nonameFish.parse({ age: 12 } as any);
|
||||
const bad3 = () => nonameFish.parse({} as any);
|
||||
|
||||
// @ts-expect-error checking runtime omits `name` only.
|
||||
const anotherNonameFish = fish.omit({ name: true, age: false });
|
||||
const bad4 = () => anotherNonameFish.parse({ nested: {} } as any);
|
||||
|
||||
expect(bad1).toThrow();
|
||||
expect(bad2).toThrow();
|
||||
expect(bad3).toThrow();
|
||||
expect(bad4).toThrow();
|
||||
});
|
||||
|
||||
test("omit - remove optional", () => {
|
||||
const schema = z.object({ a: z.string(), b: z.string().optional() });
|
||||
expect("a" in schema._zod.def.shape).toEqual(true);
|
||||
const omitted = schema.omit({ a: true });
|
||||
expect("a" in omitted._zod.def.shape).toEqual(false);
|
||||
});
|
||||
|
||||
test("nonstrict inference", () => {
|
||||
const laxfish = fish.pick({ name: true }).catchall(z.any());
|
||||
type laxfish = z.infer<typeof laxfish>;
|
||||
expectTypeOf<laxfish>().toEqualTypeOf<{ name: string; [k: string]: any }>();
|
||||
});
|
||||
|
||||
test("nonstrict parsing - pass", () => {
|
||||
const laxfish = fish.passthrough().pick({ name: true });
|
||||
laxfish.parse({ name: "asdf", whatever: "asdf" });
|
||||
laxfish.parse({ name: "asdf", age: 12, nested: {} });
|
||||
});
|
||||
|
||||
test("nonstrict parsing - fail", () => {
|
||||
const laxfish = fish.passthrough().pick({ name: true });
|
||||
const bad = () => laxfish.parse({ whatever: "asdf" } as any);
|
||||
expect(bad).toThrow();
|
||||
});
|
||||
|
||||
test("pick/omit/required/partial - do not allow unknown keys", () => {
|
||||
const schema = z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
});
|
||||
|
||||
expect(() => schema.pick({ name: true, asdf: true })).toThrow();
|
||||
|
||||
// @ts-expect-error
|
||||
expect(() => schema.pick({ $unknown: true })).toThrow();
|
||||
// @ts-expect-error
|
||||
expect(() => schema.omit({ $unknown: true })).toThrow();
|
||||
// @ts-expect-error
|
||||
expect(() => schema.required({ $unknown: true })).toThrow();
|
||||
// @ts-expect-error
|
||||
expect(() => schema.partial({ $unknown: true })).toThrow();
|
||||
});
|
||||
81
frontend/node_modules/zod/src/v4/classic/tests/pipe.test.ts
generated
vendored
Normal file
81
frontend/node_modules/zod/src/v4/classic/tests/pipe.test.ts
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("string to number pipe", () => {
|
||||
const schema = z.string().transform(Number).pipe(z.number());
|
||||
expect(schema.parse("1234")).toEqual(1234);
|
||||
});
|
||||
|
||||
test("string to number pipe async", async () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.transform(async (val) => Number(val))
|
||||
.pipe(z.number());
|
||||
expect(await schema.parseAsync("1234")).toEqual(1234);
|
||||
});
|
||||
|
||||
test("string with default fallback", () => {
|
||||
const stringWithDefault = z
|
||||
.pipe(
|
||||
z.transform((v) => (v === "none" ? undefined : v)),
|
||||
z.string()
|
||||
)
|
||||
.catch("default");
|
||||
|
||||
expect(stringWithDefault.parse("ok")).toBe("ok");
|
||||
expect(stringWithDefault.parse(undefined)).toBe("default");
|
||||
expect(stringWithDefault.parse("none")).toBe("default");
|
||||
expect(stringWithDefault.parse(15)).toBe("default");
|
||||
});
|
||||
|
||||
test("continue on non-fatal errors", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.refine((c) => c === "1234", "A")
|
||||
.transform((val) => Number(val))
|
||||
.refine((c) => c === 1234, "B");
|
||||
|
||||
schema.parse("1234");
|
||||
|
||||
expect(schema.safeParse("4321")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "A"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "B"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("break on fatal errors", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.refine((c) => c === "1234", { message: "A", abort: true })
|
||||
.transform((val) => Number(val))
|
||||
.refine((c) => c === 1234, "B");
|
||||
|
||||
schema.parse("1234");
|
||||
|
||||
expect(schema.safeParse("4321")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "A"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
37
frontend/node_modules/zod/src/v4/classic/tests/prefault.test.ts
generated
vendored
Normal file
37
frontend/node_modules/zod/src/v4/classic/tests/prefault.test.ts
generated
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
test("basic prefault", () => {
|
||||
const a = z.prefault(z.string().trim(), " default ");
|
||||
expect(a).toBeInstanceOf(z.ZodPrefault);
|
||||
expect(a.parse(" asdf ")).toEqual("asdf");
|
||||
expect(a.parse(undefined)).toEqual("default");
|
||||
|
||||
type inp = z.input<typeof a>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<string | undefined>();
|
||||
type out = z.output<typeof a>;
|
||||
expectTypeOf<out>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("prefault inside object", () => {
|
||||
// test optinality
|
||||
const a = z.object({
|
||||
name: z.string().optional(),
|
||||
age: z.number().default(1234),
|
||||
email: z.string().prefault("1234"),
|
||||
});
|
||||
|
||||
type inp = z.input<typeof a>;
|
||||
expectTypeOf<inp>().toEqualTypeOf<{
|
||||
name?: string | undefined;
|
||||
age?: number | undefined;
|
||||
email?: string | undefined;
|
||||
}>();
|
||||
|
||||
type out = z.output<typeof a>;
|
||||
expectTypeOf<out>().toEqualTypeOf<{
|
||||
name?: string | undefined;
|
||||
age: number;
|
||||
email: string;
|
||||
}>();
|
||||
});
|
||||
298
frontend/node_modules/zod/src/v4/classic/tests/preprocess.test.ts
generated
vendored
Normal file
298
frontend/node_modules/zod/src/v4/classic/tests/preprocess.test.ts
generated
vendored
Normal file
@ -0,0 +1,298 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("preprocess", () => {
|
||||
const schema = z.preprocess((data) => [data], z.string().array());
|
||||
const value = schema.parse("asdf");
|
||||
expect(value).toEqual(["asdf"]);
|
||||
expectTypeOf<(typeof schema)["_input"]>().toEqualTypeOf<unknown>();
|
||||
});
|
||||
|
||||
test("async preprocess", async () => {
|
||||
const schema = z.preprocess(async (data) => {
|
||||
return [data];
|
||||
}, z.string().array());
|
||||
const value = await schema.safeParseAsync("asdf");
|
||||
expect(value.data).toEqual(["asdf"]);
|
||||
expect(value).toMatchInlineSnapshot(`
|
||||
{
|
||||
"data": [
|
||||
"asdf",
|
||||
],
|
||||
"success": true,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("ctx.addIssue accepts string", () => {
|
||||
const schema = z.preprocess((_, ctx) => {
|
||||
ctx.addIssue("bad stuff");
|
||||
}, z.string());
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.error!.issues).toHaveLength(1);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"message": "bad stuff",
|
||||
"code": "custom",
|
||||
"path": []
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue with parse", () => {
|
||||
const a = z.preprocess((data, ctx) => {
|
||||
ctx.addIssue({
|
||||
input: data,
|
||||
code: "custom",
|
||||
message: `${data} is not one of our allowed strings`,
|
||||
});
|
||||
return data;
|
||||
}, z.string());
|
||||
|
||||
const result = a.safeParse("asdf");
|
||||
|
||||
// expect(result.error!.toJSON()).toContain("not one of our allowed strings");
|
||||
|
||||
expect(result.error!.issues).toHaveLength(1);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "asdf is not one of our allowed strings",
|
||||
"path": []
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue non-fatal by default", () => {
|
||||
const schema = z.preprocess((data, ctx) => {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: `custom error`,
|
||||
});
|
||||
return data;
|
||||
}, z.string());
|
||||
const result = schema.safeParse(1234);
|
||||
|
||||
expect(result.error!.issues).toHaveLength(2);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "custom error",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("preprocess ctx.addIssue fatal true", () => {
|
||||
const schema = z.preprocess((data, ctx) => {
|
||||
ctx.addIssue({
|
||||
input: data,
|
||||
code: "custom",
|
||||
origin: "custom",
|
||||
message: `custom error`,
|
||||
fatal: true,
|
||||
});
|
||||
return data;
|
||||
}, z.string());
|
||||
|
||||
const result = schema.safeParse(1234);
|
||||
|
||||
expect(result.error!.issues).toHaveLength(1);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"origin": "custom",
|
||||
"message": "custom error",
|
||||
"fatal": true,
|
||||
"path": []
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("async preprocess ctx.addIssue with parseAsync", async () => {
|
||||
const schema = z.preprocess(async (data, ctx) => {
|
||||
ctx.addIssue({
|
||||
input: data,
|
||||
code: "custom",
|
||||
message: `${data} is not one of our allowed strings`,
|
||||
});
|
||||
return data;
|
||||
}, z.string());
|
||||
|
||||
const result = await schema.safeParseAsync("asdf");
|
||||
|
||||
expect(result.error!.issues).toHaveLength(1);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "asdf is not one of our allowed strings",
|
||||
"path": []
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.NEVER in preprocess", () => {
|
||||
const foo = z.preprocess((val, ctx) => {
|
||||
if (!val) {
|
||||
ctx.addIssue({ input: val, code: "custom", message: "bad" });
|
||||
return z.NEVER;
|
||||
}
|
||||
return val;
|
||||
}, z.number());
|
||||
|
||||
type foo = z.infer<typeof foo>;
|
||||
expectTypeOf<foo>().toEqualTypeOf<number>();
|
||||
const result = foo.safeParse(undefined);
|
||||
|
||||
expect(result.error!.issues).toHaveLength(2);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "bad",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected number, received object"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("preprocess as the second property of object", () => {
|
||||
const schema = z.object({
|
||||
nonEmptyStr: z.string().min(1),
|
||||
positiveNum: z.preprocess((v) => Number(v), z.number().positive()),
|
||||
});
|
||||
const result = schema.safeParse({
|
||||
nonEmptyStr: "",
|
||||
positiveNum: "",
|
||||
});
|
||||
|
||||
expect(result.error!.issues).toHaveLength(2);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 1,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"nonEmptyStr"
|
||||
],
|
||||
"message": "Too small: expected string to have >=1 characters"
|
||||
},
|
||||
{
|
||||
"origin": "number",
|
||||
"code": "too_small",
|
||||
"minimum": 0,
|
||||
"inclusive": false,
|
||||
"path": [
|
||||
"positiveNum"
|
||||
],
|
||||
"message": "Too small: expected number to be >0"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("preprocess validates with sibling errors", () => {
|
||||
const schema = z.object({
|
||||
missing: z.string().refine(() => false),
|
||||
preprocess: z.preprocess((data: any) => data?.trim(), z.string().regex(/ asdf/)),
|
||||
});
|
||||
|
||||
const result = schema.safeParse({ preprocess: " asdf" });
|
||||
|
||||
expect(result.error!.issues).toHaveLength(2);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"missing"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
},
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "invalid_format",
|
||||
"format": "regex",
|
||||
"pattern": "/ asdf/",
|
||||
"path": [
|
||||
"preprocess"
|
||||
],
|
||||
"message": "Invalid string: must match pattern / asdf/"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("perform transform with non-fatal issues", () => {
|
||||
const A = z
|
||||
.string()
|
||||
.refine((_) => false)
|
||||
.min(4)
|
||||
.transform((val) => val.length)
|
||||
.pipe(z.number())
|
||||
.refine((_) => false);
|
||||
expect(A.safeParse("asdfasdf").error!.issues).toHaveLength(2);
|
||||
expect(A.safeParse("asdfasdf").error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
175
frontend/node_modules/zod/src/v4/classic/tests/primitive.test.ts
generated
vendored
Normal file
175
frontend/node_modules/zod/src/v4/classic/tests/primitive.test.ts
generated
vendored
Normal file
@ -0,0 +1,175 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const literalStringSchema = z.literal("asdf");
|
||||
const literalNumberSchema = z.literal(12);
|
||||
const literalBooleanSchema = z.literal(true);
|
||||
const literalBigIntSchema = z.literal(BigInt(42));
|
||||
|
||||
const stringSchema = z.string();
|
||||
const numberSchema = z.number();
|
||||
const bigintSchema = z.bigint();
|
||||
const booleanSchema = z.boolean();
|
||||
const dateSchema = z.date();
|
||||
const symbolSchema = z.symbol();
|
||||
const nullSchema = z.null();
|
||||
const undefinedSchema = z.undefined();
|
||||
const stringSchemaOptional = z.string().optional();
|
||||
const stringSchemaNullable = z.string().nullable();
|
||||
const numberSchemaOptional = z.number().optional();
|
||||
const numberSchemaNullable = z.number().nullable();
|
||||
const bigintSchemaOptional = z.bigint().optional();
|
||||
const bigintSchemaNullable = z.bigint().nullable();
|
||||
const booleanSchemaOptional = z.boolean().optional();
|
||||
const booleanSchemaNullable = z.boolean().nullable();
|
||||
const dateSchemaOptional = z.date().optional();
|
||||
const dateSchemaNullable = z.date().nullable();
|
||||
const symbolSchemaOptional = z.symbol().optional();
|
||||
const symbolSchemaNullable = z.symbol().nullable();
|
||||
|
||||
test("literal string schema", () => {
|
||||
expect(literalStringSchema.parse("asdf")).toBe("asdf");
|
||||
expect(() => literalStringSchema.parse("not_asdf")).toThrow();
|
||||
expect(() => literalStringSchema.parse(123)).toThrow();
|
||||
expect(() => literalStringSchema.parse(true)).toThrow();
|
||||
expect(() => literalStringSchema.parse({})).toThrow();
|
||||
});
|
||||
|
||||
test("literal number schema", () => {
|
||||
expect(literalNumberSchema.parse(12)).toBe(12);
|
||||
expect(() => literalNumberSchema.parse(13)).toThrow();
|
||||
expect(() => literalNumberSchema.parse("foo")).toThrow();
|
||||
expect(() => literalNumberSchema.parse(true)).toThrow();
|
||||
expect(() => literalNumberSchema.parse({})).toThrow();
|
||||
});
|
||||
|
||||
test("literal boolean schema", () => {
|
||||
expect(literalBooleanSchema.parse(true)).toBe(true);
|
||||
expect(() => literalBooleanSchema.parse(false)).toThrow();
|
||||
expect(() => literalBooleanSchema.parse("asdf")).toThrow();
|
||||
expect(() => literalBooleanSchema.parse(123)).toThrow();
|
||||
expect(() => literalBooleanSchema.parse({})).toThrow();
|
||||
});
|
||||
|
||||
test("literal bigint schema", () => {
|
||||
expect(literalBigIntSchema.parse(BigInt(42))).toBe(BigInt(42));
|
||||
expect(() => literalBigIntSchema.parse(BigInt(43))).toThrow();
|
||||
expect(() => literalBigIntSchema.parse("asdf")).toThrow();
|
||||
expect(() => literalBigIntSchema.parse(123)).toThrow();
|
||||
expect(() => literalBigIntSchema.parse({})).toThrow();
|
||||
});
|
||||
|
||||
test("string schema", () => {
|
||||
stringSchema.parse("foo");
|
||||
expect(() => stringSchema.parse(Math.random())).toThrow();
|
||||
expect(() => stringSchema.parse(true)).toThrow();
|
||||
expect(() => stringSchema.parse(undefined)).toThrow();
|
||||
expect(() => stringSchema.parse(null)).toThrow();
|
||||
});
|
||||
|
||||
test("number schema", () => {
|
||||
numberSchema.parse(Math.random());
|
||||
expect(() => numberSchema.parse("foo")).toThrow();
|
||||
expect(() => numberSchema.parse(BigInt(17))).toThrow();
|
||||
expect(() => numberSchema.parse(true)).toThrow();
|
||||
expect(() => numberSchema.parse(undefined)).toThrow();
|
||||
expect(() => numberSchema.parse(null)).toThrow();
|
||||
});
|
||||
|
||||
test("bigint schema", () => {
|
||||
bigintSchema.parse(BigInt(17));
|
||||
expect(() => bigintSchema.parse("foo")).toThrow();
|
||||
expect(() => bigintSchema.parse(Math.random())).toThrow();
|
||||
expect(() => bigintSchema.parse(true)).toThrow();
|
||||
expect(() => bigintSchema.parse(undefined)).toThrow();
|
||||
expect(() => bigintSchema.parse(null)).toThrow();
|
||||
});
|
||||
|
||||
test("boolean schema", () => {
|
||||
booleanSchema.parse(true);
|
||||
expect(() => booleanSchema.parse("foo")).toThrow();
|
||||
expect(() => booleanSchema.parse(Math.random())).toThrow();
|
||||
expect(() => booleanSchema.parse(undefined)).toThrow();
|
||||
expect(() => booleanSchema.parse(null)).toThrow();
|
||||
});
|
||||
|
||||
test("date schema", async () => {
|
||||
dateSchema.parse(new Date());
|
||||
expect(() => dateSchema.parse("foo")).toThrow();
|
||||
expect(() => dateSchema.parse(Math.random())).toThrow();
|
||||
expect(() => dateSchema.parse(true)).toThrow();
|
||||
expect(() => dateSchema.parse(undefined)).toThrow();
|
||||
expect(() => dateSchema.parse(null)).toThrow();
|
||||
expect(await dateSchema.safeParseAsync(new Date("invalid"))).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "date",
|
||||
"code": "invalid_type",
|
||||
"received": "Invalid Date",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected date, received Date"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("symbol schema", () => {
|
||||
symbolSchema.parse(Symbol("foo"));
|
||||
expect(() => symbolSchema.parse("foo")).toThrow();
|
||||
expect(() => symbolSchema.parse(Math.random())).toThrow();
|
||||
expect(() => symbolSchema.parse(true)).toThrow();
|
||||
expect(() => symbolSchema.parse(new Date())).toThrow();
|
||||
expect(() => symbolSchema.parse(undefined)).toThrow();
|
||||
expect(() => symbolSchema.parse(null)).toThrow();
|
||||
});
|
||||
|
||||
test("undefined schema", () => {
|
||||
undefinedSchema.parse(undefined);
|
||||
expect(() => undefinedSchema.parse("foo")).toThrow();
|
||||
expect(() => undefinedSchema.parse(Math.random())).toThrow();
|
||||
expect(() => undefinedSchema.parse(true)).toThrow();
|
||||
expect(() => undefinedSchema.parse(null)).toThrow();
|
||||
});
|
||||
|
||||
test("null schema", () => {
|
||||
nullSchema.parse(null);
|
||||
expect(() => nullSchema.parse("foo")).toThrow();
|
||||
expect(() => nullSchema.parse(Math.random())).toThrow();
|
||||
expect(() => nullSchema.parse(true)).toThrow();
|
||||
expect(() => nullSchema.parse(undefined)).toThrow();
|
||||
});
|
||||
|
||||
test("primitive inference", () => {
|
||||
expectTypeOf<z.TypeOf<typeof literalStringSchema>>().toEqualTypeOf<"asdf">();
|
||||
expectTypeOf<z.TypeOf<typeof literalNumberSchema>>().toEqualTypeOf<12>();
|
||||
expectTypeOf<z.TypeOf<typeof literalBooleanSchema>>().toEqualTypeOf<true>();
|
||||
expectTypeOf<z.TypeOf<typeof literalBigIntSchema>>().toEqualTypeOf<bigint>();
|
||||
expectTypeOf<z.TypeOf<typeof stringSchema>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.TypeOf<typeof numberSchema>>().toEqualTypeOf<number>();
|
||||
expectTypeOf<z.TypeOf<typeof bigintSchema>>().toEqualTypeOf<bigint>();
|
||||
expectTypeOf<z.TypeOf<typeof booleanSchema>>().toEqualTypeOf<boolean>();
|
||||
expectTypeOf<z.TypeOf<typeof dateSchema>>().toEqualTypeOf<Date>();
|
||||
expectTypeOf<z.TypeOf<typeof symbolSchema>>().toEqualTypeOf<symbol>();
|
||||
expectTypeOf<z.TypeOf<typeof nullSchema>>().toEqualTypeOf<null>();
|
||||
expectTypeOf<z.TypeOf<typeof undefinedSchema>>().toEqualTypeOf<undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof stringSchemaOptional>>().toEqualTypeOf<string | undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof stringSchemaNullable>>().toEqualTypeOf<string | null>();
|
||||
expectTypeOf<z.TypeOf<typeof numberSchemaOptional>>().toEqualTypeOf<number | undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof numberSchemaNullable>>().toEqualTypeOf<number | null>();
|
||||
expectTypeOf<z.TypeOf<typeof bigintSchemaOptional>>().toEqualTypeOf<bigint | undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof bigintSchemaNullable>>().toEqualTypeOf<bigint | null>();
|
||||
expectTypeOf<z.TypeOf<typeof booleanSchemaOptional>>().toEqualTypeOf<boolean | undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof booleanSchemaNullable>>().toEqualTypeOf<boolean | null>();
|
||||
expectTypeOf<z.TypeOf<typeof dateSchemaOptional>>().toEqualTypeOf<Date | undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof dateSchemaNullable>>().toEqualTypeOf<Date | null>();
|
||||
expectTypeOf<z.TypeOf<typeof symbolSchemaOptional>>().toEqualTypeOf<symbol | undefined>();
|
||||
expectTypeOf<z.TypeOf<typeof symbolSchemaNullable>>().toEqualTypeOf<symbol | null>();
|
||||
});
|
||||
|
||||
test("get literal values", () => {
|
||||
expect(literalStringSchema.values).toEqual(new Set(["asdf"]));
|
||||
expect(literalStringSchema._zod.def.values).toEqual(["asdf"]);
|
||||
});
|
||||
81
frontend/node_modules/zod/src/v4/classic/tests/promise.test.ts
generated
vendored
Normal file
81
frontend/node_modules/zod/src/v4/classic/tests/promise.test.ts
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const promSchema = z.promise(
|
||||
z.object({
|
||||
name: z.string(),
|
||||
age: z.number(),
|
||||
})
|
||||
);
|
||||
|
||||
test("promise inference", () => {
|
||||
type promSchemaType = z.infer<typeof promSchema>;
|
||||
expectTypeOf<promSchemaType>().toEqualTypeOf<{ name: string; age: number }>();
|
||||
});
|
||||
|
||||
test("promise parsing success", async () => {
|
||||
// expect(() => promSchema.parse(Promise.resolve({ name: "Bobby", age: 10 }))).toThrow();
|
||||
const pr = promSchema.parseAsync(Promise.resolve({ name: "Bobby", age: 10 }));
|
||||
expect(pr).toBeInstanceOf(Promise);
|
||||
const result = await pr;
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"age": 10,
|
||||
"name": "Bobby",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("promise parsing fail", async () => {
|
||||
const bad = await promSchema.safeParseAsync(Promise.resolve({ name: "Bobby", age: "10" }));
|
||||
expect(bad.success).toBe(false);
|
||||
expect(bad.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
test("promise parsing fail 2", async () => {
|
||||
const result = await promSchema.safeParseAsync(Promise.resolve({ name: "Bobby", age: "10" }));
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.error).toBeInstanceOf(z.ZodError);
|
||||
});
|
||||
|
||||
test("promise parsing fail", () => {
|
||||
const bad = () => promSchema.parse({ then: () => {}, catch: {} });
|
||||
expect(bad).toThrow();
|
||||
});
|
||||
|
||||
test("sync promise parsing", () => {
|
||||
expect(() => z.promise(z.string()).parse(Promise.resolve("asfd"))).toThrow();
|
||||
});
|
||||
|
||||
const asyncFunction = z.function({
|
||||
input: z.tuple([]),
|
||||
output: promSchema,
|
||||
});
|
||||
|
||||
test("async function pass", async () => {
|
||||
const validatedFunction = asyncFunction.implementAsync(async () => {
|
||||
return { name: "jimmy", age: 14 };
|
||||
});
|
||||
await expect(validatedFunction()).resolves.toEqual({
|
||||
name: "jimmy",
|
||||
age: 14,
|
||||
});
|
||||
});
|
||||
|
||||
test("async function fail", async () => {
|
||||
const validatedFunction = asyncFunction.implementAsync(() => {
|
||||
return Promise.resolve("asdf" as any);
|
||||
});
|
||||
await expect(validatedFunction()).rejects.toBeInstanceOf(z.core.$ZodError);
|
||||
});
|
||||
|
||||
test("async promise parsing", () => {
|
||||
const res = z.promise(z.number()).parseAsync(Promise.resolve(12));
|
||||
expect(res).toBeInstanceOf(Promise);
|
||||
});
|
||||
|
||||
test("resolves", () => {
|
||||
const foo = z.literal("foo");
|
||||
const res = z.promise(foo);
|
||||
expect(res.unwrap()).toEqual(foo);
|
||||
});
|
||||
23
frontend/node_modules/zod/src/v4/classic/tests/prototypes.test.ts
generated
vendored
Normal file
23
frontend/node_modules/zod/src/v4/classic/tests/prototypes.test.ts
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import { expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
declare module "zod/v4" {
|
||||
interface ZodType {
|
||||
/** @deprecated */
|
||||
_classic(): string;
|
||||
}
|
||||
}
|
||||
|
||||
test("prototype extension", () => {
|
||||
z.ZodType.prototype._classic = function () {
|
||||
return "_classic";
|
||||
};
|
||||
|
||||
// should pass
|
||||
const result = z.string()._classic();
|
||||
expect(result).toBe("_classic");
|
||||
// expectTypeOf<typeof result>().toEqualTypeOf<string>();
|
||||
|
||||
// clean up
|
||||
z.ZodType.prototype._classic = undefined;
|
||||
});
|
||||
252
frontend/node_modules/zod/src/v4/classic/tests/readonly.test.ts
generated
vendored
Normal file
252
frontend/node_modules/zod/src/v4/classic/tests/readonly.test.ts
generated
vendored
Normal file
@ -0,0 +1,252 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
enum testEnum {
|
||||
A = 0,
|
||||
B = 1,
|
||||
}
|
||||
|
||||
test("flat inference", () => {
|
||||
const readonlyString = z.string().readonly();
|
||||
const readonlyNumber = z.number().readonly();
|
||||
const readonlyNaN = z.nan().readonly();
|
||||
const readonlyBigInt = z.bigint().readonly();
|
||||
const readonlyBoolean = z.boolean().readonly();
|
||||
const readonlyDate = z.date().readonly();
|
||||
const readonlyUndefined = z.undefined().readonly();
|
||||
const readonlyNull = z.null().readonly();
|
||||
const readonlyAny = z.any().readonly();
|
||||
const readonlyUnknown = z.unknown().readonly();
|
||||
const readonlyVoid = z.void().readonly();
|
||||
const readonlyStringArray = z.array(z.string()).readonly();
|
||||
const readonlyTuple = z.tuple([z.string(), z.number()]).readonly();
|
||||
const readonlyMap = z.map(z.string(), z.date()).readonly();
|
||||
const readonlySet = z.set(z.string()).readonly();
|
||||
const readonlyStringRecord = z.record(z.string(), z.string()).readonly();
|
||||
const readonlyNumberRecord = z.record(z.string(), z.number()).readonly();
|
||||
const readonlyObject = z.object({ a: z.string(), 1: z.number() }).readonly();
|
||||
const readonlyEnum = z.nativeEnum(testEnum).readonly();
|
||||
const readonlyPromise = z.promise(z.string()).readonly();
|
||||
|
||||
expectTypeOf<typeof readonlyString._output>().toEqualTypeOf<string>();
|
||||
expectTypeOf<typeof readonlyNumber._output>().toEqualTypeOf<number>();
|
||||
expectTypeOf<typeof readonlyNaN._output>().toEqualTypeOf<number>();
|
||||
expectTypeOf<typeof readonlyBigInt._output>().toEqualTypeOf<bigint>();
|
||||
expectTypeOf<typeof readonlyBoolean._output>().toEqualTypeOf<boolean>();
|
||||
expectTypeOf<typeof readonlyDate._output>().toEqualTypeOf<Date>();
|
||||
expectTypeOf<typeof readonlyUndefined._output>().toEqualTypeOf<undefined>();
|
||||
expectTypeOf<typeof readonlyNull._output>().toEqualTypeOf<null>();
|
||||
expectTypeOf<typeof readonlyAny._output>().toEqualTypeOf<any>();
|
||||
expectTypeOf<typeof readonlyUnknown._output>().toEqualTypeOf<Readonly<unknown>>();
|
||||
expectTypeOf<typeof readonlyVoid._output>().toEqualTypeOf<void>();
|
||||
expectTypeOf<typeof readonlyStringArray._output>().toEqualTypeOf<readonly string[]>();
|
||||
expectTypeOf<typeof readonlyTuple._output>().toEqualTypeOf<readonly [string, number]>();
|
||||
expectTypeOf<typeof readonlyMap._output>().toEqualTypeOf<ReadonlyMap<string, Date>>();
|
||||
expectTypeOf<typeof readonlySet._output>().toEqualTypeOf<ReadonlySet<string>>();
|
||||
expectTypeOf<typeof readonlyStringRecord._output>().toEqualTypeOf<Readonly<Record<string, string>>>();
|
||||
expectTypeOf<typeof readonlyNumberRecord._output>().toEqualTypeOf<Readonly<Record<string, number>>>();
|
||||
expectTypeOf<typeof readonlyObject._output>().toEqualTypeOf<{ readonly a: string; readonly 1: number }>();
|
||||
expectTypeOf<typeof readonlyEnum._output>().toEqualTypeOf<Readonly<testEnum>>();
|
||||
expectTypeOf<typeof readonlyPromise._output>().toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
// test("deep inference", () => {
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[0]>>().toEqualTypeOf<string>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[1]>>().toEqualTypeOf<number>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[2]>>().toEqualTypeOf<number>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[3]>>().toEqualTypeOf<bigint>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[4]>>().toEqualTypeOf<boolean>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[5]>>().toEqualTypeOf<Date>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[6]>>().toEqualTypeOf<undefined>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[7]>>().toEqualTypeOf<null>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[8]>>().toEqualTypeOf<any>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[9]>
|
||||
// >().toEqualTypeOf<Readonly<unknown>>();
|
||||
// expectTypeOf<z.infer<(typeof deepReadonlySchemas_0)[10]>>().toEqualTypeOf<void>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[11]>
|
||||
// >().toEqualTypeOf<(args_0: string, args_1: number, ...args_2: unknown[]) => unknown>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[12]>
|
||||
// >().toEqualTypeOf<readonly string[]>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[13]>
|
||||
// >().toEqualTypeOf<readonly [string, number]>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[14]>
|
||||
// >().toEqualTypeOf<ReadonlyMap<string, Date>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[15]>
|
||||
// >().toEqualTypeOf<ReadonlySet<Promise<string>>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[16]>
|
||||
// >().toEqualTypeOf<Readonly<Record<string, string>>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[17]>
|
||||
// >().toEqualTypeOf<Readonly<Record<string, number>>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[18]>
|
||||
// >().toEqualTypeOf<{ readonly a: string; readonly 1: number }>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[19]>
|
||||
// >().toEqualTypeOf<Readonly<testEnum>>();
|
||||
// expectTypeOf<
|
||||
// z.infer<(typeof deepReadonlySchemas_0)[20]>
|
||||
// >().toEqualTypeOf<Promise<string>>();
|
||||
|
||||
// expectTypeOf<
|
||||
// z.infer<typeof crazyDeepReadonlySchema>
|
||||
// >().toEqualTypeOf<ReadonlyMap<
|
||||
// ReadonlySet<readonly [string, number]>,
|
||||
// {
|
||||
// readonly a: {
|
||||
// readonly [x: string]: readonly any[];
|
||||
// };
|
||||
// readonly b: {
|
||||
// readonly c: {
|
||||
// readonly d: {
|
||||
// readonly e: {
|
||||
// readonly f: {
|
||||
// readonly g?: {};
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// };
|
||||
// }
|
||||
// >>();
|
||||
// });
|
||||
|
||||
test("object freezing", async () => {
|
||||
expect(Object.isFrozen(z.array(z.string()).readonly().parse(["a"]))).toBe(true);
|
||||
expect(Object.isFrozen(z.tuple([z.string(), z.number()]).readonly().parse(["a", 1]))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
z
|
||||
.map(z.string(), z.date())
|
||||
.readonly()
|
||||
.parse(new Map([["a", new Date()]]))
|
||||
)
|
||||
).toBe(true);
|
||||
|
||||
expect(Object.isFrozen(z.record(z.string(), z.string()).readonly().parse({ a: "b" }))).toBe(true);
|
||||
expect(Object.isFrozen(z.record(z.string(), z.number()).readonly().parse({ a: 1 }))).toBe(true);
|
||||
expect(Object.isFrozen(z.object({ a: z.string(), 1: z.number() }).readonly().parse({ a: "b", 1: 2 }))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.set(z.promise(z.string()))
|
||||
.readonly()
|
||||
.parseAsync(new Set([Promise.resolve("a")]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.promise(z.string()).readonly().parseAsync(Promise.resolve("a")))).toBe(true);
|
||||
});
|
||||
|
||||
test("async object freezing", async () => {
|
||||
expect(Object.isFrozen(await z.array(z.string()).readonly().parseAsync(["a"]))).toBe(true);
|
||||
expect(Object.isFrozen(await z.tuple([z.string(), z.number()]).readonly().parseAsync(["a", 1]))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.map(z.string(), z.date())
|
||||
.readonly()
|
||||
.parseAsync(new Map([["a", new Date()]]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(
|
||||
await z
|
||||
.set(z.promise(z.string()))
|
||||
.readonly()
|
||||
.parseAsync(new Set([Promise.resolve("a")]))
|
||||
)
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.record(z.string(), z.string()).readonly().parseAsync({ a: "b" }))).toBe(true);
|
||||
expect(Object.isFrozen(await z.record(z.string(), z.number()).readonly().parseAsync({ a: 1 }))).toBe(true);
|
||||
expect(
|
||||
Object.isFrozen(await z.object({ a: z.string(), 1: z.number() }).readonly().parseAsync({ a: "b", 1: 2 }))
|
||||
).toBe(true);
|
||||
expect(Object.isFrozen(await z.promise(z.string()).readonly().parseAsync(Promise.resolve("a")))).toBe(true);
|
||||
});
|
||||
|
||||
test("readonly inference", () => {
|
||||
const readonlyStringArray = z.string().array().readonly();
|
||||
const readonlyStringTuple = z.tuple([z.string()]).readonly();
|
||||
const deepReadonly = z.object({ a: z.string() }).readonly();
|
||||
|
||||
type readonlyStringArray = z.infer<typeof readonlyStringArray>;
|
||||
type readonlyStringTuple = z.infer<typeof readonlyStringTuple>;
|
||||
type deepReadonly = z.infer<typeof deepReadonly>;
|
||||
|
||||
expectTypeOf<readonlyStringArray>().toEqualTypeOf<readonly string[]>();
|
||||
expectTypeOf<readonlyStringTuple>().toEqualTypeOf<readonly [string]>();
|
||||
expectTypeOf<deepReadonly>().toEqualTypeOf<{ readonly a: string }>();
|
||||
});
|
||||
|
||||
test("readonly parse", () => {
|
||||
const schema = z.array(z.string()).readonly();
|
||||
const readonlyArray = ["a", "b", "c"] as const;
|
||||
const mutableArray = ["a", "b", "c"];
|
||||
const result1 = schema.parse(readonlyArray);
|
||||
const result2 = schema.parse(mutableArray);
|
||||
expect(result1).toEqual(readonlyArray);
|
||||
expect(result2).toEqual(mutableArray);
|
||||
});
|
||||
|
||||
test("readonly parse with tuples", () => {
|
||||
const schema = z.tuple([z.string(), z.number()]).readonly();
|
||||
schema.parse(["a", 1]);
|
||||
});
|
||||
|
||||
test("readonly and the get method", () => {
|
||||
const readonlyString = z.string().readonly();
|
||||
const readonlyNumber1 = z.number().readonly();
|
||||
const readonlyNumber2 = z.number().readonly();
|
||||
const readonlyBigInt = z.bigint().readonly();
|
||||
const readonlyBoolean = z.boolean().readonly();
|
||||
const readonlyDate = z.date().readonly();
|
||||
const readonlyUndefined = z.undefined().readonly();
|
||||
const readonlyNull = z.null().readonly();
|
||||
const readonlyAny = z.any().readonly();
|
||||
const readonlyUnknown = z.unknown().readonly();
|
||||
const readonlyVoid = z.void().readonly();
|
||||
// const readonlyFunction = z.function(z.tuple([z.string(), z.number()]), z.unknown()).readonly();
|
||||
const readonlyStringArray = z.string().array().readonly();
|
||||
const readonlyTuple = z.tuple([z.string(), z.number()]).readonly();
|
||||
|
||||
expectTypeOf<z.infer<typeof readonlyString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof readonlyNumber1>>().toEqualTypeOf<number>();
|
||||
expectTypeOf<z.infer<typeof readonlyNumber2>>().toEqualTypeOf<number>();
|
||||
expectTypeOf<z.infer<typeof readonlyBigInt>>().toEqualTypeOf<bigint>();
|
||||
expectTypeOf<z.infer<typeof readonlyBoolean>>().toEqualTypeOf<boolean>();
|
||||
expectTypeOf<z.infer<typeof readonlyDate>>().toEqualTypeOf<Date>();
|
||||
expectTypeOf<z.infer<typeof readonlyUndefined>>().toEqualTypeOf<undefined>();
|
||||
expectTypeOf<z.infer<typeof readonlyNull>>().toEqualTypeOf<null>();
|
||||
expectTypeOf<z.infer<typeof readonlyAny>>().toEqualTypeOf<any>();
|
||||
expectTypeOf<z.infer<typeof readonlyUnknown>>().toEqualTypeOf<Readonly<unknown>>();
|
||||
expectTypeOf<z.infer<typeof readonlyVoid>>().toEqualTypeOf<void>();
|
||||
// expectTypeOf<z.infer<typeof readonlyFunction>>().toEqualTypeOf<
|
||||
// (args_0: string, args_1: number, ...args_2: unknown[]) => unknown
|
||||
// >();
|
||||
expectTypeOf<z.infer<typeof readonlyStringArray>>().toEqualTypeOf<readonly string[]>();
|
||||
expectTypeOf<z.infer<typeof readonlyTuple>>().toEqualTypeOf<readonly [string, number]>();
|
||||
|
||||
expect(readonlyString.parse("asdf")).toEqual("asdf");
|
||||
expect(readonlyNumber1.parse(1234)).toEqual(1234);
|
||||
expect(readonlyNumber2.parse(1234)).toEqual(1234);
|
||||
const bigIntVal = BigInt(1);
|
||||
expect(readonlyBigInt.parse(bigIntVal)).toEqual(bigIntVal);
|
||||
expect(readonlyBoolean.parse(true)).toEqual(true);
|
||||
const dateVal = new Date();
|
||||
expect(readonlyDate.parse(dateVal)).toEqual(dateVal);
|
||||
expect(readonlyUndefined.parse(undefined)).toEqual(undefined);
|
||||
expect(readonlyNull.parse(null)).toEqual(null);
|
||||
expect(readonlyAny.parse("whatever")).toEqual("whatever");
|
||||
expect(readonlyUnknown.parse("whatever")).toEqual("whatever");
|
||||
expect(readonlyVoid.parse(undefined)).toEqual(undefined);
|
||||
// expect(readonlyFunction.parse(() => void 0)).toEqual(() => void 0);
|
||||
expect(readonlyStringArray.parse(["asdf"])).toEqual(["asdf"]);
|
||||
expect(readonlyTuple.parse(["asdf", 1234])).toEqual(["asdf", 1234]);
|
||||
});
|
||||
342
frontend/node_modules/zod/src/v4/classic/tests/record.test.ts
generated
vendored
Normal file
342
frontend/node_modules/zod/src/v4/classic/tests/record.test.ts
generated
vendored
Normal file
@ -0,0 +1,342 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("type inference", () => {
|
||||
const booleanRecord = z.record(z.string(), z.boolean());
|
||||
type booleanRecord = typeof booleanRecord._output;
|
||||
|
||||
const recordWithEnumKeys = z.record(z.enum(["Tuna", "Salmon"]), z.string());
|
||||
type recordWithEnumKeys = z.infer<typeof recordWithEnumKeys>;
|
||||
|
||||
const recordWithLiteralKey = z.record(z.literal(["Tuna", "Salmon"]), z.string());
|
||||
type recordWithLiteralKey = z.infer<typeof recordWithLiteralKey>;
|
||||
|
||||
const recordWithLiteralUnionKeys = z.record(z.union([z.literal("Tuna"), z.literal("Salmon")]), z.string());
|
||||
type recordWithLiteralUnionKeys = z.infer<typeof recordWithLiteralUnionKeys>;
|
||||
|
||||
expectTypeOf<booleanRecord>().toEqualTypeOf<Record<string, boolean>>();
|
||||
expectTypeOf<recordWithEnumKeys>().toEqualTypeOf<Record<"Tuna" | "Salmon", string>>();
|
||||
expectTypeOf<recordWithLiteralKey>().toEqualTypeOf<Record<"Tuna" | "Salmon", string>>();
|
||||
expectTypeOf<recordWithLiteralUnionKeys>().toEqualTypeOf<Record<"Tuna" | "Salmon", string>>();
|
||||
});
|
||||
|
||||
test("enum exhaustiveness", () => {
|
||||
const schema = z.record(z.enum(["Tuna", "Salmon"]), z.string());
|
||||
expect(
|
||||
schema.parse({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
})
|
||||
).toEqual({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
|
||||
expect(schema.safeParse({ Tuna: "asdf", Salmon: "asdf", Trout: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "unrecognized_keys",
|
||||
"keys": [
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Unrecognized key: \\"Trout\\""
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse({ Tuna: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"Salmon"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("literal exhaustiveness", () => {
|
||||
const schema = z.record(z.literal(["Tuna", "Salmon"]), z.string());
|
||||
schema.parse({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
|
||||
expect(schema.safeParse({ Tuna: "asdf", Salmon: "asdf", Trout: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "unrecognized_keys",
|
||||
"keys": [
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Unrecognized key: \\"Trout\\""
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse({ Tuna: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"Salmon"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("pipe exhaustiveness", () => {
|
||||
const schema = z.record(z.enum(["Tuna", "Salmon"]).pipe(z.any()), z.string());
|
||||
expect(schema.parse({ Tuna: "asdf", Salmon: "asdf" })).toEqual({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
|
||||
expect(schema.safeParse({ Tuna: "asdf", Salmon: "asdf", Trout: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "unrecognized_keys",
|
||||
"keys": [
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Unrecognized key: \\"Trout\\""
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse({ Tuna: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"Salmon"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("union exhaustiveness", () => {
|
||||
const schema = z.record(z.union([z.literal("Tuna"), z.literal("Salmon")]), z.string());
|
||||
expect(schema.parse({ Tuna: "asdf", Salmon: "asdf" })).toEqual({
|
||||
Tuna: "asdf",
|
||||
Salmon: "asdf",
|
||||
});
|
||||
|
||||
expect(schema.safeParse({ Tuna: "asdf", Salmon: "asdf", Trout: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "unrecognized_keys",
|
||||
"keys": [
|
||||
"Trout"
|
||||
],
|
||||
"path": [],
|
||||
"message": "Unrecognized key: \\"Trout\\""
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse({ Tuna: "asdf" })).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"Salmon"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("string record parse - pass", () => {
|
||||
const schema = z.record(z.string(), z.boolean());
|
||||
schema.parse({
|
||||
k1: true,
|
||||
k2: false,
|
||||
1234: false,
|
||||
});
|
||||
|
||||
expect(schema.safeParse({ asdf: 1234 }).success).toEqual(false);
|
||||
expect(schema.safeParse("asdf")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "record",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected record, received string"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("key and value getters", () => {
|
||||
const rec = z.record(z.string(), z.number());
|
||||
|
||||
rec.keyType.parse("asdf");
|
||||
rec.valueType.parse(1234);
|
||||
});
|
||||
|
||||
test("is not vulnerable to prototype pollution", async () => {
|
||||
const rec = z.record(
|
||||
z.string(),
|
||||
z.object({
|
||||
a: z.string(),
|
||||
})
|
||||
);
|
||||
|
||||
const data = JSON.parse(`
|
||||
{
|
||||
"__proto__": {
|
||||
"a": "evil"
|
||||
},
|
||||
"b": {
|
||||
"a": "good"
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const obj1 = rec.parse(data);
|
||||
expect(obj1.a).toBeUndefined();
|
||||
|
||||
const obj2 = rec.safeParse(data);
|
||||
expect(obj2.success).toBe(true);
|
||||
if (obj2.success) {
|
||||
expect(obj2.data.a).toBeUndefined();
|
||||
}
|
||||
|
||||
const obj3 = await rec.parseAsync(data);
|
||||
expect(obj3.a).toBeUndefined();
|
||||
|
||||
const obj4 = await rec.safeParseAsync(data);
|
||||
expect(obj4.success).toBe(true);
|
||||
if (obj4.success) {
|
||||
expect(obj4.data.a).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
test("dont remove undefined values", () => {
|
||||
const result1 = z.record(z.string(), z.any()).parse({ foo: undefined });
|
||||
|
||||
expect(result1).toEqual({
|
||||
foo: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
test("allow undefined values", () => {
|
||||
const schema = z.record(z.string(), z.undefined());
|
||||
|
||||
expect(
|
||||
Object.keys(
|
||||
schema.parse({
|
||||
_test: undefined,
|
||||
})
|
||||
)
|
||||
).toEqual(["_test"]);
|
||||
});
|
||||
|
||||
test("async parsing", async () => {
|
||||
const schema = z
|
||||
.record(
|
||||
z.string(),
|
||||
z
|
||||
.string()
|
||||
.optional()
|
||||
.refine(async () => true)
|
||||
)
|
||||
.refine(async () => true);
|
||||
|
||||
const data = {
|
||||
foo: "bar",
|
||||
baz: "qux",
|
||||
};
|
||||
const result = await schema.safeParseAsync(data);
|
||||
expect(result.data).toEqual(data);
|
||||
});
|
||||
|
||||
test("async parsing", async () => {
|
||||
const schema = z
|
||||
.record(
|
||||
z.string(),
|
||||
z
|
||||
.string()
|
||||
.optional()
|
||||
.refine(async () => false)
|
||||
)
|
||||
.refine(async () => false);
|
||||
|
||||
const data = {
|
||||
foo: "bar",
|
||||
baz: "qux",
|
||||
};
|
||||
const result = await schema.safeParseAsync(data);
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"foo"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [
|
||||
"baz"
|
||||
],
|
||||
"message": "Invalid input"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("partial record", () => {
|
||||
const schema = z.partialRecord(z.string(), z.string());
|
||||
type schema = z.infer<typeof schema>;
|
||||
expectTypeOf<schema>().toEqualTypeOf<Partial<Record<string, string>>>();
|
||||
|
||||
const Keys = z.enum(["id", "name", "email"]).or(z.never());
|
||||
const Person = z.partialRecord(Keys, z.string());
|
||||
expectTypeOf<z.infer<typeof Person>>().toEqualTypeOf<Partial<Record<"id" | "name" | "email", string>>>();
|
||||
});
|
||||
356
frontend/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts
generated
vendored
Normal file
356
frontend/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts
generated
vendored
Normal file
@ -0,0 +1,356 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
test("recursion with z.lazy", () => {
|
||||
const data = {
|
||||
name: "I",
|
||||
subcategories: [
|
||||
{
|
||||
name: "A",
|
||||
subcategories: [
|
||||
{
|
||||
name: "1",
|
||||
subcategories: [
|
||||
{
|
||||
name: "a",
|
||||
subcategories: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const Category = z.object({
|
||||
name: z.string(),
|
||||
get subcategories() {
|
||||
return z.array(Category).optional().nullable();
|
||||
},
|
||||
});
|
||||
type Category = z.infer<typeof Category>;
|
||||
interface _Category {
|
||||
name: string;
|
||||
subcategories?: _Category[] | undefined | null;
|
||||
}
|
||||
expectTypeOf<Category>().toEqualTypeOf<_Category>();
|
||||
Category.parse(data);
|
||||
});
|
||||
|
||||
test("recursion involving union type", () => {
|
||||
const data = {
|
||||
value: 1,
|
||||
next: {
|
||||
value: 2,
|
||||
next: {
|
||||
value: 3,
|
||||
next: {
|
||||
value: 4,
|
||||
next: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const LL = z.object({
|
||||
value: z.number(),
|
||||
get next() {
|
||||
return LL.nullable();
|
||||
},
|
||||
});
|
||||
type LL = z.infer<typeof LL>;
|
||||
type _LL = {
|
||||
value: number;
|
||||
next: _LL | null;
|
||||
};
|
||||
expectTypeOf<LL>().toEqualTypeOf<_LL>();
|
||||
|
||||
LL.parse(data);
|
||||
});
|
||||
|
||||
test("mutual recursion - native", () => {
|
||||
const Alazy = z.object({
|
||||
val: z.number(),
|
||||
get b() {
|
||||
return Blazy;
|
||||
},
|
||||
});
|
||||
|
||||
const Blazy = z.object({
|
||||
val: z.number(),
|
||||
get a() {
|
||||
return Alazy.optional();
|
||||
},
|
||||
});
|
||||
const testData = {
|
||||
val: 1,
|
||||
b: {
|
||||
val: 5,
|
||||
a: {
|
||||
val: 3,
|
||||
b: {
|
||||
val: 4,
|
||||
a: {
|
||||
val: 2,
|
||||
b: {
|
||||
val: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
type Alazy = z.infer<typeof Alazy>;
|
||||
type Blazy = z.infer<typeof Blazy>;
|
||||
interface _Alazy {
|
||||
val: number;
|
||||
b: _Blazy;
|
||||
}
|
||||
interface _Blazy {
|
||||
val: number;
|
||||
a?: _Alazy | undefined;
|
||||
}
|
||||
expectTypeOf<Alazy>().toEqualTypeOf<_Alazy>();
|
||||
expectTypeOf<Blazy>().toEqualTypeOf<_Blazy>();
|
||||
Alazy.parse(testData);
|
||||
Blazy.parse(testData.b);
|
||||
|
||||
expect(() => Alazy.parse({ val: "asdf" })).toThrow();
|
||||
});
|
||||
|
||||
test("pick and omit with getter", () => {
|
||||
const Category = z.strictObject({
|
||||
name: z.string(),
|
||||
get subcategories() {
|
||||
return z.array(Category);
|
||||
},
|
||||
});
|
||||
|
||||
type Category = z.infer<typeof Category>;
|
||||
|
||||
interface _Category {
|
||||
name: string;
|
||||
subcategories: _Category[];
|
||||
}
|
||||
expectTypeOf<Category>().toEqualTypeOf<_Category>();
|
||||
|
||||
const PickedCategory = Category.pick({ name: true });
|
||||
const OmittedCategory = Category.omit({ subcategories: true });
|
||||
|
||||
const picked = { name: "test" };
|
||||
const omitted = { name: "test" };
|
||||
|
||||
PickedCategory.parse(picked);
|
||||
OmittedCategory.parse(omitted);
|
||||
|
||||
expect(() => PickedCategory.parse({ name: "test", subcategories: [] })).toThrow();
|
||||
expect(() => OmittedCategory.parse({ name: "test", subcategories: [] })).toThrow();
|
||||
});
|
||||
|
||||
test("deferred self-recursion", () => {
|
||||
const Feature = z.object({
|
||||
title: z.string(),
|
||||
get features(): z.ZodOptional<z.ZodArray<typeof Feature>> {
|
||||
return z.optional(z.array(Feature)); //.optional();
|
||||
},
|
||||
});
|
||||
// type Feature = z.infer<typeof Feature>;
|
||||
|
||||
const Output = z.object({
|
||||
id: z.int(), //.nonnegative(),
|
||||
name: z.string(),
|
||||
get features(): z.ZodArray<typeof Feature> {
|
||||
return Feature.array();
|
||||
},
|
||||
});
|
||||
type Output = z.output<typeof Output>;
|
||||
|
||||
type _Feature = {
|
||||
title: string;
|
||||
features?: _Feature[] | undefined;
|
||||
};
|
||||
|
||||
type _Output = {
|
||||
id: number;
|
||||
name: string;
|
||||
features: _Feature[];
|
||||
};
|
||||
|
||||
// expectTypeOf<Feature>().toEqualTypeOf<_Feature>();
|
||||
expectTypeOf<Output>().toEqualTypeOf<_Output>();
|
||||
});
|
||||
|
||||
test("deferred mutual recursion", () => {
|
||||
const Slot = z.object({
|
||||
slotCode: z.string(),
|
||||
|
||||
get blocks() {
|
||||
return z.array(Block);
|
||||
},
|
||||
});
|
||||
type Slot = z.infer<typeof Slot>;
|
||||
|
||||
const Block = z.object({
|
||||
blockCode: z.string(),
|
||||
get slots() {
|
||||
return z.array(Slot).optional();
|
||||
},
|
||||
});
|
||||
type Block = z.infer<typeof Block>;
|
||||
|
||||
const Page = z.object({
|
||||
slots: z.array(Slot),
|
||||
});
|
||||
type Page = z.infer<typeof Page>;
|
||||
|
||||
type _Slot = {
|
||||
slotCode: string;
|
||||
blocks: _Block[];
|
||||
};
|
||||
type _Block = {
|
||||
blockCode: string;
|
||||
slots?: _Slot[] | undefined;
|
||||
};
|
||||
type _Page = {
|
||||
slots: _Slot[];
|
||||
};
|
||||
expectTypeOf<Slot>().toEqualTypeOf<_Slot>();
|
||||
expectTypeOf<Block>().toEqualTypeOf<_Block>();
|
||||
expectTypeOf<Page>().toEqualTypeOf<_Page>();
|
||||
});
|
||||
|
||||
test("mutual recursion with meta", () => {
|
||||
const A = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
get b() {
|
||||
return B;
|
||||
},
|
||||
})
|
||||
.readonly()
|
||||
.meta({ id: "A" })
|
||||
.optional();
|
||||
|
||||
const B = z
|
||||
.object({
|
||||
name: z.string(),
|
||||
get a() {
|
||||
return A;
|
||||
},
|
||||
})
|
||||
.readonly()
|
||||
.meta({ id: "B" });
|
||||
|
||||
type A = z.infer<typeof A>;
|
||||
type B = z.infer<typeof B>;
|
||||
|
||||
type _A =
|
||||
| Readonly<{
|
||||
name: string;
|
||||
b: _B;
|
||||
}>
|
||||
| undefined;
|
||||
// | undefined;
|
||||
type _B = Readonly<{
|
||||
name: string;
|
||||
a?: _A;
|
||||
}>;
|
||||
expectTypeOf<A>().toEqualTypeOf<_A>();
|
||||
expectTypeOf<B>().toEqualTypeOf<_B>();
|
||||
});
|
||||
|
||||
test("recursion compatibility", () => {
|
||||
// array
|
||||
const A = z.object({
|
||||
get array() {
|
||||
return A.array();
|
||||
},
|
||||
get optional() {
|
||||
return A.optional();
|
||||
},
|
||||
get nullable() {
|
||||
return A.nullable();
|
||||
},
|
||||
get nonoptional() {
|
||||
return A.nonoptional();
|
||||
},
|
||||
get readonly() {
|
||||
return A.readonly();
|
||||
},
|
||||
get describe() {
|
||||
return A.describe("A recursive type");
|
||||
},
|
||||
get meta() {
|
||||
return A.meta({ description: "A recursive type" });
|
||||
},
|
||||
get pipe() {
|
||||
return A.pipe(z.any());
|
||||
},
|
||||
get strict() {
|
||||
return A.strict();
|
||||
},
|
||||
get tuple() {
|
||||
return z.tuple([A, A]);
|
||||
},
|
||||
get object() {
|
||||
return z
|
||||
.object({
|
||||
subcategories: A,
|
||||
})
|
||||
.strict()
|
||||
.loose();
|
||||
},
|
||||
get union() {
|
||||
return z.union([A, A]);
|
||||
},
|
||||
get intersection() {
|
||||
return z.intersection(A, A);
|
||||
},
|
||||
get record() {
|
||||
return z.record(z.string(), A);
|
||||
},
|
||||
get map() {
|
||||
return z.map(z.string(), A);
|
||||
},
|
||||
get set() {
|
||||
return z.set(A);
|
||||
},
|
||||
get lazy() {
|
||||
return z.lazy(() => A);
|
||||
},
|
||||
get promise() {
|
||||
return z.promise(A);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// biome-ignore lint: sadf
|
||||
export type RecursiveA = z.ZodUnion<
|
||||
[
|
||||
z.ZodObject<{
|
||||
a: z.ZodDefault<RecursiveA>;
|
||||
b: z.ZodPrefault<RecursiveA>;
|
||||
c: z.ZodNonOptional<RecursiveA>;
|
||||
d: z.ZodOptional<RecursiveA>;
|
||||
e: z.ZodNullable<RecursiveA>;
|
||||
g: z.ZodReadonly<RecursiveA>;
|
||||
h: z.ZodPipe<RecursiveA, z.ZodString>;
|
||||
i: z.ZodArray<RecursiveA>;
|
||||
j: z.ZodSet<RecursiveA>;
|
||||
k: z.ZodMap<RecursiveA, RecursiveA>;
|
||||
l: z.ZodRecord<z.ZodString, RecursiveA>;
|
||||
m: z.ZodUnion<[RecursiveA, RecursiveA]>;
|
||||
n: z.ZodIntersection<RecursiveA, RecursiveA>;
|
||||
o: z.ZodLazy<RecursiveA>;
|
||||
p: z.ZodPromise<RecursiveA>;
|
||||
q: z.ZodCatch<RecursiveA>;
|
||||
r: z.ZodSuccess<RecursiveA>;
|
||||
s: z.ZodTransform<RecursiveA, string>;
|
||||
t: z.ZodTuple<[RecursiveA, RecursiveA]>;
|
||||
u: z.ZodObject<{
|
||||
a: RecursiveA;
|
||||
}>;
|
||||
}>,
|
||||
]
|
||||
>;
|
||||
532
frontend/node_modules/zod/src/v4/classic/tests/refine.test.ts
generated
vendored
Normal file
532
frontend/node_modules/zod/src/v4/classic/tests/refine.test.ts
generated
vendored
Normal file
@ -0,0 +1,532 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
describe("basic refinement functionality", () => {
|
||||
test("should create a new schema instance when refining", () => {
|
||||
const obj1 = z.object({
|
||||
first: z.string(),
|
||||
second: z.string(),
|
||||
});
|
||||
const obj2 = obj1.partial().strict();
|
||||
const obj3 = obj2.refine((data) => data.first || data.second, "Either first or second should be filled in.");
|
||||
|
||||
expect(obj1 === (obj2 as any)).toEqual(false);
|
||||
expect(obj2 === (obj3 as any)).toEqual(false);
|
||||
});
|
||||
|
||||
test("should validate according to refinement logic", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
second: z.string(),
|
||||
})
|
||||
.partial()
|
||||
.strict()
|
||||
.refine((data) => data.first || data.second, "Either first or second should be filled in.");
|
||||
|
||||
// Should fail on empty object
|
||||
expect(() => schema.parse({})).toThrow();
|
||||
|
||||
// Should pass with first property
|
||||
expect(schema.parse({ first: "a" })).toEqual({ first: "a" });
|
||||
|
||||
// Should pass with second property
|
||||
expect(schema.parse({ second: "a" })).toEqual({ second: "a" });
|
||||
|
||||
// Should pass with both properties
|
||||
expect(schema.parse({ first: "a", second: "a" })).toEqual({ first: "a", second: "a" });
|
||||
});
|
||||
|
||||
test("should validate strict mode correctly", () => {
|
||||
const schema = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
second: z.string(),
|
||||
})
|
||||
.partial()
|
||||
.strict();
|
||||
|
||||
// Should throw on extra properties
|
||||
expect(() => schema.parse({ third: "adsf" })).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("refinement with custom error messages", () => {
|
||||
test("should use custom error message when validation fails", () => {
|
||||
const validationSchema = z
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
password: z.string(),
|
||||
confirmPassword: z.string(),
|
||||
})
|
||||
.refine((data) => data.password === data.confirmPassword, "Both password and confirmation must match");
|
||||
|
||||
const result = validationSchema.safeParse({
|
||||
email: "aaaa@gmail.com",
|
||||
password: "aaaaaaaa",
|
||||
confirmPassword: "bbbbbbbb",
|
||||
});
|
||||
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].message).toEqual("Both password and confirmation must match");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("async refinements", () => {
|
||||
test("should support async refinement functions", async () => {
|
||||
const validationSchema = z
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
password: z.string(),
|
||||
confirmPassword: z.string(),
|
||||
})
|
||||
.refine(
|
||||
(data) => Promise.resolve().then(() => data.password === data.confirmPassword),
|
||||
"Both password and confirmation must match"
|
||||
);
|
||||
|
||||
// Should pass with matching passwords
|
||||
const validData = {
|
||||
email: "aaaa@gmail.com",
|
||||
password: "password",
|
||||
confirmPassword: "password",
|
||||
};
|
||||
|
||||
await expect(validationSchema.parseAsync(validData)).resolves.toEqual(validData);
|
||||
|
||||
// Should fail with non-matching passwords
|
||||
await expect(
|
||||
validationSchema.parseAsync({
|
||||
email: "aaaa@gmail.com",
|
||||
password: "password",
|
||||
confirmPassword: "different",
|
||||
})
|
||||
).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("early termination options", () => {
|
||||
test("should abort early with continue: false", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.superRefine((val, ctx) => {
|
||||
if (val.length < 2) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
message: "BAD",
|
||||
continue: false,
|
||||
});
|
||||
}
|
||||
})
|
||||
.refine((_) => false);
|
||||
|
||||
const result = schema.safeParse("");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
expect(result.error.issues[0].message).toEqual("BAD");
|
||||
}
|
||||
});
|
||||
|
||||
test("should abort early with fatal: true", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.superRefine((val, ctx) => {
|
||||
if (val.length < 2) {
|
||||
ctx.addIssue({
|
||||
code: "custom",
|
||||
fatal: true,
|
||||
message: "BAD",
|
||||
});
|
||||
}
|
||||
})
|
||||
.refine((_) => false);
|
||||
|
||||
const result = schema.safeParse("");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
expect(result.error.issues[0].message).toEqual("BAD");
|
||||
}
|
||||
});
|
||||
|
||||
test("should abort early with abort flag", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.refine((_) => false, { abort: true })
|
||||
.refine((_) => false);
|
||||
|
||||
const result = schema.safeParse("");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("custom error paths", () => {
|
||||
test("should use custom path in error message", async () => {
|
||||
const result = await z
|
||||
.object({ password: z.string(), confirm: z.string() })
|
||||
.refine((data) => data.confirm === data.password, { path: ["confirm"] })
|
||||
.safeParse({ password: "asdf", confirm: "qewr" });
|
||||
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues[0].path).toEqual(["confirm"]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("superRefine functionality", () => {
|
||||
test("should support multiple validation rules", () => {
|
||||
const Strings = z.array(z.string()).superRefine((val, ctx) => {
|
||||
if (val.length > 3) {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: "too_big",
|
||||
origin: "array",
|
||||
maximum: 3,
|
||||
inclusive: true,
|
||||
exact: true,
|
||||
message: "Too many items 😡",
|
||||
});
|
||||
}
|
||||
|
||||
if (val.length !== new Set(val).size) {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: "custom",
|
||||
message: `No duplicates allowed.`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Should fail with too many items and duplicates
|
||||
const result = Strings.safeParse(["asfd", "asfd", "asfd", "asfd"]);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
expect(result.error.issues[0].message).toEqual("Too many items 😡");
|
||||
expect(result.error.issues[1].message).toEqual("No duplicates allowed.");
|
||||
}
|
||||
|
||||
// Should pass with valid input
|
||||
const validArray = ["asfd", "qwer"];
|
||||
expect(Strings.parse(validArray)).toEqual(validArray);
|
||||
});
|
||||
|
||||
test("should support async superRefine", async () => {
|
||||
const Strings = z.array(z.string()).superRefine(async (val, ctx) => {
|
||||
if (val.length > 3) {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: "too_big",
|
||||
origin: "array",
|
||||
maximum: 3,
|
||||
inclusive: true,
|
||||
message: "Too many items 😡",
|
||||
});
|
||||
}
|
||||
|
||||
if (val.length !== new Set(val).size) {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: "custom",
|
||||
message: `No duplicates allowed.`,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Should fail with too many items and duplicates
|
||||
const result = await Strings.safeParseAsync(["asfd", "asfd", "asfd", "asfd"]);
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(2);
|
||||
}
|
||||
|
||||
// Should pass with valid input
|
||||
const validArray = ["asfd", "qwer"];
|
||||
await expect(Strings.parseAsync(validArray)).resolves.toEqual(validArray);
|
||||
});
|
||||
|
||||
test("should accept string as shorthand for custom error message", () => {
|
||||
const schema = z.string().superRefine((_, ctx) => {
|
||||
ctx.addIssue("bad stuff");
|
||||
});
|
||||
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues).toHaveLength(1);
|
||||
expect(result.error.issues[0].message).toEqual("bad stuff");
|
||||
}
|
||||
});
|
||||
|
||||
test("should respect fatal flag in superRefine", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.superRefine((val, ctx) => {
|
||||
if (val === "") {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: "custom",
|
||||
message: "foo",
|
||||
fatal: true,
|
||||
});
|
||||
}
|
||||
})
|
||||
.superRefine((val, ctx) => {
|
||||
if (val !== " ") {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: "custom",
|
||||
message: "bar",
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const result = schema.safeParse("");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues.length).toEqual(1);
|
||||
expect(result.error.issues[0].message).toEqual("foo");
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("chained refinements", () => {
|
||||
test("should collect all validation errors when appropriate", () => {
|
||||
const objectSchema = z
|
||||
.object({
|
||||
length: z.number(),
|
||||
size: z.number(),
|
||||
})
|
||||
.refine(({ length }) => length > 5, {
|
||||
path: ["length"],
|
||||
message: "length greater than 5",
|
||||
})
|
||||
.refine(({ size }) => size > 7, {
|
||||
path: ["size"],
|
||||
message: "size greater than 7",
|
||||
});
|
||||
|
||||
// Should fail with one error
|
||||
const r1 = objectSchema.safeParse({
|
||||
length: 4,
|
||||
size: 9,
|
||||
});
|
||||
expect(r1.success).toEqual(false);
|
||||
if (!r1.success) {
|
||||
expect(r1.error.issues.length).toEqual(1);
|
||||
expect(r1.error.issues[0].path).toEqual(["length"]);
|
||||
}
|
||||
|
||||
// Should fail with two errors
|
||||
const r2 = objectSchema.safeParse({
|
||||
length: 4,
|
||||
size: 3,
|
||||
});
|
||||
expect(r2.success).toEqual(false);
|
||||
if (!r2.success) {
|
||||
expect(r2.error.issues.length).toEqual(2);
|
||||
}
|
||||
|
||||
// Should pass with valid input
|
||||
const validData = {
|
||||
length: 6,
|
||||
size: 8,
|
||||
};
|
||||
expect(objectSchema.parse(validData)).toEqual(validData);
|
||||
});
|
||||
});
|
||||
|
||||
// Commented tests can be uncommented once type-checking issues are resolved
|
||||
/*
|
||||
describe("type refinement", () => {
|
||||
test("refinement type guard", () => {
|
||||
const validationSchema = z.object({
|
||||
a: z.string().refine((s): s is "a" => s === "a"),
|
||||
});
|
||||
type Input = z.input<typeof validationSchema>;
|
||||
type Schema = z.infer<typeof validationSchema>;
|
||||
|
||||
expectTypeOf<Input["a"]>().not.toEqualTypeOf<"a">();
|
||||
expectTypeOf<Input["a"]>().toEqualTypeOf<string>();
|
||||
|
||||
expectTypeOf<Schema["a"]>().toEqualTypeOf<"a">();
|
||||
expectTypeOf<Schema["a"]>().not.toEqualTypeOf<string>();
|
||||
});
|
||||
|
||||
test("superRefine - type narrowing", () => {
|
||||
type NarrowType = { type: string; age: number };
|
||||
const schema = z
|
||||
.object({
|
||||
type: z.string(),
|
||||
age: z.number(),
|
||||
})
|
||||
.nullable()
|
||||
.superRefine((arg, ctx): arg is NarrowType => {
|
||||
if (!arg) {
|
||||
// still need to make a call to ctx.addIssue
|
||||
ctx.addIssue({
|
||||
input: arg,
|
||||
code: "custom",
|
||||
message: "cannot be null",
|
||||
fatal: true,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<NarrowType>();
|
||||
|
||||
expect(schema.safeParse({ type: "test", age: 0 }).success).toEqual(true);
|
||||
expect(schema.safeParse(null).success).toEqual(false);
|
||||
});
|
||||
|
||||
test("chained mixed refining types", () => {
|
||||
type firstRefinement = { first: string; second: number; third: true };
|
||||
type secondRefinement = { first: "bob"; second: number; third: true };
|
||||
type thirdRefinement = { first: "bob"; second: 33; third: true };
|
||||
const schema = z
|
||||
.object({
|
||||
first: z.string(),
|
||||
second: z.number(),
|
||||
third: z.boolean(),
|
||||
})
|
||||
.nullable()
|
||||
.refine((arg): arg is firstRefinement => !!arg?.third)
|
||||
.superRefine((arg, ctx): arg is secondRefinement => {
|
||||
expectTypeOf<typeof arg>().toEqualTypeOf<firstRefinement>();
|
||||
if (arg.first !== "bob") {
|
||||
ctx.addIssue({
|
||||
input: arg,
|
||||
code: "custom",
|
||||
message: "`first` property must be `bob`",
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.refine((arg): arg is thirdRefinement => {
|
||||
expectTypeOf<typeof arg>().toEqualTypeOf<secondRefinement>();
|
||||
return arg.second === 33;
|
||||
});
|
||||
|
||||
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<thirdRefinement>();
|
||||
});
|
||||
});
|
||||
*/
|
||||
|
||||
test("when", () => {
|
||||
const schema = z
|
||||
.strictObject({
|
||||
password: z.string().min(8),
|
||||
confirmPassword: z.string(),
|
||||
other: z.string(),
|
||||
})
|
||||
.refine(
|
||||
(data) => {
|
||||
console.log("running check...");
|
||||
console.log(data);
|
||||
console.log(data.password);
|
||||
return data.password === data.confirmPassword;
|
||||
},
|
||||
{
|
||||
message: "Passwords do not match",
|
||||
path: ["confirmPassword"],
|
||||
when(payload) {
|
||||
if (payload.value === undefined) return false;
|
||||
if (payload.value === null) return false;
|
||||
// no issues with confirmPassword or password
|
||||
return payload.issues.every((iss) => iss.path?.[0] !== "confirmPassword" && iss.path?.[0] !== "password");
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
expect(schema.safeParse(undefined)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "object",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected object, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(schema.safeParse(null)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "object",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected object, received null"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(
|
||||
schema.safeParse({
|
||||
password: "asdf",
|
||||
confirmPassword: "asdfg",
|
||||
other: "qwer",
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 8,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"password"
|
||||
],
|
||||
"message": "Too small: expected string to have >=8 characters"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(
|
||||
schema.safeParse({
|
||||
password: "asdf",
|
||||
confirmPassword: "asdfg",
|
||||
other: 1234,
|
||||
})
|
||||
).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"origin": "string",
|
||||
"code": "too_small",
|
||||
"minimum": 8,
|
||||
"inclusive": true,
|
||||
"path": [
|
||||
"password"
|
||||
],
|
||||
"message": "Too small: expected string to have >=8 characters"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"other"
|
||||
],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
204
frontend/node_modules/zod/src/v4/classic/tests/registries.test.ts
generated
vendored
Normal file
204
frontend/node_modules/zod/src/v4/classic/tests/registries.test.ts
generated
vendored
Normal file
@ -0,0 +1,204 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("globalRegistry", () => {
|
||||
const reg = z.registry();
|
||||
|
||||
const a = z.string();
|
||||
reg.add(a);
|
||||
expect(reg.has(a)).toEqual(true);
|
||||
|
||||
reg.remove(a);
|
||||
expect(reg.has(a)).toEqual(false);
|
||||
|
||||
a.register(z.globalRegistry, { field: "sup" });
|
||||
expect(z.globalRegistry.has(a)).toEqual(true);
|
||||
expect(z.globalRegistry.get(a)).toEqual({ field: "sup" });
|
||||
|
||||
z.globalRegistry.remove(a);
|
||||
expect(z.globalRegistry.has(a)).toEqual(false);
|
||||
});
|
||||
|
||||
test("z.registry", () => {
|
||||
const fieldRegistry = z.registry<{ name: string; description: string }>();
|
||||
|
||||
const a = z.string();
|
||||
fieldRegistry.add(a, { name: "hello", description: "world" });
|
||||
const a_meta = fieldRegistry.get(a);
|
||||
expect(a_meta).toEqual({ name: "hello", description: "world" });
|
||||
|
||||
fieldRegistry.remove(a);
|
||||
expect(fieldRegistry.has(a)).toEqual(false);
|
||||
expect(fieldRegistry.get(a)).toEqual(undefined);
|
||||
});
|
||||
|
||||
test("z.registry no metadata", () => {
|
||||
const fieldRegistry = z.registry();
|
||||
|
||||
const a = z.string();
|
||||
fieldRegistry.add(a);
|
||||
fieldRegistry.add(z.number());
|
||||
expect(fieldRegistry.get(a)).toEqual(undefined);
|
||||
expect(fieldRegistry.has(a)).toEqual(true);
|
||||
});
|
||||
|
||||
test("z.registry with schema constraints", () => {
|
||||
const fieldRegistry = z.registry<{ name: string; description: string }, z.ZodString>();
|
||||
|
||||
const a = z.string();
|
||||
fieldRegistry.add(a, { name: "hello", description: "world" });
|
||||
// @ts-expect-error
|
||||
fieldRegistry.add(z.number(), { name: "test" });
|
||||
// @ts-expect-error
|
||||
z.number().register(fieldRegistry, { name: "test", description: "test" });
|
||||
});
|
||||
|
||||
// test("z.namedRegistry", () => {
|
||||
// const namedReg = z
|
||||
// .namedRegistry<{ name: string; description: string }>()
|
||||
// .add(z.string(), { name: "hello", description: "world" })
|
||||
// .add(z.number(), { name: "number", description: "number" });
|
||||
|
||||
// expect(namedReg.get("hello")).toEqual({
|
||||
// name: "hello",
|
||||
// description: "world",
|
||||
// });
|
||||
// expect(namedReg.has("hello")).toEqual(true);
|
||||
// expect(namedReg.get("number")).toEqual({
|
||||
// name: "number",
|
||||
// description: "number",
|
||||
// });
|
||||
|
||||
// // @ts-expect-error
|
||||
// namedReg.get("world");
|
||||
// // @ts-expect-error
|
||||
// expect(namedReg.get("world")).toEqual(undefined);
|
||||
|
||||
// const hello = namedReg.get("hello");
|
||||
// expect(hello).toEqual({ name: "hello", description: "world" });
|
||||
// expectTypeOf<typeof hello>().toEqualTypeOf<{
|
||||
// name: "hello";
|
||||
// description: "world";
|
||||
// }>();
|
||||
// expectTypeOf<typeof namedReg.items>().toEqualTypeOf<{
|
||||
// hello: { name: "hello"; description: "world" };
|
||||
// number: { name: "number"; description: "number" };
|
||||
// }>();
|
||||
// });
|
||||
|
||||
test("output type in registry meta", () => {
|
||||
const reg = z.registry<{ out: z.$output }>();
|
||||
const a = z.string();
|
||||
reg.add(a, { out: "asdf" });
|
||||
// @ts-expect-error
|
||||
reg.add(a, 1234);
|
||||
expectTypeOf(reg.get(a)).toEqualTypeOf<{ out: string } | undefined>();
|
||||
});
|
||||
|
||||
test("output type in registry meta - objects and arrays", () => {
|
||||
const reg = z.registry<{ name: string; examples: z.$output[] }>();
|
||||
const a = z.string();
|
||||
reg.add(a, { name: "hello", examples: ["world"] });
|
||||
|
||||
// @ts-expect-error
|
||||
reg.add(a, { name: "hello", examples: "world" });
|
||||
expectTypeOf(reg.get(a)).toEqualTypeOf<{ name: string; examples: string[] } | undefined>();
|
||||
});
|
||||
|
||||
test("input type in registry meta", () => {
|
||||
const reg = z.registry<{ in: z.$input }>();
|
||||
const a = z.pipe(z.number(), z.transform(String));
|
||||
reg.add(a, { in: 1234 });
|
||||
// @ts-expect-error
|
||||
reg.add(a, "1234");
|
||||
expectTypeOf(reg.get(a)).toEqualTypeOf<{ in: number } | undefined>();
|
||||
});
|
||||
|
||||
test("input type in registry meta - objects and arrays", () => {
|
||||
const reg = z.registry<{ name: string; examples: z.$input[] }>();
|
||||
const a = z.pipe(z.number(), z.transform(String));
|
||||
reg.add(a, { name: "hello", examples: [1234] });
|
||||
|
||||
// @ts-expect-error
|
||||
reg.add(a, { name: "hello", examples: "world" });
|
||||
expectTypeOf(reg.get(a)).toEqualTypeOf<{ name: string; examples: number[] } | undefined>();
|
||||
});
|
||||
|
||||
test(".meta method", () => {
|
||||
const a1 = z.string();
|
||||
const a2 = a1.meta({ name: "hello" });
|
||||
|
||||
expect(a1.meta()).toEqual(undefined);
|
||||
expect(a2.meta()).toEqual({ name: "hello" });
|
||||
expect(a1 === a2).toEqual(false);
|
||||
});
|
||||
|
||||
test(".meta metadata does not bubble up", () => {
|
||||
const a1 = z.string().meta({ name: "hello" });
|
||||
const a2 = a1.optional();
|
||||
|
||||
expect(a1.meta()).toEqual({ name: "hello" });
|
||||
expect(a2.meta()).toEqual(undefined);
|
||||
});
|
||||
|
||||
test(".describe", () => {
|
||||
const a1 = z.string();
|
||||
const a2 = a1.describe("Hello");
|
||||
|
||||
expect(a1.description).toEqual(undefined);
|
||||
expect(a2.description).toEqual("Hello");
|
||||
});
|
||||
|
||||
test("inherit across clone", () => {
|
||||
const A = z.string().meta({ a: true });
|
||||
expect(A.meta()).toEqual({ a: true });
|
||||
const B = A.meta({ b: true });
|
||||
expect(B.meta()).toEqual({ a: true, b: true });
|
||||
const C = B.describe("hello");
|
||||
expect(C.meta()).toEqual({ a: true, b: true, description: "hello" });
|
||||
});
|
||||
|
||||
test("loose examples", () => {
|
||||
z.string().register(z.globalRegistry, {
|
||||
examples: ["example"],
|
||||
});
|
||||
});
|
||||
|
||||
test("function meta witout replacement", () => {
|
||||
const myReg = z.registry<{
|
||||
defaulter: (arg: string, test: boolean) => number;
|
||||
}>();
|
||||
|
||||
const mySchema = z.date();
|
||||
myReg.add(mySchema, {
|
||||
defaulter: (arg, _test) => {
|
||||
return arg.length;
|
||||
},
|
||||
});
|
||||
|
||||
expect(myReg.get(mySchema)!.defaulter("hello", true)).toEqual(5);
|
||||
});
|
||||
|
||||
test("function meta with replacement", () => {
|
||||
const myReg = z.registry<{
|
||||
defaulter: (arg: z.$input, test: boolean) => z.$output;
|
||||
}>();
|
||||
|
||||
const mySchema = z.string().transform((val) => val.length);
|
||||
myReg.add(mySchema, {
|
||||
defaulter: (arg, _test) => {
|
||||
return arg.length;
|
||||
},
|
||||
});
|
||||
|
||||
expect(myReg.get(mySchema)!.defaulter("hello", true)).toEqual(5);
|
||||
});
|
||||
|
||||
test("test .clear()", () => {
|
||||
const reg = z.registry();
|
||||
const a = z.string();
|
||||
reg.add(a);
|
||||
expect(reg.has(a)).toEqual(true);
|
||||
reg.clear();
|
||||
expect(reg.has(a)).toEqual(false);
|
||||
});
|
||||
179
frontend/node_modules/zod/src/v4/classic/tests/set.test.ts
generated
vendored
Normal file
179
frontend/node_modules/zod/src/v4/classic/tests/set.test.ts
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const stringSet = z.set(z.string());
|
||||
type stringSet = z.infer<typeof stringSet>;
|
||||
|
||||
const minTwo = z.set(z.string()).min(2);
|
||||
const maxTwo = z.set(z.string()).max(2);
|
||||
const justTwo = z.set(z.string()).size(2);
|
||||
const nonEmpty = z.set(z.string()).nonempty();
|
||||
const nonEmptyMax = z.set(z.string()).nonempty().max(2);
|
||||
|
||||
test("type inference", () => {
|
||||
expectTypeOf<stringSet>().toEqualTypeOf<Set<string>>();
|
||||
});
|
||||
|
||||
test("valid parse", () => {
|
||||
const result = stringSet.safeParse(new Set(["first", "second"]));
|
||||
expect(result.success).toEqual(true);
|
||||
expect(result.data!.has("first")).toEqual(true);
|
||||
expect(result.data!.has("second")).toEqual(true);
|
||||
expect(result.data!.has("third")).toEqual(false);
|
||||
|
||||
expect(() => {
|
||||
minTwo.parse(new Set(["a", "b"]));
|
||||
minTwo.parse(new Set(["a", "b", "c"]));
|
||||
maxTwo.parse(new Set(["a", "b"]));
|
||||
maxTwo.parse(new Set(["a"]));
|
||||
justTwo.parse(new Set(["a", "b"]));
|
||||
nonEmpty.parse(new Set(["a"]));
|
||||
nonEmptyMax.parse(new Set(["a"]));
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
test("valid parse async", async () => {
|
||||
const result = await stringSet.spa(new Set(["first", "second"]));
|
||||
expect(result.success).toEqual(true);
|
||||
expect(result.data!.has("first")).toEqual(true);
|
||||
expect(result.data!.has("second")).toEqual(true);
|
||||
expect(result.data!.has("third")).toEqual(false);
|
||||
|
||||
const asyncResult = await stringSet.safeParse(new Set(["first", "second"]));
|
||||
expect(asyncResult.success).toEqual(true);
|
||||
expect(asyncResult.data!.has("first")).toEqual(true);
|
||||
expect(asyncResult.data!.has("second")).toEqual(true);
|
||||
expect(asyncResult.data!.has("third")).toEqual(false);
|
||||
});
|
||||
|
||||
test("valid parse: size-related methods", () => {
|
||||
expect(() => {
|
||||
minTwo.parse(new Set(["a", "b"]));
|
||||
minTwo.parse(new Set(["a", "b", "c"]));
|
||||
maxTwo.parse(new Set(["a", "b"]));
|
||||
maxTwo.parse(new Set(["a"]));
|
||||
justTwo.parse(new Set(["a", "b"]));
|
||||
nonEmpty.parse(new Set(["a"]));
|
||||
nonEmptyMax.parse(new Set(["a"]));
|
||||
}).not.toThrow();
|
||||
|
||||
const sizeZeroResult = stringSet.parse(new Set());
|
||||
expect(sizeZeroResult.size).toBe(0);
|
||||
|
||||
const sizeTwoResult = minTwo.parse(new Set(["a", "b"]));
|
||||
expect(sizeTwoResult.size).toBe(2);
|
||||
});
|
||||
|
||||
test("failing when parsing empty set in nonempty ", () => {
|
||||
const result = nonEmpty.safeParse(new Set());
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error!.issues[0].code).toEqual("too_small");
|
||||
});
|
||||
|
||||
test("failing when set is smaller than min() ", () => {
|
||||
const result = minTwo.safeParse(new Set(["just_one"]));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error!.issues[0].code).toEqual("too_small");
|
||||
});
|
||||
|
||||
test("failing when set is bigger than max() ", () => {
|
||||
const result = maxTwo.safeParse(new Set(["one", "two", "three"]));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error!.issues[0].code).toEqual("too_big");
|
||||
});
|
||||
|
||||
test("doesn’t throw when an empty set is given", () => {
|
||||
const result = stringSet.safeParse(new Set([]));
|
||||
expect(result.success).toEqual(true);
|
||||
});
|
||||
|
||||
test("throws when a Map is given", () => {
|
||||
const result = stringSet.safeParse(new Map([]));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "set",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected set, received Map"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("throws when the given set has invalid input", () => {
|
||||
const result = stringSet.safeParse(new Set([Symbol()]));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(1);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received symbol"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("throws when the given set has multiple invalid entries", () => {
|
||||
const result = stringSet.safeParse(new Set([1, 2] as any[]));
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!.issues.length).toEqual(2);
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("min/max", async () => {
|
||||
const schema = z.set(z.string()).min(4).max(5);
|
||||
|
||||
const r1 = schema.safeParse(new Set(["a", "b", "c", "d"]));
|
||||
expect(r1.success).toEqual(true);
|
||||
|
||||
const r2 = schema.safeParse(new Set(["a", "b", "c"]));
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"message": "Too small: expected set to have >4 items",
|
||||
"minimum": 4,
|
||||
"origin": "set",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
|
||||
const r3 = schema.safeParse(new Set(["a", "b", "c", "d", "e", "f"]));
|
||||
expect(r3.success).toEqual(false);
|
||||
expect(r3.error!.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"maximum": 5,
|
||||
"message": "Too big: expected set to have <5 items",
|
||||
"origin": "set",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
57
frontend/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts
generated
vendored
Normal file
57
frontend/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("length checks", async () => {
|
||||
const schema = z.string();
|
||||
const result = await schema["~standard"].validate(12);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"issues": [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received number",
|
||||
"path": [],
|
||||
},
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("length checks", async () => {
|
||||
const schema = z.string();
|
||||
const result = await schema["~standard"].validate("asdf");
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"value": "asdf",
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("length checks", async () => {
|
||||
const schema = z.string().refine(async (val) => val.length > 5);
|
||||
const result = await schema["~standard"].validate(12);
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"issues": [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received number",
|
||||
"path": [],
|
||||
},
|
||||
],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("length checks", async () => {
|
||||
const schema = z.string().refine(async (val) => val.length > 5);
|
||||
const result = await schema["~standard"].validate("234134134");
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"value": "234134134",
|
||||
}
|
||||
`);
|
||||
});
|
||||
109
frontend/node_modules/zod/src/v4/classic/tests/string-formats.test.ts
generated
vendored
Normal file
109
frontend/node_modules/zod/src/v4/classic/tests/string-formats.test.ts
generated
vendored
Normal file
@ -0,0 +1,109 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("string format methods", () => {
|
||||
const a = z.email().min(10);
|
||||
const b = z.email().max(10);
|
||||
const c = z.email().length(10);
|
||||
const d = z.email().uppercase();
|
||||
const e = z.email().lowercase();
|
||||
|
||||
// Positive and negative cases for `a`
|
||||
expect(a.safeParse("longemail@example.com").success).toBe(true); // Positive
|
||||
expect(a.safeParse("ort@e.co").success).toBe(false); // Negative
|
||||
|
||||
// Positive and negative cases for `b`
|
||||
expect(b.safeParse("sho@e.co").success).toBe(true); // Positive
|
||||
expect(b.safeParse("longemail@example.com").success).toBe(false); // Negative
|
||||
|
||||
// Positive and negative cases for `c`
|
||||
expect(c.safeParse("56780@e.co").success).toBe(true); // Positive
|
||||
expect(c.safeParse("shoasdfasdfrt@e.co").success).toBe(false); // Negative
|
||||
|
||||
// Positive and negative cases for `d`
|
||||
expect(d.safeParse("EMAIL@EXAMPLE.COM").success).toBe(true); // Positive
|
||||
expect(d.safeParse("email@example.com").success).toBe(false); // Negative
|
||||
|
||||
// Positive and negative cases for `e`
|
||||
expect(e.safeParse("email@example.com").success).toBe(true); // Positive
|
||||
expect(e.safeParse("EMAIL@EXAMPLE.COM").success).toBe(false); // Negative
|
||||
});
|
||||
|
||||
test("z.stringFormat", () => {
|
||||
const ccRegex = /^(?:\d{14,19}|\d{4}(?: \d{3,6}){2,4}|\d{4}(?:-\d{3,6}){2,4})$/u;
|
||||
|
||||
const a = z
|
||||
.stringFormat("creditCard", (val) => ccRegex.test(val), {
|
||||
error: `Invalid credit card number`,
|
||||
})
|
||||
.refine((_) => false, "Also bad");
|
||||
|
||||
expect(a.safeParse("asdf")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "creditCard",
|
||||
"path": [],
|
||||
"message": "Invalid credit card number"
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Also bad"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(a.safeParse("1234-5678-9012-3456")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Also bad"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(a.def.pattern).toMatchInlineSnapshot(`undefined`);
|
||||
|
||||
const b = z
|
||||
.stringFormat("creditCard", ccRegex, {
|
||||
abort: true,
|
||||
error: `Invalid credit card number`,
|
||||
})
|
||||
.refine((_) => false, "Also bad");
|
||||
|
||||
expect(b.safeParse("asdf")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "creditCard",
|
||||
"path": [],
|
||||
"message": "Invalid credit card number"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(b.safeParse("1234-5678-9012-3456")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Also bad"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(b.def.pattern).toMatchInlineSnapshot(
|
||||
`/\\^\\(\\?:\\\\d\\{14,19\\}\\|\\\\d\\{4\\}\\(\\?: \\\\d\\{3,6\\}\\)\\{2,4\\}\\|\\\\d\\{4\\}\\(\\?:-\\\\d\\{3,6\\}\\)\\{2,4\\}\\)\\$/u`
|
||||
);
|
||||
});
|
||||
881
frontend/node_modules/zod/src/v4/classic/tests/string.test.ts
generated
vendored
Normal file
881
frontend/node_modules/zod/src/v4/classic/tests/string.test.ts
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
66
frontend/node_modules/zod/src/v4/classic/tests/stringbool.test.ts
generated
vendored
Normal file
66
frontend/node_modules/zod/src/v4/classic/tests/stringbool.test.ts
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("z.stringbool", () => {
|
||||
const a = z.stringbool();
|
||||
type a = z.infer<typeof a>;
|
||||
expectTypeOf<a>().toEqualTypeOf<boolean>();
|
||||
type a_in = z.input<typeof a>;
|
||||
expectTypeOf<a_in>().toEqualTypeOf<string>();
|
||||
|
||||
expect(z.parse(a, "true")).toEqual(true);
|
||||
expect(z.parse(a, "yes")).toEqual(true);
|
||||
expect(z.parse(a, "1")).toEqual(true);
|
||||
expect(z.parse(a, "on")).toEqual(true);
|
||||
expect(z.parse(a, "y")).toEqual(true);
|
||||
expect(z.parse(a, "enabled")).toEqual(true);
|
||||
expect(z.parse(a, "TRUE")).toEqual(true);
|
||||
|
||||
expect(z.parse(a, "false")).toEqual(false);
|
||||
expect(z.parse(a, "no")).toEqual(false);
|
||||
expect(z.parse(a, "0")).toEqual(false);
|
||||
expect(z.parse(a, "off")).toEqual(false);
|
||||
expect(z.parse(a, "n")).toEqual(false);
|
||||
expect(z.parse(a, "disabled")).toEqual(false);
|
||||
expect(z.parse(a, "FALSE")).toEqual(false);
|
||||
|
||||
expect(z.safeParse(a, "other")).toMatchObject({ success: false });
|
||||
expect(z.safeParse(a, "")).toMatchObject({ success: false });
|
||||
expect(z.safeParse(a, undefined)).toMatchObject({ success: false });
|
||||
expect(z.safeParse(a, {})).toMatchObject({ success: false });
|
||||
expect(z.safeParse(a, true)).toMatchObject({ success: false });
|
||||
expect(z.safeParse(a, false)).toMatchObject({ success: false });
|
||||
});
|
||||
|
||||
test("custom values", () => {
|
||||
const b = z.stringbool({
|
||||
truthy: ["y"],
|
||||
falsy: ["N"],
|
||||
});
|
||||
expect(z.parse(b, "y")).toEqual(true);
|
||||
expect(z.parse(b, "Y")).toEqual(true);
|
||||
expect(z.parse(b, "n")).toEqual(false);
|
||||
expect(z.parse(b, "N")).toEqual(false);
|
||||
expect(z.safeParse(b, "true")).toMatchObject({ success: false });
|
||||
expect(z.safeParse(b, "false")).toMatchObject({ success: false });
|
||||
});
|
||||
|
||||
test("custom values - case sensitive", () => {
|
||||
const c = z.stringbool({
|
||||
truthy: ["y"],
|
||||
falsy: ["N"],
|
||||
case: "sensitive",
|
||||
});
|
||||
expect(z.parse(c, "y")).toEqual(true);
|
||||
expect(z.safeParse(c, "Y")).toMatchObject({ success: false });
|
||||
expect(z.parse(c, "N")).toEqual(false);
|
||||
expect(z.safeParse(c, "n")).toMatchObject({ success: false });
|
||||
expect(z.safeParse(c, "TRUE")).toMatchObject({ success: false });
|
||||
});
|
||||
|
||||
// test custom error messages
|
||||
test("z.stringbool with custom error messages", () => {
|
||||
const a = z.stringbool("wrong!");
|
||||
|
||||
expect(() => a.parse("")).toThrowError("wrong!");
|
||||
});
|
||||
758
frontend/node_modules/zod/src/v4/classic/tests/template-literal.test.ts
generated
vendored
Normal file
758
frontend/node_modules/zod/src/v4/classic/tests/template-literal.test.ts
generated
vendored
Normal file
@ -0,0 +1,758 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
const empty = z.templateLiteral([]);
|
||||
const hello = z.templateLiteral(["hello"]);
|
||||
const world = z.templateLiteral(["", z.literal("world")]);
|
||||
const one = z.templateLiteral([1]);
|
||||
const two = z.templateLiteral(["", z.literal(2)]);
|
||||
const truee = z.templateLiteral([true]);
|
||||
const anotherTrue = z.templateLiteral(["", z.literal(true)]);
|
||||
const falsee = z.templateLiteral([false]);
|
||||
const anotherFalse = z.templateLiteral(["", z.literal(false)]);
|
||||
const nulll = z.templateLiteral([null]);
|
||||
const anotherNull = z.templateLiteral(["", z.null()]);
|
||||
const undefinedd = z.templateLiteral([undefined]);
|
||||
const anotherUndefined = z.templateLiteral(["", z.undefined()]);
|
||||
const anyString = z.templateLiteral(["", z.string()]);
|
||||
const lazyString = z.templateLiteral(["", z.lazy(() => z.string())]);
|
||||
const anyNumber = z.templateLiteral(["", z.number()]);
|
||||
const anyInt = z.templateLiteral(["", z.number().int()]);
|
||||
// const anyFiniteNumber = z.templateLiteral(["", z.number().finite()]);
|
||||
// const anyNegativeNumber = z.templateLiteral(["", z.number().negative()]);
|
||||
// const anyPositiveNumber = z.templateLiteral(["", z.number().positive()]);
|
||||
// const zeroButInADumbWay = z.templateLiteral(["", z.number().nonnegative().nonpositive()]);
|
||||
// const finiteButInADumbWay = z.templateLiteral(["", z.number().min(5).max(10)]);
|
||||
const bool = z.templateLiteral(["", z.boolean()]);
|
||||
const bigone = z.templateLiteral(["", z.literal(BigInt(1))]);
|
||||
const anyBigint = z.templateLiteral(["", z.bigint()]);
|
||||
const nullableYo = z.templateLiteral(["", z.nullable(z.literal("yo"))]);
|
||||
const nullableString = z.templateLiteral(["", z.nullable(z.string())]);
|
||||
const optionalYeah = z.templateLiteral(["", z.literal("yeah").optional()]);
|
||||
|
||||
const optionalString = z.templateLiteral(["", z.string().optional()]);
|
||||
const optionalNumber = z.templateLiteral(["", z.number().optional()]);
|
||||
const nullishBruh = z.templateLiteral(["", z.literal("bruh").nullish()]);
|
||||
const nullishString = z.templateLiteral(["", z.string().nullish()]);
|
||||
const cuid = z.templateLiteral(["", z.string().cuid()]);
|
||||
const cuidZZZ = z.templateLiteral(["", z.string().cuid(), "ZZZ"]);
|
||||
const cuid2 = z.templateLiteral(["", z.string().cuid2()]);
|
||||
const datetime = z.templateLiteral(["", z.string().datetime()]);
|
||||
const email = z.templateLiteral(["", z.string().email()]);
|
||||
// const ip = z.templateLiteral(["", z.string().ip()]);
|
||||
const ipv4 = z.templateLiteral(["", z.string().ipv4()]);
|
||||
const ipv6 = z.templateLiteral(["", z.string().ipv6()]);
|
||||
const ulid = z.templateLiteral(["", z.string().ulid()]);
|
||||
const uuid = z.templateLiteral(["", z.string().uuid()]);
|
||||
const stringAToZ = z.templateLiteral(["", z.string().regex(/^[a-z]+$/)]);
|
||||
const stringStartsWith = z.templateLiteral(["", z.string().startsWith("hello")]);
|
||||
const stringEndsWith = z.templateLiteral(["", z.string().endsWith("world")]);
|
||||
const stringMax5 = z.templateLiteral(["", z.string().max(5)]);
|
||||
const stringMin5 = z.templateLiteral(["", z.string().min(5)]);
|
||||
const stringLen5 = z.templateLiteral(["", z.string().length(5)]);
|
||||
const stringMin5Max10 = z.templateLiteral(["", z.string().min(5).max(10)]);
|
||||
const stringStartsWithMax5 = z.templateLiteral(["", z.string().startsWith("hello").max(5)]);
|
||||
const brandedString = z.templateLiteral(["", z.string().min(1).brand("myBrand")]);
|
||||
// const anything = z.templateLiteral(["", z.any()]);
|
||||
|
||||
const url = z.templateLiteral(["https://", z.string().regex(/\w+/), ".", z.enum(["com", "net"])]);
|
||||
|
||||
const measurement = z.templateLiteral([
|
||||
"",
|
||||
z.number().finite(),
|
||||
z.enum(["px", "em", "rem", "vh", "vw", "vmin", "vmax"]).optional(),
|
||||
]);
|
||||
|
||||
const connectionString = z.templateLiteral([
|
||||
"mongodb://",
|
||||
z
|
||||
.templateLiteral([
|
||||
"",
|
||||
z.string().regex(/\w+/).describe("username"),
|
||||
":",
|
||||
z.string().regex(/\w+/).describe("password"),
|
||||
"@",
|
||||
])
|
||||
.optional(),
|
||||
z.string().regex(/\w+/).describe("host"),
|
||||
":",
|
||||
z.number().finite().int().positive().describe("port"),
|
||||
z
|
||||
.templateLiteral([
|
||||
"/",
|
||||
z.string().regex(/\w+/).optional().describe("defaultauthdb"),
|
||||
z
|
||||
.templateLiteral([
|
||||
"?",
|
||||
z
|
||||
.string()
|
||||
.regex(/^\w+=\w+(&\w+=\w+)*$/)
|
||||
.optional()
|
||||
.describe("options"),
|
||||
])
|
||||
.optional(),
|
||||
])
|
||||
.optional(),
|
||||
]);
|
||||
|
||||
test("template literal type inference", () => {
|
||||
expectTypeOf<z.infer<typeof empty>>().toEqualTypeOf<``>();
|
||||
expectTypeOf<z.infer<typeof hello>>().toEqualTypeOf<`hello`>();
|
||||
expectTypeOf<z.infer<typeof world>>().toEqualTypeOf<`world`>();
|
||||
expectTypeOf<z.infer<typeof one>>().toEqualTypeOf<`1`>();
|
||||
expectTypeOf<z.infer<typeof two>>().toEqualTypeOf<`2`>();
|
||||
expectTypeOf<z.infer<typeof truee>>().toEqualTypeOf<`true`>();
|
||||
expectTypeOf<z.infer<typeof anotherTrue>>().toEqualTypeOf<`true`>();
|
||||
expectTypeOf<z.infer<typeof falsee>>().toEqualTypeOf<`false`>();
|
||||
expectTypeOf<z.infer<typeof anotherFalse>>().toEqualTypeOf<`false`>();
|
||||
expectTypeOf<z.infer<typeof nulll>>().toEqualTypeOf<`null`>();
|
||||
expectTypeOf<z.infer<typeof anotherNull>>().toEqualTypeOf<`null`>();
|
||||
expectTypeOf<z.infer<typeof undefinedd>>().toEqualTypeOf<``>();
|
||||
expectTypeOf<z.infer<typeof anotherUndefined>>().toEqualTypeOf<``>();
|
||||
expectTypeOf<z.infer<typeof anyString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof lazyString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof anyNumber>>().toEqualTypeOf<`${number}`>();
|
||||
expectTypeOf<z.infer<typeof anyInt>>().toEqualTypeOf<`${number}`>();
|
||||
// expectTypeOf<z.infer<typeof anyFiniteNumber>>().toEqualTypeOf<`${number}`>();
|
||||
// expectTypeOf<z.infer<typeof anyNegativeNumber>>().toEqualTypeOf<`${number}`>();
|
||||
// expectTypeOf<z.infer<typeof anyPositiveNumber>>().toEqualTypeOf<`${number}`>();
|
||||
// expectTypeOf<z.infer<typeof zeroButInADumbWay>>().toEqualTypeOf<`${number}`>();
|
||||
// expectTypeOf<z.infer<typeof finiteButInADumbWay>>().toEqualTypeOf<`${number}`>();
|
||||
expectTypeOf<z.infer<typeof bool>>().toEqualTypeOf<`true` | `false`>();
|
||||
expectTypeOf<z.infer<typeof bigone>>().toEqualTypeOf<`${bigint}`>();
|
||||
expectTypeOf<z.infer<typeof anyBigint>>().toEqualTypeOf<`${bigint}`>();
|
||||
expectTypeOf<z.infer<typeof nullableYo>>().toEqualTypeOf<`yo` | `null`>();
|
||||
expectTypeOf<z.infer<typeof nullableString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof optionalYeah>>().toEqualTypeOf<`yeah` | ``>();
|
||||
expectTypeOf<z.infer<typeof optionalString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof optionalNumber>>().toEqualTypeOf<`${number}` | ``>();
|
||||
expectTypeOf<z.infer<typeof nullishBruh>>().toEqualTypeOf<`bruh` | `null` | ``>();
|
||||
expectTypeOf<z.infer<typeof nullishString>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof cuid>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof cuidZZZ>>().toEqualTypeOf<`${string}ZZZ`>();
|
||||
expectTypeOf<z.infer<typeof cuid2>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof datetime>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof email>>().toEqualTypeOf<string>();
|
||||
// expectTypeOf<z.infer<typeof ip>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof ipv4>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof ipv6>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof ulid>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof uuid>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringAToZ>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringStartsWith>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringEndsWith>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringMax5>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringMin5>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringLen5>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringMin5Max10>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof stringStartsWithMax5>>().toEqualTypeOf<string>();
|
||||
expectTypeOf<z.infer<typeof brandedString>>().toEqualTypeOf<`${string & z.core.$brand<"myBrand">}`>();
|
||||
|
||||
// expectTypeOf<z.infer<typeof anything>>().toEqualTypeOf<`${any}`>();
|
||||
|
||||
expectTypeOf<z.infer<typeof url>>().toEqualTypeOf<`https://${string}.com` | `https://${string}.net`>();
|
||||
|
||||
expectTypeOf<z.infer<typeof measurement>>().toEqualTypeOf<
|
||||
| `${number}`
|
||||
| `${number}px`
|
||||
| `${number}em`
|
||||
| `${number}rem`
|
||||
| `${number}vh`
|
||||
| `${number}vw`
|
||||
| `${number}vmin`
|
||||
| `${number}vmax`
|
||||
>();
|
||||
|
||||
expectTypeOf<z.infer<typeof connectionString>>().toEqualTypeOf<
|
||||
| `mongodb://${string}:${number}`
|
||||
| `mongodb://${string}:${number}/${string}`
|
||||
| `mongodb://${string}:${number}/${string}?${string}`
|
||||
| `mongodb://${string}:${string}@${string}:${number}`
|
||||
| `mongodb://${string}:${string}@${string}:${number}/${string}`
|
||||
| `mongodb://${string}:${string}@${string}:${number}/${string}?${string}`
|
||||
>();
|
||||
});
|
||||
|
||||
test("template literal unsupported args", () => {
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.object({})])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.array(z.object({}))])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.union([z.object({}), z.string()])])
|
||||
).toThrow();
|
||||
// @ts-expect-error
|
||||
expect(() => z.templateLiteral([z.date()])).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.custom<object>((_) => true)])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
z.templateLiteral([
|
||||
// @ts-expect-error
|
||||
z.discriminatedUnion("discriminator", [z.object({}), z.object({})]),
|
||||
])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.function()])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.instanceof(class MyClass {})])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.intersection(z.object({}), z.object({}))])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.map(z.string(), z.string())])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.nullable(z.object({}))])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.optional(z.object({}))])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.promise()])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.record(z.unknown())])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.set(z.string())])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.symbol()])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.tuple([z.string()])])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.unknown()])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.void()])
|
||||
).toThrow();
|
||||
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.never()])
|
||||
).toThrow();
|
||||
// @ts-expect-error
|
||||
expect(() => z.templateLiteral([z.nan()])).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.pipe(z.string(), z.string())])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.preprocess(() => true, z.boolean())])
|
||||
).toThrow();
|
||||
expect(() =>
|
||||
// @ts-expect-error
|
||||
z.templateLiteral([z.object({}).brand("brand")])
|
||||
).toThrow();
|
||||
|
||||
// these constraints aren't enforced but they shouldn't throw
|
||||
z.templateLiteral([z.number().multipleOf(2)]);
|
||||
z.templateLiteral([z.string().emoji()]);
|
||||
z.templateLiteral([z.string().url()]);
|
||||
z.templateLiteral([z.string().url()]);
|
||||
z.templateLiteral([z.string().trim()]);
|
||||
z.templateLiteral([z.string().includes("train")]);
|
||||
z.templateLiteral([z.string().toLowerCase()]);
|
||||
z.templateLiteral([z.string().toUpperCase()]);
|
||||
});
|
||||
|
||||
test("template literal parsing - success - basic cases", () => {
|
||||
expect(() => z.templateLiteral([]).parse(7)).toThrow();
|
||||
|
||||
empty.parse("");
|
||||
hello.parse("hello");
|
||||
world.parse("world");
|
||||
one.parse("1");
|
||||
two.parse("2");
|
||||
truee.parse("true");
|
||||
anotherTrue.parse("true");
|
||||
falsee.parse("false");
|
||||
anotherFalse.parse("false");
|
||||
nulll.parse("null");
|
||||
anotherNull.parse("null");
|
||||
undefinedd.parse("undefined");
|
||||
anotherUndefined.parse("undefined");
|
||||
anyString.parse("blahblahblah");
|
||||
anyString.parse("");
|
||||
lazyString.parse("blahblahblah");
|
||||
lazyString.parse("");
|
||||
anyNumber.parse("123");
|
||||
anyNumber.parse("1.23");
|
||||
anyNumber.parse("0");
|
||||
anyNumber.parse("-1.23");
|
||||
anyNumber.parse("-123");
|
||||
// anyNumber.parse("Infinity");
|
||||
// anyNumber.parse("-Infinity");
|
||||
anyInt.parse("123");
|
||||
// anyInt.parse("-123");
|
||||
// anyFiniteNumber.parse("123");
|
||||
// anyFiniteNumber.parse("1.23");
|
||||
// anyFiniteNumber.parse("0");
|
||||
// anyFiniteNumber.parse("-1.23");
|
||||
// anyFiniteNumber.parse("-123");
|
||||
// anyNegativeNumber.parse("-123");
|
||||
// anyNegativeNumber.parse("-1.23");
|
||||
// anyNegativeNumber.parse("-Infinity");
|
||||
// anyPositiveNumber.parse("123");
|
||||
// anyPositiveNumber.parse("1.23");
|
||||
// anyPositiveNumber.parse("Infinity");
|
||||
// zeroButInADumbWay.parse("0");
|
||||
// zeroButInADumbWay.parse("00000");
|
||||
// finiteButInADumbWay.parse("5");
|
||||
// finiteButInADumbWay.parse("10");
|
||||
// finiteButInADumbWay.parse("6.66");
|
||||
bool.parse("true");
|
||||
bool.parse("false");
|
||||
bigone.parse("1");
|
||||
anyBigint.parse("123456");
|
||||
anyBigint.parse("0");
|
||||
// anyBigint.parse("-123456");
|
||||
nullableYo.parse("yo");
|
||||
nullableYo.parse("null");
|
||||
nullableString.parse("abc");
|
||||
nullableString.parse("null");
|
||||
optionalYeah.parse("yeah");
|
||||
optionalYeah.parse("");
|
||||
optionalString.parse("abc");
|
||||
optionalString.parse("");
|
||||
optionalNumber.parse("123");
|
||||
optionalNumber.parse("1.23");
|
||||
optionalNumber.parse("0");
|
||||
optionalNumber.parse("-1.23");
|
||||
optionalNumber.parse("-123");
|
||||
// optionalNumber.parse("Infinity");
|
||||
// optionalNumber.parse("-Infinity");
|
||||
nullishBruh.parse("bruh");
|
||||
nullishBruh.parse("null");
|
||||
nullishBruh.parse("");
|
||||
cuid.parse("cjld2cyuq0000t3rmniod1foy");
|
||||
cuidZZZ.parse("cjld2cyuq0000t3rmniod1foyZZZ");
|
||||
cuid2.parse("tz4a98xxat96iws9zmbrgj3a");
|
||||
datetime.parse(new Date().toISOString());
|
||||
email.parse("info@example.com");
|
||||
// ip.parse("213.174.246.205");
|
||||
// ip.parse("c359:f57c:21e5:39eb:1187:e501:f936:b452");
|
||||
ipv4.parse("213.174.246.205");
|
||||
ipv6.parse("c359:f57c:21e5:39eb:1187:e501:f936:b452");
|
||||
ulid.parse("01GW3D2QZJBYB6P1Z1AE997VPW");
|
||||
uuid.parse("808989fd-3a6e-4af2-b607-737323a176f6");
|
||||
stringAToZ.parse("asudgaskhdgashd");
|
||||
stringStartsWith.parse("hello world");
|
||||
stringEndsWith.parse("hello world");
|
||||
stringMax5.parse("hello");
|
||||
stringMin5.parse("hello");
|
||||
stringLen5.parse("hello");
|
||||
stringMin5Max10.parse("hello worl");
|
||||
stringStartsWithMax5.parse("hello");
|
||||
brandedString.parse("branded string");
|
||||
});
|
||||
|
||||
test("template literal parsing - failure - basic cases", () => {
|
||||
expect(() => empty.parse("a")).toThrow();
|
||||
expect(() => hello.parse("hello!")).toThrow();
|
||||
expect(() => hello.parse("!hello")).toThrow();
|
||||
expect(() => world.parse("world!")).toThrow();
|
||||
expect(() => world.parse("!world")).toThrow();
|
||||
expect(() => one.parse("2")).toThrow();
|
||||
expect(() => one.parse("12")).toThrow();
|
||||
expect(() => one.parse("21")).toThrow();
|
||||
expect(() => two.parse("1")).toThrow();
|
||||
expect(() => two.parse("21")).toThrow();
|
||||
expect(() => two.parse("12")).toThrow();
|
||||
expect(() => truee.parse("false")).toThrow();
|
||||
expect(() => truee.parse("1true")).toThrow();
|
||||
expect(() => truee.parse("true1")).toThrow();
|
||||
expect(() => anotherTrue.parse("false")).toThrow();
|
||||
expect(() => anotherTrue.parse("1true")).toThrow();
|
||||
expect(() => anotherTrue.parse("true1")).toThrow();
|
||||
expect(() => falsee.parse("true")).toThrow();
|
||||
expect(() => falsee.parse("1false")).toThrow();
|
||||
expect(() => falsee.parse("false1")).toThrow();
|
||||
expect(() => anotherFalse.parse("true")).toThrow();
|
||||
expect(() => anotherFalse.parse("1false")).toThrow();
|
||||
expect(() => anotherFalse.parse("false1")).toThrow();
|
||||
expect(() => nulll.parse("123")).toThrow();
|
||||
expect(() => nulll.parse("null1")).toThrow();
|
||||
expect(() => nulll.parse("1null")).toThrow();
|
||||
expect(() => anotherNull.parse("123")).toThrow();
|
||||
expect(() => anotherNull.parse("null1")).toThrow();
|
||||
expect(() => anotherNull.parse("1null")).toThrow();
|
||||
expect(() => undefinedd.parse("123")).toThrow();
|
||||
expect(() => undefinedd.parse("undefined1")).toThrow();
|
||||
expect(() => undefinedd.parse("1undefined")).toThrow();
|
||||
expect(() => anotherUndefined.parse("123")).toThrow();
|
||||
expect(() => anotherUndefined.parse("undefined1")).toThrow();
|
||||
expect(() => anotherUndefined.parse("1undefined")).toThrow();
|
||||
expect(() => anyNumber.parse("2a")).toThrow();
|
||||
expect(() => anyNumber.parse("a2")).toThrow();
|
||||
expect(() => anyNumber.parse("-2a")).toThrow();
|
||||
expect(() => anyNumber.parse("a-2")).toThrow();
|
||||
expect(() => anyNumber.parse("2.5a")).toThrow();
|
||||
expect(() => anyNumber.parse("a2.5")).toThrow();
|
||||
expect(() => anyNumber.parse("Infinitya")).toThrow();
|
||||
expect(() => anyNumber.parse("aInfinity")).toThrow();
|
||||
expect(() => anyNumber.parse("-Infinitya")).toThrow();
|
||||
expect(() => anyNumber.parse("a-Infinity")).toThrow();
|
||||
expect(() => anyNumber.parse("2e5")).toThrow();
|
||||
expect(() => anyNumber.parse("2e-5")).toThrow();
|
||||
expect(() => anyNumber.parse("2e+5")).toThrow();
|
||||
expect(() => anyNumber.parse("-2e5")).toThrow();
|
||||
expect(() => anyNumber.parse("-2e-5")).toThrow();
|
||||
expect(() => anyNumber.parse("-2e+5")).toThrow();
|
||||
expect(() => anyNumber.parse("2.1e5")).toThrow();
|
||||
expect(() => anyNumber.parse("2.1e-5")).toThrow();
|
||||
expect(() => anyNumber.parse("2.1e+5")).toThrow();
|
||||
expect(() => anyNumber.parse("-2.1e5")).toThrow();
|
||||
expect(() => anyNumber.parse("-2.1e-5")).toThrow();
|
||||
expect(() => anyNumber.parse("-2.1e+5")).toThrow();
|
||||
expect(() => anyNumber.parse("-Infinity")).toThrow();
|
||||
expect(() => anyNumber.parse("Infinity")).toThrow();
|
||||
expect(() => anyInt.parse("1.23")).toThrow();
|
||||
expect(() => anyInt.parse("-1.23")).toThrow();
|
||||
expect(() => anyInt.parse("d1")).toThrow();
|
||||
expect(() => anyInt.parse("1d")).toThrow();
|
||||
// expect(() => anyFiniteNumber.parse("Infinity")).toThrow();
|
||||
// expect(() => anyFiniteNumber.parse("-Infinity")).toThrow();
|
||||
// expect(() => anyFiniteNumber.parse("123a")).toThrow();
|
||||
// expect(() => anyFiniteNumber.parse("a123")).toThrow();
|
||||
// expect(() => anyNegativeNumber.parse("0")).toThrow();
|
||||
// expect(() => anyNegativeNumber.parse("1")).toThrow();
|
||||
// expect(() => anyNegativeNumber.parse("Infinity")).toThrow();
|
||||
// expect(() => anyPositiveNumber.parse("0")).toThrow();
|
||||
// expect(() => anyPositiveNumber.parse("-1")).toThrow();
|
||||
// expect(() => anyPositiveNumber.parse("-Infinity")).toThrow();
|
||||
// expect(() => zeroButInADumbWay.parse("1")).toThrow();
|
||||
// expect(() => zeroButInADumbWay.parse("-1")).toThrow();
|
||||
// expect(() => finiteButInADumbWay.parse("Infinity")).toThrow();
|
||||
// expect(() => finiteButInADumbWay.parse("-Infinity")).toThrow();
|
||||
// expect(() => finiteButInADumbWay.parse("-5")).toThrow();
|
||||
// expect(() => finiteButInADumbWay.parse("10a")).toThrow();
|
||||
// expect(() => finiteButInADumbWay.parse("a10")).toThrow();
|
||||
expect(() => bool.parse("123")).toThrow();
|
||||
expect(() => bigone.parse("2")).toThrow();
|
||||
expect(() => bigone.parse("c1")).toThrow();
|
||||
expect(() => anyBigint.parse("1.23")).toThrow();
|
||||
expect(() => anyBigint.parse("-1.23")).toThrow();
|
||||
expect(() => anyBigint.parse("c123")).toThrow();
|
||||
expect(() => nullableYo.parse("yo1")).toThrow();
|
||||
expect(() => nullableYo.parse("1yo")).toThrow();
|
||||
expect(() => nullableYo.parse("null1")).toThrow();
|
||||
expect(() => nullableYo.parse("1null")).toThrow();
|
||||
expect(() => optionalYeah.parse("yeah1")).toThrow();
|
||||
expect(() => optionalYeah.parse("1yeah")).toThrow();
|
||||
expect(() => optionalYeah.parse("undefined")).toThrow();
|
||||
expect(() => optionalNumber.parse("123a")).toThrow();
|
||||
expect(() => optionalNumber.parse("a123")).toThrow();
|
||||
// expect(() => optionalNumber.parse("Infinitya")).toThrow();
|
||||
// expect(() => optionalNumber.parse("aInfinity")).toThrow();
|
||||
expect(() => nullishBruh.parse("bruh1")).toThrow();
|
||||
expect(() => nullishBruh.parse("1bruh")).toThrow();
|
||||
expect(() => nullishBruh.parse("null1")).toThrow();
|
||||
expect(() => nullishBruh.parse("1null")).toThrow();
|
||||
expect(() => nullishBruh.parse("undefined")).toThrow();
|
||||
expect(() => cuid.parse("bjld2cyuq0000t3rmniod1foy")).toThrow();
|
||||
expect(() => cuid.parse("cjld2cyu")).toThrow();
|
||||
expect(() => cuid.parse("cjld2 cyu")).toThrow();
|
||||
expect(() => cuid.parse("cjld2cyuq0000t3rmniod1foy ")).toThrow();
|
||||
expect(() => cuid.parse("1cjld2cyuq0000t3rmniod1foy")).toThrow();
|
||||
expect(() => cuidZZZ.parse("cjld2cyuq0000t3rmniod1foy")).toThrow();
|
||||
expect(() => cuidZZZ.parse("cjld2cyuq0000t3rmniod1foyZZY")).toThrow();
|
||||
expect(() => cuidZZZ.parse("cjld2cyuq0000t3rmniod1foyZZZ1")).toThrow();
|
||||
expect(() => cuidZZZ.parse("1cjld2cyuq0000t3rmniod1foyZZZ")).toThrow();
|
||||
expect(() => cuid2.parse("A9z4a98xxat96iws9zmbrgj3a")).toThrow();
|
||||
expect(() => cuid2.parse("tz4a98xxat96iws9zmbrgj3!")).toThrow();
|
||||
expect(() => datetime.parse("2022-01-01 00:00:00")).toThrow();
|
||||
expect(() => email.parse("info@example.com@")).toThrow();
|
||||
// expect(() => ip.parse("213.174.246:205")).toThrow();
|
||||
// expect(() => ip.parse("c359.f57c:21e5:39eb:1187:e501:f936:b452")).toThrow();
|
||||
expect(() => ipv4.parse("1213.174.246.205")).toThrow();
|
||||
expect(() => ipv4.parse("c359:f57c:21e5:39eb:1187:e501:f936:b452")).toThrow();
|
||||
expect(() => ipv6.parse("c359:f57c:21e5:39eb:1187:e501:f936:b4521")).toThrow();
|
||||
expect(() => ipv6.parse("213.174.246.205")).toThrow();
|
||||
expect(() => ulid.parse("01GW3D2QZJBYB6P1Z1AE997VPW!")).toThrow();
|
||||
expect(() => uuid.parse("808989fd-3a6e-4af2-b607-737323a176f6Z")).toThrow();
|
||||
expect(() => uuid.parse("Z808989fd-3a6e-4af2-b607-737323a176f6")).toThrow();
|
||||
expect(() => stringAToZ.parse("asdasdasd1")).toThrow();
|
||||
expect(() => stringAToZ.parse("1asdasdasd")).toThrow();
|
||||
expect(() => stringStartsWith.parse("ahello")).toThrow();
|
||||
expect(() => stringEndsWith.parse("worlda")).toThrow();
|
||||
expect(() => stringMax5.parse("123456")).toThrow();
|
||||
expect(() => stringMin5.parse("1234")).toThrow();
|
||||
expect(() => stringLen5.parse("123456")).toThrow();
|
||||
expect(() => stringLen5.parse("1234")).toThrow();
|
||||
expect(() => stringMin5Max10.parse("1234")).toThrow();
|
||||
expect(() => stringMin5Max10.parse("12345678901")).toThrow();
|
||||
|
||||
// the "startswith" overrides the max length
|
||||
// expect(() => stringStartsWithMax5.parse("hello1")).toThrow();
|
||||
expect(() => stringStartsWithMax5.parse("1hell")).toThrow();
|
||||
expect(() => brandedString.parse("")).toThrow();
|
||||
});
|
||||
|
||||
test("regexes", () => {
|
||||
expect(empty._zod.pattern.source).toMatchInlineSnapshot(`"^$"`);
|
||||
expect(hello._zod.pattern.source).toMatchInlineSnapshot(`"^hello$"`);
|
||||
expect(world._zod.pattern.source).toMatchInlineSnapshot(`"^(world)$"`);
|
||||
expect(one._zod.pattern.source).toMatchInlineSnapshot(`"^1$"`);
|
||||
expect(two._zod.pattern.source).toMatchInlineSnapshot(`"^(2)$"`);
|
||||
expect(truee._zod.pattern.source).toMatchInlineSnapshot(`"^true$"`);
|
||||
expect(anotherTrue._zod.pattern.source).toMatchInlineSnapshot(`"^(true)$"`);
|
||||
expect(falsee._zod.pattern.source).toMatchInlineSnapshot(`"^false$"`);
|
||||
expect(anotherFalse._zod.pattern.source).toMatchInlineSnapshot(`"^(false)$"`);
|
||||
expect(nulll._zod.pattern.source).toMatchInlineSnapshot(`"^null$"`);
|
||||
expect(anotherNull._zod.pattern.source).toMatchInlineSnapshot(`"^null$"`);
|
||||
expect(undefinedd._zod.pattern.source).toMatchInlineSnapshot(`"^undefined$"`);
|
||||
expect(anotherUndefined._zod.pattern.source).toMatchInlineSnapshot(`"^undefined$"`);
|
||||
expect(anyString._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{0,}$"`);
|
||||
expect(lazyString._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{0,}$"`);
|
||||
expect(anyNumber._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?$"`);
|
||||
expect(anyInt._zod.pattern.source).toMatchInlineSnapshot(`"^\\d+$"`);
|
||||
// expect(anyFiniteNumber._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?$"`);
|
||||
// expect(anyNegativeNumber._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?$"`);
|
||||
// expect(anyPositiveNumber._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?$"`);
|
||||
// expect(zeroButInADumbWay._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?$"`);
|
||||
// expect(finiteButInADumbWay._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?$"`);
|
||||
expect(bool._zod.pattern.source).toMatchInlineSnapshot(`"^true|false$"`);
|
||||
expect(bigone._zod.pattern.source).toMatchInlineSnapshot(`"^(1)$"`);
|
||||
expect(anyBigint._zod.pattern.source).toMatchInlineSnapshot(`"^\\d+n?$"`);
|
||||
expect(nullableYo._zod.pattern.source).toMatchInlineSnapshot(`"^((yo)|null)$"`);
|
||||
expect(nullableString._zod.pattern.source).toMatchInlineSnapshot(`"^([\\s\\S]{0,}|null)$"`);
|
||||
expect(optionalYeah._zod.pattern.source).toMatchInlineSnapshot(`"^((yeah))?$"`);
|
||||
expect(optionalString._zod.pattern.source).toMatchInlineSnapshot(`"^([\\s\\S]{0,})?$"`);
|
||||
expect(optionalNumber._zod.pattern.source).toMatchInlineSnapshot(`"^(-?\\d+(?:\\.\\d+)?)?$"`);
|
||||
expect(nullishBruh._zod.pattern.source).toMatchInlineSnapshot(`"^(((bruh)|null))?$"`);
|
||||
expect(nullishString._zod.pattern.source).toMatchInlineSnapshot(`"^(([\\s\\S]{0,}|null))?$"`);
|
||||
expect(cuid._zod.pattern.source).toMatchInlineSnapshot(`"^[cC][^\\s-]{8,}$"`);
|
||||
expect(cuidZZZ._zod.pattern.source).toMatchInlineSnapshot(`"^[cC][^\\s-]{8,}ZZZ$"`);
|
||||
expect(cuid2._zod.pattern.source).toMatchInlineSnapshot(`"^[0-9a-z]+$"`);
|
||||
expect(datetime._zod.pattern.source).toMatchInlineSnapshot(
|
||||
`"^(?:(?:\\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])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"`
|
||||
);
|
||||
expect(email._zod.pattern.source).toMatchInlineSnapshot(
|
||||
`"^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"`
|
||||
);
|
||||
// expect(ip._zod.pattern.source).toMatchInlineSnapshot(
|
||||
// `"^(^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$)|(^(([a-fA-F0-9]{1,4}:){7}|::([a-fA-F0-9]{1,4}:){0,6}|([a-fA-F0-9]{1,4}:){1}:([a-fA-F0-9]{1,4}:){0,5}|([a-fA-F0-9]{1,4}:){2}:([a-fA-F0-9]{1,4}:){0,4}|([a-fA-F0-9]{1,4}:){3}:([a-fA-F0-9]{1,4}:){0,3}|([a-fA-F0-9]{1,4}:){4}:([a-fA-F0-9]{1,4}:){0,2}|([a-fA-F0-9]{1,4}:){5}:([a-fA-F0-9]{1,4}:){0,1})([a-fA-F0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$)$"`
|
||||
// );
|
||||
expect(ipv4._zod.pattern.source).toMatchInlineSnapshot(
|
||||
`"^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$"`
|
||||
);
|
||||
expect(ipv6._zod.pattern.source).toMatchInlineSnapshot(
|
||||
`"^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})$"`
|
||||
);
|
||||
expect(ulid._zod.pattern.source).toMatchInlineSnapshot(`"^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$"`);
|
||||
expect(uuid._zod.pattern.source).toMatchInlineSnapshot(
|
||||
`"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000)$"`
|
||||
);
|
||||
expect(stringAToZ._zod.pattern.source).toMatchInlineSnapshot(`"^[a-z]+$"`);
|
||||
expect(stringStartsWith._zod.pattern.source).toMatchInlineSnapshot(`"^hello.*$"`);
|
||||
expect(stringEndsWith._zod.pattern.source).toMatchInlineSnapshot(`"^.*world$"`);
|
||||
expect(stringMax5._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{0,5}$"`);
|
||||
expect(stringMin5._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{5,}$"`);
|
||||
expect(stringLen5._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{5,5}$"`);
|
||||
expect(stringMin5Max10._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{5,10}$"`);
|
||||
expect(brandedString._zod.pattern.source).toMatchInlineSnapshot(`"^[\\s\\S]{1,}$"`);
|
||||
expect(url._zod.pattern.source).toMatchInlineSnapshot(`"^https:\\/\\/\\w+\\.(com|net)$"`);
|
||||
expect(measurement._zod.pattern.source).toMatchInlineSnapshot(`"^-?\\d+(?:\\.\\d+)?((px|em|rem|vh|vw|vmin|vmax))?$"`);
|
||||
expect(connectionString._zod.pattern.source).toMatchInlineSnapshot(
|
||||
`"^mongodb:\\/\\/(\\w+:\\w+@)?\\w+:\\d+(\\/(\\w+)?(\\?(\\w+=\\w+(&\\w+=\\w+)*)?)?)?$"`
|
||||
);
|
||||
});
|
||||
|
||||
test("template literal parsing - success - complex cases", () => {
|
||||
url.parse("https://example.com");
|
||||
url.parse("https://speedtest.net");
|
||||
|
||||
// measurement.parse(1);
|
||||
// measurement.parse(1.1);
|
||||
// measurement.parse(0);
|
||||
// measurement.parse(-1.1);
|
||||
// measurement.parse(-1);
|
||||
measurement.parse("1");
|
||||
measurement.parse("1.1");
|
||||
measurement.parse("0");
|
||||
measurement.parse("-1");
|
||||
measurement.parse("-1.1");
|
||||
measurement.parse("1px");
|
||||
measurement.parse("1.1px");
|
||||
measurement.parse("0px");
|
||||
measurement.parse("-1px");
|
||||
measurement.parse("-1.1px");
|
||||
measurement.parse("1em");
|
||||
measurement.parse("1.1em");
|
||||
measurement.parse("0em");
|
||||
measurement.parse("-1em");
|
||||
measurement.parse("-1.1em");
|
||||
measurement.parse("1rem");
|
||||
measurement.parse("1.1rem");
|
||||
measurement.parse("0rem");
|
||||
measurement.parse("-1rem");
|
||||
measurement.parse("-1.1rem");
|
||||
measurement.parse("1vh");
|
||||
measurement.parse("1.1vh");
|
||||
measurement.parse("0vh");
|
||||
measurement.parse("-1vh");
|
||||
measurement.parse("-1.1vh");
|
||||
measurement.parse("1vw");
|
||||
measurement.parse("1.1vw");
|
||||
measurement.parse("0vw");
|
||||
measurement.parse("-1vw");
|
||||
measurement.parse("-1.1vw");
|
||||
measurement.parse("1vmin");
|
||||
measurement.parse("1.1vmin");
|
||||
measurement.parse("0vmin");
|
||||
measurement.parse("-1vmin");
|
||||
measurement.parse("-1.1vmin");
|
||||
measurement.parse("1vmax");
|
||||
measurement.parse("1.1vmax");
|
||||
measurement.parse("0vmax");
|
||||
measurement.parse("-1vmax");
|
||||
measurement.parse("-1.1vmax");
|
||||
|
||||
connectionString.parse("mongodb://host:1234");
|
||||
connectionString.parse("mongodb://host:1234/");
|
||||
connectionString.parse("mongodb://host:1234/defaultauthdb");
|
||||
connectionString.parse("mongodb://host:1234/defaultauthdb?authSource=admin");
|
||||
connectionString.parse("mongodb://host:1234/defaultauthdb?authSource=admin&connectTimeoutMS=300000");
|
||||
connectionString.parse("mongodb://host:1234/?authSource=admin");
|
||||
connectionString.parse("mongodb://host:1234/?authSource=admin&connectTimeoutMS=300000");
|
||||
connectionString.parse("mongodb://username:password@host:1234");
|
||||
connectionString.parse("mongodb://username:password@host:1234/");
|
||||
connectionString.parse("mongodb://username:password@host:1234/defaultauthdb");
|
||||
connectionString.parse("mongodb://username:password@host:1234/defaultauthdb?authSource=admin");
|
||||
connectionString.parse(
|
||||
"mongodb://username:password@host:1234/defaultauthdb?authSource=admin&connectTimeoutMS=300000"
|
||||
);
|
||||
connectionString.parse("mongodb://username:password@host:1234/?authSource=admin");
|
||||
connectionString.parse("mongodb://username:password@host:1234/?authSource=admin&connectTimeoutMS=300000");
|
||||
});
|
||||
|
||||
test("template literal parsing - failure - complex cases", () => {
|
||||
expect(() => url.parse("http://example.com")).toThrow();
|
||||
expect(() => url.parse("https://.com")).toThrow();
|
||||
expect(() => url.parse("https://examplecom")).toThrow();
|
||||
expect(() => url.parse("https://example.org")).toThrow();
|
||||
expect(() => url.parse("https://example.net.il")).toThrow();
|
||||
|
||||
expect(() => measurement.parse("1.1.1")).toThrow();
|
||||
expect(() => measurement.parse("Infinity")).toThrow();
|
||||
expect(() => measurement.parse("-Infinity")).toThrow();
|
||||
expect(() => measurement.parse("NaN")).toThrow();
|
||||
expect(() => measurement.parse("1%")).toThrow();
|
||||
|
||||
expect(() => connectionString.parse("mongod://host:1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://:1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:d234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:12.34")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:-1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:-12.34")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://:password@host:1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://usernamepassword@host:1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://username:@host:1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://@host:1234")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:1234/defaultauthdb?authSourceadmin")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:1234/?authSourceadmin")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:1234/defaultauthdb?&authSource=admin")).toThrow();
|
||||
expect(() => connectionString.parse("mongodb://host:1234/?&authSource=admin")).toThrow();
|
||||
});
|
||||
|
||||
test("template literal parsing - failure - issue format", () => {
|
||||
expect(anotherNull.safeParse("1null")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "template_literal",
|
||||
"pattern": "^null$",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(cuidZZZ.safeParse("1cjld2cyuq0000t3rmniod1foyZZZ")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "template_literal",
|
||||
"pattern": "^[cC][^\\\\s-]{8,}ZZZ$",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(stringMin5Max10.safeParse("1234")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "template_literal",
|
||||
"pattern": "^[\\\\s\\\\S]{5,10}$",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
expect(connectionString.safeParse("mongodb://host:1234/defaultauthdb?authSourceadmin")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "template_literal",
|
||||
"pattern": "^mongodb:\\\\/\\\\/(\\\\w+:\\\\w+@)?\\\\w+:\\\\d+(\\\\/(\\\\w+)?(\\\\?(\\\\w+=\\\\w+(&\\\\w+=\\\\w+)*)?)?)?$",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
|
||||
expect(stringStartsWithMax5.safeParse("1hell")).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "invalid_format",
|
||||
"format": "template_literal",
|
||||
"pattern": "^hello.*$",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
2314
frontend/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts
generated
vendored
Normal file
2314
frontend/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
250
frontend/node_modules/zod/src/v4/classic/tests/transform.test.ts
generated
vendored
Normal file
250
frontend/node_modules/zod/src/v4/classic/tests/transform.test.ts
generated
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("transform ctx.addIssue with parse", () => {
|
||||
const strs = ["foo", "bar"];
|
||||
const schema = z.string().transform((data, ctx) => {
|
||||
const i = strs.indexOf(data);
|
||||
if (i === -1) {
|
||||
ctx.addIssue({
|
||||
input: data,
|
||||
code: "custom",
|
||||
message: `${data} is not one of our allowed strings`,
|
||||
});
|
||||
}
|
||||
return data.length;
|
||||
});
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
expect(result.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "asdf is not one of our allowed strings",
|
||||
"path": []
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("transform ctx.addIssue with parseAsync", async () => {
|
||||
const strs = ["foo", "bar"];
|
||||
|
||||
const result = await z
|
||||
.string()
|
||||
.transform(async (data, ctx) => {
|
||||
const i = strs.indexOf(data);
|
||||
if (i === -1) {
|
||||
ctx.addIssue({
|
||||
input: data,
|
||||
code: "custom",
|
||||
message: `${data} is not one of our allowed strings`,
|
||||
});
|
||||
}
|
||||
return data.length;
|
||||
})
|
||||
.safeParseAsync("asdf");
|
||||
|
||||
expect(result).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "asdf is not one of our allowed strings",
|
||||
"path": []
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.NEVER in transform", () => {
|
||||
const foo = z
|
||||
.number()
|
||||
.optional()
|
||||
.transform((val, ctx) => {
|
||||
if (!val) {
|
||||
ctx.addIssue({
|
||||
input: val,
|
||||
code: z.ZodIssueCode.custom,
|
||||
message: "bad",
|
||||
});
|
||||
return z.NEVER;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
type foo = z.infer<typeof foo>;
|
||||
expectTypeOf<foo>().toEqualTypeOf<number>();
|
||||
const arg = foo.safeParse(undefined);
|
||||
if (!arg.success) {
|
||||
expect(arg.error.issues[0].message).toEqual("bad");
|
||||
}
|
||||
});
|
||||
|
||||
test("basic transformations", () => {
|
||||
const r1 = z
|
||||
.string()
|
||||
.transform((data) => data.length)
|
||||
.parse("asdf");
|
||||
expect(r1).toEqual(4);
|
||||
});
|
||||
|
||||
test("coercion", () => {
|
||||
const numToString = z.number().transform((n) => String(n));
|
||||
const data = z
|
||||
.object({
|
||||
id: numToString,
|
||||
})
|
||||
.parse({ id: 5 });
|
||||
|
||||
expect(data).toEqual({ id: "5" });
|
||||
});
|
||||
|
||||
test("async coercion", async () => {
|
||||
const numToString = z.number().transform(async (n) => String(n));
|
||||
const data = await z
|
||||
.object({
|
||||
id: numToString,
|
||||
})
|
||||
.parseAsync({ id: 5 });
|
||||
|
||||
expect(data).toEqual({ id: "5" });
|
||||
});
|
||||
|
||||
test("sync coercion async error", async () => {
|
||||
const asyncNumberToString = z.number().transform(async (n) => String(n));
|
||||
expect(() =>
|
||||
z
|
||||
.object({
|
||||
id: asyncNumberToString,
|
||||
})
|
||||
.parse({ id: 5 })
|
||||
).toThrow();
|
||||
// expect(data).toEqual({ id: '5' });
|
||||
});
|
||||
|
||||
test("default", () => {
|
||||
const data = z.string().default("asdf").parse(undefined); // => "asdf"
|
||||
expect(data).toEqual("asdf");
|
||||
});
|
||||
|
||||
test("dynamic default", () => {
|
||||
const data = z
|
||||
.string()
|
||||
.default(() => "string")
|
||||
.parse(undefined); // => "asdf"
|
||||
expect(data).toEqual("string");
|
||||
});
|
||||
|
||||
test("default when property is null or undefined", () => {
|
||||
const data = z
|
||||
.object({
|
||||
foo: z.boolean().nullable().default(true),
|
||||
bar: z.boolean().default(true),
|
||||
})
|
||||
.parse({ foo: null });
|
||||
|
||||
expect(data).toEqual({ foo: null, bar: true });
|
||||
});
|
||||
|
||||
test("default with falsy values", () => {
|
||||
const schema = z.object({
|
||||
emptyStr: z.string().default("def"),
|
||||
zero: z.number().default(5),
|
||||
falseBoolean: z.boolean().default(true),
|
||||
});
|
||||
const input = { emptyStr: "", zero: 0, falseBoolean: true };
|
||||
const output = schema.parse(input);
|
||||
// defaults are not supposed to be used
|
||||
expect(output).toEqual(input);
|
||||
});
|
||||
|
||||
test("object typing", () => {
|
||||
const stringToNumber = z.string().transform((arg) => Number.parseFloat(arg));
|
||||
|
||||
const t1 = z.object({
|
||||
stringToNumber,
|
||||
});
|
||||
|
||||
type t1 = z.input<typeof t1>;
|
||||
type t2 = z.output<typeof t1>;
|
||||
|
||||
expectTypeOf<t1>().toEqualTypeOf<{ stringToNumber: string }>();
|
||||
expectTypeOf<t2>().toEqualTypeOf<{ stringToNumber: number }>();
|
||||
});
|
||||
|
||||
test("transform method overloads", () => {
|
||||
const t1 = z.string().transform((val) => val.toUpperCase());
|
||||
expect(t1.parse("asdf")).toEqual("ASDF");
|
||||
|
||||
const t2 = z.string().transform((val) => val.length);
|
||||
expect(t2.parse("asdf")).toEqual(4);
|
||||
});
|
||||
|
||||
test("multiple transformers", () => {
|
||||
const stringToNumber = z.string().transform((arg) => Number.parseFloat(arg));
|
||||
|
||||
const doubler = stringToNumber.transform((val) => {
|
||||
return val * 2;
|
||||
});
|
||||
expect(doubler.parse("5")).toEqual(10);
|
||||
});
|
||||
|
||||
test("short circuit on dirty", () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.refine(() => false)
|
||||
.transform((val) => val.toUpperCase());
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const result2 = schema.safeParse(1234);
|
||||
expect(result2.success).toEqual(false);
|
||||
if (!result2.success) {
|
||||
expect(result2.error.issues[0].code).toEqual(z.ZodIssueCode.invalid_type);
|
||||
}
|
||||
});
|
||||
|
||||
test("async short circuit on dirty", async () => {
|
||||
const schema = z
|
||||
.string()
|
||||
.refine(() => false)
|
||||
.transform((val) => val.toUpperCase());
|
||||
const result = await schema.spa("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
|
||||
expect(result.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"code": "custom",
|
||||
"path": [],
|
||||
"message": "Invalid input"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const result2 = await schema.spa(1234);
|
||||
expect(result2.success).toEqual(false);
|
||||
|
||||
expect(result2.error).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected string, received number"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
163
frontend/node_modules/zod/src/v4/classic/tests/tuple.test.ts
generated
vendored
Normal file
163
frontend/node_modules/zod/src/v4/classic/tests/tuple.test.ts
generated
vendored
Normal file
@ -0,0 +1,163 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("successful validation", () => {
|
||||
const testTuple = z.tuple([z.string(), z.number()]);
|
||||
expectTypeOf<typeof testTuple._output>().toEqualTypeOf<[string, number]>();
|
||||
|
||||
const val = testTuple.parse(["asdf", 1234]);
|
||||
expect(val).toEqual(val);
|
||||
|
||||
const r1 = testTuple.safeParse(["asdf", "asdf"]);
|
||||
expect(r1.success).toEqual(false);
|
||||
expect(r1.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
1
|
||||
],
|
||||
"message": "Invalid input: expected number, received string"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const r2 = testTuple.safeParse(["asdf", 1234, true]);
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"origin": "array",
|
||||
"code": "too_big",
|
||||
"maximum": 2,
|
||||
"path": [],
|
||||
"message": "Too big: expected array to have <2 items"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const r3 = testTuple.safeParse({});
|
||||
expect(r3.success).toEqual(false);
|
||||
expect(r3.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "tuple",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected tuple, received object"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("async validation", async () => {
|
||||
const testTuple = z
|
||||
.tuple([z.string().refine(async () => true), z.number().refine(async () => true)])
|
||||
.refine(async () => true);
|
||||
expectTypeOf<typeof testTuple._output>().toEqualTypeOf<[string, number]>();
|
||||
|
||||
const val = await testTuple.parseAsync(["asdf", 1234]);
|
||||
expect(val).toEqual(val);
|
||||
|
||||
const r1 = await testTuple.safeParseAsync(["asdf", "asdf"]);
|
||||
expect(r1.success).toEqual(false);
|
||||
expect(r1.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
1
|
||||
],
|
||||
"message": "Invalid input: expected number, received string"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const r2 = await testTuple.safeParseAsync(["asdf", 1234, true]);
|
||||
expect(r2.success).toEqual(false);
|
||||
expect(r2.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"origin": "array",
|
||||
"code": "too_big",
|
||||
"maximum": 2,
|
||||
"path": [],
|
||||
"message": "Too big: expected array to have <2 items"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
|
||||
const r3 = await testTuple.safeParseAsync({});
|
||||
expect(r3.success).toEqual(false);
|
||||
expect(r3.error!).toMatchInlineSnapshot(`
|
||||
[ZodError: [
|
||||
{
|
||||
"expected": "tuple",
|
||||
"code": "invalid_type",
|
||||
"path": [],
|
||||
"message": "Invalid input: expected tuple, received object"
|
||||
}
|
||||
]]
|
||||
`);
|
||||
});
|
||||
|
||||
test("tuple with optional elements", () => {
|
||||
const myTuple = z.tuple([z.string(), z.number().optional(), z.string().optional()]).rest(z.boolean());
|
||||
expectTypeOf<typeof myTuple._output>().toEqualTypeOf<[string, number?, string?, ...boolean[]]>();
|
||||
|
||||
const goodData = [["asdf"], ["asdf", 1234], ["asdf", 1234, "asdf"], ["asdf", 1234, "asdf", true, false, true]];
|
||||
for (const data of goodData) {
|
||||
expect(myTuple.parse(data)).toEqual(data);
|
||||
}
|
||||
|
||||
const badData = [
|
||||
["asdf", "asdf"],
|
||||
["asdf", 1234, "asdf", "asdf"],
|
||||
["asdf", 1234, "asdf", true, false, "asdf"],
|
||||
];
|
||||
for (const data of badData) {
|
||||
expect(() => myTuple.parse(data)).toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
test("tuple with optional elements followed by required", () => {
|
||||
const myTuple = z.tuple([z.string(), z.number().optional(), z.string()]).rest(z.boolean());
|
||||
expectTypeOf<typeof myTuple._output>().toEqualTypeOf<[string, number | undefined, string, ...boolean[]]>();
|
||||
|
||||
const goodData = [
|
||||
["asdf", 1234, "asdf"],
|
||||
["asdf", 1234, "asdf", true, false, true],
|
||||
];
|
||||
for (const data of goodData) {
|
||||
expect(myTuple.parse(data)).toEqual(data);
|
||||
}
|
||||
|
||||
const badData = [
|
||||
["asdf"],
|
||||
["asdf", 1234],
|
||||
["asdf", 1234, "asdf", "asdf"],
|
||||
["asdf", 1234, "asdf", true, false, "asdf"],
|
||||
];
|
||||
for (const data of badData) {
|
||||
expect(() => myTuple.parse(data)).toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
test("tuple with rest schema", () => {
|
||||
const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean());
|
||||
expect(myTuple.parse(["asdf", 1234, true, false, true])).toEqual(["asdf", 1234, true, false, true]);
|
||||
|
||||
expect(myTuple.parse(["asdf", 1234])).toEqual(["asdf", 1234]);
|
||||
|
||||
expect(() => myTuple.parse(["asdf", 1234, "asdf"])).toThrow();
|
||||
type t1 = z.output<typeof myTuple>;
|
||||
|
||||
expectTypeOf<t1>().toEqualTypeOf<[string, number, ...boolean[]]>();
|
||||
});
|
||||
|
||||
test("sparse array input", () => {
|
||||
const schema = z.tuple([z.string(), z.number()]);
|
||||
expect(() => schema.parse(new Array(2))).toThrow();
|
||||
});
|
||||
94
frontend/node_modules/zod/src/v4/classic/tests/union.test.ts
generated
vendored
Normal file
94
frontend/node_modules/zod/src/v4/classic/tests/union.test.ts
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("function parsing", () => {
|
||||
const schema = z.union([z.string().refine(() => false), z.number().refine(() => false)]);
|
||||
const result = schema.safeParse("asdf");
|
||||
expect(result.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("union 2", () => {
|
||||
const result = z.union([z.number(), z.string().refine(() => false)]).safeParse("a");
|
||||
expect(result.success).toEqual(false);
|
||||
});
|
||||
|
||||
test("return valid over invalid", () => {
|
||||
const schema = z.union([
|
||||
z.object({
|
||||
email: z.string().email(),
|
||||
}),
|
||||
z.string(),
|
||||
]);
|
||||
expect(schema.parse("asdf")).toEqual("asdf");
|
||||
expect(schema.parse({ email: "asdlkjf@lkajsdf.com" })).toEqual({
|
||||
email: "asdlkjf@lkajsdf.com",
|
||||
});
|
||||
});
|
||||
|
||||
test("return errors from both union arms", () => {
|
||||
const result = z.union([z.number(), z.string().refine(() => false)]).safeParse("a");
|
||||
expect(result.success).toEqual(false);
|
||||
if (!result.success) {
|
||||
expect(result.error.issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "invalid_union",
|
||||
"errors": [
|
||||
[
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "number",
|
||||
"message": "Invalid input: expected number, received string",
|
||||
"path": [],
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
],
|
||||
],
|
||||
"message": "Invalid input",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("options getter", async () => {
|
||||
const union = z.union([z.string(), z.number()]);
|
||||
union.options[0].parse("asdf");
|
||||
union.options[1].parse(1234);
|
||||
await union.options[0].parseAsync("asdf");
|
||||
await union.options[1].parseAsync(1234);
|
||||
});
|
||||
|
||||
test("readonly union", async () => {
|
||||
const options = [z.string(), z.number()] as const;
|
||||
const union = z.union(options);
|
||||
union.parse("asdf");
|
||||
union.parse(12);
|
||||
});
|
||||
|
||||
test("union inferred types", () => {
|
||||
const test = z.object({}).or(z.array(z.object({})));
|
||||
|
||||
type Test = z.output<typeof test>; // <— any
|
||||
expectTypeOf<Test>().toEqualTypeOf<Record<string, never> | Array<Record<string, never>>>();
|
||||
});
|
||||
|
||||
test("union values", () => {
|
||||
const schema = z.union([z.literal("a"), z.literal("b"), z.literal("c")]);
|
||||
|
||||
expect(schema._zod.values).toMatchInlineSnapshot(`
|
||||
Set {
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
}
|
||||
`);
|
||||
});
|
||||
283
frontend/node_modules/zod/src/v4/classic/tests/validations.test.ts
generated
vendored
Normal file
283
frontend/node_modules/zod/src/v4/classic/tests/validations.test.ts
generated
vendored
Normal file
@ -0,0 +1,283 @@
|
||||
import { expect, test } from "vitest";
|
||||
|
||||
import * as z from "zod/v4";
|
||||
|
||||
test("string length", async () => {
|
||||
try {
|
||||
await z.string().length(4).parseAsync("asd");
|
||||
} catch (err) {
|
||||
// ("String must contain exactly 4 character(s)");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"exact": true,
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected string to have >=4 characters",
|
||||
"minimum": 4,
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
|
||||
try {
|
||||
await z.string().length(4).parseAsync("asdaa");
|
||||
} catch (err) {
|
||||
// ("String must contain exactly 4 character(s)");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"exact": true,
|
||||
"inclusive": true,
|
||||
"maximum": 4,
|
||||
"message": "Too big: expected string to have <=4 characters",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("string min/max", async () => {
|
||||
try {
|
||||
await z.string().min(4).parseAsync("asd");
|
||||
} catch (err) {
|
||||
// ("String must contain at least 4 character(s)");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected string to have >=4 characters",
|
||||
"minimum": 4,
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("string max", async () => {
|
||||
try {
|
||||
await z.string().max(4).parseAsync("aasdfsdfsd");
|
||||
} catch (err) {
|
||||
// ("String must contain at most 4 character(s)");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": true,
|
||||
"maximum": 4,
|
||||
"message": "Too big: expected string to have <=4 characters",
|
||||
"origin": "string",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number min", async () => {
|
||||
try {
|
||||
await z.number().min(3).parseAsync(2);
|
||||
} catch (err) {
|
||||
// ("Number must be greater than or equal to 3");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected number to be >=3",
|
||||
"minimum": 3,
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number gte", async () => {
|
||||
try {
|
||||
await z.number().gte(3).parseAsync(2);
|
||||
} catch (err) {
|
||||
// ("Number must be greater than or equal to 3");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected number to be >=3",
|
||||
"minimum": 3,
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number gt", async () => {
|
||||
try {
|
||||
await z.number().gt(3).parseAsync(3);
|
||||
} catch (err) {
|
||||
// ("Number must be greater than or equal to 3");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": false,
|
||||
"message": "Too small: expected number to be >3",
|
||||
"minimum": 3,
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number max", async () => {
|
||||
try {
|
||||
await z.number().max(3).parseAsync(4);
|
||||
} catch (err) {
|
||||
// ("Number must be less than or equal to 3");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": true,
|
||||
"maximum": 3,
|
||||
"message": "Too big: expected number to be <=3",
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number lte", async () => {
|
||||
try {
|
||||
await z.number().lte(3).parseAsync(4);
|
||||
} catch (err) {
|
||||
// ("Number must be less than or equal to 3");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": true,
|
||||
"maximum": 3,
|
||||
"message": "Too big: expected number to be <=3",
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number lt", async () => {
|
||||
try {
|
||||
await z.number().lt(3).parseAsync(3);
|
||||
} catch (err) {
|
||||
// ("Number must be less than or equal to 3");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": false,
|
||||
"maximum": 3,
|
||||
"message": "Too big: expected number to be <3",
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number nonnegative", async () => {
|
||||
try {
|
||||
await z.number().nonnegative().parseAsync(-1);
|
||||
} catch (err) {
|
||||
// ("Number must be greater than or equal to 0");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": true,
|
||||
"message": "Too small: expected number to be >=0",
|
||||
"minimum": 0,
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number nonpositive", async () => {
|
||||
try {
|
||||
await z.number().nonpositive().parseAsync(1);
|
||||
} catch (err) {
|
||||
// ("Number must be less than or equal to 0");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": true,
|
||||
"maximum": 0,
|
||||
"message": "Too big: expected number to be <=0",
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number negative", async () => {
|
||||
try {
|
||||
await z.number().negative().parseAsync(1);
|
||||
} catch (err) {
|
||||
// ("Number must be less than 0");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_big",
|
||||
"inclusive": false,
|
||||
"maximum": 0,
|
||||
"message": "Too big: expected number to be <0",
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
|
||||
test("number positive", async () => {
|
||||
try {
|
||||
await z.number().positive().parseAsync(-1);
|
||||
} catch (err) {
|
||||
// ("Number must be greater than 0");
|
||||
expect((err as z.ZodError).issues).toMatchInlineSnapshot(`
|
||||
[
|
||||
{
|
||||
"code": "too_small",
|
||||
"inclusive": false,
|
||||
"message": "Too small: expected number to be >0",
|
||||
"minimum": 0,
|
||||
"origin": "number",
|
||||
"path": [],
|
||||
},
|
||||
]
|
||||
`);
|
||||
}
|
||||
});
|
||||
12
frontend/node_modules/zod/src/v4/classic/tests/void.test.ts
generated
vendored
Normal file
12
frontend/node_modules/zod/src/v4/classic/tests/void.test.ts
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
test("void", () => {
|
||||
const v = z.void();
|
||||
v.parse(undefined);
|
||||
|
||||
expect(() => v.parse(null)).toThrow();
|
||||
expect(() => v.parse("")).toThrow();
|
||||
|
||||
type v = z.infer<typeof v>;
|
||||
expectTypeOf<v>().toEqualTypeOf<void>();
|
||||
});
|
||||
Reference in New Issue
Block a user