mongoose 8.14.3 → 8.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.umd.js +1 -1
- package/lib/cursor/queryCursor.js +37 -41
- package/lib/drivers/node-mongodb-native/connection.js +65 -0
- package/lib/drivers/node-mongodb-native/index.js +1 -0
- package/lib/error/serverSelection.js +1 -0
- package/lib/helpers/model/discriminator.js +47 -0
- package/lib/helpers/query/cast$expr.js +4 -1
- package/lib/model.js +50 -23
- package/lib/query.js +60 -2
- package/lib/schema/array.js +4 -0
- package/lib/schema/bigint.js +4 -0
- package/lib/schema/boolean.js +4 -0
- package/lib/schema/buffer.js +4 -0
- package/lib/schema/date.js +4 -0
- package/lib/schema/decimal128.js +4 -0
- package/lib/schema/double.js +4 -0
- package/lib/schema/int32.js +4 -0
- package/lib/schema/map.js +4 -0
- package/lib/schema/objectId.js +4 -0
- package/lib/schema/string.js +4 -0
- package/lib/schema/uuid.js +4 -0
- package/lib/schema.js +182 -2
- package/lib/schemaType.js +8 -0
- package/package.json +4 -2
- package/types/index.d.ts +37 -3
- package/types/models.d.ts +6 -0
- package/types/pipelinestage.d.ts +2 -1
- package/types/query.d.ts +1 -1
- package/types/schemaoptions.d.ts +5 -0
- package/types/schematypes.d.ts +29 -0
- package/types/types.d.ts +2 -2
- package/types/utility.d.ts +31 -7
package/lib/schema/decimal128.js
CHANGED
|
@@ -235,6 +235,10 @@ SchemaDecimal128.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
235
235
|
return createJSONSchemaTypeDefinition('string', 'decimal', options?.useBsonType, isRequired);
|
|
236
236
|
};
|
|
237
237
|
|
|
238
|
+
SchemaDecimal128.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
239
|
+
return 'decimal';
|
|
240
|
+
};
|
|
241
|
+
|
|
238
242
|
/*!
|
|
239
243
|
* Module exports.
|
|
240
244
|
*/
|
package/lib/schema/double.js
CHANGED
|
@@ -218,6 +218,10 @@ SchemaDouble.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
218
218
|
return createJSONSchemaTypeDefinition('number', 'double', options?.useBsonType, isRequired);
|
|
219
219
|
};
|
|
220
220
|
|
|
221
|
+
SchemaDouble.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
222
|
+
return 'double';
|
|
223
|
+
};
|
|
224
|
+
|
|
221
225
|
/*!
|
|
222
226
|
* Module exports.
|
|
223
227
|
*/
|
package/lib/schema/int32.js
CHANGED
|
@@ -260,6 +260,10 @@ SchemaInt32.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
260
260
|
return createJSONSchemaTypeDefinition('number', 'int', options?.useBsonType, isRequired);
|
|
261
261
|
};
|
|
262
262
|
|
|
263
|
+
SchemaInt32.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
264
|
+
return 'int';
|
|
265
|
+
};
|
|
266
|
+
|
|
263
267
|
|
|
264
268
|
/*!
|
|
265
269
|
* Module exports.
|
package/lib/schema/map.js
CHANGED
package/lib/schema/objectId.js
CHANGED
|
@@ -304,6 +304,10 @@ SchemaObjectId.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
304
304
|
return createJSONSchemaTypeDefinition('string', 'objectId', options?.useBsonType, isRequired);
|
|
305
305
|
};
|
|
306
306
|
|
|
307
|
+
SchemaObjectId.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
308
|
+
return 'objectId';
|
|
309
|
+
};
|
|
310
|
+
|
|
307
311
|
/*!
|
|
308
312
|
* Module exports.
|
|
309
313
|
*/
|
package/lib/schema/string.js
CHANGED
|
@@ -712,6 +712,10 @@ SchemaString.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
712
712
|
return createJSONSchemaTypeDefinition('string', 'string', options?.useBsonType, isRequired);
|
|
713
713
|
};
|
|
714
714
|
|
|
715
|
+
SchemaString.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
716
|
+
return 'string';
|
|
717
|
+
};
|
|
718
|
+
|
|
715
719
|
/*!
|
|
716
720
|
* Module exports.
|
|
717
721
|
*/
|
package/lib/schema/uuid.js
CHANGED
|
@@ -298,6 +298,10 @@ SchemaUUID.prototype.toJSONSchema = function toJSONSchema(options) {
|
|
|
298
298
|
return createJSONSchemaTypeDefinition('string', 'binData', options?.useBsonType, isRequired);
|
|
299
299
|
};
|
|
300
300
|
|
|
301
|
+
SchemaUUID.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
302
|
+
return 'binData';
|
|
303
|
+
};
|
|
304
|
+
|
|
301
305
|
/*!
|
|
302
306
|
* Module exports.
|
|
303
307
|
*/
|
package/lib/schema.js
CHANGED
|
@@ -86,6 +86,7 @@ const numberRE = /^\d+$/;
|
|
|
86
86
|
* - [pluginTags](https://mongoosejs.com/docs/guide.html#pluginTags): array of strings - defaults to `undefined`. If set and plugin called with `tags` option, will only apply that plugin to schemas with a matching tag.
|
|
87
87
|
* - [virtuals](https://mongoosejs.com/docs/tutorials/virtuals.html#virtuals-via-schema-options): object - virtuals to define, alias for [`.virtual`](https://mongoosejs.com/docs/api/schema.html#Schema.prototype.virtual())
|
|
88
88
|
* - [collectionOptions]: object with options passed to [`createCollection()`](https://www.mongodb.com/docs/manual/reference/method/db.createCollection/) when calling `Model.createCollection()` or `autoCreate` set to true.
|
|
89
|
+
* - [encryptionType]: the encryption type for the schema. Valid options are `csfle` or `queryableEncryption`. See https://mongoosejs.com/docs/field-level-encryption.
|
|
89
90
|
*
|
|
90
91
|
* #### Options for Nested Schemas:
|
|
91
92
|
*
|
|
@@ -128,6 +129,7 @@ function Schema(obj, options) {
|
|
|
128
129
|
// For internal debugging. Do not use this to try to save a schema in MDB.
|
|
129
130
|
this.$id = ++id;
|
|
130
131
|
this.mapPaths = [];
|
|
132
|
+
this.encryptedFields = {};
|
|
131
133
|
|
|
132
134
|
this.s = {
|
|
133
135
|
hooks: new Kareem()
|
|
@@ -463,6 +465,8 @@ Schema.prototype._clone = function _clone(Constructor) {
|
|
|
463
465
|
|
|
464
466
|
s.aliases = Object.assign({}, this.aliases);
|
|
465
467
|
|
|
468
|
+
s.encryptedFields = clone(this.encryptedFields);
|
|
469
|
+
|
|
466
470
|
return s;
|
|
467
471
|
};
|
|
468
472
|
|
|
@@ -495,7 +499,16 @@ Schema.prototype.pick = function(paths, options) {
|
|
|
495
499
|
}
|
|
496
500
|
|
|
497
501
|
for (const path of paths) {
|
|
498
|
-
if (this.
|
|
502
|
+
if (this._hasEncryptedField(path)) {
|
|
503
|
+
const encrypt = this.encryptedFields[path];
|
|
504
|
+
const schemaType = this.path(path);
|
|
505
|
+
newSchema.add({
|
|
506
|
+
[path]: {
|
|
507
|
+
encrypt,
|
|
508
|
+
[this.options.typeKey]: schemaType
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
} else if (this.nested[path]) {
|
|
499
512
|
newSchema.add({ [path]: get(this.tree, path) });
|
|
500
513
|
} else {
|
|
501
514
|
const schematype = this.path(path);
|
|
@@ -506,6 +519,10 @@ Schema.prototype.pick = function(paths, options) {
|
|
|
506
519
|
}
|
|
507
520
|
}
|
|
508
521
|
|
|
522
|
+
if (!this._hasEncryptedFields()) {
|
|
523
|
+
newSchema.options.encryptionType = null;
|
|
524
|
+
}
|
|
525
|
+
|
|
509
526
|
return newSchema;
|
|
510
527
|
};
|
|
511
528
|
|
|
@@ -667,6 +684,22 @@ Schema.prototype._defaultToObjectOptions = function(json) {
|
|
|
667
684
|
return defaultOptions;
|
|
668
685
|
};
|
|
669
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Sets the encryption type of the schema, if a value is provided, otherwise
|
|
689
|
+
* returns the encryption type.
|
|
690
|
+
*
|
|
691
|
+
* @param {'csfle' | 'queryableEncryption' | null | undefined} encryptionType plain object with paths to add, or another schema
|
|
692
|
+
*/
|
|
693
|
+
Schema.prototype.encryptionType = function encryptionType(encryptionType) {
|
|
694
|
+
if (arguments.length === 0) {
|
|
695
|
+
return this.options.encryptionType;
|
|
696
|
+
}
|
|
697
|
+
if (!(typeof encryptionType === 'string' || encryptionType === null)) {
|
|
698
|
+
throw new Error('invalid `encryptionType`: ${encryptionType}');
|
|
699
|
+
}
|
|
700
|
+
this.options.encryptionType = encryptionType;
|
|
701
|
+
};
|
|
702
|
+
|
|
670
703
|
/**
|
|
671
704
|
* Adds key path / schema type pairs to this schema.
|
|
672
705
|
*
|
|
@@ -689,7 +722,6 @@ Schema.prototype._defaultToObjectOptions = function(json) {
|
|
|
689
722
|
Schema.prototype.add = function add(obj, prefix) {
|
|
690
723
|
if (obj instanceof Schema || (obj != null && obj.instanceOfSchema)) {
|
|
691
724
|
merge(this, obj);
|
|
692
|
-
|
|
693
725
|
return this;
|
|
694
726
|
}
|
|
695
727
|
|
|
@@ -818,6 +850,31 @@ Schema.prototype.add = function add(obj, prefix) {
|
|
|
818
850
|
}
|
|
819
851
|
}
|
|
820
852
|
}
|
|
853
|
+
|
|
854
|
+
if (val.instanceOfSchema && val.encryptionType() != null) {
|
|
855
|
+
// schema.add({ field: <instance of encrypted schema> })
|
|
856
|
+
if (this.encryptionType() != val.encryptionType()) {
|
|
857
|
+
throw new Error('encryptionType of a nested schema must match the encryption type of the parent schema.');
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
for (const [encryptedField, encryptedFieldConfig] of Object.entries(val.encryptedFields)) {
|
|
861
|
+
const path = fullPath + '.' + encryptedField;
|
|
862
|
+
this._addEncryptedField(path, encryptedFieldConfig);
|
|
863
|
+
}
|
|
864
|
+
} else if (typeof val === 'object' && 'encrypt' in val) {
|
|
865
|
+
// schema.add({ field: { type: <schema type>, encrypt: { ... }}})
|
|
866
|
+
const { encrypt } = val;
|
|
867
|
+
|
|
868
|
+
if (this.encryptionType() == null) {
|
|
869
|
+
throw new Error('encryptionType must be provided');
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
this._addEncryptedField(fullPath, encrypt);
|
|
873
|
+
} else {
|
|
874
|
+
// if the field was already encrypted and we re-configure it to be unencrypted, remove
|
|
875
|
+
// the encrypted field configuration
|
|
876
|
+
this._removeEncryptedField(fullPath);
|
|
877
|
+
}
|
|
821
878
|
}
|
|
822
879
|
|
|
823
880
|
const aliasObj = Object.fromEntries(
|
|
@@ -827,6 +884,117 @@ Schema.prototype.add = function add(obj, prefix) {
|
|
|
827
884
|
return this;
|
|
828
885
|
};
|
|
829
886
|
|
|
887
|
+
/**
|
|
888
|
+
* @param {string} path
|
|
889
|
+
* @param {object} fieldConfig
|
|
890
|
+
*
|
|
891
|
+
* @api private
|
|
892
|
+
*/
|
|
893
|
+
Schema.prototype._addEncryptedField = function _addEncryptedField(path, fieldConfig) {
|
|
894
|
+
const type = this.path(path).autoEncryptionType();
|
|
895
|
+
if (type == null) {
|
|
896
|
+
throw new Error(`Invalid BSON type for FLE field: '${path}'`);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
this.encryptedFields[path] = clone(fieldConfig);
|
|
900
|
+
};
|
|
901
|
+
|
|
902
|
+
/**
|
|
903
|
+
* @param {string} path
|
|
904
|
+
*
|
|
905
|
+
* @api private
|
|
906
|
+
*/
|
|
907
|
+
Schema.prototype._removeEncryptedField = function _removeEncryptedField(path) {
|
|
908
|
+
delete this.encryptedFields[path];
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
/**
|
|
912
|
+
* @api private
|
|
913
|
+
*
|
|
914
|
+
* @returns {boolean}
|
|
915
|
+
*/
|
|
916
|
+
Schema.prototype._hasEncryptedFields = function _hasEncryptedFields() {
|
|
917
|
+
return Object.keys(this.encryptedFields).length > 0;
|
|
918
|
+
};
|
|
919
|
+
|
|
920
|
+
/**
|
|
921
|
+
* @param {string} path
|
|
922
|
+
* @returns {boolean}
|
|
923
|
+
*
|
|
924
|
+
* @api private
|
|
925
|
+
*/
|
|
926
|
+
Schema.prototype._hasEncryptedField = function _hasEncryptedField(path) {
|
|
927
|
+
return path in this.encryptedFields;
|
|
928
|
+
};
|
|
929
|
+
|
|
930
|
+
|
|
931
|
+
/**
|
|
932
|
+
* Builds an encryptedFieldsMap for the schema.
|
|
933
|
+
*
|
|
934
|
+
* @api private
|
|
935
|
+
*/
|
|
936
|
+
Schema.prototype._buildEncryptedFields = function() {
|
|
937
|
+
const fields = Object.entries(this.encryptedFields).map(
|
|
938
|
+
([path, config]) => {
|
|
939
|
+
const bsonType = this.path(path).autoEncryptionType();
|
|
940
|
+
// { path, bsonType, keyId, queries? }
|
|
941
|
+
return { path, bsonType, ...config };
|
|
942
|
+
});
|
|
943
|
+
|
|
944
|
+
return { fields };
|
|
945
|
+
};
|
|
946
|
+
|
|
947
|
+
/**
|
|
948
|
+
* Builds a schemaMap for the schema, if the schema is configured for client-side field level encryption.
|
|
949
|
+
*
|
|
950
|
+
* @api private
|
|
951
|
+
*/
|
|
952
|
+
Schema.prototype._buildSchemaMap = function() {
|
|
953
|
+
/**
|
|
954
|
+
* `schemaMap`s are JSON schemas, which use the following structure to represent objects:
|
|
955
|
+
* { field: { bsonType: 'object', properties: { ... } } }
|
|
956
|
+
*
|
|
957
|
+
* for example, a schema that looks like this `{ a: { b: int32 } }` would be encoded as
|
|
958
|
+
* `{ a: { bsonType: 'object', properties: { b: < encryption configuration > } } }`
|
|
959
|
+
*
|
|
960
|
+
* This function takes an array of path segments, an output object (that gets mutated) and
|
|
961
|
+
* a value to be associated with the full path, and constructs a valid CSFLE JSON schema path for
|
|
962
|
+
* the object. This works for deeply nested properties as well.
|
|
963
|
+
*
|
|
964
|
+
* @param {string[]} path array of path components
|
|
965
|
+
* @param {object} object the object in which to build a JSON schema of `path`'s properties
|
|
966
|
+
* @param {object} value the value to associate with the path in object
|
|
967
|
+
*/
|
|
968
|
+
function buildNestedPath(path, object, value) {
|
|
969
|
+
let i = 0, component = path[i];
|
|
970
|
+
for (; i < path.length - 1; ++i, component = path[i]) {
|
|
971
|
+
object[component] = object[component] == null ? {
|
|
972
|
+
bsonType: 'object',
|
|
973
|
+
properties: {}
|
|
974
|
+
} : object[component];
|
|
975
|
+
object = object[component].properties;
|
|
976
|
+
}
|
|
977
|
+
object[component] = value;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const schemaMapPropertyReducer = (accum, [path, propertyConfig]) => {
|
|
981
|
+
const bsonType = this.path(path).autoEncryptionType();
|
|
982
|
+
const pathComponents = path.split('.');
|
|
983
|
+
const configuration = { encrypt: { ...propertyConfig, bsonType } };
|
|
984
|
+
buildNestedPath(pathComponents, accum, configuration);
|
|
985
|
+
return accum;
|
|
986
|
+
};
|
|
987
|
+
|
|
988
|
+
const properties = Object.entries(this.encryptedFields).reduce(
|
|
989
|
+
schemaMapPropertyReducer,
|
|
990
|
+
{});
|
|
991
|
+
|
|
992
|
+
return {
|
|
993
|
+
bsonType: 'object',
|
|
994
|
+
properties
|
|
995
|
+
};
|
|
996
|
+
};
|
|
997
|
+
|
|
830
998
|
/**
|
|
831
999
|
* Add an alias for `path`. This means getting or setting the `alias`
|
|
832
1000
|
* is equivalent to getting or setting the `path`.
|
|
@@ -1378,6 +1546,16 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
|
|
|
1378
1546
|
let type = obj[options.typeKey] && (obj[options.typeKey] instanceof Function || options.typeKey !== 'type' || !obj.type.type)
|
|
1379
1547
|
? obj[options.typeKey]
|
|
1380
1548
|
: {};
|
|
1549
|
+
|
|
1550
|
+
if (type instanceof SchemaType) {
|
|
1551
|
+
if (type.path === path) {
|
|
1552
|
+
return type;
|
|
1553
|
+
}
|
|
1554
|
+
const clone = type.clone();
|
|
1555
|
+
clone.path = path;
|
|
1556
|
+
return clone;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1381
1559
|
let name;
|
|
1382
1560
|
|
|
1383
1561
|
if (utils.isPOJO(type) || type === 'mixed') {
|
|
@@ -2523,6 +2701,8 @@ Schema.prototype.remove = function(path) {
|
|
|
2523
2701
|
|
|
2524
2702
|
delete this.paths[name];
|
|
2525
2703
|
_deletePath(this, name);
|
|
2704
|
+
|
|
2705
|
+
this._removeEncryptedField(name);
|
|
2526
2706
|
}, this);
|
|
2527
2707
|
}
|
|
2528
2708
|
return this;
|
package/lib/schemaType.js
CHANGED
|
@@ -1783,6 +1783,14 @@ SchemaType.prototype.toJSONSchema = function toJSONSchema() {
|
|
|
1783
1783
|
throw new Error('Converting unsupported SchemaType to JSON Schema: ' + this.instance);
|
|
1784
1784
|
};
|
|
1785
1785
|
|
|
1786
|
+
/**
|
|
1787
|
+
* Returns the BSON type that the schema corresponds to, for automatic encryption.
|
|
1788
|
+
* @api private
|
|
1789
|
+
*/
|
|
1790
|
+
SchemaType.prototype.autoEncryptionType = function autoEncryptionType() {
|
|
1791
|
+
return null;
|
|
1792
|
+
};
|
|
1793
|
+
|
|
1786
1794
|
/*!
|
|
1787
1795
|
* Module exports.
|
|
1788
1796
|
*/
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mongoose",
|
|
3
3
|
"description": "Mongoose MongoDB ODM",
|
|
4
|
-
"version": "8.
|
|
4
|
+
"version": "8.15.1",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@babel/core": "7.27.1",
|
|
33
33
|
"@babel/preset-env": "7.27.1",
|
|
34
|
+
"@mongodb-js/mongodb-downloader": "^0.3.9",
|
|
34
35
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
35
36
|
"@typescript-eslint/parser": "^8.19.1",
|
|
36
37
|
"acquit": "1.3.0",
|
|
@@ -58,6 +59,7 @@
|
|
|
58
59
|
"mocha": "11.2.2",
|
|
59
60
|
"moment": "2.30.1",
|
|
60
61
|
"mongodb-memory-server": "10.1.4",
|
|
62
|
+
"mongodb-runner": "^5.8.2",
|
|
61
63
|
"ncp": "^2.0.0",
|
|
62
64
|
"nyc": "15.1.0",
|
|
63
65
|
"pug": "3.0.3",
|
|
@@ -104,7 +106,7 @@
|
|
|
104
106
|
"test-deno": "deno run --allow-env --allow-read --allow-net --allow-run --allow-sys --allow-write ./test/deno.mjs",
|
|
105
107
|
"test-rs": "START_REPLICA_SET=1 mocha --timeout 30000 --exit ./test/*.test.js",
|
|
106
108
|
"test-tsd": "node ./test/types/check-types-filename && tsd",
|
|
107
|
-
"setup-test-encryption": "
|
|
109
|
+
"setup-test-encryption": "node scripts/setup-encryption-tests.js",
|
|
108
110
|
"test-encryption": "mocha --exit ./test/encryption/*.test.js",
|
|
109
111
|
"tdd": "mocha ./test/*.test.js --inspect --watch --recursive --watch-files ./**/*.{js,ts}",
|
|
110
112
|
"test-coverage": "nyc --reporter=html --reporter=text npm test",
|
package/types/index.d.ts
CHANGED
|
@@ -657,9 +657,43 @@ declare module 'mongoose' {
|
|
|
657
657
|
|
|
658
658
|
export type ReturnsNewDoc = { new: true } | { returnOriginal: false } | { returnDocument: 'after' };
|
|
659
659
|
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
660
|
+
type ArrayOperators = { $slice: number | [number, number]; $elemMatch?: never } | { $elemMatch: Record<string, any>; $slice?: never };
|
|
661
|
+
/**
|
|
662
|
+
* This Type Assigns `Element | undefined` recursively to the `T` type.
|
|
663
|
+
* if it is an array it will do this to the element of the array, if it is an object it will do this for the properties of the object.
|
|
664
|
+
* `Element` is the truthy or falsy values that are going to be used as the value of the projection.(1 | true or 0 | false)
|
|
665
|
+
* For the elements of the array we will use: `Element | `undefined` | `ArrayOperators`
|
|
666
|
+
* @example
|
|
667
|
+
* type CalculatedType = Projector<{ a: string, b: number, c: { d: string }, d: string[] }, true>
|
|
668
|
+
* type CalculatedType = {
|
|
669
|
+
a?: true | undefined;
|
|
670
|
+
b?: true | undefined;
|
|
671
|
+
c?: true | {
|
|
672
|
+
d?: true | undefined;
|
|
673
|
+
} | undefined;
|
|
674
|
+
d?: true | ArrayOperators | undefined;
|
|
675
|
+
}
|
|
676
|
+
*/
|
|
677
|
+
type Projector<T, Element> = T extends Array<infer U>
|
|
678
|
+
? Projector<U, Element> | ArrayOperators
|
|
679
|
+
: T extends TreatAsPrimitives
|
|
680
|
+
? Element
|
|
681
|
+
: T extends Record<string, any>
|
|
682
|
+
? {
|
|
683
|
+
[K in keyof T]?: T[K] extends Record<string, any> ? Projector<T[K], Element> | Element : Element;
|
|
684
|
+
}
|
|
685
|
+
: Element;
|
|
686
|
+
type _IDType = { _id?: boolean | 1 | 0 };
|
|
687
|
+
export type InclusionProjection<T> = IsItRecordAndNotAny<T> extends true
|
|
688
|
+
? Omit<Projector<WithLevel1NestedPaths<T>, true | 1>, '_id'> & _IDType
|
|
689
|
+
: AnyObject;
|
|
690
|
+
export type ExclusionProjection<T> = IsItRecordAndNotAny<T> extends true
|
|
691
|
+
? Omit<Projector<WithLevel1NestedPaths<T>, false | 0>, '_id'> & _IDType
|
|
692
|
+
: AnyObject;
|
|
693
|
+
|
|
694
|
+
export type ProjectionType<T> = (InclusionProjection<T> & AnyObject)
|
|
695
|
+
| (ExclusionProjection<T> & AnyObject)
|
|
696
|
+
| string;
|
|
663
697
|
export type SortValues = SortOrder;
|
|
664
698
|
|
|
665
699
|
export type SortOrder = -1 | 1 | 'asc' | 'ascending' | 'desc' | 'descending';
|
package/types/models.d.ts
CHANGED
|
@@ -919,5 +919,11 @@ declare module 'mongoose' {
|
|
|
919
919
|
'find',
|
|
920
920
|
TInstanceMethods & TVirtuals
|
|
921
921
|
>;
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* If auto encryption is enabled, returns a ClientEncryption instance that is configured with the same settings that
|
|
925
|
+
* Mongoose's underlying MongoClient is using. If the client has not yet been configured, returns null.
|
|
926
|
+
*/
|
|
927
|
+
clientEncryption(): mongodb.ClientEncryption | null;
|
|
922
928
|
}
|
|
923
929
|
}
|
package/types/pipelinestage.d.ts
CHANGED
|
@@ -319,10 +319,11 @@ declare module 'mongoose' {
|
|
|
319
319
|
export interface VectorSearch {
|
|
320
320
|
/** [`$vectorSearch` reference](https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/) */
|
|
321
321
|
$vectorSearch: {
|
|
322
|
+
exact?: boolean;
|
|
322
323
|
index: string,
|
|
323
324
|
path: string,
|
|
324
325
|
queryVector: number[],
|
|
325
|
-
numCandidates
|
|
326
|
+
numCandidates?: number,
|
|
326
327
|
limit: number,
|
|
327
328
|
filter?: Expression,
|
|
328
329
|
}
|
package/types/query.d.ts
CHANGED
|
@@ -160,7 +160,7 @@ declare module 'mongoose' {
|
|
|
160
160
|
* Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
|
|
161
161
|
*/
|
|
162
162
|
overwriteImmutable?: boolean;
|
|
163
|
-
projection?:
|
|
163
|
+
projection?: { [P in keyof DocType]?: number | string } | AnyObject | string;
|
|
164
164
|
/**
|
|
165
165
|
* if true, returns the full ModifyResult rather than just the document
|
|
166
166
|
*/
|
package/types/schemaoptions.d.ts
CHANGED
|
@@ -259,6 +259,11 @@ declare module 'mongoose' {
|
|
|
259
259
|
* @default false
|
|
260
260
|
*/
|
|
261
261
|
overwriteModels?: boolean;
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Required when the schema is encrypted.
|
|
265
|
+
*/
|
|
266
|
+
encryptionType?: 'csfle' | 'queryableEncryption';
|
|
262
267
|
}
|
|
263
268
|
|
|
264
269
|
interface DefaultSchemaOptions {
|
package/types/schematypes.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as BSON from 'bson';
|
|
2
|
+
|
|
1
3
|
declare module 'mongoose' {
|
|
2
4
|
|
|
3
5
|
/** The Mongoose Date [SchemaType](/docs/schematypes.html). */
|
|
@@ -210,6 +212,11 @@ declare module 'mongoose' {
|
|
|
210
212
|
maxlength?: number | [number, string] | readonly [number, string];
|
|
211
213
|
|
|
212
214
|
[other: string]: any;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* If set, configures the field for automatic encryption.
|
|
218
|
+
*/
|
|
219
|
+
encrypt?: EncryptSchemaTypeOptions;
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
interface Validator<DocType = any> {
|
|
@@ -221,6 +228,28 @@ declare module 'mongoose' {
|
|
|
221
228
|
|
|
222
229
|
type ValidatorFunction<DocType = any> = (this: DocType, value: any, validatorProperties?: Validator) => any;
|
|
223
230
|
|
|
231
|
+
interface QueryEncryptionEncryptOptions {
|
|
232
|
+
/** The id of the dataKey to use for encryption. Must be a BSON binary subtype 4 (UUID). */
|
|
233
|
+
keyId: BSON.Binary;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Specifies the type of queries that the field can be queried on the encrypted field.
|
|
237
|
+
*/
|
|
238
|
+
queries?: 'equality' | 'range';
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
interface ClientSideEncryptionEncryptOptions {
|
|
242
|
+
/** The id of the dataKey to use for encryption. Must be a BSON binary subtype 4 (UUID). */
|
|
243
|
+
keyId: [BSON.Binary];
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* The algorithm to use for encryption.
|
|
247
|
+
*/
|
|
248
|
+
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic' | 'AEAD_AES_256_CBC_HMAC_SHA_512-Random';
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export type EncryptSchemaTypeOptions = QueryEncryptionEncryptOptions | ClientSideEncryptionEncryptOptions;
|
|
252
|
+
|
|
224
253
|
class SchemaType<T = any, DocType = any> {
|
|
225
254
|
/** SchemaType constructor */
|
|
226
255
|
constructor(path: string, options?: AnyObject, instance?: string);
|
package/types/types.d.ts
CHANGED
|
@@ -60,7 +60,7 @@ declare module 'mongoose' {
|
|
|
60
60
|
|
|
61
61
|
class Decimal128 extends mongodb.Decimal128 { }
|
|
62
62
|
|
|
63
|
-
class DocumentArray<T, THydratedDocumentType extends Types.Subdocument<any> = Types.Subdocument<InferId<T>, any, T> & T> extends Types.Array<THydratedDocumentType> {
|
|
63
|
+
class DocumentArray<T, THydratedDocumentType extends Types.Subdocument<any, any, T> = Types.Subdocument<InferId<T>, any, T> & T> extends Types.Array<THydratedDocumentType> {
|
|
64
64
|
/** DocumentArray constructor */
|
|
65
65
|
constructor(values: AnyObject[]);
|
|
66
66
|
|
|
@@ -85,7 +85,7 @@ declare module 'mongoose' {
|
|
|
85
85
|
class ObjectId extends mongodb.ObjectId {
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
class Subdocument<IdType =
|
|
88
|
+
class Subdocument<IdType = any, TQueryHelpers = any, DocType = any> extends Document<IdType, TQueryHelpers, DocType> {
|
|
89
89
|
$isSingleNested: true;
|
|
90
90
|
|
|
91
91
|
/** Returns the top level document of this sub-document. */
|
package/types/utility.d.ts
CHANGED
|
@@ -4,20 +4,44 @@ declare module 'mongoose' {
|
|
|
4
4
|
|
|
5
5
|
type WithLevel1NestedPaths<T, K extends keyof T = keyof T> = {
|
|
6
6
|
[P in K | NestedPaths<Required<T>, K>]: P extends K
|
|
7
|
-
|
|
7
|
+
// Handle top-level paths
|
|
8
|
+
// First, drill into documents so we don't end up surfacing `$assertPopulated`, etc.
|
|
9
|
+
? Extract<NonNullable<T[P]>, Document> extends never
|
|
10
|
+
// If not a document, then return the type. Otherwise, get the DocType.
|
|
11
|
+
? NonNullable<T[P]>
|
|
12
|
+
: Extract<NonNullable<T[P]>, Document> extends Document<any, any, infer DocType, any>
|
|
13
|
+
? DocType
|
|
14
|
+
: never
|
|
15
|
+
// Handle nested paths
|
|
8
16
|
: P extends `${infer Key}.${infer Rest}`
|
|
9
17
|
? Key extends keyof T
|
|
10
|
-
?
|
|
11
|
-
? NonNullable<
|
|
12
|
-
|
|
18
|
+
? T[Key] extends (infer U)[]
|
|
19
|
+
? Rest extends keyof NonNullable<U>
|
|
20
|
+
? NonNullable<U>[Rest]
|
|
21
|
+
: never
|
|
22
|
+
: Rest extends keyof NonNullable<T[Key]>
|
|
23
|
+
? NonNullable<T[Key]>[Rest]
|
|
24
|
+
: never
|
|
13
25
|
: never
|
|
14
26
|
: never;
|
|
15
27
|
};
|
|
16
28
|
|
|
17
29
|
type NestedPaths<T, K extends keyof T> = K extends string
|
|
18
|
-
? T[K] extends
|
|
19
|
-
?
|
|
20
|
-
: never
|
|
30
|
+
? T[K] extends TreatAsPrimitives
|
|
31
|
+
? never
|
|
32
|
+
: Extract<NonNullable<T[K]>, Document> extends never
|
|
33
|
+
? T[K] extends Array<infer U>
|
|
34
|
+
? U extends Record<string, any>
|
|
35
|
+
? `${K}.${keyof NonNullable<U> & string}`
|
|
36
|
+
: never
|
|
37
|
+
: T[K] extends Record<string, any> | null | undefined
|
|
38
|
+
? `${K}.${keyof NonNullable<T[K]> & string}`
|
|
39
|
+
: never
|
|
40
|
+
: Extract<NonNullable<T[K]>, Document> extends Document<any, any, infer DocType, any>
|
|
41
|
+
? DocType extends Record<string, any>
|
|
42
|
+
? `${K}.${keyof NonNullable<DocType> & string}`
|
|
43
|
+
: never
|
|
44
|
+
: never
|
|
21
45
|
: never;
|
|
22
46
|
|
|
23
47
|
type WithoutUndefined<T> = T extends undefined ? never : T;
|