mongoose 9.9.0 → 9.9.2
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/lib/connection.js +3 -0
- package/lib/document.js +26 -55
- package/lib/helpers/pathTrie.js +167 -0
- package/lib/model.js +9 -0
- package/lib/plugins/trackTransaction.js +25 -10
- package/lib/query.js +8 -7
- package/lib/queryHelpers.js +22 -0
- package/lib/schema/number.js +1 -1
- package/lib/schema/string.js +1 -1
- package/lib/schema.js +7 -14
- package/lib/schemaType.js +21 -0
- package/lib/utils.js +5 -15
- package/package.json +11 -11
- package/types/document.d.ts +4 -4
- package/types/index.d.ts +25 -0
- package/types/models.d.ts +133 -4
- package/types/schematypes.d.ts +1 -1
package/lib/connection.js
CHANGED
|
@@ -778,6 +778,9 @@ function _resetSessionDocuments(session) {
|
|
|
778
778
|
if (Object.hasOwn(state, 'versionKey')) {
|
|
779
779
|
doc.set(doc.schema.options.versionKey, state.versionKey);
|
|
780
780
|
}
|
|
781
|
+
if (Object.hasOwn(state, 'isDeleted')) {
|
|
782
|
+
doc.$isDeleted(state.isDeleted);
|
|
783
|
+
}
|
|
781
784
|
|
|
782
785
|
for (const path of state.modifiedPaths) {
|
|
783
786
|
doc.$__.activePaths.modify(path);
|
package/lib/document.js
CHANGED
|
@@ -14,6 +14,7 @@ const ModifiedPathsSnapshot = require('./modifiedPathsSnapshot');
|
|
|
14
14
|
const ObjectExpectedError = require('./error/objectExpected');
|
|
15
15
|
const ObjectParameterError = require('./error/objectParameter');
|
|
16
16
|
const ParallelValidateError = require('./error/parallelValidate');
|
|
17
|
+
const PathTrie = require('./helpers/pathTrie');
|
|
17
18
|
const Schema = require('./schema');
|
|
18
19
|
const StrictModeError = require('./error/strict');
|
|
19
20
|
const ValidationError = require('./error/validation');
|
|
@@ -31,7 +32,6 @@ const getEmbeddedDiscriminatorPath = require('./helpers/document/getEmbeddedDisc
|
|
|
31
32
|
const getKeysInSchemaOrder = require('./helpers/schema/getKeysInSchemaOrder');
|
|
32
33
|
const getSubdocumentStrictValue = require('./helpers/schema/getSubdocumentStrictValue');
|
|
33
34
|
const handleSpreadDoc = require('./helpers/document/handleSpreadDoc');
|
|
34
|
-
const isBsonType = require('./helpers/isBsonType');
|
|
35
35
|
const isDefiningProjection = require('./helpers/projection/isDefiningProjection');
|
|
36
36
|
const isExclusive = require('./helpers/projection/isExclusive');
|
|
37
37
|
const isPathExcluded = require('./helpers/projection/isPathExcluded');
|
|
@@ -5242,26 +5242,26 @@ Document.prototype.$__delta = function $__delta(pathsToSave, pathsToSaveSet) {
|
|
|
5242
5242
|
const optimisticConcurrency = this.$__schema.options.optimisticConcurrency;
|
|
5243
5243
|
if (optimisticConcurrency) {
|
|
5244
5244
|
if (Array.isArray(optimisticConcurrency)) {
|
|
5245
|
-
if (!this.$__schema.options.
|
|
5246
|
-
this.$__schema.options.
|
|
5245
|
+
if (!this.$__schema.options._optimisticConcurrencyTrie) {
|
|
5246
|
+
this.$__schema.options._optimisticConcurrencyTrie = new PathTrie(optimisticConcurrency);
|
|
5247
5247
|
}
|
|
5248
|
-
const
|
|
5248
|
+
const optimisticConcurrencyTrie = this.$__schema.options._optimisticConcurrencyTrie;
|
|
5249
5249
|
const modPaths = this.directModifiedPaths();
|
|
5250
5250
|
const hasRelevantModPaths = pathsToSave == null ?
|
|
5251
|
-
modPaths.find(path =>
|
|
5252
|
-
modPaths.find(path =>
|
|
5251
|
+
modPaths.find(path => optimisticConcurrencyTrie.overlapsPath(path.indexOf('.') === -1 ? path : path.split('.'))) :
|
|
5252
|
+
modPaths.find(path => optimisticConcurrencyTrie.overlapsPath(path.indexOf('.') === -1 ? path : path.split('.')) && isInPathsToSave(path, pathsToSaveSet, pathsToSave));
|
|
5253
5253
|
if (hasRelevantModPaths) {
|
|
5254
5254
|
this.$__.version = dirty.length ? VERSION_ALL : VERSION_WHERE;
|
|
5255
5255
|
}
|
|
5256
5256
|
} else if (Array.isArray(optimisticConcurrency?.exclude)) {
|
|
5257
|
-
if (!this.$__schema.options.
|
|
5258
|
-
this.$__schema.options.
|
|
5257
|
+
if (!this.$__schema.options._optimisticConcurrencyExcludeTrie) {
|
|
5258
|
+
this.$__schema.options._optimisticConcurrencyExcludeTrie = new PathTrie(optimisticConcurrency.exclude);
|
|
5259
5259
|
}
|
|
5260
|
-
const
|
|
5260
|
+
const optimisticConcurrencyExcludeTrie = this.$__schema.options._optimisticConcurrencyExcludeTrie;
|
|
5261
5261
|
const modPaths = this.directModifiedPaths();
|
|
5262
5262
|
const hasRelevantModPaths = pathsToSave == null ?
|
|
5263
|
-
modPaths.find(path => !
|
|
5264
|
-
modPaths.find(path => !
|
|
5263
|
+
modPaths.find(path => !optimisticConcurrencyExcludeTrie.matchesPathOrAncestor(path.indexOf('.') === -1 ? path : path.split('.'))) :
|
|
5264
|
+
modPaths.find(path => !optimisticConcurrencyExcludeTrie.matchesPathOrAncestor(path.indexOf('.') === -1 ? path : path.split('.')) && isInPathsToSave(path, pathsToSaveSet, pathsToSave));
|
|
5265
5265
|
if (hasRelevantModPaths) {
|
|
5266
5266
|
this.$__.version = dirty.length ? VERSION_ALL : VERSION_WHERE;
|
|
5267
5267
|
}
|
|
@@ -5755,11 +5755,21 @@ Document.prototype.$__hasOnlyPrimitiveValues = function $__hasOnlyPrimitiveValue
|
|
|
5755
5755
|
const doc = this._doc;
|
|
5756
5756
|
for (const key in doc) {
|
|
5757
5757
|
const v = doc[key];
|
|
5758
|
-
if (v == null
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
5758
|
+
if (v == null || typeof v !== 'object') {
|
|
5759
|
+
continue;
|
|
5760
|
+
}
|
|
5761
|
+
// Equivalent to `isNativeObject(v) && !Array.isArray(v)`, plus the
|
|
5762
|
+
// `isBsonType()` checks below, but without the helper calls or the
|
|
5763
|
+
// repeated `Array.isArray()`. This runs for every key of every document
|
|
5764
|
+
// that `toObject()` touches, so the call overhead is measurable.
|
|
5765
|
+
if (Array.isArray(v)) {
|
|
5766
|
+
return false;
|
|
5767
|
+
}
|
|
5768
|
+
if (v instanceof Date || v instanceof Boolean || v instanceof Number || v instanceof String) {
|
|
5769
|
+
continue;
|
|
5770
|
+
}
|
|
5771
|
+
const bsontype = v._bsontype;
|
|
5772
|
+
if (bsontype === 'ObjectId' || bsontype === 'Decimal128') {
|
|
5763
5773
|
continue;
|
|
5764
5774
|
}
|
|
5765
5775
|
return false;
|
|
@@ -5787,45 +5797,6 @@ Document.prototype._applyVersionIncrement = function _applyVersionIncrement() {
|
|
|
5787
5797
|
* Module exports.
|
|
5788
5798
|
*/
|
|
5789
5799
|
|
|
5790
|
-
/*!
|
|
5791
|
-
* Check if `path` or any of its ancestor paths exist in `pathSet`.
|
|
5792
|
-
* For example:
|
|
5793
|
-
* _pathOrAncestorInSet('profile.firstName', Set(['profile'])) === true
|
|
5794
|
-
* _pathOrAncestorInSet('profile', Set(['profile.firstName'])) === false
|
|
5795
|
-
*/
|
|
5796
|
-
function _pathOrAncestorInSet(path, pathSet) {
|
|
5797
|
-
if (pathSet.has(path)) {
|
|
5798
|
-
return true;
|
|
5799
|
-
}
|
|
5800
|
-
let idx = path.indexOf('.');
|
|
5801
|
-
while (idx !== -1) {
|
|
5802
|
-
if (pathSet.has(path.substring(0, idx))) {
|
|
5803
|
-
return true;
|
|
5804
|
-
}
|
|
5805
|
-
idx = path.indexOf('.', idx + 1);
|
|
5806
|
-
}
|
|
5807
|
-
return false;
|
|
5808
|
-
}
|
|
5809
|
-
|
|
5810
|
-
/*!
|
|
5811
|
-
* Check if `path`, any of its ancestor paths, or any of its descendant paths
|
|
5812
|
-
* exist in `pathSet`.
|
|
5813
|
-
* For example:
|
|
5814
|
-
* _pathOverlapsSet('profile.firstName', Set(['profile'])) === true
|
|
5815
|
-
* _pathOverlapsSet('profile', Set(['profile.firstName'])) === true
|
|
5816
|
-
*/
|
|
5817
|
-
function _pathOverlapsSet(path, pathSet) {
|
|
5818
|
-
if (_pathOrAncestorInSet(path, pathSet)) {
|
|
5819
|
-
return true;
|
|
5820
|
-
}
|
|
5821
|
-
for (const p of pathSet) {
|
|
5822
|
-
if (p.length > path.length + 1 && p[path.length] === '.' && p.slice(0, path.length) === path) {
|
|
5823
|
-
return true;
|
|
5824
|
-
}
|
|
5825
|
-
}
|
|
5826
|
-
return false;
|
|
5827
|
-
}
|
|
5828
|
-
|
|
5829
5800
|
Document.VERSION_WHERE = VERSION_WHERE;
|
|
5830
5801
|
Document.VERSION_INC = VERSION_INC;
|
|
5831
5802
|
Document.VERSION_ALL = VERSION_ALL;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const wildcardSegment = '$*';
|
|
4
|
+
const numericSegmentRegex = /^\d+$/;
|
|
5
|
+
|
|
6
|
+
class PathTrieNode {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.children = new Map();
|
|
9
|
+
this.terminal = false;
|
|
10
|
+
this.hasWildcard = false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Trie of dotted paths for efficient path matching. Supports the map wildcard
|
|
16
|
+
* segment `$*`, which matches any single segment. For example, a trie
|
|
17
|
+
* containing `settings.$*` matches `settings.theme` but not `settings` or
|
|
18
|
+
* `profile.theme`. In array lookups, numeric segments like array indexes are
|
|
19
|
+
* ignorable: a trie containing `comments.text` matches `comments.0.text`.
|
|
20
|
+
* Single-segment string lookups skip the numeric check entirely.
|
|
21
|
+
*
|
|
22
|
+
* @api private
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
class PathTrie {
|
|
26
|
+
/**
|
|
27
|
+
* @param {string[]} [paths] paths to add to the trie
|
|
28
|
+
*/
|
|
29
|
+
constructor(paths) {
|
|
30
|
+
this.root = new PathTrieNode();
|
|
31
|
+
if (paths != null) {
|
|
32
|
+
for (const path of paths) {
|
|
33
|
+
this.add(path);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Add a dotted path, like `settings.$*` or `profile.firstName`, to the trie.
|
|
40
|
+
*
|
|
41
|
+
* @param {string} path
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
add(path) {
|
|
45
|
+
if (path.indexOf('.') === -1) {
|
|
46
|
+
this._addSegment(this.root, path).terminal = true;
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
let node = this.root;
|
|
50
|
+
for (const segment of path.split('.')) {
|
|
51
|
+
node = this._addSegment(node, segment);
|
|
52
|
+
}
|
|
53
|
+
node.terminal = true;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @param {PathTrieNode} node
|
|
58
|
+
* @param {string} segment
|
|
59
|
+
*/
|
|
60
|
+
_addSegment(node, segment) {
|
|
61
|
+
let child = node.children.get(segment);
|
|
62
|
+
if (child == null) {
|
|
63
|
+
child = new PathTrieNode();
|
|
64
|
+
node.children.set(segment, child);
|
|
65
|
+
if (segment === wildcardSegment) {
|
|
66
|
+
node.hasWildcard = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return child;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if `path` or any of its ancestor paths exist in the trie. `path` is
|
|
74
|
+
* either a single segment string or a pre-split array of segments — lookups
|
|
75
|
+
* never split, callers are responsible for splitting dotted paths.
|
|
76
|
+
* For example, with a trie containing 'profile':
|
|
77
|
+
* matchesPathOrAncestor(['profile', 'firstName']) === true
|
|
78
|
+
* matchesPathOrAncestor('profile') === true
|
|
79
|
+
* But with a trie containing 'profile.firstName':
|
|
80
|
+
* matchesPathOrAncestor('profile') === false
|
|
81
|
+
*
|
|
82
|
+
* @param {string|string[]} path
|
|
83
|
+
*/
|
|
84
|
+
|
|
85
|
+
matchesPathOrAncestor(path) {
|
|
86
|
+
return this._walk(path) === true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Check if `path`, any of its ancestor paths, or any of its descendant paths
|
|
91
|
+
* exist in the trie. `path` is either a single segment string or a pre-split
|
|
92
|
+
* array of segments — lookups never split, callers are responsible for
|
|
93
|
+
* splitting dotted paths. For example:
|
|
94
|
+
* new PathTrie(['profile']).overlapsPath(['profile', 'firstName']) === true
|
|
95
|
+
* new PathTrie(['profile.firstName']).overlapsPath('profile') === true
|
|
96
|
+
*
|
|
97
|
+
* @param {string|string[]} path
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
overlapsPath(path) {
|
|
101
|
+
return this._walk(path) !== false;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Walk `path` through the trie. `path` is assumed to be pre-split - if the
|
|
106
|
+
* path has multiple segments, pass in an array of strings. Returns `true` if
|
|
107
|
+
* a terminal node was found at `path` or one of its ancestors, `false` if the
|
|
108
|
+
* walk dead-ended, and the array of reached nodes if `path` is a strict prefix
|
|
109
|
+
* of entries in the trie.
|
|
110
|
+
*
|
|
111
|
+
* @param {string|string[]} path
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
_walk(path) {
|
|
115
|
+
if (typeof path === 'string') {
|
|
116
|
+
const next = [];
|
|
117
|
+
const literal = this.root.children.get(path);
|
|
118
|
+
if (literal != null) {
|
|
119
|
+
if (literal.terminal) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
next.push(literal);
|
|
123
|
+
}
|
|
124
|
+
if (this.root.hasWildcard) {
|
|
125
|
+
const wildcard = this.root.children.get(wildcardSegment);
|
|
126
|
+
if (wildcard.terminal) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
next.push(wildcard);
|
|
130
|
+
}
|
|
131
|
+
return next.length === 0 ? false : next;
|
|
132
|
+
}
|
|
133
|
+
let nodes = [this.root];
|
|
134
|
+
for (const segment of path) {
|
|
135
|
+
const next = [];
|
|
136
|
+
const isNumericSegment = numericSegmentRegex.test(segment);
|
|
137
|
+
for (const node of nodes) {
|
|
138
|
+
if (isNumericSegment) {
|
|
139
|
+
// Numeric segments like array indexes are ignorable: `comments.text`
|
|
140
|
+
// in the trie matches the modified path `comments.0.text`.
|
|
141
|
+
next.push(node);
|
|
142
|
+
}
|
|
143
|
+
const literal = node.children.get(segment);
|
|
144
|
+
if (literal != null) {
|
|
145
|
+
if (literal.terminal) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
next.push(literal);
|
|
149
|
+
}
|
|
150
|
+
if (node.hasWildcard) {
|
|
151
|
+
const wildcard = node.children.get(wildcardSegment);
|
|
152
|
+
if (wildcard.terminal) {
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
next.push(wildcard);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (next.length === 0) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
nodes = next;
|
|
162
|
+
}
|
|
163
|
+
return nodes;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
module.exports = PathTrie;
|
package/lib/model.js
CHANGED
|
@@ -3622,6 +3622,15 @@ Model.bulkSave = async function bulkSave(documents, options) {
|
|
|
3622
3622
|
}
|
|
3623
3623
|
}
|
|
3624
3624
|
|
|
3625
|
+
// Associate the documents with the session like `save()` does, so built-in
|
|
3626
|
+
// `pre('save')` middleware like `trackTransaction` can snapshot document
|
|
3627
|
+
// state and restore it between transaction retries. Re: gh-16432
|
|
3628
|
+
if (Object.hasOwn(options, 'session')) {
|
|
3629
|
+
for (const document of documents) {
|
|
3630
|
+
document.$session(options.session);
|
|
3631
|
+
}
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3625
3634
|
await Promise.all(documents.map(doc => buildPreSavePromise(doc, options)));
|
|
3626
3635
|
|
|
3627
3636
|
const writeOperations = this.buildBulkWriteOperations(documents, options);
|
|
@@ -7,31 +7,45 @@ const utils = require('../utils');
|
|
|
7
7
|
|
|
8
8
|
module.exports = function trackTransaction(schema) {
|
|
9
9
|
schema.pre('save', trackTransactionPreSave);
|
|
10
|
+
schema.pre('deleteOne', { document: true, query: false }, trackTransactionPreDeleteOne);
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
function trackTransactionPreSave() {
|
|
13
|
-
|
|
14
|
+
_getInitialState(this);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function trackTransactionPreDeleteOne() {
|
|
18
|
+
const initialState = _getInitialState(this);
|
|
19
|
+
if (initialState != null && !Object.hasOwn(initialState, 'isDeleted')) {
|
|
20
|
+
initialState.isDeleted = this.$isDeleted();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function _getInitialState(doc) {
|
|
25
|
+
const session = doc.$session();
|
|
14
26
|
if (session == null) {
|
|
15
|
-
return;
|
|
27
|
+
return null;
|
|
16
28
|
}
|
|
17
29
|
if (session.transaction == null || session[sessionNewDocuments] == null) {
|
|
18
|
-
return;
|
|
30
|
+
return null;
|
|
19
31
|
}
|
|
20
32
|
|
|
21
|
-
if (!session[sessionNewDocuments].has(
|
|
33
|
+
if (!session[sessionNewDocuments].has(doc)) {
|
|
22
34
|
const initialState = {};
|
|
23
|
-
if (
|
|
35
|
+
if (doc.isNew) {
|
|
24
36
|
initialState.isNew = true;
|
|
25
37
|
}
|
|
26
|
-
if (
|
|
27
|
-
initialState.versionKey =
|
|
38
|
+
if (doc.$__schema.options.versionKey) {
|
|
39
|
+
initialState.versionKey = doc.get(doc.$__schema.options.versionKey);
|
|
28
40
|
}
|
|
29
41
|
|
|
30
|
-
initialState.modifiedPaths = new Set(Object.keys(
|
|
31
|
-
initialState.atomics = _getAtomics(
|
|
42
|
+
initialState.modifiedPaths = new Set(Object.keys(doc.$__.activePaths.getStatePaths('modify')));
|
|
43
|
+
initialState.atomics = _getAtomics(doc);
|
|
32
44
|
|
|
33
|
-
session[sessionNewDocuments].set(
|
|
45
|
+
session[sessionNewDocuments].set(doc, initialState);
|
|
34
46
|
}
|
|
47
|
+
|
|
48
|
+
return session[sessionNewDocuments].get(doc);
|
|
35
49
|
}
|
|
36
50
|
|
|
37
51
|
function _getAtomics(doc, previous) {
|
|
@@ -87,3 +101,4 @@ function mergeAtomics(destination, source) {
|
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
trackTransactionPreSave[symbols.builtInMiddleware] = true;
|
|
104
|
+
trackTransactionPreDeleteOne[symbols.builtInMiddleware] = true;
|
package/lib/query.js
CHANGED
|
@@ -2849,12 +2849,7 @@ Query.prototype.findOne = function(conditions, projection, options) {
|
|
|
2849
2849
|
|
|
2850
2850
|
Query.prototype._countDocuments = async function _countDocuments() {
|
|
2851
2851
|
this._applyTranslateAliases();
|
|
2852
|
-
|
|
2853
|
-
try {
|
|
2854
|
-
this.cast(this.model);
|
|
2855
|
-
} catch (err) {
|
|
2856
|
-
this.error(err);
|
|
2857
|
-
}
|
|
2852
|
+
this._castConditions();
|
|
2858
2853
|
|
|
2859
2854
|
if (this.error()) {
|
|
2860
2855
|
throw this.error();
|
|
@@ -5377,11 +5372,17 @@ Query.prototype.cursor = function cursor(opts) {
|
|
|
5377
5372
|
}
|
|
5378
5373
|
|
|
5379
5374
|
try {
|
|
5380
|
-
this.
|
|
5375
|
+
this._castConditions();
|
|
5381
5376
|
} catch (err) {
|
|
5377
|
+
// `_castConditions()` reports cast errors on the query, but `sanitizeFilter`
|
|
5378
|
+
// throws for filters it refuses outright, like `$where`.
|
|
5382
5379
|
return (new QueryCursor(this))._markError(err);
|
|
5383
5380
|
}
|
|
5384
5381
|
|
|
5382
|
+
if (this.error()) {
|
|
5383
|
+
return (new QueryCursor(this))._markError(this.error());
|
|
5384
|
+
}
|
|
5385
|
+
|
|
5385
5386
|
return new QueryCursor(this);
|
|
5386
5387
|
};
|
|
5387
5388
|
|
package/lib/queryHelpers.js
CHANGED
|
@@ -209,6 +209,13 @@ exports.applyPaths = function applyPaths(fields, schema, sanitizeProjection) {
|
|
|
209
209
|
switch (exclude) {
|
|
210
210
|
case true:
|
|
211
211
|
for (const fieldName of excluded) {
|
|
212
|
+
// Skip if an ancestor path is already excluded in `fields` (for
|
|
213
|
+
// example the user did `.select('-subd')` and `subd.raw` has
|
|
214
|
+
// schema-level `select: false`) to avoid MongoDB's "Path collision"
|
|
215
|
+
// error from projecting both `subd` and `subd.raw`. See gh-12798
|
|
216
|
+
if (hasExcludedAncestor(fields, fieldName)) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
212
219
|
fields[fieldName] = 0;
|
|
213
220
|
}
|
|
214
221
|
break;
|
|
@@ -372,6 +379,21 @@ exports.applyPaths = function applyPaths(fields, schema, sanitizeProjection) {
|
|
|
372
379
|
(type.selected ? selected : excluded).push(path);
|
|
373
380
|
return path;
|
|
374
381
|
}
|
|
382
|
+
|
|
383
|
+
function hasExcludedAncestor(fields, path) {
|
|
384
|
+
let i = -1;
|
|
385
|
+
while ((i = path.indexOf('.', i + 1)) !== -1) {
|
|
386
|
+
const ancestor = fields[path.slice(0, i)];
|
|
387
|
+
// Any falsy defining value (`0`, `false`, `''`, `NaN`) excludes a
|
|
388
|
+
// path, matching how `exclude` itself is derived above (`!field`).
|
|
389
|
+
// `ancestor == null` means the key isn't present at all, which is
|
|
390
|
+
// not an exclusion. See gh-12798
|
|
391
|
+
if (ancestor != null && !ancestor) {
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
375
397
|
};
|
|
376
398
|
|
|
377
399
|
/**
|
package/lib/schema/number.js
CHANGED
|
@@ -498,7 +498,7 @@ SchemaNumber.prototype.castForQuery = function($conditional, val, context) {
|
|
|
498
498
|
*/
|
|
499
499
|
|
|
500
500
|
SchemaNumber.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
501
|
-
return this._createJSONSchemaTypeDefinition('number', 'number', options);
|
|
501
|
+
return this._addJSONSchemaEnum(this._createJSONSchemaTypeDefinition('number', 'number', options));
|
|
502
502
|
};
|
|
503
503
|
|
|
504
504
|
/*!
|
package/lib/schema/string.js
CHANGED
|
@@ -719,7 +719,7 @@ SchemaString.prototype.castForQuery = function($conditional, val, context) {
|
|
|
719
719
|
*/
|
|
720
720
|
|
|
721
721
|
SchemaString.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
722
|
-
return this._createJSONSchemaTypeDefinition('string', 'string', options);
|
|
722
|
+
return this._addJSONSchemaEnum(this._createJSONSchemaTypeDefinition('string', 'string', options));
|
|
723
723
|
};
|
|
724
724
|
|
|
725
725
|
SchemaString.prototype.autoEncryptionType = function autoEncryptionType() {
|
package/lib/schema.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
const EventEmitter = require('events').EventEmitter;
|
|
8
8
|
const Kareem = require('kareem');
|
|
9
9
|
const MongooseError = require('./error/mongooseError');
|
|
10
|
+
const PathTrie = require('./helpers/pathTrie');
|
|
10
11
|
const SchemaType = require('./schemaType');
|
|
11
12
|
const SchemaTypeOptions = require('./options/schemaTypeOptions');
|
|
12
13
|
const VirtualOptions = require('./options/virtualOptions');
|
|
@@ -79,7 +80,7 @@ const numberRE = /^\d+$/;
|
|
|
79
80
|
* - [validateBeforeSave](https://mongoosejs.com/docs/guide.html#validateBeforeSave) - bool - defaults to `true`
|
|
80
81
|
* - [validateModifiedOnly](https://mongoosejs.com/docs/api/document.html#Document.prototype.validate()) - bool - defaults to `false`
|
|
81
82
|
* - [versionKey](https://mongoosejs.com/docs/guide.html#versionKey): string or object - defaults to "__v"
|
|
82
|
-
* - [optimisticConcurrency](https://mongoosejs.com/docs/guide.html#optimisticConcurrency): bool or string[] or { exclude: string[] } - defaults to false. Set to true to enable [optimistic concurrency](https://thecodebarbarian.com/whats-new-in-mongoose-5-10-optimistic-concurrency.html) for all fields. Set to a string array to enable optimistic concurrency only for the specified fields; note that this **replaces** the default array versioning behavior. Set to `{ exclude: string[] }` to enable optimistic concurrency for all fields except the specified ones; this also replaces the default array versioning.
|
|
83
|
+
* - [optimisticConcurrency](https://mongoosejs.com/docs/guide.html#optimisticConcurrency): bool or string[] or { exclude: string[] } - defaults to false. Set to true to enable [optimistic concurrency](https://thecodebarbarian.com/whats-new-in-mongoose-5-10-optimistic-concurrency.html) for all fields. Set to a string array to enable optimistic concurrency only for the specified fields; note that this **replaces** the default array versioning behavior. Set to `{ exclude: string[] }` to enable optimistic concurrency for all fields except the specified ones; this also replaces the default array versioning. Paths may include the map wildcard `$*`, like `'settings.$*'`, to match all keys of a map.
|
|
83
84
|
* - [collation](https://mongoosejs.com/docs/guide.html#collation): object - defaults to null (which means use no collation)
|
|
84
85
|
* - [timeseries](https://mongoosejs.com/docs/guide.html#timeseries): object - defaults to null (which means this schema's collection won't be a timeseries collection)
|
|
85
86
|
* - [selectPopulatedPaths](https://mongoosejs.com/docs/guide.html#selectPopulatedPaths): boolean - defaults to `true`
|
|
@@ -3142,9 +3143,9 @@ Schema.prototype._preCompile = function _preCompile() {
|
|
|
3142
3143
|
};
|
|
3143
3144
|
|
|
3144
3145
|
/*!
|
|
3145
|
-
* Build precomputed
|
|
3146
|
-
*
|
|
3147
|
-
*
|
|
3146
|
+
* Build precomputed path tries for optimisticConcurrency include/exclude so
|
|
3147
|
+
* that lookups at save time are a single trie walk that handles nested paths
|
|
3148
|
+
* and map wildcards like `settings.$*`.
|
|
3148
3149
|
*/
|
|
3149
3150
|
|
|
3150
3151
|
function _precomputeOptimisticConcurrency(schema) {
|
|
@@ -3153,9 +3154,9 @@ function _precomputeOptimisticConcurrency(schema) {
|
|
|
3153
3154
|
return;
|
|
3154
3155
|
}
|
|
3155
3156
|
if (Array.isArray(opt)) {
|
|
3156
|
-
schema.options.
|
|
3157
|
+
schema.options._optimisticConcurrencyTrie = new PathTrie(opt);
|
|
3157
3158
|
} else if (Array.isArray(opt.exclude)) {
|
|
3158
|
-
schema.options.
|
|
3159
|
+
schema.options._optimisticConcurrencyExcludeTrie = new PathTrie(opt.exclude);
|
|
3159
3160
|
}
|
|
3160
3161
|
}
|
|
3161
3162
|
|
|
@@ -3215,27 +3216,19 @@ Schema.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
3215
3216
|
}
|
|
3216
3217
|
|
|
3217
3218
|
const lastSubpath = schemaType._presplitPath[schemaType._presplitPath.length - 1];
|
|
3218
|
-
let isRequired = false;
|
|
3219
3219
|
if (path === '_id') {
|
|
3220
3220
|
if (!jsonSchemaForPath.required) {
|
|
3221
3221
|
jsonSchemaForPath.required = [];
|
|
3222
3222
|
}
|
|
3223
3223
|
jsonSchemaForPath.required.push('_id');
|
|
3224
|
-
isRequired = true;
|
|
3225
3224
|
} else if (schemaType.options.required && typeof schemaType.options.required !== 'function') {
|
|
3226
3225
|
if (!jsonSchemaForPath.required) {
|
|
3227
3226
|
jsonSchemaForPath.required = [];
|
|
3228
3227
|
}
|
|
3229
3228
|
// Only `required: true` paths are required, conditional required is not required
|
|
3230
3229
|
jsonSchemaForPath.required.push(lastSubpath);
|
|
3231
|
-
isRequired = true;
|
|
3232
3230
|
}
|
|
3233
3231
|
jsonSchemaForPath.properties[lastSubpath] = schemaType.toJSONSchema(options);
|
|
3234
|
-
if (schemaType.options.enum) {
|
|
3235
|
-
jsonSchemaForPath.properties[lastSubpath].enum = isRequired
|
|
3236
|
-
? schemaType.options.enum
|
|
3237
|
-
: [...schemaType.options.enum, null];
|
|
3238
|
-
}
|
|
3239
3232
|
}
|
|
3240
3233
|
|
|
3241
3234
|
// Otherwise MongoDB errors with "$jsonSchema keyword 'required' cannot be an empty array"
|
package/lib/schemaType.js
CHANGED
|
@@ -215,6 +215,27 @@ SchemaType.prototype._createJSONSchemaTypeDefinition = function _createJSONSchem
|
|
|
215
215
|
return { type: [type, 'null'] };
|
|
216
216
|
};
|
|
217
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Helper for adding this SchemaType's enum values to a JSON schema type definition.
|
|
220
|
+
* Reads `enumValues` rather than `options.enum` because `enum` also accepts an object.
|
|
221
|
+
*
|
|
222
|
+
* @param {object} definition the type definition from `_createJSONSchemaTypeDefinition()`
|
|
223
|
+
* @returns {object} the same definition
|
|
224
|
+
* @api private
|
|
225
|
+
*/
|
|
226
|
+
|
|
227
|
+
SchemaType.prototype._addJSONSchemaEnum = function _addJSONSchemaEnum(definition) {
|
|
228
|
+
if (!Array.isArray(this.enumValues) || this.enumValues.length === 0) {
|
|
229
|
+
return definition;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// The enum validator allows nullish values, so allow `null` wherever the type does.
|
|
233
|
+
const allowsNull = Array.isArray(definition.type ?? definition.bsonType);
|
|
234
|
+
definition.enum = allowsNull ? [...this.enumValues, null] : [...this.enumValues];
|
|
235
|
+
|
|
236
|
+
return definition;
|
|
237
|
+
};
|
|
238
|
+
|
|
218
239
|
/**
|
|
219
240
|
* The validators that Mongoose should run to validate properties at this SchemaType's path.
|
|
220
241
|
*
|
package/lib/utils.js
CHANGED
|
@@ -421,26 +421,16 @@ exports.isPOJO = require('./helpers/isPOJO');
|
|
|
421
421
|
|
|
422
422
|
exports.isNonBuiltinObject = function isNonBuiltinObject(val) {
|
|
423
423
|
return typeof val === 'object' &&
|
|
424
|
-
!
|
|
424
|
+
!Array.isArray(val) &&
|
|
425
|
+
!(val instanceof Date) &&
|
|
426
|
+
!(val instanceof Boolean) &&
|
|
427
|
+
!(val instanceof Number) &&
|
|
428
|
+
!(val instanceof String) &&
|
|
425
429
|
!exports.isMongooseType(val) &&
|
|
426
430
|
!(val instanceof UUID) &&
|
|
427
431
|
val != null;
|
|
428
432
|
};
|
|
429
433
|
|
|
430
|
-
/**
|
|
431
|
-
* Determines if `obj` is a built-in object like an array, date, boolean,
|
|
432
|
-
* etc.
|
|
433
|
-
* @param {any} arg
|
|
434
|
-
*/
|
|
435
|
-
|
|
436
|
-
exports.isNativeObject = function(arg) {
|
|
437
|
-
return Array.isArray(arg) ||
|
|
438
|
-
arg instanceof Date ||
|
|
439
|
-
arg instanceof Boolean ||
|
|
440
|
-
arg instanceof Number ||
|
|
441
|
-
arg instanceof String;
|
|
442
|
-
};
|
|
443
|
-
|
|
444
434
|
/**
|
|
445
435
|
* Determines if `val` is an object that has no own keys
|
|
446
436
|
* @param {any} val
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "9.9.
|
|
4
|
+
"version": "9.9.2",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"sift": "17.1.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@ark/attest": "0.56.
|
|
32
|
+
"@ark/attest": "0.56.3",
|
|
33
33
|
"@eslint/js": "^9.39.3",
|
|
34
34
|
"@mongodb-js/mongodb-downloader": "^1.0.0",
|
|
35
35
|
"@types/node": "^20.19.0",
|
|
@@ -37,30 +37,30 @@
|
|
|
37
37
|
"acquit-ignore": "0.2.2",
|
|
38
38
|
"acquit-require": "0.1.1",
|
|
39
39
|
"ajv": "8.20.0",
|
|
40
|
-
"c8": "
|
|
40
|
+
"c8": "12.0.0",
|
|
41
41
|
"cheerio": "1.2.0",
|
|
42
42
|
"dox": "1.0.0",
|
|
43
|
-
"eslint": "10.
|
|
43
|
+
"eslint": "10.8.0",
|
|
44
44
|
"eslint-plugin-mocha-no-only": "1.2.0",
|
|
45
45
|
"express": "5.2.1",
|
|
46
|
-
"fs-extra": "~11.
|
|
46
|
+
"fs-extra": "~11.4.0",
|
|
47
47
|
"glob": "^13.0.6",
|
|
48
48
|
"globals": "^17.4.0",
|
|
49
49
|
"highlight.js": "11.11.1",
|
|
50
|
-
"linkinator": "
|
|
50
|
+
"linkinator": "8.x",
|
|
51
51
|
"lodash.isequal": "4.5.0",
|
|
52
52
|
"lodash.isequalwith": "4.4.0",
|
|
53
|
-
"markdownlint-cli2": "0.
|
|
54
|
-
"marked": "18.0.
|
|
53
|
+
"markdownlint-cli2": "0.23.2",
|
|
54
|
+
"marked": "18.0.7",
|
|
55
55
|
"mkdirp": "^3.0.1",
|
|
56
|
-
"mocha": "12.0.0-
|
|
56
|
+
"mocha": "12.0.0-rc.5",
|
|
57
57
|
"moment": "2.30.1",
|
|
58
58
|
"mongodb-client-encryption": "^7.2.0",
|
|
59
59
|
"mongodb-memory-server": "11.2.0",
|
|
60
60
|
"mongodb-runner": "^6.0.0",
|
|
61
61
|
"ncp": "^2.0.0",
|
|
62
62
|
"pug": "3.0.4",
|
|
63
|
-
"sinon": "22.
|
|
63
|
+
"sinon": "22.1.0",
|
|
64
64
|
"tstyche": "^7.0.0",
|
|
65
65
|
"typescript": "5.9.3",
|
|
66
66
|
"typescript-eslint": "^8.31.1",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"publish-7x": "npm publish --tag 7x",
|
|
101
101
|
"create-separate-require-instance": "rm -rf ./node_modules/mongoose-separate-require-instance && node ./scripts/create-tarball && tar -xzf mongoose.tgz -C ./node_modules && mv ./node_modules/package ./node_modules/mongoose-separate-require-instance",
|
|
102
102
|
"test": "mocha --exit --ignore \"test/encryption/**/*.test.js\" \"./test/**/*.test.js\"",
|
|
103
|
-
"test:ci": "npm run test -- --reporter min",
|
|
103
|
+
"test:ci": "npm run test -- --reporter min --timeout 10000",
|
|
104
104
|
"test-deno": "deno run --allow-env --allow-read --allow-net --allow-run --allow-sys --allow-write ./test/deno.mjs",
|
|
105
105
|
"test-deno:ci": "npm run test-deno -- --reporter min",
|
|
106
106
|
"test-rs": "START_REPLICA_SET=1 mocha --timeout 30000 --exit --ignore \"test/encryption/**/*.test.js\" \"./test/**/*.test.js\"",
|
package/types/document.d.ts
CHANGED
|
@@ -289,9 +289,9 @@ declare module 'mongoose' {
|
|
|
289
289
|
): ToObjectReturnType<PopulatedRawDocType, TVirtuals, O, TSchemaOptions>;
|
|
290
290
|
toJSON<PopulatedRawDocType>(
|
|
291
291
|
this: PopulatedDocumentMarker<PopulatedRawDocType, any>
|
|
292
|
-
):
|
|
292
|
+
): DefaultToObjectReturnType<PopulatedRawDocType, TVirtuals, TSchemaOptions, 'toJSON'>;
|
|
293
293
|
toJSON<O extends ToObjectOptions>(options: O): ToObjectReturnType<DocType, TVirtuals, O, TSchemaOptions>;
|
|
294
|
-
toJSON(options?: ToObjectOptions):
|
|
294
|
+
toJSON(options?: ToObjectOptions): DefaultToObjectReturnType<DocType, TVirtuals, TSchemaOptions, 'toJSON'>;
|
|
295
295
|
toJSON<T>(options?: ToObjectOptions): Default__v<Require_id<T>, ResolveSchemaOptions<TSchemaOptions>>;
|
|
296
296
|
|
|
297
297
|
/** Converts this document into a plain-old JavaScript object ([POJO](https://masteringjs.io/tutorials/fundamentals/pojo)). */
|
|
@@ -309,9 +309,9 @@ declare module 'mongoose' {
|
|
|
309
309
|
): ToObjectReturnType<PopulatedRawDocType, TVirtuals, O, TSchemaOptions>;
|
|
310
310
|
toObject<PopulatedRawDocType>(
|
|
311
311
|
this: PopulatedDocumentMarker<PopulatedRawDocType, any>
|
|
312
|
-
):
|
|
312
|
+
): DefaultToObjectReturnType<PopulatedRawDocType, TVirtuals, TSchemaOptions, 'toObject'>;
|
|
313
313
|
toObject<O extends ToObjectOptions>(options: O): ToObjectReturnType<DocType, TVirtuals, O, TSchemaOptions>;
|
|
314
|
-
toObject(options?: ToObjectOptions):
|
|
314
|
+
toObject(options?: ToObjectOptions): DefaultToObjectReturnType<DocType, TVirtuals, TSchemaOptions, 'toObject'>;
|
|
315
315
|
toObject<T>(options?: ToObjectOptions): Default__v<Require_id<T>, ResolveSchemaOptions<TSchemaOptions>>;
|
|
316
316
|
|
|
317
317
|
/** Clears the modified state on the specified path. */
|
package/types/index.d.ts
CHANGED
|
@@ -1122,6 +1122,31 @@ declare module 'mongoose' {
|
|
|
1122
1122
|
? { [K in keyof T]: ApplyFlattenTransforms<T[K], O> }
|
|
1123
1123
|
: T;
|
|
1124
1124
|
|
|
1125
|
+
/**
|
|
1126
|
+
* Extracts the `toObject` or `toJSON` options declared in the schema options.
|
|
1127
|
+
* The runtime applies these as defaults when the corresponding method is
|
|
1128
|
+
* called without arguments.
|
|
1129
|
+
*/
|
|
1130
|
+
export type SchemaDeclaredToObjectOptions<TSchemaOptions, Key extends 'toObject' | 'toJSON'> =
|
|
1131
|
+
Key extends keyof TSchemaOptions
|
|
1132
|
+
? NonNullable<TSchemaOptions[Key]> extends infer O extends ToObjectOptions
|
|
1133
|
+
? O
|
|
1134
|
+
: {}
|
|
1135
|
+
: {};
|
|
1136
|
+
|
|
1137
|
+
/**
|
|
1138
|
+
* Computes the return type of toObject/toJSON when called without arguments,
|
|
1139
|
+
* applying the options declared in the schema like the runtime does. When the
|
|
1140
|
+
* schema declares no options for the method, the plain document shape is
|
|
1141
|
+
* returned without running it through the option transforms.
|
|
1142
|
+
*/
|
|
1143
|
+
export type DefaultToObjectReturnType<DocType, TVirtuals, TSchemaOptions, Key extends 'toObject' | 'toJSON'> =
|
|
1144
|
+
SchemaDeclaredToObjectOptions<TSchemaOptions, Key> extends infer O extends ToObjectOptions
|
|
1145
|
+
? keyof O extends never
|
|
1146
|
+
? Default__v<Require_id<DocType>, TSchemaOptions>
|
|
1147
|
+
: ToObjectReturnType<DocType, TVirtuals, O, TSchemaOptions>
|
|
1148
|
+
: Default__v<Require_id<DocType>, TSchemaOptions>;
|
|
1149
|
+
|
|
1125
1150
|
/**
|
|
1126
1151
|
* Computes the return type of toObject/toJSON based on the provided options.
|
|
1127
1152
|
* Uses a single-pass transform for flatten operations to correctly handle all combinations.
|
package/types/models.d.ts
CHANGED
|
@@ -457,6 +457,18 @@ declare module 'mongoose' {
|
|
|
457
457
|
'findOne',
|
|
458
458
|
TInstanceMethods & TVirtuals
|
|
459
459
|
>;
|
|
460
|
+
findById<ResultDoc = THydratedDocumentType>(
|
|
461
|
+
id: any,
|
|
462
|
+
projection: ProjectionType<TRawDocType> | null | undefined,
|
|
463
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
464
|
+
): QueryWithHelpers<
|
|
465
|
+
ResultDoc | null,
|
|
466
|
+
ResultDoc,
|
|
467
|
+
TQueryHelpers,
|
|
468
|
+
TLeanResultType,
|
|
469
|
+
'findOne',
|
|
470
|
+
TInstanceMethods & TVirtuals
|
|
471
|
+
>;
|
|
460
472
|
findById<ResultDoc = THydratedDocumentType>(
|
|
461
473
|
id?: any,
|
|
462
474
|
projection?: ProjectionType<TRawDocType> | null | undefined,
|
|
@@ -495,6 +507,18 @@ declare module 'mongoose' {
|
|
|
495
507
|
'findOne',
|
|
496
508
|
TInstanceMethods & TVirtuals
|
|
497
509
|
>;
|
|
510
|
+
findOne<ResultDoc = THydratedDocumentType>(
|
|
511
|
+
filter: QueryFilter<TRawDocType>,
|
|
512
|
+
projection: ProjectionType<TRawDocType> | null | undefined,
|
|
513
|
+
options: QueryOptions<TRawDocType> & { lean: false } & mongodb.Abortable
|
|
514
|
+
): QueryWithHelpers<
|
|
515
|
+
ResultDoc | null,
|
|
516
|
+
ResultDoc,
|
|
517
|
+
TQueryHelpers,
|
|
518
|
+
TLeanResultType,
|
|
519
|
+
'findOne',
|
|
520
|
+
TInstanceMethods & TVirtuals
|
|
521
|
+
>;
|
|
498
522
|
findOne<ResultDoc = THydratedDocumentType>(
|
|
499
523
|
filter?: QueryFilter<TRawDocType>,
|
|
500
524
|
projection?: ProjectionType<TRawDocType> | null | undefined,
|
|
@@ -780,12 +804,24 @@ declare module 'mongoose' {
|
|
|
780
804
|
'find',
|
|
781
805
|
TInstanceMethods & TVirtuals
|
|
782
806
|
>;
|
|
807
|
+
find<ResultDoc = THydratedDocumentType>(
|
|
808
|
+
filter: QueryFilter<TRawDocType>,
|
|
809
|
+
projection: ProjectionType<TRawDocType> | null | undefined,
|
|
810
|
+
options: QueryOptions<TRawDocType> & { lean: false } & mongodb.Abortable
|
|
811
|
+
): QueryWithHelpers<
|
|
812
|
+
ResultDoc[],
|
|
813
|
+
ResultDoc,
|
|
814
|
+
TQueryHelpers,
|
|
815
|
+
TLeanResultType,
|
|
816
|
+
'find',
|
|
817
|
+
TInstanceMethods & TVirtuals
|
|
818
|
+
>;
|
|
783
819
|
find<ResultDoc = THydratedDocumentType>(
|
|
784
820
|
filter?: QueryFilter<TRawDocType>,
|
|
785
821
|
projection?: ProjectionType<TRawDocType> | null | undefined,
|
|
786
822
|
options?: QueryOptions<TRawDocType> & mongodb.Abortable
|
|
787
823
|
): QueryWithHelpers<
|
|
788
|
-
ResultDoc[],
|
|
824
|
+
HasLeanOption<TSchema> extends true ? TLeanResultType[] : ResultDoc[],
|
|
789
825
|
ResultDoc,
|
|
790
826
|
TQueryHelpers,
|
|
791
827
|
TLeanResultType,
|
|
@@ -797,7 +833,7 @@ declare module 'mongoose' {
|
|
|
797
833
|
projection?: ProjectionType<TRawDocType> | null | undefined,
|
|
798
834
|
options?: QueryOptions<TRawDocType> & mongodb.Abortable
|
|
799
835
|
): QueryWithHelpers<
|
|
800
|
-
THydratedDocumentType[],
|
|
836
|
+
HasLeanOption<TSchema> extends true ? TLeanResultType[] : THydratedDocumentType[],
|
|
801
837
|
THydratedDocumentType,
|
|
802
838
|
TQueryHelpers,
|
|
803
839
|
TLeanResultType,
|
|
@@ -828,6 +864,17 @@ declare module 'mongoose' {
|
|
|
828
864
|
'findOneAndDelete',
|
|
829
865
|
TInstanceMethods & TVirtuals
|
|
830
866
|
>;
|
|
867
|
+
findByIdAndDelete<ResultDoc = THydratedDocumentType>(
|
|
868
|
+
id: mongodb.ObjectId | any,
|
|
869
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
870
|
+
): QueryWithHelpers<
|
|
871
|
+
ResultDoc | null,
|
|
872
|
+
ResultDoc,
|
|
873
|
+
TQueryHelpers,
|
|
874
|
+
TLeanResultType,
|
|
875
|
+
'findOneAndDelete',
|
|
876
|
+
TInstanceMethods & TVirtuals
|
|
877
|
+
>;
|
|
831
878
|
findByIdAndDelete<ResultDoc = THydratedDocumentType>(
|
|
832
879
|
id: mongodb.ObjectId | any,
|
|
833
880
|
options: QueryOptions<TRawDocType> & { includeResultMetadata: true }
|
|
@@ -889,6 +936,18 @@ declare module 'mongoose' {
|
|
|
889
936
|
'findOneAndUpdate',
|
|
890
937
|
TInstanceMethods & TVirtuals
|
|
891
938
|
>;
|
|
939
|
+
findByIdAndUpdate<ResultDoc = THydratedDocumentType>(
|
|
940
|
+
id: mongodb.ObjectId | any,
|
|
941
|
+
update: UpdateQuery<TRawDocType>,
|
|
942
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
943
|
+
): QueryWithHelpers<
|
|
944
|
+
ResultDoc | null,
|
|
945
|
+
ResultDoc,
|
|
946
|
+
TQueryHelpers,
|
|
947
|
+
TLeanResultType,
|
|
948
|
+
'findOneAndUpdate',
|
|
949
|
+
TInstanceMethods & TVirtuals
|
|
950
|
+
>;
|
|
892
951
|
findByIdAndUpdate<ResultDoc = THydratedDocumentType>(
|
|
893
952
|
id: mongodb.ObjectId | any,
|
|
894
953
|
update: UpdateQuery<TRawDocType>,
|
|
@@ -949,6 +1008,28 @@ declare module 'mongoose' {
|
|
|
949
1008
|
'findOneAndDelete',
|
|
950
1009
|
TInstanceMethods & TVirtuals
|
|
951
1010
|
>;
|
|
1011
|
+
findOneAndDelete<ResultDoc = THydratedDocumentType>(
|
|
1012
|
+
filter: QueryFilter<TRawDocType>,
|
|
1013
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
1014
|
+
): QueryWithHelpers<
|
|
1015
|
+
ResultDoc | null,
|
|
1016
|
+
ResultDoc,
|
|
1017
|
+
TQueryHelpers,
|
|
1018
|
+
TLeanResultType,
|
|
1019
|
+
'findOneAndDelete',
|
|
1020
|
+
TInstanceMethods & TVirtuals
|
|
1021
|
+
>;
|
|
1022
|
+
findOneAndDelete(
|
|
1023
|
+
filter: Query<any, any>,
|
|
1024
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
1025
|
+
): QueryWithHelpers<
|
|
1026
|
+
THydratedDocumentType | null,
|
|
1027
|
+
THydratedDocumentType,
|
|
1028
|
+
TQueryHelpers,
|
|
1029
|
+
TLeanResultType,
|
|
1030
|
+
'findOneAndDelete',
|
|
1031
|
+
TInstanceMethods & TVirtuals
|
|
1032
|
+
>;
|
|
952
1033
|
findOneAndDelete<ResultDoc = THydratedDocumentType>(
|
|
953
1034
|
filter: QueryFilter<TRawDocType>,
|
|
954
1035
|
options: QueryOptions<TRawDocType> & { includeResultMetadata: true }
|
|
@@ -975,7 +1056,7 @@ declare module 'mongoose' {
|
|
|
975
1056
|
filter?: QueryFilter<TRawDocType> | null,
|
|
976
1057
|
options?: QueryOptions<TRawDocType> | null
|
|
977
1058
|
): QueryWithHelpers<
|
|
978
|
-
HasLeanOption<TSchema> extends true ?
|
|
1059
|
+
HasLeanOption<TSchema> extends true ? TLeanResultType | null : ResultDoc | null,
|
|
979
1060
|
ResultDoc,
|
|
980
1061
|
TQueryHelpers,
|
|
981
1062
|
TLeanResultType,
|
|
@@ -986,7 +1067,7 @@ declare module 'mongoose' {
|
|
|
986
1067
|
filter?: Query<any, any> | null,
|
|
987
1068
|
options?: QueryOptions<TRawDocType> | null
|
|
988
1069
|
): QueryWithHelpers<
|
|
989
|
-
HasLeanOption<TSchema> extends true ?
|
|
1070
|
+
HasLeanOption<TSchema> extends true ? TLeanResultType | null : THydratedDocumentType | null,
|
|
990
1071
|
THydratedDocumentType,
|
|
991
1072
|
TQueryHelpers,
|
|
992
1073
|
TLeanResultType,
|
|
@@ -1019,6 +1100,30 @@ declare module 'mongoose' {
|
|
|
1019
1100
|
'findOneAndReplace',
|
|
1020
1101
|
TInstanceMethods & TVirtuals
|
|
1021
1102
|
>;
|
|
1103
|
+
findOneAndReplace<ResultDoc = THydratedDocumentType>(
|
|
1104
|
+
filter: QueryFilter<TRawDocType>,
|
|
1105
|
+
replacement: TRawDocType | AnyObject,
|
|
1106
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
1107
|
+
): QueryWithHelpers<
|
|
1108
|
+
ResultDoc | null,
|
|
1109
|
+
ResultDoc,
|
|
1110
|
+
TQueryHelpers,
|
|
1111
|
+
TLeanResultType,
|
|
1112
|
+
'findOneAndReplace',
|
|
1113
|
+
TInstanceMethods & TVirtuals
|
|
1114
|
+
>;
|
|
1115
|
+
findOneAndReplace(
|
|
1116
|
+
filter: Query<any, any>,
|
|
1117
|
+
replacement: TRawDocType | AnyObject,
|
|
1118
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
1119
|
+
): QueryWithHelpers<
|
|
1120
|
+
THydratedDocumentType | null,
|
|
1121
|
+
THydratedDocumentType,
|
|
1122
|
+
TQueryHelpers,
|
|
1123
|
+
TLeanResultType,
|
|
1124
|
+
'findOneAndReplace',
|
|
1125
|
+
TInstanceMethods & TVirtuals
|
|
1126
|
+
>;
|
|
1022
1127
|
findOneAndReplace<ResultDoc = THydratedDocumentType>(
|
|
1023
1128
|
filter: QueryFilter<TRawDocType>,
|
|
1024
1129
|
replacement: TRawDocType | AnyObject,
|
|
@@ -1141,6 +1246,30 @@ declare module 'mongoose' {
|
|
|
1141
1246
|
'findOneAndUpdate',
|
|
1142
1247
|
TInstanceMethods & TVirtuals
|
|
1143
1248
|
>;
|
|
1249
|
+
findOneAndUpdate<ResultDoc = THydratedDocumentType>(
|
|
1250
|
+
filter: QueryFilter<TRawDocType>,
|
|
1251
|
+
update: UpdateQuery<TRawDocType>,
|
|
1252
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
1253
|
+
): QueryWithHelpers<
|
|
1254
|
+
ResultDoc | null,
|
|
1255
|
+
ResultDoc,
|
|
1256
|
+
TQueryHelpers,
|
|
1257
|
+
TLeanResultType,
|
|
1258
|
+
'findOneAndUpdate',
|
|
1259
|
+
TInstanceMethods & TVirtuals
|
|
1260
|
+
>;
|
|
1261
|
+
findOneAndUpdate(
|
|
1262
|
+
filter: Query<any, any>,
|
|
1263
|
+
update: UpdateQuery<TRawDocType>,
|
|
1264
|
+
options: QueryOptions<TRawDocType> & { lean: false }
|
|
1265
|
+
): QueryWithHelpers<
|
|
1266
|
+
THydratedDocumentType | null,
|
|
1267
|
+
THydratedDocumentType,
|
|
1268
|
+
TQueryHelpers,
|
|
1269
|
+
TLeanResultType,
|
|
1270
|
+
'findOneAndUpdate',
|
|
1271
|
+
TInstanceMethods & TVirtuals
|
|
1272
|
+
>;
|
|
1144
1273
|
findOneAndUpdate<ResultDoc = THydratedDocumentType>(
|
|
1145
1274
|
filter: QueryFilter<TRawDocType>,
|
|
1146
1275
|
update: UpdateQuery<TRawDocType>,
|
package/types/schematypes.d.ts
CHANGED