@ordao/zod-utils
Version:
Helper utilities for working with zod
201 lines (200 loc) • 6.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.primitiveTypeNames = void 0;
exports.strTypeLength = strTypeLength;
exports.strTypeMinLength = strTypeMinLength;
exports.strTypeMaxLength = strTypeMaxLength;
exports.isPrimitive = isPrimitive;
exports.extractZodDescription = extractZodDescription;
exports.zodEffectInnerType = zodEffectInnerType;
exports.zodOptionalInnerType = zodOptionalInnerType;
exports.zodNullableInnerType = zodNullableInnerType;
exports.zodPipelineInnerType = zodPipelineInnerType;
exports.zodDefaultValue = zodDefaultValue;
exports.zodDefaultInnerType = zodDefaultInnerType;
exports.zodLiteralInnerType = zodLiteralInnerType;
exports.zodObjectFields = zodObjectFields;
exports.zodTypeStr = zodTypeStr;
exports.zodArrayElementType = zodArrayElementType;
exports.zodArrayMinLength = zodArrayMinLength;
exports.zodArrayMaxLength = zodArrayMaxLength;
exports.zodStringChecks = zodStringChecks;
exports.overwriteDescription = overwriteDescription;
exports.getTypeInfo = getTypeInfo;
exports.primitiveTypeNames = ['number', 'bigint', 'boolean'];
function strTypeLength(strt) {
const length = strt.checks.find(c => c.kind === 'length');
return length?.value;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function strTypeMinLength(strt) {
const length = strTypeLength(strt);
if (length) {
return length;
}
else {
const min = strt.checks.find(c => c.kind === 'min');
return min?.value;
}
}
function strTypeMaxLength(strt) {
const length = strTypeLength(strt);
if (length) {
return length;
}
else {
const max = strt.checks.find(c => c.kind === 'max');
return max?.value;
}
}
function isPrimitive(typeInfo) {
return exports.primitiveTypeNames.find(tn => tn === typeInfo.typeName) !== undefined;
}
const descriptionRe = /^(?:\s)?([^\n]+)\n{2}((?:\s|\S)*)$/g;
function extractZodDescription(schema) {
const description = schema.description;
const r = {};
if (description !== undefined) {
const titleDescMatch = new RegExp(descriptionRe).exec(description);
if (titleDescMatch) {
r.title = titleDescMatch[1];
const d = titleDescMatch[2].trimStart();
r.description = d.length === 0 ? undefined : d;
}
else {
const d = description.trimStart();
r.description = d.length === 0 ? undefined : d;
}
}
return r;
}
function zodEffectInnerType(effect) {
return effect.innerType();
}
function zodOptionalInnerType(optional) {
return optional.unwrap();
}
function zodNullableInnerType(nullable) {
return nullable.unwrap();
}
function zodPipelineInnerType(pipeline) {
return pipeline._def.out;
}
function zodDefaultValue(schema) {
return schema._def.defaultValue;
}
function zodDefaultInnerType(schema) {
return schema._def.innerType;
}
function zodLiteralInnerType(literal) {
return literal._def.value;
}
function zodObjectFields(schema) {
const r = {};
for (const field in schema.shape) {
const fieldType = schema.shape[field];
r[field] = getTypeInfo(fieldType);
}
return r;
}
function zodTypeStr(type) {
return type._def.typeName;
}
function zodArrayElementType(array) {
return getTypeInfo(array.element);
}
function zodArrayMinLength(array) {
return array._def.minLength === null ? undefined : array._def.minLength.value;
}
function zodArrayMaxLength(array) {
return array._def.maxLength === null ? undefined : array._def.maxLength.value;
}
function zodStringChecks(zstr) {
return zstr._def.checks;
}
function overwriteDescription(typeInfo, schema) {
const { title, description } = extractZodDescription(schema);
if (title !== undefined || description !== undefined) {
return {
...typeInfo,
title,
description
};
}
else {
return typeInfo;
}
}
function getTypeInfo(schema) {
const typeStr = zodTypeStr(schema);
switch (typeStr) {
case 'ZodDefault': {
const ti = getTypeInfo(zodDefaultInnerType(schema));
ti.defaultValue = zodDefaultValue(schema);
return overwriteDescription(ti, schema);
}
case 'ZodEffects': {
const ti = getTypeInfo(zodEffectInnerType(schema));
return overwriteDescription(ti, schema);
}
case 'ZodOptional': {
const ti = getTypeInfo(zodOptionalInnerType(schema));
ti.optional = true;
return overwriteDescription(ti, schema);
}
case 'ZodNullable': {
const ti = getTypeInfo(zodNullableInnerType(schema));
ti.optional = true;
return overwriteDescription(ti, schema);
}
case 'ZodPipeline': {
const ti = getTypeInfo(zodPipelineInnerType(schema));
return overwriteDescription(ti, schema);
}
case 'ZodLiteral': {
const r = {
typeName: 'literal',
schema,
value: zodLiteralInnerType(schema),
...extractZodDescription(schema)
};
}
case 'ZodObject': {
const r = {
typeName: 'object',
schema,
fields: zodObjectFields(schema),
...extractZodDescription(schema)
};
return r;
}
case 'ZodArray': {
const r = {
typeName: 'array',
schema,
elementType: zodArrayElementType(schema),
min: zodArrayMinLength(schema),
max: zodArrayMaxLength(schema),
...extractZodDescription(schema)
};
return r;
}
case 'ZodNumber':
return { typeName: 'number', schema, ...extractZodDescription(schema) };
case 'ZodBigInt':
return { typeName: 'bigint', schema, ...extractZodDescription(schema) };
case 'ZodString': {
const r = {
typeName: 'string',
schema,
checks: zodStringChecks(schema),
...extractZodDescription(schema)
};
return r;
}
case 'ZodBoolean':
return { typeName: 'boolean', schema, ...extractZodDescription(schema) };
default:
throw new Error(`Unknown type: ${typeStr}`);
}
}