use-zod-default 1.0.1

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 ADDED
@@ -0,0 +1,126 @@
1
+ # use-zod-default
2
+
3
+ Effortlessly create default instances from Zod schemas with intelligent type inference and flexible customization.
4
+
5
+ ## 🚀 Features
6
+
7
+ - 📦 Create default instances from Zod schemas
8
+ - 🧠 Intelligent type inference
9
+ - 🛠 Support for nested objects, arrays, and complex types
10
+ - 🎛 Customizable with partial source objects
11
+ - 🔄 Handles discriminated unions and regular unions
12
+ - 🏷 Full TypeScript support
13
+
14
+ ## 📦 Installation
15
+
16
+ ```bash
17
+ npm install use-zod-default
18
+ ```
19
+
20
+ or
21
+
22
+ ```bash
23
+ yarn add use-zod-default
24
+ ```
25
+
26
+ ## 🛠 Usage
27
+
28
+ ```typescript
29
+ import { z } from 'zod';
30
+ import defaultInstance from 'use-zod-default';
31
+
32
+ // Define your Zod schema
33
+ const userSchema = z.object({
34
+ name: z.string(),
35
+ age: z.number(),
36
+ isActive: z.boolean(),
37
+ roles: z.array(z.string()),
38
+ settings: z.object({
39
+ theme: z.enum(['light', 'dark']),
40
+ notifications: z.boolean()
41
+ })
42
+ });
43
+
44
+ // Create a default instance
45
+ const defaultUser = defaultInstance(userSchema);
46
+
47
+ console.log(defaultUser);
48
+ // Output:
49
+ // {
50
+ // name: '',
51
+ // age: 0,
52
+ // isActive: false,
53
+ // roles: [],
54
+ // settings: {
55
+ // theme: 'light',
56
+ // notifications: false
57
+ // }
58
+ // }
59
+ ```
60
+
61
+ ### With Partial Source
62
+
63
+ You can provide a partial source object to override default values:
64
+
65
+ ```typescript
66
+ const partialUser = {
67
+ name: 'John Doe',
68
+ settings: {
69
+ theme: 'dark'
70
+ }
71
+ };
72
+
73
+ const userWithCustomValues = defaultInstance(userSchema, partialUser);
74
+
75
+ console.log(userWithCustomValues);
76
+ // Output:
77
+ // {
78
+ // name: 'John Doe',
79
+ // age: 0,
80
+ // isActive: false,
81
+ // roles: [],
82
+ // settings: {
83
+ // theme: 'dark',
84
+ // notifications: false
85
+ // }
86
+ // }
87
+ ```
88
+
89
+ ## 🧩 Advanced Usage
90
+
91
+ ### Discriminated Unions
92
+
93
+ ```typescript
94
+ const resultSchema = z.discriminatedUnion('status', [
95
+ z.object({ status: z.literal('success'), data: z.string() }),
96
+ z.object({ status: z.literal('error'), message: z.string() })
97
+ ]);
98
+
99
+ const defaultResult = defaultInstance(resultSchema);
100
+ console.log(defaultResult); // { status: 'success', data: '' }
101
+ ```
102
+
103
+ ### Regular Unions
104
+
105
+ ```typescript
106
+ const dataSchema = z.union([
107
+ z.object({ type: z.literal('string'), value: z.string() }),
108
+ z.object({ type: z.literal('number'), value: z.number() }),
109
+ z.string()
110
+ ]);
111
+
112
+ const defaultData = defaultInstance(dataSchema);
113
+ console.log(defaultData); // { type: 'string', value: '' }
114
+ ```
115
+
116
+ ## 📝 License
117
+
118
+ MIT © [Felipe Rohde](mailto:feliperohdee@gmail.com)
119
+
120
+ ## 👨‍💻 Author
121
+
122
+ **Felipe Rohde**
123
+
124
+ - Twitter: [@felipe_rohde](https://twitter.com/felipe_rohde)
125
+ - Github: [@feliperohdee](https://github.com/feliperohdee)
126
+ - Email: feliperohdee@gmail.com
@@ -0,0 +1,3 @@
1
+ import { z } from 'zod';
2
+ declare const defaultInstance: <T extends z.ZodSchema>(schema: T, source?: any) => z.output<T>;
3
+ export default defaultInstance;
package/dist/index.js ADDED
@@ -0,0 +1,234 @@
1
+ import { z } from 'zod';
2
+ const defaultInstance = (schema, source = {}) => {
3
+ const getDefaultValue = (schema) => {
4
+ if (schema instanceof z.ZodDefault) {
5
+ return schema._def.defaultValue();
6
+ }
7
+ if (schema instanceof z.ZodAny) {
8
+ return undefined;
9
+ }
10
+ if (schema instanceof z.ZodArray) {
11
+ return [];
12
+ }
13
+ if (schema instanceof z.ZodBoolean) {
14
+ return false;
15
+ }
16
+ if (schema instanceof z.ZodDate) {
17
+ return null;
18
+ }
19
+ if (schema instanceof z.ZodDiscriminatedUnion) {
20
+ return defaultInstance(schema.options[0]);
21
+ }
22
+ if (schema instanceof z.ZodEffects) {
23
+ return getDefaultValue(schema.innerType());
24
+ }
25
+ if (schema instanceof z.ZodEnum) {
26
+ return schema.options[0];
27
+ }
28
+ if (schema instanceof z.ZodFunction) {
29
+ return () => null;
30
+ }
31
+ if (schema instanceof z.ZodIntersection) {
32
+ return defaultInstance(schema._def.left, source);
33
+ }
34
+ if (schema instanceof z.ZodLiteral) {
35
+ return schema.value;
36
+ }
37
+ if (schema instanceof z.ZodMap) {
38
+ return new Map();
39
+ }
40
+ if (schema instanceof z.ZodNativeEnum) {
41
+ const keys = Object.keys(schema._def.values);
42
+ return schema._def.values[keys[0]];
43
+ }
44
+ if (schema instanceof z.ZodNaN) {
45
+ return NaN;
46
+ }
47
+ if (schema instanceof z.ZodNever) {
48
+ return undefined;
49
+ }
50
+ if (schema instanceof z.ZodNull) {
51
+ return null;
52
+ }
53
+ if (schema instanceof z.ZodNullable) {
54
+ return null;
55
+ }
56
+ if (schema instanceof z.ZodNumber || schema instanceof z.ZodBigInt) {
57
+ return schema.minValue ?? 0;
58
+ }
59
+ if (schema instanceof z.ZodObject) {
60
+ return defaultInstance(schema, {});
61
+ }
62
+ if (schema instanceof z.ZodPipeline) {
63
+ if (!('out' in schema._def)) {
64
+ return undefined;
65
+ }
66
+ return getDefaultValue(schema._def.out);
67
+ }
68
+ if (schema instanceof z.ZodPromise) {
69
+ return Promise.resolve(getDefaultValue(schema.unwrap()));
70
+ }
71
+ if (schema instanceof z.ZodRecord) {
72
+ return {};
73
+ }
74
+ if (schema instanceof z.ZodSet) {
75
+ return new Set();
76
+ }
77
+ if (schema instanceof z.ZodString) {
78
+ return '';
79
+ }
80
+ if (schema instanceof z.ZodSymbol) {
81
+ return '';
82
+ }
83
+ if (schema instanceof z.ZodTuple) {
84
+ return [];
85
+ }
86
+ if (schema instanceof z.ZodUnion) {
87
+ return getDefaultValue(schema.options[0]);
88
+ }
89
+ if (schema instanceof z.ZodUnknown) {
90
+ return undefined;
91
+ }
92
+ if (schema instanceof z.ZodUndefined) {
93
+ return undefined;
94
+ }
95
+ if (schema instanceof z.ZodVoid) {
96
+ return undefined;
97
+ }
98
+ if (schema._def && schema._def.innerType) {
99
+ return getDefaultValue(schema._def.innerType);
100
+ }
101
+ return undefined;
102
+ };
103
+ const processArray = (schema, source) => {
104
+ if (!Array.isArray(source)) {
105
+ return [];
106
+ }
107
+ const elementSchema = schema.element;
108
+ return source.map(item => {
109
+ return processValue(elementSchema, item);
110
+ });
111
+ };
112
+ const processDiscriminatedUnion = (schema, source) => {
113
+ if (typeof source !== 'object' || source === null) {
114
+ return getDefaultValue(schema);
115
+ }
116
+ const discriminator = schema.discriminator;
117
+ const discriminatorValue = source[discriminator];
118
+ const matchingSchema = schema.options.find(option => {
119
+ return option.shape[discriminator] instanceof z.ZodLiteral && option.shape[discriminator].value === discriminatorValue;
120
+ });
121
+ if (!matchingSchema) {
122
+ // If no matching schema is found, use the first option as default
123
+ return processObject(schema.options[0], source);
124
+ }
125
+ return processObject(matchingSchema, source);
126
+ };
127
+ const processValue = (schema, value) => {
128
+ if (schema instanceof z.ZodObject) {
129
+ return processObject(schema, value);
130
+ }
131
+ else if (schema instanceof z.ZodArray) {
132
+ return processArray(schema, value);
133
+ }
134
+ else if (schema instanceof z.ZodDiscriminatedUnion) {
135
+ return processDiscriminatedUnion(schema, value);
136
+ }
137
+ else if (schema instanceof z.ZodUnion) {
138
+ return processUnion(schema, value);
139
+ }
140
+ else if (schema instanceof z.ZodBoolean) {
141
+ return typeof value === 'boolean' ? value : false;
142
+ }
143
+ else if (schema instanceof z.ZodMap) {
144
+ return processMap(schema, value);
145
+ }
146
+ else if (schema instanceof z.ZodNumber) {
147
+ return typeof value === 'number' ? value : (schema.minValue ?? 0);
148
+ }
149
+ else if (schema instanceof z.ZodRecord) {
150
+ return processRecord(schema, value);
151
+ }
152
+ else if (schema instanceof z.ZodSet) {
153
+ return processSet(schema, value);
154
+ }
155
+ else if (schema instanceof z.ZodString) {
156
+ return typeof value === 'string' ? value : '';
157
+ }
158
+ else if (schema instanceof z.ZodNullable) {
159
+ return value === null ? null : processValue(schema.unwrap(), value);
160
+ }
161
+ else {
162
+ return value;
163
+ }
164
+ };
165
+ const processMap = (schema, source) => {
166
+ if (!(source instanceof Map)) {
167
+ return new Map();
168
+ }
169
+ const valueSchema = schema._def.valueType;
170
+ const result = new Map();
171
+ source.forEach((value, key) => {
172
+ result.set(key, processValue(valueSchema, value));
173
+ });
174
+ return result;
175
+ };
176
+ const processObject = (schema, source) => {
177
+ const result = {};
178
+ const shape = schema.shape;
179
+ for (const [key, fieldSchema] of Object.entries(shape)) {
180
+ if (key in source) {
181
+ result[key] = processValue(fieldSchema, source[key]);
182
+ }
183
+ else {
184
+ result[key] = getDefaultValue(fieldSchema);
185
+ }
186
+ }
187
+ return result;
188
+ };
189
+ const processRecord = (schema, source) => {
190
+ if (typeof source !== 'object' || source === null) {
191
+ return {};
192
+ }
193
+ const valueSchema = schema._def.valueType;
194
+ const result = {};
195
+ for (const key in source) {
196
+ result[key] = processValue(valueSchema, source[key]);
197
+ }
198
+ return result;
199
+ };
200
+ const processSet = (schema, source) => {
201
+ if (!(source instanceof Set)) {
202
+ return new Set();
203
+ }
204
+ const valueSchema = schema._def.valueType;
205
+ const result = new Set();
206
+ for (const value of source) {
207
+ result.add(processValue(valueSchema, value));
208
+ }
209
+ return result;
210
+ };
211
+ const processUnion = (schema, source) => {
212
+ for (const optionSchema of schema._def.options) {
213
+ try {
214
+ const parsed = optionSchema.safeParse(source);
215
+ if (parsed.success) {
216
+ return processValue(optionSchema, source);
217
+ }
218
+ }
219
+ catch {
220
+ // If parsing fails, try the next option
221
+ }
222
+ }
223
+ // If no option matches, return the default value of the first option
224
+ return getDefaultValue(schema._def.options[0]);
225
+ };
226
+ if (schema instanceof z.ZodDiscriminatedUnion) {
227
+ return processDiscriminatedUnion(schema, source);
228
+ }
229
+ if (schema instanceof z.ZodEffects) {
230
+ schema = schema.innerType();
231
+ }
232
+ return processValue(schema, source);
233
+ };
234
+ export default defaultInstance;
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "dependencies": {
3
+ "zod": "^3.23.8"
4
+ },
5
+ "devDependencies": {
6
+ "@types/lodash": "^4.17.12",
7
+ "@types/node": "^22.7.7",
8
+ "prettier": "^3.3.3",
9
+ "typescript": "^5.6.3",
10
+ "vitest": "^2.1.3"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "license": "MIT",
16
+ "main": "dist/index.js",
17
+ "name": "use-zod-default",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/feliperohdee/use-zod-default"
21
+ },
22
+ "scripts": {
23
+ "build": "rm -rf dist && tsc -p tsconfig.json",
24
+ "lint": "prettier --write . && yarn tsc",
25
+ "npm-publish": "yarn test --run && yarn build && yarn version --patch --no-git-tag-version && yarn publish --non-interactive",
26
+ "test": "vitest"
27
+ },
28
+ "version": "1.0.1"
29
+ }