@depup/mongoose 9.1.3-depup.0
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/LICENSE.md +22 -0
- package/README.md +397 -0
- package/SECURITY.md +1 -0
- package/eslint.config.mjs +198 -0
- package/index.js +64 -0
- package/lib/aggregate.js +1189 -0
- package/lib/cast/bigint.js +46 -0
- package/lib/cast/boolean.js +32 -0
- package/lib/cast/date.js +41 -0
- package/lib/cast/decimal128.js +39 -0
- package/lib/cast/double.js +50 -0
- package/lib/cast/int32.js +36 -0
- package/lib/cast/number.js +42 -0
- package/lib/cast/objectid.js +29 -0
- package/lib/cast/string.js +37 -0
- package/lib/cast/uuid.js +35 -0
- package/lib/cast.js +436 -0
- package/lib/collection.js +321 -0
- package/lib/connection.js +1855 -0
- package/lib/connectionState.js +26 -0
- package/lib/constants.js +73 -0
- package/lib/cursor/aggregationCursor.js +466 -0
- package/lib/cursor/changeStream.js +198 -0
- package/lib/cursor/queryCursor.js +622 -0
- package/lib/document.js +5521 -0
- package/lib/driver.js +15 -0
- package/lib/drivers/SPEC.md +4 -0
- package/lib/drivers/node-mongodb-native/bulkWriteResult.js +5 -0
- package/lib/drivers/node-mongodb-native/collection.js +393 -0
- package/lib/drivers/node-mongodb-native/connection.js +506 -0
- package/lib/drivers/node-mongodb-native/index.js +10 -0
- package/lib/error/browserMissingSchema.js +29 -0
- package/lib/error/bulkSaveIncompleteError.js +44 -0
- package/lib/error/bulkWriteError.js +41 -0
- package/lib/error/cast.js +158 -0
- package/lib/error/createCollectionsError.js +26 -0
- package/lib/error/divergentArray.js +40 -0
- package/lib/error/eachAsyncMultiError.js +41 -0
- package/lib/error/index.js +237 -0
- package/lib/error/invalidSchemaOption.js +32 -0
- package/lib/error/messages.js +47 -0
- package/lib/error/missingSchema.js +33 -0
- package/lib/error/mongooseError.js +13 -0
- package/lib/error/notFound.js +47 -0
- package/lib/error/objectExpected.js +31 -0
- package/lib/error/objectParameter.js +31 -0
- package/lib/error/overwriteModel.js +31 -0
- package/lib/error/parallelSave.js +33 -0
- package/lib/error/parallelValidate.js +33 -0
- package/lib/error/serverSelection.js +62 -0
- package/lib/error/setOptionError.js +103 -0
- package/lib/error/strict.js +35 -0
- package/lib/error/strictPopulate.js +31 -0
- package/lib/error/syncIndexes.js +30 -0
- package/lib/error/validation.js +97 -0
- package/lib/error/validator.js +100 -0
- package/lib/error/version.js +38 -0
- package/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +39 -0
- package/lib/helpers/aggregate/stringifyFunctionOperators.js +50 -0
- package/lib/helpers/arrayDepth.js +33 -0
- package/lib/helpers/clone.js +204 -0
- package/lib/helpers/common.js +127 -0
- package/lib/helpers/createJSONSchemaTypeDefinition.js +24 -0
- package/lib/helpers/cursor/eachAsync.js +225 -0
- package/lib/helpers/discriminator/applyEmbeddedDiscriminators.js +36 -0
- package/lib/helpers/discriminator/areDiscriminatorValuesEqual.js +16 -0
- package/lib/helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection.js +12 -0
- package/lib/helpers/discriminator/getConstructor.js +29 -0
- package/lib/helpers/discriminator/getDiscriminatorByValue.js +28 -0
- package/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +27 -0
- package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +91 -0
- package/lib/helpers/document/applyDefaults.js +132 -0
- package/lib/helpers/document/applyTimestamps.js +106 -0
- package/lib/helpers/document/applyVirtuals.js +147 -0
- package/lib/helpers/document/cleanModifiedSubpaths.js +45 -0
- package/lib/helpers/document/compile.js +238 -0
- package/lib/helpers/document/getDeepestSubdocumentForPath.js +38 -0
- package/lib/helpers/document/getEmbeddedDiscriminatorPath.js +53 -0
- package/lib/helpers/document/handleSpreadDoc.js +35 -0
- package/lib/helpers/each.js +25 -0
- package/lib/helpers/error/combinePathErrors.js +22 -0
- package/lib/helpers/firstKey.js +8 -0
- package/lib/helpers/get.js +65 -0
- package/lib/helpers/getConstructorName.js +16 -0
- package/lib/helpers/getDefaultBulkwriteResult.js +18 -0
- package/lib/helpers/getFunctionName.js +10 -0
- package/lib/helpers/immediate.js +16 -0
- package/lib/helpers/indexes/applySchemaCollation.js +13 -0
- package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +14 -0
- package/lib/helpers/indexes/getRelatedIndexes.js +63 -0
- package/lib/helpers/indexes/isDefaultIdIndex.js +18 -0
- package/lib/helpers/indexes/isIndexEqual.js +95 -0
- package/lib/helpers/indexes/isIndexSpecEqual.js +32 -0
- package/lib/helpers/indexes/isTextIndex.js +16 -0
- package/lib/helpers/indexes/isTimeseriesIndex.js +16 -0
- package/lib/helpers/isAsyncFunction.js +9 -0
- package/lib/helpers/isBsonType.js +15 -0
- package/lib/helpers/isMongooseObject.js +22 -0
- package/lib/helpers/isObject.js +16 -0
- package/lib/helpers/isPOJO.js +12 -0
- package/lib/helpers/isPromise.js +6 -0
- package/lib/helpers/isSimpleValidator.js +22 -0
- package/lib/helpers/minimize.js +41 -0
- package/lib/helpers/model/applyDefaultsToPOJO.js +52 -0
- package/lib/helpers/model/applyHooks.js +140 -0
- package/lib/helpers/model/applyMethods.js +70 -0
- package/lib/helpers/model/applyStaticHooks.js +33 -0
- package/lib/helpers/model/applyStatics.js +13 -0
- package/lib/helpers/model/castBulkWrite.js +316 -0
- package/lib/helpers/model/decorateBulkWriteResult.js +8 -0
- package/lib/helpers/model/discriminator.js +265 -0
- package/lib/helpers/model/pushNestedArrayPaths.js +15 -0
- package/lib/helpers/omitUndefined.js +20 -0
- package/lib/helpers/once.js +12 -0
- package/lib/helpers/parallelLimit.js +37 -0
- package/lib/helpers/path/parentPaths.js +18 -0
- package/lib/helpers/path/setDottedPath.js +33 -0
- package/lib/helpers/pluralize.js +95 -0
- package/lib/helpers/populate/assignRawDocsToIdStructure.js +129 -0
- package/lib/helpers/populate/assignVals.js +360 -0
- package/lib/helpers/populate/createPopulateQueryFilter.js +97 -0
- package/lib/helpers/populate/getModelsMapForPopulate.js +776 -0
- package/lib/helpers/populate/getSchemaTypes.js +228 -0
- package/lib/helpers/populate/getVirtual.js +103 -0
- package/lib/helpers/populate/leanPopulateMap.js +7 -0
- package/lib/helpers/populate/lookupLocalFields.js +40 -0
- package/lib/helpers/populate/markArraySubdocsPopulated.js +49 -0
- package/lib/helpers/populate/modelNamesFromRefPath.js +66 -0
- package/lib/helpers/populate/removeDeselectedForeignField.js +31 -0
- package/lib/helpers/populate/setPopulatedVirtualValue.js +33 -0
- package/lib/helpers/populate/skipPopulateValue.js +10 -0
- package/lib/helpers/populate/validateRef.js +19 -0
- package/lib/helpers/printJestWarning.js +21 -0
- package/lib/helpers/processConnectionOptions.js +65 -0
- package/lib/helpers/projection/applyProjection.js +83 -0
- package/lib/helpers/projection/hasIncludedChildren.js +41 -0
- package/lib/helpers/projection/isDefiningProjection.js +18 -0
- package/lib/helpers/projection/isExclusive.js +37 -0
- package/lib/helpers/projection/isInclusive.js +39 -0
- package/lib/helpers/projection/isNestedProjection.js +8 -0
- package/lib/helpers/projection/isPathExcluded.js +40 -0
- package/lib/helpers/projection/isPathSelectedInclusive.js +28 -0
- package/lib/helpers/projection/isSubpath.js +14 -0
- package/lib/helpers/projection/parseProjection.js +33 -0
- package/lib/helpers/query/applyGlobalOption.js +29 -0
- package/lib/helpers/query/cast$expr.js +287 -0
- package/lib/helpers/query/castFilterPath.js +54 -0
- package/lib/helpers/query/castUpdate.js +643 -0
- package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +103 -0
- package/lib/helpers/query/handleImmutable.js +44 -0
- package/lib/helpers/query/handleReadPreferenceAliases.js +23 -0
- package/lib/helpers/query/hasDollarKeys.js +23 -0
- package/lib/helpers/query/isOperator.js +14 -0
- package/lib/helpers/query/sanitizeFilter.js +38 -0
- package/lib/helpers/query/sanitizeProjection.js +14 -0
- package/lib/helpers/query/selectPopulatedFields.js +62 -0
- package/lib/helpers/query/trusted.js +13 -0
- package/lib/helpers/query/validOps.js +3 -0
- package/lib/helpers/schema/addAutoId.js +7 -0
- package/lib/helpers/schema/applyBuiltinPlugins.js +12 -0
- package/lib/helpers/schema/applyPlugins.js +55 -0
- package/lib/helpers/schema/applyReadConcern.js +20 -0
- package/lib/helpers/schema/applyWriteConcern.js +39 -0
- package/lib/helpers/schema/cleanPositionalOperators.js +12 -0
- package/lib/helpers/schema/getIndexes.js +171 -0
- package/lib/helpers/schema/getKeysInSchemaOrder.js +28 -0
- package/lib/helpers/schema/getPath.js +43 -0
- package/lib/helpers/schema/getSubdocumentStrictValue.js +32 -0
- package/lib/helpers/schema/handleIdOption.js +20 -0
- package/lib/helpers/schema/handleTimestampOption.js +24 -0
- package/lib/helpers/schema/idGetter.js +34 -0
- package/lib/helpers/schema/merge.js +36 -0
- package/lib/helpers/schematype/handleImmutable.js +50 -0
- package/lib/helpers/setDefaultsOnInsert.js +158 -0
- package/lib/helpers/specialProperties.js +3 -0
- package/lib/helpers/symbols.js +20 -0
- package/lib/helpers/timers.js +3 -0
- package/lib/helpers/timestamps/setDocumentTimestamps.js +26 -0
- package/lib/helpers/timestamps/setupTimestamps.js +116 -0
- package/lib/helpers/topology/allServersUnknown.js +12 -0
- package/lib/helpers/topology/isAtlas.js +31 -0
- package/lib/helpers/topology/isSSLError.js +16 -0
- package/lib/helpers/update/applyTimestampsToChildren.js +193 -0
- package/lib/helpers/update/applyTimestampsToUpdate.js +131 -0
- package/lib/helpers/update/castArrayFilters.js +113 -0
- package/lib/helpers/update/decorateUpdateWithVersionKey.js +35 -0
- package/lib/helpers/update/modifiedPaths.js +33 -0
- package/lib/helpers/update/moveImmutableProperties.js +53 -0
- package/lib/helpers/update/removeUnusedArrayFilters.js +32 -0
- package/lib/helpers/update/updatedPathsByArrayFilter.js +27 -0
- package/lib/helpers/updateValidators.js +193 -0
- package/lib/index.js +17 -0
- package/lib/internal.js +46 -0
- package/lib/model.js +5010 -0
- package/lib/modifiedPathsSnapshot.js +9 -0
- package/lib/mongoose.js +1411 -0
- package/lib/options/populateOptions.js +36 -0
- package/lib/options/propertyOptions.js +8 -0
- package/lib/options/saveOptions.js +16 -0
- package/lib/options/schemaArrayOptions.js +78 -0
- package/lib/options/schemaBufferOptions.js +38 -0
- package/lib/options/schemaDateOptions.js +71 -0
- package/lib/options/schemaDocumentArrayOptions.js +68 -0
- package/lib/options/schemaMapOptions.js +43 -0
- package/lib/options/schemaNumberOptions.js +101 -0
- package/lib/options/schemaObjectIdOptions.js +64 -0
- package/lib/options/schemaStringOptions.js +138 -0
- package/lib/options/schemaSubdocumentOptions.js +66 -0
- package/lib/options/schemaTypeOptions.js +244 -0
- package/lib/options/schemaUnionOptions.js +32 -0
- package/lib/options/virtualOptions.js +164 -0
- package/lib/options.js +17 -0
- package/lib/plugins/index.js +6 -0
- package/lib/plugins/saveSubdocs.js +76 -0
- package/lib/plugins/sharding.js +84 -0
- package/lib/plugins/trackTransaction.js +84 -0
- package/lib/plugins/validateBeforeSave.js +41 -0
- package/lib/query.js +5673 -0
- package/lib/queryHelpers.js +387 -0
- package/lib/schema/array.js +699 -0
- package/lib/schema/bigint.js +282 -0
- package/lib/schema/boolean.js +332 -0
- package/lib/schema/buffer.js +343 -0
- package/lib/schema/date.js +467 -0
- package/lib/schema/decimal128.js +263 -0
- package/lib/schema/documentArray.js +656 -0
- package/lib/schema/documentArrayElement.js +137 -0
- package/lib/schema/double.js +246 -0
- package/lib/schema/index.js +32 -0
- package/lib/schema/int32.js +289 -0
- package/lib/schema/map.js +201 -0
- package/lib/schema/mixed.js +146 -0
- package/lib/schema/number.js +510 -0
- package/lib/schema/objectId.js +333 -0
- package/lib/schema/operators/bitwise.js +38 -0
- package/lib/schema/operators/exists.js +12 -0
- package/lib/schema/operators/geospatial.js +107 -0
- package/lib/schema/operators/helpers.js +32 -0
- package/lib/schema/operators/text.js +39 -0
- package/lib/schema/operators/type.js +20 -0
- package/lib/schema/string.js +733 -0
- package/lib/schema/subdocument.js +436 -0
- package/lib/schema/symbols.js +5 -0
- package/lib/schema/union.js +113 -0
- package/lib/schema/uuid.js +305 -0
- package/lib/schema.js +3226 -0
- package/lib/schemaType.js +1835 -0
- package/lib/stateMachine.js +232 -0
- package/lib/types/array/index.js +119 -0
- package/lib/types/array/isMongooseArray.js +5 -0
- package/lib/types/array/methods/index.js +1095 -0
- package/lib/types/arraySubdocument.js +207 -0
- package/lib/types/buffer.js +294 -0
- package/lib/types/decimal128.js +13 -0
- package/lib/types/documentArray/index.js +113 -0
- package/lib/types/documentArray/isMongooseDocumentArray.js +5 -0
- package/lib/types/documentArray/methods/index.js +415 -0
- package/lib/types/double.js +13 -0
- package/lib/types/index.js +23 -0
- package/lib/types/map.js +419 -0
- package/lib/types/objectid.js +41 -0
- package/lib/types/subdocument.js +464 -0
- package/lib/types/uuid.js +13 -0
- package/lib/utils.js +1054 -0
- package/lib/validOptions.js +42 -0
- package/lib/virtualType.js +204 -0
- package/package.json +148 -0
- package/types/aggregate.d.ts +180 -0
- package/types/augmentations.d.ts +9 -0
- package/types/callback.d.ts +8 -0
- package/types/collection.d.ts +49 -0
- package/types/connection.d.ts +297 -0
- package/types/cursor.d.ts +67 -0
- package/types/document.d.ts +374 -0
- package/types/error.d.ts +143 -0
- package/types/expressions.d.ts +3053 -0
- package/types/helpers.d.ts +32 -0
- package/types/index.d.ts +1056 -0
- package/types/indexes.d.ts +97 -0
- package/types/inferhydrateddoctype.d.ts +115 -0
- package/types/inferrawdoctype.d.ts +135 -0
- package/types/inferschematype.d.ts +337 -0
- package/types/middlewares.d.ts +59 -0
- package/types/models.d.ts +1306 -0
- package/types/mongooseoptions.d.ts +228 -0
- package/types/pipelinestage.d.ts +333 -0
- package/types/populate.d.ts +53 -0
- package/types/query.d.ts +934 -0
- package/types/schemaoptions.d.ts +282 -0
- package/types/schematypes.d.ts +654 -0
- package/types/session.d.ts +32 -0
- package/types/types.d.ts +109 -0
- package/types/utility.d.ts +175 -0
- package/types/validation.d.ts +39 -0
- package/types/virtuals.d.ts +14 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* Module dependencies
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const PopulateOptions = require('./options/populateOptions');
|
|
8
|
+
const checkEmbeddedDiscriminatorKeyProjection =
|
|
9
|
+
require('./helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection');
|
|
10
|
+
const get = require('./helpers/get');
|
|
11
|
+
const getDiscriminatorByValue =
|
|
12
|
+
require('./helpers/discriminator/getDiscriminatorByValue');
|
|
13
|
+
const isDefiningProjection = require('./helpers/projection/isDefiningProjection');
|
|
14
|
+
const clone = require('./helpers/clone');
|
|
15
|
+
const isPathSelectedInclusive = require('./helpers/projection/isPathSelectedInclusive');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Prepare a set of path options for query population. This is the MongooseQuery
|
|
19
|
+
* version
|
|
20
|
+
*
|
|
21
|
+
* @param {Query} query
|
|
22
|
+
* @param {Object} options
|
|
23
|
+
* @return {Array}
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ(query, options) {
|
|
27
|
+
const _populate = query._mongooseOptions.populate;
|
|
28
|
+
const pop = Object.keys(_populate).reduce((vals, key) => vals.concat([_populate[key]]), []);
|
|
29
|
+
|
|
30
|
+
// lean options should trickle through all queries
|
|
31
|
+
if (options.lean != null) {
|
|
32
|
+
pop
|
|
33
|
+
.filter(p => p?.options?.lean == null)
|
|
34
|
+
.forEach(makeLean(options.lean));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const session = query?.options?.session || null;
|
|
38
|
+
if (session != null) {
|
|
39
|
+
pop.forEach(path => {
|
|
40
|
+
if (path.options == null) {
|
|
41
|
+
path.options = { session: session };
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!('session' in path.options)) {
|
|
45
|
+
path.options.session = session;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const projection = query._fieldsForExec();
|
|
51
|
+
for (let i = 0; i < pop.length; ++i) {
|
|
52
|
+
if (pop[i] instanceof PopulateOptions) {
|
|
53
|
+
pop[i] = new PopulateOptions({
|
|
54
|
+
...pop[i],
|
|
55
|
+
_queryProjection: projection,
|
|
56
|
+
_localModel: query.model
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
pop[i]._queryProjection = projection;
|
|
60
|
+
pop[i]._localModel = query.model;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return pop;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* If the document is a mapped discriminator type, it returns a model instance for that type, otherwise,
|
|
69
|
+
* it returns an instance of the given model.
|
|
70
|
+
*
|
|
71
|
+
* @param {Model} model
|
|
72
|
+
* @param {Object} doc
|
|
73
|
+
* @param {Object} fields
|
|
74
|
+
*
|
|
75
|
+
* @return {Document}
|
|
76
|
+
*/
|
|
77
|
+
exports.createModel = function createModel(model, doc, fields, userProvidedFields, options) {
|
|
78
|
+
model.hooks.execPreSync('createModel', doc);
|
|
79
|
+
const discriminatorMapping = model.schema ?
|
|
80
|
+
model.schema.discriminatorMapping :
|
|
81
|
+
null;
|
|
82
|
+
|
|
83
|
+
const key = discriminatorMapping?.isRoot ?
|
|
84
|
+
discriminatorMapping.key :
|
|
85
|
+
null;
|
|
86
|
+
|
|
87
|
+
const value = doc[key];
|
|
88
|
+
if (key && value && model.discriminators) {
|
|
89
|
+
const discriminator = model.discriminators[value] || getDiscriminatorByValue(model.discriminators, value);
|
|
90
|
+
if (discriminator) {
|
|
91
|
+
const _fields = clone(userProvidedFields);
|
|
92
|
+
exports.applyPaths(_fields, discriminator.schema);
|
|
93
|
+
return new discriminator(undefined, _fields, { skipId: true });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const _opts = {
|
|
98
|
+
skipId: true,
|
|
99
|
+
isNew: false,
|
|
100
|
+
willInit: true
|
|
101
|
+
};
|
|
102
|
+
if (options != null && 'defaults' in options) {
|
|
103
|
+
_opts.defaults = options.defaults;
|
|
104
|
+
}
|
|
105
|
+
return new model(undefined, fields, _opts);
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/*!
|
|
109
|
+
* ignore
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
exports.createModelAndInit = function createModelAndInit(model, doc, fields, userProvidedFields, options, populatedIds, callback) {
|
|
113
|
+
const initOpts = populatedIds ?
|
|
114
|
+
{ populated: populatedIds } :
|
|
115
|
+
undefined;
|
|
116
|
+
|
|
117
|
+
const casted = exports.createModel(model, doc, fields, userProvidedFields, options);
|
|
118
|
+
try {
|
|
119
|
+
casted.$init(doc, initOpts, callback);
|
|
120
|
+
} catch (error) {
|
|
121
|
+
callback(error, casted);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/*!
|
|
126
|
+
* ignore
|
|
127
|
+
*/
|
|
128
|
+
|
|
129
|
+
exports.applyPaths = function applyPaths(fields, schema, sanitizeProjection) {
|
|
130
|
+
// determine if query is selecting or excluding fields
|
|
131
|
+
let exclude;
|
|
132
|
+
let keys;
|
|
133
|
+
const minusPathsToSkip = new Set();
|
|
134
|
+
|
|
135
|
+
if (fields) {
|
|
136
|
+
keys = Object.keys(fields);
|
|
137
|
+
|
|
138
|
+
// Collapse minus paths
|
|
139
|
+
const minusPaths = [];
|
|
140
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
141
|
+
const key = keys[i];
|
|
142
|
+
if (keys[i][0] !== '-') {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
delete fields[key];
|
|
147
|
+
if (key === '-_id') {
|
|
148
|
+
fields['_id'] = 0;
|
|
149
|
+
} else {
|
|
150
|
+
minusPaths.push(key.slice(1));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
keys = Object.keys(fields);
|
|
155
|
+
for (let keyIndex = 0; keyIndex < keys.length; ++keyIndex) {
|
|
156
|
+
if (keys[keyIndex][0] === '+') {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const field = fields[keys[keyIndex]];
|
|
160
|
+
// Skip `$meta` and `$slice`
|
|
161
|
+
if (!isDefiningProjection(field)) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (keys[keyIndex] === '_id' && keys.length > 1) {
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (keys[keyIndex] === schema.options.discriminatorKey && keys.length > 1 && field != null && !field) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
exclude = !field;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Potentially add back minus paths based on schema-level path config
|
|
175
|
+
// and whether the projection is inclusive
|
|
176
|
+
for (const path of minusPaths) {
|
|
177
|
+
const type = schema.path(path);
|
|
178
|
+
// If the path isn't selected by default or the projection is not
|
|
179
|
+
// inclusive, minus path is treated as equivalent to `key: 0`.
|
|
180
|
+
// But we also allow using `-name` to remove `name` from an inclusive
|
|
181
|
+
// projection if `name` has schema-level `select: true`.
|
|
182
|
+
if (!type?.selected || exclude !== false) {
|
|
183
|
+
fields[path] = 0;
|
|
184
|
+
exclude = true;
|
|
185
|
+
} else if (type?.selected && exclude === false) {
|
|
186
|
+
// Make a note of minus paths that are overwriting paths that are
|
|
187
|
+
// included by default.
|
|
188
|
+
minusPathsToSkip.add(path);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// if selecting, apply default schematype select:true fields
|
|
194
|
+
// if excluding, apply schematype select:false fields
|
|
195
|
+
const selected = [];
|
|
196
|
+
const excluded = [];
|
|
197
|
+
const stack = [];
|
|
198
|
+
|
|
199
|
+
analyzeSchema(schema);
|
|
200
|
+
switch (exclude) {
|
|
201
|
+
case true:
|
|
202
|
+
for (const fieldName of excluded) {
|
|
203
|
+
fields[fieldName] = 0;
|
|
204
|
+
}
|
|
205
|
+
break;
|
|
206
|
+
case false:
|
|
207
|
+
if (schema?.paths['_id']?.options?.select === false) {
|
|
208
|
+
fields._id = 0;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
for (const fieldName of selected) {
|
|
212
|
+
if (minusPathsToSkip.has(fieldName)) {
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (isPathSelectedInclusive(fields, fieldName)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
fields[fieldName] = fields[fieldName] || 1;
|
|
219
|
+
}
|
|
220
|
+
break;
|
|
221
|
+
case undefined:
|
|
222
|
+
if (fields == null) {
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
// Any leftover plus paths must in the schema, so delete them (gh-7017)
|
|
226
|
+
for (const key of Object.keys(fields || {})) {
|
|
227
|
+
if (key.startsWith('+')) {
|
|
228
|
+
delete fields[key];
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// user didn't specify fields, implies returning all fields.
|
|
233
|
+
// only need to apply excluded fields and delete any plus paths
|
|
234
|
+
for (const fieldName of excluded) {
|
|
235
|
+
if (fields[fieldName] != null) {
|
|
236
|
+
// Skip applying default projections to fields with non-defining
|
|
237
|
+
// projections, like `$slice`
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
fields[fieldName] = 0;
|
|
241
|
+
}
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function analyzeSchema(schema, prefix) {
|
|
246
|
+
prefix || (prefix = '');
|
|
247
|
+
|
|
248
|
+
// avoid recursion
|
|
249
|
+
if (stack.indexOf(schema) !== -1) {
|
|
250
|
+
return [];
|
|
251
|
+
}
|
|
252
|
+
stack.push(schema);
|
|
253
|
+
|
|
254
|
+
const addedPaths = [];
|
|
255
|
+
schema.eachPath(function(path, type) {
|
|
256
|
+
if (prefix) path = prefix + '.' + path;
|
|
257
|
+
if (type.$isSchemaMap || path.endsWith('.$*')) {
|
|
258
|
+
const plusPath = '+' + path;
|
|
259
|
+
const hasPlusPath = fields && plusPath in fields;
|
|
260
|
+
if (type.options?.select === false && !hasPlusPath) {
|
|
261
|
+
excluded.push(path);
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
let addedPath = analyzePath(path, type);
|
|
266
|
+
// arrays
|
|
267
|
+
if (addedPath == null && !Array.isArray(type) && type.$isMongooseArray && !type.$isMongooseDocumentArray) {
|
|
268
|
+
addedPath = analyzePath(path, type.embeddedSchemaType);
|
|
269
|
+
}
|
|
270
|
+
if (addedPath != null) {
|
|
271
|
+
addedPaths.push(addedPath);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// nested schemas
|
|
275
|
+
if (type.schema) {
|
|
276
|
+
const _addedPaths = analyzeSchema(type.schema, path);
|
|
277
|
+
|
|
278
|
+
// Special case: if discriminator key is the only field that would
|
|
279
|
+
// be projected in, remove it.
|
|
280
|
+
if (exclude === false) {
|
|
281
|
+
checkEmbeddedDiscriminatorKeyProjection(fields, path, type.schema,
|
|
282
|
+
selected, _addedPaths);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
stack.pop();
|
|
287
|
+
return addedPaths;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function analyzePath(path, type) {
|
|
291
|
+
if (fields == null) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// If schema-level selected not set, nothing to do
|
|
296
|
+
if (typeof type.selected !== 'boolean') {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// User overwriting default exclusion
|
|
301
|
+
if (type.selected === false && fields[path]) {
|
|
302
|
+
if (sanitizeProjection) {
|
|
303
|
+
fields[path] = 0;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// If set to 0, we're explicitly excluding the discriminator key. Can't do this for all fields,
|
|
310
|
+
// because we have tests that assert that using `-path` to exclude schema-level `select: true`
|
|
311
|
+
// fields counts as an exclusive projection. See gh-11546
|
|
312
|
+
if (!exclude && type.selected && path === schema.options.discriminatorKey && fields[path] != null && !fields[path]) {
|
|
313
|
+
delete fields[path];
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (exclude === false && type.selected && fields[path] != null && !fields[path]) {
|
|
318
|
+
delete fields[path];
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const plusPath = '+' + path;
|
|
323
|
+
const hasPlusPath = fields && plusPath in fields;
|
|
324
|
+
if (hasPlusPath) {
|
|
325
|
+
// forced inclusion
|
|
326
|
+
delete fields[plusPath];
|
|
327
|
+
|
|
328
|
+
// if there are other fields being included, add this one
|
|
329
|
+
// if no other included fields, leave this out (implied inclusion)
|
|
330
|
+
if (exclude === false && keys.length > 1 && !~keys.indexOf(path) && !sanitizeProjection) {
|
|
331
|
+
fields[path] = 1;
|
|
332
|
+
} else if (exclude == null && sanitizeProjection && type.selected === false) {
|
|
333
|
+
fields[path] = 0;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// check for parent exclusions
|
|
340
|
+
const pieces = path.split('.');
|
|
341
|
+
let cur = '';
|
|
342
|
+
for (let i = 0; i < pieces.length; ++i) {
|
|
343
|
+
cur += cur.length ? '.' + pieces[i] : pieces[i];
|
|
344
|
+
if (excluded.indexOf(cur) !== -1) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Special case: if user has included a parent path of a discriminator key,
|
|
350
|
+
// don't explicitly project in the discriminator key because that will
|
|
351
|
+
// project out everything else under the parent path
|
|
352
|
+
if (!exclude && (type?.options?.$skipDiscriminatorCheck || false)) {
|
|
353
|
+
let cur = '';
|
|
354
|
+
for (let i = 0; i < pieces.length; ++i) {
|
|
355
|
+
cur += (cur.length === 0 ? '' : '.') + pieces[i];
|
|
356
|
+
const projection = get(fields, cur, false) || get(fields, cur + '.$', false);
|
|
357
|
+
if (projection && typeof projection !== 'object') {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
(type.selected ? selected : excluded).push(path);
|
|
364
|
+
return path;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Set each path query option to lean
|
|
370
|
+
*
|
|
371
|
+
* @param {Object} option
|
|
372
|
+
*/
|
|
373
|
+
|
|
374
|
+
function makeLean(val) {
|
|
375
|
+
return function(option) {
|
|
376
|
+
option.options || (option.options = {});
|
|
377
|
+
|
|
378
|
+
if (Array.isArray(val?.virtuals)) {
|
|
379
|
+
val = Object.assign({}, val);
|
|
380
|
+
val.virtuals = val.virtuals.
|
|
381
|
+
filter(path => typeof path === 'string' && path.startsWith(option.path + '.')).
|
|
382
|
+
map(path => path.slice(option.path.length + 1));
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
option.options.lean = val;
|
|
386
|
+
};
|
|
387
|
+
}
|