@zodmon/core 0.10.0 → 0.11.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 +124 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +524 -125
- package/dist/index.d.ts +524 -125
- package/dist/index.js +122 -88
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -319,6 +319,40 @@ type ExtractNames<T extends readonly {
|
|
|
319
319
|
type Prettify<T> = {
|
|
320
320
|
[K in keyof T]: T[K];
|
|
321
321
|
} & {};
|
|
322
|
+
/**
|
|
323
|
+
* Generates all valid dot-separated field paths for a document type.
|
|
324
|
+
*
|
|
325
|
+
* Recursively traverses nested objects and unwraps arrays to match
|
|
326
|
+
* MongoDB's implicit array traversal semantics. Both top-level keys
|
|
327
|
+
* and nested paths are included in the resulting union.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* type Doc = { address: { city: string }; tags: Array<{ label: string }> }
|
|
332
|
+
* type Paths = DotPath<Doc>
|
|
333
|
+
* // ^? 'address' | 'address.city' | 'tags' | 'tags.label'
|
|
334
|
+
* ```
|
|
335
|
+
*/
|
|
336
|
+
type DotPath<T> = T extends ReadonlyArray<infer E> ? DotPath<E> : T extends Record<string, unknown> ? {
|
|
337
|
+
[K in keyof T & string]: T[K] extends ReadonlyArray<infer E> ? E extends Record<string, unknown> ? K | `${K}.${DotPath<E>}` : K : T[K] extends Record<string, unknown> ? K | `${K}.${DotPath<T[K]>}` : K;
|
|
338
|
+
}[keyof T & string] : never;
|
|
339
|
+
/**
|
|
340
|
+
* Resolves the value type at a dot-separated path within a document type.
|
|
341
|
+
*
|
|
342
|
+
* Splits the path on `.` and recursively descends into nested types.
|
|
343
|
+
* Unwraps arrays at intermediate levels to match MongoDB's implicit
|
|
344
|
+
* array traversal. Returns `never` for invalid paths.
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* type Doc = { address: { city: string }; tags: Array<{ label: string }> }
|
|
349
|
+
* type City = DotPathValue<Doc, 'address.city'>
|
|
350
|
+
* // ^? string
|
|
351
|
+
* type Label = DotPathValue<Doc, 'tags.label'>
|
|
352
|
+
* // ^? string
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
type DotPathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? T[K] extends ReadonlyArray<infer E> ? DotPathValue<E, Rest> : DotPathValue<T[K], Rest> : never : P extends keyof T ? T[P] : never;
|
|
322
356
|
|
|
323
357
|
/**
|
|
324
358
|
* Type-level marker that carries the target collection type through the
|
|
@@ -448,21 +482,25 @@ type InferAccumulators<T extends Record<string, Accumulator>> = {
|
|
|
448
482
|
[K in keyof T]: InferAccumulator<T[K]>;
|
|
449
483
|
};
|
|
450
484
|
/**
|
|
451
|
-
* Field reference string prefixed with `$`, constrained to
|
|
485
|
+
* Field reference string prefixed with `$`, constrained to dot-paths of `T`.
|
|
486
|
+
*
|
|
487
|
+
* Supports both top-level fields (`$price`) and nested dot-paths
|
|
488
|
+
* (`$address.city`, `$address.geo.lat`).
|
|
452
489
|
*
|
|
453
490
|
* @example
|
|
454
491
|
* ```ts
|
|
455
|
-
* type OrderRef = FieldRef<{ price: number;
|
|
456
|
-
* // ^? '$price' | '$
|
|
492
|
+
* type OrderRef = FieldRef<{ price: number; address: { city: string } }>
|
|
493
|
+
* // ^? '$price' | '$address' | '$address.city'
|
|
457
494
|
* ```
|
|
458
495
|
*/
|
|
459
|
-
type FieldRef<T> = `$${
|
|
496
|
+
type FieldRef<T> = `$${DotPath<T>}`;
|
|
460
497
|
/**
|
|
461
498
|
* Typed accumulator factory passed to the `groupBy` callback.
|
|
462
499
|
*
|
|
463
|
-
* Each method constrains field names to `
|
|
464
|
-
* IDE autocomplete and compile-time validation
|
|
465
|
-
*
|
|
500
|
+
* Each method constrains field names to `DotPath<T>`, providing
|
|
501
|
+
* IDE autocomplete and compile-time validation for both top-level
|
|
502
|
+
* and nested dot-path fields. Return types resolve to the actual
|
|
503
|
+
* field type via `DotPathValue<T, F>`, not `unknown`.
|
|
466
504
|
*
|
|
467
505
|
* @typeParam T - The current pipeline output document type.
|
|
468
506
|
*
|
|
@@ -470,10 +508,10 @@ type FieldRef<T> = `$${keyof T & string}`;
|
|
|
470
508
|
* ```ts
|
|
471
509
|
* users.aggregate()
|
|
472
510
|
* .groupBy('role', acc => ({
|
|
473
|
-
* minSalary: acc.min('salary'),
|
|
474
|
-
* firstName: acc.first('name'),
|
|
475
|
-
*
|
|
476
|
-
* count: acc.count(),
|
|
511
|
+
* minSalary: acc.min('salary'), // Accumulator<number>
|
|
512
|
+
* firstName: acc.first('name'), // Accumulator<string>
|
|
513
|
+
* allCities: acc.push('address.city'), // Accumulator<string[]>
|
|
514
|
+
* count: acc.count(), // Accumulator<number>
|
|
477
515
|
* }))
|
|
478
516
|
* ```
|
|
479
517
|
*/
|
|
@@ -481,64 +519,79 @@ type AccumulatorBuilder<T> = {
|
|
|
481
519
|
/** Count documents in each group. Always returns `Accumulator<number>`. */
|
|
482
520
|
count(): Accumulator<number>;
|
|
483
521
|
/** Sum a numeric field. Always returns `Accumulator<number>`. */
|
|
484
|
-
sum
|
|
522
|
+
sum(field: DotPath<T>): Accumulator<number>;
|
|
485
523
|
/** Sum a literal number per document. Always returns `Accumulator<number>`. */
|
|
486
524
|
sum(value: number): Accumulator<number>;
|
|
487
525
|
/** Average a numeric field. Always returns `Accumulator<number>`. */
|
|
488
|
-
avg
|
|
489
|
-
/** Minimum value of a field. Returns `Accumulator<T
|
|
490
|
-
min<
|
|
491
|
-
/** Maximum value of a field. Returns `Accumulator<T
|
|
492
|
-
max<
|
|
493
|
-
/** First value in each group (by document order). Returns `Accumulator<T
|
|
494
|
-
first<
|
|
495
|
-
/** Last value in each group (by document order). Returns `Accumulator<T
|
|
496
|
-
last<
|
|
497
|
-
/** Collect values into an array (with duplicates). Returns `Accumulator<T[
|
|
498
|
-
push<
|
|
499
|
-
/** Collect unique values into an array. Returns `Accumulator<T[
|
|
500
|
-
addToSet<
|
|
526
|
+
avg(field: DotPath<T>): Accumulator<number>;
|
|
527
|
+
/** Minimum value of a field. Returns `Accumulator<DotPathValue<T, F>>`. */
|
|
528
|
+
min<F extends DotPath<T>>(field: F): Accumulator<DotPathValue<T, F>>;
|
|
529
|
+
/** Maximum value of a field. Returns `Accumulator<DotPathValue<T, F>>`. */
|
|
530
|
+
max<F extends DotPath<T>>(field: F): Accumulator<DotPathValue<T, F>>;
|
|
531
|
+
/** First value in each group (by document order). Returns `Accumulator<DotPathValue<T, F>>`. */
|
|
532
|
+
first<F extends DotPath<T>>(field: F): Accumulator<DotPathValue<T, F>>;
|
|
533
|
+
/** Last value in each group (by document order). Returns `Accumulator<DotPathValue<T, F>>`. */
|
|
534
|
+
last<F extends DotPath<T>>(field: F): Accumulator<DotPathValue<T, F>>;
|
|
535
|
+
/** Collect values into an array (with duplicates). Returns `Accumulator<DotPathValue<T, F>[]>`. */
|
|
536
|
+
push<F extends DotPath<T>>(field: F): Accumulator<DotPathValue<T, F>[]>;
|
|
537
|
+
/** Collect unique values into an array. Returns `Accumulator<DotPathValue<T, F>[]>`. */
|
|
538
|
+
addToSet<F extends DotPath<T>>(field: F): Accumulator<DotPathValue<T, F>[]>;
|
|
501
539
|
};
|
|
502
540
|
/**
|
|
503
541
|
* Resolves the document field type from a `$`-prefixed field reference.
|
|
504
542
|
*
|
|
543
|
+
* Supports both top-level refs (`$price`) and dot-path refs
|
|
544
|
+
* (`$address.city`), resolving through nested objects and arrays.
|
|
545
|
+
*
|
|
505
546
|
* @example
|
|
506
547
|
* ```ts
|
|
507
|
-
* type Order = { price: number;
|
|
548
|
+
* type Order = { price: number; address: { city: string } }
|
|
508
549
|
* type PriceType = FieldRefType<Order, '$price'>
|
|
509
550
|
* // ^? number
|
|
551
|
+
* type CityType = FieldRefType<Order, '$address.city'>
|
|
552
|
+
* // ^? string
|
|
510
553
|
* ```
|
|
511
554
|
*/
|
|
512
|
-
type FieldRefType<T, F extends string> = F extends `$${infer K}` ? K extends
|
|
555
|
+
type FieldRefType<T, F extends string> = F extends `$${infer K}` ? DotPathValue<T, K> extends never ? never : DotPathValue<T, K> : never;
|
|
513
556
|
/**
|
|
514
557
|
* Output shape of a single-field `groupBy` stage.
|
|
515
558
|
*
|
|
516
559
|
* The `_id` field holds the grouped-by field's value, and the rest of the
|
|
517
|
-
* shape comes from the inferred accumulator types.
|
|
560
|
+
* shape comes from the inferred accumulator types. Supports dot-path keys
|
|
561
|
+
* for grouping by nested fields.
|
|
518
562
|
*
|
|
519
563
|
* @example
|
|
520
564
|
* ```ts
|
|
521
565
|
* type Result = GroupByResult<Order, 'status', { count: Accumulator<number> }>
|
|
522
566
|
* // ^? { _id: string; count: number }
|
|
567
|
+
*
|
|
568
|
+
* type Nested = GroupByResult<Order, 'address.city', { count: Accumulator<number> }>
|
|
569
|
+
* // ^? { _id: string; count: number }
|
|
523
570
|
* ```
|
|
524
571
|
*/
|
|
525
|
-
type GroupByResult<T, K extends
|
|
526
|
-
_id: T
|
|
572
|
+
type GroupByResult<T, K extends DotPath<T>, TAccum extends Record<string, Accumulator>> = Prettify<{
|
|
573
|
+
_id: DotPathValue<T, K & string>;
|
|
527
574
|
} & InferAccumulators<TAccum>>;
|
|
528
575
|
/**
|
|
529
576
|
* Output shape of a compound (multi-field) `groupBy` stage.
|
|
530
577
|
*
|
|
531
578
|
* The `_id` field is an object with one property per grouped field,
|
|
532
579
|
* and the rest of the shape comes from the inferred accumulator types.
|
|
580
|
+
* Supports dot-path keys for grouping by nested fields.
|
|
533
581
|
*
|
|
534
582
|
* @example
|
|
535
583
|
* ```ts
|
|
536
584
|
* type Result = GroupByCompoundResult<Order, 'status' | 'region', { count: Accumulator<number> }>
|
|
537
|
-
* // ^? { _id:
|
|
585
|
+
* // ^? { _id: { status: string; region: string }; count: number }
|
|
586
|
+
*
|
|
587
|
+
* type Nested = GroupByCompoundResult<Order, 'name' | 'address.city', { count: Accumulator<number> }>
|
|
588
|
+
* // ^? { _id: { name: string; 'address.city': string }; count: number }
|
|
538
589
|
* ```
|
|
539
590
|
*/
|
|
540
|
-
type GroupByCompoundResult<T, K extends
|
|
541
|
-
_id: Prettify<
|
|
591
|
+
type GroupByCompoundResult<T, K extends DotPath<T>, TAccum extends Record<string, Accumulator>> = Prettify<{
|
|
592
|
+
_id: Prettify<{
|
|
593
|
+
[P in K & string]: DotPathValue<T, P>;
|
|
594
|
+
}>;
|
|
542
595
|
} & InferAccumulators<TAccum>>;
|
|
543
596
|
/**
|
|
544
597
|
* Output shape after unwinding an array field.
|
|
@@ -792,139 +845,169 @@ declare const $avg: (field: `$${string}`) => Accumulator<number>;
|
|
|
792
845
|
/**
|
|
793
846
|
* Returns the minimum value across documents in each group.
|
|
794
847
|
*
|
|
795
|
-
*
|
|
796
|
-
*
|
|
848
|
+
* Three tiers of type safety:
|
|
849
|
+
* - **Tier 1 (document type):** `$min<Doc>('$address.city')` — resolves via `FieldRefType`.
|
|
850
|
+
* - **Tier 2 (explicit scalar):** `$min<number>('$price')` — manual result type.
|
|
851
|
+
* - **Tier 3 (untyped):** `$min('$price')` — defaults to `unknown`.
|
|
852
|
+
*
|
|
853
|
+
* For best type safety, prefer the callback builder (`acc.min('price')`).
|
|
797
854
|
*
|
|
798
|
-
* @
|
|
799
|
-
* @
|
|
800
|
-
* @returns An `Accumulator<R>`.
|
|
855
|
+
* @param field - A `$field` reference (supports dot-paths with document type param).
|
|
856
|
+
* @returns An `Accumulator` with the resolved result type.
|
|
801
857
|
*
|
|
802
858
|
* @example
|
|
803
859
|
* ```ts
|
|
860
|
+
* // Tier 1 — document type with dot-path
|
|
861
|
+
* $min<Doc>('$address.city') // Accumulator<string>
|
|
862
|
+
*
|
|
804
863
|
* // Tier 2 — explicit result type
|
|
805
|
-
*
|
|
806
|
-
* .groupBy('category', { cheapest: $min<number>('$price') })
|
|
864
|
+
* $min<number>('$price') // Accumulator<number>
|
|
807
865
|
*
|
|
808
|
-
* // Tier
|
|
809
|
-
*
|
|
810
|
-
* .groupBy('category', acc => ({ cheapest: acc.min('price') }))
|
|
866
|
+
* // Tier 3 — untyped
|
|
867
|
+
* $min('$price') // Accumulator<unknown>
|
|
811
868
|
* ```
|
|
812
869
|
*/
|
|
813
|
-
declare
|
|
870
|
+
declare function $min<T extends Record<string, unknown>>(field: FieldRef<T>): Accumulator<FieldRefType<T, FieldRef<T>>>;
|
|
871
|
+
declare function $min<R = unknown>(field: `$${string}`): Accumulator<R>;
|
|
814
872
|
/**
|
|
815
873
|
* Returns the maximum value across documents in each group.
|
|
816
874
|
*
|
|
817
|
-
*
|
|
818
|
-
*
|
|
875
|
+
* Three tiers of type safety:
|
|
876
|
+
* - **Tier 1 (document type):** `$max<Doc>('$address.city')` — resolves via `FieldRefType`.
|
|
877
|
+
* - **Tier 2 (explicit scalar):** `$max<number>('$price')` — manual result type.
|
|
878
|
+
* - **Tier 3 (untyped):** `$max('$price')` — defaults to `unknown`.
|
|
879
|
+
*
|
|
880
|
+
* For best type safety, prefer the callback builder (`acc.max('price')`).
|
|
819
881
|
*
|
|
820
|
-
* @
|
|
821
|
-
* @
|
|
822
|
-
* @returns An `Accumulator<R>`.
|
|
882
|
+
* @param field - A `$field` reference (supports dot-paths with document type param).
|
|
883
|
+
* @returns An `Accumulator` with the resolved result type.
|
|
823
884
|
*
|
|
824
885
|
* @example
|
|
825
886
|
* ```ts
|
|
887
|
+
* // Tier 1 — document type with dot-path
|
|
888
|
+
* $max<Doc>('$tags.label') // Accumulator<string>
|
|
889
|
+
*
|
|
826
890
|
* // Tier 2 — explicit result type
|
|
827
|
-
*
|
|
828
|
-
* .groupBy('category', { priciest: $max<number>('$price') })
|
|
891
|
+
* $max<number>('$price') // Accumulator<number>
|
|
829
892
|
*
|
|
830
|
-
* // Tier
|
|
831
|
-
*
|
|
832
|
-
* .groupBy('category', acc => ({ priciest: acc.max('price') }))
|
|
893
|
+
* // Tier 3 — untyped
|
|
894
|
+
* $max('$price') // Accumulator<unknown>
|
|
833
895
|
* ```
|
|
834
896
|
*/
|
|
835
|
-
declare
|
|
897
|
+
declare function $max<T extends Record<string, unknown>>(field: FieldRef<T>): Accumulator<FieldRefType<T, FieldRef<T>>>;
|
|
898
|
+
declare function $max<R = unknown>(field: `$${string}`): Accumulator<R>;
|
|
836
899
|
/**
|
|
837
900
|
* Returns the first value in each group according to the document order.
|
|
838
901
|
*
|
|
839
|
-
*
|
|
840
|
-
*
|
|
902
|
+
* Three tiers of type safety:
|
|
903
|
+
* - **Tier 1 (document type):** `$first<Doc>('$address.city')` — resolves via `FieldRefType`.
|
|
904
|
+
* - **Tier 2 (explicit scalar):** `$first<Date>('$createdAt')` — manual result type.
|
|
905
|
+
* - **Tier 3 (untyped):** `$first('$name')` — defaults to `unknown`.
|
|
841
906
|
*
|
|
842
|
-
*
|
|
843
|
-
*
|
|
844
|
-
* @
|
|
907
|
+
* For best type safety, prefer the callback builder (`acc.first('name')`).
|
|
908
|
+
*
|
|
909
|
+
* @param field - A `$field` reference (supports dot-paths with document type param).
|
|
910
|
+
* @returns An `Accumulator` with the resolved result type.
|
|
845
911
|
*
|
|
846
912
|
* @example
|
|
847
913
|
* ```ts
|
|
914
|
+
* // Tier 1 — document type with dot-path
|
|
915
|
+
* $first<Doc>('$address.city') // Accumulator<string>
|
|
916
|
+
*
|
|
848
917
|
* // Tier 2 — explicit result type
|
|
849
|
-
*
|
|
850
|
-
* .sort({ createdAt: 1 })
|
|
851
|
-
* .groupBy('status', { earliest: $first<Date>('$createdAt') })
|
|
918
|
+
* $first<Date>('$createdAt') // Accumulator<Date>
|
|
852
919
|
*
|
|
853
|
-
* // Tier
|
|
854
|
-
*
|
|
855
|
-
* .sort({ createdAt: 1 })
|
|
856
|
-
* .groupBy('status', acc => ({ earliest: acc.first('createdAt') }))
|
|
920
|
+
* // Tier 3 — untyped
|
|
921
|
+
* $first('$name') // Accumulator<unknown>
|
|
857
922
|
* ```
|
|
858
923
|
*/
|
|
859
|
-
declare
|
|
924
|
+
declare function $first<T extends Record<string, unknown>>(field: FieldRef<T>): Accumulator<FieldRefType<T, FieldRef<T>>>;
|
|
925
|
+
declare function $first<R = unknown>(field: `$${string}`): Accumulator<R>;
|
|
860
926
|
/**
|
|
861
927
|
* Returns the last value in each group according to the document order.
|
|
862
928
|
*
|
|
863
|
-
*
|
|
864
|
-
*
|
|
929
|
+
* Three tiers of type safety:
|
|
930
|
+
* - **Tier 1 (document type):** `$last<Doc>('$address.city')` — resolves via `FieldRefType`.
|
|
931
|
+
* - **Tier 2 (explicit scalar):** `$last<Date>('$createdAt')` — manual result type.
|
|
932
|
+
* - **Tier 3 (untyped):** `$last('$name')` — defaults to `unknown`.
|
|
933
|
+
*
|
|
934
|
+
* For best type safety, prefer the callback builder (`acc.last('name')`).
|
|
865
935
|
*
|
|
866
|
-
* @
|
|
867
|
-
* @
|
|
868
|
-
* @returns An `Accumulator<R>`.
|
|
936
|
+
* @param field - A `$field` reference (supports dot-paths with document type param).
|
|
937
|
+
* @returns An `Accumulator` with the resolved result type.
|
|
869
938
|
*
|
|
870
939
|
* @example
|
|
871
940
|
* ```ts
|
|
941
|
+
* // Tier 1 — document type with dot-path
|
|
942
|
+
* $last<Doc>('$address.city') // Accumulator<string>
|
|
943
|
+
*
|
|
872
944
|
* // Tier 2 — explicit result type
|
|
873
|
-
*
|
|
874
|
-
* .sort({ createdAt: -1 })
|
|
875
|
-
* .groupBy('status', { latest: $last<Date>('$createdAt') })
|
|
945
|
+
* $last<Date>('$createdAt') // Accumulator<Date>
|
|
876
946
|
*
|
|
877
|
-
* // Tier
|
|
878
|
-
*
|
|
879
|
-
* .sort({ createdAt: -1 })
|
|
880
|
-
* .groupBy('status', acc => ({ latest: acc.last('createdAt') }))
|
|
947
|
+
* // Tier 3 — untyped
|
|
948
|
+
* $last('$name') // Accumulator<unknown>
|
|
881
949
|
* ```
|
|
882
950
|
*/
|
|
883
|
-
declare
|
|
951
|
+
declare function $last<T extends Record<string, unknown>>(field: FieldRef<T>): Accumulator<FieldRefType<T, FieldRef<T>>>;
|
|
952
|
+
declare function $last<R = unknown>(field: `$${string}`): Accumulator<R>;
|
|
884
953
|
/**
|
|
885
954
|
* Pushes values into an array for each group.
|
|
886
955
|
*
|
|
887
956
|
* May contain duplicates. Use `$addToSet` for unique values.
|
|
888
|
-
* For full type safety, prefer the callback builder (`acc.push('name')`).
|
|
889
957
|
*
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
958
|
+
* Three tiers of type safety:
|
|
959
|
+
* - **Tier 1 (document type):** `$push<Doc>('$address.city')` — resolves via `FieldRefType`.
|
|
960
|
+
* - **Tier 2 (explicit scalar):** `$push<string>('$name')` — manual element type.
|
|
961
|
+
* - **Tier 3 (untyped):** `$push('$name')` — defaults to `unknown[]`.
|
|
962
|
+
*
|
|
963
|
+
* For best type safety, prefer the callback builder (`acc.push('name')`).
|
|
964
|
+
*
|
|
965
|
+
* @param field - A `$field` reference (supports dot-paths with document type param).
|
|
966
|
+
* @returns An `Accumulator` with the resolved array result type.
|
|
893
967
|
*
|
|
894
968
|
* @example
|
|
895
969
|
* ```ts
|
|
970
|
+
* // Tier 1 — document type with dot-path
|
|
971
|
+
* $push<Doc>('$address.city') // Accumulator<string[]>
|
|
972
|
+
*
|
|
896
973
|
* // Tier 2 — explicit element type
|
|
897
|
-
*
|
|
898
|
-
* .groupBy('status', { items: $push<string>('$name') })
|
|
974
|
+
* $push<string>('$name') // Accumulator<string[]>
|
|
899
975
|
*
|
|
900
|
-
* // Tier
|
|
901
|
-
*
|
|
902
|
-
* .groupBy('status', acc => ({ items: acc.push('name') }))
|
|
976
|
+
* // Tier 3 — untyped
|
|
977
|
+
* $push('$name') // Accumulator<unknown[]>
|
|
903
978
|
* ```
|
|
904
979
|
*/
|
|
905
|
-
declare
|
|
980
|
+
declare function $push<T extends Record<string, unknown>>(field: FieldRef<T>): Accumulator<FieldRefType<T, FieldRef<T>>[]>;
|
|
981
|
+
declare function $push<R = unknown>(field: `$${string}`): Accumulator<R[]>;
|
|
906
982
|
/**
|
|
907
983
|
* Collects unique values into an array for each group (set semantics).
|
|
908
984
|
*
|
|
909
985
|
* Like `$push` but deduplicates.
|
|
910
|
-
* For full type safety, prefer the callback builder (`acc.addToSet('tag')`).
|
|
911
986
|
*
|
|
912
|
-
*
|
|
913
|
-
*
|
|
914
|
-
*
|
|
987
|
+
* Three tiers of type safety:
|
|
988
|
+
* - **Tier 1 (document type):** `$addToSet<Doc>('$address.zip')` — resolves via `FieldRefType`.
|
|
989
|
+
* - **Tier 2 (explicit scalar):** `$addToSet<string>('$tag')` — manual element type.
|
|
990
|
+
* - **Tier 3 (untyped):** `$addToSet('$tag')` — defaults to `unknown[]`.
|
|
991
|
+
*
|
|
992
|
+
* For best type safety, prefer the callback builder (`acc.addToSet('tag')`).
|
|
993
|
+
*
|
|
994
|
+
* @param field - A `$field` reference (supports dot-paths with document type param).
|
|
995
|
+
* @returns An `Accumulator` with the resolved array result type.
|
|
915
996
|
*
|
|
916
997
|
* @example
|
|
917
998
|
* ```ts
|
|
999
|
+
* // Tier 1 — document type with dot-path
|
|
1000
|
+
* $addToSet<Doc>('$address.zip') // Accumulator<string[]>
|
|
1001
|
+
*
|
|
918
1002
|
* // Tier 2 — explicit element type
|
|
919
|
-
*
|
|
920
|
-
* .groupBy('category', { uniqueTags: $addToSet<string>('$tag') })
|
|
1003
|
+
* $addToSet<string>('$tag') // Accumulator<string[]>
|
|
921
1004
|
*
|
|
922
|
-
* // Tier
|
|
923
|
-
*
|
|
924
|
-
* .groupBy('category', acc => ({ uniqueTags: acc.addToSet('tag') }))
|
|
1005
|
+
* // Tier 3 — untyped
|
|
1006
|
+
* $addToSet('$tag') // Accumulator<unknown[]>
|
|
925
1007
|
* ```
|
|
926
1008
|
*/
|
|
927
|
-
declare
|
|
1009
|
+
declare function $addToSet<T extends Record<string, unknown>>(field: FieldRef<T>): Accumulator<FieldRefType<T, FieldRef<T>>[]>;
|
|
1010
|
+
declare function $addToSet<R = unknown>(field: `$${string}`): Accumulator<R[]>;
|
|
928
1011
|
/**
|
|
929
1012
|
* Create a typed accumulator builder for use inside `groupBy` callbacks.
|
|
930
1013
|
*
|
|
@@ -1018,11 +1101,11 @@ type Prev = [never, 0, 1, 2];
|
|
|
1018
1101
|
* ```ts
|
|
1019
1102
|
* type User = { address: { city: string; geo: { lat: number; lng: number } } }
|
|
1020
1103
|
*
|
|
1021
|
-
* //
|
|
1104
|
+
* // _DotPaths<User> = 'address.city' | 'address.geo' | 'address.geo.lat' | 'address.geo.lng'
|
|
1022
1105
|
* ```
|
|
1023
1106
|
*/
|
|
1024
|
-
type
|
|
1025
|
-
[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}.${
|
|
1107
|
+
type _DotPaths<T, Depth extends number = 3> = Depth extends 0 ? never : {
|
|
1108
|
+
[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;
|
|
1026
1109
|
}[keyof T & string];
|
|
1027
1110
|
/**
|
|
1028
1111
|
* Resolves the value type at a dot-separated path `P` within type `T`.
|
|
@@ -1034,11 +1117,11 @@ type DotPaths<T, Depth extends number = 3> = Depth extends 0 ? never : {
|
|
|
1034
1117
|
* ```ts
|
|
1035
1118
|
* type User = { address: { city: string; geo: { lat: number } } }
|
|
1036
1119
|
*
|
|
1037
|
-
* //
|
|
1038
|
-
* //
|
|
1120
|
+
* // _DotPathType<User, 'address.city'> = string
|
|
1121
|
+
* // _DotPathType<User, 'address.geo.lat'> = number
|
|
1039
1122
|
* ```
|
|
1040
1123
|
*/
|
|
1041
|
-
type
|
|
1124
|
+
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;
|
|
1042
1125
|
/**
|
|
1043
1126
|
* Strict type-safe MongoDB filter query type.
|
|
1044
1127
|
*
|
|
@@ -1078,7 +1161,7 @@ type DotPathType<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K
|
|
|
1078
1161
|
type TypedFilter<T> = {
|
|
1079
1162
|
[K in keyof T]?: T[K] | ComparisonOperators<T[K]>;
|
|
1080
1163
|
} & {
|
|
1081
|
-
[P in
|
|
1164
|
+
[P in _DotPaths<T>]?: _DotPathType<T, P> | ComparisonOperators<_DotPathType<T, P>>;
|
|
1082
1165
|
} & {
|
|
1083
1166
|
/** Joins clauses with a logical AND. Matches documents that satisfy all filters. */
|
|
1084
1167
|
$and?: TypedFilter<T>[];
|
|
@@ -1239,6 +1322,135 @@ type CursorPage<TDoc> = {
|
|
|
1239
1322
|
endCursor: string | null;
|
|
1240
1323
|
};
|
|
1241
1324
|
|
|
1325
|
+
type IncludeValue = 1 | true;
|
|
1326
|
+
type ExcludeValue = 0 | false;
|
|
1327
|
+
/**
|
|
1328
|
+
* Inclusion projection — maps document fields to `1 | true`.
|
|
1329
|
+
*
|
|
1330
|
+
* Allows `_id: 0 | false` to suppress the `_id` field from the result.
|
|
1331
|
+
* All other fields only accept inclusion values (`1` or `true`).
|
|
1332
|
+
*
|
|
1333
|
+
* @example
|
|
1334
|
+
* ```ts
|
|
1335
|
+
* type UserInclusion = InclusionProjection<User>
|
|
1336
|
+
* const proj: UserInclusion = { name: 1, email: 1 }
|
|
1337
|
+
* const withoutId: UserInclusion = { name: 1, _id: 0 }
|
|
1338
|
+
* ```
|
|
1339
|
+
*/
|
|
1340
|
+
type InclusionProjection<T> = {
|
|
1341
|
+
[K in keyof T & string]?: K extends '_id' ? IncludeValue | ExcludeValue : IncludeValue;
|
|
1342
|
+
};
|
|
1343
|
+
/**
|
|
1344
|
+
* Exclusion projection — maps document fields to `0 | false`.
|
|
1345
|
+
*
|
|
1346
|
+
* Removes the specified fields from the result, keeping all others.
|
|
1347
|
+
*
|
|
1348
|
+
* @example
|
|
1349
|
+
* ```ts
|
|
1350
|
+
* type UserExclusion = ExclusionProjection<User>
|
|
1351
|
+
* const proj: UserExclusion = { email: 0, age: 0 }
|
|
1352
|
+
* ```
|
|
1353
|
+
*/
|
|
1354
|
+
type ExclusionProjection<T> = {
|
|
1355
|
+
[K in keyof T & string]?: ExcludeValue;
|
|
1356
|
+
};
|
|
1357
|
+
/**
|
|
1358
|
+
* Union of inclusion or exclusion projection for a document type `T`.
|
|
1359
|
+
*
|
|
1360
|
+
* MongoDB projections must be either all-inclusion or all-exclusion (with the
|
|
1361
|
+
* exception of `_id`, which can always be excluded). This type enforces that
|
|
1362
|
+
* constraint at the type level.
|
|
1363
|
+
*
|
|
1364
|
+
* @example
|
|
1365
|
+
* ```ts
|
|
1366
|
+
* type UserProjection = TypedProjection<User>
|
|
1367
|
+
* const include: UserProjection = { name: 1, email: 1 }
|
|
1368
|
+
* const exclude: UserProjection = { email: 0, age: 0 }
|
|
1369
|
+
* ```
|
|
1370
|
+
*/
|
|
1371
|
+
type TypedProjection<T> = InclusionProjection<T> | ExclusionProjection<T>;
|
|
1372
|
+
/** True if any key in `P` (excluding `_id`) has value `1 | true`. */
|
|
1373
|
+
type IsInclusion<P> = true extends {
|
|
1374
|
+
[K in keyof P]: K extends '_id' ? never : P[K] extends IncludeValue ? true : never;
|
|
1375
|
+
}[keyof P] ? true : false;
|
|
1376
|
+
/** Keys of `P` whose value is `1 | true` (excluding `_id`). */
|
|
1377
|
+
type IncludedKeys<P> = {
|
|
1378
|
+
[K in keyof P]: K extends '_id' ? never : P[K] extends IncludeValue ? K : never;
|
|
1379
|
+
}[keyof P];
|
|
1380
|
+
/** Keys of `P` whose value is `0 | false`. */
|
|
1381
|
+
type ExcludedKeys<P> = {
|
|
1382
|
+
[K in keyof P]: P[K] extends ExcludeValue ? K : never;
|
|
1383
|
+
}[keyof P];
|
|
1384
|
+
/** True if `P` has `_id` set to `0 | false`. */
|
|
1385
|
+
type IsIdSuppressed<P> = '_id' extends keyof P ? P['_id'] extends ExcludeValue ? true : false : false;
|
|
1386
|
+
/**
|
|
1387
|
+
* Computes the result type after applying a projection `P` to document type `T`.
|
|
1388
|
+
*
|
|
1389
|
+
* For inclusion projections (`{ name: 1 }`), returns only the included fields
|
|
1390
|
+
* plus `_id` (unless `_id: 0` is specified). For exclusion projections
|
|
1391
|
+
* (`{ email: 0 }`), returns all fields except the excluded ones.
|
|
1392
|
+
*
|
|
1393
|
+
* @example
|
|
1394
|
+
* ```ts
|
|
1395
|
+
* type User = { _id: ObjectId; name: string; email: string; age: number }
|
|
1396
|
+
*
|
|
1397
|
+
* // Inclusion: picks name + _id
|
|
1398
|
+
* type A = ProjectionResult<User, { name: 1 }>
|
|
1399
|
+
* // ^? { _id: ObjectId; name: string }
|
|
1400
|
+
*
|
|
1401
|
+
* // Inclusion with _id suppressed
|
|
1402
|
+
* type B = ProjectionResult<User, { name: 1; _id: 0 }>
|
|
1403
|
+
* // ^? { name: string }
|
|
1404
|
+
*
|
|
1405
|
+
* // Exclusion: drops email
|
|
1406
|
+
* type C = ProjectionResult<User, { email: 0 }>
|
|
1407
|
+
* // ^? { _id: ObjectId; name: string; age: number }
|
|
1408
|
+
* ```
|
|
1409
|
+
*/
|
|
1410
|
+
type ProjectionResult<T, P> = IsInclusion<P> extends true ? IsIdSuppressed<P> extends true ? Prettify<Pick<T, IncludedKeys<P> & keyof T>> : Prettify<Pick<T, (IncludedKeys<P> | '_id') & keyof T>> : IsIdSuppressed<P> extends true ? Prettify<Omit<T, ExcludedKeys<P>>> : Prettify<Omit<T, Exclude<ExcludedKeys<P>, '_id'>>>;
|
|
1411
|
+
/**
|
|
1412
|
+
* Returns `true` if the projection is an inclusion projection.
|
|
1413
|
+
*
|
|
1414
|
+
* A projection is considered inclusion when any key other than `_id` has
|
|
1415
|
+
* a value of `1` or `true`. This mirrors the MongoDB rule: you cannot mix
|
|
1416
|
+
* inclusion and exclusion (except for `_id`, which may always be suppressed).
|
|
1417
|
+
*
|
|
1418
|
+
* @example
|
|
1419
|
+
* ```ts
|
|
1420
|
+
* isInclusionProjection({ name: 1 }) // true
|
|
1421
|
+
* isInclusionProjection({ name: 1, _id: 0 }) // true
|
|
1422
|
+
* isInclusionProjection({ email: 0 }) // false
|
|
1423
|
+
* ```
|
|
1424
|
+
*/
|
|
1425
|
+
declare function isInclusionProjection(projection: Record<string, 0 | 1 | boolean>): boolean;
|
|
1426
|
+
/**
|
|
1427
|
+
* Derives a scoped Zod schema by applying a MongoDB-style projection.
|
|
1428
|
+
*
|
|
1429
|
+
* For inclusion projections (`{ name: 1, email: 1 }`), returns a schema with
|
|
1430
|
+
* only the specified fields plus `_id` (unless `_id: 0`). For exclusion
|
|
1431
|
+
* projections (`{ email: 0 }`), returns a schema with the specified fields
|
|
1432
|
+
* removed.
|
|
1433
|
+
*
|
|
1434
|
+
* Keys not present in the original schema are silently ignored.
|
|
1435
|
+
*
|
|
1436
|
+
* @example
|
|
1437
|
+
* ```ts
|
|
1438
|
+
* const userSchema = z.object({
|
|
1439
|
+
* _id: z.string(),
|
|
1440
|
+
* name: z.string(),
|
|
1441
|
+
* email: z.string(),
|
|
1442
|
+
* age: z.number(),
|
|
1443
|
+
* })
|
|
1444
|
+
*
|
|
1445
|
+
* // Inclusion: picks name + email + _id
|
|
1446
|
+
* const projected = deriveProjectedSchema(userSchema, { name: 1, email: 1 })
|
|
1447
|
+
*
|
|
1448
|
+
* // Exclusion: drops email
|
|
1449
|
+
* const excluded = deriveProjectedSchema(userSchema, { email: 0 })
|
|
1450
|
+
* ```
|
|
1451
|
+
*/
|
|
1452
|
+
declare function deriveProjectedSchema(schema: z.ZodObject<z.core.$ZodShape>, projection: Record<string, 0 | 1 | boolean>): z.ZodObject<z.core.$ZodShape>;
|
|
1453
|
+
|
|
1242
1454
|
/**
|
|
1243
1455
|
* Type-safe sort specification for a document type.
|
|
1244
1456
|
*
|
|
@@ -1263,6 +1475,7 @@ type TypedSort<T> = Partial<Record<keyof T & string, 1 | -1>>;
|
|
|
1263
1475
|
*
|
|
1264
1476
|
* @typeParam TDef - The collection definition type, used to infer the document type.
|
|
1265
1477
|
* @typeParam TIndexNames - Union of declared index names accepted by `.hint()`.
|
|
1478
|
+
* @typeParam TOutput - The output document type, narrowed by `.project()`.
|
|
1266
1479
|
*
|
|
1267
1480
|
* @example
|
|
1268
1481
|
* ```ts
|
|
@@ -1272,7 +1485,7 @@ type TypedSort<T> = Partial<Record<keyof T & string, 1 | -1>>;
|
|
|
1272
1485
|
* .toArray()
|
|
1273
1486
|
* ```
|
|
1274
1487
|
*/
|
|
1275
|
-
declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends string = string
|
|
1488
|
+
declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends string = string, TOutput = InferDocument<TDef>> {
|
|
1276
1489
|
/** @internal */
|
|
1277
1490
|
private cursor;
|
|
1278
1491
|
/** @internal */
|
|
@@ -1288,6 +1501,8 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1288
1501
|
/** @internal */
|
|
1289
1502
|
private sortSpec;
|
|
1290
1503
|
/** @internal */
|
|
1504
|
+
private projectedSchema;
|
|
1505
|
+
/** @internal */
|
|
1291
1506
|
constructor(cursor: FindCursor<InferDocument<TDef>>, definition: TDef, mode: ValidationMode | false, nativeCollection: Collection<InferDocument<TDef>>, filter: any);
|
|
1292
1507
|
/**
|
|
1293
1508
|
* Set the sort order for the query.
|
|
@@ -1348,6 +1563,33 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1348
1563
|
* ```
|
|
1349
1564
|
*/
|
|
1350
1565
|
hint(indexName: TIndexNames): this;
|
|
1566
|
+
/**
|
|
1567
|
+
* Apply a projection to narrow the returned fields.
|
|
1568
|
+
*
|
|
1569
|
+
* Inclusion projections (`{ name: 1 }`) return only the specified fields
|
|
1570
|
+
* plus `_id` (unless `_id: 0`). Exclusion projections (`{ email: 0 }`)
|
|
1571
|
+
* return all fields except those excluded.
|
|
1572
|
+
*
|
|
1573
|
+
* The cursor's output type is narrowed at compile time. A derived Zod
|
|
1574
|
+
* schema is built for runtime validation of the projected fields.
|
|
1575
|
+
*
|
|
1576
|
+
* Projects from the original document type, not from a previous projection.
|
|
1577
|
+
* Calling `.project()` twice overrides the previous projection.
|
|
1578
|
+
*
|
|
1579
|
+
* @param spec - Type-safe projection document.
|
|
1580
|
+
* @returns A new cursor with the narrowed output type.
|
|
1581
|
+
*
|
|
1582
|
+
* @example
|
|
1583
|
+
* ```ts
|
|
1584
|
+
* const names = await find(users, {})
|
|
1585
|
+
* .project({ name: 1 })
|
|
1586
|
+
* .sort({ name: 1 })
|
|
1587
|
+
* .toArray()
|
|
1588
|
+
* // names[0].name ✓
|
|
1589
|
+
* // names[0].email TS error
|
|
1590
|
+
* ```
|
|
1591
|
+
*/
|
|
1592
|
+
project<P extends TypedProjection<InferDocument<TDef>>>(spec: P): TypedFindCursor<TDef, TIndexNames, Prettify<ProjectionResult<InferDocument<TDef>, P>>>;
|
|
1351
1593
|
/**
|
|
1352
1594
|
* Execute the query with offset-based pagination, returning a page of documents
|
|
1353
1595
|
* with total count and navigation metadata.
|
|
@@ -1367,7 +1609,7 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1367
1609
|
* console.log(page.total, page.totalPages, page.hasNext)
|
|
1368
1610
|
* ```
|
|
1369
1611
|
*/
|
|
1370
|
-
paginate(opts: OffsetPaginateOptions): Promise<OffsetPage<
|
|
1612
|
+
paginate(opts: OffsetPaginateOptions): Promise<OffsetPage<TOutput>>;
|
|
1371
1613
|
/**
|
|
1372
1614
|
* Execute the query with cursor-based pagination, returning a page of documents
|
|
1373
1615
|
* with opaque cursors for forward/backward navigation.
|
|
@@ -1388,7 +1630,7 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1388
1630
|
* .paginate({ cursor: first.endCursor, limit: 10 })
|
|
1389
1631
|
* ```
|
|
1390
1632
|
*/
|
|
1391
|
-
paginate(opts: CursorPaginateOptions): Promise<CursorPage<
|
|
1633
|
+
paginate(opts: CursorPaginateOptions): Promise<CursorPage<TOutput>>;
|
|
1392
1634
|
/** @internal Offset pagination implementation. */
|
|
1393
1635
|
private offsetPaginate;
|
|
1394
1636
|
/** @internal Cursor pagination implementation. */
|
|
@@ -1407,7 +1649,7 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1407
1649
|
* const admins = await find(users, { role: 'admin' }).toArray()
|
|
1408
1650
|
* ```
|
|
1409
1651
|
*/
|
|
1410
|
-
toArray(): Promise<
|
|
1652
|
+
toArray(): Promise<TOutput[]>;
|
|
1411
1653
|
/**
|
|
1412
1654
|
* Async iterator for streaming documents one at a time.
|
|
1413
1655
|
*
|
|
@@ -1424,17 +1666,33 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1424
1666
|
* }
|
|
1425
1667
|
* ```
|
|
1426
1668
|
*/
|
|
1427
|
-
[Symbol.asyncIterator](): AsyncGenerator<
|
|
1669
|
+
[Symbol.asyncIterator](): AsyncGenerator<TOutput>;
|
|
1428
1670
|
/** @internal Validate a single raw document against the schema. */
|
|
1429
1671
|
private validateDoc;
|
|
1430
1672
|
}
|
|
1431
1673
|
|
|
1432
1674
|
/**
|
|
1433
|
-
* Options for {@link findOne} and {@link findOneOrThrow}.
|
|
1675
|
+
* Options for {@link findOne} and {@link findOneOrThrow} without projection.
|
|
1434
1676
|
*/
|
|
1435
1677
|
type FindOneOptions = {
|
|
1436
|
-
/**
|
|
1437
|
-
|
|
1678
|
+
/** Override the collection-level validation mode, or `false` to skip validation entirely. */
|
|
1679
|
+
validate?: ValidationMode | false;
|
|
1680
|
+
};
|
|
1681
|
+
/**
|
|
1682
|
+
* Options for projected {@link findOne} and {@link findOneOrThrow} queries.
|
|
1683
|
+
*
|
|
1684
|
+
* @typeParam T - The document type.
|
|
1685
|
+
* @typeParam P - The projection document type.
|
|
1686
|
+
*
|
|
1687
|
+
* @example
|
|
1688
|
+
* ```ts
|
|
1689
|
+
* const user = await findOne(users, { name: 'Ada' }, { project: { name: 1 } })
|
|
1690
|
+
* // ^? { _id: ObjectId; name: string } | null
|
|
1691
|
+
* ```
|
|
1692
|
+
*/
|
|
1693
|
+
type FindOneProjectionOptions<T, P extends TypedProjection<T>> = {
|
|
1694
|
+
/** Type-safe MongoDB projection — include (`1 | true`) or exclude (`0 | false`) fields. */
|
|
1695
|
+
project: P;
|
|
1438
1696
|
/** Override the collection-level validation mode, or `false` to skip validation entirely. */
|
|
1439
1697
|
validate?: ValidationMode | false;
|
|
1440
1698
|
};
|
|
@@ -1447,7 +1705,7 @@ type FindOneOptions = {
|
|
|
1447
1705
|
*
|
|
1448
1706
|
* @param handle - The collection handle to query.
|
|
1449
1707
|
* @param filter - Type-safe filter to match documents.
|
|
1450
|
-
* @param options - Optional
|
|
1708
|
+
* @param options - Optional validation overrides.
|
|
1451
1709
|
* @returns The matched document, or `null` if no document matches.
|
|
1452
1710
|
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
1453
1711
|
*
|
|
@@ -1458,6 +1716,26 @@ type FindOneOptions = {
|
|
|
1458
1716
|
* ```
|
|
1459
1717
|
*/
|
|
1460
1718
|
declare function findOne<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef> | null>;
|
|
1719
|
+
/**
|
|
1720
|
+
* Find a single document matching the filter with a type-safe projection.
|
|
1721
|
+
*
|
|
1722
|
+
* Returns only the fields specified by the projection. The return type is
|
|
1723
|
+
* narrowed to reflect which fields are included or excluded.
|
|
1724
|
+
*
|
|
1725
|
+
* @param handle - The collection handle to query.
|
|
1726
|
+
* @param filter - Type-safe filter to match documents.
|
|
1727
|
+
* @param options - Projection and optional validation overrides.
|
|
1728
|
+
* @returns The projected document, or `null` if no document matches.
|
|
1729
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
1730
|
+
*
|
|
1731
|
+
* @example
|
|
1732
|
+
* ```ts
|
|
1733
|
+
* const user = await findOne(users, { name: 'Ada' }, { project: { name: 1 } })
|
|
1734
|
+
* if (user) console.log(user.name) // typed as string
|
|
1735
|
+
* // user.role would be a type error — not in the projection
|
|
1736
|
+
* ```
|
|
1737
|
+
*/
|
|
1738
|
+
declare function findOne<TDef extends AnyCollection, P extends TypedProjection<InferDocument<TDef>>>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options: FindOneProjectionOptions<InferDocument<TDef>, P>): Promise<Prettify<ProjectionResult<InferDocument<TDef>, P>> | null>;
|
|
1461
1739
|
/**
|
|
1462
1740
|
* Find a single document matching the filter, or throw if none exists.
|
|
1463
1741
|
*
|
|
@@ -1466,7 +1744,7 @@ declare function findOne<TDef extends AnyCollection>(handle: CollectionHandle<TD
|
|
|
1466
1744
|
*
|
|
1467
1745
|
* @param handle - The collection handle to query.
|
|
1468
1746
|
* @param filter - Type-safe filter to match documents.
|
|
1469
|
-
* @param options - Optional
|
|
1747
|
+
* @param options - Optional validation overrides.
|
|
1470
1748
|
* @returns The matched document (never null).
|
|
1471
1749
|
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
1472
1750
|
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
@@ -1478,6 +1756,28 @@ declare function findOne<TDef extends AnyCollection>(handle: CollectionHandle<TD
|
|
|
1478
1756
|
* ```
|
|
1479
1757
|
*/
|
|
1480
1758
|
declare function findOneOrThrow<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef>>;
|
|
1759
|
+
/**
|
|
1760
|
+
* Find a single document matching the filter with a type-safe projection, or throw if none exists.
|
|
1761
|
+
*
|
|
1762
|
+
* Returns only the fields specified by the projection. The return type is
|
|
1763
|
+
* narrowed to reflect which fields are included or excluded. Throws
|
|
1764
|
+
* {@link ZodmonNotFoundError} instead of returning `null`.
|
|
1765
|
+
*
|
|
1766
|
+
* @param handle - The collection handle to query.
|
|
1767
|
+
* @param filter - Type-safe filter to match documents.
|
|
1768
|
+
* @param options - Projection and optional validation overrides.
|
|
1769
|
+
* @returns The projected document (never null).
|
|
1770
|
+
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
1771
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
1772
|
+
*
|
|
1773
|
+
* @example
|
|
1774
|
+
* ```ts
|
|
1775
|
+
* const user = await findOneOrThrow(users, { name: 'Ada' }, { project: { name: 1 } })
|
|
1776
|
+
* console.log(user.name) // typed as string
|
|
1777
|
+
* // user.role would be a type error — not in the projection
|
|
1778
|
+
* ```
|
|
1779
|
+
*/
|
|
1780
|
+
declare function findOneOrThrow<TDef extends AnyCollection, P extends TypedProjection<InferDocument<TDef>>>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options: FindOneProjectionOptions<InferDocument<TDef>, P>): Promise<Prettify<ProjectionResult<InferDocument<TDef>, P>>>;
|
|
1481
1781
|
/**
|
|
1482
1782
|
* Options for {@link find}.
|
|
1483
1783
|
*/
|
|
@@ -1485,6 +1785,25 @@ type FindOptions = {
|
|
|
1485
1785
|
/** Override the collection-level validation mode, or `false` to skip validation entirely. */
|
|
1486
1786
|
validate?: ValidationMode | false;
|
|
1487
1787
|
};
|
|
1788
|
+
/**
|
|
1789
|
+
* Options for projected {@link find} queries.
|
|
1790
|
+
*
|
|
1791
|
+
* @typeParam T - The document type.
|
|
1792
|
+
* @typeParam P - The projection document type.
|
|
1793
|
+
*
|
|
1794
|
+
* @example
|
|
1795
|
+
* ```ts
|
|
1796
|
+
* const admins = await find(users, { role: 'admin' }, { project: { name: 1 } })
|
|
1797
|
+
* .toArray()
|
|
1798
|
+
* // ^? Array<{ _id: ObjectId; name: string }>
|
|
1799
|
+
* ```
|
|
1800
|
+
*/
|
|
1801
|
+
type FindProjectionOptions<T, P extends TypedProjection<T>> = {
|
|
1802
|
+
/** Type-safe MongoDB projection — include (`1 | true`) or exclude (`0 | false`) fields. */
|
|
1803
|
+
project: P;
|
|
1804
|
+
/** Override the collection-level validation mode, or `false` to skip validation entirely. */
|
|
1805
|
+
validate?: ValidationMode | false;
|
|
1806
|
+
};
|
|
1488
1807
|
/**
|
|
1489
1808
|
* Find all documents matching the filter, returning a chainable typed cursor.
|
|
1490
1809
|
*
|
|
@@ -1516,6 +1835,28 @@ type FindOptions = {
|
|
|
1516
1835
|
* ```
|
|
1517
1836
|
*/
|
|
1518
1837
|
declare function find<TDef extends AnyCollection>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options?: FindOptions): TypedFindCursor<TDef, IndexNames<TDef>>;
|
|
1838
|
+
/**
|
|
1839
|
+
* Find all documents matching the filter with a type-safe projection, returning a chainable typed cursor.
|
|
1840
|
+
*
|
|
1841
|
+
* The cursor is lazy — no query is executed until a terminal method
|
|
1842
|
+
* (`toArray`, `for await`) is called. The return type is narrowed to
|
|
1843
|
+
* reflect which fields are included or excluded by the projection.
|
|
1844
|
+
*
|
|
1845
|
+
* @param handle - The collection handle to query.
|
|
1846
|
+
* @param filter - Type-safe filter to match documents.
|
|
1847
|
+
* @param options - Projection and optional validation overrides.
|
|
1848
|
+
* @returns A typed cursor whose output type matches the projection.
|
|
1849
|
+
*
|
|
1850
|
+
* @example
|
|
1851
|
+
* ```ts
|
|
1852
|
+
* const names = await find(users, { role: 'admin' }, { project: { name: 1 } })
|
|
1853
|
+
* .sort({ name: 1 })
|
|
1854
|
+
* .toArray()
|
|
1855
|
+
* // names[0].name — string
|
|
1856
|
+
* // names[0].role — type error, not in projection
|
|
1857
|
+
* ```
|
|
1858
|
+
*/
|
|
1859
|
+
declare function find<TDef extends AnyCollection, P extends TypedProjection<InferDocument<TDef>>>(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options: FindProjectionOptions<InferDocument<TDef>, P>): TypedFindCursor<TDef, IndexNames<TDef>, Prettify<ProjectionResult<InferDocument<TDef>, P>>>;
|
|
1519
1860
|
|
|
1520
1861
|
/**
|
|
1521
1862
|
* Extracts the element type from an array type.
|
|
@@ -1541,7 +1882,7 @@ type ArrayElement<T> = T extends ReadonlyArray<infer E> ? E : never;
|
|
|
1541
1882
|
type SetFields<T> = {
|
|
1542
1883
|
[K in keyof T]?: T[K];
|
|
1543
1884
|
} & {
|
|
1544
|
-
[P in
|
|
1885
|
+
[P in _DotPaths<T>]?: _DotPathType<T, P>;
|
|
1545
1886
|
};
|
|
1546
1887
|
/**
|
|
1547
1888
|
* Fields valid for the `$inc` operator — only number-typed fields.
|
|
@@ -1556,7 +1897,7 @@ type SetFields<T> = {
|
|
|
1556
1897
|
type IncFields<T> = {
|
|
1557
1898
|
[K in keyof T as NonNullable<T[K]> extends number ? K : never]?: number;
|
|
1558
1899
|
} & {
|
|
1559
|
-
[P in
|
|
1900
|
+
[P in _DotPaths<T> as _DotPathType<T, P> extends number ? P : never]?: number;
|
|
1560
1901
|
};
|
|
1561
1902
|
/**
|
|
1562
1903
|
* Modifiers for the `$push` operator.
|
|
@@ -1965,7 +2306,7 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
1965
2306
|
* back to the collection-level default (which defaults to `'strict'`).
|
|
1966
2307
|
*
|
|
1967
2308
|
* @param filter - Type-safe filter to match documents.
|
|
1968
|
-
* @param options - Optional
|
|
2309
|
+
* @param options - Optional validation overrides.
|
|
1969
2310
|
* @returns The matched document, or `null` if no document matches.
|
|
1970
2311
|
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
1971
2312
|
*
|
|
@@ -1977,6 +2318,25 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
1977
2318
|
* ```
|
|
1978
2319
|
*/
|
|
1979
2320
|
findOne(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef> | null>;
|
|
2321
|
+
/**
|
|
2322
|
+
* Find a single document matching the filter with a type-safe projection.
|
|
2323
|
+
*
|
|
2324
|
+
* Returns only the fields specified by the projection. The return type is
|
|
2325
|
+
* narrowed to reflect which fields are included or excluded.
|
|
2326
|
+
*
|
|
2327
|
+
* @param filter - Type-safe filter to match documents.
|
|
2328
|
+
* @param options - Projection and optional validation overrides.
|
|
2329
|
+
* @returns The projected document, or `null` if no document matches.
|
|
2330
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
2331
|
+
*
|
|
2332
|
+
* @example
|
|
2333
|
+
* ```ts
|
|
2334
|
+
* const users = db.use(Users)
|
|
2335
|
+
* const user = await users.findOne({ name: 'Ada' }, { project: { name: 1 } })
|
|
2336
|
+
* if (user) console.log(user.name) // typed as string
|
|
2337
|
+
* ```
|
|
2338
|
+
*/
|
|
2339
|
+
findOne<P extends TypedProjection<InferDocument<TDef>>>(filter: TypedFilter<InferDocument<TDef>>, options: FindOneProjectionOptions<InferDocument<TDef>, P>): Promise<Prettify<ProjectionResult<InferDocument<TDef>, P>> | null>;
|
|
1980
2340
|
/**
|
|
1981
2341
|
* Find a single document matching the filter, or throw if none exists.
|
|
1982
2342
|
*
|
|
@@ -1984,7 +2344,7 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
1984
2344
|
* instead of returning `null` when no document matches the filter.
|
|
1985
2345
|
*
|
|
1986
2346
|
* @param filter - Type-safe filter to match documents.
|
|
1987
|
-
* @param options - Optional
|
|
2347
|
+
* @param options - Optional validation overrides.
|
|
1988
2348
|
* @returns The matched document (never null).
|
|
1989
2349
|
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
1990
2350
|
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
@@ -1997,6 +2357,27 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
1997
2357
|
* ```
|
|
1998
2358
|
*/
|
|
1999
2359
|
findOneOrThrow(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): Promise<InferDocument<TDef>>;
|
|
2360
|
+
/**
|
|
2361
|
+
* Find a single document matching the filter with a type-safe projection, or throw if none exists.
|
|
2362
|
+
*
|
|
2363
|
+
* Returns only the fields specified by the projection. The return type is
|
|
2364
|
+
* narrowed to reflect which fields are included or excluded. Throws
|
|
2365
|
+
* {@link ZodmonNotFoundError} instead of returning `null`.
|
|
2366
|
+
*
|
|
2367
|
+
* @param filter - Type-safe filter to match documents.
|
|
2368
|
+
* @param options - Projection and optional validation overrides.
|
|
2369
|
+
* @returns The projected document (never null).
|
|
2370
|
+
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
2371
|
+
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
2372
|
+
*
|
|
2373
|
+
* @example
|
|
2374
|
+
* ```ts
|
|
2375
|
+
* const users = db.use(Users)
|
|
2376
|
+
* const user = await users.findOneOrThrow({ name: 'Ada' }, { project: { name: 1 } })
|
|
2377
|
+
* console.log(user.name) // typed as string
|
|
2378
|
+
* ```
|
|
2379
|
+
*/
|
|
2380
|
+
findOneOrThrow<P extends TypedProjection<InferDocument<TDef>>>(filter: TypedFilter<InferDocument<TDef>>, options: FindOneProjectionOptions<InferDocument<TDef>, P>): Promise<Prettify<ProjectionResult<InferDocument<TDef>, P>>>;
|
|
2000
2381
|
/**
|
|
2001
2382
|
* Find all documents matching the filter, returning a chainable typed cursor.
|
|
2002
2383
|
*
|
|
@@ -2018,6 +2399,24 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
2018
2399
|
* ```
|
|
2019
2400
|
*/
|
|
2020
2401
|
find(filter: TypedFilter<InferDocument<TDef>>, options?: FindOptions): TypedFindCursor<TDef, IndexNames<TDef>>;
|
|
2402
|
+
/**
|
|
2403
|
+
* Find all documents matching the filter with a type-safe projection, returning a chainable typed cursor.
|
|
2404
|
+
*
|
|
2405
|
+
* The return type is narrowed to reflect which fields are included or excluded.
|
|
2406
|
+
*
|
|
2407
|
+
* @param filter - Type-safe filter to match documents.
|
|
2408
|
+
* @param options - Projection and optional validation overrides.
|
|
2409
|
+
* @returns A typed cursor whose output type matches the projection.
|
|
2410
|
+
*
|
|
2411
|
+
* @example
|
|
2412
|
+
* ```ts
|
|
2413
|
+
* const users = db.use(Users)
|
|
2414
|
+
* const names = await users.find({ role: 'admin' }, { project: { name: 1 } })
|
|
2415
|
+
* .toArray()
|
|
2416
|
+
* // names[0].name — string
|
|
2417
|
+
* ```
|
|
2418
|
+
*/
|
|
2419
|
+
find<P extends TypedProjection<InferDocument<TDef>>>(filter: TypedFilter<InferDocument<TDef>>, options: FindProjectionOptions<InferDocument<TDef>, P>): TypedFindCursor<TDef, IndexNames<TDef>, Prettify<ProjectionResult<InferDocument<TDef>, P>>>;
|
|
2021
2420
|
/**
|
|
2022
2421
|
* Update a single document matching the filter.
|
|
2023
2422
|
*
|
|
@@ -2481,8 +2880,8 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
2481
2880
|
* .toArray()
|
|
2482
2881
|
* ```
|
|
2483
2882
|
*/
|
|
2484
|
-
groupBy<K extends
|
|
2485
|
-
groupBy<K extends
|
|
2883
|
+
groupBy<K extends DotPath<TOutput>, TAccum extends Record<string, Accumulator>>(field: K, accumulators: ((acc: AccumulatorBuilder<TOutput>) => TAccum) | TAccum): AggregatePipeline<TDef, GroupByResult<TOutput, K, TAccum>>;
|
|
2884
|
+
groupBy<K extends DotPath<TOutput>, TAccum extends Record<string, Accumulator>>(field: K[], accumulators: ((acc: AccumulatorBuilder<TOutput>) => TAccum) | TAccum): AggregatePipeline<TDef, GroupByCompoundResult<TOutput, K, TAccum>>;
|
|
2486
2885
|
/**
|
|
2487
2886
|
* Add new fields or overwrite existing ones in the output documents.
|
|
2488
2887
|
*
|
|
@@ -3918,4 +4317,4 @@ type UpdateFilterOf<TDef extends AnyCollection> = TypedUpdateFilter<InferDocumen
|
|
|
3918
4317
|
*/
|
|
3919
4318
|
type SortOf<TDef extends AnyCollection> = TypedSort<InferDocument<TDef>>;
|
|
3920
4319
|
|
|
3921
|
-
export { $, $addToSet, $and, $avg, $count, $eq, $exists, $first, $gt, $gte, $in, $last, $lt, $lte, $max, $min, $ne, $nin, $nor, $not, $or, $push, $regex, $sum, type Accumulator, type AccumulatorBuilder, type AddToSetEach, type AddToSetFields, AggregatePipeline, type AnyCollection, type ArrayElement, type CollectionDefinition, CollectionHandle, type CollectionName, type CollectionOptions, type ComparisonOperators, type CompoundIndexDefinition, type CurrentDateFields, type CursorPage, type CursorPaginateOptions, Database, type
|
|
4320
|
+
export { $, $addToSet, $and, $avg, $count, $eq, $exists, $first, $gt, $gte, $in, $last, $lt, $lte, $max, $min, $ne, $nin, $nor, $not, $or, $push, $regex, $sum, type Accumulator, type AccumulatorBuilder, type AddToSetEach, type AddToSetFields, AggregatePipeline, type AnyCollection, type ArrayElement, type CollectionDefinition, CollectionHandle, type CollectionName, type CollectionOptions, type ComparisonOperators, type CompoundIndexDefinition, type CurrentDateFields, type CursorPage, type CursorPaginateOptions, Database, type DotPath, type DotPathValue, type ExclusionProjection, type Expression, type ExpressionBuilder, type ExtractRefCollection, type FieldIndexDefinition, type FieldRef, type FieldRefType, type FilterOf, type FindOneAndDeleteOptions, type FindOneAndUpdateOptions, type FindOneOptions, type FindOneProjectionOptions, type FindOptions, type FindProjectionOptions, type GroupByCompoundResult, type GroupByResult, type HandleOf, type IncFields, type InclusionProjection, IndexBuilder, type IndexMetadata, type IndexNames, type IndexOptions, type IndexSpec, type InferAccumulator, type InferAccumulators, type InferAddedFields, type InferDocument, type InferExpression, type InferInsert, type NarrowFromFilter, type OffsetPage, type OffsetPaginateOptions, type PopFields, type Prettify, type ProjectionResult, type PullFields, type PushFields, type PushModifiers, type RefFields, type RefMarker, type RefMetadata, type RenameFields, type ResolvedShape, type SetFields, type SortOf, type StaleIndex, type SyncIndexesOptions, type SyncIndexesResult, type TypedFilter, TypedFindCursor, type TypedProjection, type TypedSort, type TypedUpdateFilter, type UnsetFields, type UnwindResult, type UpdateFilterOf, type UpdateOptions, type ValidationMode, type ZodObjectId, ZodmonAuthError, ZodmonBulkWriteError, ZodmonDocValidationError, ZodmonDuplicateKeyError, ZodmonError, ZodmonIndexError, ZodmonNetworkError, ZodmonNotFoundError, ZodmonQueryError, ZodmonTimeoutError, ZodmonValidationError, ZodmonWriteConflictError, type _DotPathType, type _DotPaths, aggregate, checkUnindexedFields, collection, createAccumulatorBuilder, createClient, createExpressionBuilder, deleteMany, deleteOne, deriveProjectedSchema, extractComparableOptions, extractDbName, extractFieldIndexes, find, findOne, findOneAndDelete, findOneAndUpdate, findOneOrThrow, generateIndexName, getIndexMetadata, getRefMetadata, index, insertMany, insertOne, isInclusionProjection, isOid, objectId, oid, raw, serializeIndexKey, syncIndexes, toCompoundIndexSpec, toFieldIndexSpec, updateMany, updateOne, wrapMongoError };
|