@zod-utils/core 7.0.1 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -0
- package/dist/index.d.mts +37 -10
- package/dist/index.d.ts +37 -10
- package/dist/index.js +64 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +65 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -690,6 +690,32 @@ getFieldChecks(
|
|
|
690
690
|
// [{ check: 'min_length', ... }, { check: 'max_length', ... }]
|
|
691
691
|
```
|
|
692
692
|
|
|
693
|
+
#### Union Types
|
|
694
|
+
|
|
695
|
+
```typescript
|
|
696
|
+
// Collects checks from all union options
|
|
697
|
+
getFieldChecks(z.union([z.string().min(3), z.string().email()]));
|
|
698
|
+
// [{ check: 'min_length', minimum: 3, ... }, { check: 'string_format', format: 'email', ... }]
|
|
699
|
+
|
|
700
|
+
// Works with nullable/optional unions
|
|
701
|
+
getFieldChecks(z.string().min(5).nullable());
|
|
702
|
+
// [{ check: 'min_length', minimum: 5, ... }]
|
|
703
|
+
```
|
|
704
|
+
|
|
705
|
+
#### Format Types (Zod v4)
|
|
706
|
+
|
|
707
|
+
```typescript
|
|
708
|
+
// Format types (ZodURL, ZodEmail, ZodUUID, etc.) are fully supported
|
|
709
|
+
getFieldChecks(z.email());
|
|
710
|
+
// [{ check: 'string_format', format: 'email', ... }]
|
|
711
|
+
|
|
712
|
+
getFieldChecks(z.url());
|
|
713
|
+
// [{ check: 'string_format', format: 'url', ... }]
|
|
714
|
+
|
|
715
|
+
getFieldChecks(z.uuid());
|
|
716
|
+
// [{ check: 'string_format', format: 'uuid', ... }]
|
|
717
|
+
```
|
|
718
|
+
|
|
693
719
|
#### No Constraints
|
|
694
720
|
|
|
695
721
|
```typescript
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
2
|
import { z as z$1, util } from 'zod';
|
|
3
|
-
import { SomeType, $InferUnionInput, $ZodCheckLessThanDef, $ZodCheckGreaterThanDef, $ZodCheckMultipleOfDef, $ZodCheckNumberFormatDef, $
|
|
3
|
+
import { SomeType, $InferUnionInput, $ZodType, $ZodCheckLessThanDef, $ZodCheckGreaterThanDef, $ZodCheckMultipleOfDef, $ZodCheckNumberFormatDef, $ZodCheckMaxSizeDef, $ZodCheckMinSizeDef, $ZodCheckSizeEqualsDef, $ZodCheckMaxLengthDef, $ZodCheckMinLengthDef, $ZodCheckLengthEqualsDef, $ZodCheckStringFormatDef, $ZodCheckRegexDef, $ZodCheckIncludesDef, $ZodCheckStartsWithDef, $ZodCheckEndsWithDef, $ZodCheckMimeTypeDef, $ZodCheckOverwriteDef } from 'zod/v4/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Simplifies complex TypeScript types for better IDE hover tooltips and error messages.
|
|
@@ -650,19 +650,45 @@ type ExtractZodUnionMember<TSchema extends z$1.ZodUnion | z$1.ZodDiscriminatedUn
|
|
|
650
650
|
* @see {@link ExtractZodUnionMember} for the type-level extraction logic
|
|
651
651
|
* @since 0.6.0
|
|
652
652
|
*/
|
|
653
|
-
declare const extractDiscriminatedSchema: <TSchema extends z$1.ZodType, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,
|
|
653
|
+
declare const extractDiscriminatedSchema: <TSchema extends z$1.ZodType, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>, TUnwrapped extends z$1.ZodType = UnwrapZodType<TSchema> extends z$1.ZodType ? UnwrapZodType<TSchema> : TSchema, ReturnType extends TUnwrapped extends z$1.ZodDiscriminatedUnion ? ExtractZodUnionMember<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>, Extract<TDiscriminatorValue, DiscriminatorValue<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>>>> : undefined = TUnwrapped extends z$1.ZodDiscriminatedUnion ? ExtractZodUnionMember<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>, Extract<TDiscriminatorValue, DiscriminatorValue<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>>>> : undefined>({ schema, discriminator, }: SchemaAndDiscriminatorProps<TSchema, TDiscriminatorKey, TDiscriminatorValue>) => ReturnType;
|
|
654
654
|
|
|
655
655
|
type Split<S extends string> = S extends `${infer Head}.${infer Tail}` ? [Head, ...Split<Tail>] : [S];
|
|
656
656
|
type IsNumeric<S extends string> = S extends `${number}` ? true : false;
|
|
657
|
-
type Unwrap<T> = T extends z$1.ZodOptional<infer U> ? Unwrap<U> : T extends z$1.ZodNullable<infer U> ? Unwrap<U> : T extends z$1.ZodDefault<infer U> ? Unwrap<U> : T;
|
|
657
|
+
type Unwrap<T> = T extends z$1.ZodOptional<infer U> ? Unwrap<U> : T extends z$1.ZodNullable<infer U> ? Unwrap<U> : T extends z$1.ZodDefault<infer U> ? Unwrap<U> : T extends z$1.ZodPipe<infer In, z$1.ZodType> ? Unwrap<In> : T;
|
|
658
658
|
type NavigateZod<T, Path extends string[]> = Path extends [
|
|
659
659
|
infer First extends string,
|
|
660
660
|
...infer Rest extends string[]
|
|
661
661
|
] ? Unwrap<T> extends z$1.ZodObject<infer Shape> ? First extends keyof Shape ? Rest extends [] ? Shape[First] : NavigateZod<Shape[First], Rest> : never : Unwrap<T> extends z$1.ZodArray<infer Element> ? IsNumeric<First> extends true ? Rest extends [] ? Element : NavigateZod<Element, Rest> : never : never : T;
|
|
662
662
|
type ExtractZodByPath<Schema, Path extends string> = NavigateZod<Schema, Split<Path>>;
|
|
663
|
+
/**
|
|
664
|
+
* Extract field from a discriminated union variant.
|
|
665
|
+
* First extracts the variant using ExtractZodUnionMember, then navigates through it.
|
|
666
|
+
* @internal
|
|
667
|
+
*/
|
|
668
|
+
type ExtractFromDiscriminatedUnion<TSchema extends z$1.ZodType, TName extends string, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>, TUnwrapped extends z$1.ZodType = UnwrapZodType<TSchema> extends z$1.ZodType ? UnwrapZodType<TSchema> : TSchema, TVariant = TUnwrapped extends z$1.ZodDiscriminatedUnion ? ExtractZodUnionMember<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>, Extract<TDiscriminatorValue, DiscriminatorValue<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>>>> : never> = TVariant extends z$1.ZodType ? ExtractZodByPath<TVariant, TName> : never;
|
|
669
|
+
/**
|
|
670
|
+
* Helper type to determine if field extraction should succeed.
|
|
671
|
+
* Returns true when:
|
|
672
|
+
* 1. For discriminated unions: discriminator is provided (trust the user)
|
|
673
|
+
* 2. For non-unions: the path resolves to a valid type (not never)
|
|
674
|
+
* @internal
|
|
675
|
+
*/
|
|
676
|
+
type CanExtractField<TSchema extends z$1.ZodType, TName extends string, TDiscriminatorKey extends DiscriminatorKey<TSchema>> = IsDiscriminatedUnion<TSchema> extends true ? [TDiscriminatorKey] extends [never] ? false : true : [
|
|
677
|
+
ExtractZodByPath<TSchema, TName>
|
|
678
|
+
] extends [never] ? false : true;
|
|
679
|
+
/**
|
|
680
|
+
* Conditional return type for extractFieldFromSchema.
|
|
681
|
+
* For discriminated unions: extracts variant first, then navigates.
|
|
682
|
+
* For non-unions: navigates directly.
|
|
683
|
+
* @internal
|
|
684
|
+
*/
|
|
685
|
+
type ExtractFieldResult<TSchema extends z$1.ZodType, TName extends string, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey> = DiscriminatorValue<TSchema, TDiscriminatorKey>> = CanExtractField<TSchema, TName, TDiscriminatorKey> extends true ? IsDiscriminatedUnion<TSchema> extends true ? [
|
|
686
|
+
ExtractFromDiscriminatedUnion<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue>
|
|
687
|
+
] extends [never] ? z$1.ZodType : ExtractFromDiscriminatedUnion<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue> & z$1.ZodType : // For non-unions: navigate directly
|
|
688
|
+
ExtractZodByPath<TSchema, TName> & z$1.ZodType : (ExtractZodByPath<TSchema, TName> & z$1.ZodType) | undefined;
|
|
663
689
|
declare function extractFieldFromSchema<TSchema extends z$1.ZodType, TDiscriminatorKey extends DiscriminatorKey<TSchema> = never, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey> = never, TFilterType = unknown, TStrict extends boolean = true, TName extends string = string>(params: FieldSelectorProps<TSchema, TDiscriminatorKey, TDiscriminatorValue, TFilterType, TStrict> & {
|
|
664
690
|
name: TName;
|
|
665
|
-
}):
|
|
691
|
+
}): ExtractFieldResult<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue>;
|
|
666
692
|
/**
|
|
667
693
|
* Extends a Zod field with a transformation while preserving its metadata.
|
|
668
694
|
*
|
|
@@ -710,7 +736,7 @@ type Unwrappable = {
|
|
|
710
736
|
*
|
|
711
737
|
* @since 0.1.0
|
|
712
738
|
*/
|
|
713
|
-
declare function canUnwrap(field: z$1.
|
|
739
|
+
declare function canUnwrap(field: z$1.ZodType | $ZodType): field is (z$1.ZodType | $ZodType) & Unwrappable;
|
|
714
740
|
/**
|
|
715
741
|
* Type guard that checks if a Zod field is a ZodPipe with a ZodType input.
|
|
716
742
|
*
|
|
@@ -719,7 +745,7 @@ declare function canUnwrap(field: z$1.ZodTypeAny): field is z$1.ZodTypeAny & Unw
|
|
|
719
745
|
* @param field - The Zod field to check
|
|
720
746
|
* @returns True if field is a ZodPipe with a ZodType input
|
|
721
747
|
*/
|
|
722
|
-
declare function isPipeWithZodInput(field: z$1.
|
|
748
|
+
declare function isPipeWithZodInput(field: z$1.ZodType | $ZodType): field is z$1.ZodPipe<z$1.ZodType, z$1.ZodTypeAny>;
|
|
723
749
|
/**
|
|
724
750
|
* Attempts to strip nullish types from a union and return the single remaining type.
|
|
725
751
|
*
|
|
@@ -816,7 +842,7 @@ declare function tryStripNullishOnly(field: z$1.ZodTypeAny): z$1.ZodType | false
|
|
|
816
842
|
* @see {@link tryStripNullishOnly} for union nullish stripping logic
|
|
817
843
|
* @since 0.1.0
|
|
818
844
|
*/
|
|
819
|
-
declare const getPrimitiveType: <T extends z$1.ZodType>(field: T) => z$1.
|
|
845
|
+
declare const getPrimitiveType: <T extends z$1.ZodType>(field: T) => z$1.ZodType;
|
|
820
846
|
type StripZodDefault<T> = T extends z$1.ZodDefault<infer Inner> ? StripZodDefault<Inner> : T extends z$1.ZodOptional<infer Inner> ? z$1.ZodOptional<StripZodDefault<Inner>> : T extends z$1.ZodNullable<infer Inner> ? z$1.ZodNullable<StripZodDefault<Inner>> : T;
|
|
821
847
|
/**
|
|
822
848
|
* Removes default values from a Zod field while preserving other wrapper types.
|
|
@@ -948,7 +974,7 @@ declare const requiresValidInput: <T extends z$1.ZodType>(field: T) => boolean;
|
|
|
948
974
|
*
|
|
949
975
|
* @since 0.4.0
|
|
950
976
|
*/
|
|
951
|
-
type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckMultipleOfDef | $ZodCheckNumberFormatDef | $
|
|
977
|
+
type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckMultipleOfDef | $ZodCheckNumberFormatDef | $ZodCheckMaxSizeDef | $ZodCheckMinSizeDef | $ZodCheckSizeEqualsDef | $ZodCheckMaxLengthDef | $ZodCheckMinLengthDef | $ZodCheckLengthEqualsDef | $ZodCheckStringFormatDef | $ZodCheckRegexDef | $ZodCheckIncludesDef | $ZodCheckStartsWithDef | $ZodCheckEndsWithDef | $ZodCheckMimeTypeDef | $ZodCheckOverwriteDef;
|
|
952
978
|
/**
|
|
953
979
|
* Extracts all validation check definitions from a Zod schema field.
|
|
954
980
|
*
|
|
@@ -1024,6 +1050,7 @@ type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckM
|
|
|
1024
1050
|
* @see {@link ZodUnionCheck} for all supported check types
|
|
1025
1051
|
* @since 0.4.0
|
|
1026
1052
|
*/
|
|
1027
|
-
declare function getFieldChecks<T extends z$1.
|
|
1053
|
+
declare function getFieldChecks<T extends z$1.ZodType | $ZodType>(field: T): Array<ZodUnionCheck>;
|
|
1054
|
+
declare function extractCheck(check: z$1.core.$ZodCheck<never>): ZodUnionCheck[];
|
|
1028
1055
|
|
|
1029
|
-
export { type CommonFields, type DiscriminatedInput, type DiscriminatorKey, type DiscriminatorProps, type DiscriminatorValue, type ExtractZodByPath, type FieldSelectorProps, type FileList, type IsDiscriminatedUnion, type NameAndDiscriminatorProps, type NameProps, type PathImpl, type PathInternal, type Paths, type SchemaAndDiscriminatorProps, type SchemaProps, type Simplify, type UnwrapZodType, type ValidPaths, type ZodUnionCheck, canUnwrap, extendWithMeta, extractDefaultValue, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, isPipeWithZodInput, removeDefault, requiresValidInput, tryStripNullishOnly };
|
|
1056
|
+
export { type CommonFields, type DiscriminatedInput, type DiscriminatorKey, type DiscriminatorProps, type DiscriminatorValue, type ExtractZodByPath, type ExtractZodUnionMember, type FieldSelectorProps, type FileList, type IsDiscriminatedUnion, type NameAndDiscriminatorProps, type NameProps, type PathImpl, type PathInternal, type Paths, type SchemaAndDiscriminatorProps, type SchemaProps, type Simplify, type UnwrapZodType, type ValidPaths, type ZodUnionCheck, canUnwrap, extendWithMeta, extractCheck, extractDefaultValue, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, isPipeWithZodInput, removeDefault, requiresValidInput, tryStripNullishOnly };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
2
|
import { z as z$1, util } from 'zod';
|
|
3
|
-
import { SomeType, $InferUnionInput, $ZodCheckLessThanDef, $ZodCheckGreaterThanDef, $ZodCheckMultipleOfDef, $ZodCheckNumberFormatDef, $
|
|
3
|
+
import { SomeType, $InferUnionInput, $ZodType, $ZodCheckLessThanDef, $ZodCheckGreaterThanDef, $ZodCheckMultipleOfDef, $ZodCheckNumberFormatDef, $ZodCheckMaxSizeDef, $ZodCheckMinSizeDef, $ZodCheckSizeEqualsDef, $ZodCheckMaxLengthDef, $ZodCheckMinLengthDef, $ZodCheckLengthEqualsDef, $ZodCheckStringFormatDef, $ZodCheckRegexDef, $ZodCheckIncludesDef, $ZodCheckStartsWithDef, $ZodCheckEndsWithDef, $ZodCheckMimeTypeDef, $ZodCheckOverwriteDef } from 'zod/v4/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Simplifies complex TypeScript types for better IDE hover tooltips and error messages.
|
|
@@ -650,19 +650,45 @@ type ExtractZodUnionMember<TSchema extends z$1.ZodUnion | z$1.ZodDiscriminatedUn
|
|
|
650
650
|
* @see {@link ExtractZodUnionMember} for the type-level extraction logic
|
|
651
651
|
* @since 0.6.0
|
|
652
652
|
*/
|
|
653
|
-
declare const extractDiscriminatedSchema: <TSchema extends z$1.ZodType, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,
|
|
653
|
+
declare const extractDiscriminatedSchema: <TSchema extends z$1.ZodType, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>, TUnwrapped extends z$1.ZodType = UnwrapZodType<TSchema> extends z$1.ZodType ? UnwrapZodType<TSchema> : TSchema, ReturnType extends TUnwrapped extends z$1.ZodDiscriminatedUnion ? ExtractZodUnionMember<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>, Extract<TDiscriminatorValue, DiscriminatorValue<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>>>> : undefined = TUnwrapped extends z$1.ZodDiscriminatedUnion ? ExtractZodUnionMember<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>, Extract<TDiscriminatorValue, DiscriminatorValue<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>>>> : undefined>({ schema, discriminator, }: SchemaAndDiscriminatorProps<TSchema, TDiscriminatorKey, TDiscriminatorValue>) => ReturnType;
|
|
654
654
|
|
|
655
655
|
type Split<S extends string> = S extends `${infer Head}.${infer Tail}` ? [Head, ...Split<Tail>] : [S];
|
|
656
656
|
type IsNumeric<S extends string> = S extends `${number}` ? true : false;
|
|
657
|
-
type Unwrap<T> = T extends z$1.ZodOptional<infer U> ? Unwrap<U> : T extends z$1.ZodNullable<infer U> ? Unwrap<U> : T extends z$1.ZodDefault<infer U> ? Unwrap<U> : T;
|
|
657
|
+
type Unwrap<T> = T extends z$1.ZodOptional<infer U> ? Unwrap<U> : T extends z$1.ZodNullable<infer U> ? Unwrap<U> : T extends z$1.ZodDefault<infer U> ? Unwrap<U> : T extends z$1.ZodPipe<infer In, z$1.ZodType> ? Unwrap<In> : T;
|
|
658
658
|
type NavigateZod<T, Path extends string[]> = Path extends [
|
|
659
659
|
infer First extends string,
|
|
660
660
|
...infer Rest extends string[]
|
|
661
661
|
] ? Unwrap<T> extends z$1.ZodObject<infer Shape> ? First extends keyof Shape ? Rest extends [] ? Shape[First] : NavigateZod<Shape[First], Rest> : never : Unwrap<T> extends z$1.ZodArray<infer Element> ? IsNumeric<First> extends true ? Rest extends [] ? Element : NavigateZod<Element, Rest> : never : never : T;
|
|
662
662
|
type ExtractZodByPath<Schema, Path extends string> = NavigateZod<Schema, Split<Path>>;
|
|
663
|
+
/**
|
|
664
|
+
* Extract field from a discriminated union variant.
|
|
665
|
+
* First extracts the variant using ExtractZodUnionMember, then navigates through it.
|
|
666
|
+
* @internal
|
|
667
|
+
*/
|
|
668
|
+
type ExtractFromDiscriminatedUnion<TSchema extends z$1.ZodType, TName extends string, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>, TUnwrapped extends z$1.ZodType = UnwrapZodType<TSchema> extends z$1.ZodType ? UnwrapZodType<TSchema> : TSchema, TVariant = TUnwrapped extends z$1.ZodDiscriminatedUnion ? ExtractZodUnionMember<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>, Extract<TDiscriminatorValue, DiscriminatorValue<TUnwrapped, Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>>>> : never> = TVariant extends z$1.ZodType ? ExtractZodByPath<TVariant, TName> : never;
|
|
669
|
+
/**
|
|
670
|
+
* Helper type to determine if field extraction should succeed.
|
|
671
|
+
* Returns true when:
|
|
672
|
+
* 1. For discriminated unions: discriminator is provided (trust the user)
|
|
673
|
+
* 2. For non-unions: the path resolves to a valid type (not never)
|
|
674
|
+
* @internal
|
|
675
|
+
*/
|
|
676
|
+
type CanExtractField<TSchema extends z$1.ZodType, TName extends string, TDiscriminatorKey extends DiscriminatorKey<TSchema>> = IsDiscriminatedUnion<TSchema> extends true ? [TDiscriminatorKey] extends [never] ? false : true : [
|
|
677
|
+
ExtractZodByPath<TSchema, TName>
|
|
678
|
+
] extends [never] ? false : true;
|
|
679
|
+
/**
|
|
680
|
+
* Conditional return type for extractFieldFromSchema.
|
|
681
|
+
* For discriminated unions: extracts variant first, then navigates.
|
|
682
|
+
* For non-unions: navigates directly.
|
|
683
|
+
* @internal
|
|
684
|
+
*/
|
|
685
|
+
type ExtractFieldResult<TSchema extends z$1.ZodType, TName extends string, TDiscriminatorKey extends DiscriminatorKey<TSchema>, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey> = DiscriminatorValue<TSchema, TDiscriminatorKey>> = CanExtractField<TSchema, TName, TDiscriminatorKey> extends true ? IsDiscriminatedUnion<TSchema> extends true ? [
|
|
686
|
+
ExtractFromDiscriminatedUnion<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue>
|
|
687
|
+
] extends [never] ? z$1.ZodType : ExtractFromDiscriminatedUnion<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue> & z$1.ZodType : // For non-unions: navigate directly
|
|
688
|
+
ExtractZodByPath<TSchema, TName> & z$1.ZodType : (ExtractZodByPath<TSchema, TName> & z$1.ZodType) | undefined;
|
|
663
689
|
declare function extractFieldFromSchema<TSchema extends z$1.ZodType, TDiscriminatorKey extends DiscriminatorKey<TSchema> = never, TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey> = never, TFilterType = unknown, TStrict extends boolean = true, TName extends string = string>(params: FieldSelectorProps<TSchema, TDiscriminatorKey, TDiscriminatorValue, TFilterType, TStrict> & {
|
|
664
690
|
name: TName;
|
|
665
|
-
}):
|
|
691
|
+
}): ExtractFieldResult<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue>;
|
|
666
692
|
/**
|
|
667
693
|
* Extends a Zod field with a transformation while preserving its metadata.
|
|
668
694
|
*
|
|
@@ -710,7 +736,7 @@ type Unwrappable = {
|
|
|
710
736
|
*
|
|
711
737
|
* @since 0.1.0
|
|
712
738
|
*/
|
|
713
|
-
declare function canUnwrap(field: z$1.
|
|
739
|
+
declare function canUnwrap(field: z$1.ZodType | $ZodType): field is (z$1.ZodType | $ZodType) & Unwrappable;
|
|
714
740
|
/**
|
|
715
741
|
* Type guard that checks if a Zod field is a ZodPipe with a ZodType input.
|
|
716
742
|
*
|
|
@@ -719,7 +745,7 @@ declare function canUnwrap(field: z$1.ZodTypeAny): field is z$1.ZodTypeAny & Unw
|
|
|
719
745
|
* @param field - The Zod field to check
|
|
720
746
|
* @returns True if field is a ZodPipe with a ZodType input
|
|
721
747
|
*/
|
|
722
|
-
declare function isPipeWithZodInput(field: z$1.
|
|
748
|
+
declare function isPipeWithZodInput(field: z$1.ZodType | $ZodType): field is z$1.ZodPipe<z$1.ZodType, z$1.ZodTypeAny>;
|
|
723
749
|
/**
|
|
724
750
|
* Attempts to strip nullish types from a union and return the single remaining type.
|
|
725
751
|
*
|
|
@@ -816,7 +842,7 @@ declare function tryStripNullishOnly(field: z$1.ZodTypeAny): z$1.ZodType | false
|
|
|
816
842
|
* @see {@link tryStripNullishOnly} for union nullish stripping logic
|
|
817
843
|
* @since 0.1.0
|
|
818
844
|
*/
|
|
819
|
-
declare const getPrimitiveType: <T extends z$1.ZodType>(field: T) => z$1.
|
|
845
|
+
declare const getPrimitiveType: <T extends z$1.ZodType>(field: T) => z$1.ZodType;
|
|
820
846
|
type StripZodDefault<T> = T extends z$1.ZodDefault<infer Inner> ? StripZodDefault<Inner> : T extends z$1.ZodOptional<infer Inner> ? z$1.ZodOptional<StripZodDefault<Inner>> : T extends z$1.ZodNullable<infer Inner> ? z$1.ZodNullable<StripZodDefault<Inner>> : T;
|
|
821
847
|
/**
|
|
822
848
|
* Removes default values from a Zod field while preserving other wrapper types.
|
|
@@ -948,7 +974,7 @@ declare const requiresValidInput: <T extends z$1.ZodType>(field: T) => boolean;
|
|
|
948
974
|
*
|
|
949
975
|
* @since 0.4.0
|
|
950
976
|
*/
|
|
951
|
-
type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckMultipleOfDef | $ZodCheckNumberFormatDef | $
|
|
977
|
+
type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckMultipleOfDef | $ZodCheckNumberFormatDef | $ZodCheckMaxSizeDef | $ZodCheckMinSizeDef | $ZodCheckSizeEqualsDef | $ZodCheckMaxLengthDef | $ZodCheckMinLengthDef | $ZodCheckLengthEqualsDef | $ZodCheckStringFormatDef | $ZodCheckRegexDef | $ZodCheckIncludesDef | $ZodCheckStartsWithDef | $ZodCheckEndsWithDef | $ZodCheckMimeTypeDef | $ZodCheckOverwriteDef;
|
|
952
978
|
/**
|
|
953
979
|
* Extracts all validation check definitions from a Zod schema field.
|
|
954
980
|
*
|
|
@@ -1024,6 +1050,7 @@ type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckM
|
|
|
1024
1050
|
* @see {@link ZodUnionCheck} for all supported check types
|
|
1025
1051
|
* @since 0.4.0
|
|
1026
1052
|
*/
|
|
1027
|
-
declare function getFieldChecks<T extends z$1.
|
|
1053
|
+
declare function getFieldChecks<T extends z$1.ZodType | $ZodType>(field: T): Array<ZodUnionCheck>;
|
|
1054
|
+
declare function extractCheck(check: z$1.core.$ZodCheck<never>): ZodUnionCheck[];
|
|
1028
1055
|
|
|
1029
|
-
export { type CommonFields, type DiscriminatedInput, type DiscriminatorKey, type DiscriminatorProps, type DiscriminatorValue, type ExtractZodByPath, type FieldSelectorProps, type FileList, type IsDiscriminatedUnion, type NameAndDiscriminatorProps, type NameProps, type PathImpl, type PathInternal, type Paths, type SchemaAndDiscriminatorProps, type SchemaProps, type Simplify, type UnwrapZodType, type ValidPaths, type ZodUnionCheck, canUnwrap, extendWithMeta, extractDefaultValue, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, isPipeWithZodInput, removeDefault, requiresValidInput, tryStripNullishOnly };
|
|
1056
|
+
export { type CommonFields, type DiscriminatedInput, type DiscriminatorKey, type DiscriminatorProps, type DiscriminatorValue, type ExtractZodByPath, type ExtractZodUnionMember, type FieldSelectorProps, type FileList, type IsDiscriminatedUnion, type NameAndDiscriminatorProps, type NameProps, type PathImpl, type PathInternal, type Paths, type SchemaAndDiscriminatorProps, type SchemaProps, type Simplify, type UnwrapZodType, type ValidPaths, type ZodUnionCheck, canUnwrap, extendWithMeta, extractCheck, extractDefaultValue, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, isPipeWithZodInput, removeDefault, requiresValidInput, tryStripNullishOnly };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var z3 = require('zod');
|
|
4
|
+
var core = require('zod/v4/core');
|
|
4
5
|
|
|
5
6
|
function _interopNamespace(e) {
|
|
6
7
|
if (e && e.__esModule) return e;
|
|
@@ -110,9 +111,65 @@ var requiresValidInput = (field) => {
|
|
|
110
111
|
return !undefinedResult && !nullResult && !emptyStringResult && !emptyArrayResult;
|
|
111
112
|
};
|
|
112
113
|
function getFieldChecks(field) {
|
|
113
|
-
|
|
114
|
+
if (!(field instanceof z3.z.ZodType)) return [];
|
|
114
115
|
const primitiveType = getPrimitiveType(field);
|
|
115
|
-
|
|
116
|
+
if (primitiveType instanceof z3.z.ZodUnion) {
|
|
117
|
+
const allChecks2 = [];
|
|
118
|
+
for (const option of primitiveType.options) {
|
|
119
|
+
const optionChecks = getFieldChecks(option);
|
|
120
|
+
allChecks2.push(...optionChecks);
|
|
121
|
+
}
|
|
122
|
+
return allChecks2;
|
|
123
|
+
}
|
|
124
|
+
const allChecks = [];
|
|
125
|
+
if (primitiveType instanceof z3.ZodStringFormat) {
|
|
126
|
+
const formatCheck = primitiveType.def;
|
|
127
|
+
allChecks.push(formatCheck);
|
|
128
|
+
}
|
|
129
|
+
if (primitiveType.def.checks) {
|
|
130
|
+
for (const check of primitiveType.def.checks) {
|
|
131
|
+
allChecks.push(...extractCheck(check));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return allChecks;
|
|
135
|
+
}
|
|
136
|
+
function extractCheck(check) {
|
|
137
|
+
if (check instanceof core.$ZodCheckLessThan) {
|
|
138
|
+
return [check._zod.def];
|
|
139
|
+
} else if (check instanceof core.$ZodCheckGreaterThan) {
|
|
140
|
+
return [check._zod.def];
|
|
141
|
+
} else if (check instanceof core.$ZodCheckMultipleOf) {
|
|
142
|
+
return [check._zod.def];
|
|
143
|
+
} else if (check instanceof core.$ZodCheckNumberFormat) {
|
|
144
|
+
return [check._zod.def];
|
|
145
|
+
} else if (check instanceof core.$ZodCheckMaxSize) {
|
|
146
|
+
return [check._zod.def];
|
|
147
|
+
} else if (check instanceof core.$ZodCheckMinSize) {
|
|
148
|
+
return [check._zod.def];
|
|
149
|
+
} else if (check instanceof core.$ZodCheckSizeEquals) {
|
|
150
|
+
return [check._zod.def];
|
|
151
|
+
} else if (check instanceof core.$ZodCheckMaxLength) {
|
|
152
|
+
return [check._zod.def];
|
|
153
|
+
} else if (check instanceof core.$ZodCheckMinLength) {
|
|
154
|
+
return [check._zod.def];
|
|
155
|
+
} else if (check instanceof core.$ZodCheckLengthEquals) {
|
|
156
|
+
return [check._zod.def];
|
|
157
|
+
} else if (check instanceof core.$ZodCheckRegex) {
|
|
158
|
+
return [check._zod.def];
|
|
159
|
+
} else if (check instanceof core.$ZodCheckStringFormat) {
|
|
160
|
+
return [check._zod.def];
|
|
161
|
+
} else if (check instanceof core.$ZodCheckOverwrite) {
|
|
162
|
+
return [check._zod.def];
|
|
163
|
+
} else if (check instanceof core.$ZodCheckMimeType) {
|
|
164
|
+
return [check._zod.def];
|
|
165
|
+
} else if (check instanceof core.$ZodCheckIncludes) {
|
|
166
|
+
return [check._zod.def];
|
|
167
|
+
} else if (check instanceof core.$ZodCheckStartsWith) {
|
|
168
|
+
return [check._zod.def];
|
|
169
|
+
} else if (check instanceof core.$ZodCheckEndsWith) {
|
|
170
|
+
return [check._zod.def];
|
|
171
|
+
}
|
|
172
|
+
return [];
|
|
116
173
|
}
|
|
117
174
|
|
|
118
175
|
// src/discriminatedSchema.ts
|
|
@@ -216,10 +273,12 @@ function extractFieldFromSchema(params) {
|
|
|
216
273
|
} else if (newParams.schema instanceof z3.z.ZodObject) {
|
|
217
274
|
currentSchema = newParams.schema;
|
|
218
275
|
}
|
|
219
|
-
if (!currentSchema)
|
|
276
|
+
if (!currentSchema)
|
|
277
|
+
return void 0;
|
|
220
278
|
const segments = String(newParams.name).split(".");
|
|
221
279
|
for (const segment of segments) {
|
|
222
|
-
if (!currentSchema)
|
|
280
|
+
if (!currentSchema)
|
|
281
|
+
return void 0;
|
|
223
282
|
const unwrapped = getPrimitiveType(currentSchema);
|
|
224
283
|
if (unwrapped instanceof z3.z.ZodObject) {
|
|
225
284
|
currentSchema = getShapeField2(unwrapped, segment);
|
|
@@ -246,6 +305,7 @@ function extendWithMeta(field, transform) {
|
|
|
246
305
|
|
|
247
306
|
exports.canUnwrap = canUnwrap;
|
|
248
307
|
exports.extendWithMeta = extendWithMeta;
|
|
308
|
+
exports.extractCheck = extractCheck;
|
|
249
309
|
exports.extractDefaultValue = extractDefaultValue;
|
|
250
310
|
exports.extractDiscriminatedSchema = extractDiscriminatedSchema;
|
|
251
311
|
exports.extractFieldFromSchema = extractFieldFromSchema;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema.ts","../src/discriminatedSchema.ts","../src/defaults.ts","../src/field.ts"],"names":["z","z3","getShapeField"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\nimport type {\n $ZodCheckBigIntFormatDef,\n $ZodCheckEndsWithDef,\n $ZodCheckGreaterThanDef,\n $ZodCheckIncludesDef,\n $ZodCheckLengthEqualsDef,\n $ZodCheckLessThanDef,\n $ZodCheckLowerCaseDef,\n $ZodCheckMaxLengthDef,\n $ZodCheckMaxSizeDef,\n $ZodCheckMimeTypeDef,\n $ZodCheckMinLengthDef,\n $ZodCheckMinSizeDef,\n $ZodCheckMultipleOfDef,\n $ZodCheckNumberFormatDef,\n $ZodCheckOverwriteDef,\n $ZodCheckPropertyDef,\n $ZodCheckRegexDef,\n $ZodCheckSizeEqualsDef,\n $ZodCheckStartsWithDef,\n $ZodCheckStringFormatDef,\n $ZodCheckUpperCaseDef,\n} from 'zod/v4/core';\n\n/**\n * Type representing a Zod type that has an unwrap method\n */\ntype Unwrappable = { unwrap: () => z.ZodTypeAny };\n\n/**\n * Type guard to check if a Zod field can be unwrapped (has wrapper types like optional, nullable, default).\n *\n * This checks whether a Zod type has an `unwrap()` method, which is present on wrapper types\n * like `ZodOptional`, `ZodNullable`, `ZodDefault`, and others.\n *\n * @param field - The Zod field to check\n * @returns True if the field has an unwrap method, false otherwise\n *\n * @example\n * ```typescript\n * const optionalField = z.string().optional();\n * console.log(canUnwrap(optionalField)); // true\n *\n * const plainField = z.string();\n * console.log(canUnwrap(plainField)); // false\n * ```\n *\n * @since 0.1.0\n */\nexport function canUnwrap(\n field: z.ZodTypeAny,\n): field is z.ZodTypeAny & Unwrappable {\n return 'unwrap' in field && typeof field.unwrap === 'function';\n}\n\n/**\n * Type guard that checks if a Zod field is a ZodPipe with a ZodType input.\n *\n * Used to safely access `field.def.in` on pipe types for unwrapping transformations.\n *\n * @param field - The Zod field to check\n * @returns True if field is a ZodPipe with a ZodType input\n */\nexport function isPipeWithZodInput(\n field: z.ZodTypeAny,\n): field is z.ZodPipe<z.ZodType, z.ZodTypeAny> {\n return field instanceof z.ZodPipe && field.def.in instanceof z.ZodType;\n}\n\n/**\n * Attempts to strip nullish types from a union and return the single remaining type.\n *\n * This function filters out `ZodNull` and `ZodUndefined` from union types. If exactly\n * one type remains after filtering, it returns that unwrapped type. Otherwise, it returns\n * `false` to indicate the union couldn't be simplified to a single type.\n *\n * @param field - The Zod field to process\n * @returns The unwrapped type if only one remains, otherwise `false`\n *\n * @example\n * Union with only nullish types filtered - returns single type\n * ```typescript\n * const field = z.union([z.string(), z.null(), z.undefined()]);\n * const result = tryStripNullishOnly(field);\n * // Result: z.string() (unwrapped)\n * ```\n *\n * @example\n * Union with multiple non-nullish types - returns false\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const result = tryStripNullishOnly(field);\n * // Result: false (cannot simplify to single type)\n * ```\n *\n * @example\n * Non-union type - returns false\n * ```typescript\n * const field = z.string();\n * const result = tryStripNullishOnly(field);\n * // Result: false (not a union)\n * ```\n *\n * @see {@link getPrimitiveType} for unwrapping wrapper types\n * @since 0.5.0\n */\nexport function tryStripNullishOnly(field: z.ZodTypeAny): z.ZodType | false {\n if (field instanceof z.ZodUnion) {\n const unionOptions = [...field.def.options];\n\n const filteredOptions = unionOptions.filter(\n (option): option is z.ZodType =>\n !(option instanceof z.ZodNull) && !(option instanceof z.ZodUndefined),\n );\n\n // If exactly one option remains, return it unwrapped\n const firstOption = filteredOptions[0];\n if (firstOption && filteredOptions.length === 1) {\n return firstOption;\n }\n }\n\n // Not a union, or couldn't simplify to single type\n return false;\n}\n\n/**\n * Gets the underlying primitive type of a Zod field by recursively unwrapping wrapper types.\n *\n * This function removes wrapper layers (optional, nullable, default) to reveal the base type.\n * **Important:** It stops at array types without unwrapping them, treating arrays as primitives.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one\n * type remains after stripping, unwraps to that type. If multiple non-nullish types remain,\n * returns the union as-is (does not unwrap).\n *\n * @template T - The Zod type to unwrap\n * @param field - The Zod field to unwrap\n * @returns The unwrapped primitive Zod type\n *\n * @example\n * Unwrapping to string primitive\n * ```typescript\n * const field = z.string().optional().nullable();\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (unwrapped all wrappers)\n * ```\n *\n * @example\n * Stopping at array type\n * ```typescript\n * const field = z.array(z.string()).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.array(z.string()) (stops at array, doesn't unwrap it)\n * ```\n *\n * @example\n * Unwrapping defaults\n * ```typescript\n * const field = z.number().default(0).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.number()\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string(), z.null()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.union([z.string(), z.number()]) (returned as-is)\n * ```\n *\n * @see {@link canUnwrap} for checking if a field can be unwrapped\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport const getPrimitiveType = <T extends z.ZodType>(\n field: T,\n): z.ZodTypeAny => {\n // Stop at arrays - don't unwrap them\n if (field instanceof z.ZodArray) {\n return field;\n }\n\n if (canUnwrap(field)) {\n return getPrimitiveType(field.unwrap());\n }\n\n if (field instanceof z.ZodDiscriminatedUnion) {\n return field;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n return getPrimitiveType(unwrapped);\n }\n\n // Multiple non-nullish types or all nullish - return union as-is\n return field;\n }\n\n if (isPipeWithZodInput(field)) {\n return getPrimitiveType(field.def.in);\n }\n\n return field;\n};\n\ntype StripZodDefault<T> = T extends z.ZodDefault<infer Inner>\n ? StripZodDefault<Inner>\n : T extends z.ZodOptional<infer Inner>\n ? z.ZodOptional<StripZodDefault<Inner>>\n : T extends z.ZodNullable<infer Inner>\n ? z.ZodNullable<StripZodDefault<Inner>>\n : T;\n\n/**\n * Removes default values from a Zod field while preserving other wrapper types.\n *\n * This function recursively removes `ZodDefault` wrappers from a field, while maintaining\n * `optional()` and `nullable()` wrappers. Useful for scenarios where you want to check\n * field requirements without considering default values.\n *\n * @template T - The Zod type to process\n * @param field - The Zod field to remove defaults from\n * @returns The field without defaults but with optional/nullable preserved\n *\n * @example\n * Removing simple default\n * ```typescript\n * const field = z.string().default('hello');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string()\n * ```\n *\n * @example\n * Preserving optional wrapper\n * ```typescript\n * const field = z.string().default('hello').optional();\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().optional()\n * ```\n *\n * @example\n * Nested defaults\n * ```typescript\n * const field = z.string().default('inner').nullable().default('outer');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().nullable()\n * ```\n *\n * @see {@link requiresValidInput} for usage with requirement checking\n * @since 0.1.0\n */\nexport function removeDefault<T extends z.ZodType>(\n field: T,\n): StripZodDefault<T> {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.unwrap() as StripZodDefault<T>;\n }\n\n if ('innerType' in field.def && field.def.innerType instanceof z.ZodType) {\n const inner = removeDefault(field.def.innerType);\n // Reconstruct the wrapper with the modified inner type\n if (field instanceof z.ZodOptional) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.optional() as unknown as StripZodDefault<T>;\n }\n if (field instanceof z.ZodNullable) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.nullable() as unknown as StripZodDefault<T>;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field as StripZodDefault<T>;\n}\n\n/**\n * Determines if a field will show validation errors when the user submits empty or invalid input.\n *\n * This is useful for form UIs to indicate which fields require valid user input (e.g., showing\n * asterisks, validation states). The key insight: **defaults are just initial values** - they\n * don't prevent validation errors if the user clears the field.\n *\n * **Real-world example:**\n * ```typescript\n * // Marital status field with default but validation rules\n * const maritalStatus = z.string().min(1).default('single');\n *\n * // Initial: field shows \"single\" (from default)\n * // User deletes the value → field is now empty string\n * // User submits form → validation fails because .min(1) rejects empty strings\n * // requiresValidInput(maritalStatus) → true (shows * indicator, validation error)\n * ```\n *\n * **How it works:**\n * 1. Removes `.default()` wrappers (defaults are initial values, not validation rules)\n * 2. Tests if the underlying schema accepts empty/invalid input:\n * - `undefined` (via `.optional()`)\n * - `null` (via `.nullable()`)\n * - Empty string (plain `z.string()` without `.min(1)` or `.nonempty()`)\n * - Empty array (plain `z.array()` without `.min(1)` or `.nonempty()`)\n * 3. Returns `true` if validation will fail, `false` if empty input is accepted\n *\n * @template T - The Zod type to check\n * @param field - The Zod field to check\n * @returns True if the field will show validation errors on empty/invalid input, false otherwise\n *\n * @example\n * User name field - required, no default\n * ```typescript\n * const userName = z.string().min(1);\n * requiresValidInput(userName); // true - will error if user submits empty\n * ```\n *\n * @example\n * Marital status - required WITH default\n * ```typescript\n * const maritalStatus = z.string().min(1).default('single');\n * requiresValidInput(maritalStatus); // true - will error if user clears and submits\n * ```\n *\n * @example\n * Age with default - requires valid input\n * ```typescript\n * const age = z.number().default(0);\n * requiresValidInput(age); // true - numbers reject empty strings\n * ```\n *\n * @example\n * Optional bio field - doesn't require input\n * ```typescript\n * const bio = z.string().optional();\n * requiresValidInput(bio); // false - user can leave empty\n * ```\n *\n * @example\n * String with default but NO validation - doesn't require input\n * ```typescript\n * const notes = z.string().default('N/A');\n * requiresValidInput(notes); // false - plain z.string() accepts empty strings\n * ```\n *\n * @example\n * Nullable field - doesn't require input\n * ```typescript\n * const middleName = z.string().nullable();\n * requiresValidInput(middleName); // false - user can leave null\n * ```\n *\n * @see {@link removeDefault} for understanding how defaults are handled\n * @see {@link getPrimitiveType} for understanding type unwrapping\n * @since 0.1.0\n */\nexport const requiresValidInput = <T extends z.ZodType>(field: T) => {\n const defaultRemovedField = removeDefault(field);\n if (!(defaultRemovedField instanceof z.ZodType)) {\n return false;\n }\n\n const undefinedResult = defaultRemovedField.safeParse(undefined).success;\n\n // Check if field accepts null (nullable)\n const nullResult = defaultRemovedField.safeParse(null).success;\n\n const primitiveType = getPrimitiveType(defaultRemovedField);\n\n const emptyStringResult =\n primitiveType.type === 'string' &&\n defaultRemovedField.safeParse('').success;\n\n const emptyArrayResult =\n primitiveType.type === 'array' && defaultRemovedField.safeParse([]).success;\n\n return (\n !undefinedResult && !nullResult && !emptyStringResult && !emptyArrayResult\n );\n};\n\n/**\n * Union type of all Zod check definition types.\n *\n * Includes all validation check types supported by Zod v4:\n * - **Length checks**: `min_length`, `max_length`, `length_equals` (strings, arrays)\n * - **Size checks**: `min_size`, `max_size`, `size_equals` (files, sets, maps)\n * - **Numeric checks**: `greater_than`, `less_than`, `multiple_of`\n * - **Format checks**: `number_format` (int32, float64, etc.), `bigint_format`, `string_format` (email, url, uuid, etc.)\n * - **String pattern checks**: `regex`, `lowercase`, `uppercase`, `includes`, `starts_with`, `ends_with`\n * - **Other checks**: `property`, `mime_type`, `overwrite`\n *\n * @since 0.4.0\n */\nexport type ZodUnionCheck =\n | $ZodCheckLessThanDef\n | $ZodCheckGreaterThanDef\n | $ZodCheckMultipleOfDef\n | $ZodCheckNumberFormatDef\n | $ZodCheckBigIntFormatDef\n | $ZodCheckMaxSizeDef\n | $ZodCheckMinSizeDef\n | $ZodCheckSizeEqualsDef\n | $ZodCheckMaxLengthDef\n | $ZodCheckMinLengthDef\n | $ZodCheckLengthEqualsDef\n | $ZodCheckStringFormatDef\n | $ZodCheckRegexDef\n | $ZodCheckLowerCaseDef\n | $ZodCheckUpperCaseDef\n | $ZodCheckIncludesDef\n | $ZodCheckStartsWithDef\n | $ZodCheckEndsWithDef\n | $ZodCheckPropertyDef\n | $ZodCheckMimeTypeDef\n | $ZodCheckOverwriteDef;\n\n/**\n * Extracts all validation check definitions from a Zod schema field.\n *\n * This function analyzes a Zod field and returns all check definitions as defined\n * by Zod's internal structure. Returns Zod's raw check definition objects directly,\n * including all properties like `check`, `minimum`, `maximum`, `value`, `inclusive`,\n * `format`, `pattern`, etc.\n *\n * **Unwrapping behavior:** Automatically unwraps optional, nullable, and default layers.\n * For unions, checks only the first option (same as other schema utilities).\n *\n * **Supported check types:** Returns any of the 21 check types defined in {@link ZodUnionCheck},\n * including length, size, numeric range, format validation, string patterns, and more.\n *\n * @template T - The Zod type to extract checks from\n * @param field - The Zod field to analyze\n * @returns Array of Zod check definition objects (see {@link ZodUnionCheck})\n *\n * @example\n * String with length constraints\n * ```typescript\n * const username = z.string().min(3).max(20);\n * const checks = getFieldChecks(username);\n * // [\n * // { check: 'min_length', minimum: 3, when: [Function], ... },\n * // { check: 'max_length', maximum: 20, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Number with range constraints\n * ```typescript\n * const age = z.number().min(18).max(120);\n * const checks = getFieldChecks(age);\n * // [\n * // { check: 'greater_than', value: 18, inclusive: true, when: [Function], ... },\n * // { check: 'less_than', value: 120, inclusive: true, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Array with item count constraints\n * ```typescript\n * const tags = z.array(z.string()).min(1).max(5);\n * const checks = getFieldChecks(tags);\n * // [\n * // { check: 'min_length', minimum: 1, ... },\n * // { check: 'max_length', maximum: 5, ... }\n * // ]\n * ```\n *\n * @example\n * String with format validation\n * ```typescript\n * const email = z.string().email();\n * const checks = getFieldChecks(email);\n * // [\n * // { check: 'string_format', format: 'email', ... }\n * // ]\n * ```\n *\n * @example\n * Unwrapping optional/nullable/default layers\n * ```typescript\n * const bio = z.string().min(10).max(500).optional();\n * const checks = getFieldChecks(bio);\n * // [\n * // { check: 'min_length', minimum: 10, ... },\n * // { check: 'max_length', maximum: 500, ... }\n * // ]\n * ```\n *\n * @see {@link ZodUnionCheck} for all supported check types\n * @since 0.4.0\n */\nexport function getFieldChecks<T extends z.ZodTypeAny>(\n field: T,\n): Array<ZodUnionCheck> {\n const primitiveType = getPrimitiveType(field);\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return (primitiveType.def.checks?.map((check) => check._zod.def) ||\n []) as Array<ZodUnionCheck>;\n}\n","import { type util, z } from 'zod';\nimport type { $InferUnionInput } from 'zod/v4/core';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n/**\n * Recursively extracts the exact schema type from a discriminated union based on the discriminator value.\n *\n * This advanced TypeScript utility type walks through a union's options tuple at compile-time,\n * checking each schema against the discriminator field and value, and returns the exact matching\n * schema type (not a union of all options).\n *\n * **How it works:**\n * 1. Extracts the options tuple from the union using `infer Options`\n * 2. Destructure into head (`First`) and tail (`Rest`) using tuple pattern matching\n * 3. Checks if `First` is a ZodObject with the matching discriminator field and value\n * 4. If match found, returns `First` (the exact schema type)\n * 5. If no match, recursively processes `Rest` until a match is found or list is exhausted\n *\n * **Type narrowing magic:**\n * - Input: `z.discriminatedUnion('type', [SchemaA, SchemaB, SchemaC])`\n * - Discriminator value: `'a'` (matches SchemaA)\n * - Output: `SchemaA` (exact type, not `SchemaA | SchemaB | SchemaC`)\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion type\n * @template TDiscriminatorKey - The discriminator field name (e.g., \"type\", \"mode\")\n * @template TDiscriminatorValue - The specific discriminator value (e.g., \"create\", \"edit\")\n * @returns The exact matching schema type, or `never` if no match found\n *\n * @example\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * z.object({ mode: z.literal('edit'), id: z.number() }),\n * ]);\n *\n * // Exact type: z.object({ mode: z.literal('create'), name: z.string() })\n * type CreateSchema = ExtractZodUnionMember<typeof schema, 'mode', 'create'>;\n * ```\n */\ntype ExtractZodUnionMember<\n TSchema extends z.ZodUnion | z.ZodDiscriminatedUnion,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends z.input<TSchema>[TDiscriminatorKey] &\n util.Literal,\n> = TSchema extends z.ZodUnion<infer Options>\n ? Options extends readonly [\n infer First extends z.ZodTypeAny,\n ...infer Rest extends z.ZodTypeAny[],\n ]\n ? First extends z.ZodObject<infer Shape>\n ? TDiscriminatorKey extends keyof Shape\n ? Shape[TDiscriminatorKey] extends\n | z.ZodLiteral<TDiscriminatorValue>\n | z.ZodDefault<z.ZodLiteral<TDiscriminatorValue>>\n ? First\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : never\n : never\n : never;\n\n/**\n * Extracts a specific schema option from a discriminated union based on the discriminator field value.\n *\n * This function finds and returns the **exact matching schema** from a `ZodDiscriminatedUnion` by\n * comparing the discriminator field value. It's used internally by {@link getSchemaDefaults} to\n * extract defaults from the correct schema variant in a discriminated union.\n *\n * **Key feature:** Returns the **exact schema type**, not a union of all options, thanks to the\n * {@link ExtractZodUnionMember} recursive type utility. This enables precise type narrowing at\n * compile-time based on the discriminator value.\n *\n * **How it works:**\n * 1. Iterates through all options in the discriminated union at runtime\n * 2. For each option, validates it's a ZodObject and checks if the discriminator field matches\n * 3. Returns the first matching schema with its exact type narrowed at compile-time\n * 4. Returns `undefined` if no match found or if option is not a ZodObject\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion schema type\n * @template TDiscriminatorKey - The discriminator field name (string key of the inferred union type)\n * @template TDiscriminatorValue - The specific discriminator value to match (literal type)\n * @param params - Parameters object\n * @param params.schema - The discriminated union schema to search\n * @param params.discriminatorKey - The discriminator field name (e.g., \"mode\", \"type\")\n * @param params.discriminatorValue - The discriminator value to match (e.g., \"create\", \"edit\")\n * @returns The exact matching schema option (with precise type), or `undefined` if not found or schema is not a discriminated union\n *\n * @example\n * Basic discriminated union - create/edit mode\n * ```typescript\n * const userSchema = z.discriminatedUnion('mode', [\n * z.object({\n * mode: z.literal('create'),\n * name: z.string(),\n * age: z.number().optional(),\n * }),\n * z.object({\n * mode: z.literal('edit'),\n * id: z.number(),\n * name: z.string().optional(),\n * }),\n * ]);\n *\n * // Extract the \"create\" schema\n * const createSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n * // Result: z.object({ mode: z.literal('create'), name: z.string(), age: z.number().optional() })\n *\n * // Extract the \"edit\" schema\n * const editSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'edit' },\n * });\n * // Result: z.object({ mode: z.literal('edit'), id: z.number(), name: z.string().optional() })\n * ```\n *\n * @example\n * Type-based discrimination\n * ```typescript\n * const eventSchema = z.discriminatedUnion('type', [\n * z.object({ type: z.literal('click'), x: z.number(), y: z.number() }),\n * z.object({ type: z.literal('keypress'), key: z.string() }),\n * ]);\n *\n * const clickSchema = extractDiscriminatedSchema({\n * schema: eventSchema,\n * discriminator: { key: 'type', value: 'click' },\n * });\n * // Result: z.object({ type: z.literal('click'), x: z.number(), y: z.number() })\n * ```\n *\n * @example\n * Invalid discriminator value\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * ]);\n *\n * const result = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'invalid' }, // doesn't match any option\n * });\n * // Result: undefined\n * ```\n *\n * @example\n * Type narrowing demonstration\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string(), age: z.number() }),\n * z.object({ mode: z.literal('edit'), id: z.number(), bio: z.string() }),\n * ]);\n *\n * const createSchema = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n *\n * // Type is EXACTLY: z.object({ mode: z.literal('create'), name: z.string(), age: z.number() })\n * // NOT: z.object({ mode: ..., ... }) | z.object({ mode: ..., ... }) | undefined\n *\n * if (createSchema) {\n * createSchema.shape.age; // ✅ TypeScript knows 'age' exists\n * createSchema.shape.name; // ✅ TypeScript knows 'name' exists\n * // createSchema.shape.id; // ❌ TypeScript error: 'id' doesn't exist on 'create' schema\n * }\n * ```\n *\n * @see {@link getSchemaDefaults} for usage with discriminated unions\n * @see {@link ExtractZodUnionMember} for the type-level extraction logic\n * @since 0.6.0\n */\nexport const extractDiscriminatedSchema = <\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n ReturnType extends TSchema extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<TSchema, TDiscriminatorKey, TDiscriminatorValue>\n : never,\n>({\n schema,\n discriminator,\n}: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n>): ReturnType | undefined => {\n const primitiveSchema = getPrimitiveType(schema);\n\n if (!(primitiveSchema instanceof z.ZodDiscriminatedUnion) || !discriminator) {\n return undefined;\n }\n\n const { key, value } = discriminator;\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return primitiveSchema.options.find((option) => {\n if (option instanceof z.ZodObject) {\n const targetField = getShapeField(option, String(key));\n if (!targetField) return false;\n\n const parseResult = targetField.safeParse(value);\n return parseResult.success;\n }\n return false;\n }) as ReturnType;\n};\n","import * as z from 'zod';\nimport { extractDiscriminatedSchema } from './discriminatedSchema';\nimport {\n canUnwrap,\n getPrimitiveType,\n isPipeWithZodInput,\n tryStripNullishOnly,\n} from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n Simplify,\n} from './types';\n\n/**\n * Type-safe helper to iterate over ZodObject shape entries.\n * @internal\n */\nfunction getShapeEntries(\n schema: z.ZodObject,\n): Array<[string, z.ZodType | undefined]> {\n return Object.entries(schema.shape);\n}\n\n/**\n * Extracts the default value from a Zod field, recursively unwrapping optional, nullable, and union layers.\n *\n * This function traverses through wrapper types (like `ZodOptional`, `ZodNullable`, `ZodUnion`) to find\n * the underlying `ZodDefault` and returns its default value. If no default is found, returns `undefined`.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one type\n * remains after stripping, extracts the default from that type. If multiple non-nullish types remain,\n * returns `undefined` (does not extract from any option).\n *\n * @template T - The Zod type to extract default from\n * @param field - The Zod field to extract default from\n * @returns The default value if present, undefined otherwise\n *\n * @example\n * Basic usage with default value\n * ```typescript\n * const field = z.string().default('hello');\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello'\n * ```\n *\n * @example\n * Unwrapping optional/nullable layers\n * ```typescript\n * const field = z.string().default('world').optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'world' (unwraps optional to find default)\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.null()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello' (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.number()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined (multiple non-nullish types - no default extracted)\n * ```\n *\n * @example\n * Field without default\n * ```typescript\n * const field = z.string().optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined\n * ```\n *\n * @see {@link getSchemaDefaults} for extracting defaults from entire schemas\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport function extractDefaultValue<T extends z.ZodType>(\n field: T,\n): z.input<T> | undefined {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.def.defaultValue as z.input<T>;\n }\n\n if (canUnwrap(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.unwrap()) as z.input<T>;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n // Successfully unwrapped to single type\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(unwrapped) as z.input<T>;\n }\n\n // Multiple non-nullish types or all nullish - no default\n return undefined;\n }\n\n if (isPipeWithZodInput(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.def.in) as z.input<T>;\n }\n\n // Recursively extract defaults from nested objects\n if (field instanceof z.ZodObject) {\n const nestedDefaults: Record<string, unknown> = {};\n let hasAnyDefault = false;\n\n for (const [key, nestedField] of getShapeEntries(field)) {\n if (!nestedField) continue;\n\n const nestedDefault = extractDefaultValue(nestedField);\n if (nestedDefault !== undefined) {\n nestedDefaults[key] = nestedDefault;\n hasAnyDefault = true;\n }\n }\n\n if (hasAnyDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return nestedDefaults as z.input<T>;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts default values from a Zod object schema, returning only fields with explicit `.default()`.\n *\n * This function traverses the schema and collects fields that have explicit default values.\n * Fields without defaults are excluded from the result.\n *\n * **Important:** Nested defaults are NOT extracted unless the parent object also has\n * an explicit `.default()`. This is by design to match Zod's default value behavior.\n *\n * **Component handling:** For form inputs without explicit defaults (like `z.string()` or `z.number()`),\n * use the `?? ''` pattern in your components: `<Input value={field.value ?? ''} />`\n *\n * @template TSchema - The Zod object schema type\n * @param targetSchema - The Zod object schema to extract defaults from\n * @returns A partial object containing only fields with explicit default values\n *\n * @example\n * Basic usage - only explicit defaults\n * ```typescript\n * const schema = z.object({\n * name: z.string(), // no default → NOT included\n * age: z.number(), // no default → NOT included\n * role: z.string().default('user'), // explicit default → included\n * count: z.number().default(0), // explicit default → included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { role: 'user', count: 0 }\n * ```\n *\n * @example\n * Nested objects with defaults\n * ```typescript\n * const schema = z.object({\n * user: z.object({\n * name: z.string().default('Guest')\n * }).default({ name: 'Guest' }), // ✅ Extracted because parent has .default()\n *\n * settings: z.object({\n * theme: z.string().default('light')\n * }), // ❌ NOT extracted - parent has no .default()\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { user: { name: 'Guest' } }\n * ```\n *\n * @example\n * Unwrapping optional/nullable fields\n * ```typescript\n * const schema = z.object({\n * title: z.string().default('Untitled').optional(),\n * count: z.number().default(0).nullable(),\n * name: z.string().optional(), // no default → NOT included\n * age: z.number().optional(), // no default → NOT included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { title: 'Untitled', count: 0 }\n * ```\n *\n * @example\n * Component usage for fields without defaults\n * ```typescript\n * // For string/number fields without defaults, handle in components:\n * <Input value={field.value ?? ''} />\n * <Input type=\"number\" value={field.value ?? ''} />\n * ```\n *\n * @see {@link extractDefaultValue} for extracting defaults from individual fields\n * @since 0.1.0\n */\nexport function getSchemaDefaults<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n>(\n params: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n >,\n): Simplify<Partial<z.input<TSchema>>> {\n const primitiveSchemaParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n let targetSchema: z.ZodObject | undefined;\n if (primitiveSchemaParams.schema instanceof z.ZodDiscriminatedUnion) {\n targetSchema = extractDiscriminatedSchema(primitiveSchemaParams);\n } else if (primitiveSchemaParams.schema instanceof z.ZodObject) {\n targetSchema = primitiveSchemaParams.schema;\n }\n\n const defaults: Record<string, unknown> = {};\n\n if (targetSchema) {\n for (const [key, field] of getShapeEntries(targetSchema)) {\n if (!field) continue;\n\n const defaultValue = extractDefaultValue(field);\n if (defaultValue !== undefined) {\n defaults[key] = defaultValue;\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return defaults as Partial<z.input<TSchema>>;\n}\n","import { z } from 'zod';\nimport { extractDiscriminatedSchema } from './discriminatedSchema';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n FieldSelectorProps,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n// Split 'a.b.c' into ['a', 'b', 'c']\ntype Split<S extends string> = S extends `${infer Head}.${infer Tail}`\n ? [Head, ...Split<Tail>]\n : [S];\n\n// Check if string is numeric\ntype IsNumeric<S extends string> = S extends `${number}` ? true : false;\n\n// Unwrap ZodOptional, ZodNullable, ZodDefault\ntype Unwrap<T> = T extends z.ZodOptional<infer U>\n ? Unwrap<U>\n : T extends z.ZodNullable<infer U>\n ? Unwrap<U>\n : T extends z.ZodDefault<infer U>\n ? Unwrap<U>\n : T;\n\n// Navigate Zod schema by path array\ntype NavigateZod<T, Path extends string[]> = Path extends [\n infer First extends string,\n ...infer Rest extends string[],\n]\n ? Unwrap<T> extends z.ZodObject<infer Shape>\n ? First extends keyof Shape\n ? Rest extends []\n ? Shape[First]\n : NavigateZod<Shape[First], Rest>\n : never\n : Unwrap<T> extends z.ZodArray<infer Element>\n ? IsNumeric<First> extends true\n ? Rest extends []\n ? Element\n : NavigateZod<Element, Rest>\n : never\n : never\n : T;\n\nexport type ExtractZodByPath<Schema, Path extends string> = NavigateZod<\n Schema,\n Split<Path>\n>;\n\nexport function extractFieldFromSchema<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema> = never,\n TDiscriminatorValue extends DiscriminatorValue<\n TSchema,\n TDiscriminatorKey\n > = never,\n TFilterType = unknown,\n TStrict extends boolean = true,\n TName extends string = string,\n>(\n params: FieldSelectorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue,\n TFilterType,\n TStrict\n > & { name: TName },\n): (ExtractZodByPath<TSchema, TName> & z.ZodType) | undefined {\n let currentSchema: z.ZodType | undefined;\n\n const newParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n if (newParams.schema instanceof z.ZodDiscriminatedUnion) {\n if (newParams.discriminator) {\n currentSchema = extractDiscriminatedSchema(newParams);\n }\n } else if (newParams.schema instanceof z.ZodObject) {\n currentSchema = newParams.schema;\n }\n\n if (!currentSchema) return undefined;\n\n // Split name into segments (e.g., \"contact.email\" -> [\"contact\", \"email\"])\n const segments = String(newParams.name).split('.');\n\n for (const segment of segments) {\n if (!currentSchema) return undefined;\n\n const unwrapped: z.ZodType = getPrimitiveType(currentSchema);\n\n if (unwrapped instanceof z.ZodObject) {\n currentSchema = getShapeField(unwrapped, segment);\n } else if (unwrapped instanceof z.ZodArray) {\n // Arrays are keyed by integers only\n if (/^\\d+$/.test(segment) && unwrapped.element instanceof z.ZodType) {\n currentSchema = unwrapped.element;\n } else {\n return undefined;\n }\n } else {\n return undefined;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return currentSchema as\n | (ExtractZodByPath<TSchema, TName> & z.ZodType)\n | undefined;\n}\n\n/**\n * Extends a Zod field with a transformation while preserving its metadata.\n *\n * This is useful when you want to add validations or transformations to a field\n * but keep the original metadata (like translationKey) intact.\n *\n * @param field - The original Zod field\n * @param transform - A function that transforms the field\n * @returns The transformed field with preserved metadata\n *\n * @example\n * ```typescript\n * const baseField = z.string().meta({ translationKey: 'user.field.name' });\n *\n * // Add min/max validation while keeping the translationKey\n * const extendedField = extendWithMeta(baseField, (f) => f.min(3).max(100));\n * extendedField.meta(); // { translationKey: 'user.field.name' }\n * ```\n */\nexport function extendWithMeta<T extends z.ZodType, R extends z.ZodType>(\n field: T,\n transform: (f: T) => R,\n): R {\n const transformedField = transform(field);\n const meta = field.meta();\n if (!meta) {\n return transformedField;\n }\n return transformedField.meta({ ...meta });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/discriminatedSchema.ts","../src/defaults.ts","../src/field.ts"],"names":["z","allChecks","ZodStringFormat","$ZodCheckLessThan","$ZodCheckGreaterThan","$ZodCheckMultipleOf","$ZodCheckNumberFormat","$ZodCheckMaxSize","$ZodCheckMinSize","$ZodCheckSizeEquals","$ZodCheckMaxLength","$ZodCheckMinLength","$ZodCheckLengthEquals","$ZodCheckRegex","$ZodCheckStringFormat","$ZodCheckOverwrite","$ZodCheckMimeType","$ZodCheckIncludes","$ZodCheckStartsWith","$ZodCheckEndsWith","z3","getShapeField"],"mappings":"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","file":"index.js","sourcesContent":["import { ZodStringFormat, z } from 'zod';\nimport {\n // $ZodCheckBigIntFormat,\n // type $ZodCheckBigIntFormatDef,\n $ZodCheckEndsWith,\n type $ZodCheckEndsWithDef,\n $ZodCheckGreaterThan,\n type $ZodCheckGreaterThanDef,\n $ZodCheckIncludes,\n type $ZodCheckIncludesDef,\n $ZodCheckLengthEquals,\n type $ZodCheckLengthEqualsDef,\n $ZodCheckLessThan,\n type $ZodCheckLessThanDef,\n // $ZodCheckLowerCase,\n // type $ZodCheckLowerCaseDef,\n $ZodCheckMaxLength,\n type $ZodCheckMaxLengthDef,\n $ZodCheckMaxSize,\n type $ZodCheckMaxSizeDef,\n $ZodCheckMimeType,\n type $ZodCheckMimeTypeDef,\n $ZodCheckMinLength,\n type $ZodCheckMinLengthDef,\n $ZodCheckMinSize,\n type $ZodCheckMinSizeDef,\n $ZodCheckMultipleOf,\n type $ZodCheckMultipleOfDef,\n $ZodCheckNumberFormat,\n type $ZodCheckNumberFormatDef,\n $ZodCheckOverwrite,\n type $ZodCheckOverwriteDef,\n $ZodCheckRegex,\n type $ZodCheckRegexDef,\n $ZodCheckSizeEquals,\n type $ZodCheckSizeEqualsDef,\n $ZodCheckStartsWith,\n type $ZodCheckStartsWithDef,\n $ZodCheckStringFormat,\n type $ZodCheckStringFormatDef,\n // $ZodCheckUpperCase,\n // type $ZodCheckUpperCaseDef,\n type $ZodType,\n} from 'zod/v4/core';\n\n/**\n * Type representing a Zod type that has an unwrap method\n */\ntype Unwrappable = { unwrap: () => z.ZodTypeAny };\n\n/**\n * Type guard to check if a Zod field can be unwrapped (has wrapper types like optional, nullable, default).\n *\n * This checks whether a Zod type has an `unwrap()` method, which is present on wrapper types\n * like `ZodOptional`, `ZodNullable`, `ZodDefault`, and others.\n *\n * @param field - The Zod field to check\n * @returns True if the field has an unwrap method, false otherwise\n *\n * @example\n * ```typescript\n * const optionalField = z.string().optional();\n * console.log(canUnwrap(optionalField)); // true\n *\n * const plainField = z.string();\n * console.log(canUnwrap(plainField)); // false\n * ```\n *\n * @since 0.1.0\n */\nexport function canUnwrap(\n field: z.ZodType | $ZodType,\n): field is (z.ZodType | $ZodType) & Unwrappable {\n return 'unwrap' in field && typeof field.unwrap === 'function';\n}\n\n/**\n * Type guard that checks if a Zod field is a ZodPipe with a ZodType input.\n *\n * Used to safely access `field.def.in` on pipe types for unwrapping transformations.\n *\n * @param field - The Zod field to check\n * @returns True if field is a ZodPipe with a ZodType input\n */\nexport function isPipeWithZodInput(\n field: z.ZodType | $ZodType,\n): field is z.ZodPipe<z.ZodType, z.ZodTypeAny> {\n return field instanceof z.ZodPipe && field.def.in instanceof z.ZodType;\n}\n\n/**\n * Attempts to strip nullish types from a union and return the single remaining type.\n *\n * This function filters out `ZodNull` and `ZodUndefined` from union types. If exactly\n * one type remains after filtering, it returns that unwrapped type. Otherwise, it returns\n * `false` to indicate the union couldn't be simplified to a single type.\n *\n * @param field - The Zod field to process\n * @returns The unwrapped type if only one remains, otherwise `false`\n *\n * @example\n * Union with only nullish types filtered - returns single type\n * ```typescript\n * const field = z.union([z.string(), z.null(), z.undefined()]);\n * const result = tryStripNullishOnly(field);\n * // Result: z.string() (unwrapped)\n * ```\n *\n * @example\n * Union with multiple non-nullish types - returns false\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const result = tryStripNullishOnly(field);\n * // Result: false (cannot simplify to single type)\n * ```\n *\n * @example\n * Non-union type - returns false\n * ```typescript\n * const field = z.string();\n * const result = tryStripNullishOnly(field);\n * // Result: false (not a union)\n * ```\n *\n * @see {@link getPrimitiveType} for unwrapping wrapper types\n * @since 0.5.0\n */\nexport function tryStripNullishOnly(field: z.ZodTypeAny): z.ZodType | false {\n if (field instanceof z.ZodUnion) {\n const unionOptions = [...field.def.options];\n\n const filteredOptions = unionOptions.filter(\n (option): option is z.ZodType =>\n !(option instanceof z.ZodNull) && !(option instanceof z.ZodUndefined),\n );\n\n // If exactly one option remains, return it unwrapped\n const firstOption = filteredOptions[0];\n if (firstOption && filteredOptions.length === 1) {\n return firstOption;\n }\n }\n\n // Not a union, or couldn't simplify to single type\n return false;\n}\n\n/**\n * Gets the underlying primitive type of a Zod field by recursively unwrapping wrapper types.\n *\n * This function removes wrapper layers (optional, nullable, default) to reveal the base type.\n * **Important:** It stops at array types without unwrapping them, treating arrays as primitives.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one\n * type remains after stripping, unwraps to that type. If multiple non-nullish types remain,\n * returns the union as-is (does not unwrap).\n *\n * @template T - The Zod type to unwrap\n * @param field - The Zod field to unwrap\n * @returns The unwrapped primitive Zod type\n *\n * @example\n * Unwrapping to string primitive\n * ```typescript\n * const field = z.string().optional().nullable();\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (unwrapped all wrappers)\n * ```\n *\n * @example\n * Stopping at array type\n * ```typescript\n * const field = z.array(z.string()).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.array(z.string()) (stops at array, doesn't unwrap it)\n * ```\n *\n * @example\n * Unwrapping defaults\n * ```typescript\n * const field = z.number().default(0).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.number()\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string(), z.null()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.union([z.string(), z.number()]) (returned as-is)\n * ```\n *\n * @see {@link canUnwrap} for checking if a field can be unwrapped\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport const getPrimitiveType = <T extends z.ZodType>(field: T): z.ZodType => {\n // Stop at arrays - don't unwrap them\n if (field instanceof z.ZodArray) {\n return field;\n }\n\n if (canUnwrap(field)) {\n return getPrimitiveType(field.unwrap());\n }\n\n if (field instanceof z.ZodDiscriminatedUnion) {\n return field;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n return getPrimitiveType(unwrapped);\n }\n\n // Multiple non-nullish types or all nullish - return union as-is\n return field;\n }\n\n if (isPipeWithZodInput(field)) {\n return getPrimitiveType(field.def.in);\n }\n\n return field;\n};\n\ntype StripZodDefault<T> = T extends z.ZodDefault<infer Inner>\n ? StripZodDefault<Inner>\n : T extends z.ZodOptional<infer Inner>\n ? z.ZodOptional<StripZodDefault<Inner>>\n : T extends z.ZodNullable<infer Inner>\n ? z.ZodNullable<StripZodDefault<Inner>>\n : T;\n\n/**\n * Removes default values from a Zod field while preserving other wrapper types.\n *\n * This function recursively removes `ZodDefault` wrappers from a field, while maintaining\n * `optional()` and `nullable()` wrappers. Useful for scenarios where you want to check\n * field requirements without considering default values.\n *\n * @template T - The Zod type to process\n * @param field - The Zod field to remove defaults from\n * @returns The field without defaults but with optional/nullable preserved\n *\n * @example\n * Removing simple default\n * ```typescript\n * const field = z.string().default('hello');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string()\n * ```\n *\n * @example\n * Preserving optional wrapper\n * ```typescript\n * const field = z.string().default('hello').optional();\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().optional()\n * ```\n *\n * @example\n * Nested defaults\n * ```typescript\n * const field = z.string().default('inner').nullable().default('outer');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().nullable()\n * ```\n *\n * @see {@link requiresValidInput} for usage with requirement checking\n * @since 0.1.0\n */\nexport function removeDefault<T extends z.ZodType>(\n field: T,\n): StripZodDefault<T> {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.unwrap() as StripZodDefault<T>;\n }\n\n if ('innerType' in field.def && field.def.innerType instanceof z.ZodType) {\n const inner = removeDefault(field.def.innerType);\n // Reconstruct the wrapper with the modified inner type\n if (field instanceof z.ZodOptional) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.optional() as unknown as StripZodDefault<T>;\n }\n if (field instanceof z.ZodNullable) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.nullable() as unknown as StripZodDefault<T>;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field as StripZodDefault<T>;\n}\n\n/**\n * Determines if a field will show validation errors when the user submits empty or invalid input.\n *\n * This is useful for form UIs to indicate which fields require valid user input (e.g., showing\n * asterisks, validation states). The key insight: **defaults are just initial values** - they\n * don't prevent validation errors if the user clears the field.\n *\n * **Real-world example:**\n * ```typescript\n * // Marital status field with default but validation rules\n * const maritalStatus = z.string().min(1).default('single');\n *\n * // Initial: field shows \"single\" (from default)\n * // User deletes the value → field is now empty string\n * // User submits form → validation fails because .min(1) rejects empty strings\n * // requiresValidInput(maritalStatus) → true (shows * indicator, validation error)\n * ```\n *\n * **How it works:**\n * 1. Removes `.default()` wrappers (defaults are initial values, not validation rules)\n * 2. Tests if the underlying schema accepts empty/invalid input:\n * - `undefined` (via `.optional()`)\n * - `null` (via `.nullable()`)\n * - Empty string (plain `z.string()` without `.min(1)` or `.nonempty()`)\n * - Empty array (plain `z.array()` without `.min(1)` or `.nonempty()`)\n * 3. Returns `true` if validation will fail, `false` if empty input is accepted\n *\n * @template T - The Zod type to check\n * @param field - The Zod field to check\n * @returns True if the field will show validation errors on empty/invalid input, false otherwise\n *\n * @example\n * User name field - required, no default\n * ```typescript\n * const userName = z.string().min(1);\n * requiresValidInput(userName); // true - will error if user submits empty\n * ```\n *\n * @example\n * Marital status - required WITH default\n * ```typescript\n * const maritalStatus = z.string().min(1).default('single');\n * requiresValidInput(maritalStatus); // true - will error if user clears and submits\n * ```\n *\n * @example\n * Age with default - requires valid input\n * ```typescript\n * const age = z.number().default(0);\n * requiresValidInput(age); // true - numbers reject empty strings\n * ```\n *\n * @example\n * Optional bio field - doesn't require input\n * ```typescript\n * const bio = z.string().optional();\n * requiresValidInput(bio); // false - user can leave empty\n * ```\n *\n * @example\n * String with default but NO validation - doesn't require input\n * ```typescript\n * const notes = z.string().default('N/A');\n * requiresValidInput(notes); // false - plain z.string() accepts empty strings\n * ```\n *\n * @example\n * Nullable field - doesn't require input\n * ```typescript\n * const middleName = z.string().nullable();\n * requiresValidInput(middleName); // false - user can leave null\n * ```\n *\n * @see {@link removeDefault} for understanding how defaults are handled\n * @see {@link getPrimitiveType} for understanding type unwrapping\n * @since 0.1.0\n */\nexport const requiresValidInput = <T extends z.ZodType>(field: T) => {\n const defaultRemovedField = removeDefault(field);\n if (!(defaultRemovedField instanceof z.ZodType)) {\n return false;\n }\n\n const undefinedResult = defaultRemovedField.safeParse(undefined).success;\n\n // Check if field accepts null (nullable)\n const nullResult = defaultRemovedField.safeParse(null).success;\n\n const primitiveType = getPrimitiveType(defaultRemovedField);\n\n const emptyStringResult =\n primitiveType.type === 'string' &&\n defaultRemovedField.safeParse('').success;\n\n const emptyArrayResult =\n primitiveType.type === 'array' && defaultRemovedField.safeParse([]).success;\n\n return (\n !undefinedResult && !nullResult && !emptyStringResult && !emptyArrayResult\n );\n};\n\n/**\n * Union type of all Zod check definition types.\n *\n * Includes all validation check types supported by Zod v4:\n * - **Length checks**: `min_length`, `max_length`, `length_equals` (strings, arrays)\n * - **Size checks**: `min_size`, `max_size`, `size_equals` (files, sets, maps)\n * - **Numeric checks**: `greater_than`, `less_than`, `multiple_of`\n * - **Format checks**: `number_format` (int32, float64, etc.), `bigint_format`, `string_format` (email, url, uuid, etc.)\n * - **String pattern checks**: `regex`, `lowercase`, `uppercase`, `includes`, `starts_with`, `ends_with`\n * - **Other checks**: `property`, `mime_type`, `overwrite`\n *\n * @since 0.4.0\n */\nexport type ZodUnionCheck =\n | $ZodCheckLessThanDef\n | $ZodCheckGreaterThanDef\n | $ZodCheckMultipleOfDef\n | $ZodCheckNumberFormatDef\n // | $ZodCheckBigIntFormatDef\n | $ZodCheckMaxSizeDef\n | $ZodCheckMinSizeDef\n | $ZodCheckSizeEqualsDef\n | $ZodCheckMaxLengthDef\n | $ZodCheckMinLengthDef\n | $ZodCheckLengthEqualsDef\n | $ZodCheckStringFormatDef\n | $ZodCheckRegexDef\n // | $ZodCheckLowerCaseDef\n // | $ZodCheckUpperCaseDef\n | $ZodCheckIncludesDef\n | $ZodCheckStartsWithDef\n | $ZodCheckEndsWithDef\n | $ZodCheckMimeTypeDef\n | $ZodCheckOverwriteDef;\n\n/**\n * Extracts all validation check definitions from a Zod schema field.\n *\n * This function analyzes a Zod field and returns all check definitions as defined\n * by Zod's internal structure. Returns Zod's raw check definition objects directly,\n * including all properties like `check`, `minimum`, `maximum`, `value`, `inclusive`,\n * `format`, `pattern`, etc.\n *\n * **Unwrapping behavior:** Automatically unwraps optional, nullable, and default layers.\n * For unions, checks only the first option (same as other schema utilities).\n *\n * **Supported check types:** Returns any of the 21 check types defined in {@link ZodUnionCheck},\n * including length, size, numeric range, format validation, string patterns, and more.\n *\n * @template T - The Zod type to extract checks from\n * @param field - The Zod field to analyze\n * @returns Array of Zod check definition objects (see {@link ZodUnionCheck})\n *\n * @example\n * String with length constraints\n * ```typescript\n * const username = z.string().min(3).max(20);\n * const checks = getFieldChecks(username);\n * // [\n * // { check: 'min_length', minimum: 3, when: [Function], ... },\n * // { check: 'max_length', maximum: 20, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Number with range constraints\n * ```typescript\n * const age = z.number().min(18).max(120);\n * const checks = getFieldChecks(age);\n * // [\n * // { check: 'greater_than', value: 18, inclusive: true, when: [Function], ... },\n * // { check: 'less_than', value: 120, inclusive: true, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Array with item count constraints\n * ```typescript\n * const tags = z.array(z.string()).min(1).max(5);\n * const checks = getFieldChecks(tags);\n * // [\n * // { check: 'min_length', minimum: 1, ... },\n * // { check: 'max_length', maximum: 5, ... }\n * // ]\n * ```\n *\n * @example\n * String with format validation\n * ```typescript\n * const email = z.string().email();\n * const checks = getFieldChecks(email);\n * // [\n * // { check: 'string_format', format: 'email', ... }\n * // ]\n * ```\n *\n * @example\n * Unwrapping optional/nullable/default layers\n * ```typescript\n * const bio = z.string().min(10).max(500).optional();\n * const checks = getFieldChecks(bio);\n * // [\n * // { check: 'min_length', minimum: 10, ... },\n * // { check: 'max_length', maximum: 500, ... }\n * // ]\n * ```\n *\n * @see {@link ZodUnionCheck} for all supported check types\n * @since 0.4.0\n */\nexport function getFieldChecks<T extends z.ZodType | $ZodType>(\n field: T,\n): Array<ZodUnionCheck> {\n if (!(field instanceof z.ZodType)) return [];\n\n const primitiveType = getPrimitiveType(field);\n\n // Handle unions by collecting checks from all options\n if (primitiveType instanceof z.ZodUnion) {\n const allChecks: Array<ZodUnionCheck> = [];\n for (const option of primitiveType.options) {\n const optionChecks = getFieldChecks(option);\n allChecks.push(...optionChecks);\n }\n return allChecks;\n }\n\n const allChecks: Array<ZodUnionCheck> = [];\n\n // Handle format types (ZodURL, ZodEmail, ZodUUID, etc.)\n // These store format info in def.format instead of def.checks\n if (primitiveType instanceof ZodStringFormat) {\n const formatCheck = primitiveType.def;\n allChecks.push(formatCheck);\n }\n\n // Add any additional checks (like .max(), .min(), etc.)\n if (primitiveType.def.checks) {\n for (const check of primitiveType.def.checks) {\n allChecks.push(...extractCheck(check));\n }\n }\n\n return allChecks;\n}\n\n// Returns array instead of single value to enable 100% test coverage\n// (avoids uncoverable branch when using `if (extracted)` pattern)\nexport function extractCheck(check: z.core.$ZodCheck<never>): ZodUnionCheck[] {\n if (check instanceof $ZodCheckLessThan) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckGreaterThan) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMultipleOf) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckNumberFormat) {\n return [check._zod.def];\n // } else if (check instanceof $ZodCheckBigIntFormat) {\n // // this is format, not check\n // return [check._zod.def];\n } else if (check instanceof $ZodCheckMaxSize) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMinSize) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckSizeEquals) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMaxLength) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMinLength) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckLengthEquals) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckRegex) {\n // $ZodCheckRegex must be checked before $ZodCheckStringFormat (it's instanceof both)\n return [check._zod.def];\n } else if (check instanceof $ZodCheckStringFormat) {\n return [check._zod.def];\n // } else if (check instanceof $ZodCheckLowerCase) {\n // // these are formats not checks\n // return [check._zod.def];\n // } else if (check instanceof $ZodCheckUpperCase) {\n // // these are formats not checks\n // return [check._zod.def];\n } else if (check instanceof $ZodCheckOverwrite) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMimeType) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckIncludes) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckStartsWith) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckEndsWith) {\n return [check._zod.def];\n }\n return [];\n}\n","import { type util, z } from 'zod';\nimport type { $InferUnionInput } from 'zod/v4/core';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n UnwrapZodType,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n/**\n * Recursively extracts the exact schema type from a discriminated union based on the discriminator value.\n *\n * This advanced TypeScript utility type walks through a union's options tuple at compile-time,\n * checking each schema against the discriminator field and value, and returns the exact matching\n * schema type (not a union of all options).\n *\n * **How it works:**\n * 1. Extracts the options tuple from the union using `infer Options`\n * 2. Destructure into head (`First`) and tail (`Rest`) using tuple pattern matching\n * 3. Checks if `First` is a ZodObject with the matching discriminator field and value\n * 4. If match found, returns `First` (the exact schema type)\n * 5. If no match, recursively processes `Rest` until a match is found or list is exhausted\n *\n * **Type narrowing magic:**\n * - Input: `z.discriminatedUnion('type', [SchemaA, SchemaB, SchemaC])`\n * - Discriminator value: `'a'` (matches SchemaA)\n * - Output: `SchemaA` (exact type, not `SchemaA | SchemaB | SchemaC`)\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion type\n * @template TDiscriminatorKey - The discriminator field name (e.g., \"type\", \"mode\")\n * @template TDiscriminatorValue - The specific discriminator value (e.g., \"create\", \"edit\")\n * @returns The exact matching schema type, or `never` if no match found\n *\n * @example\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * z.object({ mode: z.literal('edit'), id: z.number() }),\n * ]);\n *\n * // Exact type: z.object({ mode: z.literal('create'), name: z.string() })\n * type CreateSchema = ExtractZodUnionMember<typeof schema, 'mode', 'create'>;\n * ```\n */\nexport type ExtractZodUnionMember<\n TSchema extends z.ZodUnion | z.ZodDiscriminatedUnion,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends z.input<TSchema>[TDiscriminatorKey] &\n util.Literal,\n> = TSchema extends z.ZodUnion<infer Options>\n ? Options extends readonly [\n infer First extends z.ZodTypeAny,\n ...infer Rest extends z.ZodTypeAny[],\n ]\n ? First extends z.ZodObject<infer Shape>\n ? TDiscriminatorKey extends keyof Shape\n ? Shape[TDiscriminatorKey] extends\n | z.ZodLiteral<TDiscriminatorValue>\n | z.ZodDefault<z.ZodLiteral<TDiscriminatorValue>>\n ? First\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : never\n : never\n : never;\n\n/**\n * Extracts a specific schema option from a discriminated union based on the discriminator field value.\n *\n * This function finds and returns the **exact matching schema** from a `ZodDiscriminatedUnion` by\n * comparing the discriminator field value. It's used internally by {@link getSchemaDefaults} to\n * extract defaults from the correct schema variant in a discriminated union.\n *\n * **Key feature:** Returns the **exact schema type**, not a union of all options, thanks to the\n * {@link ExtractZodUnionMember} recursive type utility. This enables precise type narrowing at\n * compile-time based on the discriminator value.\n *\n * **How it works:**\n * 1. Iterates through all options in the discriminated union at runtime\n * 2. For each option, validates it's a ZodObject and checks if the discriminator field matches\n * 3. Returns the first matching schema with its exact type narrowed at compile-time\n * 4. Returns `undefined` if no match found or if option is not a ZodObject\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion schema type\n * @template TDiscriminatorKey - The discriminator field name (string key of the inferred union type)\n * @template TDiscriminatorValue - The specific discriminator value to match (literal type)\n * @param params - Parameters object\n * @param params.schema - The discriminated union schema to search\n * @param params.discriminatorKey - The discriminator field name (e.g., \"mode\", \"type\")\n * @param params.discriminatorValue - The discriminator value to match (e.g., \"create\", \"edit\")\n * @returns The exact matching schema option (with precise type), or `undefined` if not found or schema is not a discriminated union\n *\n * @example\n * Basic discriminated union - create/edit mode\n * ```typescript\n * const userSchema = z.discriminatedUnion('mode', [\n * z.object({\n * mode: z.literal('create'),\n * name: z.string(),\n * age: z.number().optional(),\n * }),\n * z.object({\n * mode: z.literal('edit'),\n * id: z.number(),\n * name: z.string().optional(),\n * }),\n * ]);\n *\n * // Extract the \"create\" schema\n * const createSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n * // Result: z.object({ mode: z.literal('create'), name: z.string(), age: z.number().optional() })\n *\n * // Extract the \"edit\" schema\n * const editSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'edit' },\n * });\n * // Result: z.object({ mode: z.literal('edit'), id: z.number(), name: z.string().optional() })\n * ```\n *\n * @example\n * Type-based discrimination\n * ```typescript\n * const eventSchema = z.discriminatedUnion('type', [\n * z.object({ type: z.literal('click'), x: z.number(), y: z.number() }),\n * z.object({ type: z.literal('keypress'), key: z.string() }),\n * ]);\n *\n * const clickSchema = extractDiscriminatedSchema({\n * schema: eventSchema,\n * discriminator: { key: 'type', value: 'click' },\n * });\n * // Result: z.object({ type: z.literal('click'), x: z.number(), y: z.number() })\n * ```\n *\n * @example\n * Invalid discriminator value\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * ]);\n *\n * const result = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'invalid' }, // doesn't match any option\n * });\n * // Result: undefined\n * ```\n *\n * @example\n * Type narrowing demonstration\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string(), age: z.number() }),\n * z.object({ mode: z.literal('edit'), id: z.number(), bio: z.string() }),\n * ]);\n *\n * const createSchema = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n *\n * // Type is EXACTLY: z.object({ mode: z.literal('create'), name: z.string(), age: z.number() })\n * // NOT: z.object({ mode: ..., ... }) | z.object({ mode: ..., ... }) | undefined\n *\n * if (createSchema) {\n * createSchema.shape.age; // ✅ TypeScript knows 'age' exists\n * createSchema.shape.name; // ✅ TypeScript knows 'name' exists\n * // createSchema.shape.id; // ❌ TypeScript error: 'id' doesn't exist on 'create' schema\n * }\n * ```\n *\n * @see {@link getSchemaDefaults} for usage with discriminated unions\n * @see {@link ExtractZodUnionMember} for the type-level extraction logic\n * @since 0.6.0\n */\nexport const extractDiscriminatedSchema = <\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n TUnwrapped extends z.ZodType = UnwrapZodType<TSchema> extends z.ZodType\n ? UnwrapZodType<TSchema>\n : TSchema,\n ReturnType extends TUnwrapped extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>,\n Extract<\n TDiscriminatorValue,\n DiscriminatorValue<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>\n >\n >\n >\n : undefined = TUnwrapped extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>,\n Extract<\n TDiscriminatorValue,\n DiscriminatorValue<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>\n >\n >\n >\n : undefined,\n>({\n schema,\n discriminator,\n}: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n>): ReturnType => {\n const primitiveSchema = getPrimitiveType(schema);\n\n if (!(primitiveSchema instanceof z.ZodDiscriminatedUnion) || !discriminator) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ReturnType;\n }\n\n const { key, value } = discriminator;\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return primitiveSchema.options.find((option) => {\n if (option instanceof z.ZodObject) {\n const targetField = getShapeField(option, String(key));\n if (!targetField) return false;\n\n const parseResult = targetField.safeParse(value);\n return parseResult.success;\n }\n return false;\n }) as ReturnType;\n};\n","import * as z from 'zod';\nimport { extractDiscriminatedSchema } from './discriminatedSchema';\nimport {\n canUnwrap,\n getPrimitiveType,\n isPipeWithZodInput,\n tryStripNullishOnly,\n} from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n Simplify,\n} from './types';\n\n/**\n * Type-safe helper to iterate over ZodObject shape entries.\n * @internal\n */\nfunction getShapeEntries(\n schema: z.ZodObject,\n): Array<[string, z.ZodType | undefined]> {\n return Object.entries(schema.shape);\n}\n\n/**\n * Extracts the default value from a Zod field, recursively unwrapping optional, nullable, and union layers.\n *\n * This function traverses through wrapper types (like `ZodOptional`, `ZodNullable`, `ZodUnion`) to find\n * the underlying `ZodDefault` and returns its default value. If no default is found, returns `undefined`.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one type\n * remains after stripping, extracts the default from that type. If multiple non-nullish types remain,\n * returns `undefined` (does not extract from any option).\n *\n * @template T - The Zod type to extract default from\n * @param field - The Zod field to extract default from\n * @returns The default value if present, undefined otherwise\n *\n * @example\n * Basic usage with default value\n * ```typescript\n * const field = z.string().default('hello');\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello'\n * ```\n *\n * @example\n * Unwrapping optional/nullable layers\n * ```typescript\n * const field = z.string().default('world').optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'world' (unwraps optional to find default)\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.null()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello' (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.number()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined (multiple non-nullish types - no default extracted)\n * ```\n *\n * @example\n * Field without default\n * ```typescript\n * const field = z.string().optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined\n * ```\n *\n * @see {@link getSchemaDefaults} for extracting defaults from entire schemas\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport function extractDefaultValue<T extends z.ZodType>(\n field: T,\n): z.input<T> | undefined {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.def.defaultValue as z.input<T>;\n }\n\n if (canUnwrap(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.unwrap()) as z.input<T>;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n // Successfully unwrapped to single type\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(unwrapped) as z.input<T>;\n }\n\n // Multiple non-nullish types or all nullish - no default\n return undefined;\n }\n\n if (isPipeWithZodInput(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.def.in) as z.input<T>;\n }\n\n // Recursively extract defaults from nested objects\n if (field instanceof z.ZodObject) {\n const nestedDefaults: Record<string, unknown> = {};\n let hasAnyDefault = false;\n\n for (const [key, nestedField] of getShapeEntries(field)) {\n if (!nestedField) continue;\n\n const nestedDefault = extractDefaultValue(nestedField);\n if (nestedDefault !== undefined) {\n nestedDefaults[key] = nestedDefault;\n hasAnyDefault = true;\n }\n }\n\n if (hasAnyDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return nestedDefaults as z.input<T>;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts default values from a Zod object schema, returning only fields with explicit `.default()`.\n *\n * This function traverses the schema and collects fields that have explicit default values.\n * Fields without defaults are excluded from the result.\n *\n * **Important:** Nested defaults are NOT extracted unless the parent object also has\n * an explicit `.default()`. This is by design to match Zod's default value behavior.\n *\n * **Component handling:** For form inputs without explicit defaults (like `z.string()` or `z.number()`),\n * use the `?? ''` pattern in your components: `<Input value={field.value ?? ''} />`\n *\n * @template TSchema - The Zod object schema type\n * @param targetSchema - The Zod object schema to extract defaults from\n * @returns A partial object containing only fields with explicit default values\n *\n * @example\n * Basic usage - only explicit defaults\n * ```typescript\n * const schema = z.object({\n * name: z.string(), // no default → NOT included\n * age: z.number(), // no default → NOT included\n * role: z.string().default('user'), // explicit default → included\n * count: z.number().default(0), // explicit default → included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { role: 'user', count: 0 }\n * ```\n *\n * @example\n * Nested objects with defaults\n * ```typescript\n * const schema = z.object({\n * user: z.object({\n * name: z.string().default('Guest')\n * }).default({ name: 'Guest' }), // ✅ Extracted because parent has .default()\n *\n * settings: z.object({\n * theme: z.string().default('light')\n * }), // ❌ NOT extracted - parent has no .default()\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { user: { name: 'Guest' } }\n * ```\n *\n * @example\n * Unwrapping optional/nullable fields\n * ```typescript\n * const schema = z.object({\n * title: z.string().default('Untitled').optional(),\n * count: z.number().default(0).nullable(),\n * name: z.string().optional(), // no default → NOT included\n * age: z.number().optional(), // no default → NOT included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { title: 'Untitled', count: 0 }\n * ```\n *\n * @example\n * Component usage for fields without defaults\n * ```typescript\n * // For string/number fields without defaults, handle in components:\n * <Input value={field.value ?? ''} />\n * <Input type=\"number\" value={field.value ?? ''} />\n * ```\n *\n * @see {@link extractDefaultValue} for extracting defaults from individual fields\n * @since 0.1.0\n */\nexport function getSchemaDefaults<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n>(\n params: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n >,\n): Simplify<Partial<z.input<TSchema>>> {\n const primitiveSchemaParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n let targetSchema: z.ZodObject | undefined;\n if (primitiveSchemaParams.schema instanceof z.ZodDiscriminatedUnion) {\n targetSchema = extractDiscriminatedSchema(primitiveSchemaParams);\n } else if (primitiveSchemaParams.schema instanceof z.ZodObject) {\n targetSchema = primitiveSchemaParams.schema;\n }\n\n const defaults: Record<string, unknown> = {};\n\n if (targetSchema) {\n for (const [key, field] of getShapeEntries(targetSchema)) {\n if (!field) continue;\n\n const defaultValue = extractDefaultValue(field);\n if (defaultValue !== undefined) {\n defaults[key] = defaultValue;\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return defaults as Partial<z.input<TSchema>>;\n}\n","import { z } from 'zod';\nimport {\n type ExtractZodUnionMember,\n extractDiscriminatedSchema,\n} from './discriminatedSchema';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n FieldSelectorProps,\n IsDiscriminatedUnion,\n UnwrapZodType,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n// Split 'a.b.c' into ['a', 'b', 'c']\ntype Split<S extends string> = S extends `${infer Head}.${infer Tail}`\n ? [Head, ...Split<Tail>]\n : [S];\n\n// Check if string is numeric\ntype IsNumeric<S extends string> = S extends `${number}` ? true : false;\n\n// Unwrap ZodOptional, ZodNullable, ZodDefault, ZodPipe (transforms)\ntype Unwrap<T> = T extends z.ZodOptional<infer U>\n ? Unwrap<U>\n : T extends z.ZodNullable<infer U>\n ? Unwrap<U>\n : T extends z.ZodDefault<infer U>\n ? Unwrap<U>\n : T extends z.ZodPipe<infer In, z.ZodType>\n ? Unwrap<In>\n : T;\n\n// Navigate Zod schema by path array\ntype NavigateZod<T, Path extends string[]> = Path extends [\n infer First extends string,\n ...infer Rest extends string[],\n]\n ? Unwrap<T> extends z.ZodObject<infer Shape>\n ? First extends keyof Shape\n ? Rest extends []\n ? Shape[First]\n : NavigateZod<Shape[First], Rest>\n : never\n : Unwrap<T> extends z.ZodArray<infer Element>\n ? IsNumeric<First> extends true\n ? Rest extends []\n ? Element\n : NavigateZod<Element, Rest>\n : never\n : never\n : T;\n\nexport type ExtractZodByPath<Schema, Path extends string> = NavigateZod<\n Schema,\n Split<Path>\n>;\n\n/**\n * Extract field from a discriminated union variant.\n * First extracts the variant using ExtractZodUnionMember, then navigates through it.\n * @internal\n */\ntype ExtractFromDiscriminatedUnion<\n TSchema extends z.ZodType,\n TName extends string,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n TUnwrapped extends z.ZodType = UnwrapZodType<TSchema> extends z.ZodType\n ? UnwrapZodType<TSchema>\n : TSchema,\n TVariant = TUnwrapped extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>,\n Extract<\n TDiscriminatorValue,\n DiscriminatorValue<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>\n >\n >\n >\n : never,\n> = TVariant extends z.ZodType ? ExtractZodByPath<TVariant, TName> : never;\n\n/**\n * Helper type to determine if field extraction should succeed.\n * Returns true when:\n * 1. For discriminated unions: discriminator is provided (trust the user)\n * 2. For non-unions: the path resolves to a valid type (not never)\n * @internal\n */\ntype CanExtractField<\n TSchema extends z.ZodType,\n TName extends string,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n> = IsDiscriminatedUnion<TSchema> extends true // Discriminated union - check if discriminator is provided\n ? [TDiscriminatorKey] extends [never]\n ? false // No discriminator = can't extract\n : true // Discriminator provided = trust it\n : // Not a discriminated union - check if path is valid\n [ExtractZodByPath<TSchema, TName>] extends [never]\n ? false\n : true;\n\n/**\n * Conditional return type for extractFieldFromSchema.\n * For discriminated unions: extracts variant first, then navigates.\n * For non-unions: navigates directly.\n * @internal\n */\ntype ExtractFieldResult<\n TSchema extends z.ZodType,\n TName extends string,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<\n TSchema,\n TDiscriminatorKey\n > = DiscriminatorValue<TSchema, TDiscriminatorKey>,\n> = CanExtractField<TSchema, TName, TDiscriminatorKey> extends true\n ? IsDiscriminatedUnion<TSchema> extends true\n ? // For discriminated unions: extract variant first, then navigate\n [\n ExtractFromDiscriminatedUnion<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >,\n ] extends [never]\n ? z.ZodType // Path couldn't be resolved, return generic type\n : ExtractFromDiscriminatedUnion<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n > &\n z.ZodType\n : // For non-unions: navigate directly\n ExtractZodByPath<TSchema, TName> & z.ZodType\n : (ExtractZodByPath<TSchema, TName> & z.ZodType) | undefined;\n\nexport function extractFieldFromSchema<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema> = never,\n TDiscriminatorValue extends DiscriminatorValue<\n TSchema,\n TDiscriminatorKey\n > = never,\n TFilterType = unknown,\n TStrict extends boolean = true,\n TName extends string = string,\n>(\n params: FieldSelectorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue,\n TFilterType,\n TStrict\n > & { name: TName },\n): ExtractFieldResult<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue> {\n let currentSchema: z.ZodType | undefined;\n\n const newParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n if (newParams.schema instanceof z.ZodDiscriminatedUnion) {\n if (newParams.discriminator) {\n currentSchema = extractDiscriminatedSchema(newParams);\n }\n } else if (newParams.schema instanceof z.ZodObject) {\n currentSchema = newParams.schema;\n }\n\n if (!currentSchema)\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n\n // Split name into segments (e.g., \"contact.email\" -> [\"contact\", \"email\"])\n const segments = String(newParams.name).split('.');\n\n for (const segment of segments) {\n if (!currentSchema)\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n\n const unwrapped: z.ZodType = getPrimitiveType(currentSchema);\n\n if (unwrapped instanceof z.ZodObject) {\n currentSchema = getShapeField(unwrapped, segment);\n } else if (unwrapped instanceof z.ZodArray) {\n // Arrays are keyed by integers only\n if (/^\\d+$/.test(segment) && unwrapped.element instanceof z.ZodType) {\n currentSchema = unwrapped.element;\n } else {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey\n >;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return currentSchema as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n}\n\n/**\n * Extends a Zod field with a transformation while preserving its metadata.\n *\n * This is useful when you want to add validations or transformations to a field\n * but keep the original metadata (like translationKey) intact.\n *\n * @param field - The original Zod field\n * @param transform - A function that transforms the field\n * @returns The transformed field with preserved metadata\n *\n * @example\n * ```typescript\n * const baseField = z.string().meta({ translationKey: 'user.field.name' });\n *\n * // Add min/max validation while keeping the translationKey\n * const extendedField = extendWithMeta(baseField, (f) => f.min(3).max(100));\n * extendedField.meta(); // { translationKey: 'user.field.name' }\n * ```\n */\nexport function extendWithMeta<T extends z.ZodType, R extends z.ZodType>(\n field: T,\n transform: (f: T) => R,\n): R {\n const transformedField = transform(field);\n const meta = field.meta();\n if (!meta) {\n return transformedField;\n }\n return transformedField.meta({ ...meta });\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as z3 from 'zod';
|
|
2
|
-
import { z } from 'zod';
|
|
2
|
+
import { z, ZodStringFormat } from 'zod';
|
|
3
|
+
import { $ZodCheckLessThan, $ZodCheckGreaterThan, $ZodCheckMultipleOf, $ZodCheckNumberFormat, $ZodCheckMaxSize, $ZodCheckMinSize, $ZodCheckSizeEquals, $ZodCheckMaxLength, $ZodCheckMinLength, $ZodCheckLengthEquals, $ZodCheckRegex, $ZodCheckStringFormat, $ZodCheckOverwrite, $ZodCheckMimeType, $ZodCheckIncludes, $ZodCheckStartsWith, $ZodCheckEndsWith } from 'zod/v4/core';
|
|
3
4
|
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
5
6
|
var __defProps = Object.defineProperties;
|
|
@@ -89,9 +90,65 @@ var requiresValidInput = (field) => {
|
|
|
89
90
|
return !undefinedResult && !nullResult && !emptyStringResult && !emptyArrayResult;
|
|
90
91
|
};
|
|
91
92
|
function getFieldChecks(field) {
|
|
92
|
-
|
|
93
|
+
if (!(field instanceof z.ZodType)) return [];
|
|
93
94
|
const primitiveType = getPrimitiveType(field);
|
|
94
|
-
|
|
95
|
+
if (primitiveType instanceof z.ZodUnion) {
|
|
96
|
+
const allChecks2 = [];
|
|
97
|
+
for (const option of primitiveType.options) {
|
|
98
|
+
const optionChecks = getFieldChecks(option);
|
|
99
|
+
allChecks2.push(...optionChecks);
|
|
100
|
+
}
|
|
101
|
+
return allChecks2;
|
|
102
|
+
}
|
|
103
|
+
const allChecks = [];
|
|
104
|
+
if (primitiveType instanceof ZodStringFormat) {
|
|
105
|
+
const formatCheck = primitiveType.def;
|
|
106
|
+
allChecks.push(formatCheck);
|
|
107
|
+
}
|
|
108
|
+
if (primitiveType.def.checks) {
|
|
109
|
+
for (const check of primitiveType.def.checks) {
|
|
110
|
+
allChecks.push(...extractCheck(check));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return allChecks;
|
|
114
|
+
}
|
|
115
|
+
function extractCheck(check) {
|
|
116
|
+
if (check instanceof $ZodCheckLessThan) {
|
|
117
|
+
return [check._zod.def];
|
|
118
|
+
} else if (check instanceof $ZodCheckGreaterThan) {
|
|
119
|
+
return [check._zod.def];
|
|
120
|
+
} else if (check instanceof $ZodCheckMultipleOf) {
|
|
121
|
+
return [check._zod.def];
|
|
122
|
+
} else if (check instanceof $ZodCheckNumberFormat) {
|
|
123
|
+
return [check._zod.def];
|
|
124
|
+
} else if (check instanceof $ZodCheckMaxSize) {
|
|
125
|
+
return [check._zod.def];
|
|
126
|
+
} else if (check instanceof $ZodCheckMinSize) {
|
|
127
|
+
return [check._zod.def];
|
|
128
|
+
} else if (check instanceof $ZodCheckSizeEquals) {
|
|
129
|
+
return [check._zod.def];
|
|
130
|
+
} else if (check instanceof $ZodCheckMaxLength) {
|
|
131
|
+
return [check._zod.def];
|
|
132
|
+
} else if (check instanceof $ZodCheckMinLength) {
|
|
133
|
+
return [check._zod.def];
|
|
134
|
+
} else if (check instanceof $ZodCheckLengthEquals) {
|
|
135
|
+
return [check._zod.def];
|
|
136
|
+
} else if (check instanceof $ZodCheckRegex) {
|
|
137
|
+
return [check._zod.def];
|
|
138
|
+
} else if (check instanceof $ZodCheckStringFormat) {
|
|
139
|
+
return [check._zod.def];
|
|
140
|
+
} else if (check instanceof $ZodCheckOverwrite) {
|
|
141
|
+
return [check._zod.def];
|
|
142
|
+
} else if (check instanceof $ZodCheckMimeType) {
|
|
143
|
+
return [check._zod.def];
|
|
144
|
+
} else if (check instanceof $ZodCheckIncludes) {
|
|
145
|
+
return [check._zod.def];
|
|
146
|
+
} else if (check instanceof $ZodCheckStartsWith) {
|
|
147
|
+
return [check._zod.def];
|
|
148
|
+
} else if (check instanceof $ZodCheckEndsWith) {
|
|
149
|
+
return [check._zod.def];
|
|
150
|
+
}
|
|
151
|
+
return [];
|
|
95
152
|
}
|
|
96
153
|
|
|
97
154
|
// src/discriminatedSchema.ts
|
|
@@ -195,10 +252,12 @@ function extractFieldFromSchema(params) {
|
|
|
195
252
|
} else if (newParams.schema instanceof z.ZodObject) {
|
|
196
253
|
currentSchema = newParams.schema;
|
|
197
254
|
}
|
|
198
|
-
if (!currentSchema)
|
|
255
|
+
if (!currentSchema)
|
|
256
|
+
return void 0;
|
|
199
257
|
const segments = String(newParams.name).split(".");
|
|
200
258
|
for (const segment of segments) {
|
|
201
|
-
if (!currentSchema)
|
|
259
|
+
if (!currentSchema)
|
|
260
|
+
return void 0;
|
|
202
261
|
const unwrapped = getPrimitiveType(currentSchema);
|
|
203
262
|
if (unwrapped instanceof z.ZodObject) {
|
|
204
263
|
currentSchema = getShapeField2(unwrapped, segment);
|
|
@@ -223,6 +282,6 @@ function extendWithMeta(field, transform) {
|
|
|
223
282
|
return transformedField.meta(__spreadValues({}, meta));
|
|
224
283
|
}
|
|
225
284
|
|
|
226
|
-
export { canUnwrap, extendWithMeta, extractDefaultValue, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, isPipeWithZodInput, removeDefault, requiresValidInput, tryStripNullishOnly };
|
|
285
|
+
export { canUnwrap, extendWithMeta, extractCheck, extractDefaultValue, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, isPipeWithZodInput, removeDefault, requiresValidInput, tryStripNullishOnly };
|
|
227
286
|
//# sourceMappingURL=index.mjs.map
|
|
228
287
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/schema.ts","../src/discriminatedSchema.ts","../src/defaults.ts","../src/field.ts"],"names":["z","getShapeField"],"mappings":"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","file":"index.mjs","sourcesContent":["import { z } from 'zod';\nimport type {\n $ZodCheckBigIntFormatDef,\n $ZodCheckEndsWithDef,\n $ZodCheckGreaterThanDef,\n $ZodCheckIncludesDef,\n $ZodCheckLengthEqualsDef,\n $ZodCheckLessThanDef,\n $ZodCheckLowerCaseDef,\n $ZodCheckMaxLengthDef,\n $ZodCheckMaxSizeDef,\n $ZodCheckMimeTypeDef,\n $ZodCheckMinLengthDef,\n $ZodCheckMinSizeDef,\n $ZodCheckMultipleOfDef,\n $ZodCheckNumberFormatDef,\n $ZodCheckOverwriteDef,\n $ZodCheckPropertyDef,\n $ZodCheckRegexDef,\n $ZodCheckSizeEqualsDef,\n $ZodCheckStartsWithDef,\n $ZodCheckStringFormatDef,\n $ZodCheckUpperCaseDef,\n} from 'zod/v4/core';\n\n/**\n * Type representing a Zod type that has an unwrap method\n */\ntype Unwrappable = { unwrap: () => z.ZodTypeAny };\n\n/**\n * Type guard to check if a Zod field can be unwrapped (has wrapper types like optional, nullable, default).\n *\n * This checks whether a Zod type has an `unwrap()` method, which is present on wrapper types\n * like `ZodOptional`, `ZodNullable`, `ZodDefault`, and others.\n *\n * @param field - The Zod field to check\n * @returns True if the field has an unwrap method, false otherwise\n *\n * @example\n * ```typescript\n * const optionalField = z.string().optional();\n * console.log(canUnwrap(optionalField)); // true\n *\n * const plainField = z.string();\n * console.log(canUnwrap(plainField)); // false\n * ```\n *\n * @since 0.1.0\n */\nexport function canUnwrap(\n field: z.ZodTypeAny,\n): field is z.ZodTypeAny & Unwrappable {\n return 'unwrap' in field && typeof field.unwrap === 'function';\n}\n\n/**\n * Type guard that checks if a Zod field is a ZodPipe with a ZodType input.\n *\n * Used to safely access `field.def.in` on pipe types for unwrapping transformations.\n *\n * @param field - The Zod field to check\n * @returns True if field is a ZodPipe with a ZodType input\n */\nexport function isPipeWithZodInput(\n field: z.ZodTypeAny,\n): field is z.ZodPipe<z.ZodType, z.ZodTypeAny> {\n return field instanceof z.ZodPipe && field.def.in instanceof z.ZodType;\n}\n\n/**\n * Attempts to strip nullish types from a union and return the single remaining type.\n *\n * This function filters out `ZodNull` and `ZodUndefined` from union types. If exactly\n * one type remains after filtering, it returns that unwrapped type. Otherwise, it returns\n * `false` to indicate the union couldn't be simplified to a single type.\n *\n * @param field - The Zod field to process\n * @returns The unwrapped type if only one remains, otherwise `false`\n *\n * @example\n * Union with only nullish types filtered - returns single type\n * ```typescript\n * const field = z.union([z.string(), z.null(), z.undefined()]);\n * const result = tryStripNullishOnly(field);\n * // Result: z.string() (unwrapped)\n * ```\n *\n * @example\n * Union with multiple non-nullish types - returns false\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const result = tryStripNullishOnly(field);\n * // Result: false (cannot simplify to single type)\n * ```\n *\n * @example\n * Non-union type - returns false\n * ```typescript\n * const field = z.string();\n * const result = tryStripNullishOnly(field);\n * // Result: false (not a union)\n * ```\n *\n * @see {@link getPrimitiveType} for unwrapping wrapper types\n * @since 0.5.0\n */\nexport function tryStripNullishOnly(field: z.ZodTypeAny): z.ZodType | false {\n if (field instanceof z.ZodUnion) {\n const unionOptions = [...field.def.options];\n\n const filteredOptions = unionOptions.filter(\n (option): option is z.ZodType =>\n !(option instanceof z.ZodNull) && !(option instanceof z.ZodUndefined),\n );\n\n // If exactly one option remains, return it unwrapped\n const firstOption = filteredOptions[0];\n if (firstOption && filteredOptions.length === 1) {\n return firstOption;\n }\n }\n\n // Not a union, or couldn't simplify to single type\n return false;\n}\n\n/**\n * Gets the underlying primitive type of a Zod field by recursively unwrapping wrapper types.\n *\n * This function removes wrapper layers (optional, nullable, default) to reveal the base type.\n * **Important:** It stops at array types without unwrapping them, treating arrays as primitives.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one\n * type remains after stripping, unwraps to that type. If multiple non-nullish types remain,\n * returns the union as-is (does not unwrap).\n *\n * @template T - The Zod type to unwrap\n * @param field - The Zod field to unwrap\n * @returns The unwrapped primitive Zod type\n *\n * @example\n * Unwrapping to string primitive\n * ```typescript\n * const field = z.string().optional().nullable();\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (unwrapped all wrappers)\n * ```\n *\n * @example\n * Stopping at array type\n * ```typescript\n * const field = z.array(z.string()).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.array(z.string()) (stops at array, doesn't unwrap it)\n * ```\n *\n * @example\n * Unwrapping defaults\n * ```typescript\n * const field = z.number().default(0).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.number()\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string(), z.null()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.union([z.string(), z.number()]) (returned as-is)\n * ```\n *\n * @see {@link canUnwrap} for checking if a field can be unwrapped\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport const getPrimitiveType = <T extends z.ZodType>(\n field: T,\n): z.ZodTypeAny => {\n // Stop at arrays - don't unwrap them\n if (field instanceof z.ZodArray) {\n return field;\n }\n\n if (canUnwrap(field)) {\n return getPrimitiveType(field.unwrap());\n }\n\n if (field instanceof z.ZodDiscriminatedUnion) {\n return field;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n return getPrimitiveType(unwrapped);\n }\n\n // Multiple non-nullish types or all nullish - return union as-is\n return field;\n }\n\n if (isPipeWithZodInput(field)) {\n return getPrimitiveType(field.def.in);\n }\n\n return field;\n};\n\ntype StripZodDefault<T> = T extends z.ZodDefault<infer Inner>\n ? StripZodDefault<Inner>\n : T extends z.ZodOptional<infer Inner>\n ? z.ZodOptional<StripZodDefault<Inner>>\n : T extends z.ZodNullable<infer Inner>\n ? z.ZodNullable<StripZodDefault<Inner>>\n : T;\n\n/**\n * Removes default values from a Zod field while preserving other wrapper types.\n *\n * This function recursively removes `ZodDefault` wrappers from a field, while maintaining\n * `optional()` and `nullable()` wrappers. Useful for scenarios where you want to check\n * field requirements without considering default values.\n *\n * @template T - The Zod type to process\n * @param field - The Zod field to remove defaults from\n * @returns The field without defaults but with optional/nullable preserved\n *\n * @example\n * Removing simple default\n * ```typescript\n * const field = z.string().default('hello');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string()\n * ```\n *\n * @example\n * Preserving optional wrapper\n * ```typescript\n * const field = z.string().default('hello').optional();\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().optional()\n * ```\n *\n * @example\n * Nested defaults\n * ```typescript\n * const field = z.string().default('inner').nullable().default('outer');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().nullable()\n * ```\n *\n * @see {@link requiresValidInput} for usage with requirement checking\n * @since 0.1.0\n */\nexport function removeDefault<T extends z.ZodType>(\n field: T,\n): StripZodDefault<T> {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.unwrap() as StripZodDefault<T>;\n }\n\n if ('innerType' in field.def && field.def.innerType instanceof z.ZodType) {\n const inner = removeDefault(field.def.innerType);\n // Reconstruct the wrapper with the modified inner type\n if (field instanceof z.ZodOptional) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.optional() as unknown as StripZodDefault<T>;\n }\n if (field instanceof z.ZodNullable) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.nullable() as unknown as StripZodDefault<T>;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field as StripZodDefault<T>;\n}\n\n/**\n * Determines if a field will show validation errors when the user submits empty or invalid input.\n *\n * This is useful for form UIs to indicate which fields require valid user input (e.g., showing\n * asterisks, validation states). The key insight: **defaults are just initial values** - they\n * don't prevent validation errors if the user clears the field.\n *\n * **Real-world example:**\n * ```typescript\n * // Marital status field with default but validation rules\n * const maritalStatus = z.string().min(1).default('single');\n *\n * // Initial: field shows \"single\" (from default)\n * // User deletes the value → field is now empty string\n * // User submits form → validation fails because .min(1) rejects empty strings\n * // requiresValidInput(maritalStatus) → true (shows * indicator, validation error)\n * ```\n *\n * **How it works:**\n * 1. Removes `.default()` wrappers (defaults are initial values, not validation rules)\n * 2. Tests if the underlying schema accepts empty/invalid input:\n * - `undefined` (via `.optional()`)\n * - `null` (via `.nullable()`)\n * - Empty string (plain `z.string()` without `.min(1)` or `.nonempty()`)\n * - Empty array (plain `z.array()` without `.min(1)` or `.nonempty()`)\n * 3. Returns `true` if validation will fail, `false` if empty input is accepted\n *\n * @template T - The Zod type to check\n * @param field - The Zod field to check\n * @returns True if the field will show validation errors on empty/invalid input, false otherwise\n *\n * @example\n * User name field - required, no default\n * ```typescript\n * const userName = z.string().min(1);\n * requiresValidInput(userName); // true - will error if user submits empty\n * ```\n *\n * @example\n * Marital status - required WITH default\n * ```typescript\n * const maritalStatus = z.string().min(1).default('single');\n * requiresValidInput(maritalStatus); // true - will error if user clears and submits\n * ```\n *\n * @example\n * Age with default - requires valid input\n * ```typescript\n * const age = z.number().default(0);\n * requiresValidInput(age); // true - numbers reject empty strings\n * ```\n *\n * @example\n * Optional bio field - doesn't require input\n * ```typescript\n * const bio = z.string().optional();\n * requiresValidInput(bio); // false - user can leave empty\n * ```\n *\n * @example\n * String with default but NO validation - doesn't require input\n * ```typescript\n * const notes = z.string().default('N/A');\n * requiresValidInput(notes); // false - plain z.string() accepts empty strings\n * ```\n *\n * @example\n * Nullable field - doesn't require input\n * ```typescript\n * const middleName = z.string().nullable();\n * requiresValidInput(middleName); // false - user can leave null\n * ```\n *\n * @see {@link removeDefault} for understanding how defaults are handled\n * @see {@link getPrimitiveType} for understanding type unwrapping\n * @since 0.1.0\n */\nexport const requiresValidInput = <T extends z.ZodType>(field: T) => {\n const defaultRemovedField = removeDefault(field);\n if (!(defaultRemovedField instanceof z.ZodType)) {\n return false;\n }\n\n const undefinedResult = defaultRemovedField.safeParse(undefined).success;\n\n // Check if field accepts null (nullable)\n const nullResult = defaultRemovedField.safeParse(null).success;\n\n const primitiveType = getPrimitiveType(defaultRemovedField);\n\n const emptyStringResult =\n primitiveType.type === 'string' &&\n defaultRemovedField.safeParse('').success;\n\n const emptyArrayResult =\n primitiveType.type === 'array' && defaultRemovedField.safeParse([]).success;\n\n return (\n !undefinedResult && !nullResult && !emptyStringResult && !emptyArrayResult\n );\n};\n\n/**\n * Union type of all Zod check definition types.\n *\n * Includes all validation check types supported by Zod v4:\n * - **Length checks**: `min_length`, `max_length`, `length_equals` (strings, arrays)\n * - **Size checks**: `min_size`, `max_size`, `size_equals` (files, sets, maps)\n * - **Numeric checks**: `greater_than`, `less_than`, `multiple_of`\n * - **Format checks**: `number_format` (int32, float64, etc.), `bigint_format`, `string_format` (email, url, uuid, etc.)\n * - **String pattern checks**: `regex`, `lowercase`, `uppercase`, `includes`, `starts_with`, `ends_with`\n * - **Other checks**: `property`, `mime_type`, `overwrite`\n *\n * @since 0.4.0\n */\nexport type ZodUnionCheck =\n | $ZodCheckLessThanDef\n | $ZodCheckGreaterThanDef\n | $ZodCheckMultipleOfDef\n | $ZodCheckNumberFormatDef\n | $ZodCheckBigIntFormatDef\n | $ZodCheckMaxSizeDef\n | $ZodCheckMinSizeDef\n | $ZodCheckSizeEqualsDef\n | $ZodCheckMaxLengthDef\n | $ZodCheckMinLengthDef\n | $ZodCheckLengthEqualsDef\n | $ZodCheckStringFormatDef\n | $ZodCheckRegexDef\n | $ZodCheckLowerCaseDef\n | $ZodCheckUpperCaseDef\n | $ZodCheckIncludesDef\n | $ZodCheckStartsWithDef\n | $ZodCheckEndsWithDef\n | $ZodCheckPropertyDef\n | $ZodCheckMimeTypeDef\n | $ZodCheckOverwriteDef;\n\n/**\n * Extracts all validation check definitions from a Zod schema field.\n *\n * This function analyzes a Zod field and returns all check definitions as defined\n * by Zod's internal structure. Returns Zod's raw check definition objects directly,\n * including all properties like `check`, `minimum`, `maximum`, `value`, `inclusive`,\n * `format`, `pattern`, etc.\n *\n * **Unwrapping behavior:** Automatically unwraps optional, nullable, and default layers.\n * For unions, checks only the first option (same as other schema utilities).\n *\n * **Supported check types:** Returns any of the 21 check types defined in {@link ZodUnionCheck},\n * including length, size, numeric range, format validation, string patterns, and more.\n *\n * @template T - The Zod type to extract checks from\n * @param field - The Zod field to analyze\n * @returns Array of Zod check definition objects (see {@link ZodUnionCheck})\n *\n * @example\n * String with length constraints\n * ```typescript\n * const username = z.string().min(3).max(20);\n * const checks = getFieldChecks(username);\n * // [\n * // { check: 'min_length', minimum: 3, when: [Function], ... },\n * // { check: 'max_length', maximum: 20, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Number with range constraints\n * ```typescript\n * const age = z.number().min(18).max(120);\n * const checks = getFieldChecks(age);\n * // [\n * // { check: 'greater_than', value: 18, inclusive: true, when: [Function], ... },\n * // { check: 'less_than', value: 120, inclusive: true, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Array with item count constraints\n * ```typescript\n * const tags = z.array(z.string()).min(1).max(5);\n * const checks = getFieldChecks(tags);\n * // [\n * // { check: 'min_length', minimum: 1, ... },\n * // { check: 'max_length', maximum: 5, ... }\n * // ]\n * ```\n *\n * @example\n * String with format validation\n * ```typescript\n * const email = z.string().email();\n * const checks = getFieldChecks(email);\n * // [\n * // { check: 'string_format', format: 'email', ... }\n * // ]\n * ```\n *\n * @example\n * Unwrapping optional/nullable/default layers\n * ```typescript\n * const bio = z.string().min(10).max(500).optional();\n * const checks = getFieldChecks(bio);\n * // [\n * // { check: 'min_length', minimum: 10, ... },\n * // { check: 'max_length', maximum: 500, ... }\n * // ]\n * ```\n *\n * @see {@link ZodUnionCheck} for all supported check types\n * @since 0.4.0\n */\nexport function getFieldChecks<T extends z.ZodTypeAny>(\n field: T,\n): Array<ZodUnionCheck> {\n const primitiveType = getPrimitiveType(field);\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return (primitiveType.def.checks?.map((check) => check._zod.def) ||\n []) as Array<ZodUnionCheck>;\n}\n","import { type util, z } from 'zod';\nimport type { $InferUnionInput } from 'zod/v4/core';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n/**\n * Recursively extracts the exact schema type from a discriminated union based on the discriminator value.\n *\n * This advanced TypeScript utility type walks through a union's options tuple at compile-time,\n * checking each schema against the discriminator field and value, and returns the exact matching\n * schema type (not a union of all options).\n *\n * **How it works:**\n * 1. Extracts the options tuple from the union using `infer Options`\n * 2. Destructure into head (`First`) and tail (`Rest`) using tuple pattern matching\n * 3. Checks if `First` is a ZodObject with the matching discriminator field and value\n * 4. If match found, returns `First` (the exact schema type)\n * 5. If no match, recursively processes `Rest` until a match is found or list is exhausted\n *\n * **Type narrowing magic:**\n * - Input: `z.discriminatedUnion('type', [SchemaA, SchemaB, SchemaC])`\n * - Discriminator value: `'a'` (matches SchemaA)\n * - Output: `SchemaA` (exact type, not `SchemaA | SchemaB | SchemaC`)\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion type\n * @template TDiscriminatorKey - The discriminator field name (e.g., \"type\", \"mode\")\n * @template TDiscriminatorValue - The specific discriminator value (e.g., \"create\", \"edit\")\n * @returns The exact matching schema type, or `never` if no match found\n *\n * @example\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * z.object({ mode: z.literal('edit'), id: z.number() }),\n * ]);\n *\n * // Exact type: z.object({ mode: z.literal('create'), name: z.string() })\n * type CreateSchema = ExtractZodUnionMember<typeof schema, 'mode', 'create'>;\n * ```\n */\ntype ExtractZodUnionMember<\n TSchema extends z.ZodUnion | z.ZodDiscriminatedUnion,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends z.input<TSchema>[TDiscriminatorKey] &\n util.Literal,\n> = TSchema extends z.ZodUnion<infer Options>\n ? Options extends readonly [\n infer First extends z.ZodTypeAny,\n ...infer Rest extends z.ZodTypeAny[],\n ]\n ? First extends z.ZodObject<infer Shape>\n ? TDiscriminatorKey extends keyof Shape\n ? Shape[TDiscriminatorKey] extends\n | z.ZodLiteral<TDiscriminatorValue>\n | z.ZodDefault<z.ZodLiteral<TDiscriminatorValue>>\n ? First\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : never\n : never\n : never;\n\n/**\n * Extracts a specific schema option from a discriminated union based on the discriminator field value.\n *\n * This function finds and returns the **exact matching schema** from a `ZodDiscriminatedUnion` by\n * comparing the discriminator field value. It's used internally by {@link getSchemaDefaults} to\n * extract defaults from the correct schema variant in a discriminated union.\n *\n * **Key feature:** Returns the **exact schema type**, not a union of all options, thanks to the\n * {@link ExtractZodUnionMember} recursive type utility. This enables precise type narrowing at\n * compile-time based on the discriminator value.\n *\n * **How it works:**\n * 1. Iterates through all options in the discriminated union at runtime\n * 2. For each option, validates it's a ZodObject and checks if the discriminator field matches\n * 3. Returns the first matching schema with its exact type narrowed at compile-time\n * 4. Returns `undefined` if no match found or if option is not a ZodObject\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion schema type\n * @template TDiscriminatorKey - The discriminator field name (string key of the inferred union type)\n * @template TDiscriminatorValue - The specific discriminator value to match (literal type)\n * @param params - Parameters object\n * @param params.schema - The discriminated union schema to search\n * @param params.discriminatorKey - The discriminator field name (e.g., \"mode\", \"type\")\n * @param params.discriminatorValue - The discriminator value to match (e.g., \"create\", \"edit\")\n * @returns The exact matching schema option (with precise type), or `undefined` if not found or schema is not a discriminated union\n *\n * @example\n * Basic discriminated union - create/edit mode\n * ```typescript\n * const userSchema = z.discriminatedUnion('mode', [\n * z.object({\n * mode: z.literal('create'),\n * name: z.string(),\n * age: z.number().optional(),\n * }),\n * z.object({\n * mode: z.literal('edit'),\n * id: z.number(),\n * name: z.string().optional(),\n * }),\n * ]);\n *\n * // Extract the \"create\" schema\n * const createSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n * // Result: z.object({ mode: z.literal('create'), name: z.string(), age: z.number().optional() })\n *\n * // Extract the \"edit\" schema\n * const editSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'edit' },\n * });\n * // Result: z.object({ mode: z.literal('edit'), id: z.number(), name: z.string().optional() })\n * ```\n *\n * @example\n * Type-based discrimination\n * ```typescript\n * const eventSchema = z.discriminatedUnion('type', [\n * z.object({ type: z.literal('click'), x: z.number(), y: z.number() }),\n * z.object({ type: z.literal('keypress'), key: z.string() }),\n * ]);\n *\n * const clickSchema = extractDiscriminatedSchema({\n * schema: eventSchema,\n * discriminator: { key: 'type', value: 'click' },\n * });\n * // Result: z.object({ type: z.literal('click'), x: z.number(), y: z.number() })\n * ```\n *\n * @example\n * Invalid discriminator value\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * ]);\n *\n * const result = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'invalid' }, // doesn't match any option\n * });\n * // Result: undefined\n * ```\n *\n * @example\n * Type narrowing demonstration\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string(), age: z.number() }),\n * z.object({ mode: z.literal('edit'), id: z.number(), bio: z.string() }),\n * ]);\n *\n * const createSchema = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n *\n * // Type is EXACTLY: z.object({ mode: z.literal('create'), name: z.string(), age: z.number() })\n * // NOT: z.object({ mode: ..., ... }) | z.object({ mode: ..., ... }) | undefined\n *\n * if (createSchema) {\n * createSchema.shape.age; // ✅ TypeScript knows 'age' exists\n * createSchema.shape.name; // ✅ TypeScript knows 'name' exists\n * // createSchema.shape.id; // ❌ TypeScript error: 'id' doesn't exist on 'create' schema\n * }\n * ```\n *\n * @see {@link getSchemaDefaults} for usage with discriminated unions\n * @see {@link ExtractZodUnionMember} for the type-level extraction logic\n * @since 0.6.0\n */\nexport const extractDiscriminatedSchema = <\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n ReturnType extends TSchema extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<TSchema, TDiscriminatorKey, TDiscriminatorValue>\n : never,\n>({\n schema,\n discriminator,\n}: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n>): ReturnType | undefined => {\n const primitiveSchema = getPrimitiveType(schema);\n\n if (!(primitiveSchema instanceof z.ZodDiscriminatedUnion) || !discriminator) {\n return undefined;\n }\n\n const { key, value } = discriminator;\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return primitiveSchema.options.find((option) => {\n if (option instanceof z.ZodObject) {\n const targetField = getShapeField(option, String(key));\n if (!targetField) return false;\n\n const parseResult = targetField.safeParse(value);\n return parseResult.success;\n }\n return false;\n }) as ReturnType;\n};\n","import * as z from 'zod';\nimport { extractDiscriminatedSchema } from './discriminatedSchema';\nimport {\n canUnwrap,\n getPrimitiveType,\n isPipeWithZodInput,\n tryStripNullishOnly,\n} from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n Simplify,\n} from './types';\n\n/**\n * Type-safe helper to iterate over ZodObject shape entries.\n * @internal\n */\nfunction getShapeEntries(\n schema: z.ZodObject,\n): Array<[string, z.ZodType | undefined]> {\n return Object.entries(schema.shape);\n}\n\n/**\n * Extracts the default value from a Zod field, recursively unwrapping optional, nullable, and union layers.\n *\n * This function traverses through wrapper types (like `ZodOptional`, `ZodNullable`, `ZodUnion`) to find\n * the underlying `ZodDefault` and returns its default value. If no default is found, returns `undefined`.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one type\n * remains after stripping, extracts the default from that type. If multiple non-nullish types remain,\n * returns `undefined` (does not extract from any option).\n *\n * @template T - The Zod type to extract default from\n * @param field - The Zod field to extract default from\n * @returns The default value if present, undefined otherwise\n *\n * @example\n * Basic usage with default value\n * ```typescript\n * const field = z.string().default('hello');\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello'\n * ```\n *\n * @example\n * Unwrapping optional/nullable layers\n * ```typescript\n * const field = z.string().default('world').optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'world' (unwraps optional to find default)\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.null()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello' (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.number()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined (multiple non-nullish types - no default extracted)\n * ```\n *\n * @example\n * Field without default\n * ```typescript\n * const field = z.string().optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined\n * ```\n *\n * @see {@link getSchemaDefaults} for extracting defaults from entire schemas\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport function extractDefaultValue<T extends z.ZodType>(\n field: T,\n): z.input<T> | undefined {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.def.defaultValue as z.input<T>;\n }\n\n if (canUnwrap(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.unwrap()) as z.input<T>;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n // Successfully unwrapped to single type\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(unwrapped) as z.input<T>;\n }\n\n // Multiple non-nullish types or all nullish - no default\n return undefined;\n }\n\n if (isPipeWithZodInput(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.def.in) as z.input<T>;\n }\n\n // Recursively extract defaults from nested objects\n if (field instanceof z.ZodObject) {\n const nestedDefaults: Record<string, unknown> = {};\n let hasAnyDefault = false;\n\n for (const [key, nestedField] of getShapeEntries(field)) {\n if (!nestedField) continue;\n\n const nestedDefault = extractDefaultValue(nestedField);\n if (nestedDefault !== undefined) {\n nestedDefaults[key] = nestedDefault;\n hasAnyDefault = true;\n }\n }\n\n if (hasAnyDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return nestedDefaults as z.input<T>;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts default values from a Zod object schema, returning only fields with explicit `.default()`.\n *\n * This function traverses the schema and collects fields that have explicit default values.\n * Fields without defaults are excluded from the result.\n *\n * **Important:** Nested defaults are NOT extracted unless the parent object also has\n * an explicit `.default()`. This is by design to match Zod's default value behavior.\n *\n * **Component handling:** For form inputs without explicit defaults (like `z.string()` or `z.number()`),\n * use the `?? ''` pattern in your components: `<Input value={field.value ?? ''} />`\n *\n * @template TSchema - The Zod object schema type\n * @param targetSchema - The Zod object schema to extract defaults from\n * @returns A partial object containing only fields with explicit default values\n *\n * @example\n * Basic usage - only explicit defaults\n * ```typescript\n * const schema = z.object({\n * name: z.string(), // no default → NOT included\n * age: z.number(), // no default → NOT included\n * role: z.string().default('user'), // explicit default → included\n * count: z.number().default(0), // explicit default → included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { role: 'user', count: 0 }\n * ```\n *\n * @example\n * Nested objects with defaults\n * ```typescript\n * const schema = z.object({\n * user: z.object({\n * name: z.string().default('Guest')\n * }).default({ name: 'Guest' }), // ✅ Extracted because parent has .default()\n *\n * settings: z.object({\n * theme: z.string().default('light')\n * }), // ❌ NOT extracted - parent has no .default()\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { user: { name: 'Guest' } }\n * ```\n *\n * @example\n * Unwrapping optional/nullable fields\n * ```typescript\n * const schema = z.object({\n * title: z.string().default('Untitled').optional(),\n * count: z.number().default(0).nullable(),\n * name: z.string().optional(), // no default → NOT included\n * age: z.number().optional(), // no default → NOT included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { title: 'Untitled', count: 0 }\n * ```\n *\n * @example\n * Component usage for fields without defaults\n * ```typescript\n * // For string/number fields without defaults, handle in components:\n * <Input value={field.value ?? ''} />\n * <Input type=\"number\" value={field.value ?? ''} />\n * ```\n *\n * @see {@link extractDefaultValue} for extracting defaults from individual fields\n * @since 0.1.0\n */\nexport function getSchemaDefaults<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n>(\n params: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n >,\n): Simplify<Partial<z.input<TSchema>>> {\n const primitiveSchemaParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n let targetSchema: z.ZodObject | undefined;\n if (primitiveSchemaParams.schema instanceof z.ZodDiscriminatedUnion) {\n targetSchema = extractDiscriminatedSchema(primitiveSchemaParams);\n } else if (primitiveSchemaParams.schema instanceof z.ZodObject) {\n targetSchema = primitiveSchemaParams.schema;\n }\n\n const defaults: Record<string, unknown> = {};\n\n if (targetSchema) {\n for (const [key, field] of getShapeEntries(targetSchema)) {\n if (!field) continue;\n\n const defaultValue = extractDefaultValue(field);\n if (defaultValue !== undefined) {\n defaults[key] = defaultValue;\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return defaults as Partial<z.input<TSchema>>;\n}\n","import { z } from 'zod';\nimport { extractDiscriminatedSchema } from './discriminatedSchema';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n FieldSelectorProps,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n// Split 'a.b.c' into ['a', 'b', 'c']\ntype Split<S extends string> = S extends `${infer Head}.${infer Tail}`\n ? [Head, ...Split<Tail>]\n : [S];\n\n// Check if string is numeric\ntype IsNumeric<S extends string> = S extends `${number}` ? true : false;\n\n// Unwrap ZodOptional, ZodNullable, ZodDefault\ntype Unwrap<T> = T extends z.ZodOptional<infer U>\n ? Unwrap<U>\n : T extends z.ZodNullable<infer U>\n ? Unwrap<U>\n : T extends z.ZodDefault<infer U>\n ? Unwrap<U>\n : T;\n\n// Navigate Zod schema by path array\ntype NavigateZod<T, Path extends string[]> = Path extends [\n infer First extends string,\n ...infer Rest extends string[],\n]\n ? Unwrap<T> extends z.ZodObject<infer Shape>\n ? First extends keyof Shape\n ? Rest extends []\n ? Shape[First]\n : NavigateZod<Shape[First], Rest>\n : never\n : Unwrap<T> extends z.ZodArray<infer Element>\n ? IsNumeric<First> extends true\n ? Rest extends []\n ? Element\n : NavigateZod<Element, Rest>\n : never\n : never\n : T;\n\nexport type ExtractZodByPath<Schema, Path extends string> = NavigateZod<\n Schema,\n Split<Path>\n>;\n\nexport function extractFieldFromSchema<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema> = never,\n TDiscriminatorValue extends DiscriminatorValue<\n TSchema,\n TDiscriminatorKey\n > = never,\n TFilterType = unknown,\n TStrict extends boolean = true,\n TName extends string = string,\n>(\n params: FieldSelectorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue,\n TFilterType,\n TStrict\n > & { name: TName },\n): (ExtractZodByPath<TSchema, TName> & z.ZodType) | undefined {\n let currentSchema: z.ZodType | undefined;\n\n const newParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n if (newParams.schema instanceof z.ZodDiscriminatedUnion) {\n if (newParams.discriminator) {\n currentSchema = extractDiscriminatedSchema(newParams);\n }\n } else if (newParams.schema instanceof z.ZodObject) {\n currentSchema = newParams.schema;\n }\n\n if (!currentSchema) return undefined;\n\n // Split name into segments (e.g., \"contact.email\" -> [\"contact\", \"email\"])\n const segments = String(newParams.name).split('.');\n\n for (const segment of segments) {\n if (!currentSchema) return undefined;\n\n const unwrapped: z.ZodType = getPrimitiveType(currentSchema);\n\n if (unwrapped instanceof z.ZodObject) {\n currentSchema = getShapeField(unwrapped, segment);\n } else if (unwrapped instanceof z.ZodArray) {\n // Arrays are keyed by integers only\n if (/^\\d+$/.test(segment) && unwrapped.element instanceof z.ZodType) {\n currentSchema = unwrapped.element;\n } else {\n return undefined;\n }\n } else {\n return undefined;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return currentSchema as\n | (ExtractZodByPath<TSchema, TName> & z.ZodType)\n | undefined;\n}\n\n/**\n * Extends a Zod field with a transformation while preserving its metadata.\n *\n * This is useful when you want to add validations or transformations to a field\n * but keep the original metadata (like translationKey) intact.\n *\n * @param field - The original Zod field\n * @param transform - A function that transforms the field\n * @returns The transformed field with preserved metadata\n *\n * @example\n * ```typescript\n * const baseField = z.string().meta({ translationKey: 'user.field.name' });\n *\n * // Add min/max validation while keeping the translationKey\n * const extendedField = extendWithMeta(baseField, (f) => f.min(3).max(100));\n * extendedField.meta(); // { translationKey: 'user.field.name' }\n * ```\n */\nexport function extendWithMeta<T extends z.ZodType, R extends z.ZodType>(\n field: T,\n transform: (f: T) => R,\n): R {\n const transformedField = transform(field);\n const meta = field.meta();\n if (!meta) {\n return transformedField;\n }\n return transformedField.meta({ ...meta });\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/schema.ts","../src/discriminatedSchema.ts","../src/defaults.ts","../src/field.ts"],"names":["allChecks","z","getShapeField"],"mappings":"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","file":"index.mjs","sourcesContent":["import { ZodStringFormat, z } from 'zod';\nimport {\n // $ZodCheckBigIntFormat,\n // type $ZodCheckBigIntFormatDef,\n $ZodCheckEndsWith,\n type $ZodCheckEndsWithDef,\n $ZodCheckGreaterThan,\n type $ZodCheckGreaterThanDef,\n $ZodCheckIncludes,\n type $ZodCheckIncludesDef,\n $ZodCheckLengthEquals,\n type $ZodCheckLengthEqualsDef,\n $ZodCheckLessThan,\n type $ZodCheckLessThanDef,\n // $ZodCheckLowerCase,\n // type $ZodCheckLowerCaseDef,\n $ZodCheckMaxLength,\n type $ZodCheckMaxLengthDef,\n $ZodCheckMaxSize,\n type $ZodCheckMaxSizeDef,\n $ZodCheckMimeType,\n type $ZodCheckMimeTypeDef,\n $ZodCheckMinLength,\n type $ZodCheckMinLengthDef,\n $ZodCheckMinSize,\n type $ZodCheckMinSizeDef,\n $ZodCheckMultipleOf,\n type $ZodCheckMultipleOfDef,\n $ZodCheckNumberFormat,\n type $ZodCheckNumberFormatDef,\n $ZodCheckOverwrite,\n type $ZodCheckOverwriteDef,\n $ZodCheckRegex,\n type $ZodCheckRegexDef,\n $ZodCheckSizeEquals,\n type $ZodCheckSizeEqualsDef,\n $ZodCheckStartsWith,\n type $ZodCheckStartsWithDef,\n $ZodCheckStringFormat,\n type $ZodCheckStringFormatDef,\n // $ZodCheckUpperCase,\n // type $ZodCheckUpperCaseDef,\n type $ZodType,\n} from 'zod/v4/core';\n\n/**\n * Type representing a Zod type that has an unwrap method\n */\ntype Unwrappable = { unwrap: () => z.ZodTypeAny };\n\n/**\n * Type guard to check if a Zod field can be unwrapped (has wrapper types like optional, nullable, default).\n *\n * This checks whether a Zod type has an `unwrap()` method, which is present on wrapper types\n * like `ZodOptional`, `ZodNullable`, `ZodDefault`, and others.\n *\n * @param field - The Zod field to check\n * @returns True if the field has an unwrap method, false otherwise\n *\n * @example\n * ```typescript\n * const optionalField = z.string().optional();\n * console.log(canUnwrap(optionalField)); // true\n *\n * const plainField = z.string();\n * console.log(canUnwrap(plainField)); // false\n * ```\n *\n * @since 0.1.0\n */\nexport function canUnwrap(\n field: z.ZodType | $ZodType,\n): field is (z.ZodType | $ZodType) & Unwrappable {\n return 'unwrap' in field && typeof field.unwrap === 'function';\n}\n\n/**\n * Type guard that checks if a Zod field is a ZodPipe with a ZodType input.\n *\n * Used to safely access `field.def.in` on pipe types for unwrapping transformations.\n *\n * @param field - The Zod field to check\n * @returns True if field is a ZodPipe with a ZodType input\n */\nexport function isPipeWithZodInput(\n field: z.ZodType | $ZodType,\n): field is z.ZodPipe<z.ZodType, z.ZodTypeAny> {\n return field instanceof z.ZodPipe && field.def.in instanceof z.ZodType;\n}\n\n/**\n * Attempts to strip nullish types from a union and return the single remaining type.\n *\n * This function filters out `ZodNull` and `ZodUndefined` from union types. If exactly\n * one type remains after filtering, it returns that unwrapped type. Otherwise, it returns\n * `false` to indicate the union couldn't be simplified to a single type.\n *\n * @param field - The Zod field to process\n * @returns The unwrapped type if only one remains, otherwise `false`\n *\n * @example\n * Union with only nullish types filtered - returns single type\n * ```typescript\n * const field = z.union([z.string(), z.null(), z.undefined()]);\n * const result = tryStripNullishOnly(field);\n * // Result: z.string() (unwrapped)\n * ```\n *\n * @example\n * Union with multiple non-nullish types - returns false\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const result = tryStripNullishOnly(field);\n * // Result: false (cannot simplify to single type)\n * ```\n *\n * @example\n * Non-union type - returns false\n * ```typescript\n * const field = z.string();\n * const result = tryStripNullishOnly(field);\n * // Result: false (not a union)\n * ```\n *\n * @see {@link getPrimitiveType} for unwrapping wrapper types\n * @since 0.5.0\n */\nexport function tryStripNullishOnly(field: z.ZodTypeAny): z.ZodType | false {\n if (field instanceof z.ZodUnion) {\n const unionOptions = [...field.def.options];\n\n const filteredOptions = unionOptions.filter(\n (option): option is z.ZodType =>\n !(option instanceof z.ZodNull) && !(option instanceof z.ZodUndefined),\n );\n\n // If exactly one option remains, return it unwrapped\n const firstOption = filteredOptions[0];\n if (firstOption && filteredOptions.length === 1) {\n return firstOption;\n }\n }\n\n // Not a union, or couldn't simplify to single type\n return false;\n}\n\n/**\n * Gets the underlying primitive type of a Zod field by recursively unwrapping wrapper types.\n *\n * This function removes wrapper layers (optional, nullable, default) to reveal the base type.\n * **Important:** It stops at array types without unwrapping them, treating arrays as primitives.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one\n * type remains after stripping, unwraps to that type. If multiple non-nullish types remain,\n * returns the union as-is (does not unwrap).\n *\n * @template T - The Zod type to unwrap\n * @param field - The Zod field to unwrap\n * @returns The unwrapped primitive Zod type\n *\n * @example\n * Unwrapping to string primitive\n * ```typescript\n * const field = z.string().optional().nullable();\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (unwrapped all wrappers)\n * ```\n *\n * @example\n * Stopping at array type\n * ```typescript\n * const field = z.array(z.string()).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.array(z.string()) (stops at array, doesn't unwrap it)\n * ```\n *\n * @example\n * Unwrapping defaults\n * ```typescript\n * const field = z.number().default(0).optional();\n * const primitive = getPrimitiveType(field);\n * // Result: z.number()\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string(), z.null()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.string() (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string(), z.number()]);\n * const primitive = getPrimitiveType(field);\n * // Result: z.union([z.string(), z.number()]) (returned as-is)\n * ```\n *\n * @see {@link canUnwrap} for checking if a field can be unwrapped\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport const getPrimitiveType = <T extends z.ZodType>(field: T): z.ZodType => {\n // Stop at arrays - don't unwrap them\n if (field instanceof z.ZodArray) {\n return field;\n }\n\n if (canUnwrap(field)) {\n return getPrimitiveType(field.unwrap());\n }\n\n if (field instanceof z.ZodDiscriminatedUnion) {\n return field;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n return getPrimitiveType(unwrapped);\n }\n\n // Multiple non-nullish types or all nullish - return union as-is\n return field;\n }\n\n if (isPipeWithZodInput(field)) {\n return getPrimitiveType(field.def.in);\n }\n\n return field;\n};\n\ntype StripZodDefault<T> = T extends z.ZodDefault<infer Inner>\n ? StripZodDefault<Inner>\n : T extends z.ZodOptional<infer Inner>\n ? z.ZodOptional<StripZodDefault<Inner>>\n : T extends z.ZodNullable<infer Inner>\n ? z.ZodNullable<StripZodDefault<Inner>>\n : T;\n\n/**\n * Removes default values from a Zod field while preserving other wrapper types.\n *\n * This function recursively removes `ZodDefault` wrappers from a field, while maintaining\n * `optional()` and `nullable()` wrappers. Useful for scenarios where you want to check\n * field requirements without considering default values.\n *\n * @template T - The Zod type to process\n * @param field - The Zod field to remove defaults from\n * @returns The field without defaults but with optional/nullable preserved\n *\n * @example\n * Removing simple default\n * ```typescript\n * const field = z.string().default('hello');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string()\n * ```\n *\n * @example\n * Preserving optional wrapper\n * ```typescript\n * const field = z.string().default('hello').optional();\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().optional()\n * ```\n *\n * @example\n * Nested defaults\n * ```typescript\n * const field = z.string().default('inner').nullable().default('outer');\n * const withoutDefault = removeDefault(field);\n * // Result: z.string().nullable()\n * ```\n *\n * @see {@link requiresValidInput} for usage with requirement checking\n * @since 0.1.0\n */\nexport function removeDefault<T extends z.ZodType>(\n field: T,\n): StripZodDefault<T> {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.unwrap() as StripZodDefault<T>;\n }\n\n if ('innerType' in field.def && field.def.innerType instanceof z.ZodType) {\n const inner = removeDefault(field.def.innerType);\n // Reconstruct the wrapper with the modified inner type\n if (field instanceof z.ZodOptional) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.optional() as unknown as StripZodDefault<T>;\n }\n if (field instanceof z.ZodNullable) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return inner.nullable() as unknown as StripZodDefault<T>;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field as StripZodDefault<T>;\n}\n\n/**\n * Determines if a field will show validation errors when the user submits empty or invalid input.\n *\n * This is useful for form UIs to indicate which fields require valid user input (e.g., showing\n * asterisks, validation states). The key insight: **defaults are just initial values** - they\n * don't prevent validation errors if the user clears the field.\n *\n * **Real-world example:**\n * ```typescript\n * // Marital status field with default but validation rules\n * const maritalStatus = z.string().min(1).default('single');\n *\n * // Initial: field shows \"single\" (from default)\n * // User deletes the value → field is now empty string\n * // User submits form → validation fails because .min(1) rejects empty strings\n * // requiresValidInput(maritalStatus) → true (shows * indicator, validation error)\n * ```\n *\n * **How it works:**\n * 1. Removes `.default()` wrappers (defaults are initial values, not validation rules)\n * 2. Tests if the underlying schema accepts empty/invalid input:\n * - `undefined` (via `.optional()`)\n * - `null` (via `.nullable()`)\n * - Empty string (plain `z.string()` without `.min(1)` or `.nonempty()`)\n * - Empty array (plain `z.array()` without `.min(1)` or `.nonempty()`)\n * 3. Returns `true` if validation will fail, `false` if empty input is accepted\n *\n * @template T - The Zod type to check\n * @param field - The Zod field to check\n * @returns True if the field will show validation errors on empty/invalid input, false otherwise\n *\n * @example\n * User name field - required, no default\n * ```typescript\n * const userName = z.string().min(1);\n * requiresValidInput(userName); // true - will error if user submits empty\n * ```\n *\n * @example\n * Marital status - required WITH default\n * ```typescript\n * const maritalStatus = z.string().min(1).default('single');\n * requiresValidInput(maritalStatus); // true - will error if user clears and submits\n * ```\n *\n * @example\n * Age with default - requires valid input\n * ```typescript\n * const age = z.number().default(0);\n * requiresValidInput(age); // true - numbers reject empty strings\n * ```\n *\n * @example\n * Optional bio field - doesn't require input\n * ```typescript\n * const bio = z.string().optional();\n * requiresValidInput(bio); // false - user can leave empty\n * ```\n *\n * @example\n * String with default but NO validation - doesn't require input\n * ```typescript\n * const notes = z.string().default('N/A');\n * requiresValidInput(notes); // false - plain z.string() accepts empty strings\n * ```\n *\n * @example\n * Nullable field - doesn't require input\n * ```typescript\n * const middleName = z.string().nullable();\n * requiresValidInput(middleName); // false - user can leave null\n * ```\n *\n * @see {@link removeDefault} for understanding how defaults are handled\n * @see {@link getPrimitiveType} for understanding type unwrapping\n * @since 0.1.0\n */\nexport const requiresValidInput = <T extends z.ZodType>(field: T) => {\n const defaultRemovedField = removeDefault(field);\n if (!(defaultRemovedField instanceof z.ZodType)) {\n return false;\n }\n\n const undefinedResult = defaultRemovedField.safeParse(undefined).success;\n\n // Check if field accepts null (nullable)\n const nullResult = defaultRemovedField.safeParse(null).success;\n\n const primitiveType = getPrimitiveType(defaultRemovedField);\n\n const emptyStringResult =\n primitiveType.type === 'string' &&\n defaultRemovedField.safeParse('').success;\n\n const emptyArrayResult =\n primitiveType.type === 'array' && defaultRemovedField.safeParse([]).success;\n\n return (\n !undefinedResult && !nullResult && !emptyStringResult && !emptyArrayResult\n );\n};\n\n/**\n * Union type of all Zod check definition types.\n *\n * Includes all validation check types supported by Zod v4:\n * - **Length checks**: `min_length`, `max_length`, `length_equals` (strings, arrays)\n * - **Size checks**: `min_size`, `max_size`, `size_equals` (files, sets, maps)\n * - **Numeric checks**: `greater_than`, `less_than`, `multiple_of`\n * - **Format checks**: `number_format` (int32, float64, etc.), `bigint_format`, `string_format` (email, url, uuid, etc.)\n * - **String pattern checks**: `regex`, `lowercase`, `uppercase`, `includes`, `starts_with`, `ends_with`\n * - **Other checks**: `property`, `mime_type`, `overwrite`\n *\n * @since 0.4.0\n */\nexport type ZodUnionCheck =\n | $ZodCheckLessThanDef\n | $ZodCheckGreaterThanDef\n | $ZodCheckMultipleOfDef\n | $ZodCheckNumberFormatDef\n // | $ZodCheckBigIntFormatDef\n | $ZodCheckMaxSizeDef\n | $ZodCheckMinSizeDef\n | $ZodCheckSizeEqualsDef\n | $ZodCheckMaxLengthDef\n | $ZodCheckMinLengthDef\n | $ZodCheckLengthEqualsDef\n | $ZodCheckStringFormatDef\n | $ZodCheckRegexDef\n // | $ZodCheckLowerCaseDef\n // | $ZodCheckUpperCaseDef\n | $ZodCheckIncludesDef\n | $ZodCheckStartsWithDef\n | $ZodCheckEndsWithDef\n | $ZodCheckMimeTypeDef\n | $ZodCheckOverwriteDef;\n\n/**\n * Extracts all validation check definitions from a Zod schema field.\n *\n * This function analyzes a Zod field and returns all check definitions as defined\n * by Zod's internal structure. Returns Zod's raw check definition objects directly,\n * including all properties like `check`, `minimum`, `maximum`, `value`, `inclusive`,\n * `format`, `pattern`, etc.\n *\n * **Unwrapping behavior:** Automatically unwraps optional, nullable, and default layers.\n * For unions, checks only the first option (same as other schema utilities).\n *\n * **Supported check types:** Returns any of the 21 check types defined in {@link ZodUnionCheck},\n * including length, size, numeric range, format validation, string patterns, and more.\n *\n * @template T - The Zod type to extract checks from\n * @param field - The Zod field to analyze\n * @returns Array of Zod check definition objects (see {@link ZodUnionCheck})\n *\n * @example\n * String with length constraints\n * ```typescript\n * const username = z.string().min(3).max(20);\n * const checks = getFieldChecks(username);\n * // [\n * // { check: 'min_length', minimum: 3, when: [Function], ... },\n * // { check: 'max_length', maximum: 20, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Number with range constraints\n * ```typescript\n * const age = z.number().min(18).max(120);\n * const checks = getFieldChecks(age);\n * // [\n * // { check: 'greater_than', value: 18, inclusive: true, when: [Function], ... },\n * // { check: 'less_than', value: 120, inclusive: true, when: [Function], ... }\n * // ]\n * ```\n *\n * @example\n * Array with item count constraints\n * ```typescript\n * const tags = z.array(z.string()).min(1).max(5);\n * const checks = getFieldChecks(tags);\n * // [\n * // { check: 'min_length', minimum: 1, ... },\n * // { check: 'max_length', maximum: 5, ... }\n * // ]\n * ```\n *\n * @example\n * String with format validation\n * ```typescript\n * const email = z.string().email();\n * const checks = getFieldChecks(email);\n * // [\n * // { check: 'string_format', format: 'email', ... }\n * // ]\n * ```\n *\n * @example\n * Unwrapping optional/nullable/default layers\n * ```typescript\n * const bio = z.string().min(10).max(500).optional();\n * const checks = getFieldChecks(bio);\n * // [\n * // { check: 'min_length', minimum: 10, ... },\n * // { check: 'max_length', maximum: 500, ... }\n * // ]\n * ```\n *\n * @see {@link ZodUnionCheck} for all supported check types\n * @since 0.4.0\n */\nexport function getFieldChecks<T extends z.ZodType | $ZodType>(\n field: T,\n): Array<ZodUnionCheck> {\n if (!(field instanceof z.ZodType)) return [];\n\n const primitiveType = getPrimitiveType(field);\n\n // Handle unions by collecting checks from all options\n if (primitiveType instanceof z.ZodUnion) {\n const allChecks: Array<ZodUnionCheck> = [];\n for (const option of primitiveType.options) {\n const optionChecks = getFieldChecks(option);\n allChecks.push(...optionChecks);\n }\n return allChecks;\n }\n\n const allChecks: Array<ZodUnionCheck> = [];\n\n // Handle format types (ZodURL, ZodEmail, ZodUUID, etc.)\n // These store format info in def.format instead of def.checks\n if (primitiveType instanceof ZodStringFormat) {\n const formatCheck = primitiveType.def;\n allChecks.push(formatCheck);\n }\n\n // Add any additional checks (like .max(), .min(), etc.)\n if (primitiveType.def.checks) {\n for (const check of primitiveType.def.checks) {\n allChecks.push(...extractCheck(check));\n }\n }\n\n return allChecks;\n}\n\n// Returns array instead of single value to enable 100% test coverage\n// (avoids uncoverable branch when using `if (extracted)` pattern)\nexport function extractCheck(check: z.core.$ZodCheck<never>): ZodUnionCheck[] {\n if (check instanceof $ZodCheckLessThan) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckGreaterThan) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMultipleOf) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckNumberFormat) {\n return [check._zod.def];\n // } else if (check instanceof $ZodCheckBigIntFormat) {\n // // this is format, not check\n // return [check._zod.def];\n } else if (check instanceof $ZodCheckMaxSize) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMinSize) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckSizeEquals) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMaxLength) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMinLength) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckLengthEquals) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckRegex) {\n // $ZodCheckRegex must be checked before $ZodCheckStringFormat (it's instanceof both)\n return [check._zod.def];\n } else if (check instanceof $ZodCheckStringFormat) {\n return [check._zod.def];\n // } else if (check instanceof $ZodCheckLowerCase) {\n // // these are formats not checks\n // return [check._zod.def];\n // } else if (check instanceof $ZodCheckUpperCase) {\n // // these are formats not checks\n // return [check._zod.def];\n } else if (check instanceof $ZodCheckOverwrite) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckMimeType) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckIncludes) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckStartsWith) {\n return [check._zod.def];\n } else if (check instanceof $ZodCheckEndsWith) {\n return [check._zod.def];\n }\n return [];\n}\n","import { type util, z } from 'zod';\nimport type { $InferUnionInput } from 'zod/v4/core';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n UnwrapZodType,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n/**\n * Recursively extracts the exact schema type from a discriminated union based on the discriminator value.\n *\n * This advanced TypeScript utility type walks through a union's options tuple at compile-time,\n * checking each schema against the discriminator field and value, and returns the exact matching\n * schema type (not a union of all options).\n *\n * **How it works:**\n * 1. Extracts the options tuple from the union using `infer Options`\n * 2. Destructure into head (`First`) and tail (`Rest`) using tuple pattern matching\n * 3. Checks if `First` is a ZodObject with the matching discriminator field and value\n * 4. If match found, returns `First` (the exact schema type)\n * 5. If no match, recursively processes `Rest` until a match is found or list is exhausted\n *\n * **Type narrowing magic:**\n * - Input: `z.discriminatedUnion('type', [SchemaA, SchemaB, SchemaC])`\n * - Discriminator value: `'a'` (matches SchemaA)\n * - Output: `SchemaA` (exact type, not `SchemaA | SchemaB | SchemaC`)\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion type\n * @template TDiscriminatorKey - The discriminator field name (e.g., \"type\", \"mode\")\n * @template TDiscriminatorValue - The specific discriminator value (e.g., \"create\", \"edit\")\n * @returns The exact matching schema type, or `never` if no match found\n *\n * @example\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * z.object({ mode: z.literal('edit'), id: z.number() }),\n * ]);\n *\n * // Exact type: z.object({ mode: z.literal('create'), name: z.string() })\n * type CreateSchema = ExtractZodUnionMember<typeof schema, 'mode', 'create'>;\n * ```\n */\nexport type ExtractZodUnionMember<\n TSchema extends z.ZodUnion | z.ZodDiscriminatedUnion,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends z.input<TSchema>[TDiscriminatorKey] &\n util.Literal,\n> = TSchema extends z.ZodUnion<infer Options>\n ? Options extends readonly [\n infer First extends z.ZodTypeAny,\n ...infer Rest extends z.ZodTypeAny[],\n ]\n ? First extends z.ZodObject<infer Shape>\n ? TDiscriminatorKey extends keyof Shape\n ? Shape[TDiscriminatorKey] extends\n | z.ZodLiteral<TDiscriminatorValue>\n | z.ZodDefault<z.ZodLiteral<TDiscriminatorValue>>\n ? First\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : Rest extends []\n ? never\n : TDiscriminatorValue extends $InferUnionInput<\n Rest[number]\n >[TDiscriminatorKey]\n ? ExtractZodUnionMember<\n z.ZodUnion<Rest>,\n TDiscriminatorKey,\n TDiscriminatorValue\n >\n : never\n : never\n : never\n : never;\n\n/**\n * Extracts a specific schema option from a discriminated union based on the discriminator field value.\n *\n * This function finds and returns the **exact matching schema** from a `ZodDiscriminatedUnion` by\n * comparing the discriminator field value. It's used internally by {@link getSchemaDefaults} to\n * extract defaults from the correct schema variant in a discriminated union.\n *\n * **Key feature:** Returns the **exact schema type**, not a union of all options, thanks to the\n * {@link ExtractZodUnionMember} recursive type utility. This enables precise type narrowing at\n * compile-time based on the discriminator value.\n *\n * **How it works:**\n * 1. Iterates through all options in the discriminated union at runtime\n * 2. For each option, validates it's a ZodObject and checks if the discriminator field matches\n * 3. Returns the first matching schema with its exact type narrowed at compile-time\n * 4. Returns `undefined` if no match found or if option is not a ZodObject\n *\n * @template TSchema - The ZodUnion or ZodDiscriminatedUnion schema type\n * @template TDiscriminatorKey - The discriminator field name (string key of the inferred union type)\n * @template TDiscriminatorValue - The specific discriminator value to match (literal type)\n * @param params - Parameters object\n * @param params.schema - The discriminated union schema to search\n * @param params.discriminatorKey - The discriminator field name (e.g., \"mode\", \"type\")\n * @param params.discriminatorValue - The discriminator value to match (e.g., \"create\", \"edit\")\n * @returns The exact matching schema option (with precise type), or `undefined` if not found or schema is not a discriminated union\n *\n * @example\n * Basic discriminated union - create/edit mode\n * ```typescript\n * const userSchema = z.discriminatedUnion('mode', [\n * z.object({\n * mode: z.literal('create'),\n * name: z.string(),\n * age: z.number().optional(),\n * }),\n * z.object({\n * mode: z.literal('edit'),\n * id: z.number(),\n * name: z.string().optional(),\n * }),\n * ]);\n *\n * // Extract the \"create\" schema\n * const createSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n * // Result: z.object({ mode: z.literal('create'), name: z.string(), age: z.number().optional() })\n *\n * // Extract the \"edit\" schema\n * const editSchema = extractDiscriminatedSchema({\n * schema: userSchema,\n * discriminator: { key: 'mode', value: 'edit' },\n * });\n * // Result: z.object({ mode: z.literal('edit'), id: z.number(), name: z.string().optional() })\n * ```\n *\n * @example\n * Type-based discrimination\n * ```typescript\n * const eventSchema = z.discriminatedUnion('type', [\n * z.object({ type: z.literal('click'), x: z.number(), y: z.number() }),\n * z.object({ type: z.literal('keypress'), key: z.string() }),\n * ]);\n *\n * const clickSchema = extractDiscriminatedSchema({\n * schema: eventSchema,\n * discriminator: { key: 'type', value: 'click' },\n * });\n * // Result: z.object({ type: z.literal('click'), x: z.number(), y: z.number() })\n * ```\n *\n * @example\n * Invalid discriminator value\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string() }),\n * ]);\n *\n * const result = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'invalid' }, // doesn't match any option\n * });\n * // Result: undefined\n * ```\n *\n * @example\n * Type narrowing demonstration\n * ```typescript\n * const schema = z.discriminatedUnion('mode', [\n * z.object({ mode: z.literal('create'), name: z.string(), age: z.number() }),\n * z.object({ mode: z.literal('edit'), id: z.number(), bio: z.string() }),\n * ]);\n *\n * const createSchema = extractDiscriminatedSchema({\n * schema,\n * discriminator: { key: 'mode', value: 'create' },\n * });\n *\n * // Type is EXACTLY: z.object({ mode: z.literal('create'), name: z.string(), age: z.number() })\n * // NOT: z.object({ mode: ..., ... }) | z.object({ mode: ..., ... }) | undefined\n *\n * if (createSchema) {\n * createSchema.shape.age; // ✅ TypeScript knows 'age' exists\n * createSchema.shape.name; // ✅ TypeScript knows 'name' exists\n * // createSchema.shape.id; // ❌ TypeScript error: 'id' doesn't exist on 'create' schema\n * }\n * ```\n *\n * @see {@link getSchemaDefaults} for usage with discriminated unions\n * @see {@link ExtractZodUnionMember} for the type-level extraction logic\n * @since 0.6.0\n */\nexport const extractDiscriminatedSchema = <\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n TUnwrapped extends z.ZodType = UnwrapZodType<TSchema> extends z.ZodType\n ? UnwrapZodType<TSchema>\n : TSchema,\n ReturnType extends TUnwrapped extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>,\n Extract<\n TDiscriminatorValue,\n DiscriminatorValue<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>\n >\n >\n >\n : undefined = TUnwrapped extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>,\n Extract<\n TDiscriminatorValue,\n DiscriminatorValue<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>\n >\n >\n >\n : undefined,\n>({\n schema,\n discriminator,\n}: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n>): ReturnType => {\n const primitiveSchema = getPrimitiveType(schema);\n\n if (!(primitiveSchema instanceof z.ZodDiscriminatedUnion) || !discriminator) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ReturnType;\n }\n\n const { key, value } = discriminator;\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return primitiveSchema.options.find((option) => {\n if (option instanceof z.ZodObject) {\n const targetField = getShapeField(option, String(key));\n if (!targetField) return false;\n\n const parseResult = targetField.safeParse(value);\n return parseResult.success;\n }\n return false;\n }) as ReturnType;\n};\n","import * as z from 'zod';\nimport { extractDiscriminatedSchema } from './discriminatedSchema';\nimport {\n canUnwrap,\n getPrimitiveType,\n isPipeWithZodInput,\n tryStripNullishOnly,\n} from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n SchemaAndDiscriminatorProps,\n Simplify,\n} from './types';\n\n/**\n * Type-safe helper to iterate over ZodObject shape entries.\n * @internal\n */\nfunction getShapeEntries(\n schema: z.ZodObject,\n): Array<[string, z.ZodType | undefined]> {\n return Object.entries(schema.shape);\n}\n\n/**\n * Extracts the default value from a Zod field, recursively unwrapping optional, nullable, and union layers.\n *\n * This function traverses through wrapper types (like `ZodOptional`, `ZodNullable`, `ZodUnion`) to find\n * the underlying `ZodDefault` and returns its default value. If no default is found, returns `undefined`.\n *\n * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one type\n * remains after stripping, extracts the default from that type. If multiple non-nullish types remain,\n * returns `undefined` (does not extract from any option).\n *\n * @template T - The Zod type to extract default from\n * @param field - The Zod field to extract default from\n * @returns The default value if present, undefined otherwise\n *\n * @example\n * Basic usage with default value\n * ```typescript\n * const field = z.string().default('hello');\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello'\n * ```\n *\n * @example\n * Unwrapping optional/nullable layers\n * ```typescript\n * const field = z.string().default('world').optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'world' (unwraps optional to find default)\n * ```\n *\n * @example\n * Union with only nullish types stripped to single type\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.null()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: 'hello' (null stripped, leaving only string)\n * ```\n *\n * @example\n * Union with multiple non-nullish types\n * ```typescript\n * const field = z.union([z.string().default('hello'), z.number()]);\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined (multiple non-nullish types - no default extracted)\n * ```\n *\n * @example\n * Field without default\n * ```typescript\n * const field = z.string().optional();\n * const defaultValue = extractDefaultValue(field);\n * // Result: undefined\n * ```\n *\n * @see {@link getSchemaDefaults} for extracting defaults from entire schemas\n * @see {@link tryStripNullishOnly} for union nullish stripping logic\n * @since 0.1.0\n */\nexport function extractDefaultValue<T extends z.ZodType>(\n field: T,\n): z.input<T> | undefined {\n if (field instanceof z.ZodDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return field.def.defaultValue as z.input<T>;\n }\n\n if (canUnwrap(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.unwrap()) as z.input<T>;\n }\n\n if (field instanceof z.ZodUnion) {\n const unwrapped = tryStripNullishOnly(field);\n if (unwrapped !== false) {\n // Successfully unwrapped to single type\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(unwrapped) as z.input<T>;\n }\n\n // Multiple non-nullish types or all nullish - no default\n return undefined;\n }\n\n if (isPipeWithZodInput(field)) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return extractDefaultValue(field.def.in) as z.input<T>;\n }\n\n // Recursively extract defaults from nested objects\n if (field instanceof z.ZodObject) {\n const nestedDefaults: Record<string, unknown> = {};\n let hasAnyDefault = false;\n\n for (const [key, nestedField] of getShapeEntries(field)) {\n if (!nestedField) continue;\n\n const nestedDefault = extractDefaultValue(nestedField);\n if (nestedDefault !== undefined) {\n nestedDefaults[key] = nestedDefault;\n hasAnyDefault = true;\n }\n }\n\n if (hasAnyDefault) {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return nestedDefaults as z.input<T>;\n }\n }\n\n return undefined;\n}\n\n/**\n * Extracts default values from a Zod object schema, returning only fields with explicit `.default()`.\n *\n * This function traverses the schema and collects fields that have explicit default values.\n * Fields without defaults are excluded from the result.\n *\n * **Important:** Nested defaults are NOT extracted unless the parent object also has\n * an explicit `.default()`. This is by design to match Zod's default value behavior.\n *\n * **Component handling:** For form inputs without explicit defaults (like `z.string()` or `z.number()`),\n * use the `?? ''` pattern in your components: `<Input value={field.value ?? ''} />`\n *\n * @template TSchema - The Zod object schema type\n * @param targetSchema - The Zod object schema to extract defaults from\n * @returns A partial object containing only fields with explicit default values\n *\n * @example\n * Basic usage - only explicit defaults\n * ```typescript\n * const schema = z.object({\n * name: z.string(), // no default → NOT included\n * age: z.number(), // no default → NOT included\n * role: z.string().default('user'), // explicit default → included\n * count: z.number().default(0), // explicit default → included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { role: 'user', count: 0 }\n * ```\n *\n * @example\n * Nested objects with defaults\n * ```typescript\n * const schema = z.object({\n * user: z.object({\n * name: z.string().default('Guest')\n * }).default({ name: 'Guest' }), // ✅ Extracted because parent has .default()\n *\n * settings: z.object({\n * theme: z.string().default('light')\n * }), // ❌ NOT extracted - parent has no .default()\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { user: { name: 'Guest' } }\n * ```\n *\n * @example\n * Unwrapping optional/nullable fields\n * ```typescript\n * const schema = z.object({\n * title: z.string().default('Untitled').optional(),\n * count: z.number().default(0).nullable(),\n * name: z.string().optional(), // no default → NOT included\n * age: z.number().optional(), // no default → NOT included\n * });\n *\n * const defaults = getSchemaDefaults(schema);\n * // Result: { title: 'Untitled', count: 0 }\n * ```\n *\n * @example\n * Component usage for fields without defaults\n * ```typescript\n * // For string/number fields without defaults, handle in components:\n * <Input value={field.value ?? ''} />\n * <Input type=\"number\" value={field.value ?? ''} />\n * ```\n *\n * @see {@link extractDefaultValue} for extracting defaults from individual fields\n * @since 0.1.0\n */\nexport function getSchemaDefaults<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n>(\n params: SchemaAndDiscriminatorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue\n >,\n): Simplify<Partial<z.input<TSchema>>> {\n const primitiveSchemaParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n let targetSchema: z.ZodObject | undefined;\n if (primitiveSchemaParams.schema instanceof z.ZodDiscriminatedUnion) {\n targetSchema = extractDiscriminatedSchema(primitiveSchemaParams);\n } else if (primitiveSchemaParams.schema instanceof z.ZodObject) {\n targetSchema = primitiveSchemaParams.schema;\n }\n\n const defaults: Record<string, unknown> = {};\n\n if (targetSchema) {\n for (const [key, field] of getShapeEntries(targetSchema)) {\n if (!field) continue;\n\n const defaultValue = extractDefaultValue(field);\n if (defaultValue !== undefined) {\n defaults[key] = defaultValue;\n }\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return defaults as Partial<z.input<TSchema>>;\n}\n","import { z } from 'zod';\nimport {\n type ExtractZodUnionMember,\n extractDiscriminatedSchema,\n} from './discriminatedSchema';\nimport { getPrimitiveType } from './schema';\nimport type {\n DiscriminatorKey,\n DiscriminatorValue,\n FieldSelectorProps,\n IsDiscriminatedUnion,\n UnwrapZodType,\n} from './types';\n\n/**\n * Type-safe helper to get a field from ZodObject shape by key.\n * @internal\n */\nfunction getShapeField(\n schema: z.ZodObject,\n key: string,\n): z.ZodType | undefined {\n return Object.entries(schema.shape).find(([k]) => k === key)?.[1];\n}\n\n// Split 'a.b.c' into ['a', 'b', 'c']\ntype Split<S extends string> = S extends `${infer Head}.${infer Tail}`\n ? [Head, ...Split<Tail>]\n : [S];\n\n// Check if string is numeric\ntype IsNumeric<S extends string> = S extends `${number}` ? true : false;\n\n// Unwrap ZodOptional, ZodNullable, ZodDefault, ZodPipe (transforms)\ntype Unwrap<T> = T extends z.ZodOptional<infer U>\n ? Unwrap<U>\n : T extends z.ZodNullable<infer U>\n ? Unwrap<U>\n : T extends z.ZodDefault<infer U>\n ? Unwrap<U>\n : T extends z.ZodPipe<infer In, z.ZodType>\n ? Unwrap<In>\n : T;\n\n// Navigate Zod schema by path array\ntype NavigateZod<T, Path extends string[]> = Path extends [\n infer First extends string,\n ...infer Rest extends string[],\n]\n ? Unwrap<T> extends z.ZodObject<infer Shape>\n ? First extends keyof Shape\n ? Rest extends []\n ? Shape[First]\n : NavigateZod<Shape[First], Rest>\n : never\n : Unwrap<T> extends z.ZodArray<infer Element>\n ? IsNumeric<First> extends true\n ? Rest extends []\n ? Element\n : NavigateZod<Element, Rest>\n : never\n : never\n : T;\n\nexport type ExtractZodByPath<Schema, Path extends string> = NavigateZod<\n Schema,\n Split<Path>\n>;\n\n/**\n * Extract field from a discriminated union variant.\n * First extracts the variant using ExtractZodUnionMember, then navigates through it.\n * @internal\n */\ntype ExtractFromDiscriminatedUnion<\n TSchema extends z.ZodType,\n TName extends string,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<TSchema, TDiscriminatorKey>,\n TUnwrapped extends z.ZodType = UnwrapZodType<TSchema> extends z.ZodType\n ? UnwrapZodType<TSchema>\n : TSchema,\n TVariant = TUnwrapped extends z.ZodDiscriminatedUnion\n ? ExtractZodUnionMember<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>,\n Extract<\n TDiscriminatorValue,\n DiscriminatorValue<\n TUnwrapped,\n Extract<TDiscriminatorKey, DiscriminatorKey<TUnwrapped>>\n >\n >\n >\n : never,\n> = TVariant extends z.ZodType ? ExtractZodByPath<TVariant, TName> : never;\n\n/**\n * Helper type to determine if field extraction should succeed.\n * Returns true when:\n * 1. For discriminated unions: discriminator is provided (trust the user)\n * 2. For non-unions: the path resolves to a valid type (not never)\n * @internal\n */\ntype CanExtractField<\n TSchema extends z.ZodType,\n TName extends string,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n> = IsDiscriminatedUnion<TSchema> extends true // Discriminated union - check if discriminator is provided\n ? [TDiscriminatorKey] extends [never]\n ? false // No discriminator = can't extract\n : true // Discriminator provided = trust it\n : // Not a discriminated union - check if path is valid\n [ExtractZodByPath<TSchema, TName>] extends [never]\n ? false\n : true;\n\n/**\n * Conditional return type for extractFieldFromSchema.\n * For discriminated unions: extracts variant first, then navigates.\n * For non-unions: navigates directly.\n * @internal\n */\ntype ExtractFieldResult<\n TSchema extends z.ZodType,\n TName extends string,\n TDiscriminatorKey extends DiscriminatorKey<TSchema>,\n TDiscriminatorValue extends DiscriminatorValue<\n TSchema,\n TDiscriminatorKey\n > = DiscriminatorValue<TSchema, TDiscriminatorKey>,\n> = CanExtractField<TSchema, TName, TDiscriminatorKey> extends true\n ? IsDiscriminatedUnion<TSchema> extends true\n ? // For discriminated unions: extract variant first, then navigate\n [\n ExtractFromDiscriminatedUnion<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >,\n ] extends [never]\n ? z.ZodType // Path couldn't be resolved, return generic type\n : ExtractFromDiscriminatedUnion<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n > &\n z.ZodType\n : // For non-unions: navigate directly\n ExtractZodByPath<TSchema, TName> & z.ZodType\n : (ExtractZodByPath<TSchema, TName> & z.ZodType) | undefined;\n\nexport function extractFieldFromSchema<\n TSchema extends z.ZodType,\n TDiscriminatorKey extends DiscriminatorKey<TSchema> = never,\n TDiscriminatorValue extends DiscriminatorValue<\n TSchema,\n TDiscriminatorKey\n > = never,\n TFilterType = unknown,\n TStrict extends boolean = true,\n TName extends string = string,\n>(\n params: FieldSelectorProps<\n TSchema,\n TDiscriminatorKey,\n TDiscriminatorValue,\n TFilterType,\n TStrict\n > & { name: TName },\n): ExtractFieldResult<TSchema, TName, TDiscriminatorKey, TDiscriminatorValue> {\n let currentSchema: z.ZodType | undefined;\n\n const newParams = {\n ...params,\n schema: getPrimitiveType(params.schema),\n };\n\n if (newParams.schema instanceof z.ZodDiscriminatedUnion) {\n if (newParams.discriminator) {\n currentSchema = extractDiscriminatedSchema(newParams);\n }\n } else if (newParams.schema instanceof z.ZodObject) {\n currentSchema = newParams.schema;\n }\n\n if (!currentSchema)\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n\n // Split name into segments (e.g., \"contact.email\" -> [\"contact\", \"email\"])\n const segments = String(newParams.name).split('.');\n\n for (const segment of segments) {\n if (!currentSchema)\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n\n const unwrapped: z.ZodType = getPrimitiveType(currentSchema);\n\n if (unwrapped instanceof z.ZodObject) {\n currentSchema = getShapeField(unwrapped, segment);\n } else if (unwrapped instanceof z.ZodArray) {\n // Arrays are keyed by integers only\n if (/^\\d+$/.test(segment) && unwrapped.element instanceof z.ZodType) {\n currentSchema = unwrapped.element;\n } else {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey\n >;\n }\n } else {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return undefined as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return currentSchema as ExtractFieldResult<\n TSchema,\n TName,\n TDiscriminatorKey,\n TDiscriminatorValue\n >;\n}\n\n/**\n * Extends a Zod field with a transformation while preserving its metadata.\n *\n * This is useful when you want to add validations or transformations to a field\n * but keep the original metadata (like translationKey) intact.\n *\n * @param field - The original Zod field\n * @param transform - A function that transforms the field\n * @returns The transformed field with preserved metadata\n *\n * @example\n * ```typescript\n * const baseField = z.string().meta({ translationKey: 'user.field.name' });\n *\n * // Add min/max validation while keeping the translationKey\n * const extendedField = extendWithMeta(baseField, (f) => f.min(3).max(100));\n * extendedField.meta(); // { translationKey: 'user.field.name' }\n * ```\n */\nexport function extendWithMeta<T extends z.ZodType, R extends z.ZodType>(\n field: T,\n transform: (f: T) => R,\n): R {\n const transformedField = transform(field);\n const meta = field.meta();\n if (!meta) {\n return transformedField;\n }\n return transformedField.meta({ ...meta });\n}\n"]}
|