mongoose 8.9.1 → 8.9.3
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/browser.umd.js +1 -1
- package/lib/aggregate.js +21 -4
- package/lib/connection.js +1 -1
- package/lib/cursor/queryCursor.js +3 -9
- package/lib/document.js +9 -6
- package/lib/helpers/indexes/isIndexSpecEqual.js +32 -0
- package/lib/model.js +29 -8
- package/lib/query.js +1 -4
- package/lib/schema.js +4 -4
- package/lib/types/map.js +8 -1
- package/lib/utils.js +3 -0
- package/package.json +1 -1
- package/types/index.d.ts +76 -57
- package/types/indexes.d.ts +3 -0
- package/types/models.d.ts +47 -47
- package/types/query.d.ts +49 -49
package/lib/aggregate.js
CHANGED
|
@@ -87,6 +87,24 @@ function Aggregate(pipeline, model) {
|
|
|
87
87
|
|
|
88
88
|
Aggregate.prototype.options;
|
|
89
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Returns default options for this aggregate.
|
|
92
|
+
*
|
|
93
|
+
* @param {Model} model
|
|
94
|
+
* @api private
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
Aggregate.prototype._optionsForExec = function() {
|
|
98
|
+
const options = this.options || {};
|
|
99
|
+
|
|
100
|
+
const asyncLocalStorage = this.model()?.db?.base.transactionAsyncLocalStorage?.getStore();
|
|
101
|
+
if (!options.hasOwnProperty('session') && asyncLocalStorage?.session != null) {
|
|
102
|
+
options.session = asyncLocalStorage.session;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return options;
|
|
106
|
+
};
|
|
107
|
+
|
|
90
108
|
/**
|
|
91
109
|
* Get/set the model that this aggregation will execute on.
|
|
92
110
|
*
|
|
@@ -914,6 +932,7 @@ Aggregate.prototype.option = function(value) {
|
|
|
914
932
|
*/
|
|
915
933
|
|
|
916
934
|
Aggregate.prototype.cursor = function(options) {
|
|
935
|
+
this._optionsForExec();
|
|
917
936
|
this.options.cursor = options || {};
|
|
918
937
|
return new AggregationCursor(this); // return this;
|
|
919
938
|
};
|
|
@@ -1022,10 +1041,7 @@ Aggregate.prototype.exec = async function exec() {
|
|
|
1022
1041
|
applyGlobalMaxTimeMS(this.options, model.db.options, model.base.options);
|
|
1023
1042
|
applyGlobalDiskUse(this.options, model.db.options, model.base.options);
|
|
1024
1043
|
|
|
1025
|
-
|
|
1026
|
-
if (!this.options.hasOwnProperty('session') && asyncLocalStorage?.session != null) {
|
|
1027
|
-
this.options.session = asyncLocalStorage.session;
|
|
1028
|
-
}
|
|
1044
|
+
this._optionsForExec();
|
|
1029
1045
|
|
|
1030
1046
|
if (this.options && this.options.cursor) {
|
|
1031
1047
|
return new AggregationCursor(this);
|
|
@@ -1052,6 +1068,7 @@ Aggregate.prototype.exec = async function exec() {
|
|
|
1052
1068
|
}
|
|
1053
1069
|
|
|
1054
1070
|
const options = clone(this.options || {});
|
|
1071
|
+
|
|
1055
1072
|
let result;
|
|
1056
1073
|
try {
|
|
1057
1074
|
const cursor = await collection.aggregate(this._pipeline, options);
|
package/lib/connection.js
CHANGED
|
@@ -663,7 +663,7 @@ Connection.prototype.withSession = async function withSession(executor) {
|
|
|
663
663
|
*
|
|
664
664
|
* const session = await conn.startSession();
|
|
665
665
|
* let doc = await Person.findOne({ name: 'Ned Stark' }, null, { session });
|
|
666
|
-
* await doc.
|
|
666
|
+
* await doc.deleteOne();
|
|
667
667
|
* // `doc` will always be null, even if reading from a replica set
|
|
668
668
|
* // secondary. Without causal consistency, it is possible to
|
|
669
669
|
* // get a doc back from the below query if the query reads from a
|
|
@@ -557,17 +557,11 @@ function _onNext(error, doc) {
|
|
|
557
557
|
|
|
558
558
|
if (this.ctx._batchDocs.length < this.ctx.options._populateBatchSize) {
|
|
559
559
|
// If both `batchSize` and `_populateBatchSize` are huge, calling `next()` repeatedly may
|
|
560
|
-
// cause a stack overflow. So make sure we clear the stack
|
|
561
|
-
|
|
562
|
-
return immediate(() => this.ctx.cursor.next().then(
|
|
563
|
-
res => { _onNext.call(this, null, res); },
|
|
564
|
-
err => { _onNext.call(this, err); }
|
|
565
|
-
));
|
|
566
|
-
}
|
|
567
|
-
this.ctx.cursor.next().then(
|
|
560
|
+
// cause a stack overflow. So make sure we clear the stack.
|
|
561
|
+
immediate(() => this.ctx.cursor.next().then(
|
|
568
562
|
res => { _onNext.call(this, null, res); },
|
|
569
563
|
err => { _onNext.call(this, err); }
|
|
570
|
-
);
|
|
564
|
+
));
|
|
571
565
|
} else {
|
|
572
566
|
_populateBatch.call(this);
|
|
573
567
|
}
|
package/lib/document.js
CHANGED
|
@@ -2357,17 +2357,17 @@ Document.prototype.$isDefault = function(path) {
|
|
|
2357
2357
|
};
|
|
2358
2358
|
|
|
2359
2359
|
/**
|
|
2360
|
-
* Getter/setter, determines whether the document was
|
|
2360
|
+
* Getter/setter, determines whether the document was deleted. The `Model.prototype.deleteOne()` method sets `$isDeleted` if the delete operation succeeded.
|
|
2361
2361
|
*
|
|
2362
2362
|
* #### Example:
|
|
2363
2363
|
*
|
|
2364
|
-
* const product = await product.
|
|
2364
|
+
* const product = await product.deleteOne();
|
|
2365
2365
|
* product.$isDeleted(); // true
|
|
2366
|
-
* product.
|
|
2366
|
+
* product.deleteOne(); // no-op, doesn't send anything to the db
|
|
2367
2367
|
*
|
|
2368
2368
|
* product.$isDeleted(false);
|
|
2369
2369
|
* product.$isDeleted(); // false
|
|
2370
|
-
* product.
|
|
2370
|
+
* product.deleteOne(); // will execute a remove against the db
|
|
2371
2371
|
*
|
|
2372
2372
|
*
|
|
2373
2373
|
* @param {Boolean} [val] optional, overrides whether mongoose thinks the doc is deleted
|
|
@@ -3703,8 +3703,10 @@ Document.prototype.$getAllSubdocs = function(options) {
|
|
|
3703
3703
|
const subDocs = [];
|
|
3704
3704
|
function getSubdocs(doc) {
|
|
3705
3705
|
const newSubdocs = [];
|
|
3706
|
-
|
|
3707
|
-
|
|
3706
|
+
|
|
3707
|
+
for (const { model } of doc.$__schema.childSchemas) {
|
|
3708
|
+
// Avoid using `childSchemas.path` to avoid compatibility versions with pre-8.8 versions of Mongoose
|
|
3709
|
+
const val = doc.$__getValue(model.path);
|
|
3708
3710
|
if (val == null) {
|
|
3709
3711
|
continue;
|
|
3710
3712
|
}
|
|
@@ -3726,6 +3728,7 @@ Document.prototype.$getAllSubdocs = function(options) {
|
|
|
3726
3728
|
}
|
|
3727
3729
|
}
|
|
3728
3730
|
}
|
|
3731
|
+
|
|
3729
3732
|
for (const subdoc of newSubdocs) {
|
|
3730
3733
|
getSubdocs(subdoc);
|
|
3731
3734
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Compares two index specifications to determine if they are equal.
|
|
5
|
+
*
|
|
6
|
+
* #### Example:
|
|
7
|
+
* isIndexSpecEqual({ a: 1, b: 1 }, { a: 1, b: 1 }); // true
|
|
8
|
+
* isIndexSpecEqual({ a: 1, b: 1 }, { b: 1, a: 1 }); // false
|
|
9
|
+
* isIndexSpecEqual({ a: 1, b: -1 }, { a: 1, b: 1 }); // false
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} spec1 The first index specification to compare.
|
|
12
|
+
* @param {Object} spec2 The second index specification to compare.
|
|
13
|
+
* @returns {Boolean} Returns true if the index specifications are equal, otherwise returns false.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
module.exports = function isIndexSpecEqual(spec1, spec2) {
|
|
17
|
+
const spec1Keys = Object.keys(spec1);
|
|
18
|
+
const spec2Keys = Object.keys(spec2);
|
|
19
|
+
|
|
20
|
+
if (spec1Keys.length !== spec2Keys.length) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
for (let i = 0; i < spec1Keys.length; i++) {
|
|
25
|
+
const key = spec1Keys[i];
|
|
26
|
+
if (key !== spec2Keys[i] || spec1[key] !== spec2[key]) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return true;
|
|
32
|
+
};
|
package/lib/model.js
CHANGED
|
@@ -69,6 +69,7 @@ const util = require('util');
|
|
|
69
69
|
const utils = require('./utils');
|
|
70
70
|
const minimize = require('./helpers/minimize');
|
|
71
71
|
const MongooseBulkSaveIncompleteError = require('./error/bulkSaveIncompleteError');
|
|
72
|
+
const ObjectExpectedError = require('./error/objectExpected');
|
|
72
73
|
|
|
73
74
|
const modelCollectionSymbol = Symbol('mongoose#Model#collection');
|
|
74
75
|
const modelDbSymbol = Symbol('mongoose#Model#db');
|
|
@@ -387,7 +388,11 @@ Model.prototype.$__handleSave = function(options, callback) {
|
|
|
387
388
|
|
|
388
389
|
this[modelCollectionSymbol].updateOne(where, update, saveOptions).then(
|
|
389
390
|
ret => {
|
|
390
|
-
ret
|
|
391
|
+
if (ret == null) {
|
|
392
|
+
ret = { $where: where };
|
|
393
|
+
} else {
|
|
394
|
+
ret.$where = where;
|
|
395
|
+
}
|
|
391
396
|
callback(null, ret);
|
|
392
397
|
},
|
|
393
398
|
err => {
|
|
@@ -694,13 +699,20 @@ Model.prototype.$__where = function _where(where) {
|
|
|
694
699
|
};
|
|
695
700
|
|
|
696
701
|
/**
|
|
697
|
-
* Delete this document from the db.
|
|
702
|
+
* Delete this document from the db. Returns a Query instance containing a `deleteOne` operation by this document's `_id`.
|
|
698
703
|
*
|
|
699
704
|
* #### Example:
|
|
700
705
|
*
|
|
701
706
|
* await product.deleteOne();
|
|
702
707
|
* await Product.findById(product._id); // null
|
|
703
708
|
*
|
|
709
|
+
* Since `deleteOne()` returns a Query, the `deleteOne()` will **not** execute unless you use either `await`, `.then()`, `.catch()`, or [`.exec()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.exec())
|
|
710
|
+
*
|
|
711
|
+
* #### Example:
|
|
712
|
+
*
|
|
713
|
+
* product.deleteOne(); // Doesn't do anything
|
|
714
|
+
* product.deleteOne().exec(); // Deletes the document, returns a promise
|
|
715
|
+
*
|
|
704
716
|
* @return {Query} Query
|
|
705
717
|
* @api public
|
|
706
718
|
*/
|
|
@@ -1879,8 +1891,6 @@ Model.translateAliases = function translateAliases(fields, errorOnDuplicates) {
|
|
|
1879
1891
|
/**
|
|
1880
1892
|
* Deletes the first document that matches `conditions` from the collection.
|
|
1881
1893
|
* It returns an object with the property `deletedCount` indicating how many documents were deleted.
|
|
1882
|
-
* Behaves like `remove()`, but deletes at most one document regardless of the
|
|
1883
|
-
* `single` option.
|
|
1884
1894
|
*
|
|
1885
1895
|
* #### Example:
|
|
1886
1896
|
*
|
|
@@ -1914,8 +1924,6 @@ Model.deleteOne = function deleteOne(conditions, options) {
|
|
|
1914
1924
|
/**
|
|
1915
1925
|
* Deletes all of the documents that match `conditions` from the collection.
|
|
1916
1926
|
* It returns an object with the property `deletedCount` containing the number of documents deleted.
|
|
1917
|
-
* Behaves like `remove()`, but deletes all documents that match `conditions`
|
|
1918
|
-
* regardless of the `single` option.
|
|
1919
1927
|
*
|
|
1920
1928
|
* #### Example:
|
|
1921
1929
|
*
|
|
@@ -2729,7 +2737,7 @@ Model.create = async function create(doc, options) {
|
|
|
2729
2737
|
* // operationType: 'delete',
|
|
2730
2738
|
* // ns: { db: 'mydb', coll: 'Person' },
|
|
2731
2739
|
* // documentKey: { _id: 5a51b125c5500f5aa094c7bd } }
|
|
2732
|
-
* await doc.
|
|
2740
|
+
* await doc.deleteOne();
|
|
2733
2741
|
*
|
|
2734
2742
|
* @param {Array} [pipeline]
|
|
2735
2743
|
* @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#watch)
|
|
@@ -2777,7 +2785,7 @@ Model.watch = function(pipeline, options) {
|
|
|
2777
2785
|
*
|
|
2778
2786
|
* const session = await Person.startSession();
|
|
2779
2787
|
* let doc = await Person.findOne({ name: 'Ned Stark' }, null, { session });
|
|
2780
|
-
* await doc.
|
|
2788
|
+
* await doc.deleteOne();
|
|
2781
2789
|
* // `doc` will always be null, even if reading from a replica set
|
|
2782
2790
|
* // secondary. Without causal consistency, it is possible to
|
|
2783
2791
|
* // get a doc back from the below query if the query reads from a
|
|
@@ -3684,6 +3692,19 @@ Model.castObject = function castObject(obj, options) {
|
|
|
3684
3692
|
}
|
|
3685
3693
|
|
|
3686
3694
|
if (schemaType.$isMongooseDocumentArray) {
|
|
3695
|
+
const castNonArraysOption = schemaType.options?.castNonArrays ?? schemaType.constructor.options.castNonArrays;
|
|
3696
|
+
if (!Array.isArray(val)) {
|
|
3697
|
+
if (!castNonArraysOption) {
|
|
3698
|
+
if (!options.ignoreCastErrors) {
|
|
3699
|
+
error = error || new ValidationError();
|
|
3700
|
+
error.addError(path, new ObjectExpectedError(path, val));
|
|
3701
|
+
}
|
|
3702
|
+
} else {
|
|
3703
|
+
cur[pieces[pieces.length - 1]] = [
|
|
3704
|
+
Model.castObject.call(schemaType.caster, val)
|
|
3705
|
+
];
|
|
3706
|
+
}
|
|
3707
|
+
}
|
|
3687
3708
|
continue;
|
|
3688
3709
|
}
|
|
3689
3710
|
if (schemaType.$isSingleNested || schemaType.$isMongooseDocumentArrayElement) {
|
package/lib/query.js
CHANGED
|
@@ -2247,10 +2247,7 @@ Query.prototype.error = function error(err) {
|
|
|
2247
2247
|
*/
|
|
2248
2248
|
|
|
2249
2249
|
Query.prototype._unsetCastError = function _unsetCastError() {
|
|
2250
|
-
if (this._error == null) {
|
|
2251
|
-
return;
|
|
2252
|
-
}
|
|
2253
|
-
if (this._error != null && !(this._error instanceof CastError)) {
|
|
2250
|
+
if (this._error == null || !(this._error instanceof CastError)) {
|
|
2254
2251
|
return;
|
|
2255
2252
|
}
|
|
2256
2253
|
return this.error(null);
|
package/lib/schema.js
CHANGED
|
@@ -18,13 +18,13 @@ const getConstructorName = require('./helpers/getConstructorName');
|
|
|
18
18
|
const getIndexes = require('./helpers/schema/getIndexes');
|
|
19
19
|
const handleReadPreferenceAliases = require('./helpers/query/handleReadPreferenceAliases');
|
|
20
20
|
const idGetter = require('./helpers/schema/idGetter');
|
|
21
|
+
const isIndexSpecEqual = require('./helpers/indexes/isIndexSpecEqual');
|
|
21
22
|
const merge = require('./helpers/schema/merge');
|
|
22
23
|
const mpath = require('mpath');
|
|
23
24
|
const setPopulatedVirtualValue = require('./helpers/populate/setPopulatedVirtualValue');
|
|
24
25
|
const setupTimestamps = require('./helpers/timestamps/setupTimestamps');
|
|
25
26
|
const utils = require('./utils');
|
|
26
27
|
const validateRef = require('./helpers/populate/validateRef');
|
|
27
|
-
const util = require('util');
|
|
28
28
|
|
|
29
29
|
const hasNumericSubpathRegex = /\.\d+(\.|$)/;
|
|
30
30
|
|
|
@@ -899,7 +899,7 @@ Schema.prototype.removeIndex = function removeIndex(index) {
|
|
|
899
899
|
|
|
900
900
|
if (typeof index === 'object') {
|
|
901
901
|
for (let i = this._indexes.length - 1; i >= 0; --i) {
|
|
902
|
-
if (
|
|
902
|
+
if (isIndexSpecEqual(this._indexes[i][0], index)) {
|
|
903
903
|
this._indexes.splice(i, 1);
|
|
904
904
|
}
|
|
905
905
|
}
|
|
@@ -2147,8 +2147,8 @@ Schema.prototype.index = function(fields, options) {
|
|
|
2147
2147
|
}
|
|
2148
2148
|
|
|
2149
2149
|
for (const existingIndex of this.indexes()) {
|
|
2150
|
-
if (
|
|
2151
|
-
|
|
2150
|
+
if (options.name == null && existingIndex[1].name == null && isIndexSpecEqual(existingIndex[0], fields)) {
|
|
2151
|
+
utils.warn(`Duplicate schema index on ${JSON.stringify(fields)} found. This is often due to declaring an index using both "index: true" and "schema.index()". Please remove the duplicate index definition.`);
|
|
2152
2152
|
}
|
|
2153
2153
|
}
|
|
2154
2154
|
|
package/lib/types/map.js
CHANGED
|
@@ -9,6 +9,7 @@ const handleSpreadDoc = require('../helpers/document/handleSpreadDoc');
|
|
|
9
9
|
const util = require('util');
|
|
10
10
|
const specialProperties = require('../helpers/specialProperties');
|
|
11
11
|
const isBsonType = require('../helpers/isBsonType');
|
|
12
|
+
const cleanModifiedSubpaths = require('../helpers/document/cleanModifiedSubpaths');
|
|
12
13
|
|
|
13
14
|
const populateModelSymbol = require('../helpers/symbols').populateModelSymbol;
|
|
14
15
|
|
|
@@ -157,7 +158,13 @@ class MongooseMap extends Map {
|
|
|
157
158
|
super.set(key, value);
|
|
158
159
|
|
|
159
160
|
if (parent != null && parent.$__ != null && !deepEqual(value, priorVal)) {
|
|
160
|
-
|
|
161
|
+
const path = fullPath.call(this);
|
|
162
|
+
parent.markModified(path);
|
|
163
|
+
// If overwriting the full document array or subdoc, make sure to clean up any paths that were modified
|
|
164
|
+
// before re: #15108
|
|
165
|
+
if (this.$__schemaType.$isMongooseDocumentArray || this.$__schemaType.$isSingleNested) {
|
|
166
|
+
cleanModifiedSubpaths(parent, path);
|
|
167
|
+
}
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
// Delay calculating full path unless absolutely necessary, because string
|
package/lib/utils.js
CHANGED
|
@@ -631,6 +631,9 @@ exports.getValue = function(path, obj, map) {
|
|
|
631
631
|
const mapGetterOptions = Object.freeze({ getters: false });
|
|
632
632
|
|
|
633
633
|
function getValueLookup(obj, part) {
|
|
634
|
+
if (part === '$*' && obj instanceof Map) {
|
|
635
|
+
return obj;
|
|
636
|
+
}
|
|
634
637
|
let _from = obj?._doc || obj;
|
|
635
638
|
if (_from != null && _from.isMongooseArrayProxy) {
|
|
636
639
|
_from = _from.__array;
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -491,7 +491,7 @@ declare module 'mongoose' {
|
|
|
491
491
|
remove(paths: string | Array<string>): this;
|
|
492
492
|
|
|
493
493
|
/** Removes index by name or index spec */
|
|
494
|
-
|
|
494
|
+
removeIndex(index: string | AnyObject): this;
|
|
495
495
|
|
|
496
496
|
/** Returns an Array of path strings that are required by this schema. */
|
|
497
497
|
requiredPaths(invalidate?: boolean): string[];
|
|
@@ -572,7 +572,8 @@ declare module 'mongoose' {
|
|
|
572
572
|
| typeof Schema.Types.Number
|
|
573
573
|
| typeof Schema.Types.String
|
|
574
574
|
| typeof Schema.Types.Buffer
|
|
575
|
-
| typeof Schema.Types.ObjectId
|
|
575
|
+
| typeof Schema.Types.ObjectId
|
|
576
|
+
| typeof Schema.Types.UUID;
|
|
576
577
|
|
|
577
578
|
|
|
578
579
|
export type InferId<T> = T extends { _id?: any } ? T['_id'] : Types.ObjectId;
|
|
@@ -712,77 +713,95 @@ declare module 'mongoose' {
|
|
|
712
713
|
/**
|
|
713
714
|
* Converts any Buffer properties into mongodb.Binary instances, which is what `lean()` returns
|
|
714
715
|
*/
|
|
715
|
-
export type BufferToBinary<T> = T extends
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
716
|
+
export type BufferToBinary<T> = T extends Buffer
|
|
717
|
+
? mongodb.Binary
|
|
718
|
+
: T extends Document
|
|
719
|
+
? T
|
|
720
|
+
: T extends TreatAsPrimitives
|
|
721
|
+
? T
|
|
722
|
+
: T extends Record<string, any> ? {
|
|
723
|
+
[K in keyof T]: T[K] extends Buffer
|
|
724
|
+
? mongodb.Binary
|
|
725
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
726
|
+
? Types.DocumentArray<BufferToBinary<ItemType>>
|
|
727
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
728
|
+
? HydratedSingleSubdocument<BufferToBinary<SubdocType>>
|
|
729
|
+
: BufferToBinary<T[K]>;
|
|
730
|
+
} : T;
|
|
726
731
|
|
|
727
732
|
/**
|
|
728
733
|
* Converts any Buffer properties into { type: 'buffer', data: [1, 2, 3] } format for JSON serialization
|
|
729
734
|
*/
|
|
730
|
-
export type BufferToJSON<T> = T extends
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
735
|
+
export type BufferToJSON<T> = T extends Buffer
|
|
736
|
+
? { type: 'buffer', data: number[] }
|
|
737
|
+
: T extends Document
|
|
738
|
+
? T
|
|
739
|
+
: T extends TreatAsPrimitives
|
|
740
|
+
? T
|
|
741
|
+
: T extends Record<string, any> ? {
|
|
742
|
+
[K in keyof T]: T[K] extends Buffer
|
|
743
|
+
? { type: 'buffer', data: number[] }
|
|
744
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
745
|
+
? Types.DocumentArray<BufferToBinary<ItemType>>
|
|
746
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
747
|
+
? HydratedSingleSubdocument<SubdocType>
|
|
748
|
+
: BufferToBinary<T[K]>;
|
|
749
|
+
} : T;
|
|
741
750
|
|
|
742
751
|
/**
|
|
743
752
|
* Converts any ObjectId properties into strings for JSON serialization
|
|
744
753
|
*/
|
|
745
|
-
export type ObjectIdToString<T> = T extends
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
754
|
+
export type ObjectIdToString<T> = T extends mongodb.ObjectId
|
|
755
|
+
? string
|
|
756
|
+
: T extends Document
|
|
757
|
+
? T
|
|
758
|
+
: T extends TreatAsPrimitives
|
|
759
|
+
? T
|
|
760
|
+
: T extends Record<string, any> ? {
|
|
761
|
+
[K in keyof T]: T[K] extends mongodb.ObjectId
|
|
762
|
+
? string
|
|
763
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
764
|
+
? Types.DocumentArray<ObjectIdToString<ItemType>>
|
|
765
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
766
|
+
? HydratedSingleSubdocument<ObjectIdToString<SubdocType>>
|
|
767
|
+
: ObjectIdToString<T[K]>;
|
|
768
|
+
} : T;
|
|
756
769
|
|
|
757
770
|
/**
|
|
758
771
|
* Converts any Date properties into strings for JSON serialization
|
|
759
772
|
*/
|
|
760
|
-
export type DateToString<T> = T extends
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
773
|
+
export type DateToString<T> = T extends NativeDate
|
|
774
|
+
? string
|
|
775
|
+
: T extends Document
|
|
776
|
+
? T
|
|
777
|
+
: T extends TreatAsPrimitives
|
|
778
|
+
? T
|
|
779
|
+
: T extends Record<string, any> ? {
|
|
780
|
+
[K in keyof T]: T[K] extends NativeDate
|
|
781
|
+
? string
|
|
782
|
+
: T[K] extends (NativeDate | null | undefined)
|
|
783
|
+
? string | null | undefined
|
|
784
|
+
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
785
|
+
? Types.DocumentArray<DateToString<ItemType>>
|
|
786
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
787
|
+
? HydratedSingleSubdocument<DateToString<SubdocType>>
|
|
788
|
+
: DateToString<T[K]>;
|
|
789
|
+
} : T;
|
|
771
790
|
|
|
772
791
|
/**
|
|
773
792
|
* Converts any Mongoose subdocuments (single nested or doc arrays) into POJO equivalents
|
|
774
793
|
*/
|
|
775
|
-
export type SubdocsToPOJOs<T> = T extends
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
: T[K] extends Types.DocumentArray<infer ItemType>
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
794
|
+
export type SubdocsToPOJOs<T> = T extends Document
|
|
795
|
+
? T
|
|
796
|
+
: T extends TreatAsPrimitives
|
|
797
|
+
? T
|
|
798
|
+
: T extends Record<string, any> ? {
|
|
799
|
+
[K in keyof T]: T[K] extends Types.DocumentArray<infer ItemType>
|
|
800
|
+
? ItemType[]
|
|
801
|
+
: T[K] extends Types.Subdocument<unknown, unknown, infer SubdocType>
|
|
802
|
+
? SubdocType
|
|
803
|
+
: SubdocsToPOJOs<T[K]>;
|
|
804
|
+
} : T;
|
|
786
805
|
|
|
787
806
|
export type JSONSerialized<T> = SubdocsToPOJOs<
|
|
788
807
|
FlattenMaps<
|
package/types/indexes.d.ts
CHANGED
|
@@ -10,6 +10,9 @@ declare module 'mongoose' {
|
|
|
10
10
|
function syncIndexes(options?: SyncIndexesOptions): Promise<ConnectionSyncIndexesResult>;
|
|
11
11
|
|
|
12
12
|
interface IndexManager {
|
|
13
|
+
/* Deletes all indexes that aren't defined in this model's schema. Used by `syncIndexes()`. Returns list of dropped index names. */
|
|
14
|
+
cleanIndexes(options?: { toDrop?: string[], hideIndexes?: boolean }): Promise<string[]>;
|
|
15
|
+
|
|
13
16
|
/**
|
|
14
17
|
* Similar to `ensureIndexes()`, except for it uses the [`createIndex`](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#createIndex)
|
|
15
18
|
* function.
|