Add first business article and article layout

This commit is contained in:
2026-05-21 12:14:46 -05:00
parent 200e14e2e9
commit 4735704c6f
9617 changed files with 988627 additions and 0 deletions

32
node_modules/zod/src/v4/mini/checks.ts generated vendored Normal file
View File

@@ -0,0 +1,32 @@
export {
_lt as lt,
_lte as lte,
_lte as maximum,
_gt as gt,
_gte as gte,
_gte as minimum,
_positive as positive,
_negative as negative,
_nonpositive as nonpositive,
_nonnegative as nonnegative,
_multipleOf as multipleOf,
_maxSize as maxSize,
_minSize as minSize,
_size as size,
_maxLength as maxLength,
_minLength as minLength,
_length as length,
_regex as regex,
_lowercase as lowercase,
_uppercase as uppercase,
_includes as includes,
_startsWith as startsWith,
_endsWith as endsWith,
_property as property,
_mime as mime,
_overwrite as overwrite,
_normalize as normalize,
_trim as trim,
_toLowerCase as toLowerCase,
_toUpperCase as toUpperCase,
} from "../core/index.js";

27
node_modules/zod/src/v4/mini/coerce.ts generated vendored Normal file
View File

@@ -0,0 +1,27 @@
import * as core from "../core/index.js";
import * as schemas from "./schemas.js";
// @__NO_SIDE_EFFECTS__
export function string<T = unknown>(params?: string | core.$ZodStringParams): schemas.ZodMiniString<T> {
return core._coercedString(schemas.ZodMiniString, params) as schemas.ZodMiniString<T>;
}
// @__NO_SIDE_EFFECTS__
export function number<T = unknown>(params?: string | core.$ZodNumberParams): schemas.ZodMiniNumber<T> {
return core._coercedNumber(schemas.ZodMiniNumber, params) as schemas.ZodMiniNumber<T>;
}
// @__NO_SIDE_EFFECTS__
export function boolean<T = unknown>(params?: string | core.$ZodBooleanParams): schemas.ZodMiniBoolean<T> {
return core._coercedBoolean(schemas.ZodMiniBoolean, params) as schemas.ZodMiniBoolean<T>;
}
// @__NO_SIDE_EFFECTS__
export function bigint<T = unknown>(params?: string | core.$ZodBigIntParams): schemas.ZodMiniBigInt<T> {
return core._coercedBigint(schemas.ZodMiniBigInt, params) as schemas.ZodMiniBigInt<T>;
}
// @__NO_SIDE_EFFECTS__
export function date<T = unknown>(params?: string | core.$ZodDateParams): schemas.ZodMiniDate<T> {
return core._coercedDate(schemas.ZodMiniDate, params) as schemas.ZodMiniDate<T>;
}

41
node_modules/zod/src/v4/mini/external.ts generated vendored Normal file
View File

@@ -0,0 +1,41 @@
export * as core from "../core/index.js";
export * from "./parse.js";
export * from "./schemas.js";
export * from "./checks.js";
export type { infer, output, input } from "../core/index.js";
export type { JSONType } from "../core/util.js";
export {
globalRegistry,
registry,
config,
$output,
$input,
$brand,
clone,
regexes,
treeifyError,
prettifyError,
formatError,
flattenError,
TimePrecision,
util,
NEVER,
} from "../core/index.js";
export { toJSONSchema } from "../core/json-schema-processors.js";
export * as locales from "../locales/index.js";
/** A special constant with type `never` */
// export const NEVER = {} as never;
// iso
export * as iso from "./iso.js";
export {
ZodMiniISODateTime,
ZodMiniISODate,
ZodMiniISOTime,
ZodMiniISODuration,
} from "./iso.js";
// coerce
export * as coerce from "./coerce.js";

3
node_modules/zod/src/v4/mini/index.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import * as z from "./external.js";
export * from "./external.js";
export { z };

66
node_modules/zod/src/v4/mini/iso.ts generated vendored Normal file
View File

@@ -0,0 +1,66 @@
import * as core from "../core/index.js";
import * as schemas from "./schemas.js";
// iso time
export interface ZodMiniISODateTime extends schemas.ZodMiniStringFormat<"datetime"> {
_zod: core.$ZodISODateTimeInternals;
}
export const ZodMiniISODateTime: core.$constructor<ZodMiniISODateTime> = /*@__PURE__*/ core.$constructor(
"ZodMiniISODateTime",
(inst, def) => {
core.$ZodISODateTime.init(inst, def);
schemas.ZodMiniStringFormat.init(inst, def);
}
);
// @__NO_SIDE_EFFECTS__
export function datetime(params?: string | core.$ZodISODateTimeParams): ZodMiniISODateTime {
return core._isoDateTime(ZodMiniISODateTime, params);
}
// iso date
export interface ZodMiniISODate extends schemas.ZodMiniStringFormat<"date"> {
_zod: core.$ZodISODateInternals;
}
export const ZodMiniISODate: core.$constructor<ZodMiniISODate> = /*@__PURE__*/ core.$constructor(
"ZodMiniISODate",
(inst, def) => {
core.$ZodISODate.init(inst, def);
schemas.ZodMiniStringFormat.init(inst, def);
}
);
// @__NO_SIDE_EFFECTS__
export function date(params?: string | core.$ZodISODateParams): ZodMiniISODate {
return core._isoDate(ZodMiniISODate, params);
}
// iso time
export interface ZodMiniISOTime extends schemas.ZodMiniStringFormat<"time"> {
_zod: core.$ZodISOTimeInternals;
}
export const ZodMiniISOTime: core.$constructor<ZodMiniISOTime> = /*@__PURE__*/ core.$constructor(
"ZodMiniISOTime",
(inst, def) => {
core.$ZodISOTime.init(inst, def);
schemas.ZodMiniStringFormat.init(inst, def);
}
);
// @__NO_SIDE_EFFECTS__
export function time(params?: string | core.$ZodISOTimeParams): ZodMiniISOTime {
return core._isoTime(ZodMiniISOTime, params);
}
// iso duration
export interface ZodMiniISODuration extends schemas.ZodMiniStringFormat<"duration"> {
_zod: core.$ZodISODurationInternals;
}
export const ZodMiniISODuration: core.$constructor<ZodMiniISODuration> = /*@__PURE__*/ core.$constructor(
"ZodMiniISODuration",
(inst, def) => {
core.$ZodISODuration.init(inst, def);
schemas.ZodMiniStringFormat.init(inst, def);
}
);
// @__NO_SIDE_EFFECTS__
export function duration(params?: string | core.$ZodISODurationParams): ZodMiniISODuration {
return core._isoDuration(ZodMiniISODuration, params);
}

14
node_modules/zod/src/v4/mini/parse.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
export {
parse,
safeParse,
parseAsync,
safeParseAsync,
encode,
decode,
encodeAsync,
decodeAsync,
safeEncode,
safeDecode,
safeEncodeAsync,
safeDecodeAsync,
} from "../core/index.js";

1947
node_modules/zod/src/v4/mini/schemas.ts generated vendored Normal file

File diff suppressed because it is too large Load Diff

24
node_modules/zod/src/v4/mini/tests/apply.test.ts generated vendored Normal file
View File

@@ -0,0 +1,24 @@
import { expect, expectTypeOf, test } from "vitest";
import * as z from "../index.js";
test("basic apply (number)", () => {
const setCommonNumberChecks = <T extends z.ZodMiniNumber>(schema: T) => {
return schema.check(z.minimum(0), z.maximum(100));
};
const schema = z.nullable(z.number().apply(setCommonNumberChecks));
expect(() => z.parse(schema, -1)).toThrowError();
expect(() => z.parse(schema, 101)).toThrowError();
expect(z.parse(schema, 0)).toBe(0);
expect(z.parse(schema, null)).toBe(null);
expectTypeOf<z.infer<typeof schema>>().toEqualTypeOf<number | null>();
});
test("The callback's return value becomes the apply's return value.", () => {
const symbol = Symbol();
const result = z.number().apply(() => symbol);
expect(result).toBe(symbol);
expectTypeOf<typeof result>().toEqualTypeOf<symbol>();
});

View File

