@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,699 @@
1
+ 'use strict';
2
+
3
+ /*!
4
+ * Module dependencies.
5
+ */
6
+
7
+ const $exists = require('./operators/exists');
8
+ const $type = require('./operators/type');
9
+ const MongooseError = require('../error/mongooseError');
10
+ const SchemaArrayOptions = require('../options/schemaArrayOptions');
11
+ const SchemaType = require('../schemaType');
12
+ const CastError = SchemaType.CastError;
13
+ const Mixed = require('./mixed');
14
+ const VirtualOptions = require('../options/virtualOptions');
15
+ const VirtualType = require('../virtualType');
16
+ const arrayDepth = require('../helpers/arrayDepth');
17
+ const cast = require('../cast');
18
+ const clone = require('../helpers/clone');
19
+ const getConstructorName = require('../helpers/getConstructorName');
20
+ const isOperator = require('../helpers/query/isOperator');
21
+ const util = require('util');
22
+ const utils = require('../utils');
23
+ const castToNumber = require('./operators/helpers').castToNumber;
24
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
25
+ const geospatial = require('./operators/geospatial');
26
+ const getDiscriminatorByValue = require('../helpers/discriminator/getDiscriminatorByValue');
27
+
28
+ let MongooseArray;
29
+ let EmbeddedDoc;
30
+
31
+ const emptyOpts = Object.freeze({});
32
+
33
+ /**
34
+ * Array SchemaType constructor
35
+ *
36
+ * @param {String} key
37
+ * @param {SchemaType} cast
38
+ * @param {Object} options
39
+ * @param {Object} schemaOptions
40
+ * @param {Schema} parentSchema
41
+ * @inherits SchemaType
42
+ * @api public
43
+ */
44
+
45
+ function SchemaArray(key, cast, options, schemaOptions, parentSchema) {
46
+ // lazy load
47
+ EmbeddedDoc || (EmbeddedDoc = require('../types').Embedded);
48
+
49
+ let typeKey = 'type';
50
+ if (schemaOptions?.typeKey) {
51
+ typeKey = schemaOptions.typeKey;
52
+ }
53
+ this.schemaOptions = schemaOptions;
54
+
55
+ if (cast) {
56
+ let castOptions = {};
57
+
58
+ if (utils.isPOJO(cast)) {
59
+ if (cast[typeKey]) {
60
+ // support { type: Woot }
61
+ castOptions = clone(cast); // do not alter user arguments
62
+ delete castOptions[typeKey];
63
+ cast = cast[typeKey];
64
+ } else {
65
+ cast = Mixed;
66
+ }
67
+ }
68
+
69
+ if (options?.ref != null && castOptions.ref == null) {
70
+ castOptions.ref = options.ref;
71
+ }
72
+
73
+ if (cast === Object) {
74
+ cast = Mixed;
75
+ }
76
+
77
+ // support { type: 'String' }
78
+ const name = typeof cast === 'string'
79
+ ? cast
80
+ : utils.getFunctionName(cast);
81
+
82
+ const Types = require('./index.js');
83
+ const schemaTypeDefinition = Object.hasOwn(Types, name) ? Types[name] : cast;
84
+
85
+ if (typeof schemaTypeDefinition === 'function') {
86
+ if (schemaTypeDefinition === SchemaArray) {
87
+ this.embeddedSchemaType = new schemaTypeDefinition(key, castOptions, schemaOptions, null, parentSchema);
88
+ } else {
89
+ this.embeddedSchemaType = new schemaTypeDefinition(key, castOptions, schemaOptions, parentSchema);
90
+ }
91
+ } else if (schemaTypeDefinition instanceof SchemaType) {
92
+ this.embeddedSchemaType = schemaTypeDefinition;
93
+ if (!(this.embeddedSchemaType instanceof EmbeddedDoc)) {
94
+ this.embeddedSchemaType.path = key;
95
+ }
96
+ }
97
+
98
+ }
99
+
100
+ this.$isMongooseArray = true;
101
+
102
+ SchemaType.call(this, key, options, 'Array', parentSchema);
103
+
104
+ let defaultArr;
105
+ let fn;
106
+
107
+ if (this.defaultValue != null) {
108
+ defaultArr = this.defaultValue;
109
+ fn = typeof defaultArr === 'function';
110
+ }
111
+
112
+ if (!('defaultValue' in this) || this.defaultValue != null) {
113
+ const defaultFn = function() {
114
+ // Leave it up to `cast()` to convert the array
115
+ return fn
116
+ ? defaultArr.call(this)
117
+ : defaultArr != null
118
+ ? [].concat(defaultArr)
119
+ : [];
120
+ };
121
+ defaultFn.$runBeforeSetters = !fn;
122
+ this.default(defaultFn);
123
+ }
124
+ }
125
+
126
+ /**
127
+ * This schema type's name, to defend against minifiers that mangle
128
+ * function names.
129
+ *
130
+ * @api public
131
+ */
132
+ SchemaArray.schemaName = 'Array';
133
+
134
+
135
+ /**
136
+ * Options for all arrays.
137
+ *
138
+ * - `castNonArrays`: `true` by default. If `false`, Mongoose will throw a CastError when a value isn't an array. If `true`, Mongoose will wrap the provided value in an array before casting.
139
+ *
140
+ * @static
141
+ * @api public
142
+ */
143
+
144
+ SchemaArray.options = { castNonArrays: true };
145
+
146
+ /*!
147
+ * ignore
148
+ */
149
+
150
+ SchemaArray.defaultOptions = {};
151
+
152
+ /**
153
+ * Sets a default option for all Array instances.
154
+ *
155
+ * #### Example:
156
+ *
157
+ * // Make all Array instances have `required` of true by default.
158
+ * mongoose.Schema.Types.Array.set('required', true);
159
+ *
160
+ * const User = mongoose.model('User', new Schema({ test: Array }));
161
+ * new User({ }).validateSync().errors.test.message; // Path `test` is required.
162
+ *
163
+ * @param {String} option The option you'd like to set the value for
164
+ * @param {Any} value value for option
165
+ * @return {undefined}
166
+ * @function set
167
+ * @api public
168
+ */
169
+ SchemaArray.set = SchemaType.set;
170
+
171
+ SchemaArray.setters = [];
172
+
173
+ /**
174
+ * Attaches a getter for all Array instances
175
+ *
176
+ * @param {Function} getter
177
+ * @return {this}
178
+ * @function get
179
+ * @static
180
+ * @api public
181
+ */
182
+
183
+ SchemaArray.get = SchemaType.get;
184
+
185
+ /*!
186
+ * Inherits from SchemaType.
187
+ */
188
+ SchemaArray.prototype = Object.create(SchemaType.prototype);
189
+ SchemaArray.prototype.constructor = SchemaArray;
190
+ SchemaArray.prototype.OptionsConstructor = SchemaArrayOptions;
191
+
192
+ /*!
193
+ * ignore
194
+ */
195
+
196
+ SchemaArray._checkRequired = SchemaType.prototype.checkRequired;
197
+
198
+ /**
199
+ * Override the function the required validator uses to check whether an array
200
+ * passes the `required` check.
201
+ *
202
+ * #### Example:
203
+ *
204
+ * // Require non-empty array to pass `required` check
205
+ * mongoose.Schema.Types.Array.checkRequired(v => Array.isArray(v) && v.length);
206
+ *
207
+ * const M = mongoose.model({ arr: { type: Array, required: true } });
208
+ * new M({ arr: [] }).validateSync(); // `null`, validation fails!
209
+ *
210
+ * @param {Function} fn
211
+ * @return {Function}
212
+ * @function checkRequired
213
+ * @api public
214
+ */
215
+
216
+ SchemaArray.checkRequired = SchemaType.checkRequired;
217
+
218
+ /*!
219
+ * Virtuals defined on this array itself.
220
+ */
221
+
222
+ SchemaArray.prototype.virtuals = null;
223
+
224
+ /**
225
+ * Check if the given value satisfies the `required` validator.
226
+ *
227
+ * @param {Any} value
228
+ * @param {Document} doc
229
+ * @return {Boolean}
230
+ * @api public
231
+ */
232
+
233
+ SchemaArray.prototype.checkRequired = function checkRequired(value, doc) {
234
+ if (typeof value === 'object' && SchemaType._isRef(this, value, doc, true)) {
235
+ return !!value;
236
+ }
237
+
238
+ // `require('util').inherits()` does **not** copy static properties, and
239
+ // plugins like mongoose-float use `inherits()` for pre-ES6.
240
+ const _checkRequired = typeof this.constructor.checkRequired === 'function' ?
241
+ this.constructor.checkRequired() :
242
+ SchemaArray.checkRequired();
243
+
244
+ return _checkRequired(value);
245
+ };
246
+
247
+ /**
248
+ * Adds an enum validator if this is an array of strings or numbers. Equivalent to
249
+ * `SchemaString.prototype.enum()` or `SchemaNumber.prototype.enum()`
250
+ *
251
+ * @param {...String|Object} [args] enumeration values
252
+ * @return {SchemaArray} this
253
+ */
254
+
255
+ SchemaArray.prototype.enum = function() {
256
+ let arr = this;
257
+ while (true) {
258
+ const instance = arr?.embeddedSchemaType?.instance;
259
+ if (instance === 'Array') {
260
+ arr = arr.embeddedSchemaType;
261
+ continue;
262
+ }
263
+ if (instance !== 'String' && instance !== 'Number') {
264
+ throw new Error('`enum` can only be set on an array of strings or numbers ' +
265
+ ', not ' + instance);
266
+ }
267
+ break;
268
+ }
269
+
270
+ let enumArray = arguments;
271
+ if (!Array.isArray(arguments) && utils.isObject(arguments)) {
272
+ enumArray = utils.object.vals(enumArray);
273
+ }
274
+
275
+ arr.embeddedSchemaType.enum.apply(arr.embeddedSchemaType, enumArray);
276
+ return this;
277
+ };
278
+
279
+ /**
280
+ * Overrides the getters application for the population special-case
281
+ *
282
+ * @param {Object} value
283
+ * @param {Object} scope
284
+ * @api private
285
+ */
286
+
287
+ SchemaArray.prototype.applyGetters = function(value, scope) {
288
+ if (scope?.$__ != null && scope.$populated(this.path)) {
289
+ // means the object id was populated
290
+ return value;
291
+ }
292
+
293
+ const ret = SchemaType.prototype.applyGetters.call(this, value, scope);
294
+ return ret;
295
+ };
296
+
297
+ SchemaArray.prototype._applySetters = function(value, scope, init, priorVal) {
298
+ if (this.embeddedSchemaType.$isMongooseArray &&
299
+ SchemaArray.options.castNonArrays) {
300
+ // Check nesting levels and wrap in array if necessary
301
+ let depth = 0;
302
+ let arr = this;
303
+ while (arr != null &&
304
+ arr.$isMongooseArray &&
305
+ !arr.$isMongooseDocumentArray) {
306
+ ++depth;
307
+ arr = arr.embeddedSchemaType;
308
+ }
309
+
310
+ // No need to wrap empty arrays
311
+ if (value != null && value.length !== 0) {
312
+ const valueDepth = arrayDepth(value);
313
+ if (valueDepth.min === valueDepth.max && valueDepth.max < depth && valueDepth.containsNonArrayItem) {
314
+ for (let i = valueDepth.max; i < depth; ++i) {
315
+ value = [value];
316
+ }
317
+ }
318
+ }
319
+ }
320
+
321
+ return SchemaType.prototype._applySetters.call(this, value, scope, init, priorVal);
322
+ };
323
+
324
+ /**
325
+ * Casts values for set().
326
+ *
327
+ * @param {Object} value
328
+ * @param {Document} doc document that triggers the casting
329
+ * @param {Boolean} init whether this is an initialization cast
330
+ * @api private
331
+ */
332
+
333
+ SchemaArray.prototype.cast = function(value, doc, init, prev, options) {
334
+ // lazy load
335
+ MongooseArray || (MongooseArray = require('../types').Array);
336
+
337
+ let i;
338
+ let l;
339
+
340
+ if (Array.isArray(value)) {
341
+ const len = value.length;
342
+ if (!len && doc) {
343
+ const indexes = doc.schema.indexedPaths();
344
+
345
+ const arrayPath = this.path;
346
+ for (i = 0, l = indexes.length; i < l; ++i) {
347
+ const pathIndex = indexes[i][0][arrayPath];
348
+ if (pathIndex === '2dsphere' || pathIndex === '2d') {
349
+ return;
350
+ }
351
+ }
352
+
353
+ // Special case: if this index is on the parent of what looks like
354
+ // GeoJSON, skip setting the default to empty array re: #1668, #3233
355
+ const arrayGeojsonPath = this.path.endsWith('.coordinates') ?
356
+ this.path.substring(0, this.path.lastIndexOf('.')) : null;
357
+ if (arrayGeojsonPath != null) {
358
+ for (i = 0, l = indexes.length; i < l; ++i) {
359
+ const pathIndex = indexes[i][0][arrayGeojsonPath];
360
+ if (pathIndex === '2dsphere') {
361
+ return;
362
+ }
363
+ }
364
+ }
365
+ }
366
+
367
+ options = options || emptyOpts;
368
+
369
+ let rawValue = utils.isMongooseArray(value) ? value.__array : value;
370
+ let path = options.path || this.path;
371
+ if (options.arrayPathIndex != null) {
372
+ path += '.' + options.arrayPathIndex;
373
+ }
374
+ value = MongooseArray(rawValue, path, doc, this);
375
+ rawValue = value.__array;
376
+
377
+ if (init && doc?.$__ != null && doc.$populated(this.path)) {
378
+ return value;
379
+ }
380
+
381
+ const caster = this.embeddedSchemaType;
382
+ const isMongooseArray = caster.$isMongooseArray;
383
+ if (caster && this.embeddedSchemaType.constructor !== Mixed) {
384
+ try {
385
+ const len = rawValue.length;
386
+ for (i = 0; i < len; i++) {
387
+ const opts = {};
388
+ // Perf: creating `arrayPath` is expensive for large arrays.
389
+ // We only need `arrayPath` if this is a nested array, so
390
+ // skip if possible.
391
+ if (isMongooseArray) {
392
+ if (options.arrayPath != null) {
393
+ opts.arrayPathIndex = i;
394
+ } else if (caster._arrayParentPath != null) {
395
+ opts.arrayPathIndex = i;
396
+ }
397
+ }
398
+ if (options.hydratedPopulatedDocs) {
399
+ opts.hydratedPopulatedDocs = options.hydratedPopulatedDocs;
400
+ }
401
+ rawValue[i] = caster.applySetters(rawValue[i], doc, init, void 0, opts);
402
+ }
403
+ } catch (e) {
404
+ // rethrow
405
+ throw new CastError('[' + e.kind + ']', util.inspect(value), this.path + '.' + i, e, this);
406
+ }
407
+ }
408
+
409
+ return value;
410
+ }
411
+
412
+ const castNonArraysOption = this.options.castNonArrays ?? SchemaArray.options.castNonArrays;
413
+ if (init || castNonArraysOption) {
414
+ // gh-2442: if we're loading this from the db and its not an array, mark
415
+ // the whole array as modified.
416
+ if (doc && init) {
417
+ doc.markModified(this.path);
418
+ }
419
+ return this.cast([value], doc, init);
420
+ }
421
+
422
+ throw new CastError('Array', util.inspect(value), this.path, null, this);
423
+ };
424
+
425
+ /*!
426
+ * ignore
427
+ */
428
+
429
+ SchemaArray.prototype._castForPopulate = function _castForPopulate(value, doc) {
430
+ // lazy load
431
+ MongooseArray || (MongooseArray = require('../types').Array);
432
+
433
+ if (Array.isArray(value)) {
434
+ let i;
435
+ const rawValue = value.__array ? value.__array : value;
436
+ const len = rawValue.length;
437
+
438
+ if (this.embeddedSchemaType && this.embeddedSchemaType.constructor !== Mixed) {
439
+ try {
440
+ for (i = 0; i < len; i++) {
441
+ const opts = {};
442
+ // Perf: creating `arrayPath` is expensive for large arrays.
443
+ // We only need `arrayPath` if this is a nested array, so
444
+ // skip if possible.
445
+ if (this.embeddedSchemaType.$isMongooseArray && this.embeddedSchemaType._arrayParentPath != null) {
446
+ opts.arrayPathIndex = i;
447
+ }
448
+
449
+ rawValue[i] = this.embeddedSchemaType.cast(rawValue[i], doc, false, void 0, opts);
450
+ }
451
+ } catch (e) {
452
+ // rethrow
453
+ throw new CastError('[' + e.kind + ']', util.inspect(value), this.path + '.' + i, e, this);
454
+ }
455
+ }
456
+
457
+ return value;
458
+ }
459
+
460
+ throw new CastError('Array', util.inspect(value), this.path, null, this);
461
+ };
462
+
463
+ SchemaArray.prototype.$toObject = SchemaArray.prototype.toObject;
464
+
465
+ /*!
466
+ * ignore
467
+ */
468
+
469
+ SchemaArray.prototype.discriminator = function(...args) {
470
+ let arr = this;
471
+ while (arr.$isMongooseArray && !arr.$isMongooseDocumentArray) {
472
+ arr = arr.embeddedSchemaType;
473
+ }
474
+ if (!arr.$isMongooseDocumentArray) {
475
+ throw new MongooseError('You can only add an embedded discriminator on a document array, ' + this.path + ' is a plain array');
476
+ }
477
+ return arr.discriminator(...args);
478
+ };
479
+
480
+ /*!
481
+ * ignore
482
+ */
483
+
484
+ SchemaArray.prototype.clone = function() {
485
+ const options = Object.assign({}, this.options);
486
+ const schematype = new this.constructor(this.path, this.embeddedSchemaType, options, this.schemaOptions, this.parentSchema);
487
+ schematype.validators = this.validators.slice();
488
+ if (this.requiredValidator !== undefined) {
489
+ schematype.requiredValidator = this.requiredValidator;
490
+ }
491
+ return schematype;
492
+ };
493
+
494
+ SchemaArray.prototype._castForQuery = function(val, context) {
495
+ let embeddedSchemaType = this.embeddedSchemaType;
496
+ const discriminatorKey = embeddedSchemaType?.schema?.options?.discriminatorKey;
497
+ const discriminators = embeddedSchemaType?.discriminators;
498
+
499
+ if (val && discriminators && typeof discriminatorKey === 'string') {
500
+ if (discriminators[val[discriminatorKey]]) {
501
+ embeddedSchemaType = discriminators[val[discriminatorKey]];
502
+ } else {
503
+ const constructorByValue = getDiscriminatorByValue(discriminators, val[discriminatorKey]);
504
+ if (constructorByValue) {
505
+ embeddedSchemaType = constructorByValue;
506
+ }
507
+ }
508
+ }
509
+
510
+ if (Array.isArray(val)) {
511
+ this.setters.reverse().forEach(setter => {
512
+ val = setter.call(this, val, this);
513
+ });
514
+ val = val.map(function(v) {
515
+ if (utils.isObject(v) && v.$elemMatch) {
516
+ return v;
517
+ }
518
+ return embeddedSchemaType.castForQuery(null, v, context);
519
+ });
520
+ } else {
521
+ val = embeddedSchemaType.castForQuery(null, val, context);
522
+ }
523
+
524
+ return val;
525
+ };
526
+
527
+ /**
528
+ * Casts values for queries.
529
+ *
530
+ * @param {String} $conditional
531
+ * @param {any} [value]
532
+ * @api private
533
+ */
534
+
535
+ SchemaArray.prototype.castForQuery = function($conditional, val, context) {
536
+ let handler;
537
+
538
+ if ($conditional != null) {
539
+ handler = this.$conditionalHandlers[$conditional];
540
+
541
+ if (!handler) {
542
+ throw new Error('Can\'t use ' + $conditional + ' with Array.');
543
+ }
544
+
545
+ return handler.call(this, val, context);
546
+ } else {
547
+ return this._castForQuery(val, context);
548
+ }
549
+ };
550
+
551
+ /**
552
+ * Add a virtual to this array. Specifically to this array, not the individual elements.
553
+ *
554
+ * @param {String} name
555
+ * @param {Object} [options]
556
+ * @api private
557
+ */
558
+
559
+ SchemaArray.prototype.virtual = function virtual(name, options) {
560
+ if (name instanceof VirtualType || getConstructorName(name) === 'VirtualType') {
561
+ return this.virtual(name.path, name.options);
562
+ }
563
+ options = new VirtualOptions(options);
564
+
565
+ if (utils.hasUserDefinedProperty(options, ['ref', 'refPath'])) {
566
+ throw new MongooseError('Cannot set populate virtual as a property of an array');
567
+ }
568
+
569
+ const virtual = new VirtualType(options, name);
570
+ if (this.virtuals === null) {
571
+ this.virtuals = {};
572
+ }
573
+ this.virtuals[name] = virtual;
574
+ return virtual;
575
+ };
576
+
577
+ function cast$all(val, context) {
578
+ if (!Array.isArray(val)) {
579
+ val = [val];
580
+ }
581
+
582
+ val = val.map((v) => {
583
+ if (!utils.isObject(v)) {
584
+ return v;
585
+ }
586
+ if (v.$elemMatch != null) {
587
+ return { $elemMatch: cast(this.embeddedSchemaType.schema, v.$elemMatch, null, this?.$$context) };
588
+ }
589
+
590
+ const o = {};
591
+ o[this.path] = v;
592
+ return cast(this.embeddedSchemaType.schema, o, null, this?.$$context)[this.path];
593
+ }, this);
594
+
595
+ return this.castForQuery(null, val, context);
596
+ }
597
+
598
+ function cast$elemMatch(val, context) {
599
+ const keys = Object.keys(val);
600
+ const numKeys = keys.length;
601
+ for (let i = 0; i < numKeys; ++i) {
602
+ const key = keys[i];
603
+ const value = val[key];
604
+ if (isOperator(key) && value != null) {
605
+ val[key] = this.castForQuery(key, value, context);
606
+ }
607
+ }
608
+
609
+ return val;
610
+ }
611
+
612
+ /**
613
+ * Contains the handlers for different query operators for this schema type.
614
+ * For example, `$conditionalHandlers.$all` is the function Mongoose calls to cast `$all` filter operators.
615
+ *
616
+ * @property $conditionalHandlers
617
+ * @memberOf SchemaArray
618
+ * @instance
619
+ * @api public
620
+ */
621
+
622
+ const handle = SchemaArray.prototype.$conditionalHandlers = {};
623
+
624
+ handle.$all = cast$all;
625
+ handle.$options = String;
626
+ handle.$elemMatch = cast$elemMatch;
627
+ handle.$geoIntersects = geospatial.cast$geoIntersects;
628
+ handle.$or = createLogicalQueryOperatorHandler('$or');
629
+ handle.$and = createLogicalQueryOperatorHandler('$and');
630
+ handle.$nor = createLogicalQueryOperatorHandler('$nor');
631
+
632
+ function createLogicalQueryOperatorHandler(op) {
633
+ return function logicalQueryOperatorHandler(val, context) {
634
+ if (!Array.isArray(val)) {
635
+ throw new TypeError('conditional ' + op + ' requires an array');
636
+ }
637
+
638
+ const ret = [];
639
+ for (const obj of val) {
640
+ ret.push(cast(this.embeddedSchemaType.schema ?? context.schema, obj, null, this?.$$context));
641
+ }
642
+
643
+ return ret;
644
+ };
645
+ }
646
+
647
+ handle.$near =
648
+ handle.$nearSphere = geospatial.cast$near;
649
+
650
+ handle.$within =
651
+ handle.$geoWithin = geospatial.cast$within;
652
+
653
+ handle.$size =
654
+ handle.$minDistance =
655
+ handle.$maxDistance = castToNumber;
656
+
657
+ handle.$exists = $exists;
658
+ handle.$type = $type;
659
+
660
+ handle.$eq =
661
+ handle.$gt =
662
+ handle.$gte =
663
+ handle.$lt =
664
+ handle.$lte =
665
+ handle.$not =
666
+ handle.$regex =
667
+ handle.$ne = SchemaArray.prototype._castForQuery;
668
+
669
+ // `$in` is special because you can also include an empty array in the query
670
+ // like `$in: [1, []]`, see gh-5913
671
+ handle.$nin = SchemaType.prototype.$conditionalHandlers.$nin;
672
+ handle.$in = SchemaType.prototype.$conditionalHandlers.$in;
673
+
674
+ /**
675
+ * Returns this schema type's representation in a JSON schema.
676
+ *
677
+ * @param [options]
678
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
679
+ * @returns {Object} JSON schema properties
680
+ */
681
+
682
+ SchemaArray.prototype.toJSONSchema = function toJSONSchema(options) {
683
+ const embeddedSchemaType = this.getEmbeddedSchemaType();
684
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
685
+ return {
686
+ ...createJSONSchemaTypeDefinition('array', 'array', options?.useBsonType, isRequired),
687
+ items: embeddedSchemaType.toJSONSchema(options)
688
+ };
689
+ };
690
+
691
+ SchemaArray.prototype.autoEncryptionType = function autoEncryptionType() {
692
+ return 'array';
693
+ };
694
+
695
+ /*!
696
+ * Module exports.
697
+ */
698
+
699
+ module.exports = SchemaArray;