zod-prime
Version:
Enhance Zod with real-world schema utilities for production-grade apps.
204 lines (190 loc) • 8.62 kB
text/typescript
import { ZodTypeAny, z, ZodError, ZodRawShape, ZodObject } from 'zod';
/**
* Type-level utility: Recursively makes all fields in a type optional.
*/
type DeepPartial<T> = T extends object ? T extends Array<infer U> ? Array<DeepPartial<U>> : T extends Map<infer MK, infer MV> ? Map<MK, DeepPartial<MV>> : T extends Record<string, any> ? {
[P in keyof T]?: DeepPartial<T[P]>;
} : T : T;
/**
* Recursively makes all fields in a Zod schema optional.
*
* @template T - The Zod schema type.
* @param schema - The Zod schema to make deeply partial.
* @returns A new Zod schema with all fields optional, deeply.
*
* @example
* const schema = z.object({ user: z.object({ name: z.string() }) });
* const partial = deepPartial(schema);
* // All fields are now optional, deeply
*/
declare function deepPartial<T extends ZodTypeAny>(schema: T): z.ZodType<DeepPartial<z.infer<T>>>;
/**
* Type-level utility: Recursively makes all fields in a type required.
*/
type DeepRequired<T> = T extends object ? T extends Array<infer U> ? Array<DeepRequired<U>> : T extends Map<infer MK, infer MV> ? Map<MK, DeepRequired<MV>> : T extends Record<string, any> ? {
[P in keyof T]-?: DeepRequired<T[P]>;
} : T : T;
/**
* Recursively makes all fields in a Zod schema required.
*
* @template T - The Zod schema type.
* @param schema - The Zod schema to make deeply required.
* @returns A new Zod schema with all fields required, deeply.
*
* @example
* const schema = z.object({ user: z.object({ name: z.string().optional() }) });
* const required = deepRequired(schema);
* // All fields are now required, deeply
*/
declare function deepRequired<T extends ZodTypeAny>(schema: T): z.ZodType<DeepRequired<z.infer<T>>>;
/**
* Options for the emailPasswordSchema utility.
* @property minPasswordLength - Minimum password length (default: 8)
* @property requireSpecialChar - Require at least one special character in the password
*/
interface EmailPasswordOptions {
minPasswordLength?: number;
requireSpecialChar?: boolean;
}
/**
* Generates a Zod schema for an email and password object, with flexible password rules.
*
* @param options - Options for password requirements.
* @returns A Zod object schema with `email` and `password` fields.
*
* @example
* const schema = emailPasswordSchema({ minPasswordLength: 10, requireSpecialChar: true });
* schema.parse({ email: 'a@b.com', password: 'abc123!@#' });
*/
declare function emailPasswordSchema(options?: EmailPasswordOptions): z.ZodObject<{
email: z.ZodString;
password: z.ZodString;
}>;
/**
* Creates a type-safe Zod enum from a readonly string array.
*
* @template T - The tuple of string literals.
* @param values - The string values for the enum.
* @returns A Zod enum schema.
*
* @example
* const Color = smartEnum(['red', 'green', 'blue'] as const);
* type ColorType = z.infer<typeof Color>; // 'red' | 'green' | 'blue'
*/
declare function smartEnum<const T extends readonly [string, ...string[]]>(values: T): z.ZodEnum<z.Writeable<T>>;
/**
* Flattens a ZodError into an array of readable error objects.
*
* @param error - The ZodError instance.
* @returns An array of objects with `path` and `message` for each error.
*
* @example
* try { schema.parse(data); } catch (e) { const flat = flattenErrors(e); }
*/
declare function flattenErrors(error: ZodError): Array<{
path: string;
message: string;
}>;
/**
* Adds cross-field validation to a Zod object schema.
*
* @template T - The Zod object shape.
* @param schema - The Zod object schema to refine.
* @param refineFn - A function that receives the parsed object and returns true if valid.
* @param message - The error message to show if validation fails.
* @returns The refined Zod object schema.
*
* @example
* const schema = refineObject(
* z.object({ password: z.string(), confirm: z.string() }),
* data => data.password === data.confirm,
* 'Passwords must match'
* );
*/
declare function refineObject<T extends ZodRawShape>(schema: ZodObject<T>, refineFn: (data: z.infer<typeof schema>) => boolean, message: string): z.ZodEffects<z.ZodObject<T, z.UnknownKeysParam, z.ZodTypeAny, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_1 ? { [k in keyof T_1]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any>[k]; } : never, z.baseObjectInputType<T> extends infer T_2 ? { [k_1 in keyof T_2]: z.baseObjectInputType<T>[k_1]; } : never>, z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any> extends infer T_3 ? { [k in keyof T_3]: z.objectUtil.addQuestionMarks<z.baseObjectOutputType<T>, any>[k]; } : never, z.baseObjectInputType<T> extends infer T_4 ? { [k_1 in keyof T_4]: z.baseObjectInputType<T>[k_1]; } : never>;
/**
* Type-level utility: Recursively omits keys from a type.
*/
type DeepOmit<T, K extends string> = T extends object ? T extends Array<infer U> ? Array<DeepOmit<U, K>> : T extends Map<infer MK, infer MV> ? Map<MK, DeepOmit<MV, K>> : T extends Record<string, any> ? {
[P in Exclude<keyof T, K>]: DeepOmit<T[P], K>;
} : T : T;
/**
* Recursively omits keys from a Zod schema, deeply.
*
* @template T - The Zod schema type.
* @template K - The keys to omit (string union).
* @param schema - The Zod schema to omit keys from.
* @param keys - The keys to omit (as a string array).
* @returns A new Zod schema with the specified keys omitted, deeply.
*
* @example
* const schema = z.object({ a: z.string(), b: z.object({ c: z.number() }) });
* const omitted = deepOmit(schema, ['b']);
*/
declare function deepOmit<T extends ZodTypeAny, K extends string>(schema: T, keys: readonly K[]): z.ZodType<DeepOmit<z.infer<T>, K>>;
/**
* Type-level utility: Recursively picks only specified keys from a type.
*/
type DeepPick<T, K extends string> = T extends object ? T extends Array<infer U> ? Array<DeepPick<U, K>> : T extends Map<infer MK, infer MV> ? Map<MK, DeepPick<MV, K>> : T extends Record<string, any> ? {
[P in Extract<keyof T, K>]: DeepPick<T[P], K>;
} : T : T;
/**
* Recursively picks only specified keys from a Zod schema, deeply.
*
* @template T - The Zod schema type.
* @template K - The keys to pick (string union).
* @param schema - The Zod schema to pick keys from.
* @param keys - The keys to pick (as a string array).
* @returns A new Zod schema with only the specified keys, deeply.
*
* @example
* const schema = z.object({ a: z.string(), b: z.object({ c: z.number() }) });
* const picked = deepPick(schema, ['a', 'c']);
*/
declare function deepPick<T extends ZodTypeAny, K extends string>(schema: T, keys: readonly K[]): z.ZodType<DeepPick<z.infer<T>, K>>;
/**
* Deeply merges two Zod object schemas into one.
*
* @template A - The first Zod object shape.
* @template B - The second Zod object shape.
* @param a - The first Zod object schema.
* @param b - The second Zod object schema.
* @returns A new Zod object schema with merged shapes.
*
* @example
* const a = z.object({ foo: z.string() });
* const b = z.object({ bar: z.number() });
* const merged = mergeSchemas(a, b); // { foo: string, bar: number }
*/
declare function mergeSchemas<A extends ZodRawShape, B extends ZodRawShape>(a: ZodObject<A>, b: ZodObject<B>): z.ZodObject<A & B>;
type zodInferType<T extends z.ZodTypeAny> = z.infer<T>;
/**
* Sets a default value for a Zod schema.
*
* @template T - The Zod schema type.
* @param schema - The Zod schema to set a default for.
* @param defaultValue - The default value to use.
* @returns The Zod schema with a default value.
*
* @example
* const schema = zodDefault(z.string(), 'hello');
* schema.parse(undefined); // 'hello'
*/
declare function zodDefault<T extends ZodTypeAny>(schema: T, defaultValue: z.infer<T>): T;
/**
* Converts a Zod schema to a minimal JSON Schema representation.
*
* @param schema - The Zod schema to convert.
* @returns A JSON Schema object.
*
* @remarks
* Only handles ZodObject, ZodString, ZodNumber, ZodBoolean, ZodArray, ZodOptional, ZodNullable.
* For production, use the `zod-to-json-schema` package for full support.
*
* @example
* const schema = z.object({ foo: z.string() });
* const jsonSchema = zodToJsonSchema(schema);
* // { type: 'object', properties: { foo: { type: 'string' } } }
*/
declare function zodToJsonSchema(schema: z.ZodTypeAny): object;
export { type DeepOmit, type DeepPartial, type DeepPick, type DeepRequired, type EmailPasswordOptions, deepOmit, deepPartial, deepPick, deepRequired, emailPasswordSchema, flattenErrors, mergeSchemas, refineObject, smartEnum, zodDefault, type zodInferType, zodToJsonSchema };