@zod-utils/core 0.1.0 → 0.4.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 +93 -80
- package/dist/index.d.mts +371 -49
- package/dist/index.d.ts +371 -49
- package/dist/index.js +47 -36
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -5
package/README.md
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/@zod-utils/core)
|
|
4
4
|
[](https://www.npmjs.com/package/@zod-utils/core)
|
|
5
|
+
[](https://bundlephobia.com/package/@zod-utils/core)
|
|
5
6
|
[](https://opensource.org/licenses/MIT)
|
|
6
7
|
[](https://www.typescriptlang.org/)
|
|
7
8
|
[](https://github.com/thu-san/zod-utils/actions)
|
|
9
|
+
[](https://codecov.io/gh/thu-san/zod-utils)
|
|
8
10
|
|
|
9
11
|
Pure TypeScript utilities for Zod schema manipulation and default extraction. No React dependencies.
|
|
10
12
|
|
|
@@ -14,10 +16,14 @@ Pure TypeScript utilities for Zod schema manipulation and default extraction. No
|
|
|
14
16
|
npm install @zod-utils/core zod
|
|
15
17
|
```
|
|
16
18
|
|
|
19
|
+
## Related Packages
|
|
20
|
+
|
|
21
|
+
- **[@zod-utils/react-hook-form](https://www.npmjs.com/package/@zod-utils/react-hook-form)** - React Hook Form integration with automatic type transformation. Uses this package internally and re-exports all utilities for convenience.
|
|
22
|
+
|
|
17
23
|
## Features
|
|
18
24
|
|
|
19
25
|
- 🎯 **Extract defaults** - Get default values from Zod schemas
|
|
20
|
-
- ✅ **Check
|
|
26
|
+
- ✅ **Check validation requirements** - Determine if fields will error on empty input
|
|
21
27
|
- 🔧 **Schema utilities** - Unwrap and manipulate schema types
|
|
22
28
|
- 📦 **Zero dependencies** - Only requires Zod as a peer dependency
|
|
23
29
|
- 🌐 **Universal** - Works in Node.js, browsers, and any TypeScript project
|
|
@@ -26,20 +32,22 @@ npm install @zod-utils/core zod
|
|
|
26
32
|
|
|
27
33
|
### `getSchemaDefaults(schema)`
|
|
28
34
|
|
|
29
|
-
Extract all default values from a Zod object schema.
|
|
35
|
+
Extract all default values from a Zod object schema. Only extracts fields that explicitly have `.default()` on them.
|
|
30
36
|
|
|
31
37
|
```typescript
|
|
32
|
-
import { getSchemaDefaults } from
|
|
33
|
-
import { z } from
|
|
38
|
+
import { getSchemaDefaults } from "@zod-utils/core";
|
|
39
|
+
import { z } from "zod";
|
|
34
40
|
|
|
35
41
|
const schema = z.object({
|
|
36
|
-
name: z.string().default(
|
|
42
|
+
name: z.string().default("John Doe"),
|
|
37
43
|
age: z.number().default(25),
|
|
38
44
|
email: z.string().email(), // no default - skipped
|
|
39
|
-
settings: z
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
settings: z
|
|
46
|
+
.object({
|
|
47
|
+
theme: z.string().default("light"),
|
|
48
|
+
notifications: z.boolean().default(true),
|
|
49
|
+
})
|
|
50
|
+
.default({}), // must have explicit .default() to be extracted
|
|
43
51
|
tags: z.array(z.string()).default([]),
|
|
44
52
|
});
|
|
45
53
|
|
|
@@ -47,53 +55,101 @@ const defaults = getSchemaDefaults(schema);
|
|
|
47
55
|
// {
|
|
48
56
|
// name: 'John Doe',
|
|
49
57
|
// age: 25,
|
|
50
|
-
// settings: {
|
|
58
|
+
// settings: {},
|
|
51
59
|
// tags: []
|
|
52
60
|
// }
|
|
53
61
|
```
|
|
54
62
|
|
|
63
|
+
**Important:** Only fields with explicit `.default()` are extracted. Nested object fields without an explicit default on the parent field are not extracted, even if they contain defaults internally.
|
|
64
|
+
|
|
55
65
|
**Handles:**
|
|
56
|
-
|
|
66
|
+
|
|
57
67
|
- Optional fields with defaults: `.optional().default(value)`
|
|
68
|
+
- Nullable fields with defaults: `.nullable().default(value)`
|
|
58
69
|
- Arrays with defaults: `.array().default([])`
|
|
59
|
-
-
|
|
70
|
+
- Objects with defaults: `.object({...}).default({})`
|
|
71
|
+
- Skips fields without explicit defaults
|
|
60
72
|
|
|
61
73
|
---
|
|
62
74
|
|
|
63
|
-
### `
|
|
75
|
+
### `requiresValidInput(field)`
|
|
76
|
+
|
|
77
|
+
Determines if a field will show validation errors when the user submits empty or invalid input. Useful for form UIs to show which fields need valid user input (asterisks, validation indicators).
|
|
64
78
|
|
|
65
|
-
|
|
79
|
+
**Key insight:** Defaults are just initial values - they don't prevent validation errors if the user clears the field.
|
|
80
|
+
|
|
81
|
+
**Real-world example:**
|
|
66
82
|
|
|
67
83
|
```typescript
|
|
68
|
-
|
|
69
|
-
|
|
84
|
+
// Marital status with default but validation rules
|
|
85
|
+
const maritalStatus = z.string().min(1).default('single');
|
|
86
|
+
|
|
87
|
+
// What happens in the form:
|
|
88
|
+
// 1. Initial: field shows "single" (from default)
|
|
89
|
+
// 2. User deletes the value → empty string
|
|
90
|
+
// 3. User submits form → validation fails (.min(1) rejects empty)
|
|
91
|
+
// 4. requiresValidInput(maritalStatus) → true (show *, show error)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**How it works:**
|
|
70
95
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
96
|
+
1. Removes `.default()` wrappers (defaults ≠ validation rules)
|
|
97
|
+
2. Tests if underlying schema accepts empty/invalid input:
|
|
98
|
+
- `undefined` (via `.optional()`)
|
|
99
|
+
- `null` (via `.nullable()`)
|
|
100
|
+
- Empty string (plain `z.string()`)
|
|
101
|
+
- Empty array (plain `z.array()`)
|
|
102
|
+
3. Returns `true` if validation will fail on empty input
|
|
74
103
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
104
|
+
**Examples:**
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { requiresValidInput } from "@zod-utils/core";
|
|
108
|
+
import { z } from "zod";
|
|
109
|
+
|
|
110
|
+
// User name - required, no default
|
|
111
|
+
const userName = z.string().min(1);
|
|
112
|
+
requiresValidInput(userName); // true - will error if empty
|
|
113
|
+
|
|
114
|
+
// Marital status - required WITH default
|
|
115
|
+
const maritalStatus = z.string().min(1).default('single');
|
|
116
|
+
requiresValidInput(maritalStatus); // true - will error if user clears it
|
|
117
|
+
|
|
118
|
+
// Age with default - requires valid input
|
|
119
|
+
const age = z.number().default(0);
|
|
120
|
+
requiresValidInput(age); // true - numbers reject empty strings
|
|
121
|
+
|
|
122
|
+
// Optional bio - doesn't require input
|
|
123
|
+
const bio = z.string().optional();
|
|
124
|
+
requiresValidInput(bio); // false - user can leave empty
|
|
125
|
+
|
|
126
|
+
// Notes with default but NO validation
|
|
127
|
+
const notes = z.string().default('N/A');
|
|
128
|
+
requiresValidInput(notes); // false - plain z.string() accepts empty
|
|
129
|
+
|
|
130
|
+
// Nullable middle name
|
|
131
|
+
const middleName = z.string().nullable();
|
|
132
|
+
requiresValidInput(middleName); // false - user can leave null
|
|
78
133
|
```
|
|
79
134
|
|
|
80
135
|
---
|
|
81
136
|
|
|
82
|
-
### `getPrimitiveType(field
|
|
137
|
+
### `getPrimitiveType(field)`
|
|
83
138
|
|
|
84
139
|
Get the primitive type of a Zod field by unwrapping optional/nullable wrappers.
|
|
140
|
+
Stops at arrays without unwrapping them.
|
|
85
141
|
|
|
86
142
|
```typescript
|
|
87
|
-
import { getPrimitiveType } from
|
|
88
|
-
import { z } from
|
|
143
|
+
import { getPrimitiveType } from "@zod-utils/core";
|
|
144
|
+
import { z } from "zod";
|
|
89
145
|
|
|
90
146
|
const field = z.string().optional().nullable();
|
|
91
147
|
const primitive = getPrimitiveType(field);
|
|
92
148
|
// Returns the underlying string schema
|
|
93
149
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
150
|
+
const arrayField = z.array(z.string()).optional();
|
|
151
|
+
const arrayPrimitive = getPrimitiveType(arrayField);
|
|
152
|
+
// Returns the ZodArray (stops at arrays)
|
|
97
153
|
```
|
|
98
154
|
|
|
99
155
|
---
|
|
@@ -103,14 +159,14 @@ getPrimitiveType(z.array(z.string()), { unwrapArrays: true }); // Continues unw
|
|
|
103
159
|
Remove default values from a Zod field.
|
|
104
160
|
|
|
105
161
|
```typescript
|
|
106
|
-
import { removeDefault } from
|
|
107
|
-
import { z } from
|
|
162
|
+
import { removeDefault } from "@zod-utils/core";
|
|
163
|
+
import { z } from "zod";
|
|
108
164
|
|
|
109
|
-
const withDefault = z.string().default(
|
|
165
|
+
const withDefault = z.string().default("hello");
|
|
110
166
|
const withoutDefault = removeDefault(withDefault);
|
|
111
167
|
|
|
112
|
-
withDefault.parse(undefined);
|
|
113
|
-
withoutDefault.parse(undefined);
|
|
168
|
+
withDefault.parse(undefined); // 'hello'
|
|
169
|
+
withoutDefault.parse(undefined); // throws error
|
|
114
170
|
```
|
|
115
171
|
|
|
116
172
|
---
|
|
@@ -120,10 +176,10 @@ withoutDefault.parse(undefined); // throws error
|
|
|
120
176
|
Extract the default value from a Zod field (recursively unwraps optional/nullable).
|
|
121
177
|
|
|
122
178
|
```typescript
|
|
123
|
-
import { extractDefault } from
|
|
124
|
-
import { z } from
|
|
179
|
+
import { extractDefault } from "@zod-utils/core";
|
|
180
|
+
import { z } from "zod";
|
|
125
181
|
|
|
126
|
-
const field = z.string().optional().default(
|
|
182
|
+
const field = z.string().optional().default("hello");
|
|
127
183
|
extractDefault(field); // 'hello'
|
|
128
184
|
|
|
129
185
|
const noDefault = z.string();
|
|
@@ -132,63 +188,20 @@ extractDefault(noDefault); // undefined
|
|
|
132
188
|
|
|
133
189
|
---
|
|
134
190
|
|
|
135
|
-
### `getUnwrappedType(field)`
|
|
136
|
-
|
|
137
|
-
Get the unwrapped type without going through defaults. Useful for detecting nested objects/arrays.
|
|
138
|
-
|
|
139
|
-
```typescript
|
|
140
|
-
import { getUnwrappedType } from '@zod-utils/core';
|
|
141
|
-
import { z } from 'zod';
|
|
142
|
-
|
|
143
|
-
const field = z.object({ name: z.string() }).optional().default({});
|
|
144
|
-
const unwrapped = getUnwrappedType(field);
|
|
145
|
-
// Returns the ZodObject (preserves the default wrapper)
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
191
|
## Type Utilities
|
|
151
192
|
|
|
152
|
-
### `MakeOptionalAndNullable<T>`
|
|
153
|
-
|
|
154
|
-
Make all properties optional and nullable. Useful for form input types.
|
|
155
|
-
|
|
156
|
-
```typescript
|
|
157
|
-
import type { MakeOptionalAndNullable } from '@zod-utils/core';
|
|
158
|
-
|
|
159
|
-
type User = {
|
|
160
|
-
name: string;
|
|
161
|
-
age: number;
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
type FormInput = MakeOptionalAndNullable<User>;
|
|
165
|
-
// { name?: string | null; age?: number | null; }
|
|
166
|
-
```
|
|
167
|
-
|
|
168
193
|
### `Simplify<T>`
|
|
169
194
|
|
|
170
195
|
Simplify complex types for better IDE hints.
|
|
171
196
|
|
|
172
197
|
```typescript
|
|
173
|
-
import type { Simplify } from
|
|
198
|
+
import type { Simplify } from "@zod-utils/core";
|
|
174
199
|
|
|
175
200
|
type Complex = { a: string } & { b: number };
|
|
176
201
|
type Simple = Simplify<Complex>;
|
|
177
202
|
// { a: string; b: number }
|
|
178
203
|
```
|
|
179
204
|
|
|
180
|
-
### `PickArrayObject<T>`
|
|
181
|
-
|
|
182
|
-
Extract the element type from an array.
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
import type { PickArrayObject } from '@zod-utils/core';
|
|
186
|
-
|
|
187
|
-
type Users = Array<{ name: string }>;
|
|
188
|
-
type User = PickArrayObject<Users>;
|
|
189
|
-
// { name: string }
|
|
190
|
-
```
|
|
191
|
-
|
|
192
205
|
---
|
|
193
206
|
|
|
194
207
|
## License
|