mongoose 6.0.13 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -659,10 +659,10 @@ declare module 'mongoose' {
659
659
  $parent(): Document | undefined;
660
660
 
661
661
  /** Populates document references. */
662
- populate<Paths>(path: string | PopulateOptions | (string | PopulateOptions)[]): Promise<this & Paths>;
663
- populate<Paths>(path: string | PopulateOptions | (string | PopulateOptions)[], callback: Callback<this & Paths>): void;
664
- populate<Paths>(path: string, names: string): Promise<this & Paths>;
665
- populate<Paths>(path: string, names: string, callback: Callback<this & Paths>): void;
662
+ populate<Paths = {}>(path: string | PopulateOptions | (string | PopulateOptions)[]): Promise<this & Paths>;
663
+ populate<Paths = {}>(path: string | PopulateOptions | (string | PopulateOptions)[], callback: Callback<this & Paths>): void;
664
+ populate<Paths = {}>(path: string, names: string): Promise<this & Paths>;
665
+ populate<Paths = {}>(path: string, names: string, callback: Callback<this & Paths>): void;
666
666
 
667
667
  /** Gets _id(s) used during population of the given `path`. If the path was not populated, returns `undefined`. */
668
668
  populated(path: string): any;
@@ -747,9 +747,8 @@ declare module 'mongoose' {
747
747
  interface Model<T, TQueryHelpers = {}, TMethods = {}, TVirtuals = {}> extends NodeJS.EventEmitter, AcceptsDiscriminator {
748
748
  new(doc?: AnyKeys<T> & AnyObject, fields?: any | null, options?: boolean | AnyObject): HydratedDocument<T, TMethods, TVirtuals>;
749
749
 
750
- aggregate<R = any>(pipeline?: any[], options?: Record<string, unknown>): Aggregate<Array<R>>;
751
- aggregate<R = any>(pipeline: any[], cb: Function): Promise<Array<R>>;
752
- aggregate<R = any>(pipeline: any[], options: Record<string, unknown>, cb: Function): Promise<Array<R>>;
750
+ aggregate<R = any>(pipeline?: PipelineStage[], options?: mongodb.AggregateOptions, callback?: Callback<R[]>): Aggregate<Array<R>>;
751
+ aggregate<R = any>(pipeline: PipelineStage[], cb: Function): Aggregate<Array<R>>;
753
752
 
754
753
  /** Base Mongoose instance the model uses. */
755
754
  base: typeof mongoose;
@@ -1001,7 +1000,7 @@ declare module 'mongoose' {
1001
1000
  replaceOne(filter?: FilterQuery<T>, replacement?: T | AnyObject, options?: QueryOptions | null, callback?: Callback): QueryWithHelpers<any, HydratedDocument<T, TMethods, TVirtuals>, TQueryHelpers, T>;
1002
1001
 
1003
1002
  /** Schema the model uses. */
1004
- schema: Schema;
1003
+ schema: Schema<T>;
1005
1004
 
1006
1005
  /**
1007
1006
  * @deprecated use `updateOne` or `updateMany` instead.
@@ -1248,7 +1247,7 @@ declare module 'mongoose' {
1248
1247
  type PostMiddlewareFunction<ThisType, ResType = any> = (this: ThisType, res: ResType, next: (err?: CallbackError) => void) => void | Promise<void>;
1249
1248
  type ErrorHandlingMiddlewareFunction<ThisType, ResType = any> = (this: ThisType, err: NativeError, res: ResType, next: (err?: CallbackError) => void) => void;
1250
1249
 
1251
- class Schema<DocType = any, M = Model<DocType, any, any, any>, TInstanceMethods = {}> extends events.EventEmitter {
1250
+ class Schema<DocType = any, M = Model<DocType, any, any, any>, TInstanceMethods = any> extends events.EventEmitter {
1252
1251
  /**
1253
1252
  * Create a new schema
1254
1253
  */
@@ -1302,7 +1301,7 @@ declare module 'mongoose' {
1302
1301
  methods: { [name: string]: (this: HydratedDocument<DocType, TInstanceMethods, ExtractVirtuals<M>>, ...args: any[]) => any };
1303
1302
 
1304
1303
  /** The original object passed to the schema constructor */
1305
- obj: any;
1304
+ obj: SchemaDefinition<SchemaDefinitionType<DocType>>;
1306
1305
 
1307
1306
  /** Gets/sets schema paths. */
1308
1307
  path<ResultType extends SchemaType = SchemaType>(path: string): ResultType;
@@ -1399,7 +1398,8 @@ declare module 'mongoose' {
1399
1398
  SchemaTypeOptions<T extends undefined ? any : T>[] |
1400
1399
  Function[] |
1401
1400
  SchemaDefinition<T> |
1402
- SchemaDefinition<T>[];
1401
+ SchemaDefinition<T>[] |
1402
+ typeof SchemaTypes.Mixed;
1403
1403
 
1404
1404
  type SchemaDefinition<T = undefined> = T extends undefined
1405
1405
  ? { [path: string]: SchemaDefinitionProperty; }
@@ -1436,6 +1436,10 @@ declare module 'mongoose' {
1436
1436
  capped?: boolean | number | { size?: number; max?: number; autoIndexId?: boolean; };
1437
1437
  /** Sets a default collation for every query and aggregation. */
1438
1438
  collation?: mongodb.CollationOptions;
1439
+
1440
+ /** The timeseries option to use when creating the model's collection. */
1441
+ timeseries?: mongodb.TimeSeriesCollectionOptions;
1442
+
1439
1443
  /**
1440
1444
  * Mongoose by default produces a collection name by passing the model name to the utils.toCollectionName
1441
1445
  * method. This method pluralizes the name. Set this option if you need a different name for your collection.
@@ -1567,6 +1571,7 @@ declare module 'mongoose' {
1567
1571
  T extends string | number | boolean | NativeDate | Function ? SchemaDefinitionWithBuiltInClass<T> :
1568
1572
  T extends Schema<any, any, any> ? T :
1569
1573
  T extends Map<any, any> ? SchemaDefinition<typeof Map> :
1574
+ T extends Buffer ? SchemaDefinition<typeof Buffer> :
1570
1575
  T extends object[] ? (AnyArray<Schema<any, any, any>> | AnyArray<SchemaDefinition<Unpacked<T>>> | AnyArray<SchemaTypeOptions<Unpacked<T>>>) :
1571
1576
  T extends string[] ? AnyArray<SchemaDefinitionWithBuiltInClass<string>> | AnyArray<SchemaTypeOptions<string>> :
1572
1577
  T extends number[] ? AnyArray<SchemaDefinitionWithBuiltInClass<number>> | AnyArray<SchemaTypeOptions<number>> :
@@ -2040,7 +2045,7 @@ declare module 'mongoose' {
2040
2045
 
2041
2046
  class Decimal128 extends mongodb.Decimal128 { }
2042
2047
 
2043
- class DocumentArray<T extends Document> extends Types.Array<T> {
2048
+ class DocumentArray<T> extends Types.Array<T> {
2044
2049
  /** DocumentArray constructor */
2045
2050
  constructor(values: any[]);
2046
2051
 
@@ -2364,8 +2369,8 @@ declare module 'mongoose' {
2364
2369
  polygon(path: string, ...coordinatePairs: number[][]): this;
2365
2370
 
2366
2371
  /** Specifies paths which should be populated with other documents. */
2367
- populate<Paths>(path: string | any, select?: string | any, model?: string | Model<any, THelpers>, match?: any): QueryWithHelpers<ResultType & Paths, DocType, THelpers, RawDocType>;
2368
- populate<Paths>(options: PopulateOptions | Array<PopulateOptions>): QueryWithHelpers<ResultType & Paths, DocType, THelpers, RawDocType>;
2372
+ populate<Paths = {}>(path: string | any, select?: string | any, model?: string | Model<any, THelpers>, match?: any): QueryWithHelpers<ResultType & Paths, DocType, THelpers, RawDocType>;
2373
+ populate<Paths = {}>(options: PopulateOptions | Array<PopulateOptions>): QueryWithHelpers<ResultType & Paths, DocType, THelpers, RawDocType>;
2369
2374
 
2370
2375
  /** Get/set the current projection (AKA fields). Pass `null` to remove the current projection. */
2371
2376
  projection(fields?: any | null): any;
@@ -2645,7 +2650,7 @@ declare module 'mongoose' {
2645
2650
  [K in keyof T]: __UpdateDefProperty<T[K]>;
2646
2651
  };
2647
2652
 
2648
- export type UpdateQuery<T> = (_UpdateQuery<_UpdateQueryDef<T>> & MatchKeysAndValues<_UpdateQueryDef<LeanDocument<T>>>);
2653
+ export type UpdateQuery<T> = (_UpdateQuery<_UpdateQueryDef<T>> & MatchKeysAndValues<_UpdateQueryDef<DeepPartial<T>>>);
2649
2654
 
2650
2655
  export type DocumentDefinition<T> = {
2651
2656
  [K in keyof Omit<T, Exclude<keyof Document, '_id' | 'id' | '__v'>>]:
@@ -2687,6 +2692,10 @@ declare module 'mongoose' {
2687
2692
  export type SchemaDefinitionType<T> = T extends Document ? Omit<T, Exclude<keyof Document, '_id' | 'id' | '__v'>> : T;
2688
2693
  export type LeanDocument<T> = Omit<_LeanDocument<T>, Exclude<keyof Document, '_id' | 'id' | '__v'> | '$isSingleNested'>;
2689
2694
 
2695
+ type DeepPartial<T> = {
2696
+ [K in keyof T]?: DeepPartial<T[K]>;
2697
+ }
2698
+
2690
2699
  export type LeanDocumentOrArray<T> = 0 extends (1 & T) ? T :
2691
2700
  T extends unknown[] ? LeanDocument<T[number]>[] :
2692
2701
  T extends Document ? LeanDocument<T> :
@@ -2750,7 +2759,7 @@ declare module 'mongoose' {
2750
2759
  * Appends a new $addFields operator to this aggregate pipeline.
2751
2760
  * Requires MongoDB v3.4+ to work
2752
2761
  */
2753
- addFields(arg: any): this;
2762
+ addFields(arg: PipelineStage.AddFields['$addFields']): this;
2754
2763
 
2755
2764
  /** Sets the allowDiskUse option for the aggregation query (ignored for < 2.6.0) */
2756
2765
  allowDiskUse(value: boolean): this;
@@ -2769,7 +2778,7 @@ declare module 'mongoose' {
2769
2778
  collation(options: mongodb.CollationOptions): this;
2770
2779
 
2771
2780
  /** Appends a new $count operator to this aggregate pipeline. */
2772
- count(countName: string): this;
2781
+ count(countName: PipelineStage.Count['$count']): this;
2773
2782
 
2774
2783
  /**
2775
2784
  * Sets the cursor option for the aggregation query (ignored for < 2.6.0).
@@ -2783,13 +2792,13 @@ declare module 'mongoose' {
2783
2792
  explain(callback?: Callback): Promise<any>;
2784
2793
 
2785
2794
  /** Combines multiple aggregation pipelines. */
2786
- facet(options: any): this;
2795
+ facet(options: PipelineStage.Facet['$facet']): this;
2787
2796
 
2788
2797
  /** Appends new custom $graphLookup operator(s) to this aggregate pipeline, performing a recursive search on a collection. */
2789
- graphLookup(options: any): this;
2798
+ graphLookup(options: PipelineStage.GraphLookup['$graphLookup']): this;
2790
2799
 
2791
2800
  /** Appends new custom $group operator to this aggregate pipeline. */
2792
- group(arg: any): this;
2801
+ group(arg: PipelineStage.Group['$group']): this;
2793
2802
 
2794
2803
  /** Sets the hint option for the aggregation query (ignored for < 3.6.0) */
2795
2804
  hint(value: Record<string, unknown> | string): this;
@@ -2798,16 +2807,16 @@ declare module 'mongoose' {
2798
2807
  * Appends a new $limit operator to this aggregate pipeline.
2799
2808
  * @param num maximum number of records to pass to the next stage
2800
2809
  */
2801
- limit(num: number): this;
2810
+ limit(num: PipelineStage.Limit['$limit']): this;
2802
2811
 
2803
2812
  /** Appends new custom $lookup operator to this aggregate pipeline. */
2804
- lookup(options: any): this;
2813
+ lookup(options: PipelineStage.Lookup['$lookup']): this;
2805
2814
 
2806
2815
  /**
2807
2816
  * Appends a new custom $match operator to this aggregate pipeline.
2808
2817
  * @param arg $match operator contents
2809
2818
  */
2810
- match(arg: any): this;
2819
+ match(arg: PipelineStage.Match['$match']): this;
2811
2820
 
2812
2821
  /**
2813
2822
  * Binds this aggregate to a model.
@@ -2825,7 +2834,7 @@ declare module 'mongoose' {
2825
2834
  pipeline(): any[];
2826
2835
 
2827
2836
  /** Appends a new $project operator to this aggregate pipeline. */
2828
- project(arg: string | Object): this;
2837
+ project(arg: PipelineStage.Project['$project']): this;
2829
2838
 
2830
2839
  /** Sets the readPreference option for the aggregation query. */
2831
2840
  read(pref: string | mongodb.ReadPreferenceMode, tags?: any[]): this;
@@ -2837,13 +2846,13 @@ declare module 'mongoose' {
2837
2846
  redact(expression: any, thenExpr: string | any, elseExpr: string | any): this;
2838
2847
 
2839
2848
  /** Appends a new $replaceRoot operator to this aggregate pipeline. */
2840
- replaceRoot(newRoot: object | string): this;
2849
+ replaceRoot(newRoot: PipelineStage.ReplaceRoot['$replaceRoot'] | string): this;
2841
2850
 
2842
2851
  /**
2843
2852
  * Helper for [Atlas Text Search](https://docs.atlas.mongodb.com/reference/atlas-search/tutorial/)'s
2844
2853
  * `$search` stage.
2845
2854
  */
2846
- search(options: any): this;
2855
+ search(options: PipelineStage.Search['$search']): this;
2847
2856
 
2848
2857
  /** Lets you set arbitrary options, for middleware or plugins. */
2849
2858
  option(value: Record<string, unknown>): this;
@@ -2861,7 +2870,7 @@ declare module 'mongoose' {
2861
2870
  skip(num: number): this;
2862
2871
 
2863
2872
  /** Appends a new $sort operator to this aggregate pipeline. */
2864
- sort(arg: any): this;
2873
+ sort(arg: PipelineStage.Sort['$sort']): this;
2865
2874
 
2866
2875
  /** Provides promise for aggregate. */
2867
2876
  then: Promise<R>['then'];
@@ -2872,8 +2881,11 @@ declare module 'mongoose' {
2872
2881
  */
2873
2882
  sortByCount(arg: string | any): this;
2874
2883
 
2884
+ /** Appends new $unionWith operator to this aggregate pipeline. */
2885
+ unionWith(options: any): this;
2886
+
2875
2887
  /** Appends new custom $unwind operator(s) to this aggregate pipeline. */
2876
- unwind(...args: any[]): this;
2888
+ unwind(...args: PipelineStage.Unwind['$unwind'][]): this;
2877
2889
  }
2878
2890
 
2879
2891
  class AggregationCursor extends stream.Readable {
@@ -2913,6 +2925,276 @@ declare module 'mongoose' {
2913
2925
  next(callback: Callback): void;
2914
2926
  }
2915
2927
 
2928
+ /**
2929
+ * [Stages reference](https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/#aggregation-pipeline-stages)
2930
+ */
2931
+ export type PipelineStage =
2932
+ | PipelineStage.AddFields
2933
+ | PipelineStage.Bucket
2934
+ | PipelineStage.BucketAuto
2935
+ | PipelineStage.CollStats
2936
+ | PipelineStage.Count
2937
+ | PipelineStage.Facet
2938
+ | PipelineStage.GeoNear
2939
+ | PipelineStage.GraphLookup
2940
+ | PipelineStage.Group
2941
+ | PipelineStage.IndexStats
2942
+ | PipelineStage.Limit
2943
+ | PipelineStage.ListSessions
2944
+ | PipelineStage.Lookup
2945
+ | PipelineStage.Match
2946
+ | PipelineStage.Merge
2947
+ | PipelineStage.Out
2948
+ | PipelineStage.PlanCacheStats
2949
+ | PipelineStage.Project
2950
+ | PipelineStage.Redact
2951
+ | PipelineStage.ReplaceRoot
2952
+ | PipelineStage.ReplaceWith
2953
+ | PipelineStage.Sample
2954
+ | PipelineStage.Search
2955
+ | PipelineStage.Set
2956
+ | PipelineStage.SetWindowFields
2957
+ | PipelineStage.Skip
2958
+ | PipelineStage.Sort
2959
+ | PipelineStage.SortByCount
2960
+ | PipelineStage.UnionWith
2961
+ | PipelineStage.Unset
2962
+ | PipelineStage.Unwind
2963
+
2964
+ export namespace PipelineStage {
2965
+ export interface AddFields {
2966
+ /** [`$addFields` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/addFields/) */
2967
+ $addFields: Record<string, any>
2968
+ }
2969
+
2970
+ export interface Bucket {
2971
+ /** [`$bucket` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/bucket/) */
2972
+ $bucket: {
2973
+ groupBy: any
2974
+ boundaries: any[]
2975
+ default?: any
2976
+ output?: Record<string, { [op in AccumulatorOperator]?: any }>
2977
+ }
2978
+ }
2979
+
2980
+ export interface BucketAuto {
2981
+ /** [`$bucketAuto` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/bucketAuto/) */
2982
+ $bucketAuto: {
2983
+ groupBy: any
2984
+ buckets: number
2985
+ output?: Record<string, { [op in AccumulatorOperator]?: any }>
2986
+ granularity?: 'R5' | 'R10' | 'R20' | 'R40' | 'R80' | '1-2-5' | 'E6' | 'E12' | 'E24' | 'E48' | 'E96' | 'E192' | 'POWERSOF2'
2987
+ }
2988
+ }
2989
+
2990
+ export interface CollStats {
2991
+ /** [`$collStats` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/collStats/) */
2992
+ $collStats: {
2993
+ latencyStats?: { histograms?: boolean }
2994
+ storageStats?: { scale?: number }
2995
+ count?: {}
2996
+ queryExecStats?: {}
2997
+ }
2998
+ }
2999
+
3000
+ export interface Count {
3001
+ /** [`$count` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/count/) */
3002
+ $count: string
3003
+ }
3004
+
3005
+ export interface Facet {
3006
+ /** [`$facet` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/facet/) */
3007
+ $facet: Record<
3008
+ string,
3009
+ Exclude<PipelineStage, PipelineStage.CollStats | PipelineStage.Facet | PipelineStage.GeoNear | PipelineStage.IndexStats | PipelineStage.Out | PipelineStage.Merge | PipelineStage.PlanCacheStats>[]
3010
+ >
3011
+ }
3012
+
3013
+ export interface GeoNear {
3014
+ /** [`$geoNear` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/geoNear/) */
3015
+ $geoNear: {
3016
+ near: { type: 'Point'; coordinates: [number, number] } | [number, number]
3017
+ distanceField: string
3018
+ distanceMultiplier?: number
3019
+ includeLocs?: string
3020
+ key?: string
3021
+ maxDistance?: number
3022
+ minDistance?: number
3023
+ query?: AnyObject
3024
+ spherical?: boolean
3025
+ uniqueDocs?: boolean
3026
+ }
3027
+ }
3028
+
3029
+ export interface GraphLookup {
3030
+ /** [`$graphLookup` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/graphLookup/) */
3031
+ $graphLookup: {
3032
+ from: string
3033
+ startWith: any
3034
+ connectFromField: string
3035
+ connectToField: string
3036
+ as: string
3037
+ maxDepth?: number
3038
+ depthField?: string
3039
+ restrictSearchWithMatch?: AnyObject
3040
+ }
3041
+ }
3042
+
3043
+ export interface Group {
3044
+ /** [`$group` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/group) */
3045
+ $group: {
3046
+ _id: any
3047
+ [key: string]: { [op in AccumulatorOperator]?: any }
3048
+ }
3049
+ }
3050
+
3051
+ export interface IndexStats {
3052
+ /** [`$indexStats` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/indexStats/) */
3053
+ $indexStats: {}
3054
+ }
3055
+
3056
+ export interface Limit {
3057
+ /** [`$limit` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/limit/) */
3058
+ $limit: number
3059
+ }
3060
+
3061
+ export interface ListSessions {
3062
+ /** [`$listSessions` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/listSessions/) */
3063
+ $listSessions: { users?: { user: string; db: string }[] } | { allUsers?: true }
3064
+ }
3065
+
3066
+ export interface Lookup {
3067
+ /** [`$lookup` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/) */
3068
+ $lookup: {
3069
+ from: string
3070
+ as: string
3071
+ localField?: string
3072
+ foreignField?: string
3073
+ let?: Record<string, any>
3074
+ pipeline?: Exclude<PipelineStage, PipelineStage.Merge | PipelineStage.Out | PipelineStage.Search>[]
3075
+ }
3076
+ }
3077
+
3078
+ export interface Match {
3079
+ /** [`$match` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/match/) */
3080
+ $match: AnyObject
3081
+ }
3082
+
3083
+ export interface Merge {
3084
+ /** [`$merge` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/merge/) */
3085
+ $merge: {
3086
+ into: string | { db: string; coll: string }
3087
+ on?: string | string[]
3088
+ let?: Record<string, any>
3089
+ whenMatched?: 'replace' | 'keepExisting' | 'merge' | 'fail' | 'pipeline'
3090
+ whenNotMatched?: 'insert' | 'discard' | 'fail'
3091
+ }
3092
+ }
3093
+
3094
+ export interface Out {
3095
+ /** [`$out` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/out/) */
3096
+ $out: string | { db: string; coll: string }
3097
+ }
3098
+
3099
+ export interface PlanCacheStats {
3100
+ /** [`$planCacheStats` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/planCacheStats/) */
3101
+ $planCacheStats: {}
3102
+ }
3103
+
3104
+ export interface Project {
3105
+ /** [`$project` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/project/) */
3106
+ $project: { _id?: 0 | false; [field: string]: any }
3107
+ }
3108
+
3109
+ export interface Redact {
3110
+ /** [`$redact` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/redact/) */
3111
+ $redact: any
3112
+ }
3113
+
3114
+ export interface ReplaceRoot {
3115
+ /** [`$replaceRoot` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/replaceRoot/) */
3116
+ $replaceRoot: { newRoot: any }
3117
+ }
3118
+
3119
+ export interface ReplaceWith {
3120
+ /** [`$replaceWith` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/replaceWith/) */
3121
+ $replaceWith: any
3122
+ }
3123
+
3124
+ export interface Sample {
3125
+ /** [`$sample` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/sample/) */
3126
+ $sample: { size: number }
3127
+ }
3128
+
3129
+ export interface Search {
3130
+ /** [`$search` reference](https://docs.atlas.mongodb.com/reference/atlas-search/query-syntax/) */
3131
+ $search: {
3132
+ [key: string]: any
3133
+ index?: string
3134
+ highlight?: { path: string; maxCharsToExamine?: number; maxNumPassages?: number }
3135
+ }
3136
+ }
3137
+
3138
+ export interface Set {
3139
+ /** [`$set` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/set/) */
3140
+ $set: Record<string, any>
3141
+ }
3142
+
3143
+ export interface SetWindowFields {
3144
+ /** [`$setWindowFields` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/setWindowFields/) */
3145
+ $setWindowFields: {
3146
+ partitionBy?: any
3147
+ sortBy?: Record<string, 1 | -1>
3148
+ output: Record<
3149
+ string,
3150
+ { [op in WindowOperator]?: any } & {
3151
+ window?: {
3152
+ documents?: [string | number, string | number]
3153
+ range?: [string | number, string | number]
3154
+ unit?: 'year' | 'quarter' | 'month' | 'week' | 'day' | 'hour' | 'minute' | 'second' | 'millisecond'
3155
+ }
3156
+ }
3157
+ >
3158
+ }
3159
+ }
3160
+
3161
+ export interface Skip {
3162
+ /** [`$skip` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/skip/) */
3163
+ $skip: number
3164
+ }
3165
+
3166
+ export interface Sort {
3167
+ /** [`$sort` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/sort/) */
3168
+ $sort: Record<string, 1 | -1 | { $meta: 'textScore' }>
3169
+ }
3170
+
3171
+ export interface SortByCount {
3172
+ /** [`$sortByCount` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/sortByCount/) */
3173
+ $sortByCount: any
3174
+ }
3175
+
3176
+ export interface UnionWith {
3177
+ /** [`$unionWith` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/unionWith/) */
3178
+ $unionWith:
3179
+ | string
3180
+ | { coll: string; pipeline?: Exclude<PipelineStage, PipelineStage.Out | PipelineStage.Merge> }
3181
+ }
3182
+
3183
+ export interface Unset {
3184
+ /** [`$unset` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/unset/) */
3185
+ $unset: string | string[]
3186
+ }
3187
+
3188
+ export interface Unwind {
3189
+ /** [`$unwind` reference](https://docs.mongodb.com/manual/reference/operator/aggregation/unwind/) */
3190
+ $unwind: string | { path: string; includeArrayIndex?: string; preserveNullAndEmptyArrays?: boolean }
3191
+ }
3192
+
3193
+ type AccumulatorOperator = '$accumulator' | '$addToSet' | '$avg' | '$count' | '$first' | '$last' | '$max' | '$mergeObjects' | '$min' | '$push' | '$stdDevPop' | '$stdDevSamp' | '$sum'
3194
+
3195
+ type WindowOperator = '$addToSet' | '$avg' | '$count' | '$covariancePop' | '$covarianceSamp' | '$derivative' | '$expMovingAvg' | '$integral' | '$max' | '$min' | '$push' | '$stdDevSamp' | '$stdDevPop' | '$sum' | '$first' | '$last' | '$shift' | '$denseRank' | '$documentNumber' | '$rank'
3196
+ }
3197
+
2916
3198
  class SchemaType {
2917
3199
  /** SchemaType constructor */
2918
3200
  constructor(path: string, options?: AnyObject, instance?: string);
package/lib/aggregate.js CHANGED
@@ -593,6 +593,23 @@ Aggregate.prototype.sort = function(arg) {
593
593
  return this.append({ $sort: sort });
594
594
  };
595
595
 
596
+ /**
597
+ * Appends new $unionWith operator to this aggregate pipeline.
598
+ *
599
+ * ####Examples:
600
+ *
601
+ * aggregate.unionWith({ coll: 'users', pipeline: [ { $match: { _id: 1 } } ] });
602
+ *
603
+ * @see $unionWith https://docs.mongodb.com/manual/reference/operator/aggregation/unionWith
604
+ * @param {Object} options to $unionWith query as described in the above link
605
+ * @return {Aggregate}* @api public
606
+ */
607
+
608
+ Aggregate.prototype.unionWith = function(options) {
609
+ return this.append({ $unionWith: options });
610
+ };
611
+
612
+
596
613
  /**
597
614
  * Sets the readPreference option for the aggregation query.
598
615
  *
package/lib/connection.js CHANGED
@@ -850,10 +850,10 @@ function _setClient(conn, client, options, dbName) {
850
850
  if (type === 'Single') {
851
851
  client.on('serverDescriptionChanged', ev => {
852
852
  const newDescription = ev.newDescription;
853
- if (newDescription.type === 'Standalone') {
854
- _handleReconnect();
855
- } else {
853
+ if (newDescription.type === 'Unknown') {
856
854
  conn.readyState = STATES.disconnected;
855
+ } else {
856
+ _handleReconnect();
857
857
  }
858
858
  });
859
859
  } else if (type.startsWith('ReplicaSet')) {
@@ -1082,7 +1082,7 @@ Connection.prototype.model = function(name, schema, collection, options) {
1082
1082
  schema = false;
1083
1083
  }
1084
1084
 
1085
- if (utils.isObject(schema) && !schema.instanceOfSchema) {
1085
+ if (utils.isObject(schema) && !(schema instanceof this.base.Schema)) {
1086
1086
  schema = new Schema(schema);
1087
1087
  }
1088
1088
  if (schema && !schema.instanceOfSchema) {
@@ -1372,6 +1372,14 @@ Connection.prototype.setClient = function setClient(client) {
1372
1372
  return this;
1373
1373
  };
1374
1374
 
1375
+ Connection.prototype.syncIndexes = async function syncIndexes() {
1376
+ const result = {};
1377
+ for (const model in this.models) {
1378
+ result[model] = await this.model(model).syncIndexes();
1379
+ }
1380
+ return result;
1381
+ };
1382
+
1375
1383
  /**
1376
1384
  * Switches to a different database using the same connection pool.
1377
1385
  *
package/lib/document.js CHANGED
@@ -185,7 +185,9 @@ function Document(obj, fields, skipId, options) {
185
185
  const keys = Object.keys(this._doc);
186
186
 
187
187
  keys.forEach(function(key) {
188
- if (!(key in schema.tree)) {
188
+ // Avoid methods, virtuals, existing fields, and `$` keys. The latter is to avoid overwriting
189
+ // Mongoose internals.
190
+ if (!(key in schema.tree) && !(key in schema.methods) && !(key in schema.virtuals) && !key.startsWith('$')) {
189
191
  defineKey({ prop: key, subprops: null, prototype: _this });
190
192
  }
191
193
  });
@@ -806,7 +808,8 @@ function init(self, obj, doc, opts, prefix) {
806
808
  init(self, obj[i], doc[i], opts, path + '.');
807
809
  } else if (!schema) {
808
810
  doc[i] = obj[i];
809
- if (!strict) {
811
+ if (!strict && !prefix) {
812
+ // Set top-level properties that aren't in the schema if strict is false
810
813
  self[i] = obj[i];
811
814
  }
812
815
  } else {
@@ -987,7 +990,8 @@ Document.prototype.$session = function $session(session) {
987
990
 
988
991
  this.$__.session = session;
989
992
 
990
- if (!this.ownerDocument) {
993
+
994
+ if (!this.$__.isSubDocument) {
991
995
  const subdocs = this.$getAllSubdocs();
992
996
  for (const child of subdocs) {
993
997
  child.$session(session);
@@ -1196,6 +1200,13 @@ Document.prototype.$set = function $set(path, val, type, options) {
1196
1200
 
1197
1201
  if (pathType === 'nested' && val) {
1198
1202
  if (typeof val === 'object' && val != null) {
1203
+ if (val.$__ != null) {
1204
+ val = val.toObject(internalToObjectOptions);
1205
+ }
1206
+ if (val == null) {
1207
+ this.invalidate(path, new MongooseError.CastError('Object', val, path));
1208
+ return this;
1209
+ }
1199
1210
  const hasInitialVal = this.$__.savedState != null && this.$__.savedState.hasOwnProperty(path);
1200
1211
  if (this.$__.savedState != null && !this.$isNew && !this.$__.savedState.hasOwnProperty(path)) {
1201
1212
  const initialVal = this.$__getValue(path);
@@ -1457,9 +1468,9 @@ Document.prototype.$set = function $set(path, val, type, options) {
1457
1468
  }
1458
1469
 
1459
1470
  if (shouldSet) {
1460
- const doc = this.ownerDocument ? this.ownerDocument() : this;
1471
+ const doc = this.$__.isSubDocument ? this.ownerDocument() : this;
1461
1472
  const savedState = doc.$__.savedState;
1462
- const savedStatePath = this.ownerDocument ? this.$__.fullPath + '.' + path : path;
1473
+ const savedStatePath = this.$__.isSubDocument ? this.$__.fullPath + '.' + path : path;
1463
1474
  if (savedState != null) {
1464
1475
  const firstDot = savedStatePath.indexOf('.');
1465
1476
  const topLevelPath = firstDot === -1 ? savedStatePath : savedStatePath.slice(0, firstDot);
@@ -1833,7 +1844,7 @@ Document.prototype.$__path = function(path) {
1833
1844
 
1834
1845
  Document.prototype.markModified = function(path, scope) {
1835
1846
  this.$__.activePaths.modify(path);
1836
- if (scope != null && !this.ownerDocument) {
1847
+ if (scope != null && !this.$__.isSubDocument) {
1837
1848
  this.$__.pathsToScopes = this.$__pathsToScopes || {};
1838
1849
  this.$__.pathsToScopes[path] = scope;
1839
1850
  }
@@ -2361,7 +2372,7 @@ Document.prototype.validate = function(pathsToValidate, options, callback) {
2361
2372
  let parallelValidate;
2362
2373
  this.$op = 'validate';
2363
2374
 
2364
- if (this.ownerDocument != null) {
2375
+ if (this.$__.isSubDocument != null) {
2365
2376
  // Skip parallel validate check for subdocuments
2366
2377
  } else if (this.$__.validating) {
2367
2378
  parallelValidate = new ParallelValidateError(this, {
@@ -2420,7 +2431,11 @@ function _evaluateRequiredFunctions(doc) {
2420
2431
 
2421
2432
  if (p != null && typeof p.originalRequiredValue === 'function') {
2422
2433
  doc.$__.cachedRequired = doc.$__.cachedRequired || {};
2423
- doc.$__.cachedRequired[path] = p.originalRequiredValue.call(doc, doc);
2434
+ try {
2435
+ doc.$__.cachedRequired[path] = p.originalRequiredValue.call(doc, doc);
2436
+ } catch (err) {
2437
+ doc.invalidate(path, err);
2438
+ }
2424
2439
  }
2425
2440
  });
2426
2441
  }
@@ -3104,7 +3119,7 @@ Document.prototype.$__reset = function reset() {
3104
3119
  doc.$__reset();
3105
3120
  if (doc.$parent() === _this) {
3106
3121
  _this.$__.activePaths.init(doc.$basePath);
3107
- } else if (doc.$parent() != null && doc.$parent().ownerDocument) {
3122
+ } else if (doc.$parent() != null && doc.$parent().$__.isSubDocument) {
3108
3123
  // If map path underneath subdocument, may end up with a case where
3109
3124
  // map path is modified but parent still needs to be reset. See gh-10295
3110
3125
  doc.$parent().$__reset();
@@ -3939,9 +3954,15 @@ Document.prototype.toJSON = function(options) {
3939
3954
  return this.$toObject(options, true);
3940
3955
  };
3941
3956
 
3957
+
3958
+ Document.prototype.ownerDocument = function() {
3959
+ return this;
3960
+ };
3961
+
3962
+
3942
3963
  /**
3943
3964
  * If this document is a subdocument or populated document, returns the document's
3944
- * parent. Returns `undefined` otherwise.
3965
+ * parent. Returns the original document if there is no parent.
3945
3966
  *
3946
3967
  * @api public
3947
3968
  * @method parent
@@ -3950,7 +3971,10 @@ Document.prototype.toJSON = function(options) {
3950
3971
  */
3951
3972
 
3952
3973
  Document.prototype.parent = function() {
3953
- return this.$__.parent;
3974
+ if (this.$__.isSubDocument || this.$__.wasPopulated) {
3975
+ return this.$__.parent;
3976
+ }
3977
+ return this;
3954
3978
  };
3955
3979
 
3956
3980
  /**