mongoose 5.13.2 → 5.13.6

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
@@ -37,8 +37,7 @@ declare module 'mongoose' {
37
37
  * Mongoose constructor. The exports object of the `mongoose` module is an instance of this
38
38
  * class. Most apps will only use this one instance.
39
39
  */
40
- // eslint-disable-next-line @typescript-eslint/ban-types
41
- export const Mongoose: new (options?: object | null) => typeof mongoose;
40
+ export const Mongoose: new (options?: MongooseOptions | null) => typeof mongoose;
42
41
 
43
42
  /**
44
43
  * The Mongoose Number [SchemaType](/docs/schematypes.html). Used for
@@ -93,7 +92,7 @@ declare module 'mongoose' {
93
92
  export function disconnect(cb: (err: CallbackError) => void): void;
94
93
 
95
94
  /** Gets mongoose options */
96
- export function get(key: string): any;
95
+ export function get<K extends keyof MongooseOptions>(key: K): MongooseOptions[K];
97
96
 
98
97
  /**
99
98
  * Returns true if Mongoose can cast the given value to an ObjectId, or
@@ -120,7 +119,7 @@ declare module 'mongoose' {
120
119
  * [timestamps](/docs/guide.html#timestamps). You may stub out this function
121
120
  * using a tool like [Sinon](https://www.npmjs.com/package/sinon) for testing.
122
121
  */
123
- export function now(): Date;
122
+ export function now(): NativeDate;
124
123
 
125
124
  /** Declares a global plugin executed on all Schemas. */
126
125
  export function plugin(fn: (schema: Schema, opts?: any) => void, opts?: any): typeof mongoose;
@@ -129,7 +128,7 @@ declare module 'mongoose' {
129
128
  export function pluralize(fn?: ((str: string) => string) | null): ((str: string) => string) | null;
130
129
 
131
130
  /** Sets mongoose options */
132
- export function set(key: string, value: any): void;
131
+ export function set<K extends keyof MongooseOptions>(key: K, value: MongooseOptions[K]): typeof mongoose;
133
132
 
134
133
  /**
135
134
  * _Requires MongoDB >= 3.6.0._ Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
@@ -146,6 +145,135 @@ declare module 'mongoose' {
146
145
 
147
146
  type Mongoose = typeof mongoose;
148
147
 
148
+ interface MongooseOptions {
149
+ /** true by default. Set to false to skip applying global plugins to child schemas */
150
+ applyPluginsToChildSchemas?: boolean;
151
+
152
+ /**
153
+ * false by default. Set to true to apply global plugins to discriminator schemas.
154
+ * This typically isn't necessary because plugins are applied to the base schema and
155
+ * discriminators copy all middleware, methods, statics, and properties from the base schema.
156
+ */
157
+ applyPluginsToDiscriminators?: boolean;
158
+
159
+ /**
160
+ * Set to `true` to make Mongoose call` Model.createCollection()` automatically when you
161
+ * create a model with `mongoose.model()` or `conn.model()`. This is useful for testing
162
+ * transactions, change streams, and other features that require the collection to exist.
163
+ */
164
+ autoCreate?: boolean;
165
+
166
+ /**
167
+ * true by default. Set to false to disable automatic index creation
168
+ * for all models associated with this Mongoose instance.
169
+ */
170
+ autoIndex?: boolean;
171
+
172
+ /** enable/disable mongoose's buffering mechanism for all connections and models */
173
+ bufferCommands?: boolean;
174
+
175
+ bufferTimeoutMS?: number;
176
+
177
+ /** false by default. Set to `true` to `clone()` all schemas before compiling into a model. */
178
+ cloneSchemas?: boolean;
179
+
180
+ /**
181
+ * If `true`, prints the operations mongoose sends to MongoDB to the console.
182
+ * If a writable stream is passed, it will log to that stream, without colorization.
183
+ * If a callback function is passed, it will receive the collection name, the method
184
+ * name, then all arguments passed to the method. For example, if you wanted to
185
+ * replicate the default logging, you could output from the callback
186
+ * `Mongoose: ${collectionName}.${methodName}(${methodArgs.join(', ')})`.
187
+ */
188
+ debug?:
189
+ | boolean
190
+ | { color?: boolean; shell?: boolean }
191
+ | stream.Writable
192
+ | ((collectionName: string, methodName: string, ...methodArgs: any[]) => void);
193
+
194
+ /** If set, attaches [maxTimeMS](https://docs.mongodb.com/manual/reference/operator/meta/maxTimeMS/) to every query */
195
+ maxTimeMS?: number;
196
+
197
+ /**
198
+ * true by default. Mongoose adds a getter to MongoDB ObjectId's called `_id` that
199
+ * returns `this` for convenience with populate. Set this to false to remove the getter.
200
+ */
201
+ objectIdGetter?: boolean;
202
+
203
+ /**
204
+ * Set to `true` to default to overwriting models with the same name when calling
205
+ * `mongoose.model()`, as opposed to throwing an `OverwriteModelError`.
206
+ */
207
+ overwriteModels?: boolean;
208
+
209
+ /**
210
+ * If `false`, changes the default `returnOriginal` option to `findOneAndUpdate()`,
211
+ * `findByIdAndUpdate`, and `findOneAndReplace()` to false. This is equivalent to
212
+ * setting the `new` option to `true` for `findOneAndX()` calls by default. Read our
213
+ * `findOneAndUpdate()` [tutorial](https://mongoosejs.com/docs/tutorials/findoneandupdate.html)
214
+ * for more information.
215
+ */
216
+ returnOriginal?: boolean;
217
+
218
+ /**
219
+ * false by default. Set to true to enable [update validators](
220
+ * https://mongoosejs.com/docs/validation.html#update-validators
221
+ * ) for all validators by default.
222
+ */
223
+ runValidators?: boolean;
224
+
225
+ sanitizeProjection?: boolean;
226
+
227
+ /**
228
+ * true by default. Set to false to opt out of Mongoose adding all fields that you `populate()`
229
+ * to your `select()`. The schema-level option `selectPopulatedPaths` overwrites this one.
230
+ */
231
+ selectPopulatedPaths?: boolean;
232
+
233
+ setDefaultsOnInsert?: boolean;
234
+
235
+ /** true by default, may be `false`, `true`, or `'throw'`. Sets the default strict mode for schemas. */
236
+ strict?: boolean | 'throw';
237
+
238
+ /**
239
+ * false by default, may be `false`, `true`, or `'throw'`. Sets the default
240
+ * [strictQuery](https://mongoosejs.com/docs/guide.html#strictQuery) mode for schemas.
241
+ */
242
+ strictQuery?: boolean | 'throw';
243
+
244
+ /**
245
+ * `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to
246
+ * `toJSON()`, for determining how Mongoose documents get serialized by `JSON.stringify()`
247
+ */
248
+ toJSON?: ToObjectOptions;
249
+
250
+ /** `{ transform: true, flattenDecimals: true }` by default. Overwrites default objects to `toObject()` */
251
+ toObject?: ToObjectOptions;
252
+
253
+ /** true by default, may be `false` or `true`. Sets the default typePojoToMixed for schemas. */
254
+ typePojoToMixed?: boolean;
255
+
256
+ /**
257
+ * false by default. Set to `true` to make Mongoose's default index build use `createIndex()`
258
+ * instead of `ensureIndex()` to avoid deprecation warnings from the MongoDB driver.
259
+ */
260
+ useCreateIndex?: boolean;
261
+
262
+ /**
263
+ * true by default. Set to `false` to make `findOneAndUpdate()` and `findOneAndRemove()`
264
+ * use native `findOneAndUpdate()` rather than `findAndModify()`.
265
+ */
266
+ useFindAndModify?: boolean;
267
+
268
+ /** false by default. Set to `true` to make all connections set the `useNewUrlParser` option by default */
269
+ useNewUrlParser?: boolean;
270
+
271
+ usePushEach?: boolean;
272
+
273
+ /** false by default. Set to `true` to make all connections set the `useUnifiedTopology` option by default */
274
+ useUnifiedTopology?: boolean;
275
+ }
276
+
149
277
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
150
278
  interface ClientSession extends mongodb.ClientSession { }
151
279
 
@@ -166,6 +294,10 @@ declare module 'mongoose' {
166
294
  autoCreate?: boolean;
167
295
  /** False by default. If `true`, this connection will use `createIndex()` instead of `ensureIndex()` for automatic index builds via `Model.init()`. */
168
296
  useCreateIndex?: boolean;
297
+ /** false by default. Set to `true` to make all connections set the `useNewUrlParser` option by default */
298
+ useNewUrlParser?: boolean;
299
+ /** false by default. Set to `true` to make all connections set the `useUnifiedTopology` option by default */
300
+ useUnifiedTopology?: boolean;
169
301
  }
170
302
 
171
303
  class Connection extends events.EventEmitter {
@@ -618,20 +750,26 @@ declare module 'mongoose' {
618
750
 
619
751
  interface AcceptsDiscriminator {
620
752
  /** Adds a discriminator type. */
621
- discriminator<D extends Document>(name: string | number, schema: Schema<D>, value?: string | number | ObjectId): Model<D>;
622
- discriminator<T extends Document, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string | number | ObjectId): U;
753
+ discriminator<D>(name: string | number, schema: Schema<D>, value?: string | number | ObjectId): Model<D>;
754
+ discriminator<T, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string | number | ObjectId): U;
623
755
  }
624
756
 
757
+ type AnyKeys<T> = { [P in keyof T]?: T[P] | any };
625
758
  interface AnyObject { [k: string]: any }
626
759
  type EnforceDocument<T, TMethods> = T extends Document ? T : T & Document<any, any, T> & TMethods;
627
760
 
761
+ interface IndexesDiff {
762
+ /** Indexes that would be created in mongodb. */
763
+ toCreate: Array<any>
764
+ /** Indexes that would be dropped in mongodb. */
765
+ toDrop: Array<any>
766
+ }
767
+
628
768
  export const Model: Model<any>;
629
- // eslint-disable-next-line no-undef
630
769
  interface Model<T, TQueryHelpers = {}, TMethods = {}> extends NodeJS.EventEmitter, AcceptsDiscriminator {
631
- new(doc?: T | any): EnforceDocument<T, TMethods>;
770
+ new(doc?: AnyKeys<T> & AnyObject): EnforceDocument<T, TMethods>;
632
771
 
633
772
  aggregate<R = any>(pipeline?: any[]): Aggregate<Array<R>>;
634
- // eslint-disable-next-line @typescript-eslint/ban-types
635
773
  aggregate<R = any>(pipeline: any[], cb: Function): Promise<Array<R>>;
636
774
 
637
775
  /** Base Mongoose instance the model uses. */
@@ -722,7 +860,6 @@ declare module 'mongoose' {
722
860
  * Event emitter that reports any errors that occurred. Useful for global error
723
861
  * handling.
724
862
  */
725
- // eslint-disable-next-line no-undef
726
863
  events: NodeJS.EventEmitter;
727
864
 
728
865
  /**
@@ -786,6 +923,14 @@ declare module 'mongoose' {
786
923
  syncIndexes(options?: Record<string, unknown>): Promise<Array<string>>;
787
924
  syncIndexes(options: Record<string, unknown> | null, callback: (err: CallbackError, dropped: Array<string>) => void): void;
788
925
 
926
+ /**
927
+ * Does a dry-run of Model.syncIndexes(), meaning that
928
+ * the result of this function would be the result of
929
+ * Model.syncIndexes().
930
+ */
931
+ diffIndexes(options?: Record<string, unknown>): Promise<IndexesDiff>
932
+ diffIndexes(options: Record<string, unknown> | null, callback: (err: CallbackError, diff: IndexesDiff) => void): void
933
+
789
934
  /**
790
935
  * Starts a [MongoDB session](https://docs.mongodb.com/manual/release-notes/3.6/#client-sessions)
791
936
  * for benefits like causal consistency, [retryable writes](https://docs.mongodb.com/manual/core/retryable-writes/),
@@ -802,7 +947,6 @@ declare module 'mongoose' {
802
947
  watch(pipeline?: Array<Record<string, unknown>>, options?: mongodb.ChangeStreamOptions): mongodb.ChangeStream;
803
948
 
804
949
  /** Adds a `$where` clause to this query */
805
- // eslint-disable-next-line @typescript-eslint/ban-types
806
950
  $where(argument: string | Function): QueryWithHelpers<Array<EnforceDocument<T, TMethods>>, EnforceDocument<T, TMethods>, TQueryHelpers, T>;
807
951
 
808
952
  /** Registered discriminators for this model. */
@@ -998,7 +1142,6 @@ declare module 'mongoose' {
998
1142
  }
999
1143
 
1000
1144
  interface MapReduceOptions<T, Key, Val> {
1001
- // eslint-disable-next-line @typescript-eslint/ban-types
1002
1145
  map: Function | string;
1003
1146
  reduce: (key: Key, vals: T[]) => Val;
1004
1147
  /** query filter object. */
@@ -1134,7 +1277,7 @@ declare module 'mongoose' {
1134
1277
  eachPath(fn: (path: string, type: SchemaType) => void): this;
1135
1278
 
1136
1279
  /** Defines an index (most likely compound) for this schema. */
1137
- index(fields: any, options?: any): this;
1280
+ index(fields: mongodb.IndexSpecification, options?: IndexOptions): this;
1138
1281
 
1139
1282
  /**
1140
1283
  * Returns a list of indexes that this schema declares, via `schema.index()`
@@ -1143,7 +1286,7 @@ declare module 'mongoose' {
1143
1286
  indexes(): Array<any>;
1144
1287
 
1145
1288
  /** Gets a schema option. */
1146
- get(path: string): any;
1289
+ get<K extends keyof SchemaOptions>(key: K): SchemaOptions[K];
1147
1290
 
1148
1291
  /**
1149
1292
  * Loads an ES6 class into a schema. Maps [setters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set) + [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get), [static methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static),
@@ -1152,11 +1295,9 @@ declare module 'mongoose' {
1152
1295
  * [statics](http://mongoosejs.com/docs/guide.html#statics), and
1153
1296
  * [methods](http://mongoosejs.com/docs/guide.html#methods).
1154
1297
  */
1155
- // eslint-disable-next-line @typescript-eslint/ban-types
1156
1298
  loadClass(model: Function, onlyVirtuals?: boolean): this;
1157
1299
 
1158
1300
  /** Adds an instance method to documents constructed from Models compiled from this schema. */
1159
- // eslint-disable-next-line @typescript-eslint/ban-types
1160
1301
  method(name: string, fn: (this: EnforceDocument<DocType, TInstanceMethods>, ...args: any[]) => any, opts?: any): this;
1161
1302
  method(obj: { [name: string]: (this: EnforceDocument<DocType, TInstanceMethods>, ...args: any[]) => any }): this;
1162
1303
 
@@ -1167,7 +1308,7 @@ declare module 'mongoose' {
1167
1308
  obj: any;
1168
1309
 
1169
1310
  /** Gets/sets schema paths. */
1170
- path(path: string): SchemaType;
1311
+ path<ResultType extends SchemaType = SchemaType>(path: string): ResultType;
1171
1312
  path(path: string, constructor: any): this;
1172
1313
 
1173
1314
  /** Lists all paths and their type in the schema. */
@@ -1224,12 +1365,10 @@ declare module 'mongoose' {
1224
1365
  requiredPaths(invalidate?: boolean): string[];
1225
1366
 
1226
1367
  /** Sets a schema option. */
1227
- set(path: string, value: any, _tags?: any): this;
1368
+ set<K extends keyof SchemaOptions>(key: K, value: SchemaOptions[K], _tags?: any): this;
1228
1369
 
1229
1370
  /** Adds static "class" methods to Models compiled from this schema. */
1230
- // eslint-disable-next-line @typescript-eslint/ban-types
1231
1371
  static(name: string, fn: (this: M, ...args: any[]) => any): this;
1232
- // eslint-disable-next-line @typescript-eslint/ban-types
1233
1372
  static(obj: { [name: string]: (this: M, ...args: any[]) => any }): this;
1234
1373
 
1235
1374
  /** Object of currently defined statics on this schema. */
@@ -1432,7 +1571,7 @@ declare module 'mongoose' {
1432
1571
  interface SchemaTimestampsConfig {
1433
1572
  createdAt?: boolean | string;
1434
1573
  updatedAt?: boolean | string;
1435
- currentTime?: () => (Date | number);
1574
+ currentTime?: () => (NativeDate | number);
1436
1575
  }
1437
1576
 
1438
1577
  type Unpacked<T> = T extends (infer U)[] ? U : T;
@@ -1452,7 +1591,6 @@ declare module 'mongoose' {
1452
1591
  alias?: string;
1453
1592
 
1454
1593
  /** Function or object describing how to validate this schematype. See [validation docs](https://mongoosejs.com/docs/validation.html). */
1455
- // eslint-disable-next-line @typescript-eslint/ban-types
1456
1594
  validate?: RegExp | [RegExp, string] | Function | [Function, string] | ValidateOpts<T> | ValidateOpts<T>[];
1457
1595
 
1458
1596
  /** Allows overriding casting logic for this individual path. If a string, the given string overwrites Mongoose's default cast error message. */
@@ -1533,13 +1671,13 @@ declare module 'mongoose' {
1533
1671
  subtype?: number
1534
1672
 
1535
1673
  /** The minimum value allowed for this path. Only allowed for numbers and dates. */
1536
- min?: number | Date | [number, string] | [Date, string] | readonly [number, string] | readonly [Date, string];
1674
+ min?: number | NativeDate | [number, string] | [NativeDate, string] | readonly [number, string] | readonly [NativeDate, string];
1537
1675
 
1538
1676
  /** The maximum value allowed for this path. Only allowed for numbers and dates. */
1539
- max?: number | Date | [number, string] | [Date, string] | readonly [number, string] | readonly [Date, string];
1677
+ max?: number | NativeDate | [number, string] | [NativeDate, string] | readonly [number, string] | readonly [NativeDate, string];
1540
1678
 
1541
1679
  /** Defines a TTL index on this path. Only allowed for dates. */
1542
- expires?: number | Date;
1680
+ expires?: number | NativeDate;
1543
1681
 
1544
1682
  /** If `true`, Mongoose will skip gathering indexes on subpaths. Only allowed for subdocuments and subdocument arrays. */
1545
1683
  excludeIndexes?: boolean;
@@ -1548,7 +1686,6 @@ declare module 'mongoose' {
1548
1686
  _id?: boolean;
1549
1687
 
1550
1688
  /** If set, specifies the type of this map's values. Mongoose will cast this map's values to the given type. */
1551
- // eslint-disable-next-line @typescript-eslint/ban-types
1552
1689
  of?: Function | SchemaDefinitionProperty<any>;
1553
1690
 
1554
1691
  /** If true, uses Mongoose's default `_id` settings. Only allowed for ObjectIds */
@@ -1703,8 +1840,8 @@ declare module 'mongoose' {
1703
1840
 
1704
1841
  static options: { castNonArrays: boolean; };
1705
1842
 
1706
- discriminator<D extends Document>(name: string | number, schema: Schema<D>, value?: string): Model<D>;
1707
- discriminator<T extends Document, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string): U;
1843
+ discriminator<D>(name: string | number, schema: Schema<D>, value?: string): Model<D>;
1844
+ discriminator<T, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string): U;
1708
1845
 
1709
1846
  /**
1710
1847
  * Adds an enum validator if this is an array of strings or numbers. Equivalent to
@@ -1743,10 +1880,10 @@ declare module 'mongoose' {
1743
1880
  expires(when: number | string): this;
1744
1881
 
1745
1882
  /** Sets a maximum date validator. */
1746
- max(value: Date, message: string): this;
1883
+ max(value: NativeDate, message: string): this;
1747
1884
 
1748
1885
  /** Sets a minimum date validator. */
1749
- min(value: Date, message: string): this;
1886
+ min(value: NativeDate, message: string): this;
1750
1887
  }
1751
1888
 
1752
1889
  class Decimal128 extends SchemaType {
@@ -1760,8 +1897,8 @@ declare module 'mongoose' {
1760
1897
 
1761
1898
  static options: { castNonArrays: boolean; };
1762
1899
 
1763
- discriminator<D extends Document>(name: string | number, schema: Schema<D>, value?: string): Model<D>;
1764
- discriminator<T extends Document, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string): U;
1900
+ discriminator<D>(name: string | number, schema: Schema<D>, value?: string): Model<D>;
1901
+ discriminator<T, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string): U;
1765
1902
 
1766
1903
  /** The schema used for documents in this array */
1767
1904
  schema: Schema;
@@ -1799,12 +1936,15 @@ declare module 'mongoose' {
1799
1936
  auto(turnOn: boolean): this;
1800
1937
  }
1801
1938
 
1802
- class Embedded extends SchemaType {
1939
+ class Embedded extends SchemaType implements AcceptsDiscriminator {
1803
1940
  /** This schema type's name, to defend against minifiers that mangle function names. */
1804
1941
  static schemaName: string;
1805
1942
 
1806
1943
  /** The document's schema */
1807
1944
  schema: Schema;
1945
+
1946
+ discriminator<D>(name: string | number, schema: Schema<D>, value?: string): Model<D>;
1947
+ discriminator<T, U extends Model<T>>(name: string | number, schema: Schema<T, U>, value?: string): U;
1808
1948
  }
1809
1949
 
1810
1950
  class String extends SchemaType {
@@ -1972,7 +2112,6 @@ declare module 'mongoose' {
1972
2112
  // @todo: this doesn't seem right
1973
2113
  exec(callback?: (err: CallbackError, result: ResultType) => void): Promise<ResultType> | any;
1974
2114
 
1975
- // eslint-disable-next-line @typescript-eslint/ban-types
1976
2115
  $where(argument: string | Function): QueryWithHelpers<DocType[], DocType, THelpers, RawDocType>;
1977
2116
 
1978
2117
  /** Specifies an `$all` query condition. When called with one argument, the most recent path passed to `where()` is used. */
@@ -2051,9 +2190,7 @@ declare module 'mongoose' {
2051
2190
  distinct(field: string, filter?: FilterQuery<DocType>, callback?: (err: CallbackError, count: number) => void): QueryWithHelpers<Array<any>, DocType, THelpers, RawDocType>;
2052
2191
 
2053
2192
  /** Specifies a `$elemMatch` query condition. When called with one argument, the most recent path passed to `where()` is used. */
2054
- // eslint-disable-next-line @typescript-eslint/ban-types
2055
2193
  elemMatch(val: Function | any): this;
2056
- // eslint-disable-next-line @typescript-eslint/ban-types
2057
2194
  elemMatch(path: string, val: Function | any): this;
2058
2195
 
2059
2196
  /**
@@ -2172,7 +2309,7 @@ declare module 'mongoose' {
2172
2309
  * Runs a function `fn` and treats the return value of `fn` as the new value
2173
2310
  * for the query to resolve to.
2174
2311
  */
2175
- map<MappedType>(fn: (doc: DocType) => MappedType): QueryWithHelpers<ResultType extends unknown[] ? MappedType[] : MappedType, DocType, THelpers, RawDocType>;
2312
+ map<MappedType>(fn: (doc: ResultType) => MappedType): QueryWithHelpers<MappedType, DocType, THelpers, RawDocType>;
2176
2313
 
2177
2314
  /** Specifies an `$maxDistance` query condition. When called with one argument, the most recent path passed to `where()` is used. */
2178
2315
  maxDistance(val: number): this;
@@ -2376,9 +2513,9 @@ declare module 'mongoose' {
2376
2513
  ? mongodb.Condition<T[P]>
2377
2514
  : mongodb.Condition<T[P] | string>;
2378
2515
  } &
2379
- mongodb.RootQuerySelector<T>;
2516
+ mongodb.RootQuerySelector<DocumentDefinition<T>>;
2380
2517
 
2381
- export type FilterQuery<T> = _FilterQuery<DocumentDefinition<T>>;
2518
+ export type FilterQuery<T> = _FilterQuery<T>;
2382
2519
 
2383
2520
  type NumericTypes = number | mongodb.Decimal128 | mongodb.Double | mongodb.Int32 | mongodb.Long;
2384
2521
 
@@ -2440,8 +2577,7 @@ declare module 'mongoose' {
2440
2577
 
2441
2578
  type actualPrimitives = string | boolean | number | bigint | symbol | null | undefined;
2442
2579
  type TreatAsPrimitives = actualPrimitives |
2443
- // eslint-disable-next-line no-undef
2444
- Date | RegExp | symbol | Error | BigInt | Types.ObjectId;
2580
+ NativeDate | RegExp | symbol | Error | BigInt | Types.ObjectId;
2445
2581
 
2446
2582
  type LeanType<T> =
2447
2583
  0 extends (1 & T) ? T : // any
@@ -2451,13 +2587,18 @@ declare module 'mongoose' {
2451
2587
  type LeanArray<T extends unknown[]> = T extends unknown[][] ? LeanArray<T[number]>[] : LeanType<T[number]>[];
2452
2588
 
2453
2589
  export type _LeanDocument<T> = {
2454
- [K in keyof T]:
2455
- 0 extends (1 & T[K]) ? T[K] : // any
2456
- T[K] extends unknown[] ? LeanArray<T[K]> : // Array
2457
- T[K] extends Document ? LeanDocument<T[K]> : // Subdocument
2458
- T[K];
2590
+ [K in keyof T]: LeanDocumentElement<T[K]>;
2459
2591
  };
2460
2592
 
2593
+ // Keep this a separate type, to ensure that T is a naked type.
2594
+ // This way, the conditional type is distributive over union types.
2595
+ // This is required for PopulatedDoc.
2596
+ type LeanDocumentElement<T> =
2597
+ 0 extends (1 & T) ? T : // any
2598
+ T extends unknown[] ? LeanArray<T> : // Array
2599
+ T extends Document ? LeanDocument<T> : // Subdocument
2600
+ T;
2601
+
2461
2602
  export type LeanDocument<T> = Omit<_LeanDocument<T>, Exclude<keyof Document, '_id' | 'id' | '__v'> | '$isSingleNested'>;
2462
2603
 
2463
2604
  export type LeanDocumentOrArray<T> = 0 extends (1 & T) ? T :
@@ -2691,7 +2832,6 @@ declare module 'mongoose' {
2691
2832
  constructor(path: string, options?: any, instance?: string);
2692
2833
 
2693
2834
  /** Get/set the function used to cast arbitrary values to this type. */
2694
- // eslint-disable-next-line @typescript-eslint/ban-types
2695
2835
  static cast(caster?: Function | boolean): Function;
2696
2836
 
2697
2837
  static checkRequired(checkRequired?: (v: any) => boolean): (v: any) => boolean;
@@ -2712,7 +2852,6 @@ declare module 'mongoose' {
2712
2852
  default(val: any): any;
2713
2853
 
2714
2854
  /** Adds a getter to this schematype. */
2715
- // eslint-disable-next-line @typescript-eslint/ban-types
2716
2855
  get(fn: Function): this;
2717
2856
 
2718
2857
  /**
@@ -2740,7 +2879,6 @@ declare module 'mongoose' {
2740
2879
  select(val: boolean): this;
2741
2880
 
2742
2881
  /** Adds a setter to this schematype. */
2743
- // eslint-disable-next-line @typescript-eslint/ban-types
2744
2882
  set(fn: Function): this;
2745
2883
 
2746
2884
  /** Declares a sparse index. */
@@ -2756,7 +2894,6 @@ declare module 'mongoose' {
2756
2894
  unique(bool: boolean): this;
2757
2895
 
2758
2896
  /** Adds validator(s) for this document path. */
2759
- // eslint-disable-next-line @typescript-eslint/ban-types
2760
2897
  validate(obj: RegExp | Function | any, errorMsg?: string,
2761
2898
  type?: string): this;
2762
2899
  }
package/lib/aggregate.js CHANGED
@@ -7,6 +7,7 @@
7
7
  const AggregationCursor = require('./cursor/AggregationCursor');
8
8
  const Query = require('./query');
9
9
  const applyGlobalMaxTimeMS = require('./helpers/query/applyGlobalMaxTimeMS');
10
+ const getConstructorName = require('./helpers/getConstructorName');
10
11
  const promiseOrCallback = require('./helpers/promiseOrCallback');
11
12
  const stringifyFunctionOperators = require('./helpers/aggregate/stringifyFunctionOperators');
12
13
  const util = require('util');
@@ -562,7 +563,7 @@ Aggregate.prototype.sort = function(arg) {
562
563
 
563
564
  const sort = {};
564
565
 
565
- if (arg.constructor.name === 'Object') {
566
+ if (getConstructorName(arg) === 'Object') {
566
567
  const desc = ['desc', 'descending', -1];
567
568
  Object.keys(arg).forEach(function(field) {
568
569
  // If sorting by text score, skip coercing into 1/-1
package/lib/cast.js CHANGED
@@ -9,6 +9,7 @@ const StrictModeError = require('./error/strict');
9
9
  const Types = require('./schema/index');
10
10
  const castTextSearch = require('./schema/operators/text');
11
11
  const get = require('./helpers/get');
12
+ const getConstructorName = require('./helpers/getConstructorName');
12
13
  const getSchemaDiscriminatorByValue = require('./helpers/discriminator/getSchemaDiscriminatorByValue');
13
14
  const isOperator = require('./helpers/query/isOperator');
14
15
  const util = require('util');
@@ -267,7 +268,7 @@ module.exports = function cast(schema, obj, options, context) {
267
268
  }
268
269
  } else if (val == null) {
269
270
  continue;
270
- } else if (val.constructor.name === 'Object') {
271
+ } else if (getConstructorName(val) === 'Object') {
271
272
  any$conditionals = Object.keys(val).some(isOperator);
272
273
 
273
274
  if (!any$conditionals) {
package/lib/connection.js CHANGED
@@ -652,7 +652,7 @@ Connection.prototype.onOpen = function() {
652
652
  * @param {String} uri The URI to connect with.
653
653
  * @param {Object} [options] Passed on to http://mongodb.github.io/node-mongodb-native/2.2/api/MongoClient.html#connect
654
654
  * @param {Boolean} [options.bufferCommands=true] Mongoose specific option. Set to false to [disable buffering](http://mongoosejs.com/docs/faq.html#callback_never_executes) on all models associated with this connection.
655
- * @param {Number} [options.bufferTimeoutMS=true] Mongoose specific option. If `bufferCommands` is true, Mongoose will throw an error after `bufferTimeoutMS` if the operation is still buffered.
655
+ * @param {Number} [options.bufferTimeoutMS=10000] Mongoose specific option. If `bufferCommands` is true, Mongoose will throw an error after `bufferTimeoutMS` if the operation is still buffered.
656
656
  * @param {String} [options.dbName] The name of the database we want to use. If not provided, use database name from connection string.
657
657
  * @param {String} [options.user] username for authentication, equivalent to `options.auth.user`. Maintained for backwards compatibility.
658
658
  * @param {String} [options.pass] password for authentication, equivalent to `options.auth.password`. Maintained for backwards compatibility.
@@ -55,6 +55,9 @@ function QueryCursor(query, options) {
55
55
  if (this.options.batchSize) {
56
56
  this.options.cursor = options.cursor || {};
57
57
  this.options.cursor.batchSize = options.batchSize;
58
+
59
+ // Max out the number of documents we'll populate in parallel at 5000.
60
+ this.options._populateBatchSize = Math.min(this.options.batchSize, 5000);
58
61
  }
59
62
  model.collection.find(query._conditions, this.options, function(err, cursor) {
60
63
  if (_this._error) {
@@ -360,7 +363,7 @@ function _next(ctx, cb) {
360
363
  ctx.query._mongooseOptions);
361
364
  ctx._pop.__noPromise = true;
362
365
  }
363
- if (ctx.query._mongooseOptions.populate && ctx.options.batchSize > 1) {
366
+ if (ctx.query._mongooseOptions.populate && ctx.options._populateBatchSize > 1) {
364
367
  if (ctx._batchDocs && ctx._batchDocs.length) {
365
368
  // Return a cached populated doc
366
369
  return _nextDoc(ctx, ctx._batchDocs.shift(), ctx._pop, callback);
@@ -418,7 +421,12 @@ function _onNext(error, doc) {
418
421
 
419
422
  this.ctx._batchDocs.push(doc);
420
423
 
421
- if (this.ctx._batchDocs.length < this.ctx.options.batchSize) {
424
+ if (this.ctx._batchDocs.length < this.ctx.options._populateBatchSize) {
425
+ // If both `batchSize` and `_populateBatchSize` are huge, calling `next()` repeatedly may
426
+ // cause a stack overflow. So make sure we clear the stack regularly.
427
+ if (this.ctx._batchDocs.length > 0 && this.ctx._batchDocs.length % 1000 === 0) {
428
+ return immediate(() => this.ctx.cursor.next(_onNext.bind(this)));
429
+ }
422
430
  this.ctx.cursor.next(_onNext.bind(this));
423
431
  } else {
424
432
  _populateBatch.call(this);
package/lib/document.js CHANGED
@@ -994,6 +994,9 @@ Document.prototype.$set = function $set(path, val, type, options) {
994
994
  delete this._doc[key];
995
995
  // Make sure we set `{}` back even if we minimize re: gh-8565
996
996
  options = Object.assign({}, options, { _skipMinimizeTopLevel: true });
997
+ } else {
998
+ // Make sure we set `{_skipMinimizeTopLevel: false}` if don't have overwrite: gh-10441
999
+ options = Object.assign({}, options, { _skipMinimizeTopLevel: false });
997
1000
  }
998
1001
 
999
1002
  const someCondition = typeof path[key] === 'object' &&
@@ -4143,7 +4146,7 @@ Document.prototype.populated = function(path, val, options) {
4143
4146
  * console.log(doc.author); // '5144cf8050f071d979c118a7'
4144
4147
  * })
4145
4148
  *
4146
- * If the path was not populated, this is a no-op.
4149
+ * If the path was not provided, then all populated fields are returned to their unpopulated state.
4147
4150
  *
4148
4151
  * @param {String} path
4149
4152
  * @return {Document} this
@@ -9,6 +9,7 @@ const MongooseError = require('../../error/mongooseError');
9
9
  const Collection = require('mongodb').Collection;
10
10
  const ObjectId = require('./objectid');
11
11
  const get = require('../../helpers/get');
12
+ const getConstructorName = require('../../helpers/getConstructorName');
12
13
  const sliced = require('sliced');
13
14
  const stream = require('stream');
14
15
  const util = require('util');
@@ -376,14 +377,15 @@ function format(obj, sub, color, shell) {
376
377
 
377
378
  const clone = require('../../helpers/clone');
378
379
  let x = clone(obj, { transform: false });
380
+ const constructorName = getConstructorName(x);
379
381
 
380
- if (x.constructor.name === 'Binary') {
382
+ if (constructorName === 'Binary') {
381
383
  x = 'BinData(' + x.sub_type + ', "' + x.toString('base64') + '")';
382
- } else if (x.constructor.name === 'ObjectID') {
384
+ } else if (constructorName === 'ObjectID') {
383
385
  x = inspectable('ObjectId("' + x.toHexString() + '")');
384
- } else if (x.constructor.name === 'Date') {
386
+ } else if (constructorName === 'Date') {
385
387
  x = inspectable('new Date("' + x.toUTCString() + '")');
386
- } else if (x.constructor.name === 'Object') {
388
+ } else if (constructorName === 'Object') {
387
389
  const keys = Object.keys(x);
388
390
  const numKeys = keys.length;
389
391
  let key;
@@ -402,16 +404,17 @@ function format(obj, sub, color, shell) {
402
404
  error = _error;
403
405
  }
404
406
  }
405
- if (x[key].constructor.name === 'Binary') {
407
+ const _constructorName = getConstructorName(x[key]);
408
+ if (_constructorName === 'Binary') {
406
409
  x[key] = 'BinData(' + x[key].sub_type + ', "' +
407
410
  x[key].buffer.toString('base64') + '")';
408
- } else if (x[key].constructor.name === 'Object') {
411
+ } else if (_constructorName === 'Object') {
409
412
  x[key] = format(x[key], true);
410
- } else if (x[key].constructor.name === 'ObjectID') {
413
+ } else if (_constructorName === 'ObjectID') {
411
414
  formatObjectId(x, key);
412
- } else if (x[key].constructor.name === 'Date') {
415
+ } else if (_constructorName === 'Date') {
413
416
  formatDate(x, key, shell);
414
- } else if (x[key].constructor.name === 'ClientSession') {
417
+ } else if (_constructorName === 'ClientSession') {
415
418
  x[key] = inspectable('ClientSession("' +
416
419
  get(x[key], 'id.id.buffer', '').toString('hex') + '")');
417
420
  } else if (Array.isArray(x[key])) {
@@ -5,6 +5,7 @@
5
5
  'use strict';
6
6
 
7
7
  const MongooseError = require('./mongooseError');
8
+ const getConstructorName = require('../helpers/getConstructorName');
8
9
  const util = require('util');
9
10
 
10
11
  class ValidationError extends MongooseError {
@@ -17,7 +18,7 @@ class ValidationError extends MongooseError {
17
18
  */
18
19
  constructor(instance) {
19
20
  let _message;
20
- if (instance && instance.constructor.name === 'model') {
21
+ if (getConstructorName(instance) === 'model') {
21
22
  _message = instance.constructor.modelName + ' validation failed';
22
23
  } else {
23
24
  _message = 'Validation failed';