@@ -0,0 +1,129 @@
import { test } from "vitest";
import * as z from "zod/mini";
test("assignability", () => {
// $ZodString
z.string() satisfies z.core.$ZodString;
// $ZodNumber
z.number() satisfies z.core.$ZodNumber;
// $ZodBigInt
z.bigint() satisfies z.core.$ZodBigInt;
// $ZodBoolean
z.boolean() satisfies z.core.$ZodBoolean;
// $ZodDate
z.date() satisfies z.core.$ZodDate;
// $ZodSymbol
z.symbol() satisfies z.core.$ZodSymbol;
// $ZodUndefined
z.undefined() satisfies z.core.$ZodUndefined;
// $ZodNullable
z.nullable(z.string()) satisfies z.core.$ZodNullable;
// $ZodNull
z.null() satisfies z.core.$ZodNull;
// $ZodAny
z.any() satisfies z.core.$ZodAny;
// $ZodUnknown
z.unknown() satisfies z.core.$ZodUnknown;
// $ZodNever
z.never() satisfies z.core.$ZodNever;
// $ZodVoid
z.void() satisfies z.core.$ZodVoid;
// $ZodArray
z.array(z.string()) satisfies z.core.$ZodArray;
// $ZodObject
z.object({ key: z.string() }) satisfies z.core.$ZodObject;
// $ZodUnion
z.union([z.string(), z.number()]) satisfies z.core.$ZodUnion;
// $ZodIntersection
z.intersection(z.string(), z.number()) satisfies z.core.$ZodIntersection;
// $ZodTuple
z.tuple([z.string(), z.number()]) satisfies z.core.$ZodTuple;
// $ZodRecord
z.record(z.string(), z.number()) satisfies z.core.$ZodRecord;
// $ZodMap
z.map(z.string(), z.number()) satisfies z.core.$ZodMap;
// $ZodSet
z.set(z.string()) satisfies z.core.$ZodSet;
// $ZodLiteral
z.literal("example") satisfies z.core.$ZodLiteral;
// $ZodEnum
z.enum(["a", "b", "c"]) satisfies z.core.$ZodEnum;
// $ZodPromise
z.promise(z.string()) satisfies z.core.$ZodPromise;
// $ZodLazy
const lazySchema = z.lazy(() => z.string());
lazySchema satisfies z.core.$ZodLazy;
// $ZodOptional
z.optional(z.string()) satisfies z.core.$ZodOptional;
// $ZodDefault
z._default(z.string(), "default") satisfies z.core.$ZodDefault;
// $ZodTemplateLiteral
z.templateLiteral([z.literal("a"), z.literal("b")]) satisfies z.core.$ZodTemplateLiteral;
// $ZodCustom
z.custom<string>((val) => typeof val === "string") satisfies z.core.$ZodCustom;
// $ZodTransform
z.transform((val) => val as string) satisfies z.core.$ZodTransform;
// $ZodNonOptional
z.nonoptional(z.optional(z.string())) satisfies z.core.$ZodNonOptional;
// $ZodReadonly
z.readonly(z.object({ key: z.string() })) satisfies z.core.$ZodReadonly;
// $ZodNaN
z.nan() satisfies z.core.$ZodNaN;
// $ZodPipe
z.pipe(z.unknown(), z.number()) satisfies z.core.$ZodPipe;
// $ZodSuccess
z.success(z.string()) satisfies z.core.$ZodSuccess;
// $ZodCatch
z.catch(z.string(), "fallback") satisfies z.core.$ZodCatch;
// $ZodFile
z.file() satisfies z.core.$ZodFile;
});
test("assignability with type narrowing", () => {
type _RefinedSchema<T extends z.ZodMiniType<object> | z.ZodMiniUnion> = T extends z.ZodMiniUnion
? RefinedUnionSchema<T> // <-- Type instantiation is excessively deep and possibly infinite.
: T extends z.ZodMiniType<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.ZodMiniUnion> = T;
});

94
node_modules/zod/src/v4/mini/tests/brand.test.ts generated vendored Normal file
View File

@@ -0,0 +1,94 @@
import { expectTypeOf, test } from "vitest";
import * as z from "../index.js";
test("branded types", () => {
const mySchema = z
.object({
name: z.string(),
})
.brand<"superschema">();
// simple branding
type MySchema = z.infer<typeof mySchema>;
// Using true for type equality assertion
expectTypeOf<MySchema>().toEqualTypeOf<{ name: string } & z.$brand<"superschema">>();
const doStuff = (arg: MySchema) => arg;
doStuff(z.parse(mySchema, { 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(z.parse(extendedSchema, { 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 Age1 = z.infer<typeof age>;
type AgeInput1 = z.input<typeof age>;
// Using not for type inequality assertion
expectTypeOf<AgeInput1>().not.toEqualTypeOf<Age1>();
expectTypeOf<number>().toEqualTypeOf<AgeInput1>();
expectTypeOf<number & z.$brand<"age">>().toEqualTypeOf<Age1>();
// @ts-expect-error
doStuff({ name: "hello there!" });
});
test("brand direction: out (default)", () => {
const schema = z.string().brand<"A">();
type Input = z.input<typeof schema>;
type Output = z.output<typeof schema>;
// output is branded
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
// input is NOT branded (default behavior)
expectTypeOf<Input>().toEqualTypeOf<string>();
});
test("brand direction: out (explicit)", () => {
const schema = z.string().brand<"A", "out">();
type Input = z.input<typeof schema>;
type Output = z.output<typeof schema>;
// output is branded
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
// input is NOT branded
expectTypeOf<Input>().toEqualTypeOf<string>();
});
test("brand direction: in", () => {
const schema = z.string().brand<"A", "in">();
type Input = z.input<typeof schema>;
type Output = z.output<typeof schema>;
// input is branded
expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
// output is NOT branded
expectTypeOf<Output>().toEqualTypeOf<string>();
});
test("brand direction: inout", () => {
const schema = z.string().brand<"A", "inout">();
type Input = z.input<typeof schema>;
type Output = z.output<typeof schema>;
// both are branded
expectTypeOf<Input>().toEqualTypeOf<string & z.$brand<"A">>();
expectTypeOf<Output>().toEqualTypeOf<string & z.$brand<"A">>();
});

144
node_modules/zod/src/v4/mini/tests/checks.test.ts generated vendored Normal file
View File

@@ -0,0 +1,144 @@
import { expect, test } from "vitest";
import * as z from "../index.js";
// lt;
test("z.lt", () => {
const a = z.number().check(z.lt(10));
expect(z.safeParse(a, 9).success).toEqual(true);
expect(z.safeParse(a, 9).data).toEqual(9);
expect(z.safeParse(a, 10).success).toEqual(false);
});
// lte;
test("z.lte", () => {
const a = z.number().check(z.lte(10));
expect(z.safeParse(a, 10).success).toEqual(true);
expect(z.safeParse(a, 10).data).toEqual(10);
expect(z.safeParse(a, 11).success).toEqual(false);
});
// min;
test("z.max", () => {
const a = z.number().check(z.maximum(10));
expect(z.safeParse(a, 10).success).toEqual(true);
expect(z.safeParse(a, 10).data).toEqual(10);
expect(z.safeParse(a, 11).success).toEqual(false);
});
// gt;
test("z.gt", () => {
const a = z.number().check(z.gt(10));
expect(z.safeParse(a, 11).success).toEqual(true);
expect(z.safeParse(a, 11).data).toEqual(11);
expect(z.safeParse(a, 10).success).toEqual(false);
});
// gte;
test("z.gte", () => {
const a = z.number().check(z.gte(10));
expect(z.safeParse(a, 10).success).toEqual(true);
expect(z.safeParse(a, 10).data).toEqual(10);
expect(z.safeParse(a, 9).success).toEqual(false);
});
// min;
test("z.min", () => {
const a = z.number().check(z.minimum(10));
expect(z.safeParse(a, 10).success).toEqual(true);
expect(z.safeParse(a, 10).data).toEqual(10);
expect(z.safeParse(a, 9).success).toEqual(false);
});
// maxSize;
test("z.maxLength", () => {
const a = z.array(z.string()).check(z.maxLength(3));
expect(z.safeParse(a, ["a", "b", "c"]).success).toEqual(true);
expect(z.safeParse(a, ["a", "b", "c", "d"]).success).toEqual(false);
});
// minSize;
test("z.minLength", () => {
const a = z.array(z.string()).check(z.minLength(3));
expect(z.safeParse(a, ["a", "b"]).success).toEqual(false);
expect(z.safeParse(a, ["a", "b", "c"]).success).toEqual(true);
});
// size;
test("z.length", () => {
const a = z.array(z.string()).check(z.length(3));
expect(z.safeParse(a, ["a", "b"]).success).toEqual(false);
expect(z.safeParse(a, ["a", "b", "c"]).success).toEqual(true);
expect(z.safeParse(a, ["a", "b", "c", "d"]).success).toEqual(false);
});
// regex;
test("z.regex", () => {
const a = z.string().check(z.regex(/^aaa$/));
expect(z.safeParse(a, "aaa")).toMatchObject({ success: true, data: "aaa" });
expect(z.safeParse(a, "aa")).toMatchObject({ success: false });
});
// includes;
test("z.includes", () => {
const a = z.string().check(z.includes("asdf"));
z.parse(a, "qqqasdfqqq");
z.parse(a, "asdf");
z.parse(a, "qqqasdf");
z.parse(a, "asdfqqq");
expect(z.safeParse(a, "qqq")).toMatchObject({ success: false });
});
// startsWith;
test("z.startsWith", () => {
const a = z.string().check(z.startsWith("asdf"));
z.parse(a, "asdf");
z.parse(a, "asdfqqq");
expect(z.safeParse(a, "qqq")).toMatchObject({ success: false });
});
// endsWith;
test("z.endsWith", () => {
const a = z.string().check(z.endsWith("asdf"));
z.parse(a, "asdf");
z.parse(a, "qqqasdf");
expect(z.safeParse(a, "asdfqqq")).toMatchObject({ success: false });
});
// lowercase;
test("z.lowercase", () => {
const a = z.string().check(z.lowercase());
z.parse(a, "asdf");
expect(z.safeParse(a, "ASDF")).toMatchObject({ success: false });
});
// uppercase;
test("z.uppercase", () => {
const a = z.string().check(z.uppercase());
z.parse(a, "ASDF");
expect(z.safeParse(a, "asdf")).toMatchObject({ success: false });
});
// filename;
// fileType;
// overwrite;
test("z.overwrite", () => {
const a = z.string().check(z.overwrite((val) => val.toUpperCase()));
expect(z.safeParse(a, "asdf")).toMatchObject({ data: "ASDF" });
});
// normalize;
// trim;
// toLowerCase;
// toUpperCase;
// property
test("abort early", () => {
const schema = z.string().check(
z.refine((val) => val.length > 1),
z.refine((val) => val.length > 2, { abort: true }),
z.refine((val) => val.length > 3)
);
const data = "";
const result = z.safeParse(schema, data);
expect(result.error!.issues.length).toEqual(2);
});

548
node_modules/zod/src/v4/mini/tests/codec.test.ts generated vendored Normal file
View File

@@ -0,0 +1,548 @@
import { expect, expectTypeOf, test } from "vitest";
import { en } from "zod/locales";
import * as z from "zod/mini";
z.config(en());
const isoDateCodec = z.codec(
z.iso.datetime(), // Input: ISO string (validates to string)
z.date(), // Output: Date object
{
decode: (isoString) => new Date(isoString), // Forward: ISO string → Date
encode: (date) => date.toISOString(), // Backward: Date → ISO string
}
);
test("instanceof", () => {
expect(isoDateCodec instanceof z.ZodMiniCodec).toBe(true);
expect(isoDateCodec instanceof z.ZodMiniPipe).toBe(true);
expect(isoDateCodec instanceof z.ZodMiniType).toBe(true);
expect(isoDateCodec instanceof z.core.$ZodCodec).toBe(true);
expect(isoDateCodec instanceof z.core.$ZodPipe).toBe(true);
expect(isoDateCodec instanceof z.core.$ZodType).toBe(true);
expectTypeOf(isoDateCodec.def).toEqualTypeOf<z.core.$ZodCodecDef<z.ZodMiniISODateTime, z.ZodMiniDate<Date>>>();
});
test("codec basic functionality", () => {
// ISO string -> Date codec using z.iso.datetime() for input validation
const testIsoString = "2024-01-15T10:30:00.000Z";
const testDate = new Date("2024-01-15T10:30:00.000Z");
// Forward decoding (ISO string -> Date)
const decodedResult = z.decode(isoDateCodec, testIsoString);
expect(decodedResult).toBeInstanceOf(Date);
expect(decodedResult.toISOString()).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
// Backward encoding (Date -> ISO string)
const encodedResult = z.encode(isoDateCodec, testDate);
expect(typeof encodedResult).toBe("string");
expect(encodedResult).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
});
test("codec round trip", () => {
const isoDateCodec = z.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
});
const original = "2024-12-25T15:45:30.123Z";
const toDate = z.decode(isoDateCodec, original);
const backToString = z.encode(isoDateCodec, toDate);
expect(backToString).toMatchInlineSnapshot(`"2024-12-25T15:45:30.123Z"`);
expect(toDate).toBeInstanceOf(Date);
expect(toDate.getTime()).toMatchInlineSnapshot(`1735141530123`);
});
test("codec with refinement", () => {
const isoDateCodec = z
.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
})
.check(z.refine((val) => val.getFullYear() === 2024, { error: "Year must be 2024" }));
// Valid 2024 date
const validDate = z.decode(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(validDate.getFullYear()).toMatchInlineSnapshot(`2024`);
expect(validDate.getTime()).toMatchInlineSnapshot(`1705314600000`);
// Invalid year should fail safely
const invalidYearResult = z.safeDecode(isoDateCodec, "2023-01-15T10:30:00.000Z");
expect(invalidYearResult.success).toBe(false);
if (!invalidYearResult.success) {
expect(invalidYearResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Year must be 2024",
"path": [],
},
]
`);
}
});
test("safe codec operations", () => {
const isoDateCodec = z.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
});
// Safe decode with invalid input
const safeDecodeResult = z.safeDecode(isoDateCodec, "invalid-date");
expect(safeDecodeResult.success).toBe(false);
if (!safeDecodeResult.success) {
expect(safeDecodeResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_format",
"format": "datetime",
"message": "Invalid ISO datetime",
"origin": "string",
"path": [],
"pattern": "/^(?:(?:\\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))$/",
},
]
`);
}
// Safe decode with valid input
const safeDecodeValid = z.safeDecode(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(safeDecodeValid.success).toBe(true);
if (safeDecodeValid.success) {
expect(safeDecodeValid.data).toBeInstanceOf(Date);
expect(safeDecodeValid.data.getTime()).toMatchInlineSnapshot(`1705314600000`);
}
// Safe encode with valid input
const safeEncodeResult = z.safeEncode(isoDateCodec, new Date("2024-01-01"));
expect(safeEncodeResult.success).toBe(true);
if (safeEncodeResult.success) {
expect(safeEncodeResult.data).toMatchInlineSnapshot(`"2024-01-01T00:00:00.000Z"`);
}
});
test("codec with different types", () => {
// String -> Number codec
const stringNumberCodec = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseFloat(str),
encode: (num) => num.toString(),
});
const decodedNumber = z.decode(stringNumberCodec, "42.5");
expect(decodedNumber).toMatchInlineSnapshot(`42.5`);
expect(typeof decodedNumber).toBe("number");
const encodedString = z.encode(stringNumberCodec, 42.5);
expect(encodedString).toMatchInlineSnapshot(`"42.5"`);
expect(typeof encodedString).toBe("string");
});
test("async codec operations", async () => {
const isoDateCodec = z.codec(z.iso.datetime(), z.date(), {
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString(),
});
// Async decode
const decodedResult = await z.decodeAsync(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(decodedResult).toBeInstanceOf(Date);
expect(decodedResult.getTime()).toMatchInlineSnapshot(`1705314600000`);
// Async encode
const encodedResult = await z.encodeAsync(isoDateCodec, new Date("2024-01-15T10:30:00.000Z"));
expect(typeof encodedResult).toBe("string");
expect(encodedResult).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
// Safe async operations
const safeDecodeResult = await z.safeDecodeAsync(isoDateCodec, "2024-01-15T10:30:00.000Z");
expect(safeDecodeResult.success).toBe(true);
if (safeDecodeResult.success) {
expect(safeDecodeResult.data.getTime()).toMatchInlineSnapshot(`1705314600000`);
}
const safeEncodeResult = await z.safeEncodeAsync(isoDateCodec, new Date("2024-01-15T10:30:00.000Z"));
expect(safeEncodeResult.success).toBe(true);
if (safeEncodeResult.success) {
expect(safeEncodeResult.data).toMatchInlineSnapshot(`"2024-01-15T10:30:00.000Z"`);
}
});
test("codec type inference", () => {
const codec = z.codec(z.string(), z.number(), {
decode: (str) => Number.parseInt(str),
encode: (num) => num.toString(),
});
// These should compile without type errors
const decoded: number = z.decode(codec, "123");
const encoded: string = z.encode(codec, 123);
expect(decoded).toMatchInlineSnapshot(`123`);
expect(encoded).toMatchInlineSnapshot(`"123"`);
});
test("nested codec with object containing codec property", () => {
// Nested schema: object containing a codec as one of its properties, with refinements at all levels
const waypointSchema = z
.object({
name: z.string().check(z.minLength(1, "Waypoint name required")),
difficulty: z.enum(["easy", "medium", "hard"]),
coordinate: z
.codec(
z
.string()
.check(z.regex(/^-?\d+,-?\d+$/, "Must be 'x,y' format")), // Input: coordinate string
z
.object({ x: z.number(), y: z.number() })
.check(z.refine((coord) => coord.x >= 0 && coord.y >= 0, { error: "Coordinates must be non-negative" })), // Output: coordinate object
{
decode: (coordString: string) => {
const [x, y] = coordString.split(",").map(Number);
return { x, y };
},
encode: (coord: { x: number; y: number }) => `${coord.x},${coord.y}`,
}
)
.check(z.refine((coord) => coord.x <= 1000 && coord.y <= 1000, { error: "Coordinates must be within bounds" })),
})
.check(
z.refine((waypoint) => waypoint.difficulty !== "hard" || waypoint.coordinate.x >= 100, {
error: "Hard waypoints must be at least 100 units from origin",
})
);
// Test data
const inputWaypoint = {
name: "Summit Point",
difficulty: "medium" as const,
coordinate: "150,200",
};
// Forward decoding (object with string coordinate -> object with coordinate object)
const decodedWaypoint = z.decode(waypointSchema, inputWaypoint);
expect(decodedWaypoint).toMatchInlineSnapshot(`
{
"coordinate": {
"x": 150,
"y": 200,
},
"difficulty": "medium",
"name": "Summit Point",
}
`);
// Backward encoding (object with coordinate object -> object with string coordinate)
const encodedWaypoint = z.encode(waypointSchema, decodedWaypoint);
expect(encodedWaypoint).toMatchInlineSnapshot(`
{
"coordinate": "150,200",
"difficulty": "medium",
"name": "Summit Point",
}
`);
// Test refinements at all levels
// String validation (empty waypoint name)
const emptyNameResult = z.safeDecode(waypointSchema, {
name: "",
difficulty: "easy",
coordinate: "10,20",
});
expect(emptyNameResult.success).toBe(false);
if (!emptyNameResult.success) {
expect(emptyNameResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "too_small",
"inclusive": true,
"message": "Waypoint name required",
"minimum": 1,
"origin": "string",
"path": [
"name",
],
},
]
`);
}
// Enum validation (invalid difficulty)
const invalidDifficultyResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "impossible" as any,
coordinate: "10,20",
});
expect(invalidDifficultyResult.success).toBe(false);
if (!invalidDifficultyResult.success) {
expect(invalidDifficultyResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_value",
"message": "Invalid option: expected one of "easy"|"medium"|"hard"",
"path": [
"difficulty",
],
"values": [
"easy",
"medium",
"hard",
],
},
]
`);
}
// Codec string format validation (invalid coordinate format)
const invalidFormatResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "easy",
coordinate: "invalid",
});
expect(invalidFormatResult.success).toBe(false);
if (!invalidFormatResult.success) {
expect(invalidFormatResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "invalid_format",
"format": "regex",
"message": "Must be 'x,y' format",
"origin": "string",
"path": [
"coordinate",
],
"pattern": "/^-?\\d+,-?\\d+$/",
},
]
`);
}
// Codec object refinement (negative coordinates)
const negativeCoordResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "easy",
coordinate: "-5,10",
});
expect(negativeCoordResult.success).toBe(false);
if (!negativeCoordResult.success) {
expect(negativeCoordResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Coordinates must be non-negative",
"path": [
"coordinate",
],
},
]
`);
}
// Codec-level refinement (coordinates out of bounds)
const outOfBoundsResult = z.safeDecode(waypointSchema, {
name: "Test Point",
difficulty: "easy",
coordinate: "1500,2000",
});
expect(outOfBoundsResult.success).toBe(false);
if (!outOfBoundsResult.success) {
expect(outOfBoundsResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Coordinates must be within bounds",
"path": [
"coordinate",
],
},
]
`);
}
// Object-level refinement (hard waypoint too close to origin)
const hardWaypointResult = z.safeDecode(waypointSchema, {
name: "Expert Point",
difficulty: "hard",
coordinate: "50,60", // x < 100, but hard waypoints need x >= 100
});
expect(hardWaypointResult.success).toBe(false);
if (!hardWaypointResult.success) {
expect(hardWaypointResult.error.issues).toMatchInlineSnapshot(`
[
{
"code": "custom",
"message": "Hard waypoints must be at least 100 units from origin",
"path": [],
},
]
`);
}
// Round trip test
const roundTripResult = z.encode(waypointSchema, z.decode(waypointSchema, inputWaypoint));
expect(roundTripResult).toMatchInlineSnapshot(`
{
"coordinate": "150,200",
"difficulty": "medium",
"name": "Summit Point",
}
`);
});
test("mutating refinements", () => {
const A = z.codec(z.string(), z.string().check(z.trim()), {
decode: (val) => val,
encode: (val) => val,
});
expect(z.decode(A, " asdf ")).toMatchInlineSnapshot(`"asdf"`);
expect(z.encode(A, " asdf ")).toMatchInlineSnapshot(`"asdf"`);
});
test("codec type enforcement - correct encode/decode signatures", () => {
// Test that codec functions have correct type signatures
const stringToNumberCodec = z.codec(z.string(), z.number(), {
decode: (value: string) => Number(value), // core.output<A> -> core.input<B>
encode: (value: number) => String(value), // core.input<B> -> core.output<A>
});
// These should compile without errors - correct types (async support)
expectTypeOf<(value: string, payload: z.core.ParsePayload<string>) => z.core.util.MaybeAsync<number>>(
stringToNumberCodec.def.transform
).toBeFunction();
expectTypeOf<(value: number, payload: z.core.ParsePayload<number>) => z.core.util.MaybeAsync<string>>(
stringToNumberCodec.def.reverseTransform
).toBeFunction();
// Test that decode parameter type is core.output<A> (string)
const validDecode = (value: string) => Number(value);
expectTypeOf(validDecode).toMatchTypeOf<(value: string) => number>();
// Test that encode parameter type is core.input<B> (number)
const validEncode = (value: number) => String(value);
expectTypeOf(validEncode).toMatchTypeOf<(value: number) => string>();
z.codec(z.string(), z.number(), {
// @ts-expect-error - decode should NOT accept core.input<A> as parameter
decode: (value: never, _payload) => Number(value), // Wrong: should be string, not unknown
encode: (value: number, _payload) => String(value),
});
z.codec(z.string(), z.number(), {
decode: (value: string) => Number(value),
// @ts-expect-error - encode should NOT accept core.output<B> as parameter
encode: (value: never) => String(value), // Wrong: should be number, not unknown
});
z.codec(z.string(), z.number(), {
// @ts-expect-error - decode return type should be core.input<B>
decode: (value: string) => String(value), // Wrong: should return number, not string
encode: (value: number) => String(value),
});
z.codec(z.string(), z.number(), {
decode: (value: string) => Number(value),
// @ts-expect-error - encode return type should be core.output<A>
encode: (value: number) => Number(value), // Wrong: should return string, not number
});
});
test("async codec functionality", async () => {
// Test that async encode/decode functions work properly
const asyncCodec = z.codec(z.string(), z.number(), {
decode: async (str) => {
await new Promise((resolve) => setTimeout(resolve, 1)); // Simulate async work
return Number.parseFloat(str);
},
encode: async (num) => {
await new Promise((resolve) => setTimeout(resolve, 1)); // Simulate async work
return num.toString();
},
});
// Test async decode/encode
const decoded = await z.decodeAsync(asyncCodec, "42.5");
expect(decoded).toBe(42.5);
const encoded = await z.encodeAsync(asyncCodec, 42.5);
expect(encoded).toBe("42.5");
// Test that both sync and async work
const mixedCodec = z.codec(z.string(), z.number(), {
decode: async (str) => Number.parseFloat(str),
encode: (num) => num.toString(), // sync encode
});
const mixedResult = await z.decodeAsync(mixedCodec, "123");
expect(mixedResult).toBe(123);
});
test("codec type enforcement - complex types", () => {
type User = { id: number; name: string };
type UserInput = { id: string; name: string };
const userCodec = z.codec(
z.object({ id: z.string(), name: z.string() }),
z.object({ id: z.number(), name: z.string() }),
{
decode: (input: UserInput) => ({ id: Number(input.id), name: input.name }),
encode: (user: User) => ({ id: String(user.id), name: user.name }),
}
);
// Verify correct types are inferred (async support)
expectTypeOf<(input: UserInput, payload: z.core.ParsePayload<UserInput>) => z.core.util.MaybeAsync<User>>(
userCodec.def.transform
).toBeFunction();
expectTypeOf<(user: User, payload: z.core.ParsePayload<User>) => z.core.util.MaybeAsync<UserInput>>(
userCodec.def.reverseTransform
).toBeFunction();
z.codec(
z.object({
id: z.string(),
name: z.string(),
}),
z.object({ id: z.number(), name: z.string() }),
{
// @ts-expect-error - decode parameter should be UserInput, not User
decode: (input: User) => ({ id: Number(input.id), name: input.name }), // Wrong type
encode: (user: User) => ({ id: String(user.id), name: user.name }),
}
);
z.codec(
z.object({
id: z.string(),
name: z.string(),
}),
z.object({ id: z.number(), name: z.string() }),
{
decode: (input: UserInput) => ({ id: Number(input.id), name: input.name }),
// @ts-expect-error - encode parameter should be User, not UserInput
encode: (user: UserInput) => ({ id: String(user.id), name: user.name }), // Wrong type
}
);
});
test("invertCodec", () => {
const inverted = z.invertCodec(isoDateCodec);
type InvIn = z.input<typeof inverted>;
type InvOut = z.output<typeof inverted>;
expectTypeOf<InvIn>().toEqualTypeOf<Date>();
expectTypeOf<InvOut>().toEqualTypeOf<string>();
const testDate = new Date("2024-01-15T10:30:00.000Z");
expect(z.decode(inverted, testDate)).toBe("2024-01-15T10:30:00.000Z");
const encoded = z.encode(inverted, "2024-01-15T10:30:00.000Z");
expect(encoded).toBeInstanceOf(Date);
expect(encoded.toISOString()).toBe("2024-01-15T10:30:00.000Z");
const doubleInverted = z.invertCodec(z.invertCodec(isoDateCodec));
expect(z.decode(doubleInverted, "2024-01-15T10:30:00.000Z")).toBeInstanceOf(Date);
});

36
node_modules/zod/src/v4/mini/tests/computed.test.ts generated vendored Normal file
View File

@@ -0,0 +1,36 @@
import { expect, test } from "vitest";
import * as z from "zod/mini";
import { util as zc } from "zod/v4/core";
test("min/max", () => {
const a = z.number().check(z.minimum(5), z.minimum(6), z.minimum(7), z.maximum(10), z.maximum(11), z.maximum(12));
expect(a._zod.bag.minimum).toEqual(7);
expect(a._zod.bag.maximum).toEqual(10);
});
test("multipleOf", () => {
const b = z.number().check(z.multipleOf(5));
expect(b._zod.bag.multipleOf).toEqual(5);
});
test("int64 format", () => {
const c = z.int64();
expect(c._zod.bag.format).toEqual("int64");
expect(c._zod.bag.minimum).toEqual(zc.BIGINT_FORMAT_RANGES.int64[0]);
expect(c._zod.bag.maximum).toEqual(zc.BIGINT_FORMAT_RANGES.int64[1]);
});
test("int32 format", () => {
const d = z.int32();
expect(d._zod.bag.format).toEqual("int32");
expect(d._zod.bag.minimum).toEqual(zc.NUMBER_FORMAT_RANGES.int32[0]);
expect(d._zod.bag.maximum).toEqual(zc.NUMBER_FORMAT_RANGES.int32[1]);
});
test("array size", () => {
const e = z.array(z.string()).check(z.length(5));
expect(e._zod.bag.length).toEqual(5);
expect(e._zod.bag.minimum).toEqual(5);
expect(e._zod.bag.maximum).toEqual(5);
});

22
node_modules/zod/src/v4/mini/tests/error.test.ts generated vendored Normal file
View File

@@ -0,0 +1,22 @@
import { expect, test } from "vitest";
import * as z from "zod/mini";
test("no locale by default", () => {
const result = z.safeParse(z.string(), 12);
expect(result.success).toEqual(false);
expect(result.error!.issues.length).toEqual(1);
expect(result.error!.issues[0].message).toEqual("Invalid input");
});
test("error inheritance", () => {
const e1 = z.string().safeParse(123).error!;
expect(e1).toBeInstanceOf(z.core.$ZodError);
// expect(e1).not.toBeInstanceOf(Error);
try {
z.string().parse(123);
} catch (e2) {
expect(e2).toBeInstanceOf(z.core.$ZodRealError);
expect(e2).toBeInstanceOf(Error);
}
});

5
node_modules/zod/src/v4/mini/tests/functions.test.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import { expect, test } from "vitest";
test("z.function", () => {
expect(true).toEqual(true);
});

993
node_modules/zod/src/v4/mini/tests/index.test.ts generated vendored Normal file
View File

@@ -0,0 +1,993 @@
import { expect, expectTypeOf, test } from "vitest";
import * as z from "zod/mini";
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.union([]) / z.xor([]) / z.discriminatedUnion(_, []) construct and reject all input", () => {
for (const schema of [z.union([]), z.xor([])]) {
const r = schema.safeParse("anything");
expect(r.success).toEqual(false);
if (!r.success) {
expect(r.error.issues[0].code).toBe("invalid_union");
expect((r.error.issues[0] as any).errors).toEqual([]);
}
}
const disc = z.discriminatedUnion("type", [] as any);
const r = disc.safeParse({ type: "x" });
expect(r.success).toEqual(false);
if (!r.success) {
expect(r.error.issues[0].code).toBe("invalid_union");
expect((r.error.issues[0] as any).errors).toEqual([]);
expect((r.error.issues[0] as any).options).toEqual([]);
}
});
test("z.discriminatedUnion rejects object options missing the discriminator at type level", () => {
// @ts-expect-error missing discriminator property
z.discriminatedUnion("type", [z.object({ value: z.string() })]);
});
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 | undefined)?, ...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 | undefined)?, ...boolean[]]>();
});
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();
// literal union keys
const d = z.record(z.union([z.literal("a"), z.literal(0)]), z.string());
type d = z.output<typeof d>;
expectTypeOf<d>().toEqualTypeOf<Record<"a" | 0, string>>();
expect(z.parse(d, { a: "hello", 0: "world" })).toEqual({
a: "hello",
0: "world",
});
// TypeScript enum keys
enum Enum {
A = 0,
B = "hi",
}
const e = z.record(z.enum(Enum), z.string());
type e = z.output<typeof e>;
expectTypeOf<e>().toEqualTypeOf<Record<Enum, string>>();
expect(z.parse(e, { [Enum.A]: "hello", [Enum.B]: "world" })).toEqual({
[Enum.A]: "hello",
[Enum.B]: "world",
});
// v3-compat single-arg form: z.record(valueType) defaults keyType to z.string()
const f = (z.record as any)(z.number());
expect(f._zod.def.keyType._zod.def.type).toEqual("string");
expect(f._zod.def.valueType._zod.def.type).toEqual("number");
expect(z.parse(f, { a: 1, b: 2 })).toEqual({ a: 1, b: 2 });
});
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();
z.literal(["adf"] as const);
});
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", () => {
const a = z.custom((val) => {
return typeof val === "string";
});
expect(z.parse(a, "hello")).toEqual("hello");
expect(() => z.parse(a, 123)).toThrow();
const b = z.string().check(z.custom((val) => val.length > 3));
expect(z.parse(b, "hello")).toEqual("hello");
expect(() => z.parse(b, "hi")).toThrow();
});
test("z.check", () => {
// this is a more flexible version of z.custom that accepts an arbitrary _parse logic
// the function should return core.$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.with (alias for z.check)", () => {
// .with() should work exactly the same as .check()
const a = z.any().with(
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 with refine
const b = z.string().with(z.refine((val) => val.length > 3, "Must be longer than 3"));
expect(z.safeParse(b, "hello").success).toBe(true);
expect(z.safeParse(b, "hi").success).toBe(false);
// Test with function
const c = z.string().with(({ value, issues }) => {
if (value.length <= 3) {
issues.push({
code: "custom",
input: value,
message: "Must be longer than 3",
});
}
});
expect(z.safeParse(c, "hello").success).toBe(true);
expect(z.safeParse(c, "hi").success).toBe(false);
});
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>;
a._zod.output;
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();
});
test("z.stringbool", () => {
const a = z.stringbool();
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 });
const b = z.stringbool({
truthy: ["y"],
falsy: ["n"],
});
expect(z.parse(b, "y")).toEqual(true);
expect(z.parse(b, "n")).toEqual(false);
expect(z.safeParse(b, "true")).toMatchObject({ success: false });
expect(z.safeParse(b, "false")).toMatchObject({ success: false });
const c = z.stringbool({
case: "sensitive",
});
expect(z.parse(c, "true")).toEqual(true);
expect(z.safeParse(c, "TRUE")).toMatchObject({ success: false });
});
// promise
test("z.promise", async () => {
const a = z.promise(z.string());
type a = z.output<typeof a>;
expectTypeOf<a>().toEqualTypeOf<Promise<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("z.pipe type enforcement", () => {
z.pipe(
z.pipe(
z.string().check(z.regex(/asdf/)),
z.transform((v) => new Date(v))
),
z.date().check(z.maximum(new Date()))
);
});
test("def typing", () => {
z.string().def.type satisfies "string";
z.email().def.format satisfies "email";
z.number().def.type satisfies "number";
z.float64().def.format satisfies z.core.$ZodNumberFormats;
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.nullable(z.string()).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";
expectTypeOf(z.literal("example").def.values).toEqualTypeOf<"example"[]>();
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.optional(z.string()).def.type satisfies "optional";
z._default(z.string(), "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.nonoptional(z.string()).def.type satisfies "nonoptional";
z.readonly(z.unknown()).def.type satisfies "readonly";
z.nan().def.type satisfies "nan";
z.pipe(z.unknown(), z.number()).def.type satisfies "pipe";
z.success(z.string()).def.type satisfies "success";
z.catch(z.string(), "fallback").def.type satisfies "catch";
z.file().def.type satisfies "file";
});
test("defaulted object schema returns shallow clone", () => {
const schema = z._default(
z.object({
a: z.string(),
}),
{ a: "x" }
);
const result1 = schema.parse(undefined);
const result2 = schema.parse(undefined);
expect(result1).not.toBe(result2);
expect(result1).toEqual(result2);
});
test("runtime type property exists and returns correct values", () => {
const stringSchema = z.string();
expect(stringSchema.type).toBe("string");
});
test("type narrowing works with type property", () => {
type ArrayOrRecord = z.ZodMiniArray<z.ZodMiniString> | z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniAny>;
const arraySchema = z.array(z.string()) as ArrayOrRecord;
if (arraySchema.type === "array") {
expectTypeOf(arraySchema).toEqualTypeOf<z.ZodMiniArray<z.ZodMiniString<unknown>>>();
expect(arraySchema.def.element).toBeDefined();
}
});

95
node_modules/zod/src/v4/mini/tests/number.test.ts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import { expect, expectTypeOf, test } from "vitest";
import * as z from "zod/mini";
test("z.number", () => {
const a = z.number();
expect(z.parse(a, 123)).toEqual(123);
expect(z.parse(a, 123.45)).toEqual(123.45);
expect(() => z.parse(a, "123")).toThrow();
expect(() => z.parse(a, false)).toThrow();
type a = z.infer<typeof a>;
expectTypeOf<a>().toEqualTypeOf<number>();
});
test("z.number async", async () => {
const a = z.number().check(z.refine(async (_) => _ > 0));
await expect(z.parseAsync(a, 123)).resolves.toEqual(123);
await expect(() => z.parseAsync(a, -123)).rejects.toThrow();
await expect(() => z.parseAsync(a, "123")).rejects.toThrow();
});
test("z.int", () => {
const a = z.int();
expect(z.parse(a, 123)).toEqual(123);
expect(() => z.parse(a, 123.45)).toThrow();
expect(() => z.parse(a, "123")).toThrow();
expect(() => z.parse(a, false)).toThrow();
});
test("z.float32", () => {
const a = z.float32();
expect(z.parse(a, 123.45)).toEqual(123.45);
expect(() => z.parse(a, "123.45")).toThrow();
expect(() => z.parse(a, false)).toThrow();
// -3.4028234663852886e38, 3.4028234663852886e38;
expect(() => z.parse(a, 3.4028234663852886e38 * 2)).toThrow(); // Exceeds max
expect(() => z.parse(a, -3.4028234663852886e38 * 2)).toThrow(); // Exceeds min
});
test("z.float64", () => {
const a = z.float64();
expect(z.parse(a, 123.45)).toEqual(123.45);
expect(() => z.parse(a, "123.45")).toThrow();
expect(() => z.parse(a, false)).toThrow();
expect(() => z.parse(a, 1.7976931348623157e308 * 2)).toThrow(); // Exceeds max
expect(() => z.parse(a, -1.7976931348623157e308 * 2)).toThrow(); // Exceeds min
});
test("z.int32", () => {
const a = z.int32();
expect(z.parse(a, 123)).toEqual(123);
expect(() => z.parse(a, 123.45)).toThrow();
expect(() => z.parse(a, "123")).toThrow();
expect(() => z.parse(a, false)).toThrow();
expect(() => z.parse(a, 2147483648)).toThrow(); // Exceeds max
expect(() => z.parse(a, -2147483649)).toThrow(); // Exceeds min
});
test("z.uint32", () => {
const a = z.uint32();
expect(z.parse(a, 123)).toEqual(123);
expect(() => z.parse(a, -123)).toThrow();
expect(() => z.parse(a, 123.45)).toThrow();
expect(() => z.parse(a, "123")).toThrow();
expect(() => z.parse(a, false)).toThrow();
expect(() => z.parse(a, 4294967296)).toThrow(); // Exceeds max
expect(() => z.parse(a, -1)).toThrow(); // Below min
});
test("z.int64", () => {
const a = z.int64();
expect(z.parse(a, BigInt(123))).toEqual(BigInt(123));
expect(() => z.parse(a, 123)).toThrow();
expect(() => z.parse(a, 123.45)).toThrow();
expect(() => z.parse(a, "123")).toThrow();
expect(() => z.parse(a, false)).toThrow();
expect(() => z.parse(a, BigInt("9223372036854775808"))).toThrow();
expect(() => z.parse(a, BigInt("-9223372036854775809"))).toThrow();
// expect(() => z.parse(a, BigInt("9223372036854775808"))).toThrow(); // Exceeds max
// expect(() => z.parse(a, BigInt("-9223372036854775809"))).toThrow(); // Exceeds min
});
test("z.uint64", () => {
const a = z.uint64();
expect(z.parse(a, BigInt(123))).toEqual(BigInt(123));
expect(() => z.parse(a, 123)).toThrow();
expect(() => z.parse(a, -123)).toThrow();
expect(() => z.parse(a, 123.45)).toThrow();
expect(() => z.parse(a, "123")).toThrow();
expect(() => z.parse(a, false)).toThrow();
expect(() => z.parse(a, BigInt("18446744073709551616"))).toThrow(); // Exceeds max
expect(() => z.parse(a, BigInt("-1"))).toThrow(); // Below min
// expect(() => z.parse(a, BigInt("18446744073709551616"))).toThrow(); // Exceeds max
// expect(() => z.parse(a, BigInt("-1"))).toThrow(); // Below min
});

227
node_modules/zod/src/v4/mini/tests/object.test.ts generated vendored Normal file
View File

@@ -0,0 +1,227 @@
import { expect, expectTypeOf, test } from "vitest";
import * as z from "zod/mini";
test("z.object", () => {
const a = z.object({
name: z.string(),
age: z.number(),
points: z.optional(z.number()),
"test?": z.boolean(),
});
a._zod.def.shape["test?"];
a._zod.def.shape.points._zod.optin;
type a = z.output<typeof a>;
expectTypeOf<a>().toEqualTypeOf<{
name: string;
age: number;
points?: number | undefined;
"test?": boolean;
}>();
expect(z.parse(a, { name: "john", age: 30, "test?": true })).toEqual({
name: "john",
age: 30,
"test?": true,
});
// "test?" is required in ZodObject
expect(() => z.parse(a, { name: "john", age: "30" })).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// 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("z.object().check()", () => {
const a = z.object({
name: z.string(),
age: z.number(),
points: z.optional(z.number()),
"test?": z.boolean(),
});
type a = z.output<typeof a>;
a.check(({ value }) => {
expectTypeOf(value).toEqualTypeOf<a>();
});
});
test("z.strictObject", () => {
const a = z.strictObject({
name: z.string(),
});
expect(z.parse(a, { name: "john" })).toEqual({ name: "john" });
expect(() => z.parse(a, { name: "john", age: 30 })).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
});
test("z.looseObject", () => {
const a = z.looseObject({
name: z.string(),
age: z.number(),
});
expect(z.parse(a, { name: "john", age: 30 })).toEqual({
name: "john",
age: 30,
});
expect(z.parse(a, { name: "john", age: 30, extra: true })).toEqual({
name: "john",
age: 30,
extra: true,
});
expect(() => z.parse(a, "hello")).toThrow();
});
const userSchema = z.object({
name: z.string(),
age: z.number(),
email: z.optional(z.string()),
});
test("z.keyof", () => {
// z.keyof returns an enum schema of the keys of an object schema
const userKeysSchema = z.keyof(userSchema);
type UserKeys = z.infer<typeof userKeysSchema>;
expectTypeOf<UserKeys>().toEqualTypeOf<"name" | "age" | "email">();
expect(userKeysSchema).toBeDefined();
expect(userKeysSchema._zod.def.type).toBe("enum");
expect(userKeysSchema._zod.def.entries).toEqual({
name: "name",
age: "age",
email: "email",
});
expect(z.safeParse(userKeysSchema, "name").success).toBe(true);
expect(z.safeParse(userKeysSchema, "age").success).toBe(true);
expect(z.safeParse(userKeysSchema, "email").success).toBe(true);
expect(z.safeParse(userKeysSchema, "isAdmin").success).toBe(false);
});
test("z.extend", () => {
const extendedSchema = z.extend(userSchema, {
isAdmin: z.boolean(),
});
type ExtendedUser = z.infer<typeof extendedSchema>;
expectTypeOf<ExtendedUser>().toEqualTypeOf<{
name: string;
age: number;
email?: string | undefined;
isAdmin: boolean;
}>();
expect(extendedSchema).toBeDefined();
expect(z.safeParse(extendedSchema, { name: "John", age: 30, isAdmin: true }).success).toBe(true);
});
test("z.safeExtend", () => {
const extended = z.safeExtend(userSchema, { name: z.string() });
expect(z.safeParse(extended, { name: "John", age: 30 }).success).toBe(true);
type Extended = z.infer<typeof extended>;
expectTypeOf<Extended>().toEqualTypeOf<{ name: string; age: number; email?: string | undefined }>();
// @ts-expect-error
z.safeExtend(userSchema, { name: z.number() });
});
test("z.pick", () => {
const pickedSchema = z.pick(userSchema, { name: true, email: true });
type PickedUser = z.infer<typeof pickedSchema>;
expectTypeOf<PickedUser>().toEqualTypeOf<{ name: string; email?: string | undefined }>();
expect(pickedSchema).toBeDefined();
expect(z.safeParse(pickedSchema, { name: "John", email: "john@example.com" }).success).toBe(true);
});
test("z.omit", () => {
const omittedSchema = z.omit(userSchema, { age: true });
type OmittedUser = z.infer<typeof omittedSchema>;
expectTypeOf<OmittedUser>().toEqualTypeOf<{
name: string;
email?: string | undefined;
}>();
expect(omittedSchema).toBeDefined();
expect(Reflect.ownKeys(omittedSchema._zod.def.shape)).toEqual(["name", "email"]);
expect(z.safeParse(omittedSchema, { name: "John", email: "john@example.com" }).success).toBe(true);
});
test("z.partial", () => {
const partialSchema = z.partial(userSchema);
type PartialUser = z.infer<typeof partialSchema>;
expectTypeOf<PartialUser>().toEqualTypeOf<{
name?: string | undefined;
age?: number | undefined;
email?: string | undefined;
}>();
expect(z.safeParse(partialSchema, { name: "John" }).success).toBe(true);
});
test("z.partial with mask", () => {
const partialSchemaWithMask = z.partial(userSchema, { name: true });
type PartialUserWithMask = z.infer<typeof partialSchemaWithMask>;
expectTypeOf<PartialUserWithMask>().toEqualTypeOf<{
name?: string | undefined;
age: number;
email?: string | undefined;
}>();
expect(z.safeParse(partialSchemaWithMask, { age: 30 }).success).toBe(true);
expect(z.safeParse(partialSchemaWithMask, { name: "John" }).success).toBe(false);
});
test("z.pick/omit/partial/required - do not allow unknown keys", () => {
const schema = z.object({
name: z.string(),
age: z.number(),
});
// Mixed valid + invalid keys - throws at parse time (lazy evaluation)
// @ts-expect-error
expect(() => z.parse(z.pick(schema, { name: true, asdf: true }), {})).toThrow();
// @ts-expect-error
expect(() => z.parse(z.omit(schema, { name: true, asdf: true }), {})).toThrow();
// @ts-expect-error
expect(() => z.parse(z.partial(schema, { name: true, asdf: true }), {})).toThrow();
// @ts-expect-error
expect(() => z.parse(z.required(schema, { name: true, asdf: true }), {})).toThrow();
// Only invalid keys
// @ts-expect-error
expect(() => z.parse(z.pick(schema, { $unknown: true }), {})).toThrow();
// @ts-expect-error
expect(() => z.parse(z.omit(schema, { $unknown: true }), {})).toThrow();
// @ts-expect-error
expect(() => z.parse(z.partial(schema, { $unknown: true }), {})).toThrow();
// @ts-expect-error
expect(() => z.parse(z.required(schema, { $unknown: true }), {})).toThrow();
});
test("z.catchall", () => {
// z.catchall()
const schema = z.catchall(
z.object({
name: z.string(),
// age: z.number(),
}),
z.string()
);
type schemaIn = z.input<typeof schema>;
type schemaOut = z.output<typeof schema>;
expectTypeOf<schemaIn>().toEqualTypeOf<{
name: string;
[key: string]: string;
}>();
expectTypeOf<schemaOut>().toEqualTypeOf<{
name: string;
[key: string]: string;
}>();
schema.parse({
name: "john",
age: "30",
extra: "extra value",
});
expect(() => schema.parse({ name: "john", age: 30 })).toThrow();
});

43
node_modules/zod/src/v4/mini/tests/prototypes.test.ts generated vendored Normal file
View File

@@ -0,0 +1,43 @@
import { expect, test } from "vitest";
import * as z from "zod/mini";
declare module "zod/v4/core" {
interface $ZodType {
/** @deprecated */
_core(): string;
}
}
test("prototype extension", () => {
z.core.$ZodType.prototype._core = function () {
return "_core";
};
// should pass
const result = z.string()._core();
expect(result).toBe("_core");
// expectTypeOf<typeof result>().toEqualTypeOf<string>();
// clean up
z.ZodMiniType.prototype._core = undefined;
});
declare module "zod/v4/mini" {
interface ZodMiniType {
/** @deprecated */
_mini(): string;
}
}
test("prototype extension", () => {
z.ZodMiniType.prototype._mini = function () {
return "_mini";
};
// should pass
const result = z.string()._mini();
expect(result).toBe("_mini");
// clean up
z.ZodMiniType.prototype._mini = undefined;
});

View File

@@ -0,0 +1,325 @@
import { expect, expectTypeOf, test } from "vitest";
import { z } from "zod/mini";
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(): z.ZodMiniOptional<z.ZodMiniArray<typeof Category>> {
return z.optional(z.array(Category));
},
});
Category.parse(data);
type Category = z.infer<typeof Category>;
interface _Category {
name: string;
subcategories?: _Category[] | undefined;
}
expectTypeOf<Category>().toEqualTypeOf<_Category>();
});
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(): z.ZodMiniNullable<typeof LL> {
return z.nullable(LL);
},
});
LL.parse(data);
type LL = z.infer<typeof LL>;
type _LL = {
value: number;
next: _LL | null;
};
expectTypeOf<LL>().toEqualTypeOf<_LL>();
});
test("mutual recursion - native", () => {
const Alazy = z.object({
val: z.number(),
get b() {
return z.optional(Blazy);
},
});
const Blazy = z.object({
val: z.number(),
get a() {
return z.optional(Alazy);
},
});
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);
type Alazy = z.infer<typeof Alazy>;
type Blazy = z.infer<typeof Blazy>;
interface _Alazy {
val: number;
b?: _Blazy | undefined;
}
interface _Blazy {
val: number;
a?: _Alazy | undefined;
}
expectTypeOf<Alazy>().toEqualTypeOf<_Alazy>();
expectTypeOf<Blazy>().toEqualTypeOf<_Blazy>();
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 = z.pick(Category, { name: true });
const OmittedCategory = z.omit(Category, { subcategories: true });
type PickedCategory = z.infer<typeof PickedCategory>;
type OmittedCategory = z.infer<typeof OmittedCategory>;
interface _PickedCategory {
name: string;
}
interface _OmittedCategory {
name: string;
}
expectTypeOf<PickedCategory>().toEqualTypeOf<_PickedCategory>();
expectTypeOf<OmittedCategory>().toEqualTypeOf<_OmittedCategory>();
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.ZodMiniOptional<z.ZodMiniArray<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(),
features: z.array(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("recursion compatibility", () => {
// array
const A = z.object({
get subcategories() {
return z.array(A);
},
});
// tuple
const B = z.object({
get subcategories() {
return z.tuple([B, B]);
},
});
// object
const C = z.object({
get subcategories() {
return z.object({
subcategories: C,
});
},
});
// union
const D = z.object({
get subcategories() {
return z.union([D, z.string()]);
},
});
// intersection
const E = z.object({
get subcategories() {
return z.intersection(E, E);
},
});
// record
const F = z.object({
get subcategories() {
return z.record(z.string(), F);
},
});
// map
const G = z.object({
get subcategories() {
return z.map(z.string(), G);
},
});
// set
const H = z.object({
get subcategories() {
return z.set(H);
},
});
// optional
const I = z.object({
get subcategories() {
return z.optional(I);
},
});
// nullable
const J = z.object({
get subcategories() {
return z.nullable(J);
},
});
// optional
const L = z.object({
get subcategories() {
return z.optional(L);
},
});
// nullable
const M = z.object({
get subcategories() {
return z.nullable(M);
},
});
// nonoptional
const N = z.object({
get subcategories() {
return z.nonoptional(N);
},
});
});
test("shape stays writeable through object/strictObject/looseObject/extend with getters", () => {
const Cat = z.object({
name: z.string(),
get sub(): z.ZodMiniArray<typeof Cat> {
return z.array(Cat);
},
});
type CatShape = (typeof Cat)["shape"];
expectTypeOf<CatShape>().toEqualTypeOf<{
name: z.ZodMiniString<string>;
sub: z.ZodMiniArray<typeof Cat>;
}>();
const StrictCat = z.strictObject({
name: z.string(),
get sub(): z.ZodMiniArray<typeof StrictCat> {
return z.array(StrictCat);
},
});
type StrictShape = (typeof StrictCat)["shape"];
expectTypeOf<StrictShape>().toEqualTypeOf<{
name: z.ZodMiniString<string>;
sub: z.ZodMiniArray<typeof StrictCat>;
}>();
const LooseCat = z.looseObject({
name: z.string(),
get sub(): z.ZodMiniArray<typeof LooseCat> {
return z.array(LooseCat);
},
});
type LooseShape = (typeof LooseCat)["shape"];
expectTypeOf<LooseShape>().toEqualTypeOf<{
name: z.ZodMiniString<string>;
sub: z.ZodMiniArray<typeof LooseCat>;
}>();
const Base = z.object({ name: z.string() });
const Extended = z.extend(Base, {
get sub(): z.ZodMiniArray<typeof Extended> {
return z.array(Extended);
},
});
type ExtendedShape = (typeof Extended)["shape"];
expectTypeOf<ExtendedShape>().toEqualTypeOf<{
name: z.ZodMiniString<string>;
sub: z.ZodMiniArray<typeof Extended>;
}>();
});

View File

@@ -0,0 +1,50 @@
import { expect, test } from "vitest";
import type { StandardSchemaWithJSON } from "../../core/standard-schema.js";
import * as z from "../index.js";
function acceptSchema(schema: StandardSchemaWithJSON) {
return schema;
}
test("Zod Mini schemas are NOT assignable to StandardJSONSchema", () => {
const schema = z.string();
// @ts-expect-error
const _standard: StandardSchemaWithJSON["~standard"] = schema;
// @ts-expect-error
acceptSchema(schema);
});
test("toJSONSchema result ~standard.jsonSchema works with objects", () => {
const schema = z.object({
firstName: z.string(),
lastName: z.string(),
});
const jsonSchema = z.toJSONSchema(schema);
// Call ~standard.jsonSchema.input - this should not throw
const inputSchema = jsonSchema["~standard"].jsonSchema.input({ target: "draft-07" });
expect(inputSchema).toMatchObject({
type: "object",
properties: {
firstName: { type: "string" },
lastName: { type: "string" },
},
required: ["firstName", "lastName"],
});
// Call ~standard.jsonSchema.output - this should not throw
const outputSchema = jsonSchema["~standard"].jsonSchema.output({ target: "draft-07" });
expect(outputSchema).toMatchObject({
type: "object",
properties: {
firstName: { type: "string" },
lastName: { type: "string" },
},
required: ["firstName", "lastName"],
});
});

352
node_modules/zod/src/v4/mini/tests/string.test.ts generated vendored Normal file
View File

@@ -0,0 +1,352 @@
import { expect, expectTypeOf, test } from "vitest";
import * as z from "zod/mini";
const FAIL = { success: false };
test("z.string", async () => {
const a = z.string();
expect(z.parse(a, "hello")).toEqual("hello");
expect(() => z.parse(a, 123)).toThrow();
expect(() => z.parse(a, false)).toThrow();
type a = z.infer<typeof a>;
expectTypeOf<a>().toEqualTypeOf<string>();
});
// test("z.string with description", () => {
// const a = z.string({ description: "string description" });
// a._def;
// expect(a._def.description).toEqual("string description");
// });
test("z.string with custom error", () => {
const a = z.string({ error: () => "BAD" });
expect(z.safeParse(a, 123).error!.issues[0].message).toEqual("BAD");
});
test("inference in checks", () => {
const a = z.string().check(z.refine((val) => val.length));
z.parse(a, "___");
expect(() => z.parse(a, "")).toThrow();
const b = z.string().check(z.refine((val) => val.length));
z.parse(b, "___");
expect(() => z.parse(b, "")).toThrow();
const c = z.string().check(z.refine((val) => val.length));
z.parse(c, "___");
expect(() => z.parse(c, "")).toThrow();
const d = z.string().check(z.refine((val) => val.length));
z.parse(d, "___");
expect(() => z.parse(d, "")).toThrow();
});
test("z.string async", async () => {
// async
const a = z.string().check(z.refine(async (val) => val.length));
expect(await z.parseAsync(a, "___")).toEqual("___");
await expect(() => z.parseAsync(a, "")).rejects.toThrowError();
});
test("z.uuid", () => {
const a = z.uuid();
// parse uuid
z.parse(a, "550e8400-e29b-41d4-a716-446655440000");
z.parse(a, "550e8400-e29b-61d4-a716-446655440000");
// bad uuid
expect(() => z.parse(a, "hello")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
const b = z.uuidv4();
z.parse(b, "550e8400-e29b-41d4-a716-446655440000");
expect(z.safeParse(b, "550e8400-e29b-61d4-a716-446655440000")).toMatchObject(FAIL);
const c = z.uuidv6();
z.parse(c, "550e8400-e29b-61d4-a716-446655440000");
expect(z.safeParse(c, "550e8400-e29b-41d4-a716-446655440000")).toMatchObject(FAIL);
const d = z.uuidv7();
z.parse(d, "550e8400-e29b-71d4-a716-446655440000");
expect(z.safeParse(d, "550e8400-e29b-41d4-a716-446655440000")).toMatchObject(FAIL);
expect(z.safeParse(d, "550e8400-e29b-61d4-a716-446655440000")).toMatchObject(FAIL);
});
test("z.email", () => {
const a = z.email();
expect(z.parse(a, "test@test.com")).toEqual("test@test.com");
expect(() => z.parse(a, "test")).toThrow();
expect(z.safeParse(a, "bad email", { error: () => "bad email" }).error!.issues[0].message).toEqual("bad email");
const b = z.email("bad email");
expect(z.safeParse(b, "bad email").error!.issues[0].message).toEqual("bad email");
const c = z.email({ error: "bad email" });
expect(z.safeParse(c, "bad email").error!.issues[0].message).toEqual("bad email");
const d = z.email({ error: () => "bad email" });
expect(z.safeParse(d, "bad email").error!.issues[0].message).toEqual("bad email");
});
test("z.url", () => {
const a = z.url();
// valid URLs
expect(a.parse("http://example.com")).toEqual("http://example.com");
expect(a.parse("https://example.com")).toEqual("https://example.com");
expect(a.parse("ftp://example.com")).toEqual("ftp://example.com");
expect(a.parse("http://sub.example.com")).toEqual("http://sub.example.com");
expect(a.parse("https://example.com/path?query=123#fragment")).toEqual("https://example.com/path?query=123#fragment");
expect(a.parse("http://localhost")).toEqual("http://localhost");
expect(a.parse("https://localhost")).toEqual("https://localhost");
expect(a.parse("http://localhost:3000")).toEqual("http://localhost:3000");
expect(a.parse("https://localhost:3000")).toEqual("https://localhost:3000");
// test trimming
expect(a.parse(" http://example.com ")).toEqual("http://example.com");
expect(a.parse(" http://example.com/")).toEqual("http://example.com/");
expect(a.parse(" http://example.com")).toEqual("http://example.com");
expect(a.parse(" http://example.com//")).toEqual("http://example.com//");
// invalid URLs
expect(() => a.parse("not-a-url")).toThrow();
// expect(() => a.parse("http:/example.com")).toThrow();
expect(() => a.parse("://example.com")).toThrow();
expect(() => a.parse("http://")).toThrow();
expect(() => a.parse("example.com")).toThrow();
// wrong type
expect(() => a.parse(123)).toThrow();
expect(() => a.parse(null)).toThrow();
expect(() => a.parse(undefined)).toThrow();
});
test("z.url with optional hostname regex", () => {
const a = z.url({ hostname: /example\.com$/ });
expect(a.parse("http://example.com")).toEqual("http://example.com");
expect(a.parse("https://sub.example.com")).toEqual("https://sub.example.com");
expect(() => a.parse("http://examples.com")).toThrow();
expect(() => a.parse("http://example.org")).toThrow();
expect(() => a.parse("asdf")).toThrow();
});
test("z.url - file urls", () => {
// file URLs
const a = z.url({ hostname: /.*/ }); // allow any hostname
expect(a.parse("file:///path/to/file.txt")).toEqual("file:///path/to/file.txt");
expect(a.parse("file:///C:/path/to/file.txt")).toEqual("file:///C:/path/to/file.txt");
expect(a.parse("file:///C:/path/to/file.txt?query=123#fragment")).toEqual(
"file:///C:/path/to/file.txt?query=123#fragment"
);
});
test("z.url with optional protocol regex", () => {
const a = z.url({ protocol: /^https?$/ });
expect(a.parse("http://example.com")).toEqual("http://example.com");
expect(a.parse("https://example.com")).toEqual("https://example.com");
expect(() => a.parse("ftp://example.com")).toThrow();
expect(() => a.parse("mailto:example@example.com")).toThrow();
expect(() => a.parse("asdf")).toThrow();
});
test("z.url with both hostname and protocol regexes", () => {
const a = z.url({ hostname: /example\.com$/, protocol: /^https$/ });
expect(a.parse("https://example.com")).toEqual("https://example.com");
expect(a.parse("https://sub.example.com")).toEqual("https://sub.example.com");
expect(() => a.parse("http://example.com")).toThrow();
expect(() => a.parse("https://example.org")).toThrow();
expect(() => a.parse("ftp://example.com")).toThrow();
expect(() => a.parse("asdf")).toThrow();
});
test("z.url with invalid regex patterns", () => {
const a = z.url({ hostname: /a+$/, protocol: /^ftp$/ });
a.parse("ftp://a");
a.parse("ftp://aaaaaaaa");
expect(() => a.parse("http://aaa")).toThrow();
expect(() => a.parse("https://example.com")).toThrow();
expect(() => a.parse("ftp://asdfasdf")).toThrow();
expect(() => a.parse("ftp://invalid")).toThrow();
});
test("z.emoji", () => {
const a = z.emoji();
expect(z.parse(a, "😀")).toEqual("😀");
expect(() => z.parse(a, "hello")).toThrow();
});
test("z.nanoid", () => {
const a = z.nanoid();
expect(z.parse(a, "8FHZpIxleEK3axQRBNNjN")).toEqual("8FHZpIxleEK3axQRBNNjN");
expect(() => z.parse(a, "abc")).toThrow();
});
test("z.cuid", () => {
const a = z.cuid();
expect(z.parse(a, "cixs7y0c0000f7x3b1z6m3w6r")).toEqual("cixs7y0c0000f7x3b1z6m3w6r");
expect(() => z.parse(a, "abc")).toThrow();
});
test("z.cuid2", () => {
const a = z.cuid2();
expect(z.parse(a, "cixs7y0c0000f7x3b1z6m3w6r")).toEqual("cixs7y0c0000f7x3b1z6m3w6r");
expect(() => z.parse(a, 123)).toThrow();
});
test("z.ulid", () => {
const a = z.ulid();
expect(z.parse(a, "01ETGRM9QYVX6S9V2F3B6JXG4N")).toEqual("01ETGRM9QYVX6S9V2F3B6JXG4N");
expect(() => z.parse(a, "abc")).toThrow();
});
test("z.xid", () => {
const a = z.xid();
expect(z.parse(a, "9m4e2mr0ui3e8a215n4g")).toEqual("9m4e2mr0ui3e8a215n4g");
expect(() => z.parse(a, "abc")).toThrow();
});
test("z.ksuid", () => {
const a = z.ksuid();
expect(z.parse(a, "2naeRjTrrHJAkfd3tOuEjw90WCA")).toEqual("2naeRjTrrHJAkfd3tOuEjw90WCA");
expect(() => z.parse(a, "abc")).toThrow();
});
// test("z.ip", () => {
// const a = z.ip();
// expect(z.parse(a, "127.0.0.1")).toEqual("127.0.0.1");
// expect(z.parse(a, "2001:0db8:85a3:0000:0000:8a2e:0370:7334")).toEqual("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
// expect(() => z.parse(a, "abc")).toThrow();
// });
test("z.ipv4", () => {
const a = z.ipv4();
// valid ipv4
expect(z.parse(a, "192.168.1.1")).toEqual("192.168.1.1");
expect(z.parse(a, "255.255.255.255")).toEqual("255.255.255.255");
// invalid ipv4
expect(() => z.parse(a, "999.999.999.999")).toThrow();
expect(() => z.parse(a, "256.256.256.256")).toThrow();
expect(() => z.parse(a, "192.168.1")).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
});
test("z.ipv6", () => {
const a = z.ipv6();
// valid ipv6
expect(z.parse(a, "2001:0db8:85a3:0000:0000:8a2e:0370:7334")).toEqual("2001:0db8:85a3:0000:0000:8a2e:0370:7334");
expect(z.parse(a, "::1")).toEqual("::1");
// invalid ipv6
expect(() => z.parse(a, "2001:db8::85a3::8a2e:370:7334")).toThrow();
expect(() => z.parse(a, "2001:db8:85a3:0:0:8a2e:370g:7334")).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
});
test("z.mac", () => {
const a = z.mac();
// valid mac
expect(z.parse(a, "00:1A:2B:3C:4D:5E")).toEqual("00:1A:2B:3C:4D:5E");
// invalid mac (dash delimiter not accepted by default)
expect(() => z.parse(a, "01-23-45-67-89-AB")).toThrow();
expect(() => z.parse(a, "00:1A:2B::4D:5E")).toThrow();
expect(() => z.parse(a, "00:1a-2B:3c-4D:5e")).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
});
test("z.mac with custom delimiter", () => {
const a = z.mac({ delimiter: ":" });
// valid mac with colon
expect(z.parse(a, "00:1A:2B:3C:4D:5E")).toEqual("00:1A:2B:3C:4D:5E");
// invalid mac with dash
expect(() => z.parse(a, "00-1A-2B-3C-4D-5E")).toThrow();
const b = z.mac({ delimiter: "-" });
// valid mac with dash
expect(z.parse(b, "00-1A-2B-3C-4D-5E")).toEqual("00-1A-2B-3C-4D-5E");
// invalid mac with colon
expect(() => z.parse(b, "00:1A:2B:3C:4D:5E")).toThrow();
const c = z.mac({ delimiter: ":" });
// colon-only mac
expect(z.parse(c, "00:1A:2B:3C:4D:5E")).toEqual("00:1A:2B:3C:4D:5E");
expect(() => z.parse(c, "00-1A-2B-3C-4D-5E")).toThrow();
});
test("z.base64", () => {
const a = z.base64();
// valid base64
expect(z.parse(a, "SGVsbG8gd29ybGQ=")).toEqual("SGVsbG8gd29ybGQ=");
expect(z.parse(a, "U29tZSBvdGhlciBzdHJpbmc=")).toEqual("U29tZSBvdGhlciBzdHJpbmc=");
// invalid base64
expect(() => z.parse(a, "SGVsbG8gd29ybGQ")).toThrow();
expect(() => z.parse(a, "U29tZSBvdGhlciBzdHJpbmc")).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// whitespace is not allowed (atob would otherwise strip it)
expect(() => z.parse(a, "123 ")).toThrow();
expect(() => z.parse(a, "SGVsbG8gd29ybGQ= ")).toThrow();
expect(() => z.parse(a, "SGVsbG8gd29ybGQ=\n")).toThrow();
expect(() => z.parse(a, "SGVs bG8gd29ybGQ=")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
});
// test("z.jsonString", () => {
// const a = z.jsonString();
// // valid JSON string
// expect(z.parse(a, '{"key":"value"}')).toEqual('{"key":"value"}');
// expect(z.parse(a, '["item1", "item2"]')).toEqual('["item1", "item2"]');
// // invalid JSON string
// expect(() => z.parse(a, '{"key":value}')).toThrow();
// expect(() => z.parse(a, '["item1", "item2"')).toThrow();
// expect(() => z.parse(a, "hello")).toThrow();
// // wrong type
// expect(() => z.parse(a, 123)).toThrow();
// });
test("z.e164", () => {
const a = z.e164();
// valid e164
expect(z.parse(a, "+1234567890")).toEqual("+1234567890");
expect(z.parse(a, "+19876543210")).toEqual("+19876543210");
// invalid e164
expect(() => z.parse(a, "1234567890")).toThrow();
expect(() => z.parse(a, "+12345")).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
});
test("z.jwt", () => {
const a = z.jwt();
// valid jwt
expect(
z.parse(
a,
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
)
).toEqual(
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
);
// invalid jwt
expect(() => z.parse(a, "invalid.jwt.token")).toThrow();
expect(() => z.parse(a, "hello")).toThrow();
// wrong type
expect(() => z.parse(a, 123)).toThrow();
});
test("z.hash generic format", () => {
expect(z.hash("sha256").parse("a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3")).toBe(
"a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3"
);
// --- Type-level checks (ensure the literal format string is encoded in the return type)
expectTypeOf(z.hash("md5")).toEqualTypeOf<z.ZodMiniCustomStringFormat<"md5_hex">>();
expectTypeOf(z.hash("sha1")).toEqualTypeOf<z.ZodMiniCustomStringFormat<"sha1_hex">>();
expectTypeOf(z.hash("sha256", { enc: "base64" as const })).toEqualTypeOf<
z.ZodMiniCustomStringFormat<"sha256_base64">
>();
expectTypeOf(z.hash("sha384", { enc: "base64url" as const })).toEqualTypeOf<
z.ZodMiniCustomStringFormat<"sha384_base64url">
>();
});