@parziva-1/zod-mongoose 5.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/LICENSE +22 -0
- package/README.md +320 -0
- package/dist/index.d.ts +234 -0
- package/dist/index.js +703 -0
- package/dist/index.js.map +1 -0
- package/package.json +93 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Zodyac (bebrasmell) and contributors
|
|
4
|
+
Copyright (c) 2026 Jaime Linares / spybee-sas (fork additions)
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
# @parziva-1/zod-mongoose
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
Convert [Zod](https://www.npmjs.com/package/zod) object schemas into
|
|
9
|
+
[Mongoose](https://www.npmjs.com/package/mongoose) schemas, keeping a single
|
|
10
|
+
source of truth for both runtime validation and your database layer.
|
|
11
|
+
|
|
12
|
+
## Why this fork exists
|
|
13
|
+
|
|
14
|
+
This is a fork of the excellent
|
|
15
|
+
[`@zodyac/zod-mongoose`](https://www.npmjs.com/package/@zodyac/zod-mongoose)
|
|
16
|
+
(upstream: [git-zodyac/mongoose](https://github.com/git-zodyac/mongoose)),
|
|
17
|
+
created to add **Zod v4 support**. As of this writing, upstream is still on
|
|
18
|
+
Zod v3 internals and has not published a v4-compatible release. This fork
|
|
19
|
+
ports the schema introspection layer to Zod v4's runtime shape
|
|
20
|
+
(`schema._zod.def`) while keeping the public API unchanged, so it's a drop-in
|
|
21
|
+
replacement once your own Zod schemas are upgraded to v4.
|
|
22
|
+
|
|
23
|
+
All credit for the original design and implementation goes to the upstream
|
|
24
|
+
`zodyac` project and its contributors (see [LICENSE](./LICENSE)).
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install @parziva-1/zod-mongoose
|
|
30
|
+
pnpm add @parziva-1/zod-mongoose
|
|
31
|
+
yarn add @parziva-1/zod-mongoose
|
|
32
|
+
bun add @parziva-1/zod-mongoose
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Peer dependencies: `zod@^4.0.0` and `mongoose@^8.20.2 || ^9.0.0`.
|
|
36
|
+
|
|
37
|
+
## Migrating from `@zodyac/zod-mongoose`
|
|
38
|
+
|
|
39
|
+
- **Package name**: import from `@parziva-1/zod-mongoose` instead of
|
|
40
|
+
`@zodyac/zod-mongoose`.
|
|
41
|
+
- **Zod version**: you must be on `zod@^4.0.0`. Zod v3 is not supported at
|
|
42
|
+
all - stay on the upstream package (or this fork's `4.x` line, if you need
|
|
43
|
+
an intermediate step) until your schemas are migrated.
|
|
44
|
+
- **Module format**: this package is **ESM-only** starting with v5 (no CJS
|
|
45
|
+
build). If you `require()` it from CommonJS, use a dynamic
|
|
46
|
+
`await import("@parziva-1/zod-mongoose")` instead.
|
|
47
|
+
- **Public API is unchanged**: `zodSchema`, `zodSchemaRaw`, `extendZod`,
|
|
48
|
+
`zId`, `zUUID`, `.unique()`, `.sparse()`, `.ref()`, `.refPath()` all keep
|
|
49
|
+
their existing signatures.
|
|
50
|
+
|
|
51
|
+
See [CHANGELOG.md](./CHANGELOG.md) for the full list of changes.
|
|
52
|
+
|
|
53
|
+
## Quick start
|
|
54
|
+
|
|
55
|
+
First, extend Zod with `extendZod`, then create your Zod schema:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
import { z } from "zod";
|
|
59
|
+
import { extendZod, zId, zUUID } from "@parziva-1/zod-mongoose";
|
|
60
|
+
|
|
61
|
+
extendZod(z);
|
|
62
|
+
|
|
63
|
+
const zUser = z.object({
|
|
64
|
+
name: z.string().min(3).max(255),
|
|
65
|
+
age: z.number().min(18).max(100),
|
|
66
|
+
active: z.boolean().default(false),
|
|
67
|
+
access: z.enum(["admin", "user"]).default("user"),
|
|
68
|
+
companyId: zId("Company"),
|
|
69
|
+
wearable: zUUID(),
|
|
70
|
+
address: z.object({
|
|
71
|
+
street: z.string(),
|
|
72
|
+
city: z.string(),
|
|
73
|
+
state: z.enum(["CA", "NY", "TX"]),
|
|
74
|
+
}),
|
|
75
|
+
tags: z.array(z.string()),
|
|
76
|
+
createdAt: z.date(),
|
|
77
|
+
updatedAt: z.date(),
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Then convert it to a Mongoose schema and connect a model:
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { zodSchema } from "@parziva-1/zod-mongoose";
|
|
85
|
+
import { model } from "mongoose";
|
|
86
|
+
|
|
87
|
+
const schema = zodSchema(zUser);
|
|
88
|
+
const userModel = model("User", schema);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
That's it - now use your Mongoose model as usual:
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
userModel.find({ name: "John" });
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
> [!NOTE]
|
|
98
|
+
> `extendZod` should be called once for the whole application.
|
|
99
|
+
|
|
100
|
+
## Features
|
|
101
|
+
|
|
102
|
+
See [SUPPORTED.md](./SUPPORTED.md) for the full, authoritative type/feature
|
|
103
|
+
support matrix. Summary:
|
|
104
|
+
|
|
105
|
+
- Basic types (string, number, boolean, date)
|
|
106
|
+
- Nested objects, subdocuments, and arrays
|
|
107
|
+
- Tuples (`z.tuple()`, including `.rest()`), stored as a length/type-validated
|
|
108
|
+
array
|
|
109
|
+
- Enums and native (TypeScript) enums
|
|
110
|
+
- Literals (`z.literal()`), including Zod v4's multi-value form
|
|
111
|
+
- Discriminated unions (`z.discriminatedUnion()`)
|
|
112
|
+
- Intersections (`z.intersection()`) of two object shapes, merged into one
|
|
113
|
+
flat sub-schema
|
|
114
|
+
- Recursive / self-referencing schemas (`z.lazy()`)
|
|
115
|
+
- Fallback values (`z.catch()`)
|
|
116
|
+
- Default values (static and factory-function forms)
|
|
117
|
+
- Maps and records (records become `Map`)
|
|
118
|
+
- ObjectId and UUID, with `ref` / `refPath` support
|
|
119
|
+
- `ZodAny` and `ZodUnknown` as `SchemaTypes.Mixed`
|
|
120
|
+
- Validation via `.refine()` for String, Number, Date - including a
|
|
121
|
+
refinement applied both before *and* after a single `.transform()`
|
|
122
|
+
- `.unique()` / `.sparse()` for String, Number, Date, ObjectId, and UUID
|
|
123
|
+
- `.transform()` / `z.preprocess()`
|
|
124
|
+
|
|
125
|
+
Known limitations: plain unions (`z.union()`) pick the first inner type
|
|
126
|
+
(Mongoose has no native union type), and intersections only support merging
|
|
127
|
+
two object-shape schemas - see [SUPPORTED.md](./SUPPORTED.md) for the full
|
|
128
|
+
matrix and the design notes behind each non-obvious mapping (tuples,
|
|
129
|
+
literals, discriminated unions, `z.lazy()`, `z.catch()`).
|
|
130
|
+
|
|
131
|
+
## Checking schemas
|
|
132
|
+
|
|
133
|
+
To make sure nothing is missing, inspect `Schema.obj`:
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// schema is a mongoose schema
|
|
137
|
+
console.log(schema.obj);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Raw object
|
|
141
|
+
|
|
142
|
+
If you want the raw object produced from a Zod schema so you can modify it
|
|
143
|
+
before constructing the `Schema`, use `zodSchemaRaw`:
|
|
144
|
+
|
|
145
|
+
```typescript
|
|
146
|
+
import { extendZod, zodSchemaRaw } from "@parziva-1/zod-mongoose";
|
|
147
|
+
import { model, Schema } from "mongoose";
|
|
148
|
+
import { z } from "zod";
|
|
149
|
+
|
|
150
|
+
extendZod(z);
|
|
151
|
+
|
|
152
|
+
const schema = zodSchemaRaw(zUser);
|
|
153
|
+
schema.age.index = true;
|
|
154
|
+
|
|
155
|
+
const userModel = model(
|
|
156
|
+
"User",
|
|
157
|
+
new Schema(schema, {
|
|
158
|
+
timestamps: true,
|
|
159
|
+
}),
|
|
160
|
+
);
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## ObjectID and UUID
|
|
164
|
+
|
|
165
|
+
Use `zId(ref?: string)` and `zUUID(ref?: string)` to describe ObjectID and
|
|
166
|
+
UUID fields, and to reference another collection:
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
import { extendZod, zId, zUUID } from "@parziva-1/zod-mongoose";
|
|
170
|
+
import { z } from "zod";
|
|
171
|
+
|
|
172
|
+
extendZod(z);
|
|
173
|
+
|
|
174
|
+
const zUser = z.object({
|
|
175
|
+
// Just the ID
|
|
176
|
+
someId: zId(),
|
|
177
|
+
wearable: zUUID(),
|
|
178
|
+
|
|
179
|
+
// With reference
|
|
180
|
+
companyId: zId("Company"), // equivalent to zId().ref("Company")
|
|
181
|
+
facilityId: zId().ref("Facility"),
|
|
182
|
+
device: zUUID("Device"), // equivalent to zUUID().ref("Device")
|
|
183
|
+
badgeId: zUUID().ref("Badge"),
|
|
184
|
+
|
|
185
|
+
// `refPath` support
|
|
186
|
+
storeId: zId().refPath("store"),
|
|
187
|
+
store: z.string(),
|
|
188
|
+
proxyId: zUUID().refPath("proxy"),
|
|
189
|
+
proxy: z.string(),
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Validation
|
|
194
|
+
|
|
195
|
+
Use Zod refinement to validate your Mongoose models:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { z } from "zod";
|
|
199
|
+
import { extendZod, zodSchema } from "@parziva-1/zod-mongoose";
|
|
200
|
+
|
|
201
|
+
extendZod(z);
|
|
202
|
+
|
|
203
|
+
const zUser = z.object({
|
|
204
|
+
phone: z
|
|
205
|
+
.string()
|
|
206
|
+
.refine((v) => /^\d{3}-\d{3}-\d{4}$/.test(v), "Invalid phone number"),
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## Unique fields
|
|
211
|
+
|
|
212
|
+
To make a String, Number, Date, ObjectId, or UUID field unique, call
|
|
213
|
+
`.unique()`:
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
const zUser = z.object({
|
|
217
|
+
phone: z.string().unique(),
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Sparse fields
|
|
222
|
+
|
|
223
|
+
To make a String, Number, Date, ObjectId, or UUID field sparse, call
|
|
224
|
+
`.sparse()`:
|
|
225
|
+
|
|
226
|
+
```typescript
|
|
227
|
+
const zUser = z.object({
|
|
228
|
+
email: z.string().sparse(),
|
|
229
|
+
// combine with unique:
|
|
230
|
+
// email: z.string().unique().sparse(),
|
|
231
|
+
});
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Warnings
|
|
235
|
+
|
|
236
|
+
### ZodUnion types
|
|
237
|
+
|
|
238
|
+
Plain unions are not supported by Mongoose. A union field is converted to its
|
|
239
|
+
*first* inner type:
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const zUser = z.object({
|
|
243
|
+
access: z.union([z.string(), z.number()]),
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// Becomes:
|
|
247
|
+
// { access: { type: String } }
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
If you need every variant validated correctly, use `z.discriminatedUnion()`
|
|
251
|
+
instead - see below.
|
|
252
|
+
|
|
253
|
+
### ZodDiscriminatedUnion
|
|
254
|
+
|
|
255
|
+
`z.discriminatedUnion()` maps to `SchemaTypes.Mixed`, validated by re-parsing
|
|
256
|
+
the assigned value with the original discriminated-union schema itself
|
|
257
|
+
(Mongoose has no native way to represent a discriminated shape on a plain
|
|
258
|
+
nested field):
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
const zEvent = z.object({
|
|
262
|
+
payload: z.discriminatedUnion("type", [
|
|
263
|
+
z.object({ type: z.literal("email"), address: z.string() }),
|
|
264
|
+
z.object({ type: z.literal("sms"), phone: z.string() }),
|
|
265
|
+
]),
|
|
266
|
+
});
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### ZodTuple
|
|
270
|
+
|
|
271
|
+
`z.tuple()` maps to a Mongoose array of `Mixed`, with a `validate` enforcing
|
|
272
|
+
exact arity (or a minimum arity, if you used `.rest()`) and the correct type
|
|
273
|
+
at each position:
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
const zPoint = z.object({
|
|
277
|
+
coords: z.tuple([z.number(), z.number()]),
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### ZodIntersection
|
|
282
|
+
|
|
283
|
+
`z.intersection()` is supported only when merging two object-shape schemas -
|
|
284
|
+
the two shapes are flattened into one Mongoose sub-schema. Intersecting
|
|
285
|
+
non-object schemas (e.g. `z.string().and(z.number())`) throws, since there's
|
|
286
|
+
no sane flat-field representation for it.
|
|
287
|
+
|
|
288
|
+
### ZodLazy
|
|
289
|
+
|
|
290
|
+
`z.lazy()` supports recursive/self-referencing schemas (e.g. a comment with
|
|
291
|
+
nested replies of the same shape) by unrolling the recursive getter up to a
|
|
292
|
+
fixed depth (5 levels), then falling back to `Mixed` beyond that - Mongoose
|
|
293
|
+
has no native concept of an infinitely recursive embedded subdocument.
|
|
294
|
+
|
|
295
|
+
### ZodAny / ZodUnknown
|
|
296
|
+
|
|
297
|
+
Both are converted to `SchemaTypes.Mixed`. Prefer a more specific type when
|
|
298
|
+
possible.
|
|
299
|
+
|
|
300
|
+
### ZodRecord
|
|
301
|
+
|
|
302
|
+
`ZodRecord` is converted to `Map`. Prefer `z.map()` directly when possible.
|
|
303
|
+
|
|
304
|
+
## Contributing
|
|
305
|
+
|
|
306
|
+
Feel free to open issues and pull requests!
|
|
307
|
+
|
|
308
|
+
- Fork the repository
|
|
309
|
+
- Install the [Biome](https://biomejs.dev/) VS Code extension
|
|
310
|
+
- Install dependencies: `npm install`
|
|
311
|
+
- Make your changes
|
|
312
|
+
- Run the full check suite: `npm run check` (lint, typecheck, test, build,
|
|
313
|
+
attw, publint)
|
|
314
|
+
- Commit and push your changes
|
|
315
|
+
- Open a pull request
|
|
316
|
+
|
|
317
|
+
## License
|
|
318
|
+
|
|
319
|
+
MIT - see [LICENSE](./LICENSE). Includes the original upstream copyright
|
|
320
|
+
notice plus this fork's additions.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { Schema, SchemaDefinition, SchemaOptions, SchemaTypeOptions, SchemaTypes, Types } from "mongoose";
|
|
2
|
+
import { ZodObject, ZodRawShape, ZodType, z } from "zod";
|
|
3
|
+
//#region src/mongoose.types.d.ts
|
|
4
|
+
declare namespace zm {
|
|
5
|
+
interface zID extends z.ZodUnion<[z.ZodString, z.ZodType<Types.ObjectId, Types.ObjectId>]> {
|
|
6
|
+
__zm_type: "ObjectId";
|
|
7
|
+
__zm_ref?: string;
|
|
8
|
+
__zm_refPath?: string;
|
|
9
|
+
ref: (ref: string) => zID;
|
|
10
|
+
unique: (val?: boolean) => zID;
|
|
11
|
+
sparse: (val?: boolean) => zID;
|
|
12
|
+
refPath: (ref: string) => zID;
|
|
13
|
+
}
|
|
14
|
+
interface zUUID extends z.ZodUnion<[z.ZodString, z.ZodType<Types.UUID, Types.UUID>]> {
|
|
15
|
+
__zm_type: "UUID";
|
|
16
|
+
__zm_ref?: string;
|
|
17
|
+
__zm_refPath?: string;
|
|
18
|
+
unique: (val?: boolean) => zUUID;
|
|
19
|
+
sparse: (val?: boolean) => zUUID;
|
|
20
|
+
ref: (ref: string) => zUUID;
|
|
21
|
+
refPath: (ref: string) => zUUID;
|
|
22
|
+
}
|
|
23
|
+
type mDefault<T> = () => T;
|
|
24
|
+
interface _Field<T> {
|
|
25
|
+
required: boolean;
|
|
26
|
+
default?: mDefault<T>;
|
|
27
|
+
validate?: EffectValidator<T> | EffectValidator<T>[];
|
|
28
|
+
set?: (v: unknown) => T;
|
|
29
|
+
}
|
|
30
|
+
interface mString extends _Field<string> {
|
|
31
|
+
type: StringConstructor;
|
|
32
|
+
unique: boolean;
|
|
33
|
+
sparse: boolean;
|
|
34
|
+
enum?: string[];
|
|
35
|
+
match?: RegExp;
|
|
36
|
+
minLength?: number;
|
|
37
|
+
maxLength?: number;
|
|
38
|
+
}
|
|
39
|
+
interface mNumber extends _Field<number> {
|
|
40
|
+
type: NumberConstructor;
|
|
41
|
+
unique: boolean;
|
|
42
|
+
sparse: boolean;
|
|
43
|
+
min?: number;
|
|
44
|
+
max?: number;
|
|
45
|
+
}
|
|
46
|
+
interface mBoolean extends _Field<boolean> {
|
|
47
|
+
type: BooleanConstructor;
|
|
48
|
+
}
|
|
49
|
+
interface mDate extends _Field<Date> {
|
|
50
|
+
type: DateConstructor;
|
|
51
|
+
unique: boolean;
|
|
52
|
+
sparse: boolean;
|
|
53
|
+
}
|
|
54
|
+
interface mObjectId extends _Field<Types.ObjectId> {
|
|
55
|
+
type: typeof SchemaTypes.ObjectId;
|
|
56
|
+
unique?: boolean;
|
|
57
|
+
sparse?: boolean;
|
|
58
|
+
ref?: string;
|
|
59
|
+
refPath?: string;
|
|
60
|
+
}
|
|
61
|
+
interface mUUID extends _Field<Types.UUID> {
|
|
62
|
+
type: typeof SchemaTypes.UUID;
|
|
63
|
+
unique?: boolean;
|
|
64
|
+
sparse?: boolean;
|
|
65
|
+
ref?: string;
|
|
66
|
+
refPath?: string;
|
|
67
|
+
}
|
|
68
|
+
interface mArray<K> extends _Field<K[]> {
|
|
69
|
+
type: [_Field<K>];
|
|
70
|
+
}
|
|
71
|
+
interface mMixed<T> extends _Field<T> {
|
|
72
|
+
type: typeof SchemaTypes.Mixed;
|
|
73
|
+
}
|
|
74
|
+
type Constructor = StringConstructor | NumberConstructor | ObjectConstructor | DateConstructor | BooleanConstructor | BigIntConstructor | typeof SchemaTypes.ObjectId | typeof SchemaTypes.UUID;
|
|
75
|
+
interface mMap<T, K> extends _Field<Map<T, K>> {
|
|
76
|
+
type: typeof Map;
|
|
77
|
+
of?: zm._Field<K>;
|
|
78
|
+
}
|
|
79
|
+
interface mSubdocument<T> extends _Field<T> {
|
|
80
|
+
type: _Schema<T>;
|
|
81
|
+
}
|
|
82
|
+
type mField = mString | mNumber | mBoolean | mDate | mObjectId | mUUID | mMixed<unknown> | mArray<unknown> | _Schema<unknown> | mMap<unknown, unknown> | mSubdocument<unknown>;
|
|
83
|
+
type _Schema<T> = SchemaDefinition & { [K in keyof T]: (_Field<T[K]> & SchemaTypeOptions<T[K]>) | _Schema<T[K]>; };
|
|
84
|
+
type UnwrapZodType<T> = T extends ZodType<infer K> ? K : never;
|
|
85
|
+
type EffectValidator<T> = {
|
|
86
|
+
validator: (v: T) => boolean;
|
|
87
|
+
message?: string;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* A field's `validate` option accepts either a single validator (the
|
|
91
|
+
* common case) or an array of them - Mongoose runs every entry in the
|
|
92
|
+
* array and reports all failing messages. Used when a field carries more
|
|
93
|
+
* than one `.refine()` check (e.g. one before and one after a
|
|
94
|
+
* `.transform()`).
|
|
95
|
+
*/
|
|
96
|
+
type mValidate<T> = EffectValidator<T> | EffectValidator<T>[];
|
|
97
|
+
}
|
|
98
|
+
//#endregion
|
|
99
|
+
//#region src/extension.d.ts
|
|
100
|
+
declare module "zod" {
|
|
101
|
+
interface ZodString {
|
|
102
|
+
unique: (arg?: boolean) => ZodString;
|
|
103
|
+
sparse: (arg?: boolean) => ZodString;
|
|
104
|
+
}
|
|
105
|
+
interface ZodNumber {
|
|
106
|
+
unique: (arg?: boolean) => ZodNumber;
|
|
107
|
+
sparse: (arg?: boolean) => ZodNumber;
|
|
108
|
+
}
|
|
109
|
+
interface ZodDate {
|
|
110
|
+
unique: (arg?: boolean) => ZodDate;
|
|
111
|
+
sparse: (arg?: boolean) => ZodDate;
|
|
112
|
+
}
|
|
113
|
+
interface ZodType {
|
|
114
|
+
__zm_type?: string;
|
|
115
|
+
__zm_ref?: string;
|
|
116
|
+
__zm_refPath?: string;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Extends the Zod library with additional functionality.
|
|
121
|
+
*
|
|
122
|
+
* This function modifies the Zod library to add custom mongoose-specific
|
|
123
|
+
* metadata methods. It ensures that the extension is only applied once.
|
|
124
|
+
*
|
|
125
|
+
* @param z_0 - The Zod library to extend.
|
|
126
|
+
*
|
|
127
|
+
* @remarks
|
|
128
|
+
* - Adds a `unique` method to `ZodString`, `ZodNumber`, and `ZodDate` to mark them as unique.
|
|
129
|
+
* - Adds a `sparse` method to `ZodString`, `ZodNumber`, and `ZodDate` to mark them as sparse.
|
|
130
|
+
*
|
|
131
|
+
* As of Zod v4, refinement metadata (validator + message) no longer needs to
|
|
132
|
+
* be captured via a `refine()` override: Zod's own internal `checks` array
|
|
133
|
+
* already exposes the validator function and error message directly, so
|
|
134
|
+
* `zodSchema()` reads that straight off the schema instead.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* ```typescript
|
|
138
|
+
* import { z } from "zod";
|
|
139
|
+
* import { extendZod } from "./extension";
|
|
140
|
+
*
|
|
141
|
+
* extendZod(z);
|
|
142
|
+
*
|
|
143
|
+
* const schema = z.object({
|
|
144
|
+
* name: z.string().unique();
|
|
145
|
+
* });
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
declare function extendZod(z_0: typeof z): void;
|
|
149
|
+
type TzmId = ReturnType<typeof createId> & {
|
|
150
|
+
unique: (arg?: boolean) => TzmId;
|
|
151
|
+
sparse: (arg?: boolean) => TzmId;
|
|
152
|
+
ref: (arg: string) => TzmId;
|
|
153
|
+
refPath: (arg: string) => TzmId;
|
|
154
|
+
};
|
|
155
|
+
declare const createId: () => z.ZodUnion<[z.ZodString, z.ZodCustom<Types.ObjectId, Types.ObjectId>]>;
|
|
156
|
+
declare const zId: (ref?: string) => TzmId;
|
|
157
|
+
type TzmUUID = ReturnType<typeof createUUID> & {
|
|
158
|
+
unique: (arg?: boolean) => TzmUUID;
|
|
159
|
+
sparse: (arg?: boolean) => TzmUUID;
|
|
160
|
+
ref: (arg: string) => TzmUUID;
|
|
161
|
+
refPath: (arg: string) => TzmUUID;
|
|
162
|
+
};
|
|
163
|
+
declare const createUUID: () => z.ZodUnion<[z.ZodString, z.ZodCustom<Types.UUID, Types.UUID>]>;
|
|
164
|
+
declare const zUUID$1: (ref?: string) => TzmUUID;
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/index.d.ts
|
|
167
|
+
/**
|
|
168
|
+
* Converts a Zod schema to a Mongoose schema
|
|
169
|
+
* @param schema zod schema to parse
|
|
170
|
+
* @returns mongoose schema
|
|
171
|
+
*
|
|
172
|
+
* @example
|
|
173
|
+
* import { extendZod, zodSchema } from '@zodyac/zod-mongoose';
|
|
174
|
+
* import { model } from 'mongoose';
|
|
175
|
+
* import { z } from 'zod';
|
|
176
|
+
*
|
|
177
|
+
* extendZod(z);
|
|
178
|
+
*
|
|
179
|
+
* const zUser = z.object({
|
|
180
|
+
* name: z.string().min(3).max(255),
|
|
181
|
+
* age: z.number().min(18).max(100),
|
|
182
|
+
* active: z.boolean().default(false),
|
|
183
|
+
* access: z.enum(['admin', 'user']).default('user'),
|
|
184
|
+
* companyId: zId('Company'),
|
|
185
|
+
* address: z.object({
|
|
186
|
+
* street: z.string(),
|
|
187
|
+
* city: z.string(),
|
|
188
|
+
* state: z.enum(['CA', 'NY', 'TX']),
|
|
189
|
+
* }),
|
|
190
|
+
* tags: z.array(z.string()),
|
|
191
|
+
* createdAt: z.date(),
|
|
192
|
+
* updatedAt: z.date(),
|
|
193
|
+
* });
|
|
194
|
+
*
|
|
195
|
+
* const schema = zodSchema(zDoc);
|
|
196
|
+
* const userModel = model('User', schema);
|
|
197
|
+
*/
|
|
198
|
+
declare function zodSchema<T extends ZodRawShape>(schema: ZodObject<T>, options?: SchemaOptions<any>): Schema<z.infer<typeof schema>>;
|
|
199
|
+
/**
|
|
200
|
+
* Converts a Zod schema to a raw Mongoose schema object
|
|
201
|
+
* @param schema zod schema to parse
|
|
202
|
+
* @returns mongoose schema
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* import { extendZod, zodSchemaRaw } from '@zodyac/zod-mongoose';
|
|
206
|
+
* import { model, Schema } from 'mongoose';
|
|
207
|
+
* import { z } from 'zod';
|
|
208
|
+
*
|
|
209
|
+
* extendZod(z);
|
|
210
|
+
*
|
|
211
|
+
* const zUser = z.object({
|
|
212
|
+
* name: z.string().min(3).max(255),
|
|
213
|
+
* age: z.number().min(18).max(100),
|
|
214
|
+
* active: z.boolean().default(false),
|
|
215
|
+
* access: z.enum(['admin', 'user']).default('user'),
|
|
216
|
+
* companyId: zId('Company'),
|
|
217
|
+
* address: z.object({
|
|
218
|
+
* street: z.string(),
|
|
219
|
+
* city: z.string(),
|
|
220
|
+
* state: z.enum(['CA', 'NY', 'TX']),
|
|
221
|
+
* }),
|
|
222
|
+
* tags: z.array(z.string()),
|
|
223
|
+
* createdAt: z.date(),
|
|
224
|
+
* updatedAt: z.date(),
|
|
225
|
+
* });
|
|
226
|
+
*
|
|
227
|
+
* const rawSchema = zodSchemaRaw(zDoc);
|
|
228
|
+
* const schema = new Schema(rawSchema);
|
|
229
|
+
* const userModel = model('User', schema);
|
|
230
|
+
*/
|
|
231
|
+
declare function zodSchemaRaw<T extends ZodRawShape>(schema: ZodObject<T>): zm._Schema<T>;
|
|
232
|
+
//#endregion
|
|
233
|
+
export { TzmId, TzmUUID, zodSchema as default, zodSchema, extendZod, zId, zUUID$1 as zUUID, zodSchemaRaw };
|
|
234
|
+
//# sourceMappingURL=index.d.ts.map
|