@zod-utils/core 0.8.0 → 1.0.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/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as z from 'zod';
2
- import { $ZodCheckLessThanDef, $ZodCheckGreaterThanDef, $ZodCheckMultipleOfDef, $ZodCheckNumberFormatDef, $ZodCheckBigIntFormatDef, $ZodCheckMaxSizeDef, $ZodCheckMinSizeDef, $ZodCheckSizeEqualsDef, $ZodCheckMaxLengthDef, $ZodCheckMinLengthDef, $ZodCheckLengthEqualsDef, $ZodCheckStringFormatDef, $ZodCheckRegexDef, $ZodCheckLowerCaseDef, $ZodCheckUpperCaseDef, $ZodCheckIncludesDef, $ZodCheckStartsWithDef, $ZodCheckEndsWithDef, $ZodCheckPropertyDef, $ZodCheckMimeTypeDef, $ZodCheckOverwriteDef } from 'zod/v4/core';
2
+ import { util, z as z$1 } from 'zod';
3
+ import { $InferUnionOutput, $ZodCheckLessThanDef, $ZodCheckGreaterThanDef, $ZodCheckMultipleOfDef, $ZodCheckNumberFormatDef, $ZodCheckBigIntFormatDef, $ZodCheckMaxSizeDef, $ZodCheckMinSizeDef, $ZodCheckSizeEqualsDef, $ZodCheckMaxLengthDef, $ZodCheckMinLengthDef, $ZodCheckLengthEqualsDef, $ZodCheckStringFormatDef, $ZodCheckRegexDef, $ZodCheckLowerCaseDef, $ZodCheckUpperCaseDef, $ZodCheckIncludesDef, $ZodCheckStartsWithDef, $ZodCheckEndsWithDef, $ZodCheckPropertyDef, $ZodCheckMimeTypeDef, $ZodCheckOverwriteDef } from 'zod/v4/core';
3
4
 
4
5
  /**
5
6
  * Simplifies complex TypeScript types for better IDE hover tooltips and error messages.
@@ -51,8 +52,9 @@ type Simplify<T> = {
51
52
  * This function traverses through wrapper types (like `ZodOptional`, `ZodNullable`, `ZodUnion`) to find
52
53
  * the underlying `ZodDefault` and returns its default value. If no default is found, returns `undefined`.
53
54
  *
54
- * **Union handling:** For union types, extracts the default from the first option. If the first option
55
- * has no default, returns `undefined` (defaults in other union options are not checked).
55
+ * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one type
56
+ * remains after stripping, extracts the default from that type. If multiple non-nullish types remain,
57
+ * returns `undefined` (does not extract from any option).
56
58
  *
57
59
  * @template T - The Zod type to extract default from
58
60
  * @param field - The Zod field to extract default from
@@ -75,19 +77,19 @@ type Simplify<T> = {
75
77
  * ```
76
78
  *
77
79
  * @example
78
- * Union with default in first option
80
+ * Union with only nullish types stripped to single type
79
81
  * ```typescript
80
- * const field = z.union([z.string().default('hello'), z.number()]);
82
+ * const field = z.union([z.string().default('hello'), z.null()]);
81
83
  * const defaultValue = extractDefault(field);
82
- * // Result: 'hello' (extracts from first union option)
84
+ * // Result: 'hello' (null stripped, leaving only string)
83
85
  * ```
84
86
  *
85
87
  * @example
86
- * Union with default in second option
88
+ * Union with multiple non-nullish types
87
89
  * ```typescript
88
- * const field = z.union([z.string(), z.number().default(42)]);
90
+ * const field = z.union([z.string().default('hello'), z.number()]);
89
91
  * const defaultValue = extractDefault(field);
90
- * // Result: undefined (only checks first option)
92
+ * // Result: undefined (multiple non-nullish types - no default extracted)
91
93
  * ```
92
94
  *
93
95
  * @example
@@ -99,6 +101,7 @@ type Simplify<T> = {
99
101
  * ```
100
102
  *
101
103
  * @see {@link getSchemaDefaults} for extracting defaults from entire schemas
104
+ * @see {@link tryStripNullishOnly} for union nullish stripping logic
102
105
  * @since 0.1.0
103
106
  */
104
107
  declare function extractDefault<T extends z.ZodTypeAny>(field: T): z.infer<T> | undefined;
@@ -114,8 +117,8 @@ declare function extractDefault<T extends z.ZodTypeAny>(field: T): z.infer<T> |
114
117
  * **Component handling:** For form inputs without explicit defaults (like `z.string()` or `z.number()`),
115
118
  * use the `?? ''` pattern in your components: `<Input value={field.value ?? ''} />`
116
119
  *
117
- * @template T - The Zod object schema type
118
- * @param schema - The Zod object schema to extract defaults from
120
+ * @template TSchema - The Zod object schema type
121
+ * @param targetSchema - The Zod object schema to extract defaults from
119
122
  * @returns A partial object containing only fields with explicit default values
120
123
  *
121
124
  * @example
@@ -174,7 +177,21 @@ declare function extractDefault<T extends z.ZodTypeAny>(field: T): z.infer<T> |
174
177
  * @see {@link extractDefault} for extracting defaults from individual fields
175
178
  * @since 0.1.0
176
179
  */
177
- declare function getSchemaDefaults<T extends z.ZodObject>(schema: T): Simplify<Partial<z.infer<T>>>;
180
+ declare function getSchemaDefaults<TSchema extends z.ZodObject | z.ZodDiscriminatedUnion, TDiscriminatorKey extends keyof z.infer<TSchema> & string, TDiscriminatorValue extends z.infer<TSchema>[TDiscriminatorKey] & util.Literal>(schema: TSchema, options?: {
181
+ discriminator?: {
182
+ key: TDiscriminatorKey;
183
+ value: TDiscriminatorValue;
184
+ };
185
+ }): Simplify<Partial<z.infer<TSchema>>>;
186
+
187
+ declare function extractFieldFromSchema<TSchema extends z$1.ZodObject | z$1.ZodDiscriminatedUnion, TName extends keyof Extract<Required<z$1.infer<TSchema>>, Record<TDiscriminatorKey, TDiscriminatorValue>>, TDiscriminatorKey extends keyof z$1.infer<TSchema> & string, TDiscriminatorValue extends z$1.infer<TSchema>[TDiscriminatorKey] & util.Literal>({ schema, fieldName, discriminator, }: {
188
+ schema: TSchema;
189
+ fieldName: TName;
190
+ discriminator?: {
191
+ key: TDiscriminatorKey;
192
+ value: TDiscriminatorValue;
193
+ };
194
+ }): z$1.ZodType<unknown, unknown, z$1.core.$ZodTypeInternals<unknown, unknown>> | undefined;
178
195
 
179
196
  /**
180
197
  * Type representing a Zod type that has an unwrap method
@@ -204,83 +221,53 @@ type Unwrappable = {
204
221
  */
205
222
  declare function canUnwrap(field: z.ZodTypeAny): field is z.ZodTypeAny & Unwrappable;
206
223
  /**
207
- * Unwraps a ZodUnion type and returns the first field and all union options.
224
+ * Attempts to strip nullish types from a union and return the single remaining type.
208
225
  *
209
- * This function extracts the individual type options from a union type.
210
- * By default, it filters out `ZodNull` and `ZodUndefined` types, returning only
211
- * the meaningful type options. You can disable this filtering to get all options.
226
+ * This function filters out `ZodNull` and `ZodUndefined` from union types. If exactly
227
+ * one type remains after filtering, it returns that unwrapped type. Otherwise, it returns
228
+ * `false` to indicate the union couldn't be simplified to a single type.
212
229
  *
213
- * @template T - The Zod type to unwrap
214
- * @param field - The Zod field (union or single type)
215
- * @param options - Configuration options
216
- * @param options.filterNullish - Whether to filter out null and undefined types (default: true)
217
- * @returns Object with `field` (first option) and `union` (all options array)
230
+ * @param field - The Zod field to process
231
+ * @returns The unwrapped type if only one remains, otherwise `false`
218
232
  *
219
233
  * @example
220
- * Basic union unwrapping
234
+ * Union with only nullish types filtered - returns single type
221
235
  * ```typescript
222
- * const field = z.union([z.string(), z.number()]);
223
- * const result = unwrapUnion(field);
224
- * // Result: { field: z.string(), union: [z.string(), z.number()] }
236
+ * const field = z.union([z.string(), z.null(), z.undefined()]);
237
+ * const result = tryStripNullishOnly(field);
238
+ * // Result: z.string() (unwrapped)
225
239
  * ```
226
240
  *
227
241
  * @example
228
- * Union with null (filtered by default)
242
+ * Union with multiple non-nullish types - returns false
229
243
  * ```typescript
230
- * const field = z.union([z.string(), z.null()]);
231
- * const result = unwrapUnion(field);
232
- * // Result: { field: z.string(), union: [z.string()] }
233
- * ```
234
- *
235
- * @example
236
- * Union with null (keep all options)
237
- * ```typescript
238
- * const field = z.union([z.string(), z.null()]);
239
- * const result = unwrapUnion(field, { filterNullish: false });
240
- * // Result: { field: z.string(), union: [z.string(), z.null()] }
244
+ * const field = z.union([z.string(), z.number()]);
245
+ * const result = tryStripNullishOnly(field);
246
+ * // Result: false (cannot simplify to single type)
241
247
  * ```
242
248
  *
243
249
  * @example
244
- * Non-union type (returns single field)
250
+ * Non-union type - returns false
245
251
  * ```typescript
246
252
  * const field = z.string();
247
- * const result = unwrapUnion(field);
248
- * // Result: { field: z.string(), union: [z.string()] }
249
- * ```
250
- *
251
- * @example
252
- * Nullable as union
253
- * ```typescript
254
- * const field = z.string().nullable(); // This is z.union([z.string(), z.null()])
255
- * const result = unwrapUnion(field);
256
- * // Result: { field: z.string(), union: [z.string()] } (null filtered out)
257
- * ```
258
- *
259
- * @example
260
- * Using the first field for type checking
261
- * ```typescript
262
- * const field = z.union([z.string(), z.number()]);
263
- * const { field: firstField, union } = unwrapUnion(field);
264
- * if (firstField instanceof z.ZodString) {
265
- * console.log('First type is string');
266
- * }
253
+ * const result = tryStripNullishOnly(field);
254
+ * // Result: false (not a union)
267
255
  * ```
268
256
  *
269
257
  * @see {@link getPrimitiveType} for unwrapping wrapper types
270
- * @since 0.1.0
258
+ * @since 0.5.0
271
259
  */
272
- declare function unwrapUnion<T extends z.ZodTypeAny>(field: T, options?: {
273
- filterNullish?: boolean;
274
- }): {
275
- field: z.ZodTypeAny;
276
- union: z.ZodTypeAny[];
277
- };
260
+ declare function tryStripNullishOnly(field: z.ZodTypeAny): z.ZodType | false;
278
261
  /**
279
262
  * Gets the underlying primitive type of a Zod field by recursively unwrapping wrapper types.
280
263
  *
281
264
  * This function removes wrapper layers (optional, nullable, default) to reveal the base type.
282
265
  * **Important:** It stops at array types without unwrapping them, treating arrays as primitives.
283
266
  *
267
+ * **Union handling:** For union types, strips nullish types (null/undefined) first. If only one
268
+ * type remains after stripping, unwraps to that type. If multiple non-nullish types remain,
269
+ * returns the union as-is (does not unwrap).
270
+ *
284
271
  * @template T - The Zod type to unwrap
285
272
  * @param field - The Zod field to unwrap
286
273
  * @returns The unwrapped primitive Zod type
@@ -309,7 +296,24 @@ declare function unwrapUnion<T extends z.ZodTypeAny>(field: T, options?: {
309
296
  * // Result: z.number()
310
297
  * ```
311
298
  *
299
+ * @example
300
+ * Union with only nullish types stripped to single type
301
+ * ```typescript
302
+ * const field = z.union([z.string(), z.null()]);
303
+ * const primitive = getPrimitiveType(field);
304
+ * // Result: z.string() (null stripped, leaving only string)
305
+ * ```
306
+ *
307
+ * @example
308
+ * Union with multiple non-nullish types
309
+ * ```typescript
310
+ * const field = z.union([z.string(), z.number()]);
311
+ * const primitive = getPrimitiveType(field);
312
+ * // Result: z.union([z.string(), z.number()]) (returned as-is)
313
+ * ```
314
+ *
312
315
  * @see {@link canUnwrap} for checking if a field can be unwrapped
316
+ * @see {@link tryStripNullishOnly} for union nullish stripping logic
313
317
  * @since 0.1.0
314
318
  */
315
319
  declare const getPrimitiveType: <T extends z.ZodType>(field: T) => z.ZodTypeAny;
@@ -521,5 +525,167 @@ type ZodUnionCheck = $ZodCheckLessThanDef | $ZodCheckGreaterThanDef | $ZodCheckM
521
525
  * @since 0.4.0
522
526
  */
523
527
  declare function getFieldChecks<T extends z.ZodTypeAny>(field: T): Array<ZodUnionCheck>;
528
+ /**
529
+ * Recursively extracts the exact schema type from a discriminated union based on the discriminator value.
530
+ *
531
+ * This advanced TypeScript utility type walks through a union's options tuple at compile-time,
532
+ * checking each schema against the discriminator field and value, and returns the exact matching
533
+ * schema type (not a union of all options).
534
+ *
535
+ * **How it works:**
536
+ * 1. Extracts the options tuple from the union using `infer Options`
537
+ * 2. Destructure into head (`First`) and tail (`Rest`) using tuple pattern matching
538
+ * 3. Checks if `First` is a ZodObject with the matching discriminator field and value
539
+ * 4. If match found, returns `First` (the exact schema type)
540
+ * 5. If no match, recursively processes `Rest` until a match is found or list is exhausted
541
+ *
542
+ * **Type narrowing magic:**
543
+ * - Input: `z.discriminatedUnion('type', [SchemaA, SchemaB, SchemaC])`
544
+ * - Discriminator value: `'a'` (matches SchemaA)
545
+ * - Output: `SchemaA` (exact type, not `SchemaA | SchemaB | SchemaC`)
546
+ *
547
+ * @template TSchema - The ZodUnion or ZodDiscriminatedUnion type
548
+ * @template TDiscriminatorKey - The discriminator field name (e.g., "type", "mode")
549
+ * @template TDiscriminatorValue - The specific discriminator value (e.g., "create", "edit")
550
+ * @returns The exact matching schema type, or `never` if no match found
551
+ *
552
+ * @example
553
+ * ```typescript
554
+ * const schema = z.discriminatedUnion('mode', [
555
+ * z.object({ mode: z.literal('create'), name: z.string() }),
556
+ * z.object({ mode: z.literal('edit'), id: z.number() }),
557
+ * ]);
558
+ *
559
+ * // Exact type: z.object({ mode: z.literal('create'), name: z.string() })
560
+ * type CreateSchema = ExtractZodUnionMember<typeof schema, 'mode', 'create'>;
561
+ * ```
562
+ */
563
+ type ExtractZodUnionMember<TSchema extends z.ZodUnion | z.ZodDiscriminatedUnion, TDiscriminatorKey extends keyof z.infer<TSchema> & string, TDiscriminatorValue extends z.infer<TSchema>[TDiscriminatorKey] & util.Literal> = TSchema extends z.ZodUnion<infer Options> ? Options extends readonly [
564
+ infer First extends z.ZodTypeAny,
565
+ ...infer Rest extends z.ZodTypeAny[]
566
+ ] ? First extends z.ZodObject<infer Shape> ? TDiscriminatorKey extends keyof Shape ? Shape[TDiscriminatorKey] extends z.ZodLiteral<TDiscriminatorValue> ? First : Rest extends [] ? never : TDiscriminatorValue extends $InferUnionOutput<Rest[number]>[TDiscriminatorKey] ? ExtractZodUnionMember<z.ZodUnion<Rest>, TDiscriminatorKey, TDiscriminatorValue> : never : Rest extends [] ? never : TDiscriminatorValue extends $InferUnionOutput<Rest[number]>[TDiscriminatorKey] ? ExtractZodUnionMember<z.ZodUnion<Rest>, TDiscriminatorKey, TDiscriminatorValue> : never : never : never : never;
567
+ /**
568
+ * Extracts a specific schema option from a discriminated union based on the discriminator field value.
569
+ *
570
+ * This function finds and returns the **exact matching schema** from a `ZodDiscriminatedUnion` by
571
+ * comparing the discriminator field value. It's used internally by {@link getSchemaDefaults} to
572
+ * extract defaults from the correct schema variant in a discriminated union.
573
+ *
574
+ * **Key feature:** Returns the **exact schema type**, not a union of all options, thanks to the
575
+ * {@link ExtractZodUnionMember} recursive type utility. This enables precise type narrowing at
576
+ * compile-time based on the discriminator value.
577
+ *
578
+ * **How it works:**
579
+ * 1. Iterates through all options in the discriminated union at runtime
580
+ * 2. For each option, validates it's a ZodObject and checks if the discriminator field matches
581
+ * 3. Returns the first matching schema with its exact type narrowed at compile-time
582
+ * 4. Returns `undefined` if no match found or if option is not a ZodObject
583
+ *
584
+ * @template TSchema - The ZodUnion or ZodDiscriminatedUnion schema type
585
+ * @template TDiscriminatorKey - The discriminator field name (string key of the inferred union type)
586
+ * @template TDiscriminatorValue - The specific discriminator value to match (literal type)
587
+ * @param params - Parameters object
588
+ * @param params.schema - The discriminated union schema to search
589
+ * @param params.discriminatorKey - The discriminator field name (e.g., "mode", "type")
590
+ * @param params.discriminatorValue - The discriminator value to match (e.g., "create", "edit")
591
+ * @returns The exact matching schema option (with precise type), or `undefined` if not found
592
+ *
593
+ * @example
594
+ * Basic discriminated union - create/edit mode
595
+ * ```typescript
596
+ * const userSchema = z.discriminatedUnion('mode', [
597
+ * z.object({
598
+ * mode: z.literal('create'),
599
+ * name: z.string(),
600
+ * age: z.number().optional(),
601
+ * }),
602
+ * z.object({
603
+ * mode: z.literal('edit'),
604
+ * id: z.number(),
605
+ * name: z.string().optional(),
606
+ * }),
607
+ * ]);
608
+ *
609
+ * // Extract the "create" schema
610
+ * const createSchema = extractDiscriminatedSchema({
611
+ * schema: userSchema,
612
+ * discriminatorKey: 'mode',
613
+ * discriminatorValue: 'create',
614
+ * });
615
+ * // Result: z.object({ mode: z.literal('create'), name: z.string(), age: z.number().optional() })
616
+ *
617
+ * // Extract the "edit" schema
618
+ * const editSchema = extractDiscriminatedSchema({
619
+ * schema: userSchema,
620
+ * discriminatorKey: 'mode',
621
+ * discriminatorValue: 'edit',
622
+ * });
623
+ * // Result: z.object({ mode: z.literal('edit'), id: z.number(), name: z.string().optional() })
624
+ * ```
625
+ *
626
+ * @example
627
+ * Type-based discrimination
628
+ * ```typescript
629
+ * const eventSchema = z.discriminatedUnion('type', [
630
+ * z.object({ type: z.literal('click'), x: z.number(), y: z.number() }),
631
+ * z.object({ type: z.literal('keypress'), key: z.string() }),
632
+ * ]);
633
+ *
634
+ * const clickSchema = extractDiscriminatedSchema({
635
+ * schema: eventSchema,
636
+ * discriminatorKey: 'type',
637
+ * discriminatorValue: 'click',
638
+ * });
639
+ * // Result: z.object({ type: z.literal('click'), x: z.number(), y: z.number() })
640
+ * ```
641
+ *
642
+ * @example
643
+ * Invalid discriminator value
644
+ * ```typescript
645
+ * const schema = z.discriminatedUnion('mode', [
646
+ * z.object({ mode: z.literal('create'), name: z.string() }),
647
+ * ]);
648
+ *
649
+ * const result = extractDiscriminatedSchema({
650
+ * schema,
651
+ * discriminatorKey: 'mode',
652
+ * discriminatorValue: 'invalid', // doesn't match any option
653
+ * });
654
+ * // Result: undefined
655
+ * ```
656
+ *
657
+ * @example
658
+ * Type narrowing demonstration
659
+ * ```typescript
660
+ * const schema = z.discriminatedUnion('mode', [
661
+ * z.object({ mode: z.literal('create'), name: z.string(), age: z.number() }),
662
+ * z.object({ mode: z.literal('edit'), id: z.number(), bio: z.string() }),
663
+ * ]);
664
+ *
665
+ * const createSchema = extractDiscriminatedSchema({
666
+ * schema,
667
+ * discriminatorKey: 'mode',
668
+ * discriminatorValue: 'create',
669
+ * });
670
+ *
671
+ * // Type is EXACTLY: z.object({ mode: z.literal('create'), name: z.string(), age: z.number() })
672
+ * // NOT: z.object({ mode: ..., ... }) | z.object({ mode: ..., ... }) | undefined
673
+ *
674
+ * if (createSchema) {
675
+ * createSchema.shape.age; // ✅ TypeScript knows 'age' exists
676
+ * createSchema.shape.name; // ✅ TypeScript knows 'name' exists
677
+ * // createSchema.shape.id; // ❌ TypeScript error: 'id' doesn't exist on 'create' schema
678
+ * }
679
+ * ```
680
+ *
681
+ * @see {@link getSchemaDefaults} for usage with discriminated unions
682
+ * @see {@link ExtractZodUnionMember} for the type-level extraction logic
683
+ * @since 0.6.0
684
+ */
685
+ declare const extractDiscriminatedSchema: <TSchema extends z.ZodUnion | z.ZodDiscriminatedUnion, TDiscriminatorKey extends keyof z.infer<TSchema> & string, TDiscriminatorValue extends z.infer<TSchema>[TDiscriminatorKey] & util.Literal>({ schema, key, value, }: {
686
+ schema: TSchema;
687
+ key: TDiscriminatorKey;
688
+ value: TDiscriminatorValue;
689
+ }) => ExtractZodUnionMember<TSchema, TDiscriminatorKey, TDiscriminatorValue> | undefined;
524
690
 
525
- export { type Simplify, type ZodUnionCheck, canUnwrap, extractDefault, getFieldChecks, getPrimitiveType, getSchemaDefaults, removeDefault, requiresValidInput, unwrapUnion };
691
+ export { type Simplify, type ZodUnionCheck, canUnwrap, extractDefault, extractDiscriminatedSchema, extractFieldFromSchema, getFieldChecks, getPrimitiveType, getSchemaDefaults, removeDefault, requiresValidInput, tryStripNullishOnly };
package/dist/index.js CHANGED
@@ -22,26 +22,37 @@ function _interopNamespace(e) {
22
22
 
23
23
  var z__namespace = /*#__PURE__*/_interopNamespace(z);
24
24
 
25
- // src/defaults.ts
25
+ var __defProp = Object.defineProperty;
26
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
27
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
28
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
29
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
30
+ var __spreadValues = (a, b) => {
31
+ for (var prop in b || (b = {}))
32
+ if (__hasOwnProp.call(b, prop))
33
+ __defNormalProp(a, prop, b[prop]);
34
+ if (__getOwnPropSymbols)
35
+ for (var prop of __getOwnPropSymbols(b)) {
36
+ if (__propIsEnum.call(b, prop))
37
+ __defNormalProp(a, prop, b[prop]);
38
+ }
39
+ return a;
40
+ };
26
41
  function canUnwrap(field) {
27
42
  return "unwrap" in field && typeof field.unwrap === "function";
28
43
  }
29
- function unwrapUnion(field, options = {}) {
30
- const { filterNullish = true } = options;
44
+ function tryStripNullishOnly(field) {
31
45
  if (field instanceof z__namespace.ZodUnion) {
32
46
  const unionOptions = [...field.def.options];
33
- const filteredOptions = filterNullish ? unionOptions.filter(
47
+ const filteredOptions = unionOptions.filter(
34
48
  (option) => !(option instanceof z__namespace.ZodNull) && !(option instanceof z__namespace.ZodUndefined)
35
- ) : unionOptions;
36
- return {
37
- field: filteredOptions[0] || field,
38
- union: filteredOptions
39
- };
49
+ );
50
+ const firstOption = filteredOptions[0];
51
+ if (firstOption && filteredOptions.length === 1) {
52
+ return firstOption;
53
+ }
40
54
  }
41
- return {
42
- field,
43
- union: [field]
44
- };
55
+ return false;
45
56
  }
46
57
  var getPrimitiveType = (field) => {
47
58
  if (field instanceof z__namespace.ZodArray) {
@@ -51,7 +62,11 @@ var getPrimitiveType = (field) => {
51
62
  return getPrimitiveType(field.unwrap());
52
63
  }
53
64
  if (field instanceof z__namespace.ZodUnion) {
54
- return getPrimitiveType(unwrapUnion(field).field);
65
+ const unwrapped = tryStripNullishOnly(field);
66
+ if (unwrapped !== false) {
67
+ return getPrimitiveType(unwrapped);
68
+ }
69
+ return field;
55
70
  }
56
71
  return field;
57
72
  };
@@ -87,6 +102,23 @@ function getFieldChecks(field) {
87
102
  const primitiveType = getPrimitiveType(field);
88
103
  return ((_a = primitiveType.def.checks) == null ? void 0 : _a.map((check) => check._zod.def)) || [];
89
104
  }
105
+ var extractDiscriminatedSchema = ({
106
+ schema,
107
+ key,
108
+ value
109
+ }) => {
110
+ return schema.options.find(
111
+ (option) => {
112
+ if (option instanceof z__namespace.ZodObject) {
113
+ const targetField = option.shape[String(key)];
114
+ if (!targetField) return false;
115
+ const parseResult = targetField.safeParse(value);
116
+ return parseResult.success;
117
+ }
118
+ return false;
119
+ }
120
+ );
121
+ };
90
122
 
91
123
  // src/defaults.ts
92
124
  function extractDefault(field) {
@@ -97,30 +129,67 @@ function extractDefault(field) {
97
129
  return extractDefault(field.unwrap());
98
130
  }
99
131
  if (field instanceof z__namespace.ZodUnion) {
100
- return extractDefault(unwrapUnion(field).field);
132
+ const unwrapped = tryStripNullishOnly(field);
133
+ if (unwrapped !== false) {
134
+ return extractDefault(unwrapped);
135
+ }
136
+ return void 0;
101
137
  }
102
138
  return void 0;
103
139
  }
104
- function getSchemaDefaults(schema) {
140
+ function getSchemaDefaults(schema, options) {
141
+ let targetSchema;
142
+ if (schema instanceof z__namespace.ZodDiscriminatedUnion) {
143
+ if (options == null ? void 0 : options.discriminator) {
144
+ targetSchema = extractDiscriminatedSchema(__spreadValues({
145
+ schema
146
+ }, options.discriminator));
147
+ }
148
+ } else {
149
+ targetSchema = schema;
150
+ }
105
151
  const defaults = {};
106
- for (const key in schema.shape) {
107
- const field = schema.shape[key];
108
- if (!field) continue;
109
- const defaultValue = extractDefault(field);
110
- if (defaultValue !== void 0) {
111
- defaults[key] = defaultValue;
152
+ if (targetSchema) {
153
+ for (const key in targetSchema.shape) {
154
+ const field = targetSchema.shape[key];
155
+ if (!field) continue;
156
+ const defaultValue = extractDefault(field);
157
+ if (defaultValue !== void 0) {
158
+ defaults[key] = defaultValue;
159
+ }
112
160
  }
113
161
  }
114
162
  return defaults;
115
163
  }
164
+ function extractFieldFromSchema({
165
+ schema,
166
+ fieldName,
167
+ discriminator
168
+ }) {
169
+ let targetSchema;
170
+ if (schema instanceof z.z.ZodDiscriminatedUnion) {
171
+ if (discriminator) {
172
+ targetSchema = extractDiscriminatedSchema(__spreadValues({
173
+ schema
174
+ }, discriminator));
175
+ }
176
+ } else {
177
+ targetSchema = schema;
178
+ }
179
+ if (!targetSchema) return void 0;
180
+ const field = targetSchema.shape[String(fieldName)];
181
+ return field;
182
+ }
116
183
 
117
184
  exports.canUnwrap = canUnwrap;
118
185
  exports.extractDefault = extractDefault;
186
+ exports.extractDiscriminatedSchema = extractDiscriminatedSchema;
187
+ exports.extractFieldFromSchema = extractFieldFromSchema;
119
188
  exports.getFieldChecks = getFieldChecks;
120
189
  exports.getPrimitiveType = getPrimitiveType;
121
190
  exports.getSchemaDefaults = getSchemaDefaults;
122
191
  exports.removeDefault = removeDefault;
123
192
  exports.requiresValidInput = requiresValidInput;
124
- exports.unwrapUnion = unwrapUnion;
193
+ exports.tryStripNullishOnly = tryStripNullishOnly;
125
194
  //# sourceMappingURL=index.js.map
126
195
  //# sourceMappingURL=index.js.map