@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,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const hasIncludedChildren = require('./hasIncludedChildren');
|
|
4
|
+
const isExclusive = require('./isExclusive');
|
|
5
|
+
const isInclusive = require('./isInclusive');
|
|
6
|
+
const isPOJO = require('../../utils').isPOJO;
|
|
7
|
+
|
|
8
|
+
module.exports = function applyProjection(doc, projection, _hasIncludedChildren) {
|
|
9
|
+
if (projection == null) {
|
|
10
|
+
return doc;
|
|
11
|
+
}
|
|
12
|
+
if (doc == null) {
|
|
13
|
+
return doc;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let exclude = null;
|
|
17
|
+
if (isInclusive(projection)) {
|
|
18
|
+
exclude = false;
|
|
19
|
+
} else if (isExclusive(projection)) {
|
|
20
|
+
exclude = true;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (exclude == null) {
|
|
24
|
+
return doc;
|
|
25
|
+
} else if (exclude) {
|
|
26
|
+
_hasIncludedChildren = _hasIncludedChildren || hasIncludedChildren(projection);
|
|
27
|
+
return applyExclusiveProjection(doc, projection, _hasIncludedChildren);
|
|
28
|
+
} else {
|
|
29
|
+
_hasIncludedChildren = _hasIncludedChildren || hasIncludedChildren(projection);
|
|
30
|
+
return applyInclusiveProjection(doc, projection, _hasIncludedChildren);
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function applyExclusiveProjection(doc, projection, hasIncludedChildren, projectionLimb, prefix) {
|
|
35
|
+
if (doc == null || typeof doc !== 'object') {
|
|
36
|
+
return doc;
|
|
37
|
+
}
|
|
38
|
+
if (Array.isArray(doc)) {
|
|
39
|
+
return doc.map(el => applyExclusiveProjection(el, projection, hasIncludedChildren, projectionLimb, prefix));
|
|
40
|
+
}
|
|
41
|
+
const ret = { ...doc };
|
|
42
|
+
projectionLimb = prefix ? (projectionLimb || {}) : projection;
|
|
43
|
+
|
|
44
|
+
for (const key of Object.keys(ret)) {
|
|
45
|
+
const fullPath = prefix ? prefix + '.' + key : key;
|
|
46
|
+
if (Object.hasOwn(projection, fullPath) || Object.hasOwn(projectionLimb, key)) {
|
|
47
|
+
if (isPOJO(projection[fullPath]) || isPOJO(projectionLimb[key])) {
|
|
48
|
+
ret[key] = applyExclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
|
|
49
|
+
} else {
|
|
50
|
+
delete ret[key];
|
|
51
|
+
}
|
|
52
|
+
} else if (hasIncludedChildren[fullPath]) {
|
|
53
|
+
ret[key] = applyExclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return ret;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function applyInclusiveProjection(doc, projection, hasIncludedChildren, projectionLimb, prefix) {
|
|
60
|
+
if (doc == null || typeof doc !== 'object') {
|
|
61
|
+
return doc;
|
|
62
|
+
}
|
|
63
|
+
if (Array.isArray(doc)) {
|
|
64
|
+
return doc.map(el => applyInclusiveProjection(el, projection, hasIncludedChildren, projectionLimb, prefix));
|
|
65
|
+
}
|
|
66
|
+
const ret = { ...doc };
|
|
67
|
+
projectionLimb = prefix ? (projectionLimb || {}) : projection;
|
|
68
|
+
|
|
69
|
+
for (const key of Object.keys(ret)) {
|
|
70
|
+
const fullPath = prefix ? prefix + '.' + key : key;
|
|
71
|
+
if (Object.hasOwn(projection, fullPath) || Object.hasOwn(projectionLimb, key)) {
|
|
72
|
+
if (isPOJO(projection[fullPath]) || isPOJO(projectionLimb[key])) {
|
|
73
|
+
ret[key] = applyInclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
|
|
74
|
+
}
|
|
75
|
+
continue;
|
|
76
|
+
} else if (hasIncludedChildren[fullPath]) {
|
|
77
|
+
ret[key] = applyInclusiveProjection(ret[key], projection, hasIncludedChildren, projectionLimb[key], fullPath);
|
|
78
|
+
} else {
|
|
79
|
+
delete ret[key];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return ret;
|
|
83
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates an object that precomputes whether a given path has child fields in
|
|
5
|
+
* the projection.
|
|
6
|
+
*
|
|
7
|
+
* #### Example:
|
|
8
|
+
*
|
|
9
|
+
* const res = hasIncludedChildren({ 'a.b.c': 0 });
|
|
10
|
+
* res.a; // 1
|
|
11
|
+
* res['a.b']; // 1
|
|
12
|
+
* res['a.b.c']; // 1
|
|
13
|
+
* res['a.c']; // undefined
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} fields
|
|
16
|
+
* @api private
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
module.exports = function hasIncludedChildren(fields) {
|
|
20
|
+
const hasIncludedChildren = {};
|
|
21
|
+
const keys = Object.keys(fields);
|
|
22
|
+
|
|
23
|
+
for (const key of keys) {
|
|
24
|
+
|
|
25
|
+
if (key.indexOf('.') === -1) {
|
|
26
|
+
hasIncludedChildren[key] = 1;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const parts = key.split('.');
|
|
30
|
+
let c = parts[0];
|
|
31
|
+
|
|
32
|
+
for (let i = 0; i < parts.length; ++i) {
|
|
33
|
+
hasIncludedChildren[c] = 1;
|
|
34
|
+
if (i + 1 < parts.length) {
|
|
35
|
+
c = c + '.' + parts[i + 1];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return hasIncludedChildren;
|
|
41
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* ignore
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = function isDefiningProjection(val) {
|
|
8
|
+
if (val == null) {
|
|
9
|
+
// `undefined` or `null` become exclusive projections
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
if (typeof val === 'object') {
|
|
13
|
+
// Only cases where a value does **not** define whether the whole projection
|
|
14
|
+
// is inclusive or exclusive are `$meta` and `$slice`.
|
|
15
|
+
return !('$meta' in val) && !('$slice' in val);
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
const isPOJO = require('../isPOJO');
|
|
5
|
+
|
|
6
|
+
/*!
|
|
7
|
+
* ignore
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
module.exports = function isExclusive(projection) {
|
|
11
|
+
if (projection == null) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const keys = Object.keys(projection);
|
|
16
|
+
let exclude = null;
|
|
17
|
+
|
|
18
|
+
if (keys.length === 1 && keys[0] === '_id') {
|
|
19
|
+
exclude = !projection._id;
|
|
20
|
+
} else {
|
|
21
|
+
for (let ki = 0; ki < keys.length; ++ki) {
|
|
22
|
+
// Does this projection explicitly define inclusion/exclusion?
|
|
23
|
+
// Explicitly avoid `$meta` and `$slice`
|
|
24
|
+
const key = keys[ki];
|
|
25
|
+
if (key !== '_id' && isDefiningProjection(projection[key])) {
|
|
26
|
+
exclude = isPOJO(projection[key]) ?
|
|
27
|
+
(isExclusive(projection[key]) ?? exclude) :
|
|
28
|
+
!projection[key];
|
|
29
|
+
if (exclude != null) {
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return exclude;
|
|
37
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
const isPOJO = require('../isPOJO');
|
|
5
|
+
|
|
6
|
+
/*!
|
|
7
|
+
* ignore
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
module.exports = function isInclusive(projection) {
|
|
11
|
+
if (projection == null) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = Object.keys(projection);
|
|
16
|
+
const numProps = props.length;
|
|
17
|
+
if (numProps === 0) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (let i = 0; i < numProps; ++i) {
|
|
22
|
+
const prop = props[i];
|
|
23
|
+
// Plus paths can't define the projection (see gh-7050)
|
|
24
|
+
if (prop.startsWith('+')) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
// If field is truthy (1, true, etc.) and not an object, then this
|
|
28
|
+
// projection must be inclusive. If object, assume its $meta, $slice, etc.
|
|
29
|
+
if (isDefiningProjection(projection[prop]) && !!projection[prop]) {
|
|
30
|
+
if (isPOJO(projection[prop])) {
|
|
31
|
+
return isInclusive(projection[prop]);
|
|
32
|
+
} else {
|
|
33
|
+
return !!projection[prop];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return false;
|
|
39
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const isDefiningProjection = require('./isDefiningProjection');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Determines if `path` is excluded by `projection`
|
|
7
|
+
*
|
|
8
|
+
* @param {Object} projection
|
|
9
|
+
* @param {String} path
|
|
10
|
+
* @return {Boolean}
|
|
11
|
+
* @api private
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
module.exports = function isPathExcluded(projection, path) {
|
|
15
|
+
if (projection == null) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (path === '_id') {
|
|
20
|
+
return projection._id === 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const paths = Object.keys(projection);
|
|
24
|
+
let type = null;
|
|
25
|
+
|
|
26
|
+
for (const _path of paths) {
|
|
27
|
+
if (isDefiningProjection(projection[_path])) {
|
|
28
|
+
type = projection[path] === 1 ? 'inclusive' : 'exclusive';
|
|
29
|
+
break;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (type === 'inclusive') {
|
|
34
|
+
return projection[path] !== 1;
|
|
35
|
+
}
|
|
36
|
+
if (type === 'exclusive') {
|
|
37
|
+
return projection[path] === 0;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* ignore
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
module.exports = function isPathSelectedInclusive(fields, path) {
|
|
8
|
+
const chunks = path.split('.');
|
|
9
|
+
let cur = '';
|
|
10
|
+
let j;
|
|
11
|
+
let keys;
|
|
12
|
+
let numKeys;
|
|
13
|
+
for (let i = 0; i < chunks.length; ++i) {
|
|
14
|
+
cur += cur.length ? '.' : '' + chunks[i];
|
|
15
|
+
if (fields[cur]) {
|
|
16
|
+
keys = Object.keys(fields);
|
|
17
|
+
numKeys = keys.length;
|
|
18
|
+
for (j = 0; j < numKeys; ++j) {
|
|
19
|
+
if (keys[i].indexOf(cur + '.') === 0 && keys[i].indexOf(path) !== 0) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Determines if `path2` is a subpath of or equal to `path1`
|
|
5
|
+
*
|
|
6
|
+
* @param {string} path1
|
|
7
|
+
* @param {string} path2
|
|
8
|
+
* @return {Boolean}
|
|
9
|
+
* @api private
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
module.exports = function isSubpath(path1, path2) {
|
|
13
|
+
return path1 === path2 || path2.startsWith(path1 + '.');
|
|
14
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Convert a string or array into a projection object, retaining all
|
|
5
|
+
* `-` and `+` paths.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
module.exports = function parseProjection(v, retainMinusPaths) {
|
|
9
|
+
const type = typeof v;
|
|
10
|
+
|
|
11
|
+
if (type === 'string') {
|
|
12
|
+
v = v.split(/\s+/);
|
|
13
|
+
}
|
|
14
|
+
if (!Array.isArray(v) && Object.prototype.toString.call(v) !== '[object Arguments]') {
|
|
15
|
+
return v;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const len = v.length;
|
|
19
|
+
const ret = {};
|
|
20
|
+
for (let i = 0; i < len; ++i) {
|
|
21
|
+
let field = v[i];
|
|
22
|
+
if (!field) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const include = '-' == field[0] ? 0 : 1;
|
|
26
|
+
if (!retainMinusPaths && include === 0) {
|
|
27
|
+
field = field.substring(1);
|
|
28
|
+
}
|
|
29
|
+
ret[field] = include;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return ret;
|
|
33
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('../../utils');
|
|
4
|
+
|
|
5
|
+
function applyGlobalMaxTimeMS(options, connectionOptions, baseOptions) {
|
|
6
|
+
applyGlobalOption(options, connectionOptions, baseOptions, 'maxTimeMS');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function applyGlobalDiskUse(options, connectionOptions, baseOptions) {
|
|
10
|
+
applyGlobalOption(options, connectionOptions, baseOptions, 'allowDiskUse');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
applyGlobalMaxTimeMS,
|
|
15
|
+
applyGlobalDiskUse
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
function applyGlobalOption(options, connectionOptions, baseOptions, optionName) {
|
|
20
|
+
if (utils.hasUserDefinedProperty(options, optionName)) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (utils.hasUserDefinedProperty(connectionOptions, optionName)) {
|
|
25
|
+
options[optionName] = connectionOptions[optionName];
|
|
26
|
+
} else if (utils.hasUserDefinedProperty(baseOptions, optionName)) {
|
|
27
|
+
options[optionName] = baseOptions[optionName];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CastError = require('../../error/cast');
|
|
4
|
+
const StrictModeError = require('../../error/strict');
|
|
5
|
+
const castNumber = require('../../cast/number');
|
|
6
|
+
const omitUndefined = require('../omitUndefined');
|
|
7
|
+
|
|
8
|
+
const booleanComparison = new Set(['$and', '$or']);
|
|
9
|
+
const comparisonOperator = new Set(['$cmp', '$eq', '$lt', '$lte', '$gt', '$gte']);
|
|
10
|
+
const arithmeticOperatorArray = new Set([
|
|
11
|
+
// avoid casting '$add' or '$subtract', because expressions can be either number or date,
|
|
12
|
+
// and we don't have a good way of inferring which arguments should be numbers and which should
|
|
13
|
+
// be dates.
|
|
14
|
+
'$multiply',
|
|
15
|
+
'$divide',
|
|
16
|
+
'$log',
|
|
17
|
+
'$mod',
|
|
18
|
+
'$trunc',
|
|
19
|
+
'$avg',
|
|
20
|
+
'$max',
|
|
21
|
+
'$min',
|
|
22
|
+
'$stdDevPop',
|
|
23
|
+
'$stdDevSamp',
|
|
24
|
+
'$sum'
|
|
25
|
+
]);
|
|
26
|
+
const arithmeticOperatorNumber = new Set([
|
|
27
|
+
'$abs',
|
|
28
|
+
'$exp',
|
|
29
|
+
'$ceil',
|
|
30
|
+
'$floor',
|
|
31
|
+
'$ln',
|
|
32
|
+
'$log10',
|
|
33
|
+
'$sqrt',
|
|
34
|
+
'$sin',
|
|
35
|
+
'$cos',
|
|
36
|
+
'$tan',
|
|
37
|
+
'$asin',
|
|
38
|
+
'$acos',
|
|
39
|
+
'$atan',
|
|
40
|
+
'$atan2',
|
|
41
|
+
'$asinh',
|
|
42
|
+
'$acosh',
|
|
43
|
+
'$atanh',
|
|
44
|
+
'$sinh',
|
|
45
|
+
'$cosh',
|
|
46
|
+
'$tanh',
|
|
47
|
+
'$degreesToRadians',
|
|
48
|
+
'$radiansToDegrees'
|
|
49
|
+
]);
|
|
50
|
+
const arrayElementOperators = new Set([
|
|
51
|
+
'$arrayElemAt',
|
|
52
|
+
'$first',
|
|
53
|
+
'$last'
|
|
54
|
+
]);
|
|
55
|
+
const dateOperators = new Set([
|
|
56
|
+
'$year',
|
|
57
|
+
'$month',
|
|
58
|
+
'$week',
|
|
59
|
+
'$dayOfMonth',
|
|
60
|
+
'$dayOfYear',
|
|
61
|
+
'$hour',
|
|
62
|
+
'$minute',
|
|
63
|
+
'$second',
|
|
64
|
+
'$isoDayOfWeek',
|
|
65
|
+
'$isoWeekYear',
|
|
66
|
+
'$isoWeek',
|
|
67
|
+
'$millisecond'
|
|
68
|
+
]);
|
|
69
|
+
const expressionOperator = new Set(['$not']);
|
|
70
|
+
|
|
71
|
+
module.exports = function cast$expr(val, schema, strictQuery) {
|
|
72
|
+
if (typeof val === 'boolean') {
|
|
73
|
+
return val;
|
|
74
|
+
}
|
|
75
|
+
if (typeof val !== 'object' || val === null) {
|
|
76
|
+
throw new Error('`$expr` must be an object or boolean literal');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return _castExpression(val, schema, strictQuery);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
function _castExpression(val, schema, strictQuery) {
|
|
83
|
+
// Preserve the value if it represents a path or if it's null
|
|
84
|
+
if (isPath(val) || val === null) {
|
|
85
|
+
return val;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (val.$cond != null) {
|
|
89
|
+
if (Array.isArray(val.$cond)) {
|
|
90
|
+
val.$cond = val.$cond.map(expr => _castExpression(expr, schema, strictQuery));
|
|
91
|
+
} else {
|
|
92
|
+
val.$cond.if = _castExpression(val.$cond.if, schema, strictQuery);
|
|
93
|
+
val.$cond.then = _castExpression(val.$cond.then, schema, strictQuery);
|
|
94
|
+
val.$cond.else = _castExpression(val.$cond.else, schema, strictQuery);
|
|
95
|
+
}
|
|
96
|
+
} else if (val.$ifNull != null) {
|
|
97
|
+
val.$ifNull.map(v => _castExpression(v, schema, strictQuery));
|
|
98
|
+
} else if (val.$switch != null) {
|
|
99
|
+
if (Array.isArray(val.$switch.branches)) {
|
|
100
|
+
val.$switch.branches = val.$switch.branches.map(v => _castExpression(v, schema, strictQuery));
|
|
101
|
+
}
|
|
102
|
+
if ('default' in val.$switch) {
|
|
103
|
+
val.$switch.default = _castExpression(val.$switch.default, schema, strictQuery);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const keys = Object.keys(val);
|
|
108
|
+
for (const key of keys) {
|
|
109
|
+
if (booleanComparison.has(key)) {
|
|
110
|
+
val[key] = val[key].map(v => _castExpression(v, schema, strictQuery));
|
|
111
|
+
} else if (comparisonOperator.has(key)) {
|
|
112
|
+
val[key] = castComparison(val[key], schema, strictQuery);
|
|
113
|
+
} else if (arithmeticOperatorArray.has(key)) {
|
|
114
|
+
val[key] = castArithmetic(val[key], schema, strictQuery);
|
|
115
|
+
} else if (arithmeticOperatorNumber.has(key)) {
|
|
116
|
+
val[key] = castNumberOperator(val[key], schema, strictQuery);
|
|
117
|
+
} else if (expressionOperator.has(key)) {
|
|
118
|
+
val[key] = _castExpression(val[key], schema, strictQuery);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (val.$in) {
|
|
123
|
+
val.$in = castIn(val.$in, schema, strictQuery);
|
|
124
|
+
}
|
|
125
|
+
if (val.$size) {
|
|
126
|
+
val.$size = castNumberOperator(val.$size, schema, strictQuery);
|
|
127
|
+
}
|
|
128
|
+
if (val.$round) {
|
|
129
|
+
const $round = val.$round;
|
|
130
|
+
if (!Array.isArray($round) || $round.length < 1 || $round.length > 2) {
|
|
131
|
+
throw new CastError('Array', $round, '$round');
|
|
132
|
+
}
|
|
133
|
+
val.$round = $round.map(v => castNumberOperator(v, schema, strictQuery));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
omitUndefined(val);
|
|
137
|
+
|
|
138
|
+
return val;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// { $op: <number> }
|
|
142
|
+
function castNumberOperator(val) {
|
|
143
|
+
if (!isLiteral(val)) {
|
|
144
|
+
return val;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
try {
|
|
148
|
+
return castNumber(val);
|
|
149
|
+
} catch {
|
|
150
|
+
throw new CastError('Number', val);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function castIn(val, schema, strictQuery) {
|
|
155
|
+
const path = val[1];
|
|
156
|
+
if (!isPath(path)) {
|
|
157
|
+
return val;
|
|
158
|
+
}
|
|
159
|
+
const search = val[0];
|
|
160
|
+
|
|
161
|
+
const schematype = schema.path(path.slice(1));
|
|
162
|
+
if (schematype === null) {
|
|
163
|
+
if (strictQuery === false) {
|
|
164
|
+
return val;
|
|
165
|
+
} else if (strictQuery === 'throw') {
|
|
166
|
+
throw new StrictModeError('$in');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return void 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (!schematype.$isMongooseArray) {
|
|
173
|
+
throw new Error('Path must be an array for $in');
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return [
|
|
177
|
+
schematype.embeddedSchemaType.cast(search),
|
|
178
|
+
path
|
|
179
|
+
];
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// { $op: [<number>, <number>] }
|
|
183
|
+
function castArithmetic(val) {
|
|
184
|
+
if (!Array.isArray(val)) {
|
|
185
|
+
if (!isLiteral(val)) {
|
|
186
|
+
return val;
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
return castNumber(val);
|
|
190
|
+
} catch {
|
|
191
|
+
throw new CastError('Number', val);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return val.map(v => {
|
|
196
|
+
if (!isLiteral(v)) {
|
|
197
|
+
return v;
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
return castNumber(v);
|
|
201
|
+
} catch {
|
|
202
|
+
throw new CastError('Number', v);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// { $op: [expression, expression] }
|
|
208
|
+
function castComparison(val, schema, strictQuery) {
|
|
209
|
+
if (!Array.isArray(val) || val.length !== 2) {
|
|
210
|
+
throw new Error('Comparison operator must be an array of length 2');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
val[0] = _castExpression(val[0], schema, strictQuery);
|
|
214
|
+
const lhs = val[0];
|
|
215
|
+
|
|
216
|
+
if (isLiteral(val[1])) {
|
|
217
|
+
let path = null;
|
|
218
|
+
let schematype = null;
|
|
219
|
+
let caster = null;
|
|
220
|
+
if (isPath(lhs)) {
|
|
221
|
+
path = lhs.slice(1);
|
|
222
|
+
schematype = schema.path(path);
|
|
223
|
+
} else if (typeof lhs === 'object' && lhs != null) {
|
|
224
|
+
for (const key of Object.keys(lhs)) {
|
|
225
|
+
if (dateOperators.has(key) && isPath(lhs[key])) {
|
|
226
|
+
path = lhs[key].slice(1) + '.' + key;
|
|
227
|
+
caster = castNumber;
|
|
228
|
+
} else if (arrayElementOperators.has(key) && isPath(lhs[key])) {
|
|
229
|
+
path = lhs[key].slice(1) + '.' + key;
|
|
230
|
+
schematype = schema.path(lhs[key].slice(1));
|
|
231
|
+
if (schematype != null) {
|
|
232
|
+
if (schematype.$isMongooseArray) {
|
|
233
|
+
schematype = schematype.embeddedSchemaType;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const is$literal = typeof val[1] === 'object' && val[1] != null && val[1].$literal != null;
|
|
241
|
+
if (schematype != null) {
|
|
242
|
+
if (is$literal) {
|
|
243
|
+
val[1] = { $literal: schematype.cast(val[1].$literal) };
|
|
244
|
+
} else {
|
|
245
|
+
val[1] = schematype.cast(val[1]);
|
|
246
|
+
}
|
|
247
|
+
} else if (caster != null) {
|
|
248
|
+
if (is$literal) {
|
|
249
|
+
try {
|
|
250
|
+
val[1] = { $literal: caster(val[1].$literal) };
|
|
251
|
+
} catch {
|
|
252
|
+
throw new CastError(caster.name.replace(/^cast/, ''), val[1], path + '.$literal');
|
|
253
|
+
}
|
|
254
|
+
} else {
|
|
255
|
+
try {
|
|
256
|
+
val[1] = caster(val[1]);
|
|
257
|
+
} catch {
|
|
258
|
+
throw new CastError(caster.name.replace(/^cast/, ''), val[1], path);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
} else if (path != null && strictQuery === true) {
|
|
262
|
+
return void 0;
|
|
263
|
+
} else if (path != null && strictQuery === 'throw') {
|
|
264
|
+
throw new StrictModeError(path);
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
val[1] = _castExpression(val[1]);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return val;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
function isPath(val) {
|
|
274
|
+
return typeof val === 'string' && val[0] === '$';
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function isLiteral(val) {
|
|
278
|
+
if (typeof val === 'string' && val[0] === '$') {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (typeof val === 'object' && val !== null && Object.keys(val).find(key => key[0] === '$')) {
|
|
282
|
+
// The `$literal` expression can make an object a literal
|
|
283
|
+
// https://www.mongodb.com/docs/manual/reference/operator/aggregation/literal/#mongodb-expression-exp.-literal
|
|
284
|
+
return val.$literal != null;
|
|
285
|
+
}
|
|
286
|
+
return true;
|
|
287
|
+
}
|