mongoose 8.18.3 → 8.19.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/README.md +22 -0
- package/dist/browser.umd.js +1 -1
- package/lib/document.js +6 -2
- package/lib/helpers/query/castUpdate.js +7 -2
- package/lib/helpers/schema/getPath.js +4 -1
- package/lib/helpers/update/castArrayFilters.js +3 -4
- package/lib/helpers/update/decorateUpdateWithVersionKey.js +19 -10
- package/lib/model.js +16 -5
- package/lib/schema/documentArray.js +1 -1
- package/lib/schema/map.js +2 -2
- package/lib/schema/subdocument.js +1 -1
- package/lib/schemaType.js +1 -0
- package/package.json +10 -8
- package/types/index.d.ts +17 -8
- package/types/inferrawdoctype.d.ts +76 -95
- package/types/inferschematype.d.ts +214 -213
- package/types/models.d.ts +194 -26
- package/types/query.d.ts +76 -55
- package/types/schemaoptions.d.ts +3 -0
- package/types/schematypes.d.ts +86 -33
- package/types/utility.d.ts +108 -81
package/lib/document.js
CHANGED
|
@@ -766,6 +766,8 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
766
766
|
doc[i] = {};
|
|
767
767
|
if (!strict && !(i in docSchema.tree) && !(i in docSchema.methods) && !(i in docSchema.virtuals)) {
|
|
768
768
|
self[i] = doc[i];
|
|
769
|
+
} else if (opts?.virtuals && (i in docSchema.virtuals)) {
|
|
770
|
+
self[i] = doc[i];
|
|
769
771
|
}
|
|
770
772
|
}
|
|
771
773
|
init(self, value, doc[i], opts, path + '.');
|
|
@@ -773,6 +775,8 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
773
775
|
doc[i] = value;
|
|
774
776
|
if (!strict && !prefix) {
|
|
775
777
|
self[i] = value;
|
|
778
|
+
} else if (opts?.virtuals && (i in docSchema.virtuals)) {
|
|
779
|
+
self[i] = value;
|
|
776
780
|
}
|
|
777
781
|
} else {
|
|
778
782
|
// Retain order when overwriting defaults
|
|
@@ -789,9 +793,9 @@ function init(self, obj, doc, opts, prefix) {
|
|
|
789
793
|
if (opts && opts.setters) {
|
|
790
794
|
// Call applySetters with `init = false` because otherwise setters are a noop
|
|
791
795
|
const overrideInit = false;
|
|
792
|
-
doc[i] = schemaType.applySetters(value, self, overrideInit);
|
|
796
|
+
doc[i] = schemaType.applySetters(value, self, overrideInit, null, opts);
|
|
793
797
|
} else {
|
|
794
|
-
doc[i] = schemaType.cast(value, self, true);
|
|
798
|
+
doc[i] = schemaType.cast(value, self, true, undefined, opts);
|
|
795
799
|
}
|
|
796
800
|
} catch (e) {
|
|
797
801
|
self.invalidate(e.path, new ValidatorError({
|
|
@@ -379,8 +379,13 @@ function walkUpdatePath(schema, obj, op, options, context, filter, prefix) {
|
|
|
379
379
|
(utils.isObject(val) && Object.keys(val).length === 0);
|
|
380
380
|
}
|
|
381
381
|
} else {
|
|
382
|
-
const
|
|
383
|
-
|
|
382
|
+
const isModifier = (key === '$each' || key === '$or' || key === '$and' || key === '$in');
|
|
383
|
+
if (isModifier && !prefix) {
|
|
384
|
+
throw new MongooseError('Invalid update: Unexpected modifier "' + key + '" as a key in operator. '
|
|
385
|
+
+ 'Did you mean something like { $addToSet: { fieldName: { $each: [...] } } }? '
|
|
386
|
+
+ 'Modifiers such as "$each", "$or", "$and", "$in" must appear under a valid field path.');
|
|
387
|
+
}
|
|
388
|
+
const checkPath = isModifier ? prefix : prefix + key;
|
|
384
389
|
schematype = schema._getSchema(checkPath);
|
|
385
390
|
|
|
386
391
|
// You can use `$setOnInsert` with immutable keys
|
|
@@ -24,7 +24,7 @@ module.exports = function getPath(schema, path, discriminatorValueMap) {
|
|
|
24
24
|
cur = cur.length === 0 ? piece : cur + '.' + piece;
|
|
25
25
|
|
|
26
26
|
schematype = schema.path(cur);
|
|
27
|
-
if (schematype
|
|
27
|
+
if (schematype?.schema) {
|
|
28
28
|
schema = schematype.schema;
|
|
29
29
|
if (!isArray && schematype.$isMongooseDocumentArray) {
|
|
30
30
|
isArray = true;
|
|
@@ -33,6 +33,9 @@ module.exports = function getPath(schema, path, discriminatorValueMap) {
|
|
|
33
33
|
schema = schema.discriminators[discriminatorValueMap[cur]] ?? schema;
|
|
34
34
|
}
|
|
35
35
|
cur = '';
|
|
36
|
+
} else if (schematype?.instance === 'Mixed') {
|
|
37
|
+
// If we found a mixed path, no point in digging further, the end result is always Mixed
|
|
38
|
+
break;
|
|
36
39
|
}
|
|
37
40
|
}
|
|
38
41
|
|
|
@@ -7,6 +7,9 @@ const updatedPathsByArrayFilter = require('./updatedPathsByArrayFilter');
|
|
|
7
7
|
|
|
8
8
|
module.exports = function castArrayFilters(query) {
|
|
9
9
|
const arrayFilters = query.options.arrayFilters;
|
|
10
|
+
if (!Array.isArray(arrayFilters)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
10
13
|
const update = query.getUpdate();
|
|
11
14
|
const schema = query.schema;
|
|
12
15
|
const updatedPathsByFilter = updatedPathsByArrayFilter(update);
|
|
@@ -29,10 +32,6 @@ module.exports = function castArrayFilters(query) {
|
|
|
29
32
|
};
|
|
30
33
|
|
|
31
34
|
function _castArrayFilters(arrayFilters, schema, strictQuery, updatedPathsByFilter, query) {
|
|
32
|
-
if (!Array.isArray(arrayFilters)) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
35
|
// Map to store discriminator values for embedded documents in the array filters.
|
|
37
36
|
// This is used to handle cases where array filters target specific embedded document types.
|
|
38
37
|
const discriminatorValueMap = {};
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const modifiedPaths = require('./modifiedPaths');
|
|
4
|
-
|
|
5
3
|
/**
|
|
6
4
|
* Decorate the update with a version key, if necessary
|
|
7
5
|
* @api private
|
|
@@ -12,15 +10,26 @@ module.exports = function decorateUpdateWithVersionKey(update, options, versionK
|
|
|
12
10
|
return;
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
if (options.overwrite) {
|
|
13
|
+
if (options.overwrite) {
|
|
14
|
+
if (!hasKey(update, versionKey)) {
|
|
18
15
|
update[versionKey] = 0;
|
|
19
|
-
} else {
|
|
20
|
-
if (!update.$setOnInsert) {
|
|
21
|
-
update.$setOnInsert = {};
|
|
22
|
-
}
|
|
23
|
-
update.$setOnInsert[versionKey] = 0;
|
|
24
16
|
}
|
|
17
|
+
} else if (
|
|
18
|
+
!hasKey(update, versionKey) &&
|
|
19
|
+
!hasKey(update?.$set, versionKey) &&
|
|
20
|
+
!hasKey(update?.$inc, versionKey) &&
|
|
21
|
+
!hasKey(update?.$setOnInsert, versionKey)
|
|
22
|
+
) {
|
|
23
|
+
if (!update.$setOnInsert) {
|
|
24
|
+
update.$setOnInsert = {};
|
|
25
|
+
}
|
|
26
|
+
update.$setOnInsert[versionKey] = 0;
|
|
25
27
|
}
|
|
26
28
|
};
|
|
29
|
+
|
|
30
|
+
function hasKey(obj, key) {
|
|
31
|
+
if (obj == null || typeof obj !== 'object') {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
35
|
+
}
|
package/lib/model.js
CHANGED
|
@@ -3966,6 +3966,7 @@ Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, op
|
|
|
3966
3966
|
* @param {Object} [options] optional options
|
|
3967
3967
|
* @param {Boolean} [options.setters=false] if true, apply schema setters when hydrating
|
|
3968
3968
|
* @param {Boolean} [options.hydratedPopulatedDocs=false] if true, populates the docs if passing pre-populated data
|
|
3969
|
+
* @param {Boolean} [options.virtuals=false] if true, sets any virtuals present on `obj`
|
|
3969
3970
|
* @return {Document} document instance
|
|
3970
3971
|
* @api public
|
|
3971
3972
|
*/
|
|
@@ -3973,6 +3974,10 @@ Model.buildBulkWriteOperations = function buildBulkWriteOperations(documents, op
|
|
|
3973
3974
|
Model.hydrate = function(obj, projection, options) {
|
|
3974
3975
|
_checkContext(this, 'hydrate');
|
|
3975
3976
|
|
|
3977
|
+
if (options?.virtuals && options?.hydratedPopulatedDocs === false) {
|
|
3978
|
+
throw new MongooseError('Cannot set `hydratedPopulatedDocs` option to false if `virtuals` option is truthy because `virtuals: true` also sets populated virtuals');
|
|
3979
|
+
}
|
|
3980
|
+
|
|
3976
3981
|
if (projection != null) {
|
|
3977
3982
|
if (obj != null && obj.$__ != null) {
|
|
3978
3983
|
obj = obj.toObject(internalToObjectOptions);
|
|
@@ -4598,11 +4603,17 @@ async function _populatePath(model, docs, populateOptions) {
|
|
|
4598
4603
|
|
|
4599
4604
|
function _execPopulateQuery(mod, match, select) {
|
|
4600
4605
|
let subPopulate = clone(mod.options.populate);
|
|
4601
|
-
const queryOptions =
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
+
const queryOptions = {};
|
|
4607
|
+
if (mod.options.skip !== undefined) {
|
|
4608
|
+
queryOptions.skip = mod.options.skip;
|
|
4609
|
+
}
|
|
4610
|
+
if (mod.options.limit !== undefined) {
|
|
4611
|
+
queryOptions.limit = mod.options.limit;
|
|
4612
|
+
}
|
|
4613
|
+
if (mod.options.perDocumentLimit !== undefined) {
|
|
4614
|
+
queryOptions.perDocumentLimit = mod.options.perDocumentLimit;
|
|
4615
|
+
}
|
|
4616
|
+
Object.assign(queryOptions, mod.options.options);
|
|
4606
4617
|
|
|
4607
4618
|
if (mod.count) {
|
|
4608
4619
|
delete queryOptions.skip;
|
|
@@ -492,7 +492,7 @@ SchemaDocumentArray.prototype.cast = function(value, doc, init, prev, options) {
|
|
|
492
492
|
}
|
|
493
493
|
|
|
494
494
|
subdoc = new Constructor(null, value, initDocumentOptions, selected, i);
|
|
495
|
-
rawArray[i] = subdoc.$init(rawArray[i]);
|
|
495
|
+
rawArray[i] = subdoc.$init(rawArray[i], options);
|
|
496
496
|
} else {
|
|
497
497
|
if (prev && typeof prev.id === 'function') {
|
|
498
498
|
subdoc = prev.id(rawArray[i]._id);
|
package/lib/schema/map.js
CHANGED
|
@@ -39,7 +39,7 @@ class SchemaMap extends SchemaType {
|
|
|
39
39
|
if (_val == null) {
|
|
40
40
|
_val = map.$__schemaType._castNullish(_val);
|
|
41
41
|
} else {
|
|
42
|
-
_val = map.$__schemaType.cast(_val, doc, true, null, { path: path + '.' + key });
|
|
42
|
+
_val = map.$__schemaType.cast(_val, doc, true, null, { ...options, path: path + '.' + key });
|
|
43
43
|
}
|
|
44
44
|
map.$init(key, _val);
|
|
45
45
|
}
|
|
@@ -49,7 +49,7 @@ class SchemaMap extends SchemaType {
|
|
|
49
49
|
if (_val == null) {
|
|
50
50
|
_val = map.$__schemaType._castNullish(_val);
|
|
51
51
|
} else {
|
|
52
|
-
_val = map.$__schemaType.cast(_val, doc, true, null, { path: path + '.' + key });
|
|
52
|
+
_val = map.$__schemaType.cast(_val, doc, true, null, { ...options, path: path + '.' + key });
|
|
53
53
|
}
|
|
54
54
|
map.$init(key, _val);
|
|
55
55
|
}
|
|
@@ -203,7 +203,7 @@ SchemaSubdocument.prototype.cast = function(val, doc, init, priorVal, options) {
|
|
|
203
203
|
if (init) {
|
|
204
204
|
subdoc = new Constructor(void 0, selected, doc, false, { defaults: false });
|
|
205
205
|
delete subdoc.$__.defaults;
|
|
206
|
-
subdoc.$init(val);
|
|
206
|
+
subdoc.$init(val, options);
|
|
207
207
|
const exclude = isExclusive(selected);
|
|
208
208
|
applyDefaults(subdoc, selected, exclude);
|
|
209
209
|
} else {
|
package/lib/schemaType.js
CHANGED
|
@@ -44,6 +44,7 @@ function SchemaType(path, options, instance) {
|
|
|
44
44
|
this[schemaTypeSymbol] = true;
|
|
45
45
|
this.path = path;
|
|
46
46
|
this.instance = instance;
|
|
47
|
+
this.schemaName = this.constructor.schemaName;
|
|
47
48
|
this.validators = [];
|
|
48
49
|
this.getters = this.constructor.hasOwnProperty('getters') ?
|
|
49
50
|
this.constructor.getters.slice() :
|
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.19.1",
|
|
5
5
|
"author": "Guillermo Rauch <guillermo@learnboost.com>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"mongodb",
|
|
@@ -22,14 +22,15 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"bson": "^6.10.4",
|
|
24
24
|
"kareem": "2.6.3",
|
|
25
|
-
"mongodb": "~6.
|
|
25
|
+
"mongodb": "~6.20.0",
|
|
26
26
|
"mpath": "0.9.0",
|
|
27
27
|
"mquery": "5.0.0",
|
|
28
28
|
"ms": "2.1.3",
|
|
29
29
|
"sift": "17.1.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@
|
|
32
|
+
"@ark/attest": "0.48.2",
|
|
33
|
+
"@babel/core": "7.28.4",
|
|
33
34
|
"@babel/preset-env": "7.28.3",
|
|
34
35
|
"@mongodb-js/mongodb-downloader": "^0.4.2",
|
|
35
36
|
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
@@ -56,9 +57,9 @@
|
|
|
56
57
|
"markdownlint-cli2": "^0.18.1",
|
|
57
58
|
"marked": "15.0.12",
|
|
58
59
|
"mkdirp": "^3.0.1",
|
|
59
|
-
"mocha": "11.7.
|
|
60
|
+
"mocha": "11.7.4",
|
|
60
61
|
"moment": "2.30.1",
|
|
61
|
-
"mongodb-memory-server": "10.2.
|
|
62
|
+
"mongodb-memory-server": "10.2.1",
|
|
62
63
|
"mongodb-runner": "^5.8.2",
|
|
63
64
|
"ncp": "^2.0.0",
|
|
64
65
|
"nyc": "15.1.0",
|
|
@@ -67,9 +68,9 @@
|
|
|
67
68
|
"sinon": "21.0.0",
|
|
68
69
|
"stream-browserify": "3.0.0",
|
|
69
70
|
"tsd": "0.33.0",
|
|
70
|
-
"typescript": "5.9.
|
|
71
|
+
"typescript": "5.9.3",
|
|
71
72
|
"uuid": "11.1.0",
|
|
72
|
-
"webpack": "5.
|
|
73
|
+
"webpack": "5.102.0"
|
|
73
74
|
},
|
|
74
75
|
"directories": {
|
|
75
76
|
"lib": "./lib/mongoose"
|
|
@@ -111,7 +112,8 @@
|
|
|
111
112
|
"test-encryption": "mocha --exit ./test/encryption/*.test.js",
|
|
112
113
|
"tdd": "mocha ./test/*.test.js --inspect --watch --recursive --watch-files ./**/*.{js,ts}",
|
|
113
114
|
"test-coverage": "nyc --reporter=html --reporter=text npm test",
|
|
114
|
-
"ts-benchmark": "cd ./benchmarks/typescript/simple && npm install && npm run benchmark | node ../../../scripts/tsc-diagnostics-check"
|
|
115
|
+
"ts-benchmark": "cd ./benchmarks/typescript/simple && npm install && npm run benchmark | node ../../../scripts/tsc-diagnostics-check",
|
|
116
|
+
"attest-benchmark": "node ./benchmarks/typescript/infer.bench.mts"
|
|
115
117
|
},
|
|
116
118
|
"main": "./index.js",
|
|
117
119
|
"types": "./types/index.d.ts",
|
package/types/index.d.ts
CHANGED
|
@@ -566,11 +566,18 @@ declare module 'mongoose' {
|
|
|
566
566
|
static ObjectId: typeof Schema.Types.ObjectId;
|
|
567
567
|
}
|
|
568
568
|
|
|
569
|
-
export type NumberSchemaDefinition = typeof Number | 'number' | 'Number' | typeof Schema.Types.Number;
|
|
570
|
-
export type StringSchemaDefinition = typeof String | 'string' | 'String' | typeof Schema.Types.String;
|
|
571
|
-
export type BooleanSchemaDefinition = typeof Boolean | 'boolean' | 'Boolean' | typeof Schema.Types.Boolean;
|
|
572
|
-
export type DateSchemaDefinition = DateConstructor | 'date' | 'Date' | typeof Schema.Types.Date;
|
|
573
|
-
export type ObjectIdSchemaDefinition = 'ObjectId' | 'ObjectID' | typeof Schema.Types.ObjectId;
|
|
569
|
+
export type NumberSchemaDefinition = typeof Number | 'number' | 'Number' | typeof Schema.Types.Number | Schema.Types.Number;
|
|
570
|
+
export type StringSchemaDefinition = typeof String | 'string' | 'String' | typeof Schema.Types.String | Schema.Types.String;
|
|
571
|
+
export type BooleanSchemaDefinition = typeof Boolean | 'boolean' | 'Boolean' | typeof Schema.Types.Boolean | Schema.Types.Boolean;
|
|
572
|
+
export type DateSchemaDefinition = DateConstructor | 'date' | 'Date' | typeof Schema.Types.Date | Schema.Types.Date;
|
|
573
|
+
export type ObjectIdSchemaDefinition = 'ObjectId' | 'ObjectID' | typeof Schema.Types.ObjectId | Schema.Types.ObjectId | Types.ObjectId;
|
|
574
|
+
export type BufferSchemaDefinition = typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer;
|
|
575
|
+
export type Decimal128SchemaDefinition = 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 | Schema.Types.Decimal128 | Types.Decimal128;
|
|
576
|
+
export type BigintSchemaDefinition = 'bigint' | 'BigInt' | typeof Schema.Types.BigInt | Schema.Types.BigInt | typeof BigInt | BigInt;
|
|
577
|
+
export type UuidSchemaDefinition = 'uuid' | 'UUID' | typeof Schema.Types.UUID | Schema.Types.UUID;
|
|
578
|
+
export type MapSchemaDefinition = MapConstructor | 'Map' | typeof Schema.Types.Map;
|
|
579
|
+
export type UnionSchemaDefinition = 'Union' | 'union' | typeof Schema.Types.Union | Schema.Types.Union;
|
|
580
|
+
export type DoubleSchemaDefinition = 'double' | 'Double' | typeof Schema.Types.Double | Schema.Types.Double;
|
|
574
581
|
|
|
575
582
|
export type SchemaDefinitionWithBuiltInClass<T> = T extends number
|
|
576
583
|
? NumberSchemaDefinition
|
|
@@ -582,7 +589,9 @@ declare module 'mongoose' {
|
|
|
582
589
|
? DateSchemaDefinition
|
|
583
590
|
: (Function | string);
|
|
584
591
|
|
|
585
|
-
export type SchemaDefinitionProperty<T = undefined, EnforcedDocType = any, THydratedDocumentType = HydratedDocument<EnforcedDocType>> =
|
|
592
|
+
export type SchemaDefinitionProperty<T = undefined, EnforcedDocType = any, THydratedDocumentType = HydratedDocument<EnforcedDocType>> =
|
|
593
|
+
// ThisType intersection here avoids corrupting ThisType for SchemaTypeOptions (see test gh11828)
|
|
594
|
+
| SchemaDefinitionWithBuiltInClass<T> & ThisType<EnforcedDocType>
|
|
586
595
|
| SchemaTypeOptions<T extends undefined ? any : T, EnforcedDocType, THydratedDocumentType>
|
|
587
596
|
| typeof SchemaType
|
|
588
597
|
| Schema<any, any, any>
|
|
@@ -905,8 +914,8 @@ declare module 'mongoose' {
|
|
|
905
914
|
* https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types
|
|
906
915
|
*/
|
|
907
916
|
type FlattenProperty<T> = T extends Map<any, infer V>
|
|
908
|
-
|
|
909
|
-
? T : T extends Types.DocumentArray<infer ItemType>
|
|
917
|
+
? Record<string, V> : T extends TreatAsPrimitives
|
|
918
|
+
? T : T extends Document ? T : T extends Types.DocumentArray<infer ItemType>
|
|
910
919
|
? Types.DocumentArray<FlattenMaps<ItemType>> : FlattenMaps<T>;
|
|
911
920
|
|
|
912
921
|
export type actualPrimitives = string | boolean | number | bigint | symbol | null | undefined;
|
|
@@ -1,24 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
|
-
IsPathRequired,
|
|
3
2
|
IsSchemaTypeFromBuiltinClass,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
PathEnumOrString
|
|
3
|
+
PathEnumOrString,
|
|
4
|
+
type OptionalPathKeys,
|
|
5
|
+
type RequiredPathKeys
|
|
8
6
|
} from './inferschematype';
|
|
9
7
|
|
|
10
8
|
declare module 'mongoose' {
|
|
11
|
-
export type InferRawDocType<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
9
|
+
export type InferRawDocType<DocDefinition, TSchemaOptions extends Record<any, any> = DefaultSchemaOptions> = Show<
|
|
10
|
+
ApplySchemaOptions<
|
|
11
|
+
{
|
|
12
|
+
[K in RequiredPathKeys<DocDefinition, TSchemaOptions['typeKey']>]: ObtainRawDocumentPathType<
|
|
13
|
+
DocDefinition[K],
|
|
14
|
+
TSchemaOptions['typeKey']
|
|
15
|
+
>;
|
|
16
|
+
} & {
|
|
17
|
+
[K in OptionalPathKeys<DocDefinition, TSchemaOptions['typeKey']>]?: ObtainRawDocumentPathType<
|
|
18
|
+
DocDefinition[K],
|
|
19
|
+
TSchemaOptions['typeKey']
|
|
20
|
+
> | null;
|
|
21
|
+
},
|
|
22
|
+
TSchemaOptions
|
|
23
|
+
>
|
|
24
|
+
>;
|
|
22
25
|
|
|
23
26
|
/**
|
|
24
27
|
* @summary Obtains schema Path type.
|
|
@@ -26,18 +29,15 @@ declare module 'mongoose' {
|
|
|
26
29
|
* @param {PathValueType} PathValueType Document definition path type.
|
|
27
30
|
* @param {TypeKey} TypeKey A generic refers to document definition.
|
|
28
31
|
*/
|
|
29
|
-
type ObtainRawDocumentPathType<
|
|
30
|
-
PathValueType
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? PathValueType[TypeKey] : PathValueType,
|
|
34
|
-
PathValueType extends PathWithTypePropertyBaseType<TypeKey> ? Omit<PathValueType, TypeKey> : {},
|
|
35
|
-
TypeKey
|
|
36
|
-
>;
|
|
32
|
+
type ObtainRawDocumentPathType<PathValueType, TypeKey extends string = DefaultTypeKey> =
|
|
33
|
+
TypeKey extends keyof PathValueType ?
|
|
34
|
+
ResolveRawPathType<PathValueType[TypeKey], Omit<PathValueType, TypeKey>, TypeKey>
|
|
35
|
+
: ResolveRawPathType<PathValueType, {}, TypeKey>;
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
// can be efficiently checked like:
|
|
38
|
+
// `[T] extends [neverOrAny] ? T : ...`
|
|
39
|
+
// to avoid edge cases
|
|
40
|
+
type neverOrAny = ' ~neverOrAny~';
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Same as inferSchemaType, except:
|
|
@@ -52,73 +52,54 @@ declare module 'mongoose' {
|
|
|
52
52
|
* @param {TypeKey} TypeKey A generic of literal string type."Refers to the property used for path type definition".
|
|
53
53
|
* @returns Number, "Number" or "number" will be resolved to number type.
|
|
54
54
|
*/
|
|
55
|
-
type ResolveRawPathType<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
type ResolveRawPathType<
|
|
56
|
+
PathValueType,
|
|
57
|
+
Options extends SchemaTypeOptions<PathValueType> = {},
|
|
58
|
+
TypeKey extends string = DefaultSchemaOptions['typeKey']
|
|
59
|
+
> =
|
|
60
|
+
[PathValueType] extends [neverOrAny] ? PathValueType
|
|
61
|
+
: PathValueType extends Schema ? InferSchemaType<PathValueType>
|
|
62
|
+
: PathValueType extends ReadonlyArray<infer Item> ?
|
|
63
|
+
Item extends never ? any[]
|
|
64
|
+
: Item extends Schema ?
|
|
60
65
|
// If Item is a schema, infer its type.
|
|
61
|
-
Array<InferSchemaType<Item>>
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
PathValueType extends typeof Buffer | 'buffer' | 'Buffer' | typeof Schema.Types.Buffer ? Buffer :
|
|
101
|
-
PathValueType extends BooleanSchemaDefinition ? boolean :
|
|
102
|
-
IfEquals<PathValueType, Schema.Types.Boolean> extends true ? boolean :
|
|
103
|
-
PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId :
|
|
104
|
-
IfEquals<PathValueType, Types.ObjectId> extends true ? Types.ObjectId :
|
|
105
|
-
IfEquals<PathValueType, Schema.Types.ObjectId> extends true ? Types.ObjectId :
|
|
106
|
-
PathValueType extends 'decimal128' | 'Decimal128' | typeof Schema.Types.Decimal128 ? Types.Decimal128 :
|
|
107
|
-
IfEquals<PathValueType, Schema.Types.Decimal128> extends true ? Types.Decimal128 :
|
|
108
|
-
IfEquals<PathValueType, Types.Decimal128> extends true ? Types.Decimal128 :
|
|
109
|
-
IfEquals<PathValueType, Schema.Types.BigInt> extends true ? bigint :
|
|
110
|
-
IfEquals<PathValueType, BigInt> extends true ? bigint :
|
|
111
|
-
PathValueType extends 'bigint' | 'BigInt' | typeof Schema.Types.BigInt | typeof BigInt ? bigint :
|
|
112
|
-
PathValueType extends 'uuid' | 'UUID' | typeof Schema.Types.UUID ? Buffer :
|
|
113
|
-
IfEquals<PathValueType, Schema.Types.UUID> extends true ? Buffer :
|
|
114
|
-
PathValueType extends MapConstructor | 'Map' ? Map<string, ObtainRawDocumentPathType<Options['of']>> :
|
|
115
|
-
IfEquals<PathValueType, typeof Schema.Types.Map> extends true ? Map<string, ObtainRawDocumentPathType<Options['of']>> :
|
|
116
|
-
PathValueType extends 'Union' | 'union' | typeof Schema.Types.Union ? Options['of'] extends readonly any[] ? UnionToRawPathType<Options['of']> : never :
|
|
117
|
-
PathValueType extends ArrayConstructor ? any[] :
|
|
118
|
-
PathValueType extends typeof Schema.Types.Mixed ? any:
|
|
119
|
-
IfEquals<PathValueType, ObjectConstructor> extends true ? any:
|
|
120
|
-
IfEquals<PathValueType, {}> extends true ? any:
|
|
121
|
-
PathValueType extends typeof SchemaType ? PathValueType['prototype'] :
|
|
122
|
-
PathValueType extends Record<string, any> ? InferRawDocType<PathValueType> :
|
|
123
|
-
unknown;
|
|
66
|
+
Array<InferSchemaType<Item>>
|
|
67
|
+
: TypeKey extends keyof Item ?
|
|
68
|
+
Item[TypeKey] extends Function | String ?
|
|
69
|
+
// If Item has a type key that's a string or a callable, it must be a scalar,
|
|
70
|
+
// so we can directly obtain its path type.
|
|
71
|
+
ObtainRawDocumentPathType<Item, TypeKey>[]
|
|
72
|
+
: // If the type key isn't callable, then this is an array of objects, in which case
|
|
73
|
+
// we need to call InferRawDocType to correctly infer its type.
|
|
74
|
+
Array<InferRawDocType<Item>>
|
|
75
|
+
: IsSchemaTypeFromBuiltinClass<Item> extends true ? ResolveRawPathType<Item, { enum: Options['enum'] }, TypeKey>[]
|
|
76
|
+
: IsItRecordAndNotAny<Item> extends true ?
|
|
77
|
+
Item extends Record<string, never> ?
|
|
78
|
+
ObtainRawDocumentPathType<Item, TypeKey>[]
|
|
79
|
+
: Array<InferRawDocType<Item>>
|
|
80
|
+
: ObtainRawDocumentPathType<Item, TypeKey>[]
|
|
81
|
+
: PathValueType extends StringSchemaDefinition ? PathEnumOrString<Options['enum']>
|
|
82
|
+
: IfEquals<PathValueType, String> extends true ? PathEnumOrString<Options['enum']>
|
|
83
|
+
: PathValueType extends NumberSchemaDefinition ?
|
|
84
|
+
Options['enum'] extends ReadonlyArray<any> ?
|
|
85
|
+
Options['enum'][number]
|
|
86
|
+
: number
|
|
87
|
+
: PathValueType extends DateSchemaDefinition ? NativeDate
|
|
88
|
+
: PathValueType extends BufferSchemaDefinition ? Buffer
|
|
89
|
+
: PathValueType extends BooleanSchemaDefinition ? boolean
|
|
90
|
+
: PathValueType extends ObjectIdSchemaDefinition ? Types.ObjectId
|
|
91
|
+
: PathValueType extends Decimal128SchemaDefinition ? Types.Decimal128
|
|
92
|
+
: PathValueType extends BigintSchemaDefinition ? bigint
|
|
93
|
+
: PathValueType extends UuidSchemaDefinition ? Buffer
|
|
94
|
+
: PathValueType extends DoubleSchemaDefinition ? Types.Double
|
|
95
|
+
: PathValueType extends MapSchemaDefinition ? Map<string, ObtainRawDocumentPathType<Options['of']>>
|
|
96
|
+
: PathValueType extends UnionSchemaDefinition ?
|
|
97
|
+
ResolveRawPathType<Options['of'] extends ReadonlyArray<infer Item> ? Item : never>
|
|
98
|
+
: PathValueType extends ArrayConstructor ? any[]
|
|
99
|
+
: PathValueType extends typeof Schema.Types.Mixed ? any
|
|
100
|
+
: IfEquals<PathValueType, ObjectConstructor> extends true ? any
|
|
101
|
+
: IfEquals<PathValueType, {}> extends true ? any
|
|
102
|
+
: PathValueType extends typeof SchemaType ? PathValueType['prototype']
|
|
103
|
+
: PathValueType extends Record<string, any> ? InferRawDocType<PathValueType>
|
|
104
|
+
: unknown;
|
|
124
105
|
}
|