@zodmon/core 0.11.0 → 0.12.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 +870 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1323 -152
- package/dist/index.d.ts +1323 -152
- package/dist/index.js +861 -149
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ObjectId, Document, DeleteResult, FindCursor,
|
|
1
|
+
import { ObjectId, Document, DeleteResult, Collection, FindCursor, ClientSession, UpdateResult, MongoClientOptions } from 'mongodb';
|
|
2
2
|
import { ZodPipe, ZodCustom, ZodTransform, z, ZodDefault } from 'zod';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -260,6 +260,8 @@ type InferInsert<TDef extends {
|
|
|
260
260
|
type CollectionDefinition<TName extends string = string, TShape extends z.core.$ZodShape = z.core.$ZodShape, TIndexes extends readonly CompoundIndexDefinition<Extract<keyof TShape, string>>[] = readonly CompoundIndexDefinition<Extract<keyof TShape, string>>[]> = {
|
|
261
261
|
readonly name: TName;
|
|
262
262
|
readonly schema: z.ZodObject<ResolvedShape<TShape>>;
|
|
263
|
+
/** Strict validation variant that throws on unknown fields. */
|
|
264
|
+
readonly strictSchema: z.ZodObject<ResolvedShape<TShape>>;
|
|
263
265
|
readonly shape: TShape;
|
|
264
266
|
readonly fieldIndexes: FieldIndexDefinition[];
|
|
265
267
|
readonly compoundIndexes: TIndexes;
|
|
@@ -431,6 +433,48 @@ declare module 'zod' {
|
|
|
431
433
|
* ```
|
|
432
434
|
*/
|
|
433
435
|
declare function getRefMetadata(schema: unknown): RefMetadata | undefined;
|
|
436
|
+
/**
|
|
437
|
+
* Peel Zod wrappers (ZodOptional, ZodNullable, ZodDefault, ZodArray)
|
|
438
|
+
* to reach the inner schema type. Used to detect RefMarker on wrapped
|
|
439
|
+
* fields like `objectId().ref(X).optional()` or `z.array(objectId().ref(X))`.
|
|
440
|
+
*
|
|
441
|
+
* Bounded by wrapper depth (1-3 layers) — no circular risk.
|
|
442
|
+
*
|
|
443
|
+
* @example
|
|
444
|
+
* ```ts
|
|
445
|
+
* // ZodOptional<ZodObjectId & RefMarker<typeof Users>> → ZodObjectId & RefMarker<typeof Users>
|
|
446
|
+
* type Inner = UnwrapRef<typeof schema>
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
type UnwrapRef<T> = T extends z.ZodOptional<infer U> ? UnwrapRef<U> : T extends z.ZodNullable<infer U> ? UnwrapRef<U> : T extends z.ZodDefault<infer U> ? UnwrapRef<U> : T extends z.ZodArray<infer E> ? UnwrapRef<E> : T;
|
|
450
|
+
/**
|
|
451
|
+
* Extract field names that carry `.ref()` metadata from a collection definition.
|
|
452
|
+
*
|
|
453
|
+
* Unwraps ZodArray, ZodOptional, ZodNullable, ZodDefault to detect refs on
|
|
454
|
+
* inner schemas. Works for bare refs, array refs, and optional refs.
|
|
455
|
+
*
|
|
456
|
+
* @example
|
|
457
|
+
* ```ts
|
|
458
|
+
* type PostRefs = RefFields<typeof Posts>
|
|
459
|
+
* // ^? 'authorId' | 'categoryIds' | 'reviewerId'
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
type RefFields<TDef extends AnyCollection> = {
|
|
463
|
+
[K in keyof TDef['shape'] & string]: UnwrapRef<TDef['shape'][K]> extends RefMarker ? K : never;
|
|
464
|
+
}[keyof TDef['shape'] & string];
|
|
465
|
+
/**
|
|
466
|
+
* Given a collection definition and a ref-bearing field key, extract
|
|
467
|
+
* the target collection type from the `RefMarker<TCollection>` phantom.
|
|
468
|
+
*
|
|
469
|
+
* Unwraps Zod wrappers to reach the inner RefMarker.
|
|
470
|
+
*
|
|
471
|
+
* @example
|
|
472
|
+
* ```ts
|
|
473
|
+
* type Target = ExtractRefCollection<typeof Posts, 'authorId'>
|
|
474
|
+
* // ^? typeof Users
|
|
475
|
+
* ```
|
|
476
|
+
*/
|
|
477
|
+
type ExtractRefCollection<TDef extends AnyCollection, K extends RefFields<TDef>> = UnwrapRef<TDef['shape'][K]> extends RefMarker<infer TCol> ? TCol : never;
|
|
434
478
|
|
|
435
479
|
/**
|
|
436
480
|
* Branded wrapper for accumulator expressions used inside `groupBy`.
|
|
@@ -572,12 +616,26 @@ type FieldRefType<T, F extends string> = F extends `$${infer K}` ? DotPathValue<
|
|
|
572
616
|
type GroupByResult<T, K extends DotPath<T>, TAccum extends Record<string, Accumulator>> = Prettify<{
|
|
573
617
|
_id: DotPathValue<T, K & string>;
|
|
574
618
|
} & InferAccumulators<TAccum>>;
|
|
619
|
+
/**
|
|
620
|
+
* Replace dots with underscores in a string type.
|
|
621
|
+
*
|
|
622
|
+
* Used to sanitize dot-path keys for compound `groupBy` `_id` sub-documents,
|
|
623
|
+
* since MongoDB forbids dots in field names.
|
|
624
|
+
*
|
|
625
|
+
* @example
|
|
626
|
+
* ```ts
|
|
627
|
+
* type R = ReplaceDots<'address.city'>
|
|
628
|
+
* // ^? 'address_city'
|
|
629
|
+
* ```
|
|
630
|
+
*/
|
|
631
|
+
type ReplaceDots<S extends string> = S extends `${infer A}.${infer B}` ? `${A}_${ReplaceDots<B>}` : S;
|
|
575
632
|
/**
|
|
576
633
|
* Output shape of a compound (multi-field) `groupBy` stage.
|
|
577
634
|
*
|
|
578
635
|
* The `_id` field is an object with one property per grouped field,
|
|
579
636
|
* and the rest of the shape comes from the inferred accumulator types.
|
|
580
|
-
*
|
|
637
|
+
* Dot-path keys are sanitized (dots replaced with underscores) because
|
|
638
|
+
* MongoDB forbids dots in field names.
|
|
581
639
|
*
|
|
582
640
|
* @example
|
|
583
641
|
* ```ts
|
|
@@ -585,14 +643,30 @@ type GroupByResult<T, K extends DotPath<T>, TAccum extends Record<string, Accumu
|
|
|
585
643
|
* // ^? { _id: { status: string; region: string }; count: number }
|
|
586
644
|
*
|
|
587
645
|
* type Nested = GroupByCompoundResult<Order, 'name' | 'address.city', { count: Accumulator<number> }>
|
|
588
|
-
* // ^? { _id: { name: string;
|
|
646
|
+
* // ^? { _id: { name: string; address_city: string }; count: number }
|
|
589
647
|
* ```
|
|
590
648
|
*/
|
|
591
649
|
type GroupByCompoundResult<T, K extends DotPath<T>, TAccum extends Record<string, Accumulator>> = Prettify<{
|
|
592
650
|
_id: Prettify<{
|
|
593
|
-
[P in K & string]: DotPathValue<T, P>;
|
|
651
|
+
[P in K & string as ReplaceDots<P>]: DotPathValue<T, P>;
|
|
594
652
|
}>;
|
|
595
653
|
} & InferAccumulators<TAccum>>;
|
|
654
|
+
/**
|
|
655
|
+
* Output shape of a null-key `groupBy` stage (global aggregation).
|
|
656
|
+
*
|
|
657
|
+
* When `groupBy(null, ...)` is used, MongoDB collapses all documents
|
|
658
|
+
* into a single group with `_id: null`. The rest of the shape comes
|
|
659
|
+
* from the inferred accumulator types.
|
|
660
|
+
*
|
|
661
|
+
* @example
|
|
662
|
+
* ```ts
|
|
663
|
+
* type Result = GroupByNullResult<{ total: Accumulator<number> }>
|
|
664
|
+
* // ^? { _id: null; total: number }
|
|
665
|
+
* ```
|
|
666
|
+
*/
|
|
667
|
+
type GroupByNullResult<TAccum extends Record<string, Accumulator>> = Prettify<{
|
|
668
|
+
_id: null;
|
|
669
|
+
} & InferAccumulators<TAccum>>;
|
|
596
670
|
/**
|
|
597
671
|
* Output shape after unwinding an array field.
|
|
598
672
|
*
|
|
@@ -644,29 +718,6 @@ type NarrowFromFilter<T, F> = {
|
|
|
644
718
|
$nin: ReadonlyArray<infer V extends T[K]>;
|
|
645
719
|
} ? Exclude<T[K], V> : T[K] : T[K];
|
|
646
720
|
};
|
|
647
|
-
/**
|
|
648
|
-
* Extract field keys from a collection definition whose schema fields
|
|
649
|
-
* carry `RefMarker` (i.e. fields that have `.ref()` metadata).
|
|
650
|
-
*
|
|
651
|
-
* @example
|
|
652
|
-
* ```ts
|
|
653
|
-
* type EmpRefs = RefFields<typeof Employees> // → 'departmentId'
|
|
654
|
-
* ```
|
|
655
|
-
*/
|
|
656
|
-
type RefFields<TDef extends AnyCollection> = {
|
|
657
|
-
[K in keyof TDef['shape'] & string]: TDef['shape'][K] extends RefMarker ? K : never;
|
|
658
|
-
}[keyof TDef['shape'] & string];
|
|
659
|
-
/**
|
|
660
|
-
* Given a collection definition and a ref-bearing field key, extract
|
|
661
|
-
* the target collection type from the `RefMarker<TCollection>` phantom.
|
|
662
|
-
*
|
|
663
|
-
* @example
|
|
664
|
-
* ```ts
|
|
665
|
-
* type Target = ExtractRefCollection<typeof Employees, 'departmentId'>
|
|
666
|
-
* // → typeof Departments
|
|
667
|
-
* ```
|
|
668
|
-
*/
|
|
669
|
-
type ExtractRefCollection<TDef extends AnyCollection, K extends RefFields<TDef>> = TDef['shape'][K] extends RefMarker<infer TCol> ? TCol : never;
|
|
670
721
|
/**
|
|
671
722
|
* Extract the collection name string literal from a collection definition.
|
|
672
723
|
*
|
|
@@ -723,12 +774,44 @@ type InferExpression<T> = T extends Expression<infer R> ? R : unknown;
|
|
|
723
774
|
type InferAddedFields<T extends Record<string, unknown>> = {
|
|
724
775
|
[K in keyof T]: InferExpression<T[K]>;
|
|
725
776
|
};
|
|
777
|
+
/**
|
|
778
|
+
* Accepts either a dot-path field reference or a pre-built `Expression<R>`.
|
|
779
|
+
*
|
|
780
|
+
* Used throughout `ExpressionBuilder` to allow method inputs to be either a
|
|
781
|
+
* field name string (auto-prefixed with `$` at runtime) or the result of a
|
|
782
|
+
* previous expression call (embedded directly into the pipeline stage).
|
|
783
|
+
*
|
|
784
|
+
* @typeParam T - The current pipeline document type.
|
|
785
|
+
* @typeParam R - The runtime value type produced by this input.
|
|
786
|
+
*
|
|
787
|
+
* @example
|
|
788
|
+
* ```ts
|
|
789
|
+
* // Field path (common case)
|
|
790
|
+
* expr.round('salary', 2)
|
|
791
|
+
*
|
|
792
|
+
* // Composed expression
|
|
793
|
+
* expr.round(expr.multiply('salary', 0.1), 2)
|
|
794
|
+
* ```
|
|
795
|
+
*/
|
|
796
|
+
type FieldOrExpr<T, R = unknown> = DotPath<T> | Expression<R>;
|
|
797
|
+
/**
|
|
798
|
+
* Extracts the element type from a readonly or mutable array type.
|
|
799
|
+
*
|
|
800
|
+
* @example
|
|
801
|
+
* ```ts
|
|
802
|
+
* type Item = ArrayElement<string[]> // → string
|
|
803
|
+
* type Num = ArrayElement<number[]> // → number
|
|
804
|
+
* type N = ArrayElement<string> // → never
|
|
805
|
+
* ```
|
|
806
|
+
*/
|
|
807
|
+
type ArrayElement<T> = T extends ReadonlyArray<infer E> ? E : never;
|
|
726
808
|
/**
|
|
727
809
|
* Typed expression factory passed to the `addFields` callback.
|
|
728
810
|
*
|
|
729
|
-
* Each method
|
|
730
|
-
*
|
|
731
|
-
*
|
|
811
|
+
* Each method accepts either a `DotPath<T>` field name string (auto-prefixed
|
|
812
|
+
* with `$` at runtime) or the result of a previous expression call
|
|
813
|
+
* (`Expression<R>`, embedded directly). This enables arbitrarily deep
|
|
814
|
+
* expression composition without `.raw()`.
|
|
732
815
|
*
|
|
733
816
|
* @typeParam T - The current pipeline output document type.
|
|
734
817
|
*
|
|
@@ -736,65 +819,181 @@ type InferAddedFields<T extends Record<string, unknown>> = {
|
|
|
736
819
|
* ```ts
|
|
737
820
|
* employees.aggregate()
|
|
738
821
|
* .addFields(expr => ({
|
|
739
|
-
* hireYear: expr.year('hiredAt'),
|
|
740
|
-
*
|
|
741
|
-
*
|
|
822
|
+
* hireYear: expr.year('hiredAt'),
|
|
823
|
+
* bonus: expr.round(expr.multiply('salary', 0.1), 2),
|
|
824
|
+
* profitMargin: expr.cond(
|
|
825
|
+
* expr.eq('revenue', 0),
|
|
826
|
+
* 0,
|
|
827
|
+
* expr.round(expr.divide(expr.subtract('revenue', 'cost'), 'revenue'), 4),
|
|
828
|
+
* ),
|
|
742
829
|
* }))
|
|
743
830
|
* ```
|
|
744
831
|
*/
|
|
745
832
|
type ExpressionBuilder<T> = {
|
|
746
|
-
/** Add
|
|
747
|
-
add<
|
|
748
|
-
/** Subtract
|
|
749
|
-
subtract<
|
|
750
|
-
/** Multiply
|
|
751
|
-
multiply<
|
|
752
|
-
/** Divide a
|
|
753
|
-
divide<
|
|
754
|
-
/** Modulo of a
|
|
755
|
-
mod<
|
|
756
|
-
/** Absolute value of a numeric field. Returns `Expression<number>`. */
|
|
757
|
-
abs<
|
|
758
|
-
/** Ceiling of a numeric field. Returns `Expression<number>`. */
|
|
759
|
-
ceil<
|
|
760
|
-
/** Floor of a numeric field. Returns `Expression<number>`. */
|
|
761
|
-
floor<
|
|
762
|
-
/** Round
|
|
763
|
-
round
|
|
764
|
-
/** Concatenate field values and
|
|
765
|
-
concat(...parts: Array<
|
|
766
|
-
/** Convert a string field to lowercase. Returns `Expression<string>`. */
|
|
767
|
-
toLower<
|
|
768
|
-
/** Convert a string field to uppercase. Returns `Expression<string>`. */
|
|
769
|
-
toUpper<
|
|
770
|
-
/** Trim whitespace from a string field. Returns `Expression<string>`. */
|
|
771
|
-
trim<
|
|
772
|
-
/** Extract a substring
|
|
773
|
-
substr
|
|
774
|
-
/**
|
|
775
|
-
|
|
776
|
-
/** Test
|
|
777
|
-
|
|
778
|
-
/** Test
|
|
779
|
-
|
|
780
|
-
/** Test
|
|
781
|
-
|
|
782
|
-
/** Test if a field is
|
|
783
|
-
|
|
784
|
-
/** Test if a field is
|
|
785
|
-
|
|
786
|
-
/**
|
|
787
|
-
|
|
788
|
-
/**
|
|
789
|
-
|
|
790
|
-
/**
|
|
791
|
-
|
|
792
|
-
/**
|
|
793
|
-
|
|
794
|
-
/**
|
|
795
|
-
|
|
796
|
-
/**
|
|
797
|
-
|
|
833
|
+
/** Add two numeric values. Returns `Expression<number>`. */
|
|
834
|
+
add(a: FieldOrExpr<T, number>, b: FieldOrExpr<T, number> | number): Expression<number>;
|
|
835
|
+
/** Subtract `b` from `a`. Returns `Expression<number>`. */
|
|
836
|
+
subtract(a: FieldOrExpr<T, number>, b: FieldOrExpr<T, number> | number): Expression<number>;
|
|
837
|
+
/** Multiply two numeric values. Returns `Expression<number>`. */
|
|
838
|
+
multiply(a: FieldOrExpr<T, number>, b: FieldOrExpr<T, number> | number): Expression<number>;
|
|
839
|
+
/** Divide `a` by `b`. Returns `Expression<number>`. */
|
|
840
|
+
divide(a: FieldOrExpr<T, number>, b: FieldOrExpr<T, number> | number): Expression<number>;
|
|
841
|
+
/** Modulo of `a` divided by `b`. Returns `Expression<number>`. */
|
|
842
|
+
mod(a: FieldOrExpr<T, number>, b: FieldOrExpr<T, number> | number): Expression<number>;
|
|
843
|
+
/** Absolute value of a numeric field or expression. Returns `Expression<number>`. */
|
|
844
|
+
abs(field: FieldOrExpr<T, number>): Expression<number>;
|
|
845
|
+
/** Ceiling (round up) of a numeric field or expression. Returns `Expression<number>`. */
|
|
846
|
+
ceil(field: FieldOrExpr<T, number>): Expression<number>;
|
|
847
|
+
/** Floor (round down) of a numeric field or expression. Returns `Expression<number>`. */
|
|
848
|
+
floor(field: FieldOrExpr<T, number>): Expression<number>;
|
|
849
|
+
/** Round to `place` decimal places (default 0). Returns `Expression<number>`. */
|
|
850
|
+
round(field: FieldOrExpr<T, number>, place?: number): Expression<number>;
|
|
851
|
+
/** Concatenate field values, literal strings, and string expressions. Returns `Expression<string>`. */
|
|
852
|
+
concat(...parts: Array<DotPath<T> | string | Expression<string>>): Expression<string>;
|
|
853
|
+
/** Convert a string field or expression to lowercase. Returns `Expression<string>`. */
|
|
854
|
+
toLower(field: FieldOrExpr<T, string>): Expression<string>;
|
|
855
|
+
/** Convert a string field or expression to uppercase. Returns `Expression<string>`. */
|
|
856
|
+
toUpper(field: FieldOrExpr<T, string>): Expression<string>;
|
|
857
|
+
/** Trim whitespace from a string field or expression. Returns `Expression<string>`. */
|
|
858
|
+
trim(field: FieldOrExpr<T, string>): Expression<string>;
|
|
859
|
+
/** Extract a byte-based substring. Returns `Expression<string>`. */
|
|
860
|
+
substr(field: FieldOrExpr<T, string>, start: number, length: number): Expression<string>;
|
|
861
|
+
/** Convert any value (number, date, ObjectId, etc.) to its string representation. Returns `Expression<string>`. */
|
|
862
|
+
toString(field: FieldOrExpr<T, unknown>): Expression<string>;
|
|
863
|
+
/** Test equality of a field against a value (type-safe value). Returns `Expression<boolean>`. */
|
|
864
|
+
eq<F extends DotPath<T>>(field: F, value: DotPathValue<T, F>): Expression<boolean>;
|
|
865
|
+
/** Test equality of a field against a field reference expression (field-vs-field). Returns `Expression<boolean>`. */
|
|
866
|
+
eq(field: DotPath<T>, value: Expression<unknown>): Expression<boolean>;
|
|
867
|
+
/** Test equality with a composed expression as the left-hand side. Returns `Expression<boolean>`. */
|
|
868
|
+
eq(field: Expression<unknown>, value: unknown): Expression<boolean>;
|
|
869
|
+
/** Test if a field is greater than a value (type-safe). Returns `Expression<boolean>`. */
|
|
870
|
+
gt<F extends DotPath<T>>(field: F, value: DotPathValue<T, F>): Expression<boolean>;
|
|
871
|
+
/** Test if a field is greater than a field reference expression (field-vs-field). Returns `Expression<boolean>`. */
|
|
872
|
+
gt(field: DotPath<T>, value: Expression<unknown>): Expression<boolean>;
|
|
873
|
+
/** Test if a composed expression is greater than a value. Returns `Expression<boolean>`. */
|
|
874
|
+
gt(field: Expression<unknown>, value: unknown): Expression<boolean>;
|
|
875
|
+
/** Test if a field is greater than or equal to a value (type-safe). Returns `Expression<boolean>`. */
|
|
876
|
+
gte<F extends DotPath<T>>(field: F, value: DotPathValue<T, F>): Expression<boolean>;
|
|
877
|
+
/** Test if a field is greater than or equal to a field reference expression (field-vs-field). Returns `Expression<boolean>`. */
|
|
878
|
+
gte(field: DotPath<T>, value: Expression<unknown>): Expression<boolean>;
|
|
879
|
+
/** Test if a composed expression is greater than or equal to a value. Returns `Expression<boolean>`. */
|
|
880
|
+
gte(field: Expression<unknown>, value: unknown): Expression<boolean>;
|
|
881
|
+
/** Test if a field is less than a value (type-safe). Returns `Expression<boolean>`. */
|
|
882
|
+
lt<F extends DotPath<T>>(field: F, value: DotPathValue<T, F>): Expression<boolean>;
|
|
883
|
+
/** Test if a field is less than a field reference expression (field-vs-field). Returns `Expression<boolean>`. */
|
|
884
|
+
lt(field: DotPath<T>, value: Expression<unknown>): Expression<boolean>;
|
|
885
|
+
/** Test if a composed expression is less than a value. Returns `Expression<boolean>`. */
|
|
886
|
+
lt(field: Expression<unknown>, value: unknown): Expression<boolean>;
|
|
887
|
+
/** Test if a field is less than or equal to a value (type-safe). Returns `Expression<boolean>`. */
|
|
888
|
+
lte<F extends DotPath<T>>(field: F, value: DotPathValue<T, F>): Expression<boolean>;
|
|
889
|
+
/** Test if a field is less than or equal to a field reference expression (field-vs-field). Returns `Expression<boolean>`. */
|
|
890
|
+
lte(field: DotPath<T>, value: Expression<unknown>): Expression<boolean>;
|
|
891
|
+
/** Test if a composed expression is less than or equal to a value. Returns `Expression<boolean>`. */
|
|
892
|
+
lte(field: Expression<unknown>, value: unknown): Expression<boolean>;
|
|
893
|
+
/** Test if a field is not equal to a value (type-safe). Returns `Expression<boolean>`. */
|
|
894
|
+
ne<F extends DotPath<T>>(field: F, value: DotPathValue<T, F>): Expression<boolean>;
|
|
895
|
+
/** Test if a field is not equal to a field reference expression (field-vs-field). Returns `Expression<boolean>`. */
|
|
896
|
+
ne(field: DotPath<T>, value: Expression<unknown>): Expression<boolean>;
|
|
897
|
+
/** Test if a composed expression is not equal to a value. Returns `Expression<boolean>`. */
|
|
898
|
+
ne(field: Expression<unknown>, value: unknown): Expression<boolean>;
|
|
899
|
+
/** Extract year from a date field or expression. Returns `Expression<number>`. */
|
|
900
|
+
year(field: FieldOrExpr<T, Date>): Expression<number>;
|
|
901
|
+
/** Extract month (1-12) from a date field or expression. Returns `Expression<number>`. */
|
|
902
|
+
month(field: FieldOrExpr<T, Date>): Expression<number>;
|
|
903
|
+
/** Extract day of month (1-31) from a date field or expression. Returns `Expression<number>`. */
|
|
904
|
+
dayOfMonth(field: FieldOrExpr<T, Date>): Expression<number>;
|
|
905
|
+
/** Extract day of week (1=Sunday … 7=Saturday) from a date field or expression. Returns `Expression<number>`. */
|
|
906
|
+
dayOfWeek(field: FieldOrExpr<T, Date>): Expression<number>;
|
|
907
|
+
/**
|
|
908
|
+
* Format a date field or expression as a string.
|
|
909
|
+
*
|
|
910
|
+
* Uses MongoDB format specifiers: `%Y` year, `%m` month (01-12), `%d` day (01-31), etc.
|
|
911
|
+
*
|
|
912
|
+
* @example
|
|
913
|
+
* ```ts
|
|
914
|
+
* expr.dateToString('createdAt', '%Y-%m') // Expression<string>
|
|
915
|
+
* ```
|
|
916
|
+
*/
|
|
917
|
+
dateToString(field: FieldOrExpr<T, Date>, format: string): Expression<string>;
|
|
918
|
+
/** Current timestamp at query start (`$$NOW`). Returns `Expression<Date>`. */
|
|
919
|
+
now(): Expression<Date>;
|
|
920
|
+
/** Count elements in an array field or expression. Returns `Expression<number>`. */
|
|
921
|
+
size(field: FieldOrExpr<T, unknown[]>): Expression<number>;
|
|
922
|
+
/**
|
|
923
|
+
* Check if a value is present in an array.
|
|
924
|
+
*
|
|
925
|
+
* Named `inArray` to distinguish from the filter-level `$in` operator.
|
|
926
|
+
* The second argument may be a field/expression producing an array, or a literal array.
|
|
927
|
+
*
|
|
928
|
+
* @example
|
|
929
|
+
* ```ts
|
|
930
|
+
* expr.inArray(expr.dayOfWeek('createdAt'), [1, 7]) // Expression<boolean>
|
|
931
|
+
* ```
|
|
932
|
+
*/
|
|
933
|
+
inArray(value: FieldOrExpr<T, unknown>, array: FieldOrExpr<T, unknown[]> | ReadonlyArray<unknown>): Expression<boolean>;
|
|
934
|
+
/**
|
|
935
|
+
* Return the element at `index` from an array field (zero-based).
|
|
936
|
+
*
|
|
937
|
+
* When called with a typed field path, the element type is inferred from the schema.
|
|
938
|
+
* When called with a composed expression, the element type is `unknown`.
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```ts
|
|
942
|
+
* // items: Item[] in schema → Expression<Item>
|
|
943
|
+
* expr.arrayElemAt('items', 0)
|
|
944
|
+
* ```
|
|
945
|
+
*/
|
|
946
|
+
arrayElemAt<F extends DotPath<T>>(field: F, index: number): Expression<ArrayElement<DotPathValue<T, F>>>;
|
|
947
|
+
/** Return the element at `index` from an array expression. Returns `Expression<unknown>`. */
|
|
948
|
+
arrayElemAt(field: Expression<unknown[]>, index: number): Expression<unknown>;
|
|
949
|
+
/**
|
|
950
|
+
* Conditional expression: if `condition` is true return `thenValue`, else return `elseValue`.
|
|
951
|
+
*
|
|
952
|
+
* Both `thenValue` and `elseValue` accept literal values or composed `Expression<R>` results.
|
|
953
|
+
* Returns `Expression<TThen | TElse>`.
|
|
954
|
+
*
|
|
955
|
+
* @example
|
|
956
|
+
* ```ts
|
|
957
|
+
* expr.cond(expr.eq('revenue', 0), 0, expr.round(expr.divide('profit', 'revenue'), 4))
|
|
958
|
+
* ```
|
|
959
|
+
*/
|
|
960
|
+
cond<TThen, TElse>(condition: Expression<boolean>, thenValue: TThen | Expression<TThen>, elseValue: TElse | Expression<TElse>): Expression<TThen | TElse>;
|
|
961
|
+
/** Replace null/missing field with a default. Returns `Expression<NonNullable<DotPathValue<T, F>> | TDefault>`. */
|
|
962
|
+
ifNull<F extends DotPath<T>, TDefault>(field: F, fallback: TDefault): Expression<NonNullable<DotPathValue<T, F>> | TDefault>;
|
|
963
|
+
/** Replace null/missing expression result with a default. Returns `Expression<NonNullable<R> | TDefault>`. */
|
|
964
|
+
ifNull<R, TDefault>(field: Expression<R>, fallback: TDefault): Expression<NonNullable<R> | TDefault>;
|
|
965
|
+
/**
|
|
966
|
+
* Multi-branch conditional. Evaluates `branches` in order and returns the first matching `then` value,
|
|
967
|
+
* or `fallback` if no branch matches.
|
|
968
|
+
*
|
|
969
|
+
* TypeScript infers `TThen` as the union of all `then` value types and the fallback type.
|
|
970
|
+
*
|
|
971
|
+
* @example
|
|
972
|
+
* ```ts
|
|
973
|
+
* expr.switch([
|
|
974
|
+
* { case: expr.gte('spend', 10_000), then: 'VIP' },
|
|
975
|
+
* { case: expr.gte('spend', 5_000), then: 'Gold' },
|
|
976
|
+
* ], 'Bronze')
|
|
977
|
+
* // → Expression<'VIP' | 'Gold' | 'Bronze'>
|
|
978
|
+
* ```
|
|
979
|
+
*/
|
|
980
|
+
switch<TThen>(branches: ReadonlyArray<{
|
|
981
|
+
case: Expression<boolean>;
|
|
982
|
+
then: TThen | Expression<TThen>;
|
|
983
|
+
}>, fallback: TThen | Expression<TThen>): Expression<TThen>;
|
|
984
|
+
/**
|
|
985
|
+
* Create a typed field reference for use as a comparison operand.
|
|
986
|
+
*
|
|
987
|
+
* Use when the right-hand side of a comparison should be a document
|
|
988
|
+
* field rather than a literal value (field-vs-field comparison).
|
|
989
|
+
*
|
|
990
|
+
* @example
|
|
991
|
+
* ```ts
|
|
992
|
+
* // Compare two fields in the same document
|
|
993
|
+
* .match({}, (expr) => expr.gt('totalAmount', expr.field('refundedAmount')))
|
|
994
|
+
* ```
|
|
995
|
+
*/
|
|
996
|
+
field<F extends DotPath<T>>(name: F): Expression<DotPathValue<T, F>>;
|
|
798
997
|
};
|
|
799
998
|
|
|
800
999
|
/**
|
|
@@ -1030,19 +1229,20 @@ declare function createAccumulatorBuilder<T>(): AccumulatorBuilder<T>;
|
|
|
1030
1229
|
/**
|
|
1031
1230
|
* Create a typed expression builder for use inside `addFields` callbacks.
|
|
1032
1231
|
*
|
|
1033
|
-
* The builder
|
|
1034
|
-
*
|
|
1035
|
-
* `AggregatePipeline.addFields` — most users
|
|
1036
|
-
* the callback parameter rather than calling
|
|
1232
|
+
* The builder accepts either a field name string (auto-prefixed with `$`) or a
|
|
1233
|
+
* pre-built `Expression<R>` from another builder method, enabling composition.
|
|
1234
|
+
* Primarily used internally by `AggregatePipeline.addFields` — most users
|
|
1235
|
+
* interact with the builder via the callback parameter rather than calling
|
|
1236
|
+
* this directly.
|
|
1037
1237
|
*
|
|
1038
1238
|
* @typeParam T - The current pipeline output document type.
|
|
1039
1239
|
* @returns An `ExpressionBuilder<T>` with methods for each MongoDB expression operator.
|
|
1040
1240
|
*
|
|
1041
1241
|
* @example
|
|
1042
1242
|
* ```ts
|
|
1043
|
-
* const expr = createExpressionBuilder<{ salary: number;
|
|
1044
|
-
* expr.year('hiredAt')
|
|
1045
|
-
* expr.multiply('salary', 0.
|
|
1243
|
+
* const expr = createExpressionBuilder<{ salary: number; hiredAt: Date }>()
|
|
1244
|
+
* expr.year('hiredAt') // { __expr: true, value: { $year: '$hiredAt' } }
|
|
1245
|
+
* expr.round(expr.multiply('salary', 0.1), 2) // { __expr: true, value: { $round: [{ $multiply: ['$salary', 0.1] }, 2] } }
|
|
1046
1246
|
* ```
|
|
1047
1247
|
*/
|
|
1048
1248
|
declare function createExpressionBuilder<T>(): ExpressionBuilder<T>;
|
|
@@ -1088,40 +1288,21 @@ type ComparisonOperators<V> = {
|
|
|
1088
1288
|
} & (V extends string ? {
|
|
1089
1289
|
$regex?: RegExp | string;
|
|
1090
1290
|
} : unknown);
|
|
1091
|
-
/** Depth counter for limiting dot-notation recursion. Index = current depth, value = next depth. */
|
|
1092
|
-
type Prev = [never, 0, 1, 2];
|
|
1093
1291
|
/**
|
|
1094
|
-
*
|
|
1292
|
+
* Dot-separated paths for nested fields, excluding top-level keys.
|
|
1095
1293
|
*
|
|
1096
|
-
*
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1294
|
+
* Filters out `keyof T & string` because top-level fields are already
|
|
1295
|
+
* handled by slot (A) of {@link TypedFilter}. Keeping them separate
|
|
1296
|
+
* preserves the intersection structure for lazy TypeScript evaluation.
|
|
1099
1297
|
*
|
|
1100
1298
|
* @example
|
|
1101
1299
|
* ```ts
|
|
1102
|
-
* type User = {
|
|
1103
|
-
*
|
|
1104
|
-
* //
|
|
1300
|
+
* type User = { name: string; address: { city: string } }
|
|
1301
|
+
* type Paths = DotSubPaths<User>
|
|
1302
|
+
* // ^? 'address.city'
|
|
1105
1303
|
* ```
|
|
1106
1304
|
*/
|
|
1107
|
-
type
|
|
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;
|
|
1109
|
-
}[keyof T & string];
|
|
1110
|
-
/**
|
|
1111
|
-
* Resolves the value type at a dot-separated path `P` within type `T`.
|
|
1112
|
-
*
|
|
1113
|
-
* Splits `P` on the first `.` and recursively descends into `T`'s nested types.
|
|
1114
|
-
* Returns `never` if the path is invalid.
|
|
1115
|
-
*
|
|
1116
|
-
* @example
|
|
1117
|
-
* ```ts
|
|
1118
|
-
* type User = { address: { city: string; geo: { lat: number } } }
|
|
1119
|
-
*
|
|
1120
|
-
* // _DotPathType<User, 'address.city'> = string
|
|
1121
|
-
* // _DotPathType<User, 'address.geo.lat'> = number
|
|
1122
|
-
* ```
|
|
1123
|
-
*/
|
|
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;
|
|
1305
|
+
type DotSubPaths<T> = Exclude<DotPath<T>, keyof T & string>;
|
|
1125
1306
|
/**
|
|
1126
1307
|
* Strict type-safe MongoDB filter query type.
|
|
1127
1308
|
*
|
|
@@ -1132,7 +1313,7 @@ type _DotPathType<T, P extends string> = P extends `${infer K}.${infer Rest}` ?
|
|
|
1132
1313
|
* Supports three forms of filter expressions:
|
|
1133
1314
|
* - **Direct field values** (implicit `$eq`): `{ name: 'Alice' }`
|
|
1134
1315
|
* - **Comparison operators**: `{ age: { $gt: 25 } }` or `{ age: $gt(25) }`
|
|
1135
|
-
* - **Dot notation**
|
|
1316
|
+
* - **Dot notation** including nested and array-traversed fields: `{ 'address.city': 'NYC' }`
|
|
1136
1317
|
*
|
|
1137
1318
|
* Logical operators `$and`, `$or`, and `$nor` accept arrays of `TypedFilter<T>`
|
|
1138
1319
|
* for composing complex queries.
|
|
@@ -1161,7 +1342,7 @@ type _DotPathType<T, P extends string> = P extends `${infer K}.${infer Rest}` ?
|
|
|
1161
1342
|
type TypedFilter<T> = {
|
|
1162
1343
|
[K in keyof T]?: T[K] | ComparisonOperators<T[K]>;
|
|
1163
1344
|
} & {
|
|
1164
|
-
[P in
|
|
1345
|
+
[P in DotSubPaths<T>]?: DotPathValue<T, P> | ComparisonOperators<DotPathValue<T, P>>;
|
|
1165
1346
|
} & {
|
|
1166
1347
|
/** Joins clauses with a logical AND. Matches documents that satisfy all filters. */
|
|
1167
1348
|
$and?: TypedFilter<T>[];
|
|
@@ -1451,6 +1632,400 @@ declare function isInclusionProjection(projection: Record<string, 0 | 1 | boolea
|
|
|
1451
1632
|
*/
|
|
1452
1633
|
declare function deriveProjectedSchema(schema: z.ZodObject<z.core.$ZodShape>, projection: Record<string, 0 | 1 | boolean>): z.ZodObject<z.core.$ZodShape>;
|
|
1453
1634
|
|
|
1635
|
+
/**
|
|
1636
|
+
* Typed return value from {@link PopulateRefBuilder.project}.
|
|
1637
|
+
*
|
|
1638
|
+
* Carries the projection type `P` for compile-time narrowing in populate calls.
|
|
1639
|
+
* Callers never construct this directly — it is returned by the builder and
|
|
1640
|
+
* consumed by the `.populate()` overload to narrow the result type.
|
|
1641
|
+
*
|
|
1642
|
+
* @example
|
|
1643
|
+
* ```ts
|
|
1644
|
+
* // P is inferred as { name: 1; email: 1 } — post.authorId is narrowed accordingly
|
|
1645
|
+
* const post = await posts.findOne({}).populate('authorId', (b) => b.project({ name: 1, email: 1 }))
|
|
1646
|
+
* ```
|
|
1647
|
+
*/
|
|
1648
|
+
type PopulateProjectionConfig<P> = {
|
|
1649
|
+
readonly projection: P;
|
|
1650
|
+
};
|
|
1651
|
+
/**
|
|
1652
|
+
* Fluent builder passed to populate projection callbacks.
|
|
1653
|
+
*
|
|
1654
|
+
* Call `.project()` to specify which fields to fetch from the referenced collection.
|
|
1655
|
+
* The projection type `P` flows back to the `.populate()` overload to narrow the
|
|
1656
|
+
* result type at compile time.
|
|
1657
|
+
*
|
|
1658
|
+
* @typeParam TDoc - The referenced document type (e.g. `InferDocument<typeof Users>`).
|
|
1659
|
+
*
|
|
1660
|
+
* @example
|
|
1661
|
+
* ```ts
|
|
1662
|
+
* posts.findOne({}).populate('authorId', (b) => b.project({ name: 1, email: 1 }))
|
|
1663
|
+
* // post.authorId is narrowed to { _id: ObjectId; name: string; email: string }
|
|
1664
|
+
* ```
|
|
1665
|
+
*/
|
|
1666
|
+
declare class PopulateRefBuilder<TDoc> {
|
|
1667
|
+
/**
|
|
1668
|
+
* Declare a projection to apply when fetching the referenced documents.
|
|
1669
|
+
*
|
|
1670
|
+
* Supported: inclusion (`{ name: 1 }`), exclusion (`{ email: 0 }`), or
|
|
1671
|
+
* `_id` suppression (`{ name: 1, _id: 0 }`).
|
|
1672
|
+
*
|
|
1673
|
+
* @param projection - MongoDB-style inclusion or exclusion projection.
|
|
1674
|
+
* @returns A config object carrying the projection type for compile-time narrowing.
|
|
1675
|
+
*
|
|
1676
|
+
* @example
|
|
1677
|
+
* ```ts
|
|
1678
|
+
* (b) => b.project({ name: 1, email: 1 })
|
|
1679
|
+
* (b) => b.project({ password: 0 })
|
|
1680
|
+
* ```
|
|
1681
|
+
*/
|
|
1682
|
+
project<P extends TypedProjection<TDoc>>(projection: P): PopulateProjectionConfig<P>;
|
|
1683
|
+
}
|
|
1684
|
+
|
|
1685
|
+
/**
|
|
1686
|
+
* Resolve the populated type for a ref field, preserving wrappers.
|
|
1687
|
+
*
|
|
1688
|
+
* Transforms the field type from ID to document based on the Zod wrapper:
|
|
1689
|
+
* - `ObjectId` → `InferDocument<Target>`
|
|
1690
|
+
* - `ObjectId[]` → `InferDocument<Target>[]`
|
|
1691
|
+
* - `ObjectId | undefined` → `InferDocument<Target> | undefined`
|
|
1692
|
+
* - `ObjectId | null` → `InferDocument<Target> | null`
|
|
1693
|
+
*
|
|
1694
|
+
* @example
|
|
1695
|
+
* ```ts
|
|
1696
|
+
* type Author = PopulateField<typeof Posts, 'authorId'>
|
|
1697
|
+
* // ^? { _id: ObjectId; name: string; email: string; companyId: ObjectId }
|
|
1698
|
+
*
|
|
1699
|
+
* type Cats = PopulateField<typeof Posts, 'categoryIds'>
|
|
1700
|
+
* // ^? { _id: ObjectId; title: string }[]
|
|
1701
|
+
* ```
|
|
1702
|
+
*/
|
|
1703
|
+
type PopulateField<TDef extends AnyCollection, K extends RefFields<TDef>> = TDef['shape'][K] extends z.ZodArray<infer _E> ? InferDocument<ExtractRefCollection<TDef, K>>[] : TDef['shape'][K] extends z.ZodOptional<infer _U> ? InferDocument<ExtractRefCollection<TDef, K>> | undefined : TDef['shape'][K] extends z.ZodNullable<infer _U> ? InferDocument<ExtractRefCollection<TDef, K>> | null : InferDocument<ExtractRefCollection<TDef, K>>;
|
|
1704
|
+
/**
|
|
1705
|
+
* Document type with specified ref fields replaced by their populated types.
|
|
1706
|
+
*
|
|
1707
|
+
* @example
|
|
1708
|
+
* ```ts
|
|
1709
|
+
* type PostWithAuthor = Populated<typeof Posts, 'authorId'>
|
|
1710
|
+
* // ^? { _id: ObjectId; title: string; authorId: User; categoryIds: ObjectId[]; ... }
|
|
1711
|
+
*
|
|
1712
|
+
* type PostFull = Populated<typeof Posts, 'authorId' | 'categoryIds'>
|
|
1713
|
+
* // ^? { ...; authorId: User; categoryIds: Category[]; ... }
|
|
1714
|
+
* ```
|
|
1715
|
+
*/
|
|
1716
|
+
type Populated<TDef extends AnyCollection, K extends RefFields<TDef>> = Prettify<Omit<InferDocument<TDef>, K> & {
|
|
1717
|
+
[P in K]: PopulateField<TDef, P>;
|
|
1718
|
+
}>;
|
|
1719
|
+
/**
|
|
1720
|
+
* Apply a single populate step to the output type.
|
|
1721
|
+
*
|
|
1722
|
+
* Without rename: replaces the field type in-place.
|
|
1723
|
+
* With rename: removes the old key and adds the new key with the populated type.
|
|
1724
|
+
*
|
|
1725
|
+
* @example
|
|
1726
|
+
* ```ts
|
|
1727
|
+
* // No rename: authorId stays, type changes to User
|
|
1728
|
+
* type A = ApplyPopulate<PostDoc, typeof Posts, 'authorId'>
|
|
1729
|
+
*
|
|
1730
|
+
* // Rename: authorId removed, author added with User type
|
|
1731
|
+
* type B = ApplyPopulate<PostDoc, typeof Posts, 'authorId', 'author'>
|
|
1732
|
+
* ```
|
|
1733
|
+
*/
|
|
1734
|
+
type ApplyPopulate<T, TDef extends AnyCollection, K extends RefFields<TDef>, TAs extends string = K> = Prettify<Omit<T, K> & {
|
|
1735
|
+
[P in TAs]: PopulateField<TDef, K>;
|
|
1736
|
+
}>;
|
|
1737
|
+
/**
|
|
1738
|
+
* Resolve the projected populated type for a ref field, preserving wrappers.
|
|
1739
|
+
*
|
|
1740
|
+
* Like {@link PopulateField} but applies `ProjectionResult<T, P>` to narrow
|
|
1741
|
+
* the document type to only the projected fields.
|
|
1742
|
+
*
|
|
1743
|
+
* - `ObjectId` → `ProjectionResult<InferDocument<Target>, P>`
|
|
1744
|
+
* - `ObjectId[]` → `ProjectionResult<InferDocument<Target>, P>[]`
|
|
1745
|
+
* - `ObjectId | undefined` → `ProjectionResult<InferDocument<Target>, P> | undefined`
|
|
1746
|
+
* - `ObjectId | null` → `ProjectionResult<InferDocument<Target>, P> | null`
|
|
1747
|
+
*
|
|
1748
|
+
* @example
|
|
1749
|
+
* ```ts
|
|
1750
|
+
* type Author = PopulateFieldProjected<typeof Posts, 'authorId', { name: 1; email: 1 }>
|
|
1751
|
+
* // ^? { _id: ObjectId; name: string; email: string }
|
|
1752
|
+
* ```
|
|
1753
|
+
*/
|
|
1754
|
+
type PopulateFieldProjected<TDef extends AnyCollection, K extends RefFields<TDef>, P> = TDef['shape'][K] extends z.ZodArray<infer _E> ? ProjectionResult<InferDocument<ExtractRefCollection<TDef, K>>, P>[] : TDef['shape'][K] extends z.ZodOptional<infer _U> ? ProjectionResult<InferDocument<ExtractRefCollection<TDef, K>>, P> | undefined : TDef['shape'][K] extends z.ZodNullable<infer _U> ? ProjectionResult<InferDocument<ExtractRefCollection<TDef, K>>, P> | null : ProjectionResult<InferDocument<ExtractRefCollection<TDef, K>>, P>;
|
|
1755
|
+
/**
|
|
1756
|
+
* Apply a projected populate step to the output type.
|
|
1757
|
+
*
|
|
1758
|
+
* Like {@link ApplyPopulate} but uses {@link PopulateFieldProjected} to narrow
|
|
1759
|
+
* the result to only the projected fields. Use `TAs` to rename the output field.
|
|
1760
|
+
*
|
|
1761
|
+
* @example
|
|
1762
|
+
* ```ts
|
|
1763
|
+
* type Result = ApplyPopulateProjected<PostDoc, typeof Posts, 'authorId', { name: 1; email: 1 }>
|
|
1764
|
+
* // ^? { ...; authorId: { _id: ObjectId; name: string; email: string } }
|
|
1765
|
+
* ```
|
|
1766
|
+
*/
|
|
1767
|
+
type ApplyPopulateProjected<T, TDef extends AnyCollection, K extends RefFields<TDef>, P, TAs extends string = K> = Prettify<Omit<T, K> & {
|
|
1768
|
+
[F in TAs]: PopulateFieldProjected<TDef, K, P>;
|
|
1769
|
+
}>;
|
|
1770
|
+
/**
|
|
1771
|
+
* Apply a populate at an arbitrary nesting depth.
|
|
1772
|
+
*
|
|
1773
|
+
* Splits the dot-path and recursively navigates into the output type.
|
|
1774
|
+
* If a parent field is an array, the element type is transformed.
|
|
1775
|
+
*
|
|
1776
|
+
* @example
|
|
1777
|
+
* ```ts
|
|
1778
|
+
* // Nested: author.companyId → author.company
|
|
1779
|
+
* type Result = DeepPopulate<PostWithAuthor, 'author.companyId', 'companyId', 'company', Company>
|
|
1780
|
+
* ```
|
|
1781
|
+
*/
|
|
1782
|
+
type DeepPopulate<T, Path extends string, LeafField extends string, TAs extends string, PopType> = Path extends `${infer Parent}.${infer Rest}` ? Parent extends keyof T ? T[Parent] extends (infer E)[] ? Prettify<Omit<T, Parent> & {
|
|
1783
|
+
[P in Parent]: DeepPopulate<E, Rest, LeafField, TAs, PopType>[];
|
|
1784
|
+
}> : Prettify<Omit<T, Parent> & {
|
|
1785
|
+
[P in Parent]: DeepPopulate<T[Parent], Rest, LeafField, TAs, PopType>;
|
|
1786
|
+
}> : never : Prettify<Omit<T, LeafField> & {
|
|
1787
|
+
[P in TAs]: PopType;
|
|
1788
|
+
}>;
|
|
1789
|
+
/**
|
|
1790
|
+
* Valid nested populate paths given the current TPopMap.
|
|
1791
|
+
*
|
|
1792
|
+
* Produces a union of `parentPath.refField` strings where `parentPath`
|
|
1793
|
+
* is a key in TPopMap and `refField` is a ref-bearing field in that
|
|
1794
|
+
* parent's collection definition.
|
|
1795
|
+
*
|
|
1796
|
+
* @example
|
|
1797
|
+
* ```ts
|
|
1798
|
+
* // If TPopMap = { author: typeof Users }, produces:
|
|
1799
|
+
* // 'author.companyId' | 'author.<other ref fields>'
|
|
1800
|
+
* type Paths = NestedRefPath<{ author: typeof Users }>
|
|
1801
|
+
* ```
|
|
1802
|
+
*/
|
|
1803
|
+
type NestedRefPath<TPopMap extends Record<string, AnyCollection>> = {
|
|
1804
|
+
[Path in keyof TPopMap & string]: `${Path}.${RefFields<TPopMap[Path]>}`;
|
|
1805
|
+
}[keyof TPopMap & string];
|
|
1806
|
+
/**
|
|
1807
|
+
* Runtime data for a single populate step.
|
|
1808
|
+
*
|
|
1809
|
+
* Built by each `.populate()` call and consumed by `executePopulate()`.
|
|
1810
|
+
*/
|
|
1811
|
+
type PopulateStep = {
|
|
1812
|
+
/** The original field path from the root collection. */
|
|
1813
|
+
readonly originalPath: string;
|
|
1814
|
+
/** The leaf field name in the target shape. */
|
|
1815
|
+
readonly leafField: string;
|
|
1816
|
+
/** The output field name (renamed or original). */
|
|
1817
|
+
readonly as: string;
|
|
1818
|
+
/** Parent path in the output document for nesting, or undefined for top-level. */
|
|
1819
|
+
readonly parentOutputPath: string | undefined;
|
|
1820
|
+
/** The target collection definition resolved from RefMarker metadata. */
|
|
1821
|
+
readonly targetCollection: AnyCollection;
|
|
1822
|
+
/** Whether the field is an array ref. */
|
|
1823
|
+
readonly isArray: boolean;
|
|
1824
|
+
/** MongoDB projection spec to pass to the `$in` query. Omit to fetch the full document. */
|
|
1825
|
+
readonly projection?: Record<string, 0 | 1 | boolean>;
|
|
1826
|
+
};
|
|
1827
|
+
|
|
1828
|
+
/**
|
|
1829
|
+
* Extract the parent segment from a dot-separated path.
|
|
1830
|
+
*
|
|
1831
|
+
* @example
|
|
1832
|
+
* ```ts
|
|
1833
|
+
* type P = ExtractParent<'author.companyId'> // 'author'
|
|
1834
|
+
* ```
|
|
1835
|
+
*/
|
|
1836
|
+
type ExtractParent$1<T extends string> = T extends `${infer P}.${string}` ? P : never;
|
|
1837
|
+
/**
|
|
1838
|
+
* Extract the leaf segment from a dot-separated path.
|
|
1839
|
+
*
|
|
1840
|
+
* @example
|
|
1841
|
+
* ```ts
|
|
1842
|
+
* type L = ExtractLeaf<'author.companyId'> // 'companyId'
|
|
1843
|
+
* ```
|
|
1844
|
+
*/
|
|
1845
|
+
type ExtractLeaf$1<T extends string> = T extends `${string}.${infer L}` ? L : never;
|
|
1846
|
+
/**
|
|
1847
|
+
* Cursor with chained populate steps, wrapping a {@link TypedFindCursor}.
|
|
1848
|
+
*
|
|
1849
|
+
* Created by calling `.populate()` on a `TypedFindCursor`. Exposes only
|
|
1850
|
+
* `.populate()` (for additional fields) and terminal methods (`toArray`,
|
|
1851
|
+
* async iteration). Cursor modifiers (`sort`, `skip`, `limit`) are not
|
|
1852
|
+
* available -- they must be called before `.populate()`.
|
|
1853
|
+
*
|
|
1854
|
+
* @typeParam TDef - The root collection definition type.
|
|
1855
|
+
* @typeParam TOutput - The current output document type after populate transforms.
|
|
1856
|
+
* @typeParam TPopMap - Map of populated alias names to their collection definitions,
|
|
1857
|
+
* used to resolve nested populate paths.
|
|
1858
|
+
*
|
|
1859
|
+
* @example
|
|
1860
|
+
* ```ts
|
|
1861
|
+
* const posts = await db.use(Posts)
|
|
1862
|
+
* .find({ published: true })
|
|
1863
|
+
* .sort({ createdAt: -1 })
|
|
1864
|
+
* .limit(10)
|
|
1865
|
+
* .populate('authorId', 'author')
|
|
1866
|
+
* .populate('categoryIds')
|
|
1867
|
+
* .toArray()
|
|
1868
|
+
* ```
|
|
1869
|
+
*/
|
|
1870
|
+
declare class PopulateCursor<TDef extends AnyCollection, TOutput, TPopMap extends Record<string, AnyCollection> = Record<string, never>> {
|
|
1871
|
+
private readonly cursor;
|
|
1872
|
+
private readonly definition;
|
|
1873
|
+
private readonly steps;
|
|
1874
|
+
private readonly nativeCollection;
|
|
1875
|
+
/** @internal */
|
|
1876
|
+
constructor(cursor: TypedFindCursor<TDef>, definition: TDef, steps: readonly PopulateStep[], nativeCollection: Collection<InferDocument<TDef>>);
|
|
1877
|
+
/**
|
|
1878
|
+
* Populate a top-level ref field, keeping the original field name.
|
|
1879
|
+
*
|
|
1880
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
1881
|
+
* @returns A new cursor with the field type replaced by the referenced document.
|
|
1882
|
+
*
|
|
1883
|
+
* @example
|
|
1884
|
+
* ```ts
|
|
1885
|
+
* const posts = await db.use(Posts)
|
|
1886
|
+
* .find({})
|
|
1887
|
+
* .populate('authorId')
|
|
1888
|
+
* .toArray()
|
|
1889
|
+
* // posts[0].authorId is now a User document instead of ObjectId
|
|
1890
|
+
* ```
|
|
1891
|
+
*/
|
|
1892
|
+
populate<K extends RefFields<TDef>>(field: K): PopulateCursor<TDef, ApplyPopulate<TOutput, TDef, K>, TPopMap & {
|
|
1893
|
+
[P in K]: ExtractRefCollection<TDef, K>;
|
|
1894
|
+
}>;
|
|
1895
|
+
/**
|
|
1896
|
+
* Populate a top-level ref field with a projection, keeping the original field name.
|
|
1897
|
+
*
|
|
1898
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
1899
|
+
* @param configure - Callback receiving a builder; call `.project()` to set the projection.
|
|
1900
|
+
* @returns A new cursor with the field type narrowed to only the projected fields.
|
|
1901
|
+
*
|
|
1902
|
+
* @example
|
|
1903
|
+
* ```ts
|
|
1904
|
+
* const posts = await db.use(Posts)
|
|
1905
|
+
* .find({})
|
|
1906
|
+
* .populate('authorId', (b) => b.project({ name: 1, email: 1 }))
|
|
1907
|
+
* .toArray()
|
|
1908
|
+
* // posts[0].authorId is { _id: ObjectId; name: string; email: string }
|
|
1909
|
+
* ```
|
|
1910
|
+
*/
|
|
1911
|
+
populate<K extends RefFields<TDef>, P>(field: K, configure: (b: PopulateRefBuilder<InferDocument<ExtractRefCollection<TDef, K>>>) => PopulateProjectionConfig<P>): PopulateCursor<TDef, ApplyPopulateProjected<TOutput, TDef, K, P>, TPopMap & {
|
|
1912
|
+
[F in K]: ExtractRefCollection<TDef, K>;
|
|
1913
|
+
}>;
|
|
1914
|
+
/**
|
|
1915
|
+
* Populate a top-level ref field and rename it in the output.
|
|
1916
|
+
*
|
|
1917
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
1918
|
+
* @param as - The new field name in the output document.
|
|
1919
|
+
* @returns A new cursor with the old field removed and the new field added.
|
|
1920
|
+
*
|
|
1921
|
+
* @example
|
|
1922
|
+
* ```ts
|
|
1923
|
+
* const posts = await db.use(Posts)
|
|
1924
|
+
* .find({})
|
|
1925
|
+
* .populate('authorId', 'author')
|
|
1926
|
+
* .toArray()
|
|
1927
|
+
* // posts[0].author is a User document; posts[0].authorId no longer exists
|
|
1928
|
+
* ```
|
|
1929
|
+
*/
|
|
1930
|
+
populate<K extends RefFields<TDef>, TAs extends string>(field: K, as: TAs): PopulateCursor<TDef, ApplyPopulate<TOutput, TDef, K, TAs>, TPopMap & {
|
|
1931
|
+
[P in TAs]: ExtractRefCollection<TDef, K>;
|
|
1932
|
+
}>;
|
|
1933
|
+
/**
|
|
1934
|
+
* Populate a nested ref field, keeping the leaf field name.
|
|
1935
|
+
*
|
|
1936
|
+
* The parent path must have been populated in a previous `.populate()` call.
|
|
1937
|
+
*
|
|
1938
|
+
* @param path - A dot-separated path like `'author.companyId'`.
|
|
1939
|
+
* @returns A new cursor with the nested field type replaced.
|
|
1940
|
+
*
|
|
1941
|
+
* @example
|
|
1942
|
+
* ```ts
|
|
1943
|
+
* const posts = await db.use(Posts)
|
|
1944
|
+
* .find({})
|
|
1945
|
+
* .populate('authorId', 'author')
|
|
1946
|
+
* .populate('author.companyId')
|
|
1947
|
+
* .toArray()
|
|
1948
|
+
* // posts[0].author.companyId is now a Company document
|
|
1949
|
+
* ```
|
|
1950
|
+
*/
|
|
1951
|
+
populate<TPath extends NestedRefPath<TPopMap>>(path: TPath): PopulateCursor<TDef, DeepPopulate<TOutput, `${ExtractParent$1<TPath>}.${ExtractLeaf$1<TPath>}`, ExtractLeaf$1<TPath>, ExtractLeaf$1<TPath>, PopulateField<TPopMap[ExtractParent$1<TPath>], ExtractLeaf$1<TPath> & RefFields<TPopMap[ExtractParent$1<TPath>]>>>, TPopMap & {
|
|
1952
|
+
[P in `${ExtractParent$1<TPath>}.${ExtractLeaf$1<TPath>}`]: ExtractRefCollection<TPopMap[ExtractParent$1<TPath>], ExtractLeaf$1<TPath> & RefFields<TPopMap[ExtractParent$1<TPath>]>>;
|
|
1953
|
+
}>;
|
|
1954
|
+
/**
|
|
1955
|
+
* Populate a nested ref field and rename the leaf in the output.
|
|
1956
|
+
*
|
|
1957
|
+
* The parent path must have been populated in a previous `.populate()` call.
|
|
1958
|
+
*
|
|
1959
|
+
* @param path - A dot-separated path like `'author.companyId'`.
|
|
1960
|
+
* @param as - The new name for the leaf field in the output.
|
|
1961
|
+
* @returns A new cursor with the nested field renamed and typed.
|
|
1962
|
+
*
|
|
1963
|
+
* @example
|
|
1964
|
+
* ```ts
|
|
1965
|
+
* const posts = await db.use(Posts)
|
|
1966
|
+
* .find({})
|
|
1967
|
+
* .populate('authorId', 'author')
|
|
1968
|
+
* .populate('author.companyId', 'company')
|
|
1969
|
+
* .toArray()
|
|
1970
|
+
* // posts[0].author.company is a Company document
|
|
1971
|
+
* ```
|
|
1972
|
+
*/
|
|
1973
|
+
populate<TPath extends NestedRefPath<TPopMap>, TAs extends string>(path: TPath, as: TAs): PopulateCursor<TDef, DeepPopulate<TOutput, `${ExtractParent$1<TPath>}.${TAs}`, ExtractLeaf$1<TPath>, TAs, PopulateField<TPopMap[ExtractParent$1<TPath>], ExtractLeaf$1<TPath> & RefFields<TPopMap[ExtractParent$1<TPath>]>>>, TPopMap & {
|
|
1974
|
+
[P in `${ExtractParent$1<TPath>}.${TAs}`]: ExtractRefCollection<TPopMap[ExtractParent$1<TPath>], ExtractLeaf$1<TPath> & RefFields<TPopMap[ExtractParent$1<TPath>]>>;
|
|
1975
|
+
}>;
|
|
1976
|
+
/**
|
|
1977
|
+
* Execute the query and return all matching documents as a populated array.
|
|
1978
|
+
*
|
|
1979
|
+
* Fetches all documents from the underlying cursor, then applies populate
|
|
1980
|
+
* steps in order using batch `$in` queries (no N+1 problem).
|
|
1981
|
+
*
|
|
1982
|
+
* @returns Array of populated documents.
|
|
1983
|
+
*
|
|
1984
|
+
* @example
|
|
1985
|
+
* ```ts
|
|
1986
|
+
* const posts = await db.use(Posts)
|
|
1987
|
+
* .find({})
|
|
1988
|
+
* .populate('authorId', 'author')
|
|
1989
|
+
* .toArray()
|
|
1990
|
+
* ```
|
|
1991
|
+
*/
|
|
1992
|
+
toArray(): Promise<TOutput[]>;
|
|
1993
|
+
/**
|
|
1994
|
+
* Async iterator for streaming populated documents.
|
|
1995
|
+
*
|
|
1996
|
+
* Fetches all documents first (populate requires the full batch for
|
|
1997
|
+
* efficient `$in` queries), then yields results one at a time.
|
|
1998
|
+
*
|
|
1999
|
+
* @yields Populated documents one at a time.
|
|
2000
|
+
*
|
|
2001
|
+
* @example
|
|
2002
|
+
* ```ts
|
|
2003
|
+
* for await (const post of db.use(Posts).find({}).populate('authorId', 'author')) {
|
|
2004
|
+
* console.log(post.author.name)
|
|
2005
|
+
* }
|
|
2006
|
+
* ```
|
|
2007
|
+
*/
|
|
2008
|
+
[Symbol.asyncIterator](): AsyncGenerator<TOutput>;
|
|
2009
|
+
}
|
|
2010
|
+
/**
|
|
2011
|
+
* Create a new {@link PopulateCursor} from a {@link TypedFindCursor}.
|
|
2012
|
+
*
|
|
2013
|
+
* This factory function exists to break the circular import between
|
|
2014
|
+
* `query/cursor.ts` and `populate/cursor.ts`. The `TypedFindCursor.populate()`
|
|
2015
|
+
* method uses a lazy `require()` to call this function at runtime.
|
|
2016
|
+
*
|
|
2017
|
+
* @param cursor - The typed find cursor to wrap.
|
|
2018
|
+
* @param definition - The collection definition.
|
|
2019
|
+
* @param steps - Initial populate steps (typically empty).
|
|
2020
|
+
* @returns A new PopulateCursor instance.
|
|
2021
|
+
*
|
|
2022
|
+
* @example
|
|
2023
|
+
* ```ts
|
|
2024
|
+
* const popCursor = createPopulateCursor(typedCursor, Posts, [])
|
|
2025
|
+
* ```
|
|
2026
|
+
*/
|
|
2027
|
+
declare function createPopulateCursor<TDef extends AnyCollection>(cursor: TypedFindCursor<TDef>, definition: TDef, steps: readonly PopulateStep[]): PopulateCursor<TDef, InferDocument<TDef>>;
|
|
2028
|
+
|
|
1454
2029
|
/**
|
|
1455
2030
|
* Type-safe sort specification for a document type.
|
|
1456
2031
|
*
|
|
@@ -1489,21 +2064,25 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1489
2064
|
/** @internal */
|
|
1490
2065
|
private cursor;
|
|
1491
2066
|
/** @internal */
|
|
2067
|
+
readonly definition: TDef;
|
|
2068
|
+
/** @internal */
|
|
1492
2069
|
private schema;
|
|
1493
2070
|
/** @internal */
|
|
1494
2071
|
private collectionName;
|
|
1495
2072
|
/** @internal */
|
|
1496
2073
|
private mode;
|
|
1497
2074
|
/** @internal */
|
|
1498
|
-
|
|
2075
|
+
readonly nativeCollection: Collection<InferDocument<TDef>>;
|
|
1499
2076
|
/** @internal */
|
|
1500
2077
|
private readonly filter;
|
|
1501
2078
|
/** @internal */
|
|
2079
|
+
private readonly session;
|
|
2080
|
+
/** @internal */
|
|
1502
2081
|
private sortSpec;
|
|
1503
2082
|
/** @internal */
|
|
1504
2083
|
private projectedSchema;
|
|
1505
2084
|
/** @internal */
|
|
1506
|
-
constructor(cursor: FindCursor<InferDocument<TDef>>, definition: TDef, mode: ValidationMode | false, nativeCollection: Collection<InferDocument<TDef>>, filter: any);
|
|
2085
|
+
constructor(cursor: FindCursor<InferDocument<TDef>>, definition: TDef, mode: ValidationMode | false, nativeCollection: Collection<InferDocument<TDef>>, filter: any, session?: ClientSession);
|
|
1507
2086
|
/**
|
|
1508
2087
|
* Set the sort order for the query.
|
|
1509
2088
|
*
|
|
@@ -1590,6 +2169,73 @@ declare class TypedFindCursor<TDef extends AnyCollection, TIndexNames extends st
|
|
|
1590
2169
|
* ```
|
|
1591
2170
|
*/
|
|
1592
2171
|
project<P extends TypedProjection<InferDocument<TDef>>>(spec: P): TypedFindCursor<TDef, TIndexNames, Prettify<ProjectionResult<InferDocument<TDef>, P>>>;
|
|
2172
|
+
/**
|
|
2173
|
+
* Populate a top-level ref field, keeping the original field name.
|
|
2174
|
+
*
|
|
2175
|
+
* Transitions to a {@link PopulateCursor} that only exposes `.populate()`
|
|
2176
|
+
* and terminal methods. Cursor modifiers (`sort`, `skip`, `limit`) must
|
|
2177
|
+
* be called before `.populate()`.
|
|
2178
|
+
*
|
|
2179
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
2180
|
+
* @returns A populate cursor with the field type replaced by the referenced document.
|
|
2181
|
+
*
|
|
2182
|
+
* @example
|
|
2183
|
+
* ```ts
|
|
2184
|
+
* const posts = await db.use(Posts)
|
|
2185
|
+
* .find({})
|
|
2186
|
+
* .populate('authorId')
|
|
2187
|
+
* .toArray()
|
|
2188
|
+
* ```
|
|
2189
|
+
*/
|
|
2190
|
+
populate<K extends RefFields<TDef>>(field: K): PopulateCursor<TDef, ApplyPopulate<TOutput, TDef, K>, {
|
|
2191
|
+
[P in K]: ExtractRefCollection<TDef, K>;
|
|
2192
|
+
}>;
|
|
2193
|
+
/**
|
|
2194
|
+
* Populate a top-level ref field with a projection, keeping the original field name.
|
|
2195
|
+
*
|
|
2196
|
+
* Transitions to a {@link PopulateCursor}. Cursor modifiers (`sort`, `skip`, `limit`)
|
|
2197
|
+
* must be called before `.populate()`.
|
|
2198
|
+
*
|
|
2199
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
2200
|
+
* @param configure - Callback receiving a builder; call `.project()` to set the projection.
|
|
2201
|
+
* @returns A populate cursor with the field type narrowed to only the projected fields.
|
|
2202
|
+
*
|
|
2203
|
+
* @example
|
|
2204
|
+
* ```ts
|
|
2205
|
+
* const posts = await db.use(Posts)
|
|
2206
|
+
* .find({})
|
|
2207
|
+
* .populate('authorId', (b) => b.project({ name: 1, email: 1 }))
|
|
2208
|
+
* .toArray()
|
|
2209
|
+
* // posts[0].authorId is { _id: ObjectId; name: string; email: string }
|
|
2210
|
+
* ```
|
|
2211
|
+
*/
|
|
2212
|
+
populate<K extends RefFields<TDef>, P>(field: K, configure: (b: PopulateRefBuilder<InferDocument<ExtractRefCollection<TDef, K>>>) => PopulateProjectionConfig<P>): PopulateCursor<TDef, ApplyPopulateProjected<TOutput, TDef, K, P>, {
|
|
2213
|
+
[F in K]: ExtractRefCollection<TDef, K>;
|
|
2214
|
+
}>;
|
|
2215
|
+
/**
|
|
2216
|
+
* Populate a top-level ref field and rename it in the output.
|
|
2217
|
+
*
|
|
2218
|
+
* Transitions to a {@link PopulateCursor} that only exposes `.populate()`
|
|
2219
|
+
* and terminal methods. Cursor modifiers (`sort`, `skip`, `limit`) must
|
|
2220
|
+
* be called before `.populate()`.
|
|
2221
|
+
*
|
|
2222
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
2223
|
+
* @param as - The new field name in the output document.
|
|
2224
|
+
* @returns A populate cursor with the old field removed and the new field added.
|
|
2225
|
+
*
|
|
2226
|
+
* @example
|
|
2227
|
+
* ```ts
|
|
2228
|
+
* const posts = await db.use(Posts)
|
|
2229
|
+
* .find({})
|
|
2230
|
+
* .sort({ createdAt: -1 })
|
|
2231
|
+
* .limit(10)
|
|
2232
|
+
* .populate('authorId', 'author')
|
|
2233
|
+
* .toArray()
|
|
2234
|
+
* ```
|
|
2235
|
+
*/
|
|
2236
|
+
populate<K extends RefFields<TDef>, TAs extends string>(field: K, as: TAs): PopulateCursor<TDef, ApplyPopulate<TOutput, TDef, K, TAs>, {
|
|
2237
|
+
[P in TAs]: ExtractRefCollection<TDef, K>;
|
|
2238
|
+
}>;
|
|
1593
2239
|
/**
|
|
1594
2240
|
* Execute the query with offset-based pagination, returning a page of documents
|
|
1595
2241
|
* with total count and navigation metadata.
|
|
@@ -1858,16 +2504,6 @@ declare function find<TDef extends AnyCollection>(handle: CollectionHandle<TDef>
|
|
|
1858
2504
|
*/
|
|
1859
2505
|
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>>>;
|
|
1860
2506
|
|
|
1861
|
-
/**
|
|
1862
|
-
* Extracts the element type from an array type.
|
|
1863
|
-
*
|
|
1864
|
-
* @example
|
|
1865
|
-
* ```ts
|
|
1866
|
-
* type E = ArrayElement<string[]> // string
|
|
1867
|
-
* type N = ArrayElement<number[]> // number
|
|
1868
|
-
* ```
|
|
1869
|
-
*/
|
|
1870
|
-
type ArrayElement<T> = T extends ReadonlyArray<infer E> ? E : never;
|
|
1871
2507
|
/**
|
|
1872
2508
|
* Fields valid for `$set`, `$setOnInsert`, `$min`, and `$max` operators.
|
|
1873
2509
|
*
|
|
@@ -1882,7 +2518,7 @@ type ArrayElement<T> = T extends ReadonlyArray<infer E> ? E : never;
|
|
|
1882
2518
|
type SetFields<T> = {
|
|
1883
2519
|
[K in keyof T]?: T[K];
|
|
1884
2520
|
} & {
|
|
1885
|
-
[P in
|
|
2521
|
+
[P in DotSubPaths<T>]?: DotPathValue<T, P>;
|
|
1886
2522
|
};
|
|
1887
2523
|
/**
|
|
1888
2524
|
* Fields valid for the `$inc` operator — only number-typed fields.
|
|
@@ -1897,7 +2533,7 @@ type SetFields<T> = {
|
|
|
1897
2533
|
type IncFields<T> = {
|
|
1898
2534
|
[K in keyof T as NonNullable<T[K]> extends number ? K : never]?: number;
|
|
1899
2535
|
} & {
|
|
1900
|
-
[P in
|
|
2536
|
+
[P in DotSubPaths<T> as DotPathValue<T, P> extends number ? P : never]?: number;
|
|
1901
2537
|
};
|
|
1902
2538
|
/**
|
|
1903
2539
|
* Modifiers for the `$push` operator.
|
|
@@ -2242,6 +2878,257 @@ type SyncIndexesResult = {
|
|
|
2242
2878
|
stale: StaleIndex[];
|
|
2243
2879
|
};
|
|
2244
2880
|
|
|
2881
|
+
/**
|
|
2882
|
+
* Extract the parent segment from a dot-separated path.
|
|
2883
|
+
*
|
|
2884
|
+
* @example
|
|
2885
|
+
* ```ts
|
|
2886
|
+
* type P = ExtractParent<'author.companyId'> // 'author'
|
|
2887
|
+
* ```
|
|
2888
|
+
*/
|
|
2889
|
+
type ExtractParent<T extends string> = T extends `${infer P}.${string}` ? P : never;
|
|
2890
|
+
/**
|
|
2891
|
+
* Extract the leaf segment from a dot-separated path.
|
|
2892
|
+
*
|
|
2893
|
+
* @example
|
|
2894
|
+
* ```ts
|
|
2895
|
+
* type L = ExtractLeaf<'author.companyId'> // 'companyId'
|
|
2896
|
+
* ```
|
|
2897
|
+
*/
|
|
2898
|
+
type ExtractLeaf<T extends string> = T extends `${string}.${infer L}` ? L : never;
|
|
2899
|
+
/**
|
|
2900
|
+
* Fluent populate builder for findOne queries.
|
|
2901
|
+
*
|
|
2902
|
+
* Implements `PromiseLike` so it can be awaited directly without `.populate()`.
|
|
2903
|
+
* Each `.populate()` call returns a new builder with updated generics.
|
|
2904
|
+
*
|
|
2905
|
+
* @example
|
|
2906
|
+
* ```ts
|
|
2907
|
+
* // Without populate (backward compatible)
|
|
2908
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
2909
|
+
*
|
|
2910
|
+
* // With populate
|
|
2911
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
2912
|
+
* .populate('authorId', 'author')
|
|
2913
|
+
* .populate('author.companyId', 'company')
|
|
2914
|
+
* ```
|
|
2915
|
+
*/
|
|
2916
|
+
declare class PopulateOneQuery<TDef extends AnyCollection, TOutput, TPopMap extends Record<string, AnyCollection> = Record<string, never>> implements PromiseLike<TOutput | null> {
|
|
2917
|
+
private readonly handle;
|
|
2918
|
+
private readonly filter;
|
|
2919
|
+
private readonly options;
|
|
2920
|
+
private readonly steps;
|
|
2921
|
+
constructor(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options: FindOneOptions | undefined, steps?: readonly PopulateStep[]);
|
|
2922
|
+
/**
|
|
2923
|
+
* Populate a top-level ref field, keeping the original field name.
|
|
2924
|
+
*
|
|
2925
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
2926
|
+
* @returns A new builder with the field type replaced by the referenced document.
|
|
2927
|
+
*
|
|
2928
|
+
* @example
|
|
2929
|
+
* ```ts
|
|
2930
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
2931
|
+
* .populate('authorId')
|
|
2932
|
+
* // post.authorId is now a User document instead of ObjectId
|
|
2933
|
+
* ```
|
|
2934
|
+
*/
|
|
2935
|
+
populate<K extends RefFields<TDef>>(field: K): PopulateOneQuery<TDef, ApplyPopulate<TOutput, TDef, K>, TPopMap & {
|
|
2936
|
+
[P in K]: ExtractRefCollection<TDef, K>;
|
|
2937
|
+
}>;
|
|
2938
|
+
/**
|
|
2939
|
+
* Populate a top-level ref field with a projection, keeping the original field name.
|
|
2940
|
+
*
|
|
2941
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
2942
|
+
* @param configure - Callback receiving a builder; call `.project()` to set the projection.
|
|
2943
|
+
* @returns A new builder with the field type narrowed to only the projected fields.
|
|
2944
|
+
*
|
|
2945
|
+
* @example
|
|
2946
|
+
* ```ts
|
|
2947
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
2948
|
+
* .populate('authorId', (b) => b.project({ name: 1, email: 1 }))
|
|
2949
|
+
* // post.authorId is { _id: ObjectId; name: string; email: string }
|
|
2950
|
+
* // post.authorId.age → TS error
|
|
2951
|
+
* ```
|
|
2952
|
+
*/
|
|
2953
|
+
populate<K extends RefFields<TDef>, P>(field: K, configure: (b: PopulateRefBuilder<InferDocument<ExtractRefCollection<TDef, K>>>) => PopulateProjectionConfig<P>): PopulateOneQuery<TDef, ApplyPopulateProjected<TOutput, TDef, K, P>, TPopMap & {
|
|
2954
|
+
[F in K]: ExtractRefCollection<TDef, K>;
|
|
2955
|
+
}>;
|
|
2956
|
+
/**
|
|
2957
|
+
* Populate a top-level ref field and rename it in the output.
|
|
2958
|
+
*
|
|
2959
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
2960
|
+
* @param as - The new field name in the output document.
|
|
2961
|
+
* @returns A new builder with the old field removed and the new field added.
|
|
2962
|
+
*
|
|
2963
|
+
* @example
|
|
2964
|
+
* ```ts
|
|
2965
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
2966
|
+
* .populate('authorId', 'author')
|
|
2967
|
+
* // post.author is a User document; post.authorId no longer exists
|
|
2968
|
+
* ```
|
|
2969
|
+
*/
|
|
2970
|
+
populate<K extends RefFields<TDef>, TAs extends string>(field: K, as: TAs): PopulateOneQuery<TDef, ApplyPopulate<TOutput, TDef, K, TAs>, TPopMap & {
|
|
2971
|
+
[P in TAs]: ExtractRefCollection<TDef, K>;
|
|
2972
|
+
}>;
|
|
2973
|
+
/**
|
|
2974
|
+
* Populate a nested ref field, keeping the leaf field name.
|
|
2975
|
+
*
|
|
2976
|
+
* The parent path must have been populated in a previous `.populate()` call.
|
|
2977
|
+
*
|
|
2978
|
+
* @param path - A dot-separated path like `'author.companyId'`.
|
|
2979
|
+
* @returns A new builder with the nested field type replaced.
|
|
2980
|
+
*
|
|
2981
|
+
* @example
|
|
2982
|
+
* ```ts
|
|
2983
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
2984
|
+
* .populate('authorId', 'author')
|
|
2985
|
+
* .populate('author.companyId')
|
|
2986
|
+
* // post.author.companyId is now a Company document
|
|
2987
|
+
* ```
|
|
2988
|
+
*/
|
|
2989
|
+
populate<TPath extends NestedRefPath<TPopMap>>(path: TPath): PopulateOneQuery<TDef, DeepPopulate<TOutput, `${ExtractParent<TPath>}.${ExtractLeaf<TPath>}`, ExtractLeaf<TPath>, ExtractLeaf<TPath>, PopulateField<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>>, TPopMap & {
|
|
2990
|
+
[P in `${ExtractParent<TPath>}.${ExtractLeaf<TPath>}`]: ExtractRefCollection<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>;
|
|
2991
|
+
}>;
|
|
2992
|
+
/**
|
|
2993
|
+
* Populate a nested ref field and rename the leaf in the output.
|
|
2994
|
+
*
|
|
2995
|
+
* The parent path must have been populated in a previous `.populate()` call.
|
|
2996
|
+
*
|
|
2997
|
+
* @param path - A dot-separated path like `'author.companyId'`.
|
|
2998
|
+
* @param as - The new name for the leaf field in the output.
|
|
2999
|
+
* @returns A new builder with the nested field renamed and typed.
|
|
3000
|
+
*
|
|
3001
|
+
* @example
|
|
3002
|
+
* ```ts
|
|
3003
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
3004
|
+
* .populate('authorId', 'author')
|
|
3005
|
+
* .populate('author.companyId', 'company')
|
|
3006
|
+
* // post.author.company is a Company document
|
|
3007
|
+
* ```
|
|
3008
|
+
*/
|
|
3009
|
+
populate<TPath extends NestedRefPath<TPopMap>, TAs extends string>(path: TPath, as: TAs): PopulateOneQuery<TDef, DeepPopulate<TOutput, `${ExtractParent<TPath>}.${TAs}`, ExtractLeaf<TPath>, TAs, PopulateField<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>>, TPopMap & {
|
|
3010
|
+
[P in `${ExtractParent<TPath>}.${TAs}`]: ExtractRefCollection<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>;
|
|
3011
|
+
}>;
|
|
3012
|
+
/**
|
|
3013
|
+
* Attach fulfillment and rejection handlers to the query promise.
|
|
3014
|
+
*
|
|
3015
|
+
* Executes the base findOne query and applies populate steps if any.
|
|
3016
|
+
* Returns `null` when no document matches the filter.
|
|
3017
|
+
*/
|
|
3018
|
+
then<TResult1 = TOutput | null, TResult2 = never>(onfulfilled?: ((value: TOutput | null) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
3019
|
+
private execute;
|
|
3020
|
+
}
|
|
3021
|
+
/**
|
|
3022
|
+
* Fluent populate builder for findOneOrThrow queries.
|
|
3023
|
+
*
|
|
3024
|
+
* Identical to {@link PopulateOneQuery} but resolves to `TOutput` (never null).
|
|
3025
|
+
* Throws {@link ZodmonNotFoundError} when no document matches the filter.
|
|
3026
|
+
*
|
|
3027
|
+
* @example
|
|
3028
|
+
* ```ts
|
|
3029
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3030
|
+
* .populate('authorId', 'author')
|
|
3031
|
+
* // Guaranteed non-null; throws if not found
|
|
3032
|
+
* ```
|
|
3033
|
+
*/
|
|
3034
|
+
declare class PopulateOneOrThrowQuery<TDef extends AnyCollection, TOutput, TPopMap extends Record<string, AnyCollection> = Record<string, never>> implements PromiseLike<TOutput> {
|
|
3035
|
+
private readonly handle;
|
|
3036
|
+
private readonly filter;
|
|
3037
|
+
private readonly options;
|
|
3038
|
+
private readonly steps;
|
|
3039
|
+
constructor(handle: CollectionHandle<TDef>, filter: TypedFilter<InferDocument<TDef>>, options: FindOneOptions | undefined, steps?: readonly PopulateStep[]);
|
|
3040
|
+
/**
|
|
3041
|
+
* Populate a top-level ref field, keeping the original field name.
|
|
3042
|
+
*
|
|
3043
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
3044
|
+
* @returns A new builder with the field type replaced by the referenced document.
|
|
3045
|
+
*
|
|
3046
|
+
* @example
|
|
3047
|
+
* ```ts
|
|
3048
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3049
|
+
* .populate('authorId')
|
|
3050
|
+
* ```
|
|
3051
|
+
*/
|
|
3052
|
+
populate<K extends RefFields<TDef>>(field: K): PopulateOneOrThrowQuery<TDef, ApplyPopulate<TOutput, TDef, K>, TPopMap & {
|
|
3053
|
+
[P in K]: ExtractRefCollection<TDef, K>;
|
|
3054
|
+
}>;
|
|
3055
|
+
/**
|
|
3056
|
+
* Populate a top-level ref field with a projection, keeping the original field name.
|
|
3057
|
+
*
|
|
3058
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
3059
|
+
* @param configure - Callback receiving a builder; call `.project()` to set the projection.
|
|
3060
|
+
* @returns A new builder with the field type narrowed to only the projected fields.
|
|
3061
|
+
*
|
|
3062
|
+
* @example
|
|
3063
|
+
* ```ts
|
|
3064
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3065
|
+
* .populate('authorId', (b) => b.project({ name: 1, email: 1 }))
|
|
3066
|
+
* // post.authorId is { _id: ObjectId; name: string; email: string }
|
|
3067
|
+
* // post.authorId.age → TS error
|
|
3068
|
+
* ```
|
|
3069
|
+
*/
|
|
3070
|
+
populate<K extends RefFields<TDef>, P>(field: K, configure: (b: PopulateRefBuilder<InferDocument<ExtractRefCollection<TDef, K>>>) => PopulateProjectionConfig<P>): PopulateOneOrThrowQuery<TDef, ApplyPopulateProjected<TOutput, TDef, K, P>, TPopMap & {
|
|
3071
|
+
[F in K]: ExtractRefCollection<TDef, K>;
|
|
3072
|
+
}>;
|
|
3073
|
+
/**
|
|
3074
|
+
* Populate a top-level ref field and rename it in the output.
|
|
3075
|
+
*
|
|
3076
|
+
* @param field - A ref-bearing field name on the root collection.
|
|
3077
|
+
* @param as - The new field name in the output document.
|
|
3078
|
+
* @returns A new builder with the old field removed and the new field added.
|
|
3079
|
+
*
|
|
3080
|
+
* @example
|
|
3081
|
+
* ```ts
|
|
3082
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3083
|
+
* .populate('authorId', 'author')
|
|
3084
|
+
* ```
|
|
3085
|
+
*/
|
|
3086
|
+
populate<K extends RefFields<TDef>, TAs extends string>(field: K, as: TAs): PopulateOneOrThrowQuery<TDef, ApplyPopulate<TOutput, TDef, K, TAs>, TPopMap & {
|
|
3087
|
+
[P in TAs]: ExtractRefCollection<TDef, K>;
|
|
3088
|
+
}>;
|
|
3089
|
+
/**
|
|
3090
|
+
* Populate a nested ref field, keeping the leaf field name.
|
|
3091
|
+
*
|
|
3092
|
+
* @param path - A dot-separated path like `'author.companyId'`.
|
|
3093
|
+
* @returns A new builder with the nested field type replaced.
|
|
3094
|
+
*
|
|
3095
|
+
* @example
|
|
3096
|
+
* ```ts
|
|
3097
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3098
|
+
* .populate('authorId', 'author')
|
|
3099
|
+
* .populate('author.companyId')
|
|
3100
|
+
* ```
|
|
3101
|
+
*/
|
|
3102
|
+
populate<TPath extends NestedRefPath<TPopMap>>(path: TPath): PopulateOneOrThrowQuery<TDef, DeepPopulate<TOutput, `${ExtractParent<TPath>}.${ExtractLeaf<TPath>}`, ExtractLeaf<TPath>, ExtractLeaf<TPath>, PopulateField<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>>, TPopMap & {
|
|
3103
|
+
[P in `${ExtractParent<TPath>}.${ExtractLeaf<TPath>}`]: ExtractRefCollection<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>;
|
|
3104
|
+
}>;
|
|
3105
|
+
/**
|
|
3106
|
+
* Populate a nested ref field and rename the leaf in the output.
|
|
3107
|
+
*
|
|
3108
|
+
* @param path - A dot-separated path like `'author.companyId'`.
|
|
3109
|
+
* @param as - The new name for the leaf field in the output.
|
|
3110
|
+
* @returns A new builder with the nested field renamed and typed.
|
|
3111
|
+
*
|
|
3112
|
+
* @example
|
|
3113
|
+
* ```ts
|
|
3114
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3115
|
+
* .populate('authorId', 'author')
|
|
3116
|
+
* .populate('author.companyId', 'company')
|
|
3117
|
+
* ```
|
|
3118
|
+
*/
|
|
3119
|
+
populate<TPath extends NestedRefPath<TPopMap>, TAs extends string>(path: TPath, as: TAs): PopulateOneOrThrowQuery<TDef, DeepPopulate<TOutput, `${ExtractParent<TPath>}.${TAs}`, ExtractLeaf<TPath>, TAs, PopulateField<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>>, TPopMap & {
|
|
3120
|
+
[P in `${ExtractParent<TPath>}.${TAs}`]: ExtractRefCollection<TPopMap[ExtractParent<TPath>], ExtractLeaf<TPath> & RefFields<TPopMap[ExtractParent<TPath>]>>;
|
|
3121
|
+
}>;
|
|
3122
|
+
/**
|
|
3123
|
+
* Attach fulfillment and rejection handlers to the query promise.
|
|
3124
|
+
*
|
|
3125
|
+
* Executes the base findOneOrThrow query and applies populate steps if any.
|
|
3126
|
+
* Throws {@link ZodmonNotFoundError} when no document matches.
|
|
3127
|
+
*/
|
|
3128
|
+
then<TResult1 = TOutput, TResult2 = never>(onfulfilled?: ((value: TOutput) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
|
|
3129
|
+
private execute;
|
|
3130
|
+
}
|
|
3131
|
+
|
|
2245
3132
|
/**
|
|
2246
3133
|
* Typed wrapper around a MongoDB driver `Collection`.
|
|
2247
3134
|
*
|
|
@@ -2257,7 +3144,35 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
2257
3144
|
readonly definition: TDef;
|
|
2258
3145
|
/** The underlying MongoDB driver collection, typed to the inferred document type. */
|
|
2259
3146
|
readonly native: Collection<InferDocument<TDef>>;
|
|
2260
|
-
|
|
3147
|
+
/**
|
|
3148
|
+
* The MongoDB client session bound to this handle, if any.
|
|
3149
|
+
*
|
|
3150
|
+
* When set, all CRUD and aggregation operations performed through this
|
|
3151
|
+
* handle will include the session in their options, enabling transactional
|
|
3152
|
+
* reads and writes. Undefined when no session is bound.
|
|
3153
|
+
*/
|
|
3154
|
+
readonly session: ClientSession | undefined;
|
|
3155
|
+
constructor(definition: TDef, native: Collection<InferDocument<TDef>>, session?: ClientSession);
|
|
3156
|
+
/**
|
|
3157
|
+
* Create a new handle bound to the given MongoDB client session.
|
|
3158
|
+
*
|
|
3159
|
+
* Returns a new {@link CollectionHandle} that shares the same collection
|
|
3160
|
+
* definition and native driver collection, but passes `session` to every
|
|
3161
|
+
* CRUD and aggregation operation. The original handle is not modified.
|
|
3162
|
+
*
|
|
3163
|
+
* @param session - The MongoDB `ClientSession` to bind.
|
|
3164
|
+
* @returns A new handle with the session attached.
|
|
3165
|
+
*
|
|
3166
|
+
* @example
|
|
3167
|
+
* ```ts
|
|
3168
|
+
* const users = db.use(Users)
|
|
3169
|
+
* await db.client.withSession(async (session) => {
|
|
3170
|
+
* const bound = users.withSession(session)
|
|
3171
|
+
* await bound.insertOne({ name: 'Ada' }) // uses session
|
|
3172
|
+
* })
|
|
3173
|
+
* ```
|
|
3174
|
+
*/
|
|
3175
|
+
withSession(session: ClientSession): CollectionHandle<TDef>;
|
|
2261
3176
|
/**
|
|
2262
3177
|
* Insert a single document into the collection.
|
|
2263
3178
|
*
|
|
@@ -2301,13 +3216,12 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
2301
3216
|
/**
|
|
2302
3217
|
* Find a single document matching the filter.
|
|
2303
3218
|
*
|
|
2304
|
-
*
|
|
2305
|
-
*
|
|
2306
|
-
* back to the collection-level default (which defaults to `'strict'`).
|
|
3219
|
+
* Returns a {@link PopulateOneQuery} that can be awaited directly or chained
|
|
3220
|
+
* with `.populate()` calls to resolve foreign key references.
|
|
2307
3221
|
*
|
|
2308
3222
|
* @param filter - Type-safe filter to match documents.
|
|
2309
3223
|
* @param options - Optional validation overrides.
|
|
2310
|
-
* @returns
|
|
3224
|
+
* @returns A populate builder that resolves to the matched document, or `null`.
|
|
2311
3225
|
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
2312
3226
|
*
|
|
2313
3227
|
* @example
|
|
@@ -2316,13 +3230,20 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
2316
3230
|
* const user = await users.findOne({ name: 'Ada' })
|
|
2317
3231
|
* if (user) console.log(user.role)
|
|
2318
3232
|
* ```
|
|
3233
|
+
*
|
|
3234
|
+
* @example
|
|
3235
|
+
* ```ts
|
|
3236
|
+
* const post = await posts.findOne({ title: 'Hello' })
|
|
3237
|
+
* .populate('authorId', 'author')
|
|
3238
|
+
* ```
|
|
2319
3239
|
*/
|
|
2320
|
-
findOne(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions):
|
|
3240
|
+
findOne(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): PopulateOneQuery<TDef, InferDocument<TDef>>;
|
|
2321
3241
|
/**
|
|
2322
3242
|
* Find a single document matching the filter with a type-safe projection.
|
|
2323
3243
|
*
|
|
2324
3244
|
* Returns only the fields specified by the projection. The return type is
|
|
2325
3245
|
* narrowed to reflect which fields are included or excluded.
|
|
3246
|
+
* Projected queries do not support `.populate()`.
|
|
2326
3247
|
*
|
|
2327
3248
|
* @param filter - Type-safe filter to match documents.
|
|
2328
3249
|
* @param options - Projection and optional validation overrides.
|
|
@@ -2340,12 +3261,13 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
2340
3261
|
/**
|
|
2341
3262
|
* Find a single document matching the filter, or throw if none exists.
|
|
2342
3263
|
*
|
|
2343
|
-
*
|
|
2344
|
-
*
|
|
3264
|
+
* Returns a {@link PopulateOneOrThrowQuery} that can be awaited directly or
|
|
3265
|
+
* chained with `.populate()` calls. Throws {@link ZodmonNotFoundError}
|
|
3266
|
+
* instead of returning `null` when no document matches.
|
|
2345
3267
|
*
|
|
2346
3268
|
* @param filter - Type-safe filter to match documents.
|
|
2347
3269
|
* @param options - Optional validation overrides.
|
|
2348
|
-
* @returns
|
|
3270
|
+
* @returns A populate builder that resolves to the matched document (never null).
|
|
2349
3271
|
* @throws {ZodmonNotFoundError} When no document matches the filter.
|
|
2350
3272
|
* @throws {ZodmonValidationError} When the fetched document fails schema validation in strict mode.
|
|
2351
3273
|
*
|
|
@@ -2355,14 +3277,21 @@ declare class CollectionHandle<TDef extends AnyCollection = AnyCollection> {
|
|
|
2355
3277
|
* const user = await users.findOneOrThrow({ name: 'Ada' })
|
|
2356
3278
|
* console.log(user.role) // guaranteed non-null
|
|
2357
3279
|
* ```
|
|
3280
|
+
*
|
|
3281
|
+
* @example
|
|
3282
|
+
* ```ts
|
|
3283
|
+
* const post = await posts.findOneOrThrow({ title: 'Hello' })
|
|
3284
|
+
* .populate('authorId', 'author')
|
|
3285
|
+
* ```
|
|
2358
3286
|
*/
|
|
2359
|
-
findOneOrThrow(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions):
|
|
3287
|
+
findOneOrThrow(filter: TypedFilter<InferDocument<TDef>>, options?: FindOneOptions): PopulateOneOrThrowQuery<TDef, InferDocument<TDef>>;
|
|
2360
3288
|
/**
|
|
2361
3289
|
* Find a single document matching the filter with a type-safe projection, or throw if none exists.
|
|
2362
3290
|
*
|
|
2363
3291
|
* Returns only the fields specified by the projection. The return type is
|
|
2364
3292
|
* narrowed to reflect which fields are included or excluded. Throws
|
|
2365
3293
|
* {@link ZodmonNotFoundError} instead of returning `null`.
|
|
3294
|
+
* Projected queries do not support `.populate()`.
|
|
2366
3295
|
*
|
|
2367
3296
|
* @param filter - Type-safe filter to match documents.
|
|
2368
3297
|
* @param options - Projection and optional validation overrides.
|
|
@@ -2612,7 +3541,8 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
2612
3541
|
protected readonly definition: TDef;
|
|
2613
3542
|
private readonly nativeCollection;
|
|
2614
3543
|
private readonly stages;
|
|
2615
|
-
|
|
3544
|
+
private readonly session;
|
|
3545
|
+
constructor(definition: TDef, nativeCollection: Collection<InferDocument<TDef>>, stages: Document[], session?: ClientSession);
|
|
2616
3546
|
/**
|
|
2617
3547
|
* Append an arbitrary aggregation stage to the pipeline (escape hatch).
|
|
2618
3548
|
*
|
|
@@ -2728,10 +3658,21 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
2728
3658
|
* .toArray()
|
|
2729
3659
|
* // subset[0].role → 'engineer' | 'designer'
|
|
2730
3660
|
* ```
|
|
3661
|
+
*
|
|
3662
|
+
* @example
|
|
3663
|
+
* ```ts
|
|
3664
|
+
* // Field-vs-field comparison via $expr callback
|
|
3665
|
+
* const overRefunded = await orders.aggregate()
|
|
3666
|
+
* .match(
|
|
3667
|
+
* { status: 'completed' },
|
|
3668
|
+
* (expr) => expr.gt('totalAmount', expr.field('refundedAmount')),
|
|
3669
|
+
* )
|
|
3670
|
+
* .toArray()
|
|
3671
|
+
* ```
|
|
2731
3672
|
*/
|
|
2732
3673
|
match<TNarrow extends {
|
|
2733
3674
|
[K in keyof TNarrow]: K extends keyof TOutput ? TOutput[K] : never;
|
|
2734
|
-
} = {}, F extends TypedFilter<TOutput> = TypedFilter<TOutput>>(filter: F): AggregatePipeline<TDef, Prettify<Omit<NarrowFromFilter<TOutput, F>, keyof TNarrow> & TNarrow>>;
|
|
3675
|
+
} = {}, F extends TypedFilter<TOutput> = TypedFilter<TOutput>>(filter: F, exprCb?: (expr: ExpressionBuilder<TOutput>) => Expression<boolean>): AggregatePipeline<TDef, Prettify<Omit<NarrowFromFilter<TOutput, F>, keyof TNarrow> & TNarrow>>;
|
|
2735
3676
|
/**
|
|
2736
3677
|
* Sort documents by one or more fields.
|
|
2737
3678
|
*
|
|
@@ -2848,7 +3789,7 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
2848
3789
|
* and compile-time field validation. Builder methods resolve return types
|
|
2849
3790
|
* to the actual field type (`T[K]`), not `unknown`.
|
|
2850
3791
|
*
|
|
2851
|
-
* @param field - A field name
|
|
3792
|
+
* @param field - A field name, array of field names, or `null` to aggregate all documents into a single group.
|
|
2852
3793
|
* @param accumulators - A callback `(acc) => ({ ... })` or plain accumulator object.
|
|
2853
3794
|
* @returns A new pipeline with the `$group` stage appended.
|
|
2854
3795
|
*
|
|
@@ -2879,7 +3820,20 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
2879
3820
|
* .groupBy(['role', 'dept'], acc => ({ count: acc.count() }))
|
|
2880
3821
|
* .toArray()
|
|
2881
3822
|
* ```
|
|
3823
|
+
*
|
|
3824
|
+
* @example
|
|
3825
|
+
* ```ts
|
|
3826
|
+
* // Null groupBy — aggregate all documents into a single summary
|
|
3827
|
+
* const totals = await aggregate(orders)
|
|
3828
|
+
* .groupBy(null, acc => ({
|
|
3829
|
+
* grandTotal: acc.sum('amount'),
|
|
3830
|
+
* orderCount: acc.count(),
|
|
3831
|
+
* }))
|
|
3832
|
+
* .toArray()
|
|
3833
|
+
* // → [{ _id: null, grandTotal: 2740, orderCount: 7 }]
|
|
3834
|
+
* ```
|
|
2882
3835
|
*/
|
|
3836
|
+
groupBy<TAccum extends Record<string, Accumulator>>(field: null, accumulators: ((acc: AccumulatorBuilder<TOutput>) => TAccum) | TAccum): AggregatePipeline<TDef, GroupByNullResult<TAccum>>;
|
|
2883
3837
|
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
3838
|
groupBy<K extends DotPath<TOutput>, TAccum extends Record<string, Accumulator>>(field: K[], accumulators: ((acc: AccumulatorBuilder<TOutput>) => TAccum) | TAccum): AggregatePipeline<TDef, GroupByCompoundResult<TOutput, K, TAccum>>;
|
|
2885
3839
|
/**
|
|
@@ -3016,6 +3970,37 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
3016
3970
|
}): AggregatePipeline<TDef, Prettify<TOutput & {
|
|
3017
3971
|
[P in TAs]: InferDocument<TForeignDef>[];
|
|
3018
3972
|
}>>;
|
|
3973
|
+
/**
|
|
3974
|
+
* Run multiple sub-pipelines on the same input documents in parallel.
|
|
3975
|
+
*
|
|
3976
|
+
* Each key in `spec` maps to a callback that receives a fresh `SubPipeline`
|
|
3977
|
+
* starting from `TOutput`. The callback chains stages and returns the terminal
|
|
3978
|
+
* pipeline. Zodmon extracts the accumulated stages at runtime to build the
|
|
3979
|
+
* `$facet` document. The output type is fully inferred — no annotation needed.
|
|
3980
|
+
*
|
|
3981
|
+
* Sub-pipelines support all stage methods including `.raw()` for operators not
|
|
3982
|
+
* yet first-class. Execution methods (`toArray`, `explain`) are not available
|
|
3983
|
+
* inside branches.
|
|
3984
|
+
*
|
|
3985
|
+
* @param spec - An object mapping branch names to sub-pipeline builder callbacks.
|
|
3986
|
+
* @returns A new pipeline whose output is one document with each branch name mapped to an array of results.
|
|
3987
|
+
*
|
|
3988
|
+
* @example
|
|
3989
|
+
* ```ts
|
|
3990
|
+
* const [report] = await aggregate(orders)
|
|
3991
|
+
* .facet({
|
|
3992
|
+
* byCategory: (sub) => sub
|
|
3993
|
+
* .groupBy('category', acc => ({ count: acc.count() }))
|
|
3994
|
+
* .sort({ count: -1 }),
|
|
3995
|
+
* totals: (sub) => sub
|
|
3996
|
+
* .groupBy(null, acc => ({ grandTotal: acc.sum('amount') })),
|
|
3997
|
+
* })
|
|
3998
|
+
* .toArray()
|
|
3999
|
+
* // report.byCategory → { _id: 'electronics' | 'books' | 'clothing'; count: number }[]
|
|
4000
|
+
* // report.totals → { _id: null; grandTotal: number }[]
|
|
4001
|
+
* ```
|
|
4002
|
+
*/
|
|
4003
|
+
facet<TSpec extends Record<string, (sub: SubPipeline<TDef, TOutput>) => AggregatePipeline<TDef, any>>>(spec: TSpec): AggregatePipeline<TDef, Prettify<InferFacetOutput<TSpec>>>;
|
|
3019
4004
|
/**
|
|
3020
4005
|
* Count documents per group, sorted by count descending.
|
|
3021
4006
|
*
|
|
@@ -3112,6 +4097,8 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
3112
4097
|
bottom(n: number, options: {
|
|
3113
4098
|
by: keyof TOutput & string;
|
|
3114
4099
|
}): AggregatePipeline<TDef, TOutput>;
|
|
4100
|
+
/** @internal Used by facet() to extract branch stages. Not part of the public API. */
|
|
4101
|
+
getStages(): Document[];
|
|
3115
4102
|
}
|
|
3116
4103
|
/**
|
|
3117
4104
|
* Create a new aggregation pipeline for a collection.
|
|
@@ -3131,6 +4118,99 @@ declare class AggregatePipeline<TDef extends AnyCollection, TOutput> {
|
|
|
3131
4118
|
* ```
|
|
3132
4119
|
*/
|
|
3133
4120
|
declare function aggregate<TDef extends AnyCollection>(handle: CollectionHandle<TDef>): AggregatePipeline<TDef, InferDocument<TDef>>;
|
|
4121
|
+
/**
|
|
4122
|
+
* A sub-pipeline passed to each `.facet()` branch callback.
|
|
4123
|
+
*
|
|
4124
|
+
* All stage-building methods are available. Execution methods (`toArray`,
|
|
4125
|
+
* `explain`, `[Symbol.asyncIterator]`) are omitted — sub-pipelines are
|
|
4126
|
+
* not executed directly; they only accumulate stages for the parent `$facet` stage.
|
|
4127
|
+
*
|
|
4128
|
+
* @typeParam TDef - The collection definition type.
|
|
4129
|
+
* @typeParam TOutput - The current output document type.
|
|
4130
|
+
*
|
|
4131
|
+
* @example
|
|
4132
|
+
* ```ts
|
|
4133
|
+
* .facet({
|
|
4134
|
+
* summary: (sub: SubPipeline<typeof Orders, Order>) => sub.groupBy(null, acc => ({ total: acc.sum('amount') }))
|
|
4135
|
+
* })
|
|
4136
|
+
* ```
|
|
4137
|
+
*/
|
|
4138
|
+
type SubPipeline<TDef extends AnyCollection, TOutput> = Omit<AggregatePipeline<TDef, TOutput>, 'toArray' | 'explain' | typeof Symbol.asyncIterator>;
|
|
4139
|
+
/**
|
|
4140
|
+
* Maps a `.facet()` spec object to its inferred output shape.
|
|
4141
|
+
*
|
|
4142
|
+
* Each key maps to the array of results produced by that branch's terminal pipeline.
|
|
4143
|
+
* Uses `any` for the sub-pipeline parameter to avoid TypeScript contravariance
|
|
4144
|
+
* complications — inference of `TOut` from the return type is what matters.
|
|
4145
|
+
*
|
|
4146
|
+
* @example
|
|
4147
|
+
* ```ts
|
|
4148
|
+
* type Spec = {
|
|
4149
|
+
* byCategory: (sub: SubPipeline<any, any>) => AggregatePipeline<any, { _id: string; count: number }>
|
|
4150
|
+
* }
|
|
4151
|
+
* type Result = InferFacetOutput<Spec>
|
|
4152
|
+
* // ^? { byCategory: { _id: string; count: number }[] }
|
|
4153
|
+
* ```
|
|
4154
|
+
*/
|
|
4155
|
+
type InferFacetOutput<TSpec> = {
|
|
4156
|
+
[K in keyof TSpec]: TSpec[K] extends (sub: any) => AggregatePipeline<any, infer TOut> ? TOut[] : never;
|
|
4157
|
+
};
|
|
4158
|
+
|
|
4159
|
+
/**
|
|
4160
|
+
* The callback signature for {@link Database.transaction}.
|
|
4161
|
+
*
|
|
4162
|
+
* @typeParam T - The return type of the transaction callback.
|
|
4163
|
+
*
|
|
4164
|
+
* @example
|
|
4165
|
+
* ```ts
|
|
4166
|
+
* const fn: TransactionFn<void> = async (tx) => {
|
|
4167
|
+
* const txUsers = tx.use(users)
|
|
4168
|
+
* await txUsers.insertOne({ name: 'Ada' })
|
|
4169
|
+
* }
|
|
4170
|
+
* ```
|
|
4171
|
+
*/
|
|
4172
|
+
type TransactionFn<T> = (tx: TransactionContext) => Promise<T>;
|
|
4173
|
+
/**
|
|
4174
|
+
* Transaction context passed to the {@link Database.transaction} callback.
|
|
4175
|
+
*
|
|
4176
|
+
* Use {@link use} to bind existing collection handles to this transaction's
|
|
4177
|
+
* session. All operations on the returned handle participate in the
|
|
4178
|
+
* transaction -- auto-committed on success, auto-rolled-back on error.
|
|
4179
|
+
*
|
|
4180
|
+
* @example
|
|
4181
|
+
* ```ts
|
|
4182
|
+
* await db.transaction(async (tx) => {
|
|
4183
|
+
* const txUsers = tx.use(users)
|
|
4184
|
+
* const txPosts = tx.use(posts)
|
|
4185
|
+
* const user = await txUsers.insertOne({ name: 'Ada' })
|
|
4186
|
+
* await txPosts.insertOne({ authorId: user._id, title: 'Hello' })
|
|
4187
|
+
* })
|
|
4188
|
+
* ```
|
|
4189
|
+
*/
|
|
4190
|
+
declare class TransactionContext {
|
|
4191
|
+
/** @internal */
|
|
4192
|
+
private readonly session;
|
|
4193
|
+
/** @internal */
|
|
4194
|
+
constructor(session: ClientSession);
|
|
4195
|
+
/**
|
|
4196
|
+
* Bind a collection handle to this transaction's session.
|
|
4197
|
+
*
|
|
4198
|
+
* Returns a cloned handle whose CRUD operations automatically include
|
|
4199
|
+
* the transaction session. The original handle is not modified.
|
|
4200
|
+
*
|
|
4201
|
+
* @param handle - An existing collection handle from `db.use()`.
|
|
4202
|
+
* @returns A new handle bound to the transaction session.
|
|
4203
|
+
*
|
|
4204
|
+
* @example
|
|
4205
|
+
* ```ts
|
|
4206
|
+
* await db.transaction(async (tx) => {
|
|
4207
|
+
* const txUsers = tx.use(users)
|
|
4208
|
+
* await txUsers.insertOne({ name: 'Ada' })
|
|
4209
|
+
* })
|
|
4210
|
+
* ```
|
|
4211
|
+
*/
|
|
4212
|
+
use<TDef extends AnyCollection>(handle: CollectionHandle<TDef>): CollectionHandle<TDef>;
|
|
4213
|
+
}
|
|
3134
4214
|
|
|
3135
4215
|
/**
|
|
3136
4216
|
* Wraps a MongoDB `MongoClient` and `Db`, providing typed collection access
|
|
@@ -3187,11 +4267,40 @@ declare class Database {
|
|
|
3187
4267
|
*/
|
|
3188
4268
|
syncIndexes(options?: SyncIndexesOptions): Promise<Record<string, SyncIndexesResult>>;
|
|
3189
4269
|
/**
|
|
3190
|
-
* Execute a function within a MongoDB transaction
|
|
4270
|
+
* Execute a function within a MongoDB transaction.
|
|
4271
|
+
*
|
|
4272
|
+
* Starts a client session and runs the callback inside
|
|
4273
|
+
* `session.withTransaction()`. The driver handles commit on success,
|
|
4274
|
+
* abort on error, and automatic retries for transient transaction errors.
|
|
4275
|
+
*
|
|
4276
|
+
* The return value of `fn` is forwarded as the return value of this method.
|
|
4277
|
+
*
|
|
4278
|
+
* @param fn - Async callback receiving a {@link TransactionContext}.
|
|
4279
|
+
* @returns The value returned by `fn`.
|
|
4280
|
+
*
|
|
4281
|
+
* @example
|
|
4282
|
+
* ```ts
|
|
4283
|
+
* const user = await db.transaction(async (tx) => {
|
|
4284
|
+
* const txUsers = tx.use(users)
|
|
4285
|
+
* return await txUsers.insertOne({ name: 'Ada' })
|
|
4286
|
+
* })
|
|
4287
|
+
* ```
|
|
3191
4288
|
*
|
|
3192
|
-
*
|
|
4289
|
+
* @example
|
|
4290
|
+
* ```ts
|
|
4291
|
+
* // Rollback on error
|
|
4292
|
+
* try {
|
|
4293
|
+
* await db.transaction(async (tx) => {
|
|
4294
|
+
* const txUsers = tx.use(users)
|
|
4295
|
+
* await txUsers.insertOne({ name: 'Ada' })
|
|
4296
|
+
* throw new Error('abort!')
|
|
4297
|
+
* })
|
|
4298
|
+
* } catch (err) {
|
|
4299
|
+
* // insert was rolled back, err is the original error
|
|
4300
|
+
* }
|
|
4301
|
+
* ```
|
|
3193
4302
|
*/
|
|
3194
|
-
transaction<T>(
|
|
4303
|
+
transaction<T>(fn: TransactionFn<T>): Promise<T>;
|
|
3195
4304
|
/**
|
|
3196
4305
|
* Close the underlying `MongoClient` connection. Safe to call even if
|
|
3197
4306
|
* no connection was established (the driver handles this gracefully).
|
|
@@ -4009,6 +5118,68 @@ type WarnableDefinition = {
|
|
|
4009
5118
|
*/
|
|
4010
5119
|
declare function checkUnindexedFields(definition: WarnableDefinition, filter: Record<string, unknown>): void;
|
|
4011
5120
|
|
|
5121
|
+
/**
|
|
5122
|
+
* Walk through Zod wrappers to find the inner schema with ref metadata.
|
|
5123
|
+
*
|
|
5124
|
+
* Mirrors the type-level `UnwrapRef<T>` at runtime. Peels ZodOptional,
|
|
5125
|
+
* ZodNullable, ZodDefault (via `_zod.def.innerType`), and ZodArray
|
|
5126
|
+
* (via `_zod.def.element`).
|
|
5127
|
+
*
|
|
5128
|
+
* @param schema - The Zod schema to unwrap.
|
|
5129
|
+
* @returns The innermost schema after stripping wrappers.
|
|
5130
|
+
*
|
|
5131
|
+
* @example
|
|
5132
|
+
* ```ts
|
|
5133
|
+
* const inner = unwrapRefSchema(Posts.shape.categoryIds)
|
|
5134
|
+
* const ref = getRefMetadata(inner) // { collection: Categories }
|
|
5135
|
+
* ```
|
|
5136
|
+
*/
|
|
5137
|
+
declare function unwrapRefSchema(schema: z.ZodType): z.ZodType;
|
|
5138
|
+
/**
|
|
5139
|
+
* Resolve a `.populate()` call into a `PopulateStep`.
|
|
5140
|
+
*
|
|
5141
|
+
* For top-level fields, inspects the collection's shape directly.
|
|
5142
|
+
* For nested dot-paths, walks previous steps to find the parent
|
|
5143
|
+
* collection definition, then resolves the leaf field in that shape.
|
|
5144
|
+
*
|
|
5145
|
+
* @param definition - The root collection definition.
|
|
5146
|
+
* @param previousSteps - Steps from earlier `.populate()` calls.
|
|
5147
|
+
* @param path - The field path (e.g. `'authorId'` or `'author.companyId'`).
|
|
5148
|
+
* @param as - The output field name (renamed or original).
|
|
5149
|
+
* @param projection - Optional projection to pass to the `$in` query.
|
|
5150
|
+
* @returns A resolved `PopulateStep`.
|
|
5151
|
+
* @throws When the field has no `.ref()` metadata or the parent path is not populated.
|
|
5152
|
+
*
|
|
5153
|
+
* @example
|
|
5154
|
+
* ```ts
|
|
5155
|
+
* const step = resolvePopulateStep(Posts, [], 'authorId', 'author')
|
|
5156
|
+
* // { leafField: 'authorId', as: 'author', targetCollection: Users, ... }
|
|
5157
|
+
* ```
|
|
5158
|
+
*/
|
|
5159
|
+
declare function resolvePopulateStep(definition: AnyCollection, previousSteps: readonly PopulateStep[], path: string, as: string, projection?: Record<string, 0 | 1 | boolean>): PopulateStep;
|
|
5160
|
+
/**
|
|
5161
|
+
* Execute populate steps against a set of documents.
|
|
5162
|
+
*
|
|
5163
|
+
* Processes steps in order. For each step:
|
|
5164
|
+
* 1. Navigate to the parent level for nested paths
|
|
5165
|
+
* 2. Collect unique IDs from the leaf field
|
|
5166
|
+
* 3. Batch query the target collection with `$in`
|
|
5167
|
+
* 4. Merge results back, applying rename if needed
|
|
5168
|
+
*
|
|
5169
|
+
* Mutates the documents in place and returns them.
|
|
5170
|
+
*
|
|
5171
|
+
* @param documents - The documents to populate (mutated in place).
|
|
5172
|
+
* @param steps - The populate steps to execute in order.
|
|
5173
|
+
* @param getCollection - Function to get a native MongoDB Collection by name.
|
|
5174
|
+
* @returns The populated documents.
|
|
5175
|
+
*
|
|
5176
|
+
* @example
|
|
5177
|
+
* ```ts
|
|
5178
|
+
* const docs = await executePopulate(rawDocs, steps, name => db.collection(name))
|
|
5179
|
+
* ```
|
|
5180
|
+
*/
|
|
5181
|
+
declare function executePopulate(documents: Document[], steps: readonly PopulateStep[], getCollection: (name: string) => Collection): Promise<Document[]>;
|
|
5182
|
+
|
|
4012
5183
|
/**
|
|
4013
5184
|
* Convenience namespace that groups all query operators under a single import.
|
|
4014
5185
|
*
|
|
@@ -4317,4 +5488,4 @@ type UpdateFilterOf<TDef extends AnyCollection> = TypedUpdateFilter<InferDocumen
|
|
|
4317
5488
|
*/
|
|
4318
5489
|
type SortOf<TDef extends AnyCollection> = TypedSort<InferDocument<TDef>>;
|
|
4319
5490
|
|
|
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,
|
|
5491
|
+
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 ApplyPopulate, type ApplyPopulateProjected, type ArrayElement, type CollectionDefinition, CollectionHandle, type CollectionName, type CollectionOptions, type ComparisonOperators, type CompoundIndexDefinition, type CurrentDateFields, type CursorPage, type CursorPaginateOptions, Database, type DeepPopulate, type DotPath, type DotPathValue, type DotSubPaths, type ExclusionProjection, type Expression, type ExpressionBuilder, type ExtractRefCollection, type FieldIndexDefinition, type FieldOrExpr, type FieldRef, type FieldRefType, type FilterOf, type FindOneAndDeleteOptions, type FindOneAndUpdateOptions, type FindOneOptions, type FindOneProjectionOptions, type FindOptions, type FindProjectionOptions, type GroupByCompoundResult, type GroupByNullResult, 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 NestedRefPath, type OffsetPage, type OffsetPaginateOptions, type PopFields, PopulateCursor, type PopulateField, type PopulateFieldProjected, PopulateOneOrThrowQuery, PopulateOneQuery, type PopulateProjectionConfig, PopulateRefBuilder, type PopulateStep, type Populated, type Prettify, type ProjectionResult, type PullFields, type PushFields, type PushModifiers, type RefFields, type RefMarker, type RefMetadata, type RenameFields, type ReplaceDots, type ResolvedShape, type SetFields, type SortOf, type StaleIndex, type SyncIndexesOptions, type SyncIndexesResult, TransactionContext, type TransactionFn, type TypedFilter, TypedFindCursor, type TypedProjection, type TypedSort, type TypedUpdateFilter, type UnsetFields, type UnwindResult, type UnwrapRef, type UpdateFilterOf, type UpdateOptions, type ValidationMode, type ZodObjectId, ZodmonAuthError, ZodmonBulkWriteError, ZodmonDocValidationError, ZodmonDuplicateKeyError, ZodmonError, ZodmonIndexError, ZodmonNetworkError, ZodmonNotFoundError, ZodmonQueryError, ZodmonTimeoutError, ZodmonValidationError, ZodmonWriteConflictError, aggregate, checkUnindexedFields, collection, createAccumulatorBuilder, createClient, createExpressionBuilder, createPopulateCursor, deleteMany, deleteOne, deriveProjectedSchema, executePopulate, extractComparableOptions, extractDbName, extractFieldIndexes, find, findOne, findOneAndDelete, findOneAndUpdate, findOneOrThrow, generateIndexName, getIndexMetadata, getRefMetadata, index, insertMany, insertOne, isInclusionProjection, isOid, objectId, oid, raw, resolvePopulateStep, serializeIndexKey, syncIndexes, toCompoundIndexSpec, toFieldIndexSpec, unwrapRefSchema, updateMany, updateOne, wrapMongoError };
|