@mastra/core
Version:
150 lines (149 loc) • 4.95 kB
JavaScript
//#region src/utils/zod-utils.ts
/**
* Checks if a value is a Zod type
* @param value - The value to check
* @returns True if the value is a Zod type, false otherwise
*/
function isZodType(value) {
return typeof value === "object" && value !== null && "_def" in value && "parse" in value && typeof value.parse === "function" && "safeParse" in value && typeof value.safeParse === "function";
}
/**
* Get the Zod typeName from a schema, compatible with both Zod 3 and Zod 4.
* Uses string-based typeName instead of instanceof to avoid dual-package hazard
* where multiple Zod instances can cause instanceof checks to fail.
*
* Zod 3 uses `_def.typeName` with values like "ZodString", "ZodOptional", etc.
* Zod 4 uses `_def.type` with lowercase values like "string", "optional", etc.
*
* This function normalizes to Zod 3 format (e.g., "ZodString") for compatibility.
*
* @param schema - The Zod schema to get the type name from
* @returns The Zod type name string (e.g., "ZodString", "ZodOptional") or undefined
*/
function getZodTypeName(schema) {
const schemaAny = schema;
if (schemaAny._def?.typeName) return schemaAny._def.typeName;
const zod4Type = schemaAny._def?.type;
if (typeof zod4Type === "string" && zod4Type) return "Zod" + zod4Type.charAt(0).toUpperCase() + zod4Type.slice(1);
}
/**
* Check if a value is a ZodArray type
* @param value - The value to check (can be any type)
* @returns True if the value is a ZodArray
*/
function isZodArray(value) {
if (!isZodType(value)) return false;
return getZodTypeName(value) === "ZodArray";
}
/**
* Check if a value is a ZodObject type
* @param value - The value to check (can be any type)
* @returns True if the value is a ZodObject
*/
function isZodObject(value) {
if (!isZodType(value)) return false;
return getZodTypeName(value) === "ZodObject";
}
/**
* Add fields to a ZodObject, compatible with both Zod 3 and Zod 4.
*
* Zod 4's `.extend()` throws ("Cannot overwrite keys on object schemas containing
* refinements. Use `.safeExtend()` instead.") when overwriting a key on a schema that
* carries a `.refine()`/`.superRefine()` check. `.safeExtend()` is the v4
* escape hatch and keeps the refinement; Zod 3 has neither the restriction nor
* `.safeExtend()`, so we fall back to `.extend()` there.
*
* @param schema - The ZodObject to extend
* @param shape - The fields to add
* @returns The extended ZodObject
*/
function safeExtendZodObject(schema, shape) {
return (schema.safeExtend ?? schema.extend).call(schema, shape);
}
/**
* Get the def object from a Zod schema, compatible with both Zod 3 and Zod 4.
* @param schema - The Zod schema
* @returns The def object
*/
function getZodDef(schema) {
const schemaAny = schema;
return schemaAny._zod?.def ?? schemaAny._def;
}
/**
* Get the inner type from a wrapper schema (nullable, optional, default, effects, branded).
* Compatible with both Zod 3 and Zod 4.
*
* @param schema - The wrapper Zod schema
* @param typeName - The Zod type name of the wrapper (e.g., "ZodOptional")
* @returns The inner schema, or undefined if not found
*/
function getZodInnerType(schema, typeName) {
const schemaAny = schema;
if (typeName === "ZodNullable" || typeName === "ZodOptional" || typeName === "ZodDefault") return schemaAny._zod?.def?.innerType ?? schemaAny._def?.innerType;
if (typeName === "ZodEffects") return schemaAny._zod?.def?.schema ?? schemaAny._def?.schema;
if (typeName === "ZodBranded") return schemaAny._zod?.def?.type ?? schemaAny._def?.type;
}
/**
* Unwraps Zod wrapper types (optional, nullable, default, effects, branded)
* to find the base schema type. Compatible with both Zod 3 and Zod 4.
*
* For example, `z.array(z.string()).nullish().default([])` unwraps to `z.array(z.string())`.
*
* @param schema - The Zod schema to unwrap
* @returns The innermost base schema
*/
function unwrapZodType(schema) {
let current = schema;
while (true) {
const typeName = getZodTypeName(current);
if (!typeName) break;
const inner = getZodInnerType(current, typeName);
if (!inner) break;
current = inner;
}
return current;
}
//#endregion
Object.defineProperty(exports, "getZodDef", {
enumerable: true,
get: function() {
return getZodDef;
}
});
Object.defineProperty(exports, "getZodInnerType", {
enumerable: true,
get: function() {
return getZodInnerType;
}
});
Object.defineProperty(exports, "getZodTypeName", {
enumerable: true,
get: function() {
return getZodTypeName;
}
});
Object.defineProperty(exports, "isZodArray", {
enumerable: true,
get: function() {
return isZodArray;
}
});
Object.defineProperty(exports, "isZodObject", {
enumerable: true,
get: function() {
return isZodObject;
}
});
Object.defineProperty(exports, "safeExtendZodObject", {
enumerable: true,
get: function() {
return safeExtendZodObject;
}
});
Object.defineProperty(exports, "unwrapZodType", {
enumerable: true,
get: function() {
return unwrapZodType;
}
});
//# sourceMappingURL=zod-utils-BAGXGqPm.cjs.map