zod
Version:
TypeScript-first schema declaration and validation library with static type inference
562 lines (560 loc) • 21.7 kB
JavaScript
"use strict";
// import { $ZodType } from "./schemas.js";
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 });
exports.$ZodCheckOverwrite = exports.$ZodCheckMimeType = exports.$ZodCheckProperties = exports.$ZodCheckProperty = exports.$ZodCheckEndsWith = exports.$ZodCheckStartsWith = exports.$ZodCheckIncludes = exports.$ZodCheckUpperCase = exports.$ZodCheckLowerCase = exports.$ZodCheckRegex = exports.$ZodCheckStringFormat = exports.$ZodCheckLengthEquals = exports.$ZodCheckMinLength = exports.$ZodCheckMaxLength = exports.$ZodCheckSizeEquals = exports.$ZodCheckMinSize = exports.$ZodCheckMaxSize = exports.$ZodCheckBigIntFormat = exports.$ZodCheckNumberFormat = exports.$ZodCheckMultipleOf = exports.$ZodCheckGreaterThan = exports.$ZodCheckLessThan = exports.$ZodCheck = void 0;
const core = __importStar(require("./core.cjs"));
const regexes = __importStar(require("./regexes.cjs"));
const util = __importStar(require("./util.cjs"));
exports.$ZodCheck = core.$constructor("$ZodCheck", (inst, def) => {
var _a;
inst._zod ?? (inst._zod = {});
inst._zod.def = def;
(_a = inst._zod).onattach ?? (_a.onattach = []);
});
/** Default `when` for size-based checks: run only on non-nullish values with a `size`. */
const _whenHasSize = (payload) => {
const val = payload.value;
return !util.nullish(val) && val.size !== undefined;
};
/** Default `when` for length-based checks: run only on non-nullish values with a `length`. */
const _whenHasLength = (payload) => {
const val = payload.value;
return !util.nullish(val) && val.length !== undefined;
};
const numericOriginMap = {
number: "number",
bigint: "bigint",
object: "date",
};
exports.$ZodCheckLessThan = core.$constructor("$ZodCheckLessThan", (inst, def) => {
exports.$ZodCheck.init(inst, def);
const origin = numericOriginMap[typeof def.value];
inst._zod.check = (payload) => {
if (def.inclusive ? payload.value <= def.value : payload.value < def.value) {
return;
}
payload.issues.push({
origin: numericOriginMap[typeof payload.value] ?? origin,
code: "too_big",
maximum: typeof def.value === "object" ? def.value.getTime() : def.value,
input: payload.value,
inclusive: def.inclusive,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckGreaterThan = core.$constructor("$ZodCheckGreaterThan", (inst, def) => {
exports.$ZodCheck.init(inst, def);
const origin = numericOriginMap[typeof def.value];
inst._zod.check = (payload) => {
if (def.inclusive ? payload.value >= def.value : payload.value > def.value) {
return;
}
payload.issues.push({
origin: numericOriginMap[typeof payload.value] ?? origin,
code: "too_small",
minimum: typeof def.value === "object" ? def.value.getTime() : def.value,
input: payload.value,
inclusive: def.inclusive,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckMultipleOf =
/*@__PURE__*/ core.$constructor("$ZodCheckMultipleOf", (inst, def) => {
exports.$ZodCheck.init(inst, def);
inst._zod.check = (payload) => {
if (typeof payload.value !== typeof def.value)
throw new Error("Cannot mix number and bigint in multiple_of check.");
const isMultiple = typeof payload.value === "bigint"
? // `value % 0n` throws, and nothing is a multiple of zero — the number branch already fails this way via NaN
def.value !== BigInt(0) && payload.value % def.value === BigInt(0)
: util.floatSafeRemainder(payload.value, def.value) === 0;
if (isMultiple)
return;
payload.issues.push({
origin: typeof payload.value,
code: "not_multiple_of",
divisor: def.value,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckNumberFormat = core.$constructor("$ZodCheckNumberFormat", (inst, def) => {
exports.$ZodCheck.init(inst, def); // no format checks
def.format = def.format || "float64";
const isInt = def.format?.includes("int");
const origin = isInt ? "int" : "number";
const [minimum, maximum] = util.NUMBER_FORMAT_RANGES[def.format];
inst._zod.check = (payload) => {
const input = payload.value;
if (isInt) {
if (!Number.isInteger(input)) {
// invalid_format issue
// payload.issues.push({
// expected: def.format,
// format: def.format,
// code: "invalid_format",
// input,
// inst,
// });
// invalid_type issue
payload.issues.push({
expected: origin,
format: def.format,
code: "invalid_type",
continue: false,
input,
inst,
});
return;
// not_multiple_of issue
// payload.issues.push({
// code: "not_multiple_of",
// origin: "number",
// input,
// inst,
// divisor: 1,
// });
}
if (!Number.isSafeInteger(input)) {
if (input > 0) {
// too_big
payload.issues.push({
input,
code: "too_big",
maximum: Number.MAX_SAFE_INTEGER,
note: "Integers must be within the safe integer range.",
inst,
origin,
inclusive: true,
continue: !def.abort,
});
}
else {
// too_small
payload.issues.push({
input,
code: "too_small",
minimum: Number.MIN_SAFE_INTEGER,
note: "Integers must be within the safe integer range.",
inst,
origin,
inclusive: true,
continue: !def.abort,
});
}
return;
}
}
if (input < minimum) {
payload.issues.push({
origin: "number",
input,
code: "too_small",
minimum,
inclusive: true,
inst,
continue: !def.abort,
});
}
if (input > maximum) {
payload.issues.push({
origin: "number",
input,
code: "too_big",
maximum,
inclusive: true,
inst,
continue: !def.abort,
});
}
};
});
exports.$ZodCheckBigIntFormat = core.$constructor("$ZodCheckBigIntFormat", (inst, def) => {
exports.$ZodCheck.init(inst, def); // no format checks
const [minimum, maximum] = util.BIGINT_FORMAT_RANGES[def.format];
inst._zod.check = (payload) => {
const input = payload.value;
if (input < minimum) {
payload.issues.push({
origin: "bigint",
input,
code: "too_small",
minimum: minimum,
inclusive: true,
inst,
continue: !def.abort,
});
}
if (input > maximum) {
payload.issues.push({
origin: "bigint",
input,
code: "too_big",
maximum,
inclusive: true,
inst,
continue: !def.abort,
});
}
};
});
exports.$ZodCheckMaxSize = core.$constructor("$ZodCheckMaxSize", (inst, def) => {
var _a;
exports.$ZodCheck.init(inst, def);
(_a = inst._zod.def).when ?? (_a.when = _whenHasSize);
inst._zod.check = (payload) => {
const input = payload.value;
const size = input.size;
if (size <= def.maximum)
return;
payload.issues.push({
origin: util.getSizableOrigin(input),
code: "too_big",
maximum: def.maximum,
inclusive: true,
input,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckMinSize = core.$constructor("$ZodCheckMinSize", (inst, def) => {
var _a;
exports.$ZodCheck.init(inst, def);
(_a = inst._zod.def).when ?? (_a.when = _whenHasSize);
inst._zod.check = (payload) => {
const input = payload.value;
const size = input.size;
if (size >= def.minimum)
return;
payload.issues.push({
origin: util.getSizableOrigin(input),
code: "too_small",
minimum: def.minimum,
inclusive: true,
input,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckSizeEquals = core.$constructor("$ZodCheckSizeEquals", (inst, def) => {
var _a;
exports.$ZodCheck.init(inst, def);
(_a = inst._zod.def).when ?? (_a.when = _whenHasSize);
inst._zod.check = (payload) => {
const input = payload.value;
const size = input.size;
if (size === def.size)
return;
const tooBig = size > def.size;
payload.issues.push({
origin: util.getSizableOrigin(input),
...(tooBig ? { code: "too_big", maximum: def.size } : { code: "too_small", minimum: def.size }),
inclusive: true,
exact: true,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckMaxLength = core.$constructor("$ZodCheckMaxLength", (inst, def) => {
var _a;
exports.$ZodCheck.init(inst, def);
(_a = inst._zod.def).when ?? (_a.when = _whenHasLength);
inst._zod.check = (payload) => {
const input = payload.value;
const units = input.length;
// Strings are measured in Unicode code points, not UTF-16 units. A code point is at most two units, so a string that already fits in units fits in code points; only an overflow has to be counted.
const length = typeof input === "string" && units > def.maximum ? util.codePointLength(input) : units;
if (length <= def.maximum)
return;
const origin = util.getLengthableOrigin(input);
payload.issues.push({
origin,
code: "too_big",
maximum: def.maximum,
inclusive: true,
input,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckMinLength = core.$constructor("$ZodCheckMinLength", (inst, def) => {
var _a;
exports.$ZodCheck.init(inst, def);
(_a = inst._zod.def).when ?? (_a.when = _whenHasLength);
inst._zod.check = (payload) => {
const input = payload.value;
const units = input.length;
// A code point is one or two UTF-16 units, so fewer units than the floor can never reach it and twice the floor always clears it. Only in between is the exact count in doubt.
const length = typeof input === "string" && units >= def.minimum && units < def.minimum * 2
? util.codePointLength(input)
: units;
if (length >= def.minimum)
return;
const origin = util.getLengthableOrigin(input);
payload.issues.push({
origin,
code: "too_small",
minimum: def.minimum,
inclusive: true,
input,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckLengthEquals = core.$constructor("$ZodCheckLengthEquals", (inst, def) => {
var _a;
exports.$ZodCheck.init(inst, def);
(_a = inst._zod.def).when ?? (_a.when = _whenHasLength);
inst._zod.check = (payload) => {
const input = payload.value;
const units = input.length;
// A code point is one or two UTF-16 units, so outside `[length, length * 2]` units the target is missed either way — and missed in the same direction in both measures.
const length = typeof input === "string" && units >= def.length && units <= def.length * 2
? util.codePointLength(input)
: units;
if (length === def.length)
return;
const origin = util.getLengthableOrigin(input);
const tooBig = length > def.length;
payload.issues.push({
origin,
...(tooBig ? { code: "too_big", maximum: def.length } : { code: "too_small", minimum: def.length }),
inclusive: true,
exact: true,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckStringFormat = core.$constructor("$ZodCheckStringFormat", (inst, def) => {
var _a, _b;
exports.$ZodCheck.init(inst, def);
if (def.pattern)
(_a = inst._zod).check ?? (_a.check = (payload) => {
def.pattern.lastIndex = 0;
if (def.pattern.test(payload.value))
return;
payload.issues.push({
origin: "string",
code: "invalid_format",
format: def.format,
input: payload.value,
...(def.pattern ? { pattern: def.pattern.toString() } : {}),
inst,
continue: !def.abort,
});
});
else
(_b = inst._zod).check ?? (_b.check = () => { });
});
exports.$ZodCheckRegex = core.$constructor("$ZodCheckRegex", (inst, def) => {
exports.$ZodCheckStringFormat.init(inst, def);
inst._zod.check = (payload) => {
def.pattern.lastIndex = 0;
if (def.pattern.test(payload.value))
return;
payload.issues.push({
origin: "string",
code: "invalid_format",
format: "regex",
input: payload.value,
pattern: def.pattern.toString(),
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckLowerCase = core.$constructor("$ZodCheckLowerCase", (inst, def) => {
def.pattern ?? (def.pattern = regexes.lowercase);
exports.$ZodCheckStringFormat.init(inst, def);
});
exports.$ZodCheckUpperCase = core.$constructor("$ZodCheckUpperCase", (inst, def) => {
def.pattern ?? (def.pattern = regexes.uppercase);
exports.$ZodCheckStringFormat.init(inst, def);
});
exports.$ZodCheckIncludes = core.$constructor("$ZodCheckIncludes", (inst, def) => {
exports.$ZodCheck.init(inst, def);
const escapedRegex = util.escapeRegex(def.includes);
// `String.prototype.includes(sub, position)` matches `sub` at `position`
// OR LATER, so the pattern must allow at least `position` leading chars
// (`{N,}`), not exactly `position` chars (`{N}`).
const pattern = new RegExp(typeof def.position === "number" ? `^.{${def.position},}${escapedRegex}` : escapedRegex);
def.pattern = pattern;
inst._zod.check = (payload) => {
if (payload.value.includes(def.includes, def.position))
return;
payload.issues.push({
origin: "string",
code: "invalid_format",
format: "includes",
includes: def.includes,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckStartsWith = core.$constructor("$ZodCheckStartsWith", (inst, def) => {
exports.$ZodCheck.init(inst, def);
const pattern = new RegExp(`^${util.escapeRegex(def.prefix)}.*`);
def.pattern ?? (def.pattern = pattern);
inst._zod.check = (payload) => {
if (payload.value.startsWith(def.prefix))
return;
payload.issues.push({
origin: "string",
code: "invalid_format",
format: "starts_with",
prefix: def.prefix,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckEndsWith = core.$constructor("$ZodCheckEndsWith", (inst, def) => {
exports.$ZodCheck.init(inst, def);
const pattern = new RegExp(`.*${util.escapeRegex(def.suffix)}$`);
def.pattern ?? (def.pattern = pattern);
inst._zod.check = (payload) => {
if (payload.value.endsWith(def.suffix))
return;
payload.issues.push({
origin: "string",
code: "invalid_format",
format: "ends_with",
suffix: def.suffix,
input: payload.value,
inst,
continue: !def.abort,
});
};
});
///////////////////////////////////
///// $ZodCheckProperty /////
///////////////////////////////////
function handleCheckPropertyResult(result, payload, property) {
if (result.issues.length) {
payload.issues.push(...util.prefixIssues(property, result.issues));
}
}
exports.$ZodCheckProperty = core.$constructor("$ZodCheckProperty", (inst, def) => {
exports.$ZodCheck.init(inst, def);
inst._zod.check = (payload) => {
const result = def.schema._zod.run({
value: payload.value[def.property],
issues: [],
}, {});
if (result instanceof Promise) {
return result.then((result) => handleCheckPropertyResult(result, payload, def.property));
}
handleCheckPropertyResult(result, payload, def.property);
return;
};
});
exports.$ZodCheckProperties = core.$constructor("$ZodCheckProperties", (inst, def) => {
exports.$ZodCheck.init(inst, def);
util.hide(inst, Symbol.iterator, function* () {
yield inst;
});
// key and schema snapshotted together: reading one live and the other cached lets a later mutation of the caller's shape object pair a stale key with a missing schema
let entries;
inst._zod.check = (payload) => {
// the base schema already typed the value, so only a nullish one is rejected here: the properties read on a primitive too, matching z.property() on a string's length
if (payload.value == null) {
payload.issues.push({ expected: "object", code: "invalid_type", input: payload.value, inst });
return undefined;
}
entries ?? (entries = Reflect.ownKeys(def.shape).map((key) => [key, def.shape[key]]));
const input = payload.value;
let proms;
for (const [key, schema] of entries) {
const result = schema._zod.run({ value: input[key], issues: [] }, {});
if (result instanceof Promise) {
proms ?? (proms = []);
proms.push(result.then((result) => handleCheckPropertyResult(result, payload, key)));
}
else {
handleCheckPropertyResult(result, payload, key);
}
}
if (proms)
return Promise.all(proms).then(() => undefined);
return undefined;
};
});
exports.$ZodCheckMimeType = core.$constructor("$ZodCheckMimeType", (inst, def) => {
exports.$ZodCheck.init(inst, def);
const mimeSet = new Set(def.mime);
inst._zod.check = (payload) => {
if (mimeSet.has(payload.value.type))
return;
payload.issues.push({
code: "invalid_value",
values: def.mime,
input: payload.value.type,
inst,
continue: !def.abort,
});
};
});
exports.$ZodCheckOverwrite = core.$constructor("$ZodCheckOverwrite", (inst, def) => {
exports.$ZodCheck.init(inst, def);
inst._zod.check = (payload) => {
payload.value = def.tx(payload.value);
};
});
// seal-cjs-exports
(function () {
var keys = Object.getOwnPropertyNames(exports);
for (var i = 0; i < keys.length; i++) {
var desc = Object.getOwnPropertyDescriptor(exports, keys[i]);
if (!desc || !desc.get || !desc.configurable) continue;
var value;
try {
value = desc.get();
} catch (e) {
continue;
}
// a circular require may not have settled this one yet, so leave it live
if (value === undefined) continue;
Object.defineProperty(exports, keys[i], { value: value, writable: false, enumerable: desc.enumerable, configurable: false });
}
Object.freeze(exports);
})();