@zodmon/core 0.3.0 → 0.5.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.cjs +364 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +558 -138
- package/dist/index.d.ts +558 -138
- package/dist/index.js +356 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ObjectId,
|
|
2
|
-
import { ZodPipe, ZodCustom, ZodTransform, z } from 'zod';
|
|
1
|
+
import { ObjectId, FindCursor, Collection, MongoClientOptions } from 'mongodb';
|
|
2
|
+
import { ZodPipe, ZodCustom, ZodTransform, z, ZodDefault } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Options controlling how a field-level MongoDB index is created.
|
|
@@ -225,10 +225,12 @@ type CompoundIndexDefinition<TKeys extends string = string> = {
|
|
|
225
225
|
type FieldIndexDefinition = {
|
|
226
226
|
field: string;
|
|
227
227
|
} & IndexOptions;
|
|
228
|
+
/** Validation strategy for documents read from or written to MongoDB. */
|
|
229
|
+
type ValidationMode = 'strict' | 'strip' | 'passthrough';
|
|
228
230
|
/** Options passed to collection() as the third argument. */
|
|
229
231
|
type CollectionOptions<TKeys extends string = string> = {
|
|
230
232
|
indexes?: CompoundIndexDefinition<TKeys>[];
|
|
231
|
-
validation?:
|
|
233
|
+
validation?: ValidationMode;
|
|
232
234
|
warnUnindexedQueries?: boolean;
|
|
233
235
|
schemaVersion?: number;
|
|
234
236
|
migrate?: (doc: Record<string, unknown>, version: number) => Record<string, unknown>;
|
|
@@ -242,7 +244,7 @@ type CollectionOptions<TKeys extends string = string> = {
|
|
|
242
244
|
* This allows custom id types (nanoid, UUID, etc.) when needed.
|
|
243
245
|
*/
|
|
244
246
|
type ResolvedShape<TShape extends z.core.$ZodShape> = '_id' extends keyof TShape ? TShape : {
|
|
245
|
-
_id: ZodObjectId
|
|
247
|
+
_id: ZodDefault<ZodObjectId>;
|
|
246
248
|
} & TShape;
|
|
247
249
|
/**
|
|
248
250
|
* The document type inferred from a collection definition.
|
|
@@ -256,6 +258,23 @@ type ResolvedShape<TShape extends z.core.$ZodShape> = '_id' extends keyof TShape
|
|
|
256
258
|
type InferDocument<TDef extends {
|
|
257
259
|
readonly schema: z.ZodType;
|
|
258
260
|
}> = z.infer<TDef['schema']>;
|
|
261
|
+
/**
|
|
262
|
+
* The input type for inserting a document into a collection.
|
|
263
|
+
*
|
|
264
|
+
* Uses Zod's input type so fields with `.default()` (including the
|
|
265
|
+
* auto-generated `_id`) are optional. Custom `_id` fields without
|
|
266
|
+
* a default remain required.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```ts
|
|
270
|
+
* // Auto-generated _id — optional on insert
|
|
271
|
+
* type Insert = InferInsert<typeof Users>
|
|
272
|
+
* // { _id?: string | ObjectId; name: string; role?: string }
|
|
273
|
+
* ```
|
|
274
|
+
*/
|
|
275
|
+
type InferInsert<TDef extends {
|
|
276
|
+
readonly schema: z.ZodType;
|
|
277
|
+
}> = z.input<TDef['schema']>;
|
|
259
278
|
/**
|
|
260
279
|
* The immutable definition object returned by collection().
|
|
261
280
|
* Holds everything needed to later create a live collection handle.
|
|
@@ -271,6 +290,337 @@ type CollectionDefinition<TShape extends z.core.$ZodShape = z.core.$ZodShape> =
|
|
|
271
290
|
/** Erased collection type for use in generic contexts. */
|
|
272
291
|
type AnyCollection = CollectionDefinition<z.core.$ZodShape>;
|
|
273
292
|
|
|
293
|
+
/**
|
|
294
|
+
* Type-safe sort specification for a document type.
|
|
295
|
+
*
|
|
296
|
+
* Constrains sort keys to top-level fields of `T` with direction `1` (ascending)
|
|
297
|
+
* or `-1` (descending). Dot-path sorts deferred to v1.0.
|
|
298
|
+
*
|
|
299
|
+
* @example
|
|
300
|
+
* ```ts
|
|
301
|
+
* const sort: TypedSort<User> = { name: 1, createdAt: -1 }
|
|
302
|
+
* ```
|
|
303
|
+
*/
|
|
304
|
+
type TypedSort<T> = Partial<Record<keyof T & string, 1 | -1>>;
|
|
305
|
+
/**
|
|
306
|
+
* Type-safe cursor wrapping MongoDB's `FindCursor`.
|
|
307
|
+
*
|
|
308
|
+
* Provides chainable query modifiers (`sort`, `skip`, `limit`) that return
|
|
309
|
+
* `this` for fluent chaining, and terminal methods (`toArray`,
|
|
310
|
+
* `[Symbol.asyncIterator]`) that validate each document against the
|
|
311
|
+
* collection's Zod schema before returning.
|
|
312
|
+
*
|
|
313
|
+
* Created by {@link find} — do not construct directly.
|
|
314
|
+
*
|
|
315
|
+
* @typeParam TDef - The collection definition type, used to infer the document type.
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```ts
|
|
319
|
+
* const docs = await find(users, { role: 'admin' })
|
|
320
|
+
* .sort({ name: 1 })
|
|
321
|
+
* .limit(10)
|
|
322
|
+
* .toArray()
|
|
323
|
+
* ```
|
|
324
|
+
*/
|
|
325
|
+
declare class TypedFindCursor<TDef extends AnyCollection> {
|
|
326
|
+
/** @internal */
|
|
327
|
+
private cursor;
|
|
328
|
+
/** @internal */
|
|
329
|
+
private schema;
|
|
330
|
+
/** @internal */
|
|
331
|
+
private collectionName;
|
|
332
|
+
/** @internal */
|
|
333
|
+
private mode;
|
|
334
|
+
/** @internal */
|
|
335
|
+
constructor(cursor: FindCursor<InferDocument<TDef>>, definition: TDef, mode: ValidationMode | false);
|
|
336
|
+
/**
|
|
337
|
+
* Set the sort order for the query.
|
|
338
|
+
*
|
|
339
|
+
* Only top-level document fields are accepted as sort keys.
|
|
340
|
+
* Values must be `1` (ascending) or `-1` (descending).
|
|
341
|
+
*
|
|
342
|
+
* @param spec - Sort specification mapping field names to sort direction.
|
|
343
|
+
* @returns `this` for chaining.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```ts
|
|
347
|
+
* find(users, {}).sort({ name: 1, age: -1 }).toArray()
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
sort(spec: TypedSort<InferDocument<TDef>>): this;
|
|
351
|
+
/**
|
|
352
|
+
* Skip the first `n` documents in the result set.
|
|
353
|
+
*
|
|
354
|
+
* @param n - Number of documents to skip.
|
|
355
|
+
* @returns `this` for chaining.
|
|
356
|
+
*
|
|
357
|
+
* @example
|
|
358
|
+
* ```ts
|
|
359
|
+
* find(users, {}).skip(10).limit(10).toArray() // page 2
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
skip(n: number): this;
|
|
363
|
+
/**
|
|
364
|
+
* Limit the number of documents returned.
|
|
365
|
+
*
|
|
366
|
+
* @param n - Maximum number of documents to return.
|
|
367
|
+
* @returns `this` for chaining.
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
* ```ts
|
|
371
|
+
* find(users, {}).limit(10).toArray() // at most 10 docs
|
|
372
|
+
* ```
|
|
373
|
+
*/
|
|
374
|
+
limit(n: number): this;
|
|
375
|
+
/**
|
|
376
|
+
* Execute the query and return all matching documents as an array.
|
|
377
|
+
*
|
|
378
|
+
* Each document is validated against the collection's Zod schema
|
|
379
|
+
* according to the resolved validation mode.
|
|
380
|
+
*
|
|
381
|
+
* @returns Array of validated documents.
|
|
382
|
+
* @throws {ZodmonValidationError} When a document fails schema validation in strict/strip mode.
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```ts
|
|
386
|
+
* const admins = await find(users, { role: 'admin' }).toArray()
|
|
387
|
+
* ```
|
|
388
|
+
*/
|
|
389
|
+
toArray(): Promise<InferDocument<TDef>[]>;
|
|
390
|
+
/**
|
|
391
|
+
* Async iterator for streaming documents one at a time.
|
|
392
|
+
*
|
|
393
|
+
* Each yielded document is validated against the collection's Zod schema.
|
|
394
|
+
* Memory-efficient for large result sets.
|
|
395
|
+
*
|
|
396
|
+
* @yields Validated documents one at a time.
|
|
397
|
+
* @throws {ZodmonValidationError} When a document fails schema validation.
|
|
398
|
+
*
|
|
399
|
+
* @example
|
|
400
|
+
* ```ts
|
|
401
|
+
* for await (const user of find(users, {})) {
|
|
402
|
+
* console.log(user.name)
|
|
403
|
+
* }
|
|
404
|
+
* ```
|
|
405
|
+
*/
|
|
406
|
+
[Symbol.asyncIterator](): AsyncGenerator<InferDocument<TDef>>;
|
|
407
|
+
/** @internal Validate a single raw document against the schema. */
|
|
408
|
+
private validateDoc;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Comparison operators for a field value of type `V`.
|
|
413
|
+
*
|
|
414
|
+
* Maps each MongoDB comparison operator to its expected value type.
|
|
415
|
+
* `$regex` is only available when `V` extends `string`.
|
|
416
|
+
*
|
|
417
|
+
* Used as the operator object that can be assigned to a field in {@link TypedFilter}.
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```ts
|
|
421
|
+
* // As a raw object (without builder functions)
|
|
422
|
+
* const filter: TypedFilter<User> = { age: { $gt: 25, $lte: 65 } }
|
|
423
|
+
*
|
|
424
|
+
* // $regex only available on string fields
|
|
425
|
+
* const filter: TypedFilter<User> = { name: { $regex: /^A/i } }
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
type ComparisonOperators<V> = {
|
|
429
|
+
/** Matches values equal to the specified value. */
|
|
430
|
+
$eq?: V;
|
|
431
|
+
/** Matches values not equal to the specified value. */
|
|
432
|
+
$ne?: V;
|
|
433
|
+
/** Matches values greater than the specified value. */
|
|
434
|
+
$gt?: V;
|
|
435
|
+
/** Matches values greater than or equal to the specified value. */
|
|
436
|
+
$gte?: V;
|
|
437
|
+
/** Matches values less than the specified value. */
|
|
438
|
+
$lt?: V;
|
|
439
|
+
/** Matches values less than or equal to the specified value. */
|
|
440
|
+
$lte?: V;
|
|
441
|
+
/** Matches any value in the specified array. */
|
|
442
|
+
$in?: V[];
|
|
443
|
+
/** Matches none of the values in the specified array. */
|
|
444
|
+
$nin?: V[];
|
|
445
|
+
/** Matches documents where the field exists (`true`) or does not exist (`false`). */
|
|
446
|
+
$exists?: boolean;
|
|
447
|
+
/** Negates a comparison operator. */
|
|
448
|
+
$not?: ComparisonOperators<V>;
|
|
449
|
+
} & (V extends string ? {
|
|
450
|
+
$regex?: RegExp | string;
|
|
451
|
+
} : unknown);
|
|
452
|
+
/** Depth counter for limiting dot-notation recursion. Index = current depth, value = next depth. */
|
|
453
|
+
type Prev = [never, 0, 1, 2];
|
|
454
|
+
/**
|
|
455
|
+
* Generates a union of all valid dot-separated paths for nested object fields in `T`.
|
|
456
|
+
*
|
|
457
|
+
* Recursion is limited to 3 levels deep to prevent TypeScript compilation performance issues.
|
|
458
|
+
* Only plain object fields are traversed — arrays, `Date`, `RegExp`, and `ObjectId` are
|
|
459
|
+
* treated as leaf nodes and do not produce sub-paths.
|
|
460
|
+
*
|
|
461
|
+
* @example
|
|
462
|
+
* ```ts
|
|
463
|
+
* type User = { address: { city: string; geo: { lat: number; lng: number } } }
|
|
464
|
+
*
|
|
465
|
+
* // DotPaths<User> = 'address.city' | 'address.geo' | 'address.geo.lat' | 'address.geo.lng'
|
|
466
|
+
* ```
|
|
467
|
+
*/
|
|
468
|
+
type DotPaths<T, Depth extends number = 3> = Depth extends 0 ? never : {
|
|
469
|
+
[K in keyof T & string]: NonNullable<T[K]> extends ReadonlyArray<unknown> | Date | RegExp | ObjectId ? never : NonNullable<T[K]> extends Record<string, unknown> ? `${K}.${keyof NonNullable<T[K]> & string}` | `${K}.${DotPaths<NonNullable<T[K]>, Prev[Depth]>}` : never;
|
|
470
|
+
}[keyof T & string];
|
|
471
|
+
/**
|
|
472
|
+
* Resolves the value type at a dot-separated path `P` within type `T`.
|
|
473
|
+
*
|
|
474
|
+
* Splits `P` on the first `.` and recursively descends into `T`'s nested types.
|
|
475
|
+
* Returns `never` if the path is invalid.
|
|
476
|
+
*
|
|
477
|
+
* @example
|
|
478
|
+
* ```ts
|
|
479
|
+
* type User = { address: { city: string; geo: { lat: number } } }
|
|
480
|
+
*
|
|
481
|
+
* // DotPathType<User, 'address.city'> = string
|
|
482
|
+
* // DotPathType<User, 'address.geo.lat'> = number
|
|
483
|
+
* ```
|
|
484
|
+
*/
|
|
485
|
+
type DotPathType<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? Rest extends keyof NonNullable<T[K]> ? NonNullable<T[K]>[Rest] : DotPathType<NonNullable<T[K]>, Rest> : never : P extends keyof T ? T[P] : never;
|
|
486
|
+
/**
|
|
487
|
+
* Strict type-safe MongoDB filter query type.
|
|
488
|
+
*
|
|
489
|
+
* Validates filter objects at compile time — rejects nonexistent fields, type mismatches,
|
|
490
|
+
* and invalid operator usage. Unlike the MongoDB driver's `Filter<T>`, does NOT allow
|
|
491
|
+
* arbitrary keys via `& Document`.
|
|
492
|
+
*
|
|
493
|
+
* Supports three forms of filter expressions:
|
|
494
|
+
* - **Direct field values** (implicit `$eq`): `{ name: 'Alice' }`
|
|
495
|
+
* - **Comparison operators**: `{ age: { $gt: 25 } }` or `{ age: $gt(25) }`
|
|
496
|
+
* - **Dot notation** for nested fields up to 3 levels: `{ 'address.city': 'NYC' }`
|
|
497
|
+
*
|
|
498
|
+
* Logical operators `$and`, `$or`, and `$nor` accept arrays of `TypedFilter<T>`
|
|
499
|
+
* for composing complex queries.
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* ```ts
|
|
503
|
+
* // Simple equality
|
|
504
|
+
* const filter: TypedFilter<User> = { name: 'Alice' }
|
|
505
|
+
*
|
|
506
|
+
* // Builder functions mixed with object literals
|
|
507
|
+
* const filter: TypedFilter<User> = { age: $gte(18), role: $in(['admin', 'mod']) }
|
|
508
|
+
*
|
|
509
|
+
* // Logical composition
|
|
510
|
+
* const filter = $and<User>(
|
|
511
|
+
* $or<User>({ role: 'admin' }, { role: 'moderator' }),
|
|
512
|
+
* { age: $gte(18) },
|
|
513
|
+
* { email: $exists() },
|
|
514
|
+
* )
|
|
515
|
+
*
|
|
516
|
+
* // Dynamic conditional building
|
|
517
|
+
* const conditions: TypedFilter<User>[] = []
|
|
518
|
+
* if (name) conditions.push({ name })
|
|
519
|
+
* if (minAge) conditions.push({ age: $gte(minAge) })
|
|
520
|
+
* const filter = conditions.length ? $and<User>(...conditions) : {}
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
type TypedFilter<T> = {
|
|
524
|
+
[K in keyof T]?: T[K] | ComparisonOperators<T[K]>;
|
|
525
|
+
} & {
|
|
526
|
+
[P in DotPaths<T>]?: DotPathType<T, P> | ComparisonOperators<DotPathType<T, P>>;
|
|
527
|
+
} & {
|
|
528
|
+
/** Joins clauses with a logical AND. Matches documents that satisfy all filters. */
|
|
529
|
+
$and?: TypedFilter<T>[];
|
|
530
|
+
/** Joins clauses with a logical OR. Matches documents that satisfy at least one filter. */
|
|
531
|
+
$or?: TypedFilter<T>[];
|
|
532
|
+
/** Joins clauses with a logical NOR. Matches documents that fail all filters. */
|
|
533
|
+
$nor?: TypedFilter<T>[];
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Options for {@link findOne} and {@link findOneOrThrow}.
|
|
538
|
+
*/
|
|
539
|
+
type FindOneOptions = {
|
|
540
|
+
/** MongoDB projection — include (`1`) or exclude (`0`) fields. Typed projections deferred to v1.0. */
|
|
541
|
+
project?: Record<string, 0 | 1>;
|
|
542
|
+
/** Override the collection-level validation mode, or `false` to skip validation entirely. */
|
|
543
|
+
validate?: ValidationMode | false;
|
|
544
|
+
};
|
|
545
|
+
/**
|
|
546
|
+
* Find a single document matching the filter.
|
|
547
|
+
*
|
|
548
|
+
* Queries MongoDB, then validates the fetched document against the collection's
|
|
549
|
+
* Zod schema. Validation mode is resolved from the per-query option, falling
|
|
550
|
+
* back to the collection-level default (which defaults to `'strict'`).
|
|
551
|
+
*
|
|
552
|
+
* @param handle - The collection handle to query.
|
|
553
|
+
* @param filter - Type-safe filter to match documents.
|
|
554
|
+
* @param options - Optional projection and validation overrides.
|
|
555
|
+
* @returns The matched document, or `null` if no document matches.
|
|
556
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
557
|
+
*
|
|
558
|
+
* @example
|
|
559
|
+
* ```ts
|
|
560
|
+
* const user = await findOne(users, { name: 'Ada' })
|
|
561
|
+
* if (user) console.log(user.role) // typed as 'admin' | 'user'
|
|
562
|
+
* ```
|
|
563
|
+
*/
|
|
564
|
+
declare function findOne<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef> | null>;
|
|
565
|
+
/**
|
|
566
|
+
* Find a single document matching the filter, or throw if none exists.
|
|
567
|
+
*
|
|
568
|
+
* Behaves identically to {@link findOne} but throws {@link ZodmonNotFoundError}
|
|
569
|
+
* instead of returning `null` when no document matches the filter.
|
|
570
|
+
*
|
|
571
|
+
* @param handle - The collection handle to query.
|
|
572
|
+
* @param filter - Type-safe filter to match documents.
|
|
573
|
+
* @param options - Optional projection and validation overrides.
|
|
574
|
+
* @returns The matched document (never null).
|
|
575
|
+
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
576
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* ```ts
|
|
580
|
+
* const user = await findOneOrThrow(users, { name: 'Ada' })
|
|
581
|
+
* console.log(user.role) // typed as 'admin' | 'user', guaranteed non-null
|
|
582
|
+
* ```
|
|
583
|
+
*/
|
|
584
|
+
declare function findOneOrThrow<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef>>;
|
|
585
|
+
/**
|
|
586
|
+
* Options for {@link find}.
|
|
587
|
+
*/
|
|
588
|
+
type FindOptions = {
|
|
589
|
+
/** Override the collection-level validation mode, or `false` to skip validation entirely. */
|
|
590
|
+
validate?: ValidationMode | false;
|
|
591
|
+
};
|
|
592
|
+
/**
|
|
593
|
+
* Find all documents matching the filter, returning a chainable typed cursor.
|
|
594
|
+
*
|
|
595
|
+
* The cursor is lazy — no query is executed until a terminal method
|
|
596
|
+
* (`toArray`, `for await`) is called. Use `sort`, `skip`, and `limit`
|
|
597
|
+
* to shape the query before executing.
|
|
598
|
+
*
|
|
599
|
+
* Each document is validated against the collection's Zod schema when
|
|
600
|
+
* a terminal method consumes it.
|
|
601
|
+
*
|
|
602
|
+
* @param handle - The collection handle to query.
|
|
603
|
+
* @param filter - Type-safe filter to match documents.
|
|
604
|
+
* @param options - Optional validation overrides.
|
|
605
|
+
* @returns A typed cursor for chaining query modifiers.
|
|
606
|
+
*
|
|
607
|
+
* @example
|
|
608
|
+
* ```ts
|
|
609
|
+
* const admins = await find(users, { role: 'admin' })
|
|
610
|
+
* .sort({ name: 1 })
|
|
611
|
+
* .limit(10)
|
|
612
|
+
* .toArray()
|
|
613
|
+
* ```
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* ```ts
|
|
617
|
+
* for await (const user of find(users, {})) {
|
|
618
|
+
* console.log(user.name)
|
|
619
|
+
* }
|
|
620
|
+
* ```
|
|
621
|
+
*/
|
|
622
|
+
declare function find<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options?: FindOptions): TypedFindCursor<TDef>;
|
|
623
|
+
|
|
274
624
|
/**
|
|
275
625
|
* Typed wrapper around a MongoDB driver `Collection`.
|
|
276
626
|
*
|
|
@@ -278,18 +628,116 @@ type AnyCollection = CollectionDefinition<z.core.$ZodShape>;
|
|
|
278
628
|
* (for runtime schema validation and index metadata) alongside the native
|
|
279
629
|
* driver collection parameterized with the inferred document type.
|
|
280
630
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
-
* @typeParam TDoc - The document type inferred from the Zod schema
|
|
285
|
-
* (e.g. `{ _id: ObjectId; name: string }`). Defaults to `Document`.
|
|
631
|
+
* @typeParam TDef - The collection definition type. Used to derive both
|
|
632
|
+
* the document type (`InferDocument`) and the insert type (`InferInsert`).
|
|
286
633
|
*/
|
|
287
|
-
declare class CollectionHandle<
|
|
634
|
+
declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
288
635
|
/** The collection definition containing schema, name, and index metadata. */
|
|
289
|
-
readonly definition:
|
|
290
|
-
/** The underlying MongoDB driver collection, typed to
|
|
291
|
-
readonly native: Collection<
|
|
292
|
-
constructor(definition:
|
|
636
|
+
readonly definition: TDef;
|
|
637
|
+
/** The underlying MongoDB driver collection, typed to the inferred document type. */
|
|
638
|
+
readonly native: Collection<InferDocument<TDef>>;
|
|
639
|
+
constructor(definition: TDef, native: Collection<InferDocument<TDef>>);
|
|
640
|
+
/**
|
|
641
|
+
* Insert a single document into the collection.
|
|
642
|
+
*
|
|
643
|
+
* Validates the input against the collection's Zod schema before writing.
|
|
644
|
+
* Schema defaults (including auto-generated `_id`) are applied during
|
|
645
|
+
* validation. Returns the full document with all defaults filled in.
|
|
646
|
+
*
|
|
647
|
+
* @param doc - The document to insert. Fields with `.default()` are optional.
|
|
648
|
+
* @returns The inserted document with `_id` and all defaults applied.
|
|
649
|
+
* @throws {ZodmonValidationError} When the document fails schema validation.
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* ```ts
|
|
653
|
+
* const users = db.use(Users)
|
|
654
|
+
* const user = await users.insertOne({ name: 'Ada' })
|
|
655
|
+
* console.log(user._id) // ObjectId (auto-generated)
|
|
656
|
+
* console.log(user.role) // 'user' (schema default)
|
|
657
|
+
* ```
|
|
658
|
+
*/
|
|
659
|
+
insertOne(doc: InferInsert<TDef>): Promise<InferDocument<TDef>>;
|
|
660
|
+
/**
|
|
661
|
+
* Insert multiple documents into the collection.
|
|
662
|
+
*
|
|
663
|
+
* Validates every document against the collection's Zod schema before
|
|
664
|
+
* writing any to MongoDB. If any document fails validation, none are
|
|
665
|
+
* inserted (fail-fast before the driver call).
|
|
666
|
+
*
|
|
667
|
+
* @param docs - The documents to insert.
|
|
668
|
+
* @returns The inserted documents with `_id` and all defaults applied.
|
|
669
|
+
* @throws {ZodmonValidationError} When any document fails schema validation.
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```ts
|
|
673
|
+
* const created = await users.insertMany([
|
|
674
|
+
* { name: 'Ada' },
|
|
675
|
+
* { name: 'Bob', role: 'admin' },
|
|
676
|
+
* ])
|
|
677
|
+
* ```
|
|
678
|
+
*/
|
|
679
|
+
insertMany(docs: InferInsert<TDef>[]): Promise<InferDocument<TDef>[]>;
|
|
680
|
+
/**
|
|
681
|
+
* Find a single document matching the filter.
|
|
682
|
+
*
|
|
683
|
+
* Queries MongoDB, then validates the fetched document against the collection's
|
|
684
|
+
* Zod schema. Validation mode is resolved from the per-query option, falling
|
|
685
|
+
* back to the collection-level default (which defaults to `'strict'`).
|
|
686
|
+
*
|
|
687
|
+
* @param filter - Type-safe filter to match documents.
|
|
688
|
+
* @param options - Optional projection and validation overrides.
|
|
689
|
+
* @returns The matched document, or `null` if no document matches.
|
|
690
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```ts
|
|
694
|
+
* const users = db.use(Users)
|
|
695
|
+
* const user = await users.findOne({ name: 'Ada' })
|
|
696
|
+
* if (user) console.log(user.role)
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
findOne(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef> | null>;
|
|
700
|
+
/**
|
|
701
|
+
* Find a single document matching the filter, or throw if none exists.
|
|
702
|
+
*
|
|
703
|
+
* Behaves identically to {@link findOne} but throws {@link ZodmonNotFoundError}
|
|
704
|
+
* instead of returning `null` when no document matches the filter.
|
|
705
|
+
*
|
|
706
|
+
* @param filter - Type-safe filter to match documents.
|
|
707
|
+
* @param options - Optional projection and validation overrides.
|
|
708
|
+
* @returns The matched document (never null).
|
|
709
|
+
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
710
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
711
|
+
*
|
|
712
|
+
* @example
|
|
713
|
+
* ```ts
|
|
714
|
+
* const users = db.use(Users)
|
|
715
|
+
* const user = await users.findOneOrThrow({ name: 'Ada' })
|
|
716
|
+
* console.log(user.role) // guaranteed non-null
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
findOneOrThrow(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef>>;
|
|
720
|
+
/**
|
|
721
|
+
* Find all documents matching the filter, returning a chainable typed cursor.
|
|
722
|
+
*
|
|
723
|
+
* The cursor is lazy — no query is executed until a terminal method
|
|
724
|
+
* (`toArray`, `for await`) is called. Use `sort`, `skip`, and `limit`
|
|
725
|
+
* to shape the query before executing.
|
|
726
|
+
*
|
|
727
|
+
* @param filter - Type-safe filter to match documents.
|
|
728
|
+
* @param options - Optional validation overrides.
|
|
729
|
+
* @returns A typed cursor for chaining query modifiers.
|
|
730
|
+
*
|
|
731
|
+
* @example
|
|
732
|
+
* ```ts
|
|
733
|
+
* const users = db.use(Users)
|
|
734
|
+
* const admins = await users.find({ role: 'admin' })
|
|
735
|
+
* .sort({ name: 1 })
|
|
736
|
+
* .limit(10)
|
|
737
|
+
* .toArray()
|
|
738
|
+
* ```
|
|
739
|
+
*/
|
|
740
|
+
find(filter: TypedFilter<InferDocument<TDef>>, options?: FindOptions): TypedFindCursor<TDef>;
|
|
293
741
|
}
|
|
294
742
|
|
|
295
743
|
/**
|
|
@@ -324,7 +772,7 @@ declare class Database {
|
|
|
324
772
|
* @param def - A collection definition created by `collection()`.
|
|
325
773
|
* @returns A typed collection handle for CRUD operations.
|
|
326
774
|
*/
|
|
327
|
-
use<TShape extends z.core.$ZodShape>(def: CollectionDefinition<TShape>): CollectionHandle<
|
|
775
|
+
use<TShape extends z.core.$ZodShape>(def: CollectionDefinition<TShape>): CollectionHandle<CollectionDefinition<TShape>>;
|
|
328
776
|
/**
|
|
329
777
|
* Synchronize indexes defined in registered collections with MongoDB.
|
|
330
778
|
*
|
|
@@ -461,173 +909,145 @@ declare class IndexBuilder<TKeys extends string> {
|
|
|
461
909
|
declare function index<TKeys extends string>(fields: Record<TKeys, IndexDirection>): IndexBuilder<TKeys>;
|
|
462
910
|
|
|
463
911
|
/**
|
|
464
|
-
*
|
|
465
|
-
*
|
|
466
|
-
* - Called with **no arguments**: generates a brand-new `ObjectId`.
|
|
467
|
-
* - Called with a **hex string**: coerces it to an `ObjectId` via
|
|
468
|
-
* `ObjectId.createFromHexString`.
|
|
469
|
-
* - Called with an **existing `ObjectId`**: returns it unchanged.
|
|
912
|
+
* Insert a single document into the collection.
|
|
470
913
|
*
|
|
471
|
-
*
|
|
472
|
-
*
|
|
914
|
+
* Validates the input against the collection's Zod schema before writing.
|
|
915
|
+
* Schema defaults (including auto-generated `_id`) are applied during
|
|
916
|
+
* validation. Returns the full document with all defaults filled in.
|
|
473
917
|
*
|
|
474
|
-
* @param
|
|
475
|
-
*
|
|
476
|
-
* @returns
|
|
918
|
+
* @param handle - The collection handle to insert into.
|
|
919
|
+
* @param doc - The document to insert. Fields with `.default()` are optional.
|
|
920
|
+
* @returns The inserted document with `_id` and all defaults applied.
|
|
921
|
+
* @throws {ZodmonValidationError} When the document fails schema validation.
|
|
477
922
|
*
|
|
478
923
|
* @example
|
|
479
924
|
* ```ts
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
*
|
|
925
|
+
* const user = await insertOne(users, { name: 'Ada' })
|
|
926
|
+
* console.log(user._id) // ObjectId (auto-generated)
|
|
927
|
+
* console.log(user.role) // 'user' (schema default)
|
|
483
928
|
* ```
|
|
484
929
|
*/
|
|
485
|
-
declare function
|
|
486
|
-
declare function oid(value: string): ObjectId;
|
|
487
|
-
declare function oid(value: ObjectId): ObjectId;
|
|
930
|
+
declare function insertOne<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, doc: InferInsert<TDef>): Promise<InferDocument<TDef>>;
|
|
488
931
|
/**
|
|
489
|
-
*
|
|
932
|
+
* Insert multiple documents into the collection.
|
|
490
933
|
*
|
|
491
|
-
*
|
|
492
|
-
*
|
|
934
|
+
* Validates every document against the collection's Zod schema before
|
|
935
|
+
* writing any to MongoDB. If any document fails validation, none are
|
|
936
|
+
* inserted (fail-fast before the driver call).
|
|
493
937
|
*
|
|
494
|
-
* @param
|
|
495
|
-
* @
|
|
938
|
+
* @param handle - The collection handle to insert into.
|
|
939
|
+
* @param docs - The documents to insert.
|
|
940
|
+
* @returns The inserted documents with `_id` and all defaults applied.
|
|
941
|
+
* @throws {ZodmonValidationError} When any document fails schema validation.
|
|
496
942
|
*
|
|
497
943
|
* @example
|
|
498
944
|
* ```ts
|
|
499
|
-
* const
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
945
|
+
* const users = await insertMany(handle, [
|
|
946
|
+
* { name: 'Ada' },
|
|
947
|
+
* { name: 'Bob', role: 'admin' },
|
|
948
|
+
* ])
|
|
503
949
|
* ```
|
|
504
950
|
*/
|
|
505
|
-
declare function
|
|
951
|
+
declare function insertMany<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, docs: InferInsert<TDef>[]): Promise<InferDocument<TDef>[]>;
|
|
506
952
|
|
|
507
953
|
/**
|
|
508
|
-
*
|
|
954
|
+
* Thrown when a query expected to find a document returns no results.
|
|
509
955
|
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
* Used as the operator object that can be assigned to a field in {@link TypedFilter}.
|
|
956
|
+
* Used by {@link findOneOrThrow} when no document matches the provided filter.
|
|
957
|
+
* Callers can inspect `.collection` to identify which collection the query targeted.
|
|
514
958
|
*
|
|
515
959
|
* @example
|
|
516
960
|
* ```ts
|
|
517
|
-
*
|
|
518
|
-
*
|
|
519
|
-
*
|
|
520
|
-
*
|
|
521
|
-
*
|
|
961
|
+
* try {
|
|
962
|
+
* await users.findOneOrThrow({ name: 'nonexistent' })
|
|
963
|
+
* } catch (err) {
|
|
964
|
+
* if (err instanceof ZodmonNotFoundError) {
|
|
965
|
+
* console.log(err.message) // => 'Document not found in "users"'
|
|
966
|
+
* console.log(err.collection) // => 'users'
|
|
967
|
+
* }
|
|
968
|
+
* }
|
|
522
969
|
* ```
|
|
523
970
|
*/
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
/** Matches values greater than or equal to the specified value. */
|
|
532
|
-
$gte?: V;
|
|
533
|
-
/** Matches values less than the specified value. */
|
|
534
|
-
$lt?: V;
|
|
535
|
-
/** Matches values less than or equal to the specified value. */
|
|
536
|
-
$lte?: V;
|
|
537
|
-
/** Matches any value in the specified array. */
|
|
538
|
-
$in?: V[];
|
|
539
|
-
/** Matches none of the values in the specified array. */
|
|
540
|
-
$nin?: V[];
|
|
541
|
-
/** Matches documents where the field exists (`true`) or does not exist (`false`). */
|
|
542
|
-
$exists?: boolean;
|
|
543
|
-
/** Negates a comparison operator. */
|
|
544
|
-
$not?: ComparisonOperators<V>;
|
|
545
|
-
} & (V extends string ? {
|
|
546
|
-
$regex?: RegExp | string;
|
|
547
|
-
} : unknown);
|
|
548
|
-
/** Depth counter for limiting dot-notation recursion. Index = current depth, value = next depth. */
|
|
549
|
-
type Prev = [never, 0, 1, 2];
|
|
971
|
+
declare class ZodmonNotFoundError extends Error {
|
|
972
|
+
readonly name = "ZodmonNotFoundError";
|
|
973
|
+
/** The MongoDB collection name where the query found no results. */
|
|
974
|
+
readonly collection: string;
|
|
975
|
+
constructor(collection: string);
|
|
976
|
+
}
|
|
977
|
+
|
|
550
978
|
/**
|
|
551
|
-
*
|
|
979
|
+
* Thrown when a document fails Zod schema validation before a MongoDB write.
|
|
552
980
|
*
|
|
553
|
-
*
|
|
554
|
-
*
|
|
555
|
-
*
|
|
981
|
+
* Wraps the original `ZodError` with the collection name and a human-readable
|
|
982
|
+
* message listing each invalid field and its error. Callers can inspect
|
|
983
|
+
* `.zodError.issues` for programmatic access to individual failures.
|
|
556
984
|
*
|
|
557
985
|
* @example
|
|
558
986
|
* ```ts
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
987
|
+
* try {
|
|
988
|
+
* await users.insertOne({ name: 123 })
|
|
989
|
+
* } catch (err) {
|
|
990
|
+
* if (err instanceof ZodmonValidationError) {
|
|
991
|
+
* console.log(err.message)
|
|
992
|
+
* // => 'Validation failed for "users": name (Expected string, received number)'
|
|
993
|
+
* console.log(err.collection) // => 'users'
|
|
994
|
+
* console.log(err.zodError) // => ZodError with .issues array
|
|
995
|
+
* }
|
|
996
|
+
* }
|
|
562
997
|
* ```
|
|
563
998
|
*/
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
999
|
+
declare class ZodmonValidationError extends Error {
|
|
1000
|
+
readonly name = "ZodmonValidationError";
|
|
1001
|
+
/** The MongoDB collection name where the validation failed. */
|
|
1002
|
+
readonly collection: string;
|
|
1003
|
+
/** The original Zod validation error with detailed issue information. */
|
|
1004
|
+
readonly zodError: z.ZodError;
|
|
1005
|
+
constructor(collection: string, zodError: z.ZodError);
|
|
1006
|
+
}
|
|
1007
|
+
|
|
567
1008
|
/**
|
|
568
|
-
*
|
|
1009
|
+
* Create or coerce a MongoDB `ObjectId`.
|
|
569
1010
|
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
1011
|
+
* - Called with **no arguments**: generates a brand-new `ObjectId`.
|
|
1012
|
+
* - Called with a **hex string**: coerces it to an `ObjectId` via
|
|
1013
|
+
* `ObjectId.createFromHexString`.
|
|
1014
|
+
* - Called with an **existing `ObjectId`**: returns it unchanged.
|
|
1015
|
+
*
|
|
1016
|
+
* This is a convenience wrapper that removes the need for `new ObjectId()`
|
|
1017
|
+
* boilerplate throughout application code.
|
|
1018
|
+
*
|
|
1019
|
+
* @param value - Optional hex string or `ObjectId` to coerce. Omit to
|
|
1020
|
+
* generate a new `ObjectId`.
|
|
1021
|
+
* @returns An `ObjectId` instance.
|
|
572
1022
|
*
|
|
573
1023
|
* @example
|
|
574
1024
|
* ```ts
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
* //
|
|
578
|
-
* // DotPathType<User, 'address.geo.lat'> = number
|
|
1025
|
+
* oid() // new random ObjectId
|
|
1026
|
+
* oid('64f1a2b3c4d5e6f7a8b9c0d1') // coerce hex string
|
|
1027
|
+
* oid(existingId) // pass-through
|
|
579
1028
|
* ```
|
|
580
1029
|
*/
|
|
581
|
-
|
|
1030
|
+
declare function oid(): ObjectId;
|
|
1031
|
+
declare function oid(value: string): ObjectId;
|
|
1032
|
+
declare function oid(value: ObjectId): ObjectId;
|
|
582
1033
|
/**
|
|
583
|
-
*
|
|
584
|
-
*
|
|
585
|
-
* Validates filter objects at compile time — rejects nonexistent fields, type mismatches,
|
|
586
|
-
* and invalid operator usage. Unlike the MongoDB driver's `Filter<T>`, does NOT allow
|
|
587
|
-
* arbitrary keys via `& Document`.
|
|
1034
|
+
* Type guard that narrows an `unknown` value to `ObjectId`.
|
|
588
1035
|
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
* - **Comparison operators**: `{ age: { $gt: 25 } }` or `{ age: $gt(25) }`
|
|
592
|
-
* - **Dot notation** for nested fields up to 3 levels: `{ 'address.city': 'NYC' }`
|
|
1036
|
+
* Uses `instanceof` internally, so it works with any value without risk
|
|
1037
|
+
* of throwing.
|
|
593
1038
|
*
|
|
594
|
-
*
|
|
595
|
-
*
|
|
1039
|
+
* @param value - The value to check.
|
|
1040
|
+
* @returns `true` if `value` is an `ObjectId` instance.
|
|
596
1041
|
*
|
|
597
1042
|
* @example
|
|
598
1043
|
* ```ts
|
|
599
|
-
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
602
|
-
*
|
|
603
|
-
* const filter: TypedFilter<User> = { age: $gte(18), role: $in(['admin', 'mod']) }
|
|
604
|
-
*
|
|
605
|
-
* // Logical composition
|
|
606
|
-
* const filter = $and<User>(
|
|
607
|
-
* $or<User>({ role: 'admin' }, { role: 'moderator' }),
|
|
608
|
-
* { age: $gte(18) },
|
|
609
|
-
* { email: $exists() },
|
|
610
|
-
* )
|
|
611
|
-
*
|
|
612
|
-
* // Dynamic conditional building
|
|
613
|
-
* const conditions: TypedFilter<User>[] = []
|
|
614
|
-
* if (name) conditions.push({ name })
|
|
615
|
-
* if (minAge) conditions.push({ age: $gte(minAge) })
|
|
616
|
-
* const filter = conditions.length ? $and<User>(...conditions) : {}
|
|
1044
|
+
* const raw: unknown = getFromDb()
|
|
1045
|
+
* if (isOid(raw)) {
|
|
1046
|
+
* console.log(raw.toHexString()) // raw is narrowed to ObjectId
|
|
1047
|
+
* }
|
|
617
1048
|
* ```
|
|
618
1049
|
*/
|
|
619
|
-
|
|
620
|
-
[K in keyof T]?: T[K] | ComparisonOperators<T[K]>;
|
|
621
|
-
} & {
|
|
622
|
-
[P in DotPaths<T>]?: DotPathType<T, P> | ComparisonOperators<DotPathType<T, P>>;
|
|
623
|
-
} & {
|
|
624
|
-
/** Joins clauses with a logical AND. Matches documents that satisfy all filters. */
|
|
625
|
-
$and?: TypedFilter<T>[];
|
|
626
|
-
/** Joins clauses with a logical OR. Matches documents that satisfy at least one filter. */
|
|
627
|
-
$or?: TypedFilter<T>[];
|
|
628
|
-
/** Joins clauses with a logical NOR. Matches documents that fail all filters. */
|
|
629
|
-
$nor?: TypedFilter<T>[];
|
|
630
|
-
};
|
|
1050
|
+
declare function isOid(value: unknown): value is ObjectId;
|
|
631
1051
|
|
|
632
1052
|
/**
|
|
633
1053
|
* Matches values equal to the specified value.
|
|
@@ -901,4 +1321,4 @@ declare function getRefMetadata(schema: unknown): RefMetadata | undefined;
|
|
|
901
1321
|
*/
|
|
902
1322
|
declare function installRefExtension(): void;
|
|
903
1323
|
|
|
904
|
-
export { $and, $eq, $exists, $gt, $gte, $in, $lt, $lte, $ne, $nin, $nor, $not, $or, $regex, type AnyCollection, type CollectionDefinition, CollectionHandle, type CollectionOptions, type ComparisonOperators, type CompoundIndexDefinition, Database, type DotPathType, type DotPaths, type FieldIndexDefinition, IndexBuilder, type IndexMetadata, type IndexOptions, type InferDocument, type RefMarker, type RefMetadata, type ResolvedShape, type TypedFilter, type ZodObjectId, collection, createClient, extractDbName, extractFieldIndexes, getIndexMetadata, getRefMetadata, index, installExtensions, installRefExtension, isOid, objectId, oid, raw };
|
|
1324
|
+
export { $and, $eq, $exists, $gt, $gte, $in, $lt, $lte, $ne, $nin, $nor, $not, $or, $regex, type AnyCollection, type CollectionDefinition, CollectionHandle, type CollectionOptions, type ComparisonOperators, type CompoundIndexDefinition, Database, type DotPathType, type DotPaths, type FieldIndexDefinition, type FindOneOptions, type FindOptions, IndexBuilder, type IndexMetadata, type IndexOptions, type InferDocument, type InferInsert, type RefMarker, type RefMetadata, type ResolvedShape, type TypedFilter, TypedFindCursor, type TypedSort, type ValidationMode, type ZodObjectId, ZodmonNotFoundError, ZodmonValidationError, collection, createClient, extractDbName, extractFieldIndexes, find, findOne, findOneOrThrow, getIndexMetadata, getRefMetadata, index, insertMany, insertOne, installExtensions, installRefExtension, isOid, objectId, oid, raw };
|