zod
Version:
TypeScript-first schema declaration and validation library with static type inference
261 lines (260 loc) • 10.2 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const z = __importStar(require("zod/v4"));
(0, vitest_1.test)("enum from string array", () => {
const MyEnum = z.enum(["Red", "Green", "Blue"]);
(0, vitest_1.expect)(MyEnum.enum.Red).toEqual("Red");
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
});
(0, vitest_1.test)("enum from const object", () => {
const Fruits = {
Apple: "apple",
Banana: "banana",
};
const fruitEnum = z.nativeEnum(Fruits);
fruitEnum.parse("apple");
fruitEnum.parse("banana");
fruitEnum.parse(Fruits.Apple);
fruitEnum.parse(Fruits.Banana);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
});
(0, vitest_1.test)("enum from native enum", () => {
let Fruits;
(function (Fruits) {
Fruits["Apple"] = "apple";
Fruits["Banana"] = "banana";
Fruits[Fruits["Orange"] = 3] = "Orange";
})(Fruits || (Fruits = {}));
// @ts-ignore
const fruitEnum = z.nativeEnum(Fruits);
fruitEnum.parse("apple");
fruitEnum.parse("banana");
fruitEnum.parse(Fruits.Apple);
fruitEnum.parse(Fruits.Banana);
(0, vitest_1.expect)(fruitEnum.safeParse("Apple").success).toEqual(false);
(0, vitest_1.expect)(fruitEnum.safeParse("Cantaloupe").success).toEqual(false);
(0, vitest_1.expectTypeOf)().toMatchTypeOf();
(0, vitest_1.expectTypeOf)().toMatchTypeOf();
});
(0, vitest_1.test)("enum from native enum with numeric keys", () => {
const FruitValues = {
Apple: 10,
Banana: 20,
// @ts-ignore
};
const fruitEnum = z.nativeEnum(FruitValues);
fruitEnum.parse(10);
fruitEnum.parse(20);
fruitEnum.parse(FruitValues.Apple);
fruitEnum.parse(FruitValues.Banana);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
});
(0, vitest_1.test)("issue metadata", () => {
const schema = z.enum(["Red", "Green", "Blue"]);
const result = schema.safeParse("Yellow");
(0, vitest_1.expect)(result.error.issues[0]).toMatchInlineSnapshot(`
{
"code": "invalid_value",
"message": "Invalid option: expected one of "Red"|"Green"|"Blue"",
"path": [],
"values": [
"Red",
"Green",
"Blue",
],
}
`);
});
(0, vitest_1.test)("enum from non-const inputs", () => {
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"];
const FoodEnum = z.enum(foods);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
(0, vitest_1.expect)(FoodEnum.safeParse("Pasta").success).toEqual(true);
(0, vitest_1.expect)(FoodEnum.safeParse("Cucumbers").success).toEqual(false);
});
(0, vitest_1.test)("get options", () => {
(0, vitest_1.expect)(z.enum(["tuna", "trout"]).options).toEqual(["tuna", "trout"]);
});
(0, vitest_1.test)("readonly enum", () => {
const HTTP_SUCCESS = ["200", "201"];
const arg = z.enum(HTTP_SUCCESS);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
arg.parse("201");
(0, vitest_1.expect)(() => arg.parse("202")).toThrow();
});
(0, vitest_1.test)("error map", () => {
const result = z
.enum(["test"], { error: (iss) => (iss.input === undefined ? "REQUIRED" : undefined) })
.safeParse(undefined);
(0, vitest_1.expect)(result.success).toEqual(false);
if (!result.success) {
(0, vitest_1.expect)(result.error.issues[0].message).toEqual("REQUIRED");
}
});
(0, vitest_1.test)("type signatures", () => {
const a = z.enum(["a", "b", "c"]);
const b = z.enum(a.options);
(0, vitest_1.expectTypeOf)(a).toEqualTypeOf(b);
const c = z.enum({ a: 1, b: 2 });
(0, vitest_1.expectTypeOf)(c.enum).toEqualTypeOf();
let Fruit;
(function (Fruit) {
Fruit["Apple"] = "apple";
Fruit["Banana"] = "banana";
Fruit["Orange"] = "orange";
})(Fruit || (Fruit = {}));
const d = z.enum(Fruit);
(0, vitest_1.expectTypeOf)(d.enum).toEqualTypeOf(Fruit);
const e = z.enum({ a: 1, b: 2 });
(0, vitest_1.expectTypeOf)(e.enum).toEqualTypeOf();
});
(0, vitest_1.test)("extract", () => {
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"];
const FoodEnum = z.enum(foods);
const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]);
(0, vitest_1.expect)(ItalianEnum.safeParse("Pasta").success).toEqual(true);
(0, vitest_1.expect)(ItalianEnum.safeParse("Tacos").success).toEqual(false);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
});
(0, vitest_1.test)("exclude", () => {
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"];
const FoodEnum = z.enum(foods);
const UnhealthyEnum = FoodEnum.exclude(["Salad"]);
(0, vitest_1.expect)(UnhealthyEnum.safeParse("Pasta").success).toEqual(true);
(0, vitest_1.expect)(UnhealthyEnum.safeParse("Salad").success).toEqual(false);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
const EmptyFoodEnum = FoodEnum.exclude(foods);
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
(0, vitest_1.expectTypeOf)().toEqualTypeOf();
});
(0, vitest_1.test)("error map inheritance", () => {
const foods = ["Pasta", "Pizza", "Tacos", "Burgers", "Salad"];
const FoodEnum = z.enum(foods, { error: () => "This is not food!" });
const ItalianEnum = FoodEnum.extract(["Pasta", "Pizza"]);
const foodsError = FoodEnum.safeParse("Cucumbers");
const italianError = ItalianEnum.safeParse("Tacos");
(0, vitest_1.expect)(foodsError.error.issues[0].message).toEqual(italianError.error.issues[0].message);
const UnhealthyEnum = FoodEnum.exclude(["Salad"], {
error: () => ({ message: "This is not healthy food!" }),
});
const unhealthyError = UnhealthyEnum.safeParse("Salad");
if (!unhealthyError.success) {
(0, vitest_1.expect)(unhealthyError.error.issues[0].message).toEqual("This is not healthy food!");
}
});
(0, vitest_1.test)("readonly in ZodEnumDef", () => {
});
(0, vitest_1.test)("enum error message, invalid enum elementstring", () => {
const result = z.enum(["Tuna", "Trout"]).safeParse("Salmon");
(0, vitest_1.expect)(result.success).toEqual(false);
(0, vitest_1.expect)(result.error.issues.length).toEqual(1);
(0, vitest_1.expect)(result.error).toMatchInlineSnapshot(`
[ZodError: [
{
"code": "invalid_value",
"values": [
"Tuna",
"Trout"
],
"path": [],
"message": "Invalid option: expected one of \\"Tuna\\"|\\"Trout\\""
}
]]
`);
});
(0, vitest_1.test)("enum error message, invalid type", () => {
const result = z.enum(["Tuna", "Trout"]).safeParse(12);
(0, vitest_1.expect)(result.success).toEqual(false);
(0, vitest_1.expect)(result.error.issues.length).toEqual(1);
// expect(result.error!.issues[0].message).toEqual('Invalid input: expected one of "Tuna"|"Trout"');
(0, vitest_1.expect)(result.error).toMatchInlineSnapshot(`
[ZodError: [
{
"code": "invalid_value",
"values": [
"Tuna",
"Trout"
],
"path": [],
"message": "Invalid option: expected one of \\"Tuna\\"|\\"Trout\\""
}
]]
`);
});
(0, vitest_1.test)("nativeEnum default error message", () => {
let Fish;
(function (Fish) {
Fish["Tuna"] = "Tuna";
Fish["Trout"] = "Trout";
})(Fish || (Fish = {}));
const result = z.nativeEnum(Fish).safeParse("Salmon");
(0, vitest_1.expect)(result.success).toEqual(false);
(0, vitest_1.expect)(result.error.issues.length).toEqual(1);
// expect(result.error!.issues[0].message).toEqual('Invalid input: expected one of "Tuna"|"Trout"');
(0, vitest_1.expect)(result.error).toMatchInlineSnapshot(`
[ZodError: [
{
"code": "invalid_value",
"values": [
"Tuna",
"Trout"
],
"path": [],
"message": "Invalid option: expected one of \\"Tuna\\"|\\"Trout\\""
}
]]
`);
});
(0, vitest_1.test)("enum with message returns the custom error message", () => {
const schema = z.enum(["apple", "banana"], {
message: "the value provided is invalid",
});
const result1 = schema.safeParse("berries");
(0, vitest_1.expect)(result1.success).toEqual(false);
if (!result1.success) {
(0, vitest_1.expect)(result1.error.issues[0].message).toEqual("the value provided is invalid");
}
const result2 = schema.safeParse(undefined);
(0, vitest_1.expect)(result2.success).toEqual(false);
if (!result2.success) {
(0, vitest_1.expect)(result2.error.issues[0].message).toEqual("the value provided is invalid");
}
const result3 = schema.safeParse("banana");
(0, vitest_1.expect)(result3.success).toEqual(true);
const result4 = schema.safeParse(null);
(0, vitest_1.expect)(result4.success).toEqual(false);
if (!result4.success) {
(0, vitest_1.expect)(result4.error.issues[0].message).toEqual("the value provided is invalid");
}
});
(0, vitest_1.test)("enum with diagonal keys", () => {
const schema_02 = z.enum({
A: 1,
B: "A",
});
(0, vitest_1.expect)(schema_02.safeParse("A")).toMatchObject({ success: true });
});