@moostjs/zod
Version:
552 lines (545 loc) • 21.2 kB
JavaScript
;
//#region rolldown:runtime
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
const zod = __toESM(require("zod"));
const moost = __toESM(require("moost"));
//#region packages/zod/src/primitives.ts
const primitivesConstructorMap = new WeakMap();
primitivesConstructorMap.set(String, (opts) => zod.z.string(opts));
primitivesConstructorMap.set(Number, (opts) => zod.z.number(opts));
primitivesConstructorMap.set(Boolean, (opts) => zod.z.boolean(opts));
primitivesConstructorMap.set(Array, (opts) => zod.z.array(zod.z.unknown(), opts));
primitivesConstructorMap.set(Date, (opts) => zod.z.array(zod.z.date(), opts));
primitivesConstructorMap.set(Object, (opts) => zod.z.any(opts));
primitivesConstructorMap.set(Set, (opts) => zod.z.any(opts));
primitivesConstructorMap.set(Map, (opts) => zod.z.any(opts));
primitivesConstructorMap.set(Promise, (opts) => zod.z.any(opts));
primitivesConstructorMap.set(Function, (opts) => zod.z.any(opts));
const primitivesMap = new Map();
primitivesMap.set("undefined", (opts) => zod.z.undefined(opts));
primitivesMap.set("boolean", (opts) => zod.z.boolean(opts));
primitivesMap.set("number", (opts) => zod.z.number(opts));
primitivesMap.set("bigint", (opts) => zod.z.bigint(opts));
primitivesMap.set("string", (opts) => zod.z.string(opts));
primitivesMap.set("symbol", (opts) => zod.z.symbol(opts));
function resolveZodPrimitive(from, opts) {
const zodFactory = primitivesMap.get(from);
if (zodFactory) return zodFactory(opts);
throw new Error(`Could not retrieve ZodType for type "${from}".`);
}
function resolveZodPrimitiveByConstructor(type, opts) {
const factory = primitivesConstructorMap.get(type);
if (factory) return factory(opts);
}
//#endregion
//#region packages/zod/src/zod.mate.ts
function getZodMate() {
return (0, moost.getMoostMate)();
}
//#endregion
//#region packages/zod/src/validate.ts
const mate$1 = getZodMate();
const cachedTypes = new WeakMap();
const cachedPropsTypes = new WeakMap();
async function validate(data, dto, opts, safe, logger) {
if (dto instanceof zod.z.ZodType) return safe === true ? await dto.safeParseAsync(data) : await dto.parseAsync(data);
const zodType = getZodType({ type: dto }, opts, logger);
if (zodType) return await validate(data, zodType, opts, safe);
return safe === true ? {
data,
success: true
} : data;
}
function getZodTypeForProp(origin, target, opts, logger) {
let store = cachedPropsTypes.get(origin.type);
if (!store) {
store = {
props: new Map(),
params: new Map()
};
cachedPropsTypes.set(origin.type, store);
}
if (typeof origin.index === "number") {
const cached = store.params.get(origin.key);
if (cached) {
if (!cached[origin.index]) cached[origin.index] = getZodType(target, opts, logger);
return cached[origin.index];
} else {
const zodType = getZodType(target, opts, logger);
const paramsArray = [];
paramsArray[origin.index] = zodType;
store.params.set(origin.key, paramsArray);
return zodType;
}
} else {
const cached = store.props.get(origin.key);
if (cached) return cached;
else {
const zodType = getZodType(target, opts, logger);
store.props.set(origin.key, zodType);
return zodType;
}
}
}
function getZodType(target, opts, logger) {
const { type, value, additionalMeta } = target;
const typeOfValue = typeof value;
const ownMeta = type && mate$1.read(type) || undefined;
let needToCache = false;
let toWrapIntoArray = false;
const overrideZodType = additionalMeta?.zodType;
if (!overrideZodType) {
const cached = lookupInCache();
if (cached) return processResult(cached);
}
const zodInitialType = resolveInitialType();
return processResult(ownMeta ? applyZodFunctions(zodInitialType, {
description: ownMeta.description,
zodDefault: ownMeta.zodDefault,
zodPreprocess: ownMeta.zodPreprocess,
zodFn: ownMeta.zodFn,
zodClassName: ownMeta.zodClassName,
zodPropName: ownMeta.zodPropName,
zodParamIndex: ownMeta.zodParamIndex
}, logger) : zodInitialType);
function lookupInCache() {
if (type) return cachedTypes.get(type);
}
function resolveInitialType() {
if (overrideZodType) {
const overridenType = typeof overrideZodType === "function" ? overrideZodType(opts) : overrideZodType;
if (type === Array && !(overridenType instanceof zod.z.ZodTuple)) toWrapIntoArray = true;
return overridenType;
}
if (type) {
if ((type === Object || type === Array) && typeOfValue !== "undefined") {
const { zt, isArray } = resolveZodTypeByValue(value, opts);
if (isArray) toWrapIntoArray = true;
return zt;
}
const zodType = resolveZodPrimitiveByConstructor(type, opts);
if (zodType) return zodType;
needToCache = true;
if (ownMeta?.zodType) return typeof ownMeta.zodType === "function" ? ownMeta.zodType(opts) : ownMeta.zodType;
const fakeInstance = new type();
const keys = [...Object.keys(fakeInstance), ...ownMeta?.properties || []];
const shape = {};
for (const key of keys) {
const propMeta = mate$1.read(type, key);
try {
shape[key] = getZodType({
type: propMeta?.type,
value: fakeInstance[key],
additionalMeta: propMeta
}, {
...opts,
coerce: propMeta?.zodCoerce || undefined
}, logger);
} catch (error) {
throw new Error(`Could not create ZodType for class "${type.name}". Type of property "${key}" (${propMeta?.type?.name || ""}) is unknown:\n${error.message}`);
}
}
const obj = zod.z.object(shape);
if (ownMeta?.zodObj === "passthrough") return obj.passthrough();
if (ownMeta?.zodObj === "strip") return obj.strip();
return obj.strict();
} else {
const { zt, isArray } = resolveZodTypeByValue(value, opts);
if (isArray) toWrapIntoArray = true;
return zt;
}
}
function processResult(zt) {
const toReturn = applyZodFunctions(zt, {
optional: additionalMeta?.optional,
description: additionalMeta?.description,
zodDefault: additionalMeta?.zodDefault,
zodPreprocess: additionalMeta?.zodPreprocess,
zodFn: additionalMeta?.zodFn,
wrapIntoArray: additionalMeta?.zodMarkedAsArray ? false : toWrapIntoArray,
zodClassName: additionalMeta?.zodClassName,
zodPropName: additionalMeta?.zodPropName,
zodParamIndex: additionalMeta?.zodParamIndex
}, logger);
if (needToCache && type && !overrideZodType) {
Object.assign(zt, { __type_ref: type });
Object.assign(toReturn, { __type_ref: type });
cachedTypes.set(type, zt);
}
return toReturn;
}
}
function resolveZodTypeByValue(value, opts, logger) {
const type = typeof value;
if (type === "object") {
if (Array.isArray(value)) {
if (value.length > 0) {
const subType = resolveZodTypeByValue(value[0], opts, logger);
return {
isArray: true,
zt: subType.isArray ? subType.zt.array() : subType.zt
};
}
throw new Error("Could not resolve array item type.");
} else if (value === null) return { zt: zod.z.null(opts) };
else if (value instanceof Date) return { zt: zod.z.date(opts) };
}
return { zt: resolveZodPrimitive(typeof value, opts) };
}
function applyZodFunctions(type, toApply, logger) {
if (toApply) {
let newType = type;
if (toApply.zodFn?.length) Array.from(toApply.zodFn).reverse().forEach((zodFn) => {
try {
newType = zodFn.fn(newType);
} catch (error) {
const cl = toApply.zodClassName;
const prop = toApply.zodPropName;
const i = toApply.zodParamIndex;
const arg = typeof i === "number";
const message = `${"\x1B[4m"}@${zodFn.decorator}${"\x1B[24m"} skipped for ${arg ? `${"\x1B[36m"}argument[${i}]${"\x1B[33m"} at ` : ""}${"\x1B[36m"}${cl}${prop ? `.${prop}` : ""}${"\x1B[33m"}, ` + `${"\x1B[4m"}${newType._def.typeName}${"\x1B[24m"} does not support such function.`;
(logger || console).warn(`${"\x1B[33m"}${message} ${"\x1B[37m\x1B[2m"}Runtime error: ${error.message}${"\x1B[0m"}`);
}
});
if (toApply.zodPreprocess) {
let prev = newType;
for (let i = toApply.zodPreprocess.length - 1; i >= 0; i--) {
const fn = toApply.zodPreprocess[i];
newType = zod.z.preprocess(fn, prev);
prev = newType;
}
}
if (toApply.wrapIntoArray) newType = newType.array();
if (toApply.optional && !(newType instanceof zod.z.ZodOptional) && !newType.isOptional()) newType = newType.optional();
if (toApply.description) newType = newType.describe(toApply.description);
if (toApply.zodDefault !== undefined) newType = newType.default(toApply.zodDefault);
return newType;
}
return type;
}
//#endregion
//#region packages/zod/src/zod.decorators.ts
const mate = getZodMate();
function ZodFn(decorator, fn) {
return (target, propertyKey, descriptor) => {
mate.decorate((meta, level, key, index) => {
if (!meta.zodFn) meta.zodFn = [];
if (!meta.zodPropName && ["PARAM", "PROP"].includes(level)) {
meta.zodPropName = key;
if (level === "PARAM") meta.zodParamIndex = index;
}
meta.zodFn.push({
decorator,
fn
});
if (!meta.zodClassName) meta.zodClassName = target.name || target.constructor.name;
return meta;
})(target, propertyKey, descriptor);
};
}
const Validatable = () => mate.decorate("zodValidate", true);
const Strict = () => mate.decorate("zodObj", "strict");
const Passthrough = () => mate.decorate("zodObj", "passthrough");
const Strip = () => mate.decorate("zodObj", "strip");
const Zod = (type) => {
const decorator = mate.decorate("zodType", type);
const getZt = (opts) => typeof type === "function" ? type(opts) : type;
decorator.optional = () => mate.decorate("zodType", (opts) => getZt(opts).optional());
decorator.nullable = () => mate.decorate("zodType", (opts) => getZt(opts).nullable());
decorator.nullish = () => mate.decorate("zodType", (opts) => getZt(opts).nullish());
return decorator;
};
const ZodSkip = () => mate.decorate("zodSkip", true);
const LazyType = (getter, opts) => Zod((_opts) => zod.z.lazy(() => toZodType(getter()), {
...opts,
..._opts
}));
const Coerce = () => mate.decorate("zodCoerce", true);
const Default = (value) => mate.decorate("zodDefault", value);
const IsArray = (types, opts) => {
const decorators = [ZodFn("IsArray", (t) => t.array()), mate.decorate("zodMarkedAsArray", true)];
if (types) if (Array.isArray(types)) {
if (types.length > 1) {
const zodType = zod.z.union(types.map((t) => toZodType(t, opts)));
decorators.push(Zod(zodType));
} else if (types.length === 1) decorators.push(Zod(toZodType(types[0], opts)));
} else decorators.push(Zod(toZodType(types, opts)));
const decorator = mate.apply(...decorators);
decorator.optional = () => {
decorators[0] = ZodFn("IsArray", (t) => t.array().optional());
return mate.apply(...decorators);
};
decorator.nullable = () => {
decorators[0] = ZodFn("IsArray", (t) => t.array().nullable());
return mate.apply(...decorators);
};
decorator.nullish = () => {
decorators[0] = ZodFn("IsArray", (t) => t.array().nullish());
return mate.apply(...decorators);
};
return decorator;
};
const Refine = (...args) => ZodFn("Refine", (t) => t.refine(...args));
const SuperRefine = (...args) => ZodFn("SuperRefine", (t) => t.superRefine(...args));
const Trim = () => ZodFn("Trim", (t) => t.trim());
const Transform = (...args) => ZodFn("Transform", (t) => t.transform(...args));
const OnCatch = (def) => ZodFn("OnCatch", (t) => t.catch(...[def]));
const HasLength = (...args) => ZodFn("HasLength", (t) => t.length(...args));
const Min = (...args) => ZodFn("Min", (t) => t.min(...args));
const Max = (...args) => ZodFn("Max", (t) => t.max(...args));
const DateFrom = (...args) => ZodFn("DateFrom", (t) => t.min(...args));
const DateTo = (...args) => ZodFn("DateTo", (t) => t.max(...args));
const IsNullable = () => ZodFn("IsNullable", (t) => t.nullable());
const IsNullish = () => ZodFn("IsNullish", (t) => t.nullish());
const IsEmail = (...args) => ZodFn("IsEmail", (t) => t.email(...args));
const IsUrl = (...args) => ZodFn("IsUrl", (t) => t.url(...args));
const IsEmoji = (...args) => ZodFn("IsEmoji", (t) => t.emoji(...args));
const IsUuid = (...args) => ZodFn("IsUuid", (t) => t.uuid(...args));
const IsCuid = (...args) => ZodFn("IsCuid", (t) => t.cuid(...args));
const IsCuid2 = (...args) => ZodFn("IsCuid2", (t) => t.cuid2(...args));
const IsUlid = (...args) => ZodFn("IsUlid", (t) => t.ulid(...args));
const IsDatetime = (...args) => ZodFn("IsDatetime", (t) => t.datetime(...args));
const IsIp = (...args) => ZodFn("IsIp", (t) => t.ip(...args));
const MatchesRegex = (...args) => ZodFn("MatchesRegex", (t) => t.regex(...args));
const StartsWith = (...args) => ZodFn("StartsWith", (t) => t.startsWith(...args));
const EndsWith = (...args) => ZodFn("EndsWith", (t) => t.endsWith(...args));
const IsGt = (...args) => ZodFn("IsGt", (t) => t.gt(...args));
const IsGte = (...args) => ZodFn("IsGte", (t) => t.gte(...args));
const IsLt = (...args) => ZodFn("IsLt", (t) => t.lt(...args));
const IsLte = (...args) => ZodFn("IsLte", (t) => t.lte(...args));
const IsInt = (...args) => ZodFn("IsInt", (t) => t.int(...args));
const IsPositive = (...args) => ZodFn("IsPositive", (t) => t.positive(...args));
const IsNonnegative = (...args) => ZodFn("IsNonnegative", (t) => t.nonnegative(...args));
const IsNegative = (...args) => ZodFn("IsNegative", (t) => t.negative(...args));
const IsNonpositive = (...args) => ZodFn("IsNonpositive", (t) => t.nonpositive(...args));
const IsMultipleOf = (...args) => ZodFn("IsMultipleOf", (t) => t.multipleOf(...args));
const IsFinite = (...args) => ZodFn("IsFinite", (t) => t.finite(...args));
const IsSafeNumber = (...args) => ZodFn("IsSafeNumber", (t) => t.safe(...args));
const Includes = (...args) => ZodFn("Includes", (t) => t.includes(...args));
const IsString = (...args) => Zod((opts) => zod.z.string(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsNumber = (...args) => Zod((opts) => zod.z.number(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsBigint = (...args) => Zod((opts) => zod.z.bigint(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsBoolean = (...args) => Zod((opts) => zod.z.boolean(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsDate = (...args) => Zod((opts) => zod.z.date(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsSymbol = (...args) => Zod((opts) => zod.z.symbol(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsUndefined = (...args) => Zod((opts) => zod.z.undefined(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsNull = (...args) => Zod((opts) => zod.z.null(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsVoid = (...args) => Zod((opts) => zod.z.void(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsAny = (...args) => Zod((opts) => zod.z.any(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsUnknown = (...args) => Zod((opts) => zod.z.unknown(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsNever = (...args) => Zod((opts) => zod.z.never(...opts ? [{
...args[0],
...opts
}, ...args.slice(1)] : args));
const IsTuple = (schemas) => Zod(zod.z.tuple(schemas.map((s) => toZodType(s))));
const IsEnum = (...args) => Zod(zod.z.enum(...args));
const IsNativeEnum = (...args) => Zod(zod.z.nativeEnum(...args));
const IsSet = (type) => Zod(zod.z.set(toZodType(type)));
const IsMap = (type, type2) => Zod(zod.z.map(toZodType(type), toZodType(type2)));
const IsLiteral = (...args) => Zod(zod.z.literal(...args));
const IsNaN = (...args) => Zod(zod.z.nan(...args));
const IsRecord = (type, type2) => Zod(zod.z.record(toZodType(type), type2 ? toZodType(type2) : undefined));
const IsUnion = (...types) => Zod(zod.z.union(types.map((t) => toZodType(t))));
const IsDiscriminatedUnion = (discriminator, options) => Zod(zod.z.discriminatedUnion(discriminator, options.map((t) => toZodType(t))));
const IsIntersection = (left, right) => Zod(zod.z.intersection(toZodType(left), toZodType(right)));
const IsPromise = (type) => Zod(zod.z.promise(toZodType(type)));
const Preprocess = (fn) => mate.decorate("zodPreprocess", fn, true);
const ToNumber = () => Preprocess((val) => typeof val === "string" && !!val ? Number(val) : val);
const ToBoolean = (truthful = [
"true",
"True",
"TRUE",
1
], falsy = [
"false",
"False",
"FALSE",
0
]) => Preprocess((val) => {
if (typeof val === "boolean") return val;
if (truthful.includes(val)) return true;
if (falsy.includes(val)) return false;
return val;
});
const IsCustom = (...args) => Zod(zod.z.custom(...args));
const And = (type) => ZodFn("And", (t) => t.and(toZodType(type)));
const Or = (type) => ZodFn("Or", (t) => t.or(toZodType(type)));
function toZodType(type, opts) {
if (type instanceof zod.z.ZodType) return type;
if (typeof type === "string") return resolveZodPrimitive(type);
return getZodType({ type }, opts);
}
//#endregion
//#region packages/zod/src/zod.pipe.ts
const ZodPipeline = (opts) => (0, moost.definePipeFn)(async (value, metas, level) => {
const { targetMeta } = metas;
if (!targetMeta || targetMeta.zodSkip || metas.classMeta?.zodSkip || metas.methodMeta?.zodSkip || metas.paramMeta?.zodSkip) return value;
const validatableMeta = getZodMate().read(targetMeta.type);
if (!targetMeta.zodValidate && !validatableMeta?.zodValidate && ![
String,
Number,
Date,
Boolean,
BigInt
].includes(targetMeta.type)) return value;
const logger = (0, moost.useEventLogger)("@moostjs/zod");
if (targetMeta.zodType || targetMeta.type) {
const zodType = getZodTypeForProp({
type: metas.type,
key: metas.key,
index: metas.index
}, {
type: targetMeta.type,
additionalMeta: targetMeta
}, opts, logger);
const check = await zodType.spa(value);
if (check.success) return check.data;
else {
if (opts?.formatError) throw opts.formatError(check.error, value, metas, level);
throw check.error;
}
}
return value;
}, moost.TPipePriority.VALIDATE);
//#endregion
exports.And = And
exports.Coerce = Coerce
exports.DateFrom = DateFrom
exports.DateTo = DateTo
exports.Default = Default
exports.EndsWith = EndsWith
exports.HasLength = HasLength
exports.Includes = Includes
exports.IsAny = IsAny
exports.IsArray = IsArray
exports.IsBigint = IsBigint
exports.IsBoolean = IsBoolean
exports.IsCuid = IsCuid
exports.IsCuid2 = IsCuid2
exports.IsCustom = IsCustom
exports.IsDate = IsDate
exports.IsDatetime = IsDatetime
exports.IsDiscriminatedUnion = IsDiscriminatedUnion
exports.IsEmail = IsEmail
exports.IsEmoji = IsEmoji
exports.IsEnum = IsEnum
exports.IsFinite = IsFinite
exports.IsGt = IsGt
exports.IsGte = IsGte
exports.IsInt = IsInt
exports.IsIntersection = IsIntersection
exports.IsIp = IsIp
exports.IsLiteral = IsLiteral
exports.IsLt = IsLt
exports.IsLte = IsLte
exports.IsMap = IsMap
exports.IsMultipleOf = IsMultipleOf
exports.IsNaN = IsNaN
exports.IsNativeEnum = IsNativeEnum
exports.IsNegative = IsNegative
exports.IsNever = IsNever
exports.IsNonnegative = IsNonnegative
exports.IsNonpositive = IsNonpositive
exports.IsNull = IsNull
exports.IsNullable = IsNullable
exports.IsNullish = IsNullish
exports.IsNumber = IsNumber
exports.IsPositive = IsPositive
exports.IsPromise = IsPromise
exports.IsRecord = IsRecord
exports.IsSafeNumber = IsSafeNumber
exports.IsSet = IsSet
exports.IsString = IsString
exports.IsSymbol = IsSymbol
exports.IsTuple = IsTuple
exports.IsUlid = IsUlid
exports.IsUndefined = IsUndefined
exports.IsUnion = IsUnion
exports.IsUnknown = IsUnknown
exports.IsUrl = IsUrl
exports.IsUuid = IsUuid
exports.IsVoid = IsVoid
exports.LazyType = LazyType
exports.MatchesRegex = MatchesRegex
exports.Max = Max
exports.Min = Min
exports.OnCatch = OnCatch
exports.Or = Or
exports.Passthrough = Passthrough
exports.Preprocess = Preprocess
exports.Refine = Refine
exports.StartsWith = StartsWith
exports.Strict = Strict
exports.Strip = Strip
exports.SuperRefine = SuperRefine
exports.ToBoolean = ToBoolean
exports.ToNumber = ToNumber
exports.Transform = Transform
exports.Trim = Trim
exports.Validatable = Validatable
exports.Zod = Zod
exports.ZodPipeline = ZodPipeline
exports.ZodSkip = ZodSkip
exports.getZodMate = getZodMate
exports.getZodType = getZodType
exports.getZodTypeForProp = getZodTypeForProp
exports.validate = validate
Object.defineProperty(exports, 'z', {
enumerable: true,
get: function () {
return zod.z;
}
});