/** * Zod Internal Access Utilities * * Zod 스키마의 내부 `_def` 속성에 접근하는 로직을 중앙화합니다. * `as any` 캐스팅은 이 파일 내부에만 존재하며, * 외부에는 타입 안전한 API만 노출합니다. */ import type { ZodTypeAny } from "zod"; // ============================================================================ // Internal _def access (as any is confined here) // ============================================================================ interface ZodDef { typeName: string; innerType?: ZodTypeAny; type?: ZodTypeAny; schema?: ZodTypeAny; shape?: () => Record; checks?: ReadonlyArray<{ kind: string; value?: number; inclusive?: boolean; regex?: RegExp }>; values?: readonly unknown[]; options?: readonly ZodTypeAny[]; value?: unknown; defaultValue?: () => unknown; description?: string; } /** * Zod 스키마의 내부 _def 속성을 안전하게 추출합니다. * `_def` is Zod's documented-but-internal introspection field and is not * part of the public `ZodTypeAny` type. A narrow `{ _def: ZodDef }` cast * keeps the escape hatch localised without relying on `any`. */ function getDef(schema: ZodTypeAny): ZodDef { return (schema as unknown as { _def: ZodDef })._def; } // ============================================================================ // Type Name // ============================================================================ /** Zod 스키마의 typeName을 반환합니다. */ export function getZodTypeName(schema: ZodTypeAny): string { return getDef(schema).typeName; } // ============================================================================ // Inner Type Access // ============================================================================ /** * ZodOptional, ZodNullable, ZodDefault 등 래퍼 스키마의 내부 타입을 반환합니다. * `_def.innerType`에 해당합니다. */ export function getZodInnerType(schema: ZodTypeAny): ZodTypeAny | undefined { return getDef(schema).innerType; } /** * ZodArray의 요소 타입을 반환합니다. * `_def.type`에 해당합니다. */ export function getZodArrayElementType(schema: ZodTypeAny): ZodTypeAny | undefined { return getDef(schema).type; } /** * ZodEffects의 내부 스키마를 반환합니다. * `_def.schema`에 해당합니다. */ export function getZodEffectsSchema(schema: ZodTypeAny): ZodTypeAny | undefined { return getDef(schema).schema; } // ============================================================================ // Object Shape // ============================================================================ /** * ZodObject의 shape를 반환합니다. * `_def.shape()`에 해당합니다. */ export function getZodObjectShape(schema: ZodTypeAny): Record | undefined { const def = getDef(schema); return typeof def.shape === "function" ? def.shape() : undefined; } // ============================================================================ // Checks (validation rules) // ============================================================================ interface ZodCheck { kind: string; value?: number; inclusive?: boolean; regex?: RegExp; } /** * ZodString, ZodNumber 등의 validation checks를 반환합니다. * `_def.checks`에 해당합니다. */ export function getZodChecks(schema: ZodTypeAny): readonly ZodCheck[] { return getDef(schema).checks ?? []; } // ============================================================================ // Enum / Literal / Union // ============================================================================ /** ZodEnum의 values를 반환합니다. */ export function getZodEnumValues(schema: ZodTypeAny): readonly unknown[] | undefined { return getDef(schema).values; } /** ZodUnion의 options를 반환합니다. */ export function getZodUnionOptions(schema: ZodTypeAny): readonly ZodTypeAny[] | undefined { return getDef(schema).options; } /** ZodLiteral의 value를 반환합니다. */ export function getZodLiteralValue(schema: ZodTypeAny): unknown { return getDef(schema).value; } // ============================================================================ // Default Value // ============================================================================ /** * ZodDefault의 기본값을 반환합니다. * `_def.defaultValue()`에 해당합니다. */ export function getZodDefaultValue(schema: ZodTypeAny): unknown { const fn = getDef(schema).defaultValue; return typeof fn === "function" ? fn() : undefined; } // ============================================================================ // Type Predicates // ============================================================================ /** 스키마가 ZodOptional인지 확인합니다. */ export function isZodOptional(schema: ZodTypeAny): boolean { return getZodTypeName(schema) === "ZodOptional"; } /** 스키마가 ZodDefault인지 확인합니다. */ export function isZodDefault(schema: ZodTypeAny): boolean { return getZodTypeName(schema) === "ZodDefault"; } /** 필드가 required인지 확인합니다 (Optional/Default가 아닌 경우). */ export function isZodRequired(schema: ZodTypeAny): boolean { const typeName = getZodTypeName(schema); return typeName !== "ZodOptional" && typeName !== "ZodDefault"; }