@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.
Files changed (295) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +397 -0
  3. package/SECURITY.md +1 -0
  4. package/eslint.config.mjs +198 -0
  5. package/index.js +64 -0
  6. package/lib/aggregate.js +1189 -0
  7. package/lib/cast/bigint.js +46 -0
  8. package/lib/cast/boolean.js +32 -0
  9. package/lib/cast/date.js +41 -0
  10. package/lib/cast/decimal128.js +39 -0
  11. package/lib/cast/double.js +50 -0
  12. package/lib/cast/int32.js +36 -0
  13. package/lib/cast/number.js +42 -0
  14. package/lib/cast/objectid.js +29 -0
  15. package/lib/cast/string.js +37 -0
  16. package/lib/cast/uuid.js +35 -0
  17. package/lib/cast.js +436 -0
  18. package/lib/collection.js +321 -0
  19. package/lib/connection.js +1855 -0
  20. package/lib/connectionState.js +26 -0
  21. package/lib/constants.js +73 -0
  22. package/lib/cursor/aggregationCursor.js +466 -0
  23. package/lib/cursor/changeStream.js +198 -0
  24. package/lib/cursor/queryCursor.js +622 -0
  25. package/lib/document.js +5521 -0
  26. package/lib/driver.js +15 -0
  27. package/lib/drivers/SPEC.md +4 -0
  28. package/lib/drivers/node-mongodb-native/bulkWriteResult.js +5 -0
  29. package/lib/drivers/node-mongodb-native/collection.js +393 -0
  30. package/lib/drivers/node-mongodb-native/connection.js +506 -0
  31. package/lib/drivers/node-mongodb-native/index.js +10 -0
  32. package/lib/error/browserMissingSchema.js +29 -0
  33. package/lib/error/bulkSaveIncompleteError.js +44 -0
  34. package/lib/error/bulkWriteError.js +41 -0
  35. package/lib/error/cast.js +158 -0
  36. package/lib/error/createCollectionsError.js +26 -0
  37. package/lib/error/divergentArray.js +40 -0
  38. package/lib/error/eachAsyncMultiError.js +41 -0
  39. package/lib/error/index.js +237 -0
  40. package/lib/error/invalidSchemaOption.js +32 -0
  41. package/lib/error/messages.js +47 -0
  42. package/lib/error/missingSchema.js +33 -0
  43. package/lib/error/mongooseError.js +13 -0
  44. package/lib/error/notFound.js +47 -0
  45. package/lib/error/objectExpected.js +31 -0
  46. package/lib/error/objectParameter.js +31 -0
  47. package/lib/error/overwriteModel.js +31 -0
  48. package/lib/error/parallelSave.js +33 -0
  49. package/lib/error/parallelValidate.js +33 -0
  50. package/lib/error/serverSelection.js +62 -0
  51. package/lib/error/setOptionError.js +103 -0
  52. package/lib/error/strict.js +35 -0
  53. package/lib/error/strictPopulate.js +31 -0
  54. package/lib/error/syncIndexes.js +30 -0
  55. package/lib/error/validation.js +97 -0
  56. package/lib/error/validator.js +100 -0
  57. package/lib/error/version.js +38 -0
  58. package/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +39 -0
  59. package/lib/helpers/aggregate/stringifyFunctionOperators.js +50 -0
  60. package/lib/helpers/arrayDepth.js +33 -0
  61. package/lib/helpers/clone.js +204 -0
  62. package/lib/helpers/common.js +127 -0
  63. package/lib/helpers/createJSONSchemaTypeDefinition.js +24 -0
  64. package/lib/helpers/cursor/eachAsync.js +225 -0
  65. package/lib/helpers/discriminator/applyEmbeddedDiscriminators.js +36 -0
  66. package/lib/helpers/discriminator/areDiscriminatorValuesEqual.js +16 -0
  67. package/lib/helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection.js +12 -0
  68. package/lib/helpers/discriminator/getConstructor.js +29 -0
  69. package/lib/helpers/discriminator/getDiscriminatorByValue.js +28 -0
  70. package/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +27 -0
  71. package/lib/helpers/discriminator/mergeDiscriminatorSchema.js +91 -0
  72. package/lib/helpers/document/applyDefaults.js +132 -0
  73. package/lib/helpers/document/applyTimestamps.js +106 -0
  74. package/lib/helpers/document/applyVirtuals.js +147 -0
  75. package/lib/helpers/document/cleanModifiedSubpaths.js +45 -0
  76. package/lib/helpers/document/compile.js +238 -0
  77. package/lib/helpers/document/getDeepestSubdocumentForPath.js +38 -0
  78. package/lib/helpers/document/getEmbeddedDiscriminatorPath.js +53 -0
  79. package/lib/helpers/document/handleSpreadDoc.js +35 -0
  80. package/lib/helpers/each.js +25 -0
  81. package/lib/helpers/error/combinePathErrors.js +22 -0
  82. package/lib/helpers/firstKey.js +8 -0
  83. package/lib/helpers/get.js +65 -0
  84. package/lib/helpers/getConstructorName.js +16 -0
  85. package/lib/helpers/getDefaultBulkwriteResult.js +18 -0
  86. package/lib/helpers/getFunctionName.js +10 -0
  87. package/lib/helpers/immediate.js +16 -0
  88. package/lib/helpers/indexes/applySchemaCollation.js +13 -0
  89. package/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +14 -0
  90. package/lib/helpers/indexes/getRelatedIndexes.js +63 -0
  91. package/lib/helpers/indexes/isDefaultIdIndex.js +18 -0
  92. package/lib/helpers/indexes/isIndexEqual.js +95 -0
  93. package/lib/helpers/indexes/isIndexSpecEqual.js +32 -0
  94. package/lib/helpers/indexes/isTextIndex.js +16 -0
  95. package/lib/helpers/indexes/isTimeseriesIndex.js +16 -0
  96. package/lib/helpers/isAsyncFunction.js +9 -0
  97. package/lib/helpers/isBsonType.js +15 -0
  98. package/lib/helpers/isMongooseObject.js +22 -0
  99. package/lib/helpers/isObject.js +16 -0
  100. package/lib/helpers/isPOJO.js +12 -0
  101. package/lib/helpers/isPromise.js +6 -0
  102. package/lib/helpers/isSimpleValidator.js +22 -0
  103. package/lib/helpers/minimize.js +41 -0
  104. package/lib/helpers/model/applyDefaultsToPOJO.js +52 -0
  105. package/lib/helpers/model/applyHooks.js +140 -0
  106. package/lib/helpers/model/applyMethods.js +70 -0
  107. package/lib/helpers/model/applyStaticHooks.js +33 -0
  108. package/lib/helpers/model/applyStatics.js +13 -0
  109. package/lib/helpers/model/castBulkWrite.js +316 -0
  110. package/lib/helpers/model/decorateBulkWriteResult.js +8 -0
  111. package/lib/helpers/model/discriminator.js +265 -0
  112. package/lib/helpers/model/pushNestedArrayPaths.js +15 -0
  113. package/lib/helpers/omitUndefined.js +20 -0
  114. package/lib/helpers/once.js +12 -0
  115. package/lib/helpers/parallelLimit.js +37 -0
  116. package/lib/helpers/path/parentPaths.js +18 -0
  117. package/lib/helpers/path/setDottedPath.js +33 -0
  118. package/lib/helpers/pluralize.js +95 -0
  119. package/lib/helpers/populate/assignRawDocsToIdStructure.js +129 -0
  120. package/lib/helpers/populate/assignVals.js +360 -0
  121. package/lib/helpers/populate/createPopulateQueryFilter.js +97 -0
  122. package/lib/helpers/populate/getModelsMapForPopulate.js +776 -0
  123. package/lib/helpers/populate/getSchemaTypes.js +228 -0
  124. package/lib/helpers/populate/getVirtual.js +103 -0
  125. package/lib/helpers/populate/leanPopulateMap.js +7 -0
  126. package/lib/helpers/populate/lookupLocalFields.js +40 -0
  127. package/lib/helpers/populate/markArraySubdocsPopulated.js +49 -0
  128. package/lib/helpers/populate/modelNamesFromRefPath.js +66 -0
  129. package/lib/helpers/populate/removeDeselectedForeignField.js +31 -0
  130. package/lib/helpers/populate/setPopulatedVirtualValue.js +33 -0
  131. package/lib/helpers/populate/skipPopulateValue.js +10 -0
  132. package/lib/helpers/populate/validateRef.js +19 -0
  133. package/lib/helpers/printJestWarning.js +21 -0
  134. package/lib/helpers/processConnectionOptions.js +65 -0
  135. package/lib/helpers/projection/applyProjection.js +83 -0
  136. package/lib/helpers/projection/hasIncludedChildren.js +41 -0
  137. package/lib/helpers/projection/isDefiningProjection.js +18 -0
  138. package/lib/helpers/projection/isExclusive.js +37 -0
  139. package/lib/helpers/projection/isInclusive.js +39 -0
  140. package/lib/helpers/projection/isNestedProjection.js +8 -0
  141. package/lib/helpers/projection/isPathExcluded.js +40 -0
  142. package/lib/helpers/projection/isPathSelectedInclusive.js +28 -0
  143. package/lib/helpers/projection/isSubpath.js +14 -0
  144. package/lib/helpers/projection/parseProjection.js +33 -0
  145. package/lib/helpers/query/applyGlobalOption.js +29 -0
  146. package/lib/helpers/query/cast$expr.js +287 -0
  147. package/lib/helpers/query/castFilterPath.js +54 -0
  148. package/lib/helpers/query/castUpdate.js +643 -0
  149. package/lib/helpers/query/getEmbeddedDiscriminatorPath.js +103 -0
  150. package/lib/helpers/query/handleImmutable.js +44 -0
  151. package/lib/helpers/query/handleReadPreferenceAliases.js +23 -0
  152. package/lib/helpers/query/hasDollarKeys.js +23 -0
  153. package/lib/helpers/query/isOperator.js +14 -0
  154. package/lib/helpers/query/sanitizeFilter.js +38 -0
  155. package/lib/helpers/query/sanitizeProjection.js +14 -0
  156. package/lib/helpers/query/selectPopulatedFields.js +62 -0
  157. package/lib/helpers/query/trusted.js +13 -0
  158. package/lib/helpers/query/validOps.js +3 -0
  159. package/lib/helpers/schema/addAutoId.js +7 -0
  160. package/lib/helpers/schema/applyBuiltinPlugins.js +12 -0
  161. package/lib/helpers/schema/applyPlugins.js +55 -0
  162. package/lib/helpers/schema/applyReadConcern.js +20 -0
  163. package/lib/helpers/schema/applyWriteConcern.js +39 -0
  164. package/lib/helpers/schema/cleanPositionalOperators.js +12 -0
  165. package/lib/helpers/schema/getIndexes.js +171 -0
  166. package/lib/helpers/schema/getKeysInSchemaOrder.js +28 -0
  167. package/lib/helpers/schema/getPath.js +43 -0
  168. package/lib/helpers/schema/getSubdocumentStrictValue.js +32 -0
  169. package/lib/helpers/schema/handleIdOption.js +20 -0
  170. package/lib/helpers/schema/handleTimestampOption.js +24 -0
  171. package/lib/helpers/schema/idGetter.js +34 -0
  172. package/lib/helpers/schema/merge.js +36 -0
  173. package/lib/helpers/schematype/handleImmutable.js +50 -0
  174. package/lib/helpers/setDefaultsOnInsert.js +158 -0
  175. package/lib/helpers/specialProperties.js +3 -0
  176. package/lib/helpers/symbols.js +20 -0
  177. package/lib/helpers/timers.js +3 -0
  178. package/lib/helpers/timestamps/setDocumentTimestamps.js +26 -0
  179. package/lib/helpers/timestamps/setupTimestamps.js +116 -0
  180. package/lib/helpers/topology/allServersUnknown.js +12 -0
  181. package/lib/helpers/topology/isAtlas.js +31 -0
  182. package/lib/helpers/topology/isSSLError.js +16 -0
  183. package/lib/helpers/update/applyTimestampsToChildren.js +193 -0
  184. package/lib/helpers/update/applyTimestampsToUpdate.js +131 -0
  185. package/lib/helpers/update/castArrayFilters.js +113 -0
  186. package/lib/helpers/update/decorateUpdateWithVersionKey.js +35 -0
  187. package/lib/helpers/update/modifiedPaths.js +33 -0
  188. package/lib/helpers/update/moveImmutableProperties.js +53 -0
  189. package/lib/helpers/update/removeUnusedArrayFilters.js +32 -0
  190. package/lib/helpers/update/updatedPathsByArrayFilter.js +27 -0
  191. package/lib/helpers/updateValidators.js +193 -0
  192. package/lib/index.js +17 -0
  193. package/lib/internal.js +46 -0
  194. package/lib/model.js +5010 -0
  195. package/lib/modifiedPathsSnapshot.js +9 -0
  196. package/lib/mongoose.js +1411 -0
  197. package/lib/options/populateOptions.js +36 -0
  198. package/lib/options/propertyOptions.js +8 -0
  199. package/lib/options/saveOptions.js +16 -0
  200. package/lib/options/schemaArrayOptions.js +78 -0
  201. package/lib/options/schemaBufferOptions.js +38 -0
  202. package/lib/options/schemaDateOptions.js +71 -0
  203. package/lib/options/schemaDocumentArrayOptions.js +68 -0
  204. package/lib/options/schemaMapOptions.js +43 -0
  205. package/lib/options/schemaNumberOptions.js +101 -0
  206. package/lib/options/schemaObjectIdOptions.js +64 -0
  207. package/lib/options/schemaStringOptions.js +138 -0
  208. package/lib/options/schemaSubdocumentOptions.js +66 -0
  209. package/lib/options/schemaTypeOptions.js +244 -0
  210. package/lib/options/schemaUnionOptions.js +32 -0
  211. package/lib/options/virtualOptions.js +164 -0
  212. package/lib/options.js +17 -0
  213. package/lib/plugins/index.js +6 -0
  214. package/lib/plugins/saveSubdocs.js +76 -0
  215. package/lib/plugins/sharding.js +84 -0
  216. package/lib/plugins/trackTransaction.js +84 -0
  217. package/lib/plugins/validateBeforeSave.js +41 -0
  218. package/lib/query.js +5673 -0
  219. package/lib/queryHelpers.js +387 -0
  220. package/lib/schema/array.js +699 -0
  221. package/lib/schema/bigint.js +282 -0
  222. package/lib/schema/boolean.js +332 -0
  223. package/lib/schema/buffer.js +343 -0
  224. package/lib/schema/date.js +467 -0
  225. package/lib/schema/decimal128.js +263 -0
  226. package/lib/schema/documentArray.js +656 -0
  227. package/lib/schema/documentArrayElement.js +137 -0
  228. package/lib/schema/double.js +246 -0
  229. package/lib/schema/index.js +32 -0
  230. package/lib/schema/int32.js +289 -0
  231. package/lib/schema/map.js +201 -0
  232. package/lib/schema/mixed.js +146 -0
  233. package/lib/schema/number.js +510 -0
  234. package/lib/schema/objectId.js +333 -0
  235. package/lib/schema/operators/bitwise.js +38 -0
  236. package/lib/schema/operators/exists.js +12 -0
  237. package/lib/schema/operators/geospatial.js +107 -0
  238. package/lib/schema/operators/helpers.js +32 -0
  239. package/lib/schema/operators/text.js +39 -0
  240. package/lib/schema/operators/type.js +20 -0
  241. package/lib/schema/string.js +733 -0
  242. package/lib/schema/subdocument.js +436 -0
  243. package/lib/schema/symbols.js +5 -0
  244. package/lib/schema/union.js +113 -0
  245. package/lib/schema/uuid.js +305 -0
  246. package/lib/schema.js +3226 -0
  247. package/lib/schemaType.js +1835 -0
  248. package/lib/stateMachine.js +232 -0
  249. package/lib/types/array/index.js +119 -0
  250. package/lib/types/array/isMongooseArray.js +5 -0
  251. package/lib/types/array/methods/index.js +1095 -0
  252. package/lib/types/arraySubdocument.js +207 -0
  253. package/lib/types/buffer.js +294 -0
  254. package/lib/types/decimal128.js +13 -0
  255. package/lib/types/documentArray/index.js +113 -0
  256. package/lib/types/documentArray/isMongooseDocumentArray.js +5 -0
  257. package/lib/types/documentArray/methods/index.js +415 -0
  258. package/lib/types/double.js +13 -0
  259. package/lib/types/index.js +23 -0
  260. package/lib/types/map.js +419 -0
  261. package/lib/types/objectid.js +41 -0
  262. package/lib/types/subdocument.js +464 -0
  263. package/lib/types/uuid.js +13 -0
  264. package/lib/utils.js +1054 -0
  265. package/lib/validOptions.js +42 -0
  266. package/lib/virtualType.js +204 -0
  267. package/package.json +148 -0
  268. package/types/aggregate.d.ts +180 -0
  269. package/types/augmentations.d.ts +9 -0
  270. package/types/callback.d.ts +8 -0
  271. package/types/collection.d.ts +49 -0
  272. package/types/connection.d.ts +297 -0
  273. package/types/cursor.d.ts +67 -0
  274. package/types/document.d.ts +374 -0
  275. package/types/error.d.ts +143 -0
  276. package/types/expressions.d.ts +3053 -0
  277. package/types/helpers.d.ts +32 -0
  278. package/types/index.d.ts +1056 -0
  279. package/types/indexes.d.ts +97 -0
  280. package/types/inferhydrateddoctype.d.ts +115 -0
  281. package/types/inferrawdoctype.d.ts +135 -0
  282. package/types/inferschematype.d.ts +337 -0
  283. package/types/middlewares.d.ts +59 -0
  284. package/types/models.d.ts +1306 -0
  285. package/types/mongooseoptions.d.ts +228 -0
  286. package/types/pipelinestage.d.ts +333 -0
  287. package/types/populate.d.ts +53 -0
  288. package/types/query.d.ts +934 -0
  289. package/types/schemaoptions.d.ts +282 -0
  290. package/types/schematypes.d.ts +654 -0
  291. package/types/session.d.ts +32 -0
  292. package/types/types.d.ts +109 -0
  293. package/types/utility.d.ts +175 -0
  294. package/types/validation.d.ts +39 -0
  295. 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,8 @@
1
+ 'use strict';
2
+
3
+ module.exports = function isNestedProjection(val) {
4
+ if (val == null || typeof val !== 'object') {
5
+ return false;
6
+ }
7
+ return val.$slice == null && val.$elemMatch == null && val.$meta == null && val.$ == null;
8
+ };
@@ -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
+ }