mongoose 9.10.2 → 9.10.4
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/collection.js +1 -2
- package/lib/drivers/node-mongodb-native/connection.js +5 -0
- package/lib/helpers/indexes/isIndexEqual.js +10 -8
- package/lib/helpers/model/castBulkWrite.js +25 -10
- package/lib/helpers/query/cast$expr.js +9 -1
- package/lib/helpers/query/castUpdate.js +26 -5
- package/lib/model.js +26 -17
- package/lib/schema/union.js +4 -0
- package/lib/types/array/methods/index.js +3 -1
- package/lib/types/map.js +6 -0
- package/package.json +9 -9
package/lib/collection.js
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
const EventEmitter = require('events').EventEmitter;
|
|
8
|
-
const STATES = require('./connectionState');
|
|
9
8
|
const immediate = require('./helpers/immediate');
|
|
10
9
|
|
|
11
10
|
/**
|
|
@@ -32,7 +31,7 @@ function Collection(name, conn, opts) {
|
|
|
32
31
|
this.buffer = !conn?._hasOpened;
|
|
33
32
|
this.emitter = new EventEmitter();
|
|
34
33
|
|
|
35
|
-
if (
|
|
34
|
+
if (conn?._hasOpened) {
|
|
36
35
|
this.onOpen();
|
|
37
36
|
}
|
|
38
37
|
}
|
|
@@ -495,6 +495,11 @@ function _setClient(conn, client, options, dbName) {
|
|
|
495
495
|
otherDb._flushQueue();
|
|
496
496
|
}
|
|
497
497
|
}
|
|
498
|
+
for (const collection of Object.values(conn.collections)) {
|
|
499
|
+
if (collection.buffer) {
|
|
500
|
+
collection.onOpen();
|
|
501
|
+
}
|
|
502
|
+
}
|
|
498
503
|
});
|
|
499
504
|
|
|
500
505
|
if (options.monitorCommands) {
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
const get = require('../get');
|
|
4
4
|
const utils = require('../../utils');
|
|
5
|
+
|
|
6
|
+
const simpleCollation = Object.freeze({ locale: 'simple' });
|
|
7
|
+
|
|
5
8
|
/**
|
|
6
9
|
* Given a Mongoose index definition (key + options objects) and a MongoDB server
|
|
7
10
|
* index definition, determine if the two indexes are equal.
|
|
@@ -61,14 +64,13 @@ module.exports = function isIndexEqual(schemaIndexKeysObject, options, dbIndex)
|
|
|
61
64
|
continue;
|
|
62
65
|
}
|
|
63
66
|
if (key === 'collation') {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
if (get(schemaCollation, opt) !== get(dbCollation, opt)) {
|
|
67
|
+
// No collation is equivalent to { locale: 'simple' }. MongoDB server 9
|
|
68
|
+
// reports { locale: 'simple' } for indexes created with no collation,
|
|
69
|
+
// older versions omit it.
|
|
70
|
+
const schemaCollation = options.collation ?? simpleCollation;
|
|
71
|
+
const dbCollation = dbIndex.collation ?? simpleCollation;
|
|
72
|
+
for (const opt of Object.keys(schemaCollation)) {
|
|
73
|
+
if (schemaCollation[opt] !== dbCollation[opt]) {
|
|
72
74
|
return false;
|
|
73
75
|
}
|
|
74
76
|
}
|
|
@@ -149,7 +149,7 @@ module.exports.castUpdateOne = function castUpdateOne(originalModel, updateOne,
|
|
|
149
149
|
model.schema.options.versionKey
|
|
150
150
|
);
|
|
151
151
|
|
|
152
|
-
updateOne['filter'] =
|
|
152
|
+
updateOne['filter'] = _castFilter(model, updateOne['filter'], {
|
|
153
153
|
strict: strict,
|
|
154
154
|
upsert: updateOne.upsert
|
|
155
155
|
});
|
|
@@ -176,11 +176,13 @@ module.exports.castUpdateMany = function castUpdateMany(originalModel, updateMan
|
|
|
176
176
|
const schema = model.schema;
|
|
177
177
|
const strict = options.strict ?? model.schema.options.strict;
|
|
178
178
|
|
|
179
|
+
const update = clone(updateMany['update']);
|
|
180
|
+
|
|
179
181
|
const globalSetDefaultsOnInsert = originalModel.base.options.setDefaultsOnInsert;
|
|
180
182
|
const shouldSetDefaultsOnInsert = updateMany.setDefaultsOnInsert ?? globalSetDefaultsOnInsert;
|
|
181
183
|
|
|
182
184
|
if (shouldSetDefaultsOnInsert !== false) {
|
|
183
|
-
setDefaultsOnInsert(updateMany['filter'], model.schema,
|
|
185
|
+
setDefaultsOnInsert(updateMany['filter'], model.schema, update, {
|
|
184
186
|
setDefaultsOnInsert: true,
|
|
185
187
|
upsert: updateMany.upsert
|
|
186
188
|
});
|
|
@@ -191,29 +193,29 @@ module.exports.castUpdateMany = function castUpdateMany(originalModel, updateMan
|
|
|
191
193
|
if (model.schema.$timestamps != null && doInitTimestamps) {
|
|
192
194
|
const createdAt = model.schema.$timestamps.createdAt;
|
|
193
195
|
const updatedAt = model.schema.$timestamps.updatedAt;
|
|
194
|
-
applyTimestampsToUpdate(now, createdAt, updatedAt,
|
|
196
|
+
applyTimestampsToUpdate(now, createdAt, updatedAt, update, {
|
|
195
197
|
timestamps: updateMany.timestamps,
|
|
196
198
|
overwriteImmutable: updateMany.overwriteImmutable
|
|
197
199
|
}, updateMany.upsert);
|
|
198
200
|
}
|
|
199
201
|
if (doInitTimestamps) {
|
|
200
|
-
applyTimestampsToChildren(now,
|
|
202
|
+
applyTimestampsToChildren(now, update, model.schema);
|
|
201
203
|
}
|
|
202
204
|
|
|
203
205
|
_addDiscriminatorToObject(schema, updateMany['filter']);
|
|
204
206
|
|
|
205
207
|
decorateUpdateWithVersionKey(
|
|
206
|
-
|
|
208
|
+
update,
|
|
207
209
|
updateMany,
|
|
208
210
|
model.schema.options.versionKey
|
|
209
211
|
);
|
|
210
212
|
|
|
211
|
-
updateMany['filter'] =
|
|
213
|
+
updateMany['filter'] = _castFilter(model, updateMany['filter'], {
|
|
212
214
|
strict: strict,
|
|
213
215
|
upsert: updateMany.upsert
|
|
214
216
|
});
|
|
215
217
|
|
|
216
|
-
updateMany['update'] = castUpdate(model.schema,
|
|
218
|
+
updateMany['update'] = castUpdate(model.schema, update, {
|
|
217
219
|
strict: strict,
|
|
218
220
|
upsert: updateMany.upsert,
|
|
219
221
|
arrayFilters: updateMany.arrayFilters,
|
|
@@ -228,7 +230,7 @@ module.exports.castReplaceOne = async function castReplaceOne(originalModel, rep
|
|
|
228
230
|
const strict = options.strict ?? model.schema.options.strict;
|
|
229
231
|
|
|
230
232
|
_addDiscriminatorToObject(schema, replaceOne['filter']);
|
|
231
|
-
replaceOne['filter'] =
|
|
233
|
+
replaceOne['filter'] = _castFilter(model, replaceOne['filter'], {
|
|
232
234
|
strict: strict,
|
|
233
235
|
upsert: replaceOne.upsert
|
|
234
236
|
});
|
|
@@ -262,7 +264,7 @@ module.exports.castDeleteOne = function castDeleteOne(originalModel, deleteOne)
|
|
|
262
264
|
|
|
263
265
|
_addDiscriminatorToObject(schema, deleteOne['filter']);
|
|
264
266
|
|
|
265
|
-
deleteOne['filter'] =
|
|
267
|
+
deleteOne['filter'] = _castFilter(model, deleteOne['filter']);
|
|
266
268
|
};
|
|
267
269
|
|
|
268
270
|
module.exports.castDeleteMany = function castDeleteMany(originalModel, deleteMany) {
|
|
@@ -271,7 +273,7 @@ module.exports.castDeleteMany = function castDeleteMany(originalModel, deleteMan
|
|
|
271
273
|
|
|
272
274
|
_addDiscriminatorToObject(schema, deleteMany['filter']);
|
|
273
275
|
|
|
274
|
-
deleteMany['filter'] =
|
|
276
|
+
deleteMany['filter'] = _castFilter(model, deleteMany['filter']);
|
|
275
277
|
};
|
|
276
278
|
|
|
277
279
|
module.exports.cast = {
|
|
@@ -283,6 +285,19 @@ module.exports.cast = {
|
|
|
283
285
|
deleteMany: module.exports.castDeleteMany
|
|
284
286
|
};
|
|
285
287
|
|
|
288
|
+
function _castFilter(model, filter, options) {
|
|
289
|
+
try {
|
|
290
|
+
return cast(model.schema, filter, options);
|
|
291
|
+
} catch (err) {
|
|
292
|
+
// Set the model on cast errors so `{MODEL}` gets replaced, like it is for
|
|
293
|
+
// query filter casting (gh-8300)
|
|
294
|
+
if (typeof err.setModel === 'function') {
|
|
295
|
+
err.setModel(model);
|
|
296
|
+
}
|
|
297
|
+
throw err;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
286
301
|
function _addDiscriminatorToObject(schema, obj) {
|
|
287
302
|
if (schema == null) {
|
|
288
303
|
return;
|
|
@@ -97,7 +97,15 @@ function _castExpression(val, schema, strictQuery) {
|
|
|
97
97
|
val.$ifNull.map(v => _castExpression(v, schema, strictQuery));
|
|
98
98
|
} else if (val.$switch != null) {
|
|
99
99
|
if (Array.isArray(val.$switch.branches)) {
|
|
100
|
-
|
|
100
|
+
for (const branch of val.$switch.branches) {
|
|
101
|
+
if (branch?.case != null) {
|
|
102
|
+
branch.case = _castExpression(branch.case, schema, strictQuery);
|
|
103
|
+
}
|
|
104
|
+
if (branch?.then != null) {
|
|
105
|
+
branch.then = _castExpression(branch.then, schema, strictQuery);
|
|
106
|
+
}
|
|
107
|
+
omitUndefined(branch);
|
|
108
|
+
}
|
|
101
109
|
}
|
|
102
110
|
if ('default' in val.$switch) {
|
|
103
111
|
val.$switch.default = _castExpression(val.$switch.default, schema, strictQuery);
|
|
@@ -262,7 +262,16 @@ function walkUpdatePath(schema, obj, op, options, context, filter, prefix) {
|
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
264
|
if (schematype?.schema != null) {
|
|
265
|
-
|
|
265
|
+
try {
|
|
266
|
+
obj[key] = cast(schematype.schema, obj[key], options, context);
|
|
267
|
+
} catch (error) {
|
|
268
|
+
if (error instanceof CastError) {
|
|
269
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
270
|
+
continue;
|
|
271
|
+
} else {
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
266
275
|
hasKeys = true;
|
|
267
276
|
continue;
|
|
268
277
|
}
|
|
@@ -446,11 +455,15 @@ function walkUpdatePath(schema, obj, op, options, context, filter, prefix) {
|
|
|
446
455
|
}
|
|
447
456
|
} else {
|
|
448
457
|
if (op === '$rename') {
|
|
449
|
-
|
|
450
|
-
|
|
458
|
+
try {
|
|
459
|
+
if (obj[key] == null) {
|
|
460
|
+
throw new CastError('String', obj[key], `${prefix}${key}.$rename`);
|
|
461
|
+
}
|
|
462
|
+
const schematype = new SchemaString(`${prefix}${key}.$rename`, null, null, schema);
|
|
463
|
+
obj[key] = schematype.castForQuery(null, obj[key], context);
|
|
464
|
+
} catch (error) {
|
|
465
|
+
aggregatedError = _appendError(error, context, key, aggregatedError);
|
|
451
466
|
}
|
|
452
|
-
const schematype = new SchemaString(`${prefix}${key}.$rename`, null, null, schema);
|
|
453
|
-
obj[key] = schematype.castForQuery(null, obj[key], context);
|
|
454
467
|
continue;
|
|
455
468
|
}
|
|
456
469
|
|
|
@@ -499,6 +512,14 @@ function walkUpdatePath(schema, obj, op, options, context, filter, prefix) {
|
|
|
499
512
|
*/
|
|
500
513
|
|
|
501
514
|
function _appendError(error, query, key, aggregatedError) {
|
|
515
|
+
// Set the model on cast errors so `{MODEL}` gets replaced, like it is for
|
|
516
|
+
// query filter casting and document validation (gh-8300). `query` is a
|
|
517
|
+
// Query, or the model itself when casting a `bulkWrite()` operation.
|
|
518
|
+
const model = query?.modelName != null ? query : query?.model;
|
|
519
|
+
if (model != null && typeof error.setModel === 'function') {
|
|
520
|
+
error.setModel(model);
|
|
521
|
+
}
|
|
522
|
+
|
|
502
523
|
if (typeof query !== 'object' || !query.options.multipleCastError) {
|
|
503
524
|
throw error;
|
|
504
525
|
}
|
package/lib/model.js
CHANGED
|
@@ -3676,7 +3676,8 @@ Model.bulkSave = async function bulkSave(documents, options) {
|
|
|
3676
3676
|
|
|
3677
3677
|
await Promise.all(documents.map(doc => buildPreSavePromise(doc, options)));
|
|
3678
3678
|
|
|
3679
|
-
const
|
|
3679
|
+
const documentIndexes = [];
|
|
3680
|
+
const writeOperations = this.buildBulkWriteOperations(documents, options, documentIndexes);
|
|
3680
3681
|
const opts = { skipValidation: true, _skipCastBulkWrite: true, ...options };
|
|
3681
3682
|
const { bulkWriteResult, bulkWriteError } = await this.bulkWrite(writeOperations, opts).then(
|
|
3682
3683
|
(res) => ({ bulkWriteResult: res, bulkWriteError: null }),
|
|
@@ -3697,20 +3698,22 @@ Model.bulkSave = async function bulkSave(documents, options) {
|
|
|
3697
3698
|
);
|
|
3698
3699
|
}
|
|
3699
3700
|
|
|
3700
|
-
const
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
|
|
3707
|
-
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
successfulDocuments.
|
|
3701
|
+
const writeErrors = bulkWriteError?.writeErrors || [];
|
|
3702
|
+
let successfulDocuments = documents;
|
|
3703
|
+
if (writeErrors.length > 0) {
|
|
3704
|
+
if (options.ordered !== false) {
|
|
3705
|
+
// Unchanged documents don't generate operations, so map back to the input before slicing.
|
|
3706
|
+
successfulDocuments = documents.slice(0, documentIndexes[writeErrors[0].index]);
|
|
3707
|
+
} else {
|
|
3708
|
+
const failedDocumentIndexes = documents.length >= 25 ? {} : null;
|
|
3709
|
+
if (failedDocumentIndexes != null) {
|
|
3710
|
+
for (const writeError of writeErrors) {
|
|
3711
|
+
failedDocumentIndexes[documentIndexes[writeError.index]] = true;
|
|
3712
|
+
}
|
|
3713
|
+
}
|
|
3714
|
+
successfulDocuments = documents.filter((document, i) => failedDocumentIndexes == null ?
|
|
3715
|
+
!writeErrors.some(writeError => documentIndexes[writeError.index] === i) :
|
|
3716
|
+
!failedDocumentIndexes[i]);
|
|
3714
3717
|
}
|
|
3715
3718
|
}
|
|
3716
3719
|
await Promise.all(successfulDocuments.map(document => handleSuccessfulWrite(document, options)));
|
|
@@ -3976,11 +3979,12 @@ Model.castObject = function castObject(obj, options) {
|
|
|
3976
3979
|
* @param {object} options
|
|
3977
3980
|
* @param {boolean} options.skipValidation defaults to `false`, when set to true, building the write operations will bypass validating the documents.
|
|
3978
3981
|
* @param {boolean} options.timestamps defaults to `null`, when set to false, mongoose will not add/update timestamps to the documents.
|
|
3982
|
+
* @param {number[]} [documentIndexes] If provided, receives the input document index for each generated operation in order.
|
|
3979
3983
|
* @return {Promise[]} Returns a array of all Promises the function executes to be awaited.
|
|
3980
3984
|
* @api private
|
|
3981
3985
|
*/
|
|
3982
3986
|
|
|
3983
|
-
Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, options) {
|
|
3987
|
+
Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, options, documentIndexes) {
|
|
3984
3988
|
if (!Array.isArray(documents)) {
|
|
3985
3989
|
throw new MongooseError(`bulkSave expects an array of documents to be passed, received \`${documents}\` instead`);
|
|
3986
3990
|
}
|
|
@@ -4010,6 +4014,7 @@ Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, op
|
|
|
4010
4014
|
}
|
|
4011
4015
|
const writeOperation = { insertOne: { document } };
|
|
4012
4016
|
utils.injectTimestampsOption(writeOperation.insertOne, options.timestamps);
|
|
4017
|
+
documentIndexes?.push(i);
|
|
4013
4018
|
return writeOperation;
|
|
4014
4019
|
}
|
|
4015
4020
|
|
|
@@ -4036,6 +4041,7 @@ Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, op
|
|
|
4036
4041
|
document.$__version(where, delta);
|
|
4037
4042
|
const writeOperation = { updateOne: { filter: where, update: changes } };
|
|
4038
4043
|
utils.injectTimestampsOption(writeOperation.updateOne, options.timestamps);
|
|
4044
|
+
documentIndexes?.push(i);
|
|
4039
4045
|
return writeOperation;
|
|
4040
4046
|
}
|
|
4041
4047
|
|
|
@@ -4763,7 +4769,10 @@ async function _populatePath(model, docs, populateOptions) {
|
|
|
4763
4769
|
// Get the assigned (filtered) children from parent docs
|
|
4764
4770
|
const childDocsToPopulate = [];
|
|
4765
4771
|
for (const doc of mod.docs) {
|
|
4766
|
-
|
|
4772
|
+
// `utils.getValue()` rather than a bracket lookup, because `mod.options.path` may be
|
|
4773
|
+
// a dotted path like 'children.child', which a lean result does not store as a
|
|
4774
|
+
// single key.
|
|
4775
|
+
const childVal = doc.$__ != null ? doc.get(mod.options.path) : utils.getValue(mod.options.path, doc);
|
|
4767
4776
|
if (Array.isArray(childVal)) {
|
|
4768
4777
|
childDocsToPopulate.push(...childVal);
|
|
4769
4778
|
} else if (childVal != null) {
|
package/lib/schema/union.js
CHANGED
|
@@ -60,6 +60,10 @@ class Union extends SchemaType {
|
|
|
60
60
|
|
|
61
61
|
// Setters also need to be aware of casting - we need to apply the setters of the entry in the union we choose.
|
|
62
62
|
applySetters(val, doc, init, prev, options) {
|
|
63
|
+
// Setters on the union path itself run first, so they can change which entry
|
|
64
|
+
// in the union the value resolves to.
|
|
65
|
+
val = this._applySetters(val, doc, init, prev, options);
|
|
66
|
+
|
|
63
67
|
let firstValue = firstValueSymbol;
|
|
64
68
|
let lastError;
|
|
65
69
|
// Loop through each schema type in the union. If one of the schematypes returns a value that is `=== val`, then
|
|
@@ -544,11 +544,13 @@ const methods = {
|
|
|
544
544
|
if (isBsonType(obj, 'ObjectId')) {
|
|
545
545
|
obj = obj.toString();
|
|
546
546
|
}
|
|
547
|
+
// Compare dates by timestamp like `addToSet()` does, so `pull()` works on date arrays
|
|
548
|
+
const isDate = obj instanceof Date;
|
|
547
549
|
|
|
548
550
|
fromIndex = fromIndex == null ? 0 : fromIndex;
|
|
549
551
|
const len = this.length;
|
|
550
552
|
for (let i = fromIndex; i < len; ++i) {
|
|
551
|
-
if (obj == this[i]) {
|
|
553
|
+
if (obj == this[i] || (isDate && this[i] instanceof Date && +obj === +this[i])) {
|
|
552
554
|
return i;
|
|
553
555
|
}
|
|
554
556
|
}
|
package/lib/types/map.js
CHANGED
|
@@ -4,6 +4,7 @@ const Mixed = require('../schema/mixed');
|
|
|
4
4
|
const MongooseError = require('../error/mongooseError');
|
|
5
5
|
const clone = require('../helpers/clone');
|
|
6
6
|
const deepEqual = require('../utils').deepEqual;
|
|
7
|
+
const isMongooseArray = require('../utils').isMongooseArray;
|
|
7
8
|
const getConstructorName = require('../helpers/getConstructorName');
|
|
8
9
|
const handleSpreadDoc = require('../helpers/document/handleSpreadDoc');
|
|
9
10
|
const util = require('util');
|
|
@@ -160,6 +161,11 @@ class MongooseMap extends Map {
|
|
|
160
161
|
if (parent?.$__ != null && !deepEqual(value, priorVal)) {
|
|
161
162
|
const path = fullPath.call(this);
|
|
162
163
|
parent.markModified(path);
|
|
164
|
+
// Replacing the whole array means later push(), pull() or addToSet() calls must not be sent as
|
|
165
|
+
// atomics against the array that was in the database, same as Document#$set re: gh-1126
|
|
166
|
+
if (isMongooseArray(value)) {
|
|
167
|
+
value._registerAtomic('$set', value);
|
|
168
|
+
}
|
|
163
169
|
// If overwriting the full document array or subdoc, make sure to clean up any paths that were modified
|
|
164
170
|
// before re: #15108
|
|
165
171
|
if (this.$__schemaType.$isMongooseDocumentArray || this.$__schemaType.$isSingleNested) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "9.10.
|
|
4
|
+
"version": "9.10.4",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -29,9 +29,9 @@
|
|
|
29
29
|
"sift": "17.1.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@ark/attest": "0.56.
|
|
32
|
+
"@ark/attest": "0.56.5",
|
|
33
33
|
"@eslint/js": "^9.39.3",
|
|
34
|
-
"@mongodb-js/mongodb-downloader": "^
|
|
34
|
+
"@mongodb-js/mongodb-downloader": "^2.0.2",
|
|
35
35
|
"@types/node": "^20.19.0",
|
|
36
36
|
"acquit": "1.4.0",
|
|
37
37
|
"acquit-ignore": "0.2.2",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"c8": "12.0.0",
|
|
41
41
|
"cheerio": "1.2.0",
|
|
42
42
|
"dox": "1.0.0",
|
|
43
|
-
"eslint": "10.
|
|
43
|
+
"eslint": "10.11.0",
|
|
44
44
|
"eslint-plugin-mocha-no-only": "1.2.0",
|
|
45
45
|
"express": "5.2.1",
|
|
46
46
|
"fs-extra": "~11.4.0",
|
|
@@ -50,13 +50,13 @@
|
|
|
50
50
|
"linkinator": "8.x",
|
|
51
51
|
"lodash.isequal": "4.5.0",
|
|
52
52
|
"lodash.isequalwith": "4.4.0",
|
|
53
|
-
"markdownlint-cli2": "0.23.
|
|
54
|
-
"marked": "18.0.
|
|
53
|
+
"markdownlint-cli2": "0.23.3",
|
|
54
|
+
"marked": "18.0.14",
|
|
55
55
|
"mkdirp": "^3.0.1",
|
|
56
|
-
"mocha": "12.0.
|
|
57
|
-
"moment": "2.
|
|
56
|
+
"mocha": "12.0.2",
|
|
57
|
+
"moment": "2.31.0",
|
|
58
58
|
"mongodb-client-encryption": "^7.2.0",
|
|
59
|
-
"mongodb-memory-server": "11.
|
|
59
|
+
"mongodb-memory-server": "11.3.0",
|
|
60
60
|
"mongodb-runner": "^6.0.0",
|
|
61
61
|
"ncp": "^2.0.0",
|
|
62
62
|
"pug": "3.0.4",
|