@nullix/zod-mongoose-studio 1.0.12 → 2.0.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 (314) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{Db4IAypj.js → 0J_bLG6U.js} +1 -1
  3. package/.output/public/_nuxt/{Y39o1QEi.js → 5KLjKHc1.js} +1 -1
  4. package/.output/public/_nuxt/{B4zoPYF-.js → B2UrsJHg.js} +1 -1
  5. package/.output/public/_nuxt/{BSqjh6Vk.js → BC5hGokz.js} +1 -1
  6. package/.output/public/_nuxt/{BS4yU4O0.js → BJwN20Xm.js} +1 -1
  7. package/.output/public/_nuxt/{D8_n84hl.js → BMgDPqps.js} +1 -1
  8. package/.output/public/_nuxt/{CqNsQbt9.js → B_sGF2qN.js} +1 -1
  9. package/.output/public/_nuxt/{NAqlztEN.js → BeaJ7I-K.js} +10 -10
  10. package/.output/public/_nuxt/{WZ0WK9cR.js → BkE1sm_1.js} +1 -1
  11. package/.output/public/_nuxt/{kBtP64Rx.js → CADbZwE5.js} +1 -1
  12. package/.output/public/_nuxt/{B8qGaxNm.js → CB0WRoVi.js} +1 -1
  13. package/.output/public/_nuxt/{BV6uALfO.js → CCh0PVV0.js} +1 -1
  14. package/.output/public/_nuxt/{CP9Z7-_9.js → Cr0GW7rA.js} +1 -1
  15. package/.output/public/_nuxt/{DeCqoVOS.js → DJe7Wxdv.js} +1 -1
  16. package/.output/public/_nuxt/{dBZQW7JD.js → DRBrUaE5.js} +1 -1
  17. package/.output/public/_nuxt/{Db19R32y.js → DV2n9B6m.js} +1 -1
  18. package/.output/public/_nuxt/{CvnpbYw0.js → DVD-jGiv.js} +1 -1
  19. package/.output/public/_nuxt/{BWajNATZ.js → Dk9qGA5X.js} +3 -3
  20. package/.output/public/_nuxt/builds/latest.json +1 -1
  21. package/.output/public/_nuxt/builds/meta/dc761332-547d-4953-b51d-b2d453009b48.json +1 -0
  22. package/.output/public/_nuxt/error-404.64pZEiDn.css +1 -0
  23. package/.output/public/_nuxt/error-500.DHOpI0Ir.css +1 -0
  24. package/.output/public/_nuxt/{BoHhCIKW.js → koEZfutw.js} +3 -3
  25. package/.output/public/_nuxt/{B_782F4p.js → r6LdR7DN.js} +1 -1
  26. package/.output/public/_nuxt/{BEI71c6K.js → rEfOp38p.js} +1 -1
  27. package/.output/server/chunks/_/error-500.mjs.map +1 -1
  28. package/.output/server/chunks/build/client.precomputed.mjs +1 -1
  29. package/.output/server/chunks/build/{error-404-8tbBXju4.mjs → error-404-BN-7rNE4.mjs} +4 -4
  30. package/.output/server/chunks/build/error-404-BN-7rNE4.mjs.map +1 -0
  31. package/.output/server/chunks/build/error-404-styles.Byx46oLR.mjs +8 -0
  32. package/.output/server/chunks/build/error-404-styles.Byx46oLR.mjs.map +1 -0
  33. package/.output/server/chunks/build/{error-500-DxFsom1i.mjs → error-500-DhIQ-2yt.mjs} +4 -4
  34. package/.output/server/chunks/build/error-500-DhIQ-2yt.mjs.map +1 -0
  35. package/.output/server/chunks/build/error-500-styles.BL3UT0Wa.mjs +8 -0
  36. package/.output/server/chunks/build/error-500-styles.BL3UT0Wa.mjs.map +1 -0
  37. package/.output/server/chunks/build/{index-BB-Clavm.mjs → index-Dnrh1ePF.mjs} +1 -1
  38. package/.output/server/chunks/build/index-Dnrh1ePF.mjs.map +1 -0
  39. package/.output/server/chunks/build/server.mjs +9 -9
  40. package/.output/server/chunks/build/styles.mjs +4 -4
  41. package/.output/server/chunks/nitro/nitro.mjs +342 -342
  42. package/.output/server/chunks/nitro/nitro.mjs.map +1 -1
  43. package/.output/server/chunks/routes/renderer.mjs.map +1 -1
  44. package/.output/server/node_modules/bson/lib/bson.cjs +157 -48
  45. package/.output/server/node_modules/bson/package.json +9 -11
  46. package/.output/server/node_modules/kareem/index.js +228 -343
  47. package/.output/server/node_modules/kareem/package.json +3 -3
  48. package/.output/server/node_modules/mongodb/lib/bson.js +27 -5
  49. package/.output/server/node_modules/mongodb/lib/bulk/common.js +7 -9
  50. package/.output/server/node_modules/mongodb/lib/change_stream.js +91 -39
  51. package/.output/server/node_modules/mongodb/lib/client-side-encryption/auto_encrypter.js +21 -14
  52. package/.output/server/node_modules/mongodb/lib/client-side-encryption/client_encryption.js +2 -5
  53. package/.output/server/node_modules/mongodb/lib/client-side-encryption/errors.js +3 -1
  54. package/.output/server/node_modules/mongodb/lib/client-side-encryption/mongocryptd_manager.js +1 -1
  55. package/.output/server/node_modules/mongodb/lib/client-side-encryption/state_machine.js +1 -0
  56. package/.output/server/node_modules/mongodb/lib/cmap/auth/aws4.js +161 -0
  57. package/.output/server/node_modules/mongodb/lib/cmap/auth/aws_temporary_credentials.js +11 -58
  58. package/.output/server/node_modules/mongodb/lib/cmap/auth/gssapi.js +4 -6
  59. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongo_credentials.js +2 -16
  60. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongodb_aws.js +14 -23
  61. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongodb_oidc/azure_machine_workflow.js +3 -3
  62. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongodb_oidc/gcp_machine_workflow.js +3 -3
  63. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongodb_oidc/k8s_machine_workflow.js +4 -3
  64. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongodb_oidc/token_machine_workflow.js +4 -3
  65. package/.output/server/node_modules/mongodb/lib/cmap/auth/mongodb_oidc.js +4 -4
  66. package/.output/server/node_modules/mongodb/lib/cmap/auth/plain.js +1 -1
  67. package/.output/server/node_modules/mongodb/lib/cmap/auth/providers.js +0 -1
  68. package/.output/server/node_modules/mongodb/lib/cmap/auth/scram.js +53 -40
  69. package/.output/server/node_modules/mongodb/lib/cmap/commands.js +46 -39
  70. package/.output/server/node_modules/mongodb/lib/cmap/connect.js +35 -3
  71. package/.output/server/node_modules/mongodb/lib/cmap/connection.js +36 -32
  72. package/.output/server/node_modules/mongodb/lib/cmap/connection_pool.js +67 -67
  73. package/.output/server/node_modules/mongodb/lib/cmap/connection_pool_events.js +3 -3
  74. package/.output/server/node_modules/mongodb/lib/cmap/errors.js +1 -1
  75. package/.output/server/node_modules/mongodb/lib/cmap/handshake/client_metadata.js +15 -13
  76. package/.output/server/node_modules/mongodb/lib/cmap/metrics.js +3 -3
  77. package/.output/server/node_modules/mongodb/lib/cmap/wire_protocol/compression.js +26 -10
  78. package/.output/server/node_modules/mongodb/lib/cmap/wire_protocol/constants.js +3 -1
  79. package/.output/server/node_modules/mongodb/lib/cmap/wire_protocol/on_data.js +0 -1
  80. package/.output/server/node_modules/mongodb/lib/cmap/wire_protocol/on_demand/document.js +9 -9
  81. package/.output/server/node_modules/mongodb/lib/cmap/wire_protocol/responses.js +2 -2
  82. package/.output/server/node_modules/mongodb/lib/collection.js +1 -1
  83. package/.output/server/node_modules/mongodb/lib/connection_string.js +30 -15
  84. package/.output/server/node_modules/mongodb/lib/cursor/abstract_cursor.js +17 -34
  85. package/.output/server/node_modules/mongodb/lib/cursor/change_stream_cursor.js +2 -2
  86. package/.output/server/node_modules/mongodb/lib/cursor/find_cursor.js +37 -26
  87. package/.output/server/node_modules/mongodb/lib/cursor/run_command_cursor.js +1 -1
  88. package/.output/server/node_modules/mongodb/lib/db.js +6 -7
  89. package/.output/server/node_modules/mongodb/lib/deps.js +0 -13
  90. package/.output/server/node_modules/mongodb/lib/error.js +7 -10
  91. package/.output/server/node_modules/mongodb/lib/gridfs/download.js +7 -6
  92. package/.output/server/node_modules/mongodb/lib/gridfs/index.js +9 -9
  93. package/.output/server/node_modules/mongodb/lib/gridfs/upload.js +17 -23
  94. package/.output/server/node_modules/mongodb/lib/index.js +2 -4
  95. package/.output/server/node_modules/mongodb/lib/mongo_client.js +58 -67
  96. package/.output/server/node_modules/mongodb/lib/mongo_client_auth_providers.js +0 -6
  97. package/.output/server/node_modules/mongodb/lib/mongo_logger.js +11 -5
  98. package/.output/server/node_modules/mongodb/lib/mongo_types.js +1 -2
  99. package/.output/server/node_modules/mongodb/lib/operations/aggregate.js +0 -3
  100. package/.output/server/node_modules/mongodb/lib/operations/create_collection.js +0 -1
  101. package/.output/server/node_modules/mongodb/lib/operations/drop.js +8 -9
  102. package/.output/server/node_modules/mongodb/lib/operations/end_sessions.js +34 -0
  103. package/.output/server/node_modules/mongodb/lib/operations/execute_operation.js +121 -45
  104. package/.output/server/node_modules/mongodb/lib/operations/operation.js +1 -0
  105. package/.output/server/node_modules/mongodb/lib/read_preference.js +10 -14
  106. package/.output/server/node_modules/mongodb/lib/runtime_adapters.js +32 -0
  107. package/.output/server/node_modules/mongodb/lib/sdam/monitor.js +8 -8
  108. package/.output/server/node_modules/mongodb/lib/sdam/server.js +55 -43
  109. package/.output/server/node_modules/mongodb/lib/sdam/server_description.js +1 -1
  110. package/.output/server/node_modules/mongodb/lib/sdam/server_selection.js +135 -72
  111. package/.output/server/node_modules/mongodb/lib/sdam/srv_polling.js +3 -3
  112. package/.output/server/node_modules/mongodb/lib/sdam/topology.js +37 -77
  113. package/.output/server/node_modules/mongodb/lib/sdam/topology_description.js +1 -1
  114. package/.output/server/node_modules/mongodb/lib/sessions.js +150 -40
  115. package/.output/server/node_modules/mongodb/lib/transactions.js +2 -13
  116. package/.output/server/node_modules/mongodb/lib/utils.js +42 -90
  117. package/.output/server/node_modules/mongodb/package.json +49 -45
  118. package/.output/server/node_modules/mongodb-connection-string-url/lib/index.js +45 -19
  119. package/.output/server/node_modules/mongodb-connection-string-url/lib/redact.js +30 -19
  120. package/.output/server/node_modules/mongodb-connection-string-url/package.json +25 -16
  121. package/.output/server/node_modules/mongoose/lib/aggregate.js +108 -127
  122. package/.output/server/node_modules/mongoose/lib/cast/bigint.js +3 -3
  123. package/.output/server/node_modules/mongoose/lib/cast/boolean.js +3 -3
  124. package/.output/server/node_modules/mongoose/lib/cast/double.js +4 -4
  125. package/.output/server/node_modules/mongoose/lib/cast/int32.js +2 -2
  126. package/.output/server/node_modules/mongoose/lib/cast/number.js +6 -6
  127. package/.output/server/node_modules/mongoose/lib/cast/string.js +3 -3
  128. package/.output/server/node_modules/mongoose/lib/cast/uuid.js +5 -48
  129. package/.output/server/node_modules/mongoose/lib/cast.js +16 -24
  130. package/.output/server/node_modules/mongoose/lib/collection.js +6 -6
  131. package/.output/server/node_modules/mongoose/lib/connection.js +108 -105
  132. package/.output/server/node_modules/mongoose/lib/cursor/aggregationCursor.js +23 -33
  133. package/.output/server/node_modules/mongoose/lib/cursor/changeStream.js +60 -40
  134. package/.output/server/node_modules/mongoose/lib/cursor/queryCursor.js +21 -25
  135. package/.output/server/node_modules/mongoose/lib/document.js +712 -531
  136. package/.output/server/node_modules/mongoose/lib/drivers/node-mongodb-native/collection.js +85 -130
  137. package/.output/server/node_modules/mongoose/lib/drivers/node-mongodb-native/connection.js +32 -41
  138. package/.output/server/node_modules/mongoose/lib/error/cast.js +21 -12
  139. package/.output/server/node_modules/mongoose/lib/error/createCollectionsError.js +2 -2
  140. package/.output/server/node_modules/mongoose/lib/error/divergentArray.js +1 -1
  141. package/.output/server/node_modules/mongoose/lib/error/eachAsyncMultiError.js +1 -1
  142. package/.output/server/node_modules/mongoose/lib/error/index.js +3 -3
  143. package/.output/server/node_modules/mongoose/lib/error/invalidSchemaOption.js +1 -1
  144. package/.output/server/node_modules/mongoose/lib/error/messages.js +1 -0
  145. package/.output/server/node_modules/mongoose/lib/error/missingSchema.js +1 -1
  146. package/.output/server/node_modules/mongoose/lib/error/objectParameter.js +4 -5
  147. package/.output/server/node_modules/mongoose/lib/error/overwriteModel.js +1 -1
  148. package/.output/server/node_modules/mongoose/lib/error/setOptionError.js +3 -3
  149. package/.output/server/node_modules/mongoose/lib/error/strict.js +3 -3
  150. package/.output/server/node_modules/mongoose/lib/error/strictPopulate.js +2 -2
  151. package/.output/server/node_modules/mongoose/lib/error/syncIndexes.js +2 -2
  152. package/.output/server/node_modules/mongoose/lib/error/validation.js +2 -10
  153. package/.output/server/node_modules/mongoose/lib/error/validator.js +1 -1
  154. package/.output/server/node_modules/mongoose/lib/error/version.js +2 -2
  155. package/.output/server/node_modules/mongoose/lib/helpers/aggregate/prepareDiscriminatorPipeline.js +4 -4
  156. package/.output/server/node_modules/mongoose/lib/helpers/buildMiddlewareFilter.js +24 -0
  157. package/.output/server/node_modules/mongoose/lib/helpers/clone.js +35 -18
  158. package/.output/server/node_modules/mongoose/lib/helpers/common.js +5 -5
  159. package/.output/server/node_modules/mongoose/lib/helpers/cursor/eachAsync.js +4 -4
  160. package/.output/server/node_modules/mongoose/lib/helpers/discriminator/getConstructor.js +1 -1
  161. package/.output/server/node_modules/mongoose/lib/helpers/discriminator/getDiscriminatorByValue.js +1 -1
  162. package/.output/server/node_modules/mongoose/lib/helpers/discriminator/getSchemaDiscriminatorByValue.js +1 -1
  163. package/.output/server/node_modules/mongoose/lib/helpers/discriminator/mergeDiscriminatorSchema.js +10 -5
  164. package/.output/server/node_modules/mongoose/lib/helpers/document/applyDefaults.js +1 -1
  165. package/.output/server/node_modules/mongoose/lib/helpers/document/applyTimestamps.js +11 -10
  166. package/.output/server/node_modules/mongoose/lib/helpers/document/applyVirtuals.js +10 -9
  167. package/.output/server/node_modules/mongoose/lib/helpers/document/cleanModifiedSubpaths.js +1 -1
  168. package/.output/server/node_modules/mongoose/lib/helpers/document/compile.js +17 -14
  169. package/.output/server/node_modules/mongoose/lib/helpers/document/getDeepestSubdocumentForPath.js +3 -3
  170. package/.output/server/node_modules/mongoose/lib/helpers/document/getEmbeddedDiscriminatorPath.js +2 -2
  171. package/.output/server/node_modules/mongoose/lib/helpers/document/isInPathsToSave.js +24 -0
  172. package/.output/server/node_modules/mongoose/lib/helpers/get.js +1 -1
  173. package/.output/server/node_modules/mongoose/lib/helpers/indexes/decorateDiscriminatorIndexOptions.js +1 -1
  174. package/.output/server/node_modules/mongoose/lib/helpers/indexes/getRelatedIndexes.js +3 -3
  175. package/.output/server/node_modules/mongoose/lib/helpers/indexes/isIndexEqual.js +3 -4
  176. package/.output/server/node_modules/mongoose/lib/helpers/indexes/isIndexSpecEqual.js +3 -3
  177. package/.output/server/node_modules/mongoose/lib/helpers/isBsonType.js +1 -1
  178. package/.output/server/node_modules/mongoose/lib/helpers/isMongooseObject.js +1 -1
  179. package/.output/server/node_modules/mongoose/lib/helpers/isObject.js +2 -2
  180. package/.output/server/node_modules/mongoose/lib/helpers/isSimpleValidator.js +2 -2
  181. package/.output/server/node_modules/mongoose/lib/helpers/minimize.js +2 -2
  182. package/.output/server/node_modules/mongoose/lib/helpers/model/applyDefaultsToPOJO.js +2 -2
  183. package/.output/server/node_modules/mongoose/lib/helpers/model/applyHooks.js +55 -54
  184. package/.output/server/node_modules/mongoose/lib/helpers/model/applyMethods.js +2 -2
  185. package/.output/server/node_modules/mongoose/lib/helpers/model/applyStaticHooks.js +1 -48
  186. package/.output/server/node_modules/mongoose/lib/helpers/model/castBulkWrite.js +8 -12
  187. package/.output/server/node_modules/mongoose/lib/helpers/model/discriminator.js +1 -1
  188. package/.output/server/node_modules/mongoose/lib/helpers/parallelLimit.js +18 -36
  189. package/.output/server/node_modules/mongoose/lib/helpers/pluralize.js +4 -4
  190. package/.output/server/node_modules/mongoose/lib/helpers/populate/assignRawDocsToIdStructure.js +4 -11
  191. package/.output/server/node_modules/mongoose/lib/helpers/populate/assignVals.js +10 -10
  192. package/.output/server/node_modules/mongoose/lib/helpers/populate/createPopulateQueryFilter.js +3 -3
  193. package/.output/server/node_modules/mongoose/lib/helpers/populate/getModelsMapForPopulate.js +197 -69
  194. package/.output/server/node_modules/mongoose/lib/helpers/populate/getSchemaTypes.js +15 -15
  195. package/.output/server/node_modules/mongoose/lib/helpers/populate/markArraySubdocsPopulated.js +1 -1
  196. package/.output/server/node_modules/mongoose/lib/helpers/populate/modelNamesFromRefPath.js +10 -2
  197. package/.output/server/node_modules/mongoose/lib/helpers/populate/setPopulatedVirtualValue.js +5 -5
  198. package/.output/server/node_modules/mongoose/lib/helpers/printJestWarning.js +1 -1
  199. package/.output/server/node_modules/mongoose/lib/helpers/processConnectionOptions.js +1 -1
  200. package/.output/server/node_modules/mongoose/lib/helpers/projection/hasIncludedChildren.js +1 -1
  201. package/.output/server/node_modules/mongoose/lib/helpers/projection/isPathExcluded.js +3 -3
  202. package/.output/server/node_modules/mongoose/lib/helpers/projection/isSubpath.js +1 -1
  203. package/.output/server/node_modules/mongoose/lib/helpers/projection/parseProjection.js +9 -4
  204. package/.output/server/node_modules/mongoose/lib/helpers/query/cast$expr.js +8 -10
  205. package/.output/server/node_modules/mongoose/lib/helpers/query/castFilterPath.js +1 -1
  206. package/.output/server/node_modules/mongoose/lib/helpers/query/castUpdate.js +44 -38
  207. package/.output/server/node_modules/mongoose/lib/helpers/query/getEmbeddedDiscriminatorPath.js +8 -8
  208. package/.output/server/node_modules/mongoose/lib/helpers/query/handleImmutable.js +8 -8
  209. package/.output/server/node_modules/mongoose/lib/helpers/schema/applyPlugins.js +2 -2
  210. package/.output/server/node_modules/mongoose/lib/helpers/schema/applyReadConcern.js +1 -1
  211. package/.output/server/node_modules/mongoose/lib/helpers/schema/applyWriteConcern.js +4 -2
  212. package/.output/server/node_modules/mongoose/lib/helpers/schema/getIndexes.js +5 -11
  213. package/.output/server/node_modules/mongoose/lib/helpers/schema/getSubdocumentStrictValue.js +2 -2
  214. package/.output/server/node_modules/mongoose/lib/helpers/schema/handleIdOption.js +1 -1
  215. package/.output/server/node_modules/mongoose/lib/helpers/schema/idGetter.js +1 -1
  216. package/.output/server/node_modules/mongoose/lib/helpers/schematype/handleImmutable.js +1 -1
  217. package/.output/server/node_modules/mongoose/lib/helpers/setDefaultsOnInsert.js +26 -13
  218. package/.output/server/node_modules/mongoose/lib/helpers/timestamps/setDocumentTimestamps.js +2 -2
  219. package/.output/server/node_modules/mongoose/lib/helpers/timestamps/setupTimestamps.js +60 -38
  220. package/.output/server/node_modules/mongoose/lib/helpers/update/applyTimestampsToUpdate.js +13 -10
  221. package/.output/server/node_modules/mongoose/lib/helpers/update/castArrayFilters.js +4 -4
  222. package/.output/server/node_modules/mongoose/lib/helpers/update/decorateUpdateWithVersionKey.js +1 -1
  223. package/.output/server/node_modules/mongoose/lib/helpers/update/modifiedPaths.js +2 -2
  224. package/.output/server/node_modules/mongoose/lib/helpers/update/removeUnusedArrayFilters.js +7 -2
  225. package/.output/server/node_modules/mongoose/lib/helpers/updateValidators.js +58 -119
  226. package/.output/server/node_modules/mongoose/lib/model.js +940 -946
  227. package/.output/server/node_modules/mongoose/lib/mongoose.js +131 -79
  228. package/.output/server/node_modules/mongoose/lib/options/schemaArrayOptions.js +2 -2
  229. package/.output/server/node_modules/mongoose/lib/options/schemaBufferOptions.js +1 -1
  230. package/.output/server/node_modules/mongoose/lib/options/schemaDocumentArrayOptions.js +23 -0
  231. package/.output/server/node_modules/mongoose/lib/options/schemaNumberOptions.js +3 -3
  232. package/.output/server/node_modules/mongoose/lib/options/schemaObjectIdOptions.js +2 -2
  233. package/.output/server/node_modules/mongoose/lib/options/schemaStringOptions.js +6 -6
  234. package/.output/server/node_modules/mongoose/lib/options/schemaSubdocumentOptions.js +23 -0
  235. package/.output/server/node_modules/mongoose/lib/options/schemaTypeOptions.js +27 -13
  236. package/.output/server/node_modules/mongoose/lib/options/virtualOptions.js +12 -12
  237. package/.output/server/node_modules/mongoose/lib/plugins/index.js +0 -1
  238. package/.output/server/node_modules/mongoose/lib/plugins/saveSubdocs.js +84 -92
  239. package/.output/server/node_modules/mongoose/lib/plugins/sharding.js +33 -15
  240. package/.output/server/node_modules/mongoose/lib/plugins/trackTransaction.js +29 -25
  241. package/.output/server/node_modules/mongoose/lib/query.js +700 -548
  242. package/.output/server/node_modules/mongoose/lib/queryHelpers.js +34 -32
  243. package/.output/server/node_modules/mongoose/lib/schema/array.js +69 -113
  244. package/.output/server/node_modules/mongoose/lib/schema/bigint.js +18 -20
  245. package/.output/server/node_modules/mongoose/lib/schema/boolean.js +20 -22
  246. package/.output/server/node_modules/mongoose/lib/schema/buffer.js +23 -25
  247. package/.output/server/node_modules/mongoose/lib/schema/date.js +19 -21
  248. package/.output/server/node_modules/mongoose/lib/schema/decimal128.js +16 -18
  249. package/.output/server/node_modules/mongoose/lib/schema/documentArray.js +94 -131
  250. package/.output/server/node_modules/mongoose/lib/schema/documentArrayElement.js +50 -16
  251. package/.output/server/node_modules/mongoose/lib/schema/double.js +16 -18
  252. package/.output/server/node_modules/mongoose/lib/schema/index.js +1 -0
  253. package/.output/server/node_modules/mongoose/lib/schema/int32.js +17 -19
  254. package/.output/server/node_modules/mongoose/lib/schema/map.js +17 -24
  255. package/.output/server/node_modules/mongoose/lib/schema/mixed.js +14 -14
  256. package/.output/server/node_modules/mongoose/lib/schema/number.js +38 -28
  257. package/.output/server/node_modules/mongoose/lib/schema/objectId.js +18 -20
  258. package/.output/server/node_modules/mongoose/lib/schema/operators/exists.js +1 -1
  259. package/.output/server/node_modules/mongoose/lib/schema/operators/geospatial.js +1 -1
  260. package/.output/server/node_modules/mongoose/lib/schema/operators/text.js +4 -4
  261. package/.output/server/node_modules/mongoose/lib/schema/string.js +42 -27
  262. package/.output/server/node_modules/mongoose/lib/schema/subdocument.js +47 -58
  263. package/.output/server/node_modules/mongoose/lib/schema/union.js +54 -4
  264. package/.output/server/node_modules/mongoose/lib/schema/uuid.js +17 -40
  265. package/.output/server/node_modules/mongoose/lib/schema.js +235 -176
  266. package/.output/server/node_modules/mongoose/lib/schemaType.js +227 -158
  267. package/.output/server/node_modules/mongoose/lib/stateMachine.js +5 -8
  268. package/.output/server/node_modules/mongoose/lib/types/array/index.js +5 -5
  269. package/.output/server/node_modules/mongoose/lib/types/array/methods/index.js +27 -28
  270. package/.output/server/node_modules/mongoose/lib/types/arraySubdocument.js +11 -11
  271. package/.output/server/node_modules/mongoose/lib/types/buffer.js +15 -15
  272. package/.output/server/node_modules/mongoose/lib/types/decimal128.js +1 -1
  273. package/.output/server/node_modules/mongoose/lib/types/documentArray/index.js +4 -4
  274. package/.output/server/node_modules/mongoose/lib/types/documentArray/methods/index.js +15 -13
  275. package/.output/server/node_modules/mongoose/lib/types/double.js +1 -1
  276. package/.output/server/node_modules/mongoose/lib/types/map.js +20 -71
  277. package/.output/server/node_modules/mongoose/lib/types/objectid.js +1 -1
  278. package/.output/server/node_modules/mongoose/lib/types/subdocument.js +32 -81
  279. package/.output/server/node_modules/mongoose/lib/types/uuid.js +1 -1
  280. package/.output/server/node_modules/mongoose/lib/utils.js +91 -70
  281. package/.output/server/node_modules/mongoose/lib/validOptions.js +4 -3
  282. package/.output/server/node_modules/mongoose/lib/virtualType.js +18 -18
  283. package/.output/server/node_modules/mongoose/package.json +46 -63
  284. package/.output/server/node_modules/mquery/lib/collection/collection.js +3 -1
  285. package/.output/server/node_modules/mquery/lib/collection/node.js +17 -3
  286. package/.output/server/node_modules/mquery/lib/mquery.js +136 -93
  287. package/.output/server/node_modules/mquery/lib/permissions.js +21 -6
  288. package/.output/server/node_modules/mquery/package.json +4 -7
  289. package/.output/server/package.json +7 -9
  290. package/package.json +3 -3
  291. package/.output/public/_nuxt/builds/meta/b59771ef-8e58-4078-9d18-ccc01cba96e9.json +0 -1
  292. package/.output/public/_nuxt/error-404.CTWLHxjC.css +0 -1
  293. package/.output/public/_nuxt/error-500.UBfk8-QP.css +0 -1
  294. package/.output/server/chunks/build/error-404-8tbBXju4.mjs.map +0 -1
  295. package/.output/server/chunks/build/error-404-styles.BeWfK6Py.mjs +0 -8
  296. package/.output/server/chunks/build/error-404-styles.BeWfK6Py.mjs.map +0 -1
  297. package/.output/server/chunks/build/error-500-DxFsom1i.mjs.map +0 -1
  298. package/.output/server/chunks/build/error-500-styles.CPUUvoY-.mjs +0 -8
  299. package/.output/server/chunks/build/error-500-styles.CPUUvoY-.mjs.map +0 -1
  300. package/.output/server/chunks/build/index-BB-Clavm.mjs.map +0 -1
  301. package/.output/server/node_modules/debug/package.json +0 -64
  302. package/.output/server/node_modules/debug/src/browser.js +0 -272
  303. package/.output/server/node_modules/debug/src/common.js +0 -292
  304. package/.output/server/node_modules/debug/src/index.js +0 -10
  305. package/.output/server/node_modules/debug/src/node.js +0 -263
  306. package/.output/server/node_modules/mongodb/lib/client-side-encryption/crypto_callbacks.js +0 -81
  307. package/.output/server/node_modules/mongodb/lib/resource_management.js +0 -58
  308. package/.output/server/node_modules/mongoose/lib/browserDocument.js +0 -101
  309. package/.output/server/node_modules/mongoose/lib/documentProvider.js +0 -30
  310. package/.output/server/node_modules/mongoose/lib/helpers/createJSONSchemaTypeDefinition.js +0 -24
  311. package/.output/server/node_modules/mongoose/lib/helpers/promiseOrCallback.js +0 -54
  312. package/.output/server/node_modules/mongoose/lib/plugins/validateBeforeSave.js +0 -51
  313. package/.output/server/node_modules/supports-color/index.js +0 -202
  314. package/.output/server/node_modules/supports-color/package.json +0 -64
@@ -20,6 +20,7 @@ const castArrayFilters = require('./helpers/update/castArrayFilters');
20
20
  const castNumber = require('./cast/number');
21
21
  const castUpdate = require('./helpers/query/castUpdate');
22
22
  const clone = require('./helpers/clone');
23
+ const decorateUpdateWithVersionKey = require('./helpers/update/decorateUpdateWithVersionKey');
23
24
  const getDiscriminatorByValue = require('./helpers/discriminator/getDiscriminatorByValue');
24
25
  const helpers = require('./queryHelpers');
25
26
  const internalToObjectOptions = require('./options').internalToObjectOptions;
@@ -33,6 +34,7 @@ const parseProjection = require('./helpers/projection/parseProjection');
33
34
  const removeUnusedArrayFilters = require('./helpers/update/removeUnusedArrayFilters');
34
35
  const sanitizeFilter = require('./helpers/query/sanitizeFilter');
35
36
  const sanitizeProjection = require('./helpers/query/sanitizeProjection');
37
+ const { buildMiddlewareFilter } = require('./helpers/buildMiddlewareFilter');
36
38
  const selectPopulatedFields = require('./helpers/query/selectPopulatedFields');
37
39
  const setDefaultsOnInsert = require('./helpers/setDefaultsOnInsert');
38
40
  const specialProperties = require('./helpers/specialProperties');
@@ -84,6 +86,8 @@ const opToThunk = new Map([
84
86
  ['findOneAndDelete', '_findOneAndDelete']
85
87
  ]);
86
88
 
89
+ const queryUpdateSymbol = Symbol('mongoose#Query#update');
90
+
87
91
  /**
88
92
  * Query constructor used for building queries. You do not need
89
93
  * to instantiate a `Query` directly. Instead use Model functions like
@@ -100,10 +104,10 @@ const opToThunk = new Map([
100
104
  * // this unless you're an advanced user with a very good reason to.
101
105
  * const query = new mongoose.Query();
102
106
  *
103
- * @param {Object} [options]
104
- * @param {Object} [model]
105
- * @param {Object} [conditions]
106
- * @param {Object} [collection] Mongoose collection
107
+ * @param {object} [options]
108
+ * @param {object} [model]
109
+ * @param {object} [conditions]
110
+ * @param {object} [collection] Mongoose collection
107
111
  * @api public
108
112
  */
109
113
 
@@ -116,7 +120,7 @@ function Query(conditions, options, model, collection) {
116
120
 
117
121
  this._transforms = [];
118
122
  this._hooks = new Kareem();
119
- this._executionStack = null;
123
+ this._execCount = 0;
120
124
 
121
125
  // this is the case where we have a CustomQuery, we need to check if we got
122
126
  // options passed in, and if we did, merge them in
@@ -136,7 +140,7 @@ function Query(conditions, options, model, collection) {
136
140
 
137
141
  // this is needed because map reduce returns a model that can be queried, but
138
142
  // all of the queries on said model should be lean
139
- if (this.model && this.model._mapreduce) {
143
+ if (this.model?._mapreduce) {
140
144
  this.lean();
141
145
  }
142
146
 
@@ -156,10 +160,7 @@ function Query(conditions, options, model, collection) {
156
160
  // versions of MongoDB
157
161
  this.$useProjection = true;
158
162
 
159
- const collation = this &&
160
- this.schema &&
161
- this.schema.options &&
162
- this.schema.options.collation || null;
163
+ const collation = this?.schema?.options?.collation || null;
163
164
  if (collation != null) {
164
165
  this.options.collation = collation;
165
166
  }
@@ -169,7 +170,7 @@ function Query(conditions, options, model, collection) {
169
170
  function isEmptyFilter(obj) {
170
171
  if (obj == null) return true;
171
172
  if (typeof obj !== 'object') return true;
172
- if (Object.keys(obj).length === 0) return true;
173
+ if (utils.hasOwnKeys(obj) === false) return true;
173
174
 
174
175
  // Check $and, $or, $nor arrays
175
176
  for (const key of ['$and', '$or', '$nor']) {
@@ -186,8 +187,8 @@ function isEmptyFilter(obj) {
186
187
 
187
188
  // Helper function to check for empty/invalid filter
188
189
  function checkRequireFilter(filter, options) {
189
- if (options && options.requireFilter && isEmptyFilter(filter)) {
190
- throw new Error('Empty or invalid filter not allowed with requireFilter enabled');
190
+ if (options?.requireFilter && isEmptyFilter(filter)) {
191
+ throw new MongooseError('Empty or invalid filter not allowed with requireFilter enabled');
191
192
  }
192
193
  }
193
194
 
@@ -198,6 +199,18 @@ function checkRequireFilter(filter, options) {
198
199
  Query.prototype = new mquery();
199
200
  Query.prototype.constructor = Query;
200
201
 
202
+ Object.defineProperty(Query.prototype, '_update', {
203
+ configurable: true,
204
+ enumerable: true,
205
+ get: function() {
206
+ _cloneUpdateIfShared(this);
207
+ return this[queryUpdateSymbol];
208
+ },
209
+ set: function(v) {
210
+ this[queryUpdateSymbol] = v;
211
+ }
212
+ });
213
+
201
214
  // Remove some legacy methods that we removed in Mongoose 8, but
202
215
  // are still in mquery 5.
203
216
  Query.prototype.count = undefined;
@@ -300,10 +313,9 @@ Query.prototype.toConstructor = function toConstructor() {
300
313
  p.setOptions(options);
301
314
 
302
315
  p.op = this.op;
303
- p._validateOp();
304
316
  p._conditions = clone(this._conditions);
305
317
  p._fields = clone(this._fields);
306
- p._update = clone(this._update, {
318
+ p[queryUpdateSymbol] = clone(this[queryUpdateSymbol], {
307
319
  flattenDecimals: false
308
320
  });
309
321
  p._path = this._path;
@@ -349,10 +361,9 @@ Query.prototype.clone = function() {
349
361
  q.setOptions(options);
350
362
 
351
363
  q.op = this.op;
352
- q._validateOp();
353
364
  q._conditions = clone(this._conditions);
354
365
  q._fields = clone(this._fields);
355
- q._update = clone(this._update, {
366
+ q[queryUpdateSymbol] = clone(this[queryUpdateSymbol], {
356
367
  flattenDecimals: false
357
368
  });
358
369
  q._path = this._path;
@@ -383,7 +394,7 @@ Query.prototype.clone = function() {
383
394
  *
384
395
  * @see $where https://www.mongodb.com/docs/manual/reference/operator/where/
385
396
  * @method $where
386
- * @param {String|Function} js javascript string or function
397
+ * @param {string|Function} js javascript string or function
387
398
  * @return {Query} this
388
399
  * @memberOf Query
389
400
  * @instance
@@ -415,7 +426,7 @@ Query.prototype.clone = function() {
415
426
  * @method where
416
427
  * @memberOf Query
417
428
  * @instance
418
- * @param {String|Object} [path]
429
+ * @param {string|object} [path]
419
430
  * @param {any} [val]
420
431
  * @return {Query} this
421
432
  * @api public
@@ -451,16 +462,16 @@ Query.prototype.clone = function() {
451
462
  * @method slice
452
463
  * @memberOf Query
453
464
  * @instance
454
- * @param {String} [path]
455
- * @param {Number|Array} val number of elements to slice or array with number of elements to skip and number of elements to slice
465
+ * @param {string} [path]
466
+ * @param {number|Array} val number of elements to slice or array with number of elements to skip and number of elements to slice
456
467
  * @return {Query} this
457
468
  * @see mongodb https://www.mongodb.com/docs/manual/tutorial/query-documents/#projection
458
469
  * @see $slice https://www.mongodb.com/docs/manual/reference/projection/slice/#prj._S_slice
459
470
  * @api public
460
471
  */
461
472
 
462
- Query.prototype.slice = function() {
463
- if (arguments.length === 0) {
473
+ Query.prototype.slice = function(...args) {
474
+ if (args.length === 0) {
464
475
  return this;
465
476
  }
466
477
 
@@ -469,8 +480,8 @@ Query.prototype.slice = function() {
469
480
  let path;
470
481
  let val;
471
482
 
472
- if (arguments.length === 1) {
473
- const arg = arguments[0];
483
+ if (args.length === 1) {
484
+ const arg = args[0];
474
485
  if (typeof arg === 'object' && !Array.isArray(arg)) {
475
486
  const keys = Object.keys(arg);
476
487
  const numKeys = keys.length;
@@ -481,19 +492,19 @@ Query.prototype.slice = function() {
481
492
  }
482
493
  this._ensurePath('slice');
483
494
  path = this._path;
484
- val = arguments[0];
485
- } else if (arguments.length === 2) {
486
- if ('number' === typeof arguments[0]) {
495
+ val = args[0];
496
+ } else if (args.length === 2) {
497
+ if ('number' === typeof args[0]) {
487
498
  this._ensurePath('slice');
488
499
  path = this._path;
489
- val = [arguments[0], arguments[1]];
500
+ val = [args[0], args[1]];
490
501
  } else {
491
- path = arguments[0];
492
- val = arguments[1];
502
+ path = args[0];
503
+ val = args[1];
493
504
  }
494
- } else if (arguments.length === 3) {
495
- path = arguments[0];
496
- val = [arguments[1], arguments[2]];
505
+ } else if (args.length === 3) {
506
+ path = args[0];
507
+ val = [args[1], args[2]];
497
508
  }
498
509
 
499
510
  const p = {};
@@ -513,6 +524,10 @@ Query.prototype._validateOp = function() {
513
524
  if (this.op != null && !validOpsSet.has(this.op)) {
514
525
  this.error(new Error('Query has invalid `op`: "' + this.op + '"'));
515
526
  }
527
+
528
+ if (this.op !== 'estimatedDocumentCount' && this._conditions == null) {
529
+ throw new ObjectParameterError(this._conditions, 'filter', this.op);
530
+ }
516
531
  };
517
532
 
518
533
  /**
@@ -529,7 +544,7 @@ Query.prototype._validateOp = function() {
529
544
  * @method equals
530
545
  * @memberOf Query
531
546
  * @instance
532
- * @param {Object} val
547
+ * @param {object} val
533
548
  * @return {Query} this
534
549
  * @api public
535
550
  */
@@ -597,8 +612,8 @@ Query.prototype._validateOp = function() {
597
612
  * @method gt
598
613
  * @memberOf Query
599
614
  * @instance
600
- * @param {String} [path]
601
- * @param {Number} val
615
+ * @param {string} [path]
616
+ * @param {number} val
602
617
  * @see $gt https://www.mongodb.com/docs/manual/reference/operator/gt/
603
618
  * @api public
604
619
  */
@@ -611,8 +626,8 @@ Query.prototype._validateOp = function() {
611
626
  * @method gte
612
627
  * @memberOf Query
613
628
  * @instance
614
- * @param {String} [path]
615
- * @param {Number} val
629
+ * @param {string} [path]
630
+ * @param {number} val
616
631
  * @see $gte https://www.mongodb.com/docs/manual/reference/operator/gte/
617
632
  * @api public
618
633
  */
@@ -625,8 +640,8 @@ Query.prototype._validateOp = function() {
625
640
  * @method lt
626
641
  * @memberOf Query
627
642
  * @instance
628
- * @param {String} [path]
629
- * @param {Number} val
643
+ * @param {string} [path]
644
+ * @param {number} val
630
645
  * @see $lt https://www.mongodb.com/docs/manual/reference/operator/lt/
631
646
  * @api public
632
647
  */
@@ -640,8 +655,8 @@ Query.prototype._validateOp = function() {
640
655
  * @see $lte https://www.mongodb.com/docs/manual/reference/operator/lte/
641
656
  * @memberOf Query
642
657
  * @instance
643
- * @param {String} [path]
644
- * @param {Number} val
658
+ * @param {string} [path]
659
+ * @param {number} val
645
660
  * @api public
646
661
  */
647
662
 
@@ -654,7 +669,7 @@ Query.prototype._validateOp = function() {
654
669
  * @method ne
655
670
  * @memberOf Query
656
671
  * @instance
657
- * @param {String} [path]
672
+ * @param {string} [path]
658
673
  * @param {any} val
659
674
  * @api public
660
675
  */
@@ -668,7 +683,7 @@ Query.prototype._validateOp = function() {
668
683
  * @method in
669
684
  * @memberOf Query
670
685
  * @instance
671
- * @param {String} [path]
686
+ * @param {string} [path]
672
687
  * @param {Array} val
673
688
  * @api public
674
689
  */
@@ -682,7 +697,7 @@ Query.prototype._validateOp = function() {
682
697
  * @method nin
683
698
  * @memberOf Query
684
699
  * @instance
685
- * @param {String} [path]
700
+ * @param {string} [path]
686
701
  * @param {Array} val
687
702
  * @api public
688
703
  */
@@ -702,7 +717,7 @@ Query.prototype._validateOp = function() {
702
717
  * @method all
703
718
  * @memberOf Query
704
719
  * @instance
705
- * @param {String} [path]
720
+ * @param {string} [path]
706
721
  * @param {Array} val
707
722
  * @api public
708
723
  */
@@ -722,8 +737,8 @@ Query.prototype._validateOp = function() {
722
737
  * @method size
723
738
  * @memberOf Query
724
739
  * @instance
725
- * @param {String} [path]
726
- * @param {Number} val
740
+ * @param {string} [path]
741
+ * @param {number} val
727
742
  * @api public
728
743
  */
729
744
 
@@ -736,8 +751,8 @@ Query.prototype._validateOp = function() {
736
751
  * @method regex
737
752
  * @memberOf Query
738
753
  * @instance
739
- * @param {String} [path]
740
- * @param {String|RegExp} val
754
+ * @param {string} [path]
755
+ * @param {string|RegExp} val
741
756
  * @api public
742
757
  */
743
758
 
@@ -750,8 +765,8 @@ Query.prototype._validateOp = function() {
750
765
  * @method maxDistance
751
766
  * @memberOf Query
752
767
  * @instance
753
- * @param {String} [path]
754
- * @param {Number} val
768
+ * @param {string} [path]
769
+ * @param {number} val
755
770
  * @api public
756
771
  */
757
772
 
@@ -770,7 +785,7 @@ Query.prototype._validateOp = function() {
770
785
  * @method mod
771
786
  * @memberOf Query
772
787
  * @instance
773
- * @param {String} [path]
788
+ * @param {string} [path]
774
789
  * @param {Array} val must be of length 2, first element is `divisor`, 2nd element is `remainder`.
775
790
  * @return {Query} this
776
791
  * @see $mod https://www.mongodb.com/docs/manual/reference/operator/mod/
@@ -819,8 +834,8 @@ Query.prototype.mod = function() {
819
834
  * @method exists
820
835
  * @memberOf Query
821
836
  * @instance
822
- * @param {String} [path]
823
- * @param {Boolean} val
837
+ * @param {string} [path]
838
+ * @param {boolean} val
824
839
  * @return {Query} this
825
840
  * @see $exists https://www.mongodb.com/docs/manual/reference/operator/exists/
826
841
  * @api public
@@ -848,8 +863,8 @@ Query.prototype.mod = function() {
848
863
  * @method elemMatch
849
864
  * @memberOf Query
850
865
  * @instance
851
- * @param {String|Object|Function} path
852
- * @param {Object|Function} filter
866
+ * @param {string|object|Function} path
867
+ * @param {object|Function} filter
853
868
  * @return {Query} this
854
869
  * @see $elemMatch https://www.mongodb.com/docs/manual/reference/operator/elemMatch/
855
870
  * @api public
@@ -908,7 +923,7 @@ Query.prototype.mod = function() {
908
923
  * @method limit
909
924
  * @memberOf Query
910
925
  * @instance
911
- * @param {Number} val
926
+ * @param {number} val
912
927
  * @api public
913
928
  */
914
929
 
@@ -918,7 +933,7 @@ Query.prototype.limit = function limit(v) {
918
933
  if (typeof v === 'string') {
919
934
  try {
920
935
  v = castNumber(v);
921
- } catch (err) {
936
+ } catch {
922
937
  throw new CastError('Number', v, 'limit');
923
938
  }
924
939
  }
@@ -941,7 +956,7 @@ Query.prototype.limit = function limit(v) {
941
956
  * @method skip
942
957
  * @memberOf Query
943
958
  * @instance
944
- * @param {Number} val
959
+ * @param {number} val
945
960
  * @see cursor.skip https://www.mongodb.com/docs/manual/reference/method/cursor.skip/
946
961
  * @api public
947
962
  */
@@ -952,7 +967,7 @@ Query.prototype.skip = function skip(v) {
952
967
  if (typeof v === 'string') {
953
968
  try {
954
969
  v = castNumber(v);
955
- } catch (err) {
970
+ } catch {
956
971
  throw new CastError('Number', v, 'skip');
957
972
  }
958
973
  }
@@ -975,7 +990,7 @@ Query.prototype.skip = function skip(v) {
975
990
  * @method batchSize
976
991
  * @memberOf Query
977
992
  * @instance
978
- * @param {Number} val
993
+ * @param {number} val
979
994
  * @see batchSize https://www.mongodb.com/docs/manual/reference/method/cursor.batchSize/
980
995
  * @api public
981
996
  */
@@ -994,7 +1009,7 @@ Query.prototype.skip = function skip(v) {
994
1009
  * @method comment
995
1010
  * @memberOf Query
996
1011
  * @instance
997
- * @param {String} val
1012
+ * @param {string} val
998
1013
  * @see comment https://www.mongodb.com/docs/manual/reference/operator/comment/
999
1014
  * @api public
1000
1015
  */
@@ -1013,7 +1028,7 @@ Query.prototype.skip = function skip(v) {
1013
1028
  * @method hint
1014
1029
  * @memberOf Query
1015
1030
  * @instance
1016
- * @param {Object} val a hint object
1031
+ * @param {object} val a hint object
1017
1032
  * @return {Query} this
1018
1033
  * @see $hint https://www.mongodb.com/docs/manual/reference/operator/hint/
1019
1034
  * @api public
@@ -1044,8 +1059,8 @@ Query.prototype.skip = function skip(v) {
1044
1059
  * @method projection
1045
1060
  * @memberOf Query
1046
1061
  * @instance
1047
- * @param {Object|null} arg
1048
- * @return {Object} the current projection
1062
+ * @param {object|null} arg
1063
+ * @return {object} the current projection
1049
1064
  * @api public
1050
1065
  */
1051
1066
 
@@ -1102,7 +1117,7 @@ Query.prototype.projection = function(arg) {
1102
1117
  * @method select
1103
1118
  * @memberOf Query
1104
1119
  * @instance
1105
- * @param {Object|String|String[]} arg
1120
+ * @param {object|string|Array<string>} arg
1106
1121
  * @return {Query} this
1107
1122
  * @see SchemaType https://mongoosejs.com/docs/api/schematype.html
1108
1123
  * @api public
@@ -1113,7 +1128,7 @@ Query.prototype.select = function select() {
1113
1128
  if (!arg) return this;
1114
1129
 
1115
1130
  if (arguments.length !== 1) {
1116
- throw new Error('Invalid select: select only takes 1 argument');
1131
+ throw new MongooseError('Invalid select: select only takes 1 argument');
1117
1132
  }
1118
1133
 
1119
1134
  this._validate('select');
@@ -1206,7 +1221,7 @@ Query.prototype.select = function select() {
1206
1221
  * @method schemaLevelProjections
1207
1222
  * @memberOf Query
1208
1223
  * @instance
1209
- * @param {Boolean} value
1224
+ * @param {boolean} value
1210
1225
  * @return {Query} this
1211
1226
  * @see SchemaTypeOptions https://mongoosejs.com/docs/schematypes.html#all-schema-types
1212
1227
  * @api public
@@ -1259,7 +1274,7 @@ Query.prototype.schemaLevelProjections = function schemaLevelProjections(value)
1259
1274
  * @method sanitizeProjection
1260
1275
  * @memberOf Query
1261
1276
  * @instance
1262
- * @param {Boolean} value
1277
+ * @param {boolean} value
1263
1278
  * @return {Query} this
1264
1279
  * @see sanitizeProjection https://thecodebarbarian.com/whats-new-in-mongoose-5-13-sanitizeprojection.html
1265
1280
  * @api public
@@ -1319,7 +1334,7 @@ Query.prototype.sanitizeProjection = function sanitizeProjection(value) {
1319
1334
  * @method read
1320
1335
  * @memberOf Query
1321
1336
  * @instance
1322
- * @param {String} mode one of the listed preference options or aliases
1337
+ * @param {string} mode one of the listed preference options or aliases
1323
1338
  * @param {Array} [tags] optional tags for this query
1324
1339
  * @see mongodb https://www.mongodb.com/docs/manual/applications/replication/#read-preference
1325
1340
  * @return {Query} this
@@ -1365,7 +1380,7 @@ Query.prototype.toString = function toString() {
1365
1380
  this.op === 'update' ||
1366
1381
  this.op === 'updateMany' ||
1367
1382
  this.op === 'updateOne') {
1368
- return `${this.model.modelName}.${this.op}(${util.inspect(this._conditions)}, ${util.inspect(this._update)})`;
1383
+ return `${this.model.modelName}.${this.op}(${util.inspect(this._conditions)}, ${util.inspect(this[queryUpdateSymbol])})`;
1369
1384
  }
1370
1385
 
1371
1386
  // 'estimatedDocumentCount' or any others
@@ -1432,8 +1447,8 @@ Query.prototype.session = function session(v) {
1432
1447
  * @method writeConcern
1433
1448
  * @memberOf Query
1434
1449
  * @instance
1435
- * @param {Object} writeConcern the write concern value to set
1436
- * @see WriteConcernSettings https://mongodb.github.io/node-mongodb-native/4.9/interfaces/WriteConcernSettings.html
1450
+ * @param {object} writeConcern the write concern value to set
1451
+ * @see WriteConcernSettings https://mongodb.github.io/node-mongodb-native/7.0/interfaces/WriteConcernSettings.html
1437
1452
  * @return {Query} this
1438
1453
  * @api public
1439
1454
  */
@@ -1473,7 +1488,7 @@ Query.prototype.writeConcern = function writeConcern(val) {
1473
1488
  * @method w
1474
1489
  * @memberOf Query
1475
1490
  * @instance
1476
- * @param {String|number} val 0 for fire-and-forget, 1 for acknowledged by one server, 'majority' for majority of the replica set, or [any of the more advanced options](https://www.mongodb.com/docs/manual/reference/write-concern/#w-option).
1491
+ * @param {string|number} val 0 for fire-and-forget, 1 for acknowledged by one server, 'majority' for majority of the replica set, or [any of the more advanced options](https://www.mongodb.com/docs/manual/reference/write-concern/#w-option).
1477
1492
  * @see mongodb https://www.mongodb.com/docs/manual/reference/write-concern/#w-option
1478
1493
  * @return {Query} this
1479
1494
  * @api public
@@ -1624,7 +1639,7 @@ Query.prototype.wtimeout = function wtimeout(ms) {
1624
1639
  *
1625
1640
  * @memberOf Query
1626
1641
  * @method readConcern
1627
- * @param {String} level one of the listed read concern level or their aliases
1642
+ * @param {'local'|'available'|'majority'|'snapshot'|'linearizable'|'l'|'a'|'m'|'s'|'lz'} level one of the listed read concern level or their aliases
1628
1643
  * @see mongodb https://www.mongodb.com/docs/manual/reference/read-concern/
1629
1644
  * @return {Query} this
1630
1645
  * @api public
@@ -1640,7 +1655,7 @@ Query.prototype.wtimeout = function wtimeout(ms) {
1640
1655
  * query.setOptions({ maxTimeMS: 1000 });
1641
1656
  * query.getOptions(); // { limit: 10, maxTimeMS: 1000 }
1642
1657
  *
1643
- * @return {Object} the options
1658
+ * @return {object} the options
1644
1659
  * @api public
1645
1660
  */
1646
1661
 
@@ -1669,6 +1684,7 @@ Query.prototype.getOptions = function() {
1669
1684
  * - [upsert](https://www.mongodb.com/docs/manual/reference/method/db.collection.update/)
1670
1685
  * - [writeConcern](https://www.mongodb.com/docs/manual/reference/method/db.collection.update/)
1671
1686
  * - [timestamps](https://mongoosejs.com/docs/guide.html#timestamps): If `timestamps` is set in the schema, set this option to `false` to skip timestamps for that particular update. Has no effect if `timestamps` is not enabled in the schema options.
1687
+ * - cloneUpdate: set to `false` to skip cloning the update before executing the query.
1672
1688
  * - overwriteDiscriminatorKey: allow setting the discriminator key in the update. Will use the correct discriminator schema if the update changes the discriminator key.
1673
1689
  * - overwriteImmutable: allow overwriting properties that are set to `immutable` in the schema. Defaults to false.
1674
1690
  *
@@ -1679,6 +1695,7 @@ Query.prototype.getOptions = function() {
1679
1695
  * - [projection](https://mongoosejs.com/docs/api/query.html#Query.prototype.projection())
1680
1696
  * - sanitizeProjection
1681
1697
  * - useBigInt64
1698
+ * - defaults: if `false`, skip applying default values to the returned document(s). Defaults to true.
1682
1699
  *
1683
1700
  * The following options are only for all operations **except** `updateOne()`, `updateMany()`, `deleteOne()`, and `deleteMany()`:
1684
1701
  *
@@ -1698,8 +1715,9 @@ Query.prototype.getOptions = function() {
1698
1715
  * - [collation](https://www.mongodb.com/docs/manual/reference/collation/)
1699
1716
  * - [session](https://www.mongodb.com/docs/manual/reference/server-sessions/)
1700
1717
  * - [explain](https://www.mongodb.com/docs/manual/reference/method/cursor.explain/)
1718
+ * - [middleware](https://mongoosejs.com/docs/middleware.html#skipping): set to `false` to skip all user-defined middleware, or `{ pre: false }` / `{ post: false }` to skip only pre or post hooks
1701
1719
  *
1702
- * @param {Object} options
1720
+ * @param {object} options
1703
1721
  * @return {Query} this
1704
1722
  * @api public
1705
1723
  */
@@ -1720,7 +1738,7 @@ Query.prototype.setOptions = function(options, overwrite) {
1720
1738
  return this;
1721
1739
  }
1722
1740
  if (typeof options !== 'object') {
1723
- throw new Error('Options must be an object, got "' + options + '"');
1741
+ throw new MongooseError('Options must be an object, got "' + options + '"');
1724
1742
  }
1725
1743
 
1726
1744
  options = Object.assign({}, options);
@@ -1746,6 +1764,14 @@ Query.prototype.setOptions = function(options, overwrite) {
1746
1764
  this._mongooseOptions.overwriteImmutable = options.overwriteImmutable;
1747
1765
  delete options.overwriteImmutable;
1748
1766
  }
1767
+ if ('updatePipeline' in options) {
1768
+ this._mongooseOptions.updatePipeline = options.updatePipeline;
1769
+ delete options.updatePipeline;
1770
+ }
1771
+ if ('cloneUpdate' in options) {
1772
+ this._mongooseOptions.cloneUpdate = options.cloneUpdate;
1773
+ delete options.cloneUpdate;
1774
+ }
1749
1775
  if ('sanitizeProjection' in options) {
1750
1776
  if (options.sanitizeProjection && !this._mongooseOptions.sanitizeProjection) {
1751
1777
  sanitizeProjection(this._fields);
@@ -1782,14 +1808,14 @@ Query.prototype.setOptions = function(options, overwrite) {
1782
1808
  if (typeof options.limit === 'string') {
1783
1809
  try {
1784
1810
  options.limit = castNumber(options.limit);
1785
- } catch (err) {
1811
+ } catch {
1786
1812
  throw new CastError('Number', options.limit, 'limit');
1787
1813
  }
1788
1814
  }
1789
1815
  if (typeof options.skip === 'string') {
1790
1816
  try {
1791
1817
  options.skip = castNumber(options.skip);
1792
- } catch (err) {
1818
+ } catch {
1793
1819
  throw new CastError('Number', options.skip, 'skip');
1794
1820
  }
1795
1821
  }
@@ -1823,7 +1849,7 @@ Query.prototype.setOptions = function(options, overwrite) {
1823
1849
  * const res = await query.find({ a: 1 }).explain('queryPlanner');
1824
1850
  * console.log(res);
1825
1851
  *
1826
- * @param {String} [verbose] The verbosity mode. Either 'queryPlanner', 'executionStats', or 'allPlansExecution'. The default is 'queryPlanner'
1852
+ * @param {'queryPlanner'|'executionStats'|'allPlansExecution'} [verbose] The verbosity mode. The default is 'queryPlanner'
1827
1853
  * @return {Query} this
1828
1854
  * @api public
1829
1855
  */
@@ -1855,7 +1881,7 @@ Query.prototype.explain = function explain(verbose) {
1855
1881
  * // Equivalent:
1856
1882
  * await query.find().sort({ name: 1 }).allowDiskUse();
1857
1883
  *
1858
- * @param {Boolean} [v] Enable/disable `allowDiskUse`. If called with 0 arguments, sets `allowDiskUse: true`
1884
+ * @param {boolean} [v] Enable/disable `allowDiskUse`. If called with 0 arguments, sets `allowDiskUse: true`
1859
1885
  * @return {Query} this
1860
1886
  * @api public
1861
1887
  */
@@ -1885,7 +1911,7 @@ Query.prototype.allowDiskUse = function(v) {
1885
1911
  * // >= 1 doc in the queried collection
1886
1912
  * const res = await query.find({ $where: 'sleep(1000) || true' }).maxTimeMS(100);
1887
1913
  *
1888
- * @param {Number} [ms] The number of milliseconds
1914
+ * @param {number} [ms] The number of milliseconds
1889
1915
  * @return {Query} this
1890
1916
  * @api public
1891
1917
  */
@@ -1904,7 +1930,7 @@ Query.prototype.maxTimeMS = function(ms) {
1904
1930
  * query.find({ a: 1 }).where('b').gt(2);
1905
1931
  * query.getFilter(); // { a: 1, b: { $gt: 2 } }
1906
1932
  *
1907
- * @return {Object} current query filter
1933
+ * @return {object} current query filter
1908
1934
  * @api public
1909
1935
  */
1910
1936
 
@@ -1924,7 +1950,7 @@ Query.prototype.getFilter = function() {
1924
1950
  * query.find({ a: 1 }).where('b').gt(2);
1925
1951
  * query.getQuery(); // { a: 1, b: { $gt: 2 } }
1926
1952
  *
1927
- * @return {Object} current query filter
1953
+ * @return {object} current query filter
1928
1954
  * @api public
1929
1955
  */
1930
1956
 
@@ -1942,7 +1968,7 @@ Query.prototype.getQuery = function() {
1942
1968
  * query.setQuery({ a: 2 });
1943
1969
  * query.getQuery(); // { a: 2 }
1944
1970
  *
1945
- * @param {Object} new query conditions
1971
+ * @param {object} new query conditions
1946
1972
  * @return {undefined}
1947
1973
  * @api public
1948
1974
  */
@@ -1960,7 +1986,7 @@ Query.prototype.setQuery = function(val) {
1960
1986
  * query.updateOne({}, { $set: { a: 5 } });
1961
1987
  * query.getUpdate(); // { $set: { a: 5 } }
1962
1988
  *
1963
- * @return {Object} current update operations
1989
+ * @return {object} current update operations
1964
1990
  * @api public
1965
1991
  */
1966
1992
 
@@ -1978,20 +2004,25 @@ Query.prototype.getUpdate = function() {
1978
2004
  * query.setUpdate({ $set: { b: 6 } });
1979
2005
  * query.getUpdate(); // { $set: { b: 6 } }
1980
2006
  *
1981
- * @param {Object} new update operation
2007
+ * @param {object} new update operation
2008
+ * @param {boolean} [cloneUpdate=true] if `false`, Mongoose will not clone the update
1982
2009
  * @return {undefined}
1983
2010
  * @api public
1984
2011
  */
1985
2012
 
1986
- Query.prototype.setUpdate = function(val) {
1987
- this._update = val;
2013
+ Query.prototype.setUpdate = function(val, cloneUpdate) {
2014
+ this[queryUpdateSymbol] = cloneUpdate === false ? val : clone(val);
2015
+ if (cloneUpdate != null) {
2016
+ this._mongooseOptions.cloneUpdate = cloneUpdate;
2017
+ }
2018
+ this._updateIsShared = false;
1988
2019
  };
1989
2020
 
1990
2021
  /**
1991
2022
  * Returns fields selection for this query.
1992
2023
  *
1993
2024
  * @method _fieldsForExec
1994
- * @return {Object}
2025
+ * @return {object}
1995
2026
  * @api private
1996
2027
  * @memberOf Query
1997
2028
  */
@@ -2000,7 +2031,7 @@ Query.prototype._fieldsForExec = function() {
2000
2031
  if (this._fields == null) {
2001
2032
  return null;
2002
2033
  }
2003
- if (Object.keys(this._fields).length === 0) {
2034
+ if (utils.hasOwnKeys(this._fields) === false) {
2004
2035
  return null;
2005
2036
  }
2006
2037
  return clone(this._fields);
@@ -2011,13 +2042,13 @@ Query.prototype._fieldsForExec = function() {
2011
2042
  * Return an update document with corrected `$set` operations.
2012
2043
  *
2013
2044
  * @method _updateForExec
2014
- * @return {Object}
2045
+ * @return {object}
2015
2046
  * @api private
2016
2047
  * @memberOf Query
2017
2048
  */
2018
2049
 
2019
2050
  Query.prototype._updateForExec = function() {
2020
- const update = clone(this._update, {
2051
+ const update = clone(this[queryUpdateSymbol], {
2021
2052
  transform: false,
2022
2053
  depopulate: true
2023
2054
  });
@@ -2058,7 +2089,7 @@ Query.prototype._updateForExec = function() {
2058
2089
  * This method is inherited by `mquery`
2059
2090
  *
2060
2091
  * @method _ensurePath
2061
- * @param {String} method
2092
+ * @param {string} method
2062
2093
  * @api private
2063
2094
  * @memberOf Query
2064
2095
  */
@@ -2069,8 +2100,8 @@ Query.prototype._updateForExec = function() {
2069
2100
  * @method canMerge
2070
2101
  * @memberOf Query
2071
2102
  * @instance
2072
- * @param {Object} conds
2073
- * @return {Boolean}
2103
+ * @param {object} conds
2104
+ * @return {boolean}
2074
2105
  * @api private
2075
2106
  */
2076
2107
 
@@ -2098,10 +2129,7 @@ Query.prototype._optionsForExec = function(model) {
2098
2129
  options.session = asyncLocalStorage.session;
2099
2130
  }
2100
2131
 
2101
- const readPreference = model &&
2102
- model.schema &&
2103
- model.schema.options &&
2104
- model.schema.options.read;
2132
+ const readPreference = model?.schema?.options?.read;
2105
2133
  if (!('readPreference' in options) && readPreference) {
2106
2134
  options.readPreference = readPreference;
2107
2135
  }
@@ -2186,7 +2214,7 @@ Query.prototype._optionsForExec = function(model) {
2186
2214
  * - [mongoose-lean-getters](https://plugins.mongoosejs.io/plugins/lean-getters)
2187
2215
  * - [mongoose-lean-defaults](https://www.npmjs.com/package/mongoose-lean-defaults)
2188
2216
  *
2189
- * @param {Boolean|Object} bool defaults to true
2217
+ * @param {boolean|object} bool defaults to true
2190
2218
  * @return {Query} this
2191
2219
  * @api public
2192
2220
  */
@@ -2207,13 +2235,15 @@ Query.prototype.lean = function(v) {
2207
2235
  * new Query().updateOne({}, {}).set('updatedAt', new Date());
2208
2236
  * new Query().updateMany({}, {}).set({ updatedAt: new Date() });
2209
2237
  *
2210
- * @param {String|Object} path path or object of key/value pairs to set
2211
- * @param {Any} [val] the value to set
2238
+ * @param {string|object} path path or object of key/value pairs to set
2239
+ * @param {any} [val] the value to set
2212
2240
  * @return {Query} this
2213
2241
  * @api public
2214
2242
  */
2215
2243
 
2216
2244
  Query.prototype.set = function(path, val) {
2245
+ _cloneUpdateIfShared(this);
2246
+
2217
2247
  if (typeof path === 'object') {
2218
2248
  const keys = Object.keys(path);
2219
2249
  for (const key of keys) {
@@ -2222,12 +2252,16 @@ Query.prototype.set = function(path, val) {
2222
2252
  return this;
2223
2253
  }
2224
2254
 
2225
- this._update = this._update || {};
2226
- if (path in this._update) {
2227
- delete this._update[path];
2255
+ let update = this[queryUpdateSymbol];
2256
+ if (update == null) {
2257
+ update = {};
2258
+ this[queryUpdateSymbol] = update;
2259
+ }
2260
+ if (path in update) {
2261
+ delete update[path];
2228
2262
  }
2229
- this._update.$set = this._update.$set || {};
2230
- this._update.$set[path] = val;
2263
+ update.$set = update.$set || {};
2264
+ update.$set[path] = val;
2231
2265
  return this;
2232
2266
  };
2233
2267
 
@@ -2241,13 +2275,13 @@ Query.prototype.set = function(path, val) {
2241
2275
  * const query = Model.updateOne({}, { $set: { name: 'Jean-Luc Picard' } });
2242
2276
  * query.get('name'); // 'Jean-Luc Picard'
2243
2277
  *
2244
- * @param {String|Object} path path or object of key/value pairs to get
2278
+ * @param {string|object} path path or object of key/value pairs to get
2245
2279
  * @return {Query} this
2246
2280
  * @api public
2247
2281
  */
2248
2282
 
2249
2283
  Query.prototype.get = function get(path) {
2250
- const update = this._update;
2284
+ const update = this[queryUpdateSymbol];
2251
2285
  if (update == null) {
2252
2286
  return void 0;
2253
2287
  }
@@ -2331,13 +2365,14 @@ Query.prototype._unsetCastError = function _unsetCastError() {
2331
2365
  * - `strictQuery`: controls how Mongoose handles keys that aren't in the schema for the query `filter`. This option is `false` by default, which means Mongoose will allow `Model.find({ foo: 'bar' })` even if `foo` is not in the schema. See the [`strictQuery` docs](https://mongoosejs.com/docs/guide.html#strictQuery) for more information.
2332
2366
  * - `nearSphere`: use `$nearSphere` instead of `near()`. See the [`Query.prototype.nearSphere()` docs](https://mongoosejs.com/docs/api/query.html#Query.prototype.nearSphere())
2333
2367
  * - `schemaLevelProjections`: if `false`, Mongoose will not apply schema-level `select: false` or `select: true` for this query
2368
+ * - `cloneUpdate`: if `false`, Mongoose will not clone updates before executing the query
2334
2369
  *
2335
2370
  * Mongoose maintains a separate object for internal options because
2336
2371
  * Mongoose sends `Query.prototype.options` to the MongoDB server, and the
2337
2372
  * above options are not relevant for the MongoDB server.
2338
2373
  *
2339
- * @param {Object} options if specified, overwrites the current options
2340
- * @return {Object} the options
2374
+ * @param {object} options if specified, overwrites the current options
2375
+ * @return {object} the options
2341
2376
  * @api public
2342
2377
  */
2343
2378
 
@@ -2407,16 +2442,24 @@ Query.prototype._find = async function _find() {
2407
2442
  const mongooseOptions = this._mongooseOptions;
2408
2443
  const userProvidedFields = this._userProvidedFields || {};
2409
2444
 
2410
- applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
2411
- applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
2445
+ const dbOptions = this.model.db.options;
2446
+ const baseOptions = this.model.base.options;
2447
+ applyGlobalMaxTimeMS(this.options, dbOptions, baseOptions);
2448
+ applyGlobalDiskUse(this.options, dbOptions, baseOptions);
2412
2449
 
2413
2450
  // Separate options to pass down to `completeMany()` in case we need to
2414
2451
  // set a session on the document
2415
2452
  const completeManyOptions = {
2416
- session: this && this.options && this.options.session || null,
2453
+ session: this?.options?.session || null,
2417
2454
  lean: mongooseOptions.lean || null
2418
2455
  };
2419
2456
 
2457
+ // Only pass `defaults` through when it is non-nullish; `null` and
2458
+ // `undefined` are treated as "not set" and omitted from `createModel()`.
2459
+ if (mongooseOptions.defaults != null) {
2460
+ completeManyOptions.defaults = mongooseOptions.defaults;
2461
+ }
2462
+
2420
2463
  const options = this._optionsForExec();
2421
2464
 
2422
2465
  const filter = this._conditions;
@@ -2434,7 +2477,7 @@ Query.prototype._find = async function _find() {
2434
2477
 
2435
2478
  if (!mongooseOptions.populate) {
2436
2479
  const versionKey = this.schema.options.versionKey;
2437
- if (mongooseOptions.lean && mongooseOptions.lean.versionKey === false && versionKey) {
2480
+ if (mongooseOptions.lean?.versionKey === false && versionKey) {
2438
2481
  docs.forEach((doc) => {
2439
2482
  if (versionKey in doc) {
2440
2483
  delete doc[versionKey];
@@ -2448,6 +2491,16 @@ Query.prototype._find = async function _find() {
2448
2491
 
2449
2492
  const pop = helpers.preparePopulationOptionsMQ(this, mongooseOptions);
2450
2493
 
2494
+ // _deferPopulate is used internally when we need to defer populate until after
2495
+ // filtering (when using match functions with nested populate via hooks)
2496
+ if (this.options?._deferPopulate) {
2497
+ docs = mongooseOptions.lean ?
2498
+ docs :
2499
+ await this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
2500
+ this._deferredPopulate = pop;
2501
+ return docs;
2502
+ }
2503
+
2451
2504
  if (mongooseOptions.lean) {
2452
2505
  return this.model.populate(docs, pop);
2453
2506
  }
@@ -2468,7 +2521,7 @@ Query.prototype._find = async function _find() {
2468
2521
  *
2469
2522
  * const arr = await Movie.find({ year: { $gte: 1980, $lte: 1989 } });
2470
2523
  *
2471
- * @param {Object|ObjectId} [filter] mongodb filter. If not specified, returns all documents.
2524
+ * @param {object|ObjectId} [filter] mongodb filter. If not specified, returns all documents.
2472
2525
  * @return {Query} this
2473
2526
  * @api public
2474
2527
  */
@@ -2481,7 +2534,7 @@ Query.prototype.find = function(conditions) {
2481
2534
 
2482
2535
  this.op = 'find';
2483
2536
 
2484
- if (mquery.canMerge(conditions)) {
2537
+ if (canMerge(conditions)) {
2485
2538
  this.merge(conditions);
2486
2539
 
2487
2540
  prepareDiscriminatorCriteria(this);
@@ -2497,15 +2550,20 @@ Query.prototype.find = function(conditions) {
2497
2550
  *
2498
2551
  * When a Query is passed, conditions, field selection and options are merged.
2499
2552
  *
2500
- * @param {Query|Object} source
2553
+ * @param {Query|object} source
2501
2554
  * @return {Query} this
2502
2555
  */
2503
2556
 
2504
2557
  Query.prototype.merge = function(source) {
2505
2558
  if (!source) {
2559
+ if (source === null) {
2560
+ this._conditions = null;
2561
+ }
2506
2562
  return this;
2507
2563
  }
2508
2564
 
2565
+ this._conditions = this._conditions ?? {};
2566
+
2509
2567
  const opts = { overwrite: true };
2510
2568
 
2511
2569
  if (source instanceof Query) {
@@ -2534,9 +2592,10 @@ Query.prototype.merge = function(source) {
2534
2592
  utils.merge(this.options, source.options, opts);
2535
2593
  }
2536
2594
 
2537
- if (source._update) {
2538
- this._update || (this._update = {});
2539
- utils.mergeClone(this._update, source._update);
2595
+ if (source[queryUpdateSymbol] != null) {
2596
+ _cloneUpdateIfShared(this);
2597
+ this[queryUpdateSymbol] || (this[queryUpdateSymbol] = {});
2598
+ utils.mergeClone(this[queryUpdateSymbol], source[queryUpdateSymbol]);
2540
2599
  }
2541
2600
 
2542
2601
  if (source._distinct) {
@@ -2550,7 +2609,7 @@ Query.prototype.merge = function(source) {
2550
2609
  utils.merge(this._conditions, { _id: source }, opts);
2551
2610
 
2552
2611
  return this;
2553
- } else if (source && source.$__) {
2612
+ } else if (source?.$__) {
2554
2613
  source = source.toObject(internalToObjectOptions);
2555
2614
  }
2556
2615
 
@@ -2583,7 +2642,7 @@ Query.prototype.merge = function(source) {
2583
2642
  /**
2584
2643
  * Adds a collation to this op (MongoDB 3.4 and up)
2585
2644
  *
2586
- * @param {Object} value
2645
+ * @param {object} value
2587
2646
  * @return {Query} this
2588
2647
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/method/cursor.collation/#cursor.collation
2589
2648
  * @api public
@@ -2624,7 +2683,7 @@ Query.prototype._completeOne = function(doc, res, projection, callback) {
2624
2683
 
2625
2684
  if (!mongooseOptions.populate) {
2626
2685
  const versionKey = this.schema.options.versionKey;
2627
- if (mongooseOptions.lean && mongooseOptions.lean.versionKey === false && versionKey) {
2686
+ if (mongooseOptions.lean?.versionKey === false && versionKey) {
2628
2687
  if (versionKey in doc) {
2629
2688
  delete doc[versionKey];
2630
2689
  }
@@ -2660,9 +2719,9 @@ Query.prototype._completeOne = function(doc, res, projection, callback) {
2660
2719
  * of the model. Used to initialize docs returned from the db from `find()`
2661
2720
  *
2662
2721
  * @param {Array} docs
2663
- * @param {Object} fields the projection used, including `select` from schemas
2664
- * @param {Object} userProvidedFields the user-specified projection
2665
- * @param {Object} [opts]
2722
+ * @param {object} fields the projection used, including `select` from schemas
2723
+ * @param {object} userProvidedFields the user-specified projection
2724
+ * @param {object} [opts]
2666
2725
  * @param {Array} [opts.populated]
2667
2726
  * @param {ClientSession} [opts.session]
2668
2727
  * @api private
@@ -2672,7 +2731,7 @@ Query.prototype._completeMany = async function _completeMany(docs, fields, userP
2672
2731
  const model = this.model;
2673
2732
  return Promise.all(docs.map(doc => new Promise((resolve, reject) => {
2674
2733
  const rawDoc = doc;
2675
- doc = helpers.createModel(model, doc, fields, userProvidedFields);
2734
+ doc = helpers.createModel(model, doc, fields, userProvidedFields, opts);
2676
2735
  if (opts.session != null) {
2677
2736
  doc.$session(opts.session);
2678
2737
  }
@@ -2701,8 +2760,10 @@ Query.prototype._findOne = async function _findOne() {
2701
2760
  throw err;
2702
2761
  }
2703
2762
 
2704
- applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
2705
- applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
2763
+ const dbOptions = this.model.db.options;
2764
+ const baseOptions = this.model.base.options;
2765
+ applyGlobalMaxTimeMS(this.options, dbOptions, baseOptions);
2766
+ applyGlobalDiskUse(this.options, dbOptions, baseOptions);
2706
2767
 
2707
2768
  const options = this._optionsForExec();
2708
2769
 
@@ -2737,10 +2798,10 @@ Query.prototype._findOne = async function _findOne() {
2737
2798
  * const query = Kitten.where({ color: 'white' });
2738
2799
  * const kitten = await query.findOne();
2739
2800
  *
2740
- * @param {Object} [filter] mongodb selector
2741
- * @param {Object} [projection] optional fields to return
2742
- * @param {Object} [options] see [`setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
2743
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2801
+ * @param {object} [filter] mongodb selector
2802
+ * @param {object} [projection] optional fields to return
2803
+ * @param {object} [options] see [`setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
2804
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
2744
2805
  * @return {Query} this
2745
2806
  * @see findOne https://www.mongodb.com/docs/manual/reference/method/db.collection.findOne/
2746
2807
  * @see Query.select https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
@@ -2756,7 +2817,6 @@ Query.prototype.findOne = function(conditions, projection, options) {
2756
2817
  }
2757
2818
 
2758
2819
  this.op = 'findOne';
2759
- this._validateOp();
2760
2820
 
2761
2821
  if (options) {
2762
2822
  this.setOptions(options);
@@ -2766,7 +2826,7 @@ Query.prototype.findOne = function(conditions, projection, options) {
2766
2826
  this.select(projection);
2767
2827
  }
2768
2828
 
2769
- if (mquery.canMerge(conditions)) {
2829
+ if (canMerge(conditions)) {
2770
2830
  this.merge(conditions);
2771
2831
 
2772
2832
  prepareDiscriminatorCriteria(this);
@@ -2781,7 +2841,7 @@ Query.prototype.findOne = function(conditions, projection, options) {
2781
2841
  /**
2782
2842
  * Execute a countDocuments query
2783
2843
  *
2784
- * @see countDocuments https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#countDocuments
2844
+ * @see countDocuments https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#countDocuments
2785
2845
  * @api private
2786
2846
  */
2787
2847
 
@@ -2798,8 +2858,10 @@ Query.prototype._countDocuments = async function _countDocuments() {
2798
2858
  throw this.error();
2799
2859
  }
2800
2860
 
2801
- applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
2802
- applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
2861
+ const dbOptions = this.model.db.options;
2862
+ const baseOptions = this.model.base.options;
2863
+ applyGlobalMaxTimeMS(this.options, dbOptions, baseOptions);
2864
+ applyGlobalDiskUse(this.options, dbOptions, baseOptions);
2803
2865
 
2804
2866
  const options = this._optionsForExec();
2805
2867
 
@@ -2826,10 +2888,11 @@ Query.prototype._applyTranslateAliases = function _applyTranslateAliases() {
2826
2888
  return;
2827
2889
  }
2828
2890
 
2829
- if (this.model?.schema?.aliases && Object.keys(this.model.schema.aliases).length > 0) {
2891
+ if (this.model?.schema?.aliases && utils.hasOwnKeys(this.model.schema.aliases)) {
2892
+ _cloneUpdateIfShared(this);
2830
2893
  this.model.translateAliases(this._conditions, true);
2831
2894
  this.model.translateAliases(this._fields, true);
2832
- this.model.translateAliases(this._update, true);
2895
+ this.model.translateAliases(this[queryUpdateSymbol], true);
2833
2896
  if (this._distinct != null && this.model.schema.aliases[this._distinct] != null) {
2834
2897
  this._distinct = this.model.schema.aliases[this._distinct];
2835
2898
  }
@@ -2839,7 +2902,7 @@ Query.prototype._applyTranslateAliases = function _applyTranslateAliases() {
2839
2902
  /**
2840
2903
  * Execute a estimatedDocumentCount() query
2841
2904
  *
2842
- * @see estimatedDocumentCount https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#estimatedDocumentCount
2905
+ * @see estimatedDocumentCount https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#estimatedDocumentCount
2843
2906
  * @api private
2844
2907
  */
2845
2908
 
@@ -2870,9 +2933,9 @@ Query.prototype._estimatedDocumentCount = async function _estimatedDocumentCount
2870
2933
  *
2871
2934
  * await Model.find().estimatedDocumentCount();
2872
2935
  *
2873
- * @param {Object} [options] passed transparently to the [MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/EstimatedDocumentCountOptions.html)
2936
+ * @param {object} [options] passed transparently to the [MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/EstimatedDocumentCountOptions.html)
2874
2937
  * @return {Query} this
2875
- * @see estimatedDocumentCount https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#estimatedDocumentCount
2938
+ * @see estimatedDocumentCount https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#estimatedDocumentCount
2876
2939
  * @api public
2877
2940
  */
2878
2941
 
@@ -2883,7 +2946,6 @@ Query.prototype.estimatedDocumentCount = function(options) {
2883
2946
  }
2884
2947
 
2885
2948
  this.op = 'estimatedDocumentCount';
2886
- this._validateOp();
2887
2949
 
2888
2950
  if (options != null) {
2889
2951
  this.setOptions(options);
@@ -2897,7 +2959,7 @@ Query.prototype.estimatedDocumentCount = function(options) {
2897
2959
  * except it always does a full collection scan when passed an empty filter `{}`.
2898
2960
  *
2899
2961
  * There are also minor differences in how `countDocuments()` handles
2900
- * [`$where` and a couple geospatial operators](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#countDocuments).
2962
+ * [`$where` and a couple geospatial operators](https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#countDocuments).
2901
2963
  * versus `count()`.
2902
2964
  *
2903
2965
  * This function triggers the following middleware.
@@ -2915,7 +2977,7 @@ Query.prototype.estimatedDocumentCount = function(options) {
2915
2977
  * query.where('color', 'black').countDocuments().exec();
2916
2978
  *
2917
2979
  * The `countDocuments()` function is similar to `count()`, but there are a
2918
- * [few operators that `countDocuments()` does not support](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#countDocuments).
2980
+ * [few operators that `countDocuments()` does not support](https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#countDocuments).
2919
2981
  * Below are the operators that `count()` supports but `countDocuments()` does not,
2920
2982
  * and the suggested replacement:
2921
2983
  *
@@ -2923,10 +2985,10 @@ Query.prototype.estimatedDocumentCount = function(options) {
2923
2985
  * - `$near`: [`$geoWithin`](https://www.mongodb.com/docs/manual/reference/operator/query/geoWithin/) with [`$center`](https://www.mongodb.com/docs/manual/reference/operator/query/center/#op._S_center)
2924
2986
  * - `$nearSphere`: [`$geoWithin`](https://www.mongodb.com/docs/manual/reference/operator/query/geoWithin/) with [`$centerSphere`](https://www.mongodb.com/docs/manual/reference/operator/query/centerSphere/#op._S_centerSphere)
2925
2987
  *
2926
- * @param {Object} [filter] mongodb selector
2927
- * @param {Object} [options]
2988
+ * @param {object} [filter] mongodb selector
2989
+ * @param {object} [options]
2928
2990
  * @return {Query} this
2929
- * @see countDocuments https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#countDocuments
2991
+ * @see countDocuments https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#countDocuments
2930
2992
  * @api public
2931
2993
  */
2932
2994
 
@@ -2938,9 +3000,8 @@ Query.prototype.countDocuments = function(conditions, options) {
2938
3000
  }
2939
3001
 
2940
3002
  this.op = 'countDocuments';
2941
- this._validateOp();
2942
3003
 
2943
- if (mquery.canMerge(conditions)) {
3004
+ if (canMerge(conditions)) {
2944
3005
  this.merge(conditions);
2945
3006
  }
2946
3007
 
@@ -2966,8 +3027,10 @@ Query.prototype.__distinct = async function __distinct() {
2966
3027
  throw this.error();
2967
3028
  }
2968
3029
 
2969
- applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
2970
- applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
3030
+ const dbOptions = this.model.db.options;
3031
+ const baseOptions = this.model.base.options;
3032
+ applyGlobalMaxTimeMS(this.options, dbOptions, baseOptions);
3033
+ applyGlobalDiskUse(this.options, dbOptions, baseOptions);
2971
3034
 
2972
3035
  const options = this._optionsForExec();
2973
3036
 
@@ -2987,9 +3050,9 @@ Query.prototype.__distinct = async function __distinct() {
2987
3050
  * distinct(field)
2988
3051
  * distinct()
2989
3052
  *
2990
- * @param {String} [field]
2991
- * @param {Object|Query} [filter]
2992
- * @param {Object} [options]
3053
+ * @param {string} [field]
3054
+ * @param {object|Query} [filter]
3055
+ * @param {object} [options]
2993
3056
  * @return {Query} this
2994
3057
  * @see distinct https://www.mongodb.com/docs/manual/reference/method/db.collection.distinct/
2995
3058
  * @api public
@@ -3004,9 +3067,8 @@ Query.prototype.distinct = function(field, conditions, options) {
3004
3067
  }
3005
3068
 
3006
3069
  this.op = 'distinct';
3007
- this._validateOp();
3008
3070
 
3009
- if (mquery.canMerge(conditions)) {
3071
+ if (canMerge(conditions)) {
3010
3072
  this.merge(conditions);
3011
3073
 
3012
3074
  prepareDiscriminatorCriteria(this);
@@ -3049,9 +3111,9 @@ Query.prototype.distinct = function(field, conditions, options) {
3049
3111
  *
3050
3112
  * Cannot be used with `distinct()`
3051
3113
  *
3052
- * @param {Object|String|Array<Array<(string | number)>>} arg
3053
- * @param {Object} [options]
3054
- * @param {Boolean} [options.override=false] If true, replace existing sort options with `arg`
3114
+ * @param {object|string|Array<Array<(string | number)>>} arg
3115
+ * @param {object} [options]
3116
+ * @param {boolean} [options.override=false] If true, replace existing sort options with `arg`
3055
3117
  * @return {Query} this
3056
3118
  * @see cursor.sort https://www.mongodb.com/docs/manual/reference/method/cursor.sort/
3057
3119
  * @api public
@@ -3059,16 +3121,16 @@ Query.prototype.distinct = function(field, conditions, options) {
3059
3121
 
3060
3122
  Query.prototype.sort = function(arg, options) {
3061
3123
  if (arguments.length > 2) {
3062
- throw new Error('sort() takes at most 2 arguments');
3124
+ throw new MongooseError('sort() takes at most 2 arguments');
3063
3125
  }
3064
3126
  if (options != null && typeof options !== 'object') {
3065
- throw new Error('sort() options argument must be an object or nullish');
3127
+ throw new MongooseError('sort() options argument must be an object or nullish');
3066
3128
  }
3067
3129
 
3068
3130
  if (this.options.sort == null) {
3069
3131
  this.options.sort = {};
3070
3132
  }
3071
- if (options && options.override) {
3133
+ if (options?.override) {
3072
3134
  this.options.sort = {};
3073
3135
  }
3074
3136
  const sort = this.options.sort;
@@ -3145,7 +3207,7 @@ function _handleSortValue(val, key) {
3145
3207
  *
3146
3208
  * await Character.deleteOne({ name: 'Eddard Stark' });
3147
3209
  *
3148
- * This function calls the MongoDB driver's [`Collection#deleteOne()` function](https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteOne).
3210
+ * This function calls the MongoDB driver's [`Collection#deleteOne()` function](https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#deleteOne).
3149
3211
  * The returned [promise](https://mongoosejs.com/docs/queries.html) resolves to an
3150
3212
  * object that contains 2 properties:
3151
3213
  *
@@ -3158,12 +3220,12 @@ function _handleSortValue(val, key) {
3158
3220
  * // `1` if MongoDB deleted a doc, `0` if no docs matched the filter `{ name: ... }`
3159
3221
  * res.deletedCount;
3160
3222
  *
3161
- * @param {Object|Query} [filter] mongodb selector
3162
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3163
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3223
+ * @param {object|Query} [filter] mongodb selector
3224
+ * @param {object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3225
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3164
3226
  * @return {Query} this
3165
- * @see DeleteResult https://mongodb.github.io/node-mongodb-native/6.15/interfaces/DeleteResult.html
3166
- * @see deleteOne https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteOne
3227
+ * @see DeleteResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/DeleteResult.html
3228
+ * @see deleteOne https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#deleteOne
3167
3229
  * @api public
3168
3230
  */
3169
3231
 
@@ -3174,7 +3236,7 @@ Query.prototype.deleteOne = function deleteOne(filter, options) {
3174
3236
  this.op = 'deleteOne';
3175
3237
  this.setOptions(options);
3176
3238
 
3177
- if (mquery.canMerge(filter)) {
3239
+ if (canMerge(filter)) {
3178
3240
  this.merge(filter);
3179
3241
 
3180
3242
  prepareDiscriminatorCriteria(this);
@@ -3221,7 +3283,7 @@ Query.prototype._deleteOne = async function _deleteOne() {
3221
3283
  *
3222
3284
  * await Character.deleteMany({ name: /Stark/, age: { $gte: 18 } });
3223
3285
  *
3224
- * This function calls the MongoDB driver's [`Collection#deleteMany()` function](https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteMany).
3286
+ * This function calls the MongoDB driver's [`Collection#deleteMany()` function](https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#deleteMany).
3225
3287
  * The returned [promise](https://mongoosejs.com/docs/queries.html) resolves to an
3226
3288
  * object that contains 2 properties:
3227
3289
  *
@@ -3234,12 +3296,12 @@ Query.prototype._deleteOne = async function _deleteOne() {
3234
3296
  * // `0` if no docs matched the filter, number of docs deleted otherwise
3235
3297
  * res.deletedCount;
3236
3298
  *
3237
- * @param {Object|Query} [filter] mongodb selector
3238
- * @param {Object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3239
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3299
+ * @param {object|Query} [filter] mongodb selector
3300
+ * @param {object} [options] optional see [`Query.prototype.setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3301
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3240
3302
  * @return {Query} this
3241
- * @see DeleteResult https://mongodb.github.io/node-mongodb-native/6.15/interfaces/DeleteResult.html
3242
- * @see deleteMany https://mongodb.github.io/node-mongodb-native/6.15/classes/Collection.html#deleteMany
3303
+ * @see DeleteResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/DeleteResult.html
3304
+ * @see deleteMany https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#deleteMany
3243
3305
  * @api public
3244
3306
  */
3245
3307
 
@@ -3250,7 +3312,7 @@ Query.prototype.deleteMany = function(filter, options) {
3250
3312
  this.setOptions(options);
3251
3313
  this.op = 'deleteMany';
3252
3314
 
3253
- if (mquery.canMerge(filter)) {
3315
+ if (canMerge(filter)) {
3254
3316
  this.merge(filter);
3255
3317
 
3256
3318
  prepareDiscriminatorCriteria(this);
@@ -3291,8 +3353,8 @@ Query.prototype._deleteMany = async function _deleteMany() {
3291
3353
  *
3292
3354
  * @param {Model} model
3293
3355
  * @param {Document} doc
3294
- * @param {Object} res 3rd parameter to callback
3295
- * @param {Object} fields
3356
+ * @param {object} res 3rd parameter to callback
3357
+ * @param {object} fields
3296
3358
  * @param {Query} self
3297
3359
  * @param {Array} [pop] array of paths used in population
3298
3360
  * @param {Function} callback
@@ -3338,13 +3400,13 @@ function completeOne(model, doc, res, options, fields, userProvidedFields, pop,
3338
3400
  */
3339
3401
 
3340
3402
  function prepareDiscriminatorCriteria(query) {
3341
- if (!query || !query.model || !query.model.schema) {
3403
+ if (!query?.model?.schema) {
3342
3404
  return;
3343
3405
  }
3344
3406
 
3345
3407
  const schema = query.model.schema;
3346
3408
 
3347
- if (schema && schema.discriminatorMapping && !schema.discriminatorMapping.isRoot) {
3409
+ if (schema?.discriminatorMapping && !schema.discriminatorMapping.isRoot) {
3348
3410
  query._conditions[schema.discriminatorMapping.key] = schema.discriminatorMapping.value;
3349
3411
  }
3350
3412
  }
@@ -3381,39 +3443,40 @@ function prepareDiscriminatorCriteria(query) {
3381
3443
  * @method findOneAndUpdate
3382
3444
  * @memberOf Query
3383
3445
  * @instance
3384
- * @param {Object|Query} [filter]
3385
- * @param {Object} [doc]
3386
- * @param {Object} [options]
3387
- * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3388
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3446
+ * @param {object|Query} [filter]
3447
+ * @param {object} [update]
3448
+ * @param {object} [options]
3449
+ * @param {boolean} [options.cloneUpdate=true] if `false`, Mongoose will not clone the update before executing the query
3450
+ * @param {boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html) rather than just the document
3451
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3389
3452
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3390
- * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3391
- * @param {Boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied.
3392
- * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3393
- * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3394
- * @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
3395
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3396
- * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3397
- * @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
3398
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3453
+ * @param {boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3454
+ * @param {boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied. **Deprecated:** Use `returnDocument: 'after'` instead of `new: true`, or `returnDocument: 'before'` instead of `new: false`.
3455
+ * @param {object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3456
+ * @param {boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3457
+ * @param {boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`. **Deprecated:** Use `returnDocument: 'after'` instead of `returnOriginal: false`, or `returnDocument: 'before'` instead of `returnOriginal: true`.
3458
+ * @param {'before'|'after'} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
3459
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3460
+ * @param {boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3461
+ * @param {boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
3462
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3399
3463
  * @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
3400
3464
  * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3401
- * @see ModifyResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html
3402
- * @see findOneAndUpdate https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#findOneAndUpdate
3465
+ * @see ModifyResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html
3466
+ * @see findOneAndUpdate https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#findOneAndUpdate
3403
3467
  * @return {Query} this
3404
3468
  * @api public
3405
3469
  */
3406
3470
 
3407
- Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3471
+ Query.prototype.findOneAndUpdate = function(filter, update, options) {
3408
3472
  if (typeof filter === 'function' ||
3409
- typeof doc === 'function' ||
3473
+ typeof update === 'function' ||
3410
3474
  typeof options === 'function' ||
3411
3475
  typeof arguments[3] === 'function') {
3412
3476
  throw new MongooseError('Query.prototype.findOneAndUpdate() no longer accepts a callback');
3413
3477
  }
3414
3478
 
3415
3479
  this.op = 'findOneAndUpdate';
3416
- this._validateOp();
3417
3480
  this._validate();
3418
3481
 
3419
3482
  switch (arguments.length) {
@@ -3421,12 +3484,12 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3421
3484
  options = undefined;
3422
3485
  break;
3423
3486
  case 1:
3424
- doc = filter;
3487
+ update = filter;
3425
3488
  filter = options = undefined;
3426
3489
  break;
3427
3490
  }
3428
3491
 
3429
- if (mquery.canMerge(filter)) {
3492
+ if (canMerge(filter)) {
3430
3493
  this.merge(filter);
3431
3494
  } else if (filter != null) {
3432
3495
  this.error(
@@ -3434,11 +3497,6 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3434
3497
  );
3435
3498
  }
3436
3499
 
3437
- // apply doc
3438
- if (doc) {
3439
- this._mergeUpdate(doc);
3440
- }
3441
-
3442
3500
  options = options ? clone(options) : {};
3443
3501
 
3444
3502
  if (options.projection) {
@@ -3450,17 +3508,37 @@ Query.prototype.findOneAndUpdate = function(filter, doc, options) {
3450
3508
  delete options.fields;
3451
3509
  }
3452
3510
 
3453
- const returnOriginal = this &&
3454
- this.model &&
3455
- this.model.base &&
3456
- this.model.base.options &&
3457
- this.model.base.options.returnOriginal;
3458
- if (options.new == null && options.returnDocument == null && options.returnOriginal == null && returnOriginal != null) {
3459
- options.returnOriginal = returnOriginal;
3511
+ const globalReturnDocument = this?.model?.base?.options?.returnDocument;
3512
+ const globalReturnOriginal = this?.model?.base?.options?.returnOriginal;
3513
+ if (options.new == null && options.returnDocument == null && options.returnOriginal == null) {
3514
+ if (globalReturnDocument != null) {
3515
+ options.returnDocument = globalReturnDocument;
3516
+ } else if (globalReturnOriginal != null) {
3517
+ options.returnOriginal = globalReturnOriginal;
3518
+ }
3519
+ }
3520
+
3521
+ const updatePipeline = this?.model?.base?.options?.updatePipeline;
3522
+ if (options.updatePipeline == null && updatePipeline != null) {
3523
+ options.updatePipeline = updatePipeline;
3524
+ }
3525
+
3526
+ if (!options.updatePipeline && Array.isArray(update)) {
3527
+ throw new MongooseError('Cannot pass an array to query updates unless the `updatePipeline` option is set.');
3460
3528
  }
3461
3529
 
3462
3530
  this.setOptions(options);
3463
3531
 
3532
+ // apply doc
3533
+ if (update) {
3534
+ if (this[queryUpdateSymbol] == null || utils.isEmptyObject(this[queryUpdateSymbol])) {
3535
+ this[queryUpdateSymbol] = update;
3536
+ this._updateIsShared = true;
3537
+ } else {
3538
+ this._mergeUpdate(update);
3539
+ }
3540
+ }
3541
+
3464
3542
  return this;
3465
3543
  };
3466
3544
 
@@ -3485,8 +3563,10 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
3485
3563
  throw this.error();
3486
3564
  }
3487
3565
 
3488
- applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
3489
- applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
3566
+ const dbOptions = this.model.db.options;
3567
+ const baseOptions = this.model.base.options;
3568
+ applyGlobalMaxTimeMS(this.options, dbOptions, baseOptions);
3569
+ applyGlobalDiskUse(this.options, dbOptions, baseOptions);
3490
3570
 
3491
3571
  if ('strict' in this.options) {
3492
3572
  this._mongooseOptions.strict = this.options.strict;
@@ -3494,46 +3574,51 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
3494
3574
  const options = this._optionsForExec(this.model);
3495
3575
  convertNewToReturnDocument(options);
3496
3576
 
3497
- this._update = this._castUpdate(this._update);
3577
+ this[queryUpdateSymbol] = this._castUpdate(this[queryUpdateSymbol]);
3578
+ this._updateIsShared = false;
3579
+ decorateUpdateWithVersionKey(this[queryUpdateSymbol], options, this.schema.options.versionKey);
3498
3580
 
3499
- const _opts = Object.assign({}, options, {
3500
- setDefaultsOnInsert: this._mongooseOptions.setDefaultsOnInsert
3501
- });
3502
- this._update = setDefaultsOnInsert(this._conditions, this.model.schema,
3503
- this._update, _opts);
3581
+ this[queryUpdateSymbol] = setDefaultsOnInsert(
3582
+ this._conditions,
3583
+ this.model.schema,
3584
+ this[queryUpdateSymbol],
3585
+ options,
3586
+ this._mongooseOptions,
3587
+ this
3588
+ );
3504
3589
 
3505
- if (!this._update || Object.keys(this._update).length === 0) {
3590
+ if (!this[queryUpdateSymbol] || utils.hasOwnKeys(this[queryUpdateSymbol]) === false) {
3506
3591
  if (options.upsert) {
3507
3592
  // still need to do the upsert to empty doc
3508
- const $set = clone(this._update);
3593
+ const $set = clone(this[queryUpdateSymbol]);
3509
3594
  delete $set._id;
3510
- this._update = { $set };
3595
+ this[queryUpdateSymbol] = { $set };
3511
3596
  } else {
3512
- this._executionStack = null;
3597
+ this._execCount = 0;
3513
3598
  const res = await this._findOne();
3514
3599
  return res;
3515
3600
  }
3516
- } else if (this._update instanceof Error) {
3517
- throw this._update;
3601
+ } else if (this[queryUpdateSymbol] instanceof Error) {
3602
+ throw this[queryUpdateSymbol];
3518
3603
  } else {
3519
3604
  // In order to make MongoDB 2.6 happy (see
3520
3605
  // https://jira.mongodb.org/browse/SERVER-12266 and related issues)
3521
3606
  // if we have an actual update document but $set is empty, junk the $set.
3522
- if (this._update.$set && Object.keys(this._update.$set).length === 0) {
3523
- delete this._update.$set;
3607
+ if (this[queryUpdateSymbol].$set && utils.hasOwnKeys(this[queryUpdateSymbol].$set) === false) {
3608
+ delete this[queryUpdateSymbol].$set;
3524
3609
  }
3525
3610
  }
3526
3611
 
3527
3612
  const runValidators = _getOption(this, 'runValidators', false);
3528
3613
  if (runValidators) {
3529
- await this.validate(this._update, options, false);
3614
+ await this.validate(this[queryUpdateSymbol], options, false);
3530
3615
  }
3531
3616
 
3532
- if (this._update.toBSON) {
3533
- this._update = this._update.toBSON();
3617
+ if (typeof this[queryUpdateSymbol].toBSON === 'function') {
3618
+ this[queryUpdateSymbol] = this[queryUpdateSymbol].toBSON();
3534
3619
  }
3535
3620
 
3536
- let res = await this.mongooseCollection.findOneAndUpdate(this._conditions, this._update, options);
3621
+ let res = await this.mongooseCollection.findOneAndUpdate(this._conditions, this[queryUpdateSymbol], options);
3537
3622
  for (const fn of this._transforms) {
3538
3623
  res = fn(res);
3539
3624
  }
@@ -3572,12 +3657,12 @@ Query.prototype._findOneAndUpdate = async function _findOneAndUpdate() {
3572
3657
  *
3573
3658
  * @method findOneAndDelete
3574
3659
  * @memberOf Query
3575
- * @param {Object} [filter]
3576
- * @param {Object} [options]
3577
- * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3578
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3660
+ * @param {object} [filter]
3661
+ * @param {object} [options]
3662
+ * @param {boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html) rather than just the document
3663
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3579
3664
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3580
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3665
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3581
3666
  * @return {Query} this
3582
3667
  * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3583
3668
  * @api public
@@ -3591,10 +3676,9 @@ Query.prototype.findOneAndDelete = function(filter, options) {
3591
3676
  }
3592
3677
 
3593
3678
  this.op = 'findOneAndDelete';
3594
- this._validateOp();
3595
3679
  this._validate();
3596
3680
 
3597
- if (mquery.canMerge(filter)) {
3681
+ if (canMerge(filter)) {
3598
3682
  this.merge(filter);
3599
3683
  }
3600
3684
 
@@ -3656,7 +3740,7 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
3656
3740
  *
3657
3741
  * - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
3658
3742
  * - `maxTimeMS`: puts a time limit on the query - requires mongodb >= 2.6.0
3659
- * - `includeResultMetadata`: if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3743
+ * - `includeResultMetadata`: if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html) rather than just the document
3660
3744
  * - `requireFilter`: bool - if true, throws an error if the filter is empty (`{}`). Defaults to false.
3661
3745
  *
3662
3746
  * #### Example:
@@ -3667,20 +3751,22 @@ Query.prototype._findOneAndDelete = async function _findOneAndDelete() {
3667
3751
  *
3668
3752
  * @method findOneAndReplace
3669
3753
  * @memberOf Query
3670
- * @param {Object} [filter]
3671
- * @param {Object} [replacement]
3672
- * @param {Object} [options]
3673
- * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3754
+ * @param {object} [filter]
3755
+ * @param {object} [replacement]
3756
+ * @param {object} [options]
3757
+ * @param {boolean} [options.cloneUpdate=true] if `false`, Mongoose will not clone the update before executing the query
3758
+ * @param {boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html) rather than just the document
3674
3759
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3675
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3676
- * @param {Boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied.
3677
- * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3760
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3761
+ * @param {boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied. **Deprecated:** Use `returnDocument: 'after'` instead of `new: true`, or `returnDocument: 'before'` instead of `new: false`.
3762
+ * @param {object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3678
3763
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3679
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3680
- * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3681
- * @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
3682
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3683
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3764
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3765
+ * @param {boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3766
+ * @param {boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`. **Deprecated:** Use `returnDocument: 'after'` instead of `returnOriginal: false`, or `returnDocument: 'before'` instead of `returnOriginal: true`.
3767
+ * @param {'before'|'after'} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
3768
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3769
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
3684
3770
  * @return {Query} this
3685
3771
  * @api public
3686
3772
  */
@@ -3694,10 +3780,9 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options) {
3694
3780
  }
3695
3781
 
3696
3782
  this.op = 'findOneAndReplace';
3697
- this._validateOp();
3698
3783
  this._validate();
3699
3784
 
3700
- if (mquery.canMerge(filter)) {
3785
+ if (canMerge(filter)) {
3701
3786
  this.merge(filter);
3702
3787
  } else if (filter != null) {
3703
3788
  this.error(
@@ -3711,14 +3796,16 @@ Query.prototype.findOneAndReplace = function(filter, replacement, options) {
3711
3796
 
3712
3797
  options = options || {};
3713
3798
 
3714
- const returnOriginal = this &&
3715
- this.model &&
3716
- this.model.base &&
3717
- this.model.base.options &&
3718
- this.model.base.options.returnOriginal;
3719
- if (options.new == null && options.returnDocument == null && options.returnOriginal == null && returnOriginal != null) {
3720
- options.returnOriginal = returnOriginal;
3799
+ const globalReturnDocument = this?.model?.base?.options?.returnDocument;
3800
+ const globalReturnOriginal = this?.model?.base?.options?.returnOriginal;
3801
+ if (options.new == null && options.returnDocument == null && options.returnOriginal == null) {
3802
+ if (globalReturnDocument != null) {
3803
+ options.returnDocument = globalReturnDocument;
3804
+ } else if (globalReturnOriginal != null) {
3805
+ options.returnOriginal = globalReturnOriginal;
3806
+ }
3721
3807
  }
3808
+
3722
3809
  this.setOptions(options);
3723
3810
 
3724
3811
  return this;
@@ -3763,13 +3850,13 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
3763
3850
  const runValidators = _getOption(this, 'runValidators', false);
3764
3851
 
3765
3852
  try {
3766
- const update = new this.model(this._update, null, modelOpts);
3853
+ const update = new this.model(this[queryUpdateSymbol], null, modelOpts);
3767
3854
  if (runValidators) {
3768
3855
  await update.validate();
3769
3856
  } else if (update.$__.validationError) {
3770
3857
  throw update.$__.validationError;
3771
3858
  }
3772
- this._update = update.toBSON();
3859
+ this[queryUpdateSymbol] = update.toBSON();
3773
3860
  } catch (err) {
3774
3861
  if (err instanceof ValidationError) {
3775
3862
  throw err;
@@ -3779,7 +3866,7 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
3779
3866
  throw validationError;
3780
3867
  }
3781
3868
 
3782
- let res = await this.mongooseCollection.findOneAndReplace(filter, this._update, options);
3869
+ let res = await this.mongooseCollection.findOneAndReplace(filter, this[queryUpdateSymbol], options);
3783
3870
 
3784
3871
  for (const fn of this._transforms) {
3785
3872
  res = fn(res);
@@ -3809,10 +3896,10 @@ Query.prototype._findOneAndReplace = async function _findOneAndReplace() {
3809
3896
  * @method findById
3810
3897
  * @memberOf Query
3811
3898
  * @instance
3812
- * @param {Any} id value of `_id` to query by
3813
- * @param {Object} [projection] optional fields to return
3814
- * @param {Object} [options] see [`setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3815
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3899
+ * @param {any} id value of `_id` to query by
3900
+ * @param {object} [projection] optional fields to return
3901
+ * @param {object} [options] see [`setOptions()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions())
3902
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3816
3903
  * @return {Query} this
3817
3904
  * @see findOne https://www.mongodb.com/docs/manual/reference/method/db.collection.findOne/
3818
3905
  * @see Query.select https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
@@ -3838,24 +3925,26 @@ Query.prototype.findById = function(id, projection, options) {
3838
3925
  * @method findByIdAndUpdate
3839
3926
  * @memberOf Query
3840
3927
  * @instance
3841
- * @param {Any} id value of `_id` to query by
3842
- * @param {Object} [doc]
3843
- * @param {Object} [options]
3844
- * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3845
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3928
+ * @param {any} id value of `_id` to query by
3929
+ * @param {object} [doc]
3930
+ * @param {object} [options]
3931
+ * @param {boolean} [options.cloneUpdate=true] if `false`, Mongoose will not clone the update before executing the query
3932
+ * @param {boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html) rather than just the document
3933
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3846
3934
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3847
- * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3848
- * @param {Boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied.
3849
- * @param {Object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3850
- * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3851
- * @param {Boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`.
3852
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3853
- * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3854
- * @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
3935
+ * @param {boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
3936
+ * @param {boolean} [options.new=false] By default, `findOneAndUpdate()` returns the document as it was **before** `update` was applied. If you set `new: true`, `findOneAndUpdate()` will instead give you the object after `update` was applied. **Deprecated:** Use `returnDocument: 'after'` instead of `new: true`, or `returnDocument: 'before'` instead of `new: false`.
3937
+ * @param {object} [options.lean] if truthy, mongoose will return the document as a plain JavaScript object rather than a mongoose document. See [`Query.lean()`](https://mongoosejs.com/docs/api/query.html#Query.prototype.lean()) and [the Mongoose lean tutorial](https://mongoosejs.com/docs/tutorials/lean.html).
3938
+ * @param {boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
3939
+ * @param {boolean} [options.returnOriginal=null] An alias for the `new` option. `returnOriginal: false` is equivalent to `new: true`. **Deprecated:** Use `returnDocument: 'after'` instead of `returnOriginal: false`, or `returnDocument: 'before'` instead of `returnOriginal: true`.
3940
+ * @param {'before'|'after'} [options.returnDocument='before'] Has two possible values, `'before'` and `'after'`. By default, it will return the document before the update was applied.
3941
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
3942
+ * @param {boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
3943
+ * @param {boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
3855
3944
  * @see Tutorial https://mongoosejs.com/docs/tutorials/findoneandupdate.html
3856
3945
  * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3857
- * @see ModifyResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html
3858
- * @see findOneAndUpdate https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#findOneAndUpdate
3946
+ * @see ModifyResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html
3947
+ * @see findOneAndUpdate https://mongodb.github.io/node-mongodb-native/7.0/classes/Collection.html#findOneAndUpdate
3859
3948
  * @return {Query} this
3860
3949
  * @api public
3861
3950
  */
@@ -3876,10 +3965,10 @@ Query.prototype.findByIdAndUpdate = function(id, update, options) {
3876
3965
  * @method findByIdAndDelete
3877
3966
  * @memberOf Query
3878
3967
  * @param {any} id value of `_id` to query by
3879
- * @param {Object} [options]
3880
- * @param {Boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/ModifyResult.html) rather than just the document
3968
+ * @param {object} [options]
3969
+ * @param {boolean} [options.includeResultMetadata] if true, returns the full [ModifyResult from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/7.0/interfaces/ModifyResult.html) rather than just the document
3881
3970
  * @param {ClientSession} [options.session=null] The session associated with this query. See [transactions docs](https://mongoosejs.com/docs/transactions.html).
3882
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3971
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
3883
3972
  * @return {Query} this
3884
3973
  * @see findAndModify command https://www.mongodb.com/docs/manual/reference/command/findAndModify/
3885
3974
  * @api public
@@ -3897,10 +3986,20 @@ Query.prototype.findByIdAndDelete = function(id, options) {
3897
3986
 
3898
3987
  function convertNewToReturnDocument(options) {
3899
3988
  if ('new' in options) {
3989
+ const replacement = options['new'] ? '\'after\'' : '\'before\'';
3990
+ utils.warn(
3991
+ 'mongoose: the `new` option for `findOneAndUpdate()` and `findOneAndReplace()` is deprecated. ' +
3992
+ 'Use `returnDocument: ' + replacement + '` instead.'
3993
+ );
3900
3994
  options.returnDocument = options['new'] ? 'after' : 'before';
3901
3995
  delete options['new'];
3902
3996
  }
3903
3997
  if ('returnOriginal' in options) {
3998
+ const replacement = options['returnOriginal'] ? '\'before\'' : '\'after\'';
3999
+ utils.warn(
4000
+ 'mongoose: the `returnOriginal` option for `findOneAndUpdate()` and `findOneAndReplace()` is deprecated. ' +
4001
+ 'Use `returnDocument: ' + replacement + '` instead.'
4002
+ );
3904
4003
  options.returnDocument = options['returnOriginal'] ? 'before' : 'after';
3905
4004
  delete options['returnOriginal'];
3906
4005
  }
@@ -3913,8 +4012,8 @@ function convertNewToReturnDocument(options) {
3913
4012
  /**
3914
4013
  * Get options from query opts, falling back to the base mongoose object.
3915
4014
  * @param {Query} query
3916
- * @param {Object} option
3917
- * @param {Any} def
4015
+ * @param {object} option
4016
+ * @param {any} def
3918
4017
  * @api private
3919
4018
  */
3920
4019
 
@@ -3997,104 +4096,76 @@ function _completeManyLean(schema, docs, path, opts) {
3997
4096
  * Override mquery.prototype._mergeUpdate to handle mongoose objects in
3998
4097
  * updates.
3999
4098
  *
4000
- * @param {Object} doc
4099
+ * @param {object} update
4001
4100
  * @method _mergeUpdate
4002
4101
  * @memberOf Query
4003
4102
  * @instance
4004
4103
  * @api private
4005
4104
  */
4006
4105
 
4007
- Query.prototype._mergeUpdate = function(doc) {
4008
- if (!this._update) {
4009
- this._update = Array.isArray(doc) ? [] : {};
4106
+ Query.prototype._mergeUpdate = function(update) {
4107
+ _cloneUpdateIfShared(this);
4108
+
4109
+ const updatePipeline = this._mongooseOptions.updatePipeline;
4110
+ if (!updatePipeline && Array.isArray(update)) {
4111
+ throw new MongooseError('Cannot pass an array to query updates unless the `updatePipeline` option is set.');
4112
+ }
4113
+ if (!this[queryUpdateSymbol]) {
4114
+ this[queryUpdateSymbol] = Array.isArray(update) ? [] : {};
4010
4115
  }
4011
4116
 
4012
- if (doc == null || (typeof doc === 'object' && Object.keys(doc).length === 0)) {
4117
+ if (update == null || (typeof update === 'object' && utils.hasOwnKeys(update) === false)) {
4013
4118
  return;
4014
4119
  }
4015
4120
 
4016
- if (doc instanceof Query) {
4017
- if (Array.isArray(this._update)) {
4018
- throw new Error('Cannot mix array and object updates');
4121
+ if (update instanceof Query) {
4122
+ if (Array.isArray(this[queryUpdateSymbol])) {
4123
+ throw new MongooseError(`Cannot mix array and object updates (current: ${_previewUpdate(this[queryUpdateSymbol])}, incoming: ${_previewUpdate(update[queryUpdateSymbol])})`);
4019
4124
  }
4020
- if (doc._update) {
4021
- utils.mergeClone(this._update, doc._update);
4125
+ if (update[queryUpdateSymbol]) {
4126
+ utils.mergeClone(this[queryUpdateSymbol], update[queryUpdateSymbol]);
4022
4127
  }
4023
- } else if (Array.isArray(doc)) {
4024
- if (!Array.isArray(this._update)) {
4025
- throw new Error('Cannot mix array and object updates');
4128
+ } else if (Array.isArray(update)) {
4129
+ if (!Array.isArray(this[queryUpdateSymbol])) {
4130
+ // `_update` may be empty object by default, like in `doc.updateOne()`
4131
+ // because we create the query first, then run hooks, then apply the update.
4132
+ if (this[queryUpdateSymbol] == null || utils.isEmptyObject(this[queryUpdateSymbol])) {
4133
+ this[queryUpdateSymbol] = [];
4134
+ } else {
4135
+ throw new MongooseError(`Cannot mix array and object updates (current: ${_previewUpdate(this[queryUpdateSymbol])}, incoming: ${_previewUpdate(update)})`);
4136
+ }
4026
4137
  }
4027
- this._update = this._update.concat(doc);
4138
+ this[queryUpdateSymbol] = this[queryUpdateSymbol].concat(update);
4028
4139
  } else {
4029
- if (Array.isArray(this._update)) {
4030
- throw new Error('Cannot mix array and object updates');
4140
+ if (Array.isArray(this[queryUpdateSymbol])) {
4141
+ throw new MongooseError(`Cannot mix array and object updates (current: ${_previewUpdate(this[queryUpdateSymbol])}, incoming: ${_previewUpdate(update)})`);
4031
4142
  }
4032
- utils.mergeClone(this._update, doc);
4143
+ utils.mergeClone(this[queryUpdateSymbol], update);
4033
4144
  }
4034
4145
  };
4035
4146
 
4036
- /*!
4037
- * ignore
4038
- */
4039
-
4040
- async function _updateThunk(op) {
4041
- this._applyTranslateAliases();
4042
-
4043
- this._castConditions();
4044
-
4045
- // Check for empty/invalid filter with requireFilter option
4046
- checkRequireFilter(this._conditions, this.options);
4047
-
4048
- _castArrayFilters(this);
4049
-
4050
- if (this.error() != null) {
4051
- throw this.error();
4052
- }
4053
-
4054
- const castedQuery = this._conditions;
4055
- const options = this._optionsForExec(this.model);
4056
-
4057
- this._update = clone(this._update, options);
4058
- const isOverwriting = op === 'replaceOne';
4059
- if (isOverwriting) {
4060
- this._update = new this.model(this._update, null, true);
4061
- } else {
4062
- this._update = this._castUpdate(this._update);
4063
-
4064
- if (this._update == null || Object.keys(this._update).length === 0) {
4065
- return { acknowledged: false };
4066
- }
4067
-
4068
- const _opts = Object.assign({}, options, {
4069
- setDefaultsOnInsert: this._mongooseOptions.setDefaultsOnInsert
4070
- });
4071
- this._update = setDefaultsOnInsert(this._conditions, this.model.schema,
4072
- this._update, _opts);
4073
- }
4074
-
4075
- if (Array.isArray(options.arrayFilters)) {
4076
- options.arrayFilters = removeUnusedArrayFilters(this._update, options.arrayFilters);
4077
- }
4078
-
4079
- const runValidators = _getOption(this, 'runValidators', false);
4080
- if (runValidators) {
4081
- await this.validate(this._update, options, isOverwriting);
4082
- }
4147
+ function _previewUpdate(update) {
4148
+ const preview = util.inspect(update, {
4149
+ depth: 2,
4150
+ maxArrayLength: 5,
4151
+ breakLength: 80,
4152
+ compact: true
4153
+ });
4083
4154
 
4084
- if (this._update.toBSON) {
4085
- this._update = this._update.toBSON();
4155
+ if (preview.length > 200) {
4156
+ return `${preview.slice(0, 197)}...`;
4086
4157
  }
4087
4158
 
4088
- return this.mongooseCollection[op](castedQuery, this._update, options);
4159
+ return preview;
4089
4160
  }
4090
4161
 
4091
4162
  /**
4092
4163
  * Mongoose calls this function internally to validate the query if
4093
4164
  * `runValidators` is set
4094
4165
  *
4095
- * @param {Object} castedDoc the update, after casting
4096
- * @param {Object} options the options from `_optionsForExec()`
4097
- * @param {Boolean} isOverwriting
4166
+ * @param {object} castedDoc the update, after casting
4167
+ * @param {object} options the options from `_optionsForExec()`
4168
+ * @param {boolean} isOverwriting
4098
4169
  * @method validate
4099
4170
  * @memberOf Query
4100
4171
  * @instance
@@ -4111,14 +4182,14 @@ Query.prototype.validate = async function validate(castedDoc, options, isOverwri
4111
4182
  if (isOverwriting) {
4112
4183
  await castedDoc.$validate();
4113
4184
  } else {
4114
- await new Promise((resolve, reject) => {
4115
- updateValidators(this, this.model.schema, castedDoc, options, (err) => {
4116
- if (err != null) {
4117
- return reject(err);
4118
- }
4119
- resolve();
4120
- });
4121
- });
4185
+ const validationErrors = await updateValidators(this, this.model.schema, castedDoc, options);
4186
+ if (validationErrors.length > 0) {
4187
+ const err = new ValidationError(null);
4188
+ for (const validationError of validationErrors) {
4189
+ err.addError(validationError.path, validationError);
4190
+ }
4191
+ throw err;
4192
+ }
4122
4193
  }
4123
4194
 
4124
4195
  await _executePostHooks(this, null, null, 'validate');
@@ -4134,7 +4205,40 @@ Query.prototype.validate = async function validate(castedDoc, options, isOverwri
4134
4205
  * @api private
4135
4206
  */
4136
4207
  Query.prototype._updateMany = async function _updateMany() {
4137
- return _updateThunk.call(this, 'updateMany');
4208
+ this._applyTranslateAliases();
4209
+ this._castConditions();
4210
+ checkRequireFilter(this._conditions, this.options);
4211
+ _castArrayFilters(this);
4212
+ if (this.error() != null) {
4213
+ throw this.error();
4214
+ }
4215
+
4216
+ const options = this._optionsForExec(this.model);
4217
+ _cloneUpdateIfShared(this);
4218
+ this[queryUpdateSymbol] = this._castUpdate(this[queryUpdateSymbol]);
4219
+ if (this[queryUpdateSymbol] == null || utils.hasOwnKeys(this[queryUpdateSymbol]) === false) {
4220
+ return { acknowledged: false };
4221
+ }
4222
+ removeUnusedArrayFilters(this[queryUpdateSymbol], options);
4223
+
4224
+ this[queryUpdateSymbol] = setDefaultsOnInsert(
4225
+ this._conditions,
4226
+ this.model.schema,
4227
+ this[queryUpdateSymbol],
4228
+ options,
4229
+ this._mongooseOptions,
4230
+ this
4231
+ );
4232
+
4233
+ if (_getOption(this, 'runValidators', false)) {
4234
+ await this.validate(this[queryUpdateSymbol], options, false);
4235
+ }
4236
+
4237
+ if (typeof this[queryUpdateSymbol].toBSON === 'function') {
4238
+ this[queryUpdateSymbol] = this[queryUpdateSymbol].toBSON();
4239
+ }
4240
+
4241
+ return this.mongooseCollection.updateMany(this._conditions, this[queryUpdateSymbol], options);
4138
4242
  };
4139
4243
 
4140
4244
  /**
@@ -4147,7 +4251,40 @@ Query.prototype._updateMany = async function _updateMany() {
4147
4251
  * @api private
4148
4252
  */
4149
4253
  Query.prototype._updateOne = async function _updateOne() {
4150
- return _updateThunk.call(this, 'updateOne');
4254
+ this._applyTranslateAliases();
4255
+ this._castConditions();
4256
+ checkRequireFilter(this._conditions, this.options);
4257
+ _castArrayFilters(this);
4258
+ if (this.error() != null) {
4259
+ throw this.error();
4260
+ }
4261
+
4262
+ const options = this._optionsForExec(this.model);
4263
+ _cloneUpdateIfShared(this);
4264
+ this[queryUpdateSymbol] = this._castUpdate(this[queryUpdateSymbol]);
4265
+ if (this[queryUpdateSymbol] == null || utils.hasOwnKeys(this[queryUpdateSymbol]) === false) {
4266
+ return { acknowledged: false };
4267
+ }
4268
+ removeUnusedArrayFilters(this[queryUpdateSymbol], options);
4269
+
4270
+ this[queryUpdateSymbol] = setDefaultsOnInsert(
4271
+ this._conditions,
4272
+ this.model.schema,
4273
+ this[queryUpdateSymbol],
4274
+ options,
4275
+ this._mongooseOptions,
4276
+ this
4277
+ );
4278
+
4279
+ if (_getOption(this, 'runValidators', false)) {
4280
+ await this.validate(this[queryUpdateSymbol], options, false);
4281
+ }
4282
+
4283
+ if (typeof this[queryUpdateSymbol].toBSON === 'function') {
4284
+ this[queryUpdateSymbol] = this[queryUpdateSymbol].toBSON();
4285
+ }
4286
+
4287
+ return this.mongooseCollection.updateOne(this._conditions, this[queryUpdateSymbol], options);
4151
4288
  };
4152
4289
 
4153
4290
  /**
@@ -4160,7 +4297,27 @@ Query.prototype._updateOne = async function _updateOne() {
4160
4297
  * @api private
4161
4298
  */
4162
4299
  Query.prototype._replaceOne = async function _replaceOne() {
4163
- return _updateThunk.call(this, 'replaceOne');
4300
+ this._applyTranslateAliases();
4301
+ this._castConditions();
4302
+ checkRequireFilter(this._conditions, this.options);
4303
+ _castArrayFilters(this);
4304
+ if (this.error() != null) {
4305
+ throw this.error();
4306
+ }
4307
+
4308
+ const options = this._optionsForExec(this.model);
4309
+ this[queryUpdateSymbol] = new this.model(this[queryUpdateSymbol], null, { skipId: true });
4310
+ removeUnusedArrayFilters(this[queryUpdateSymbol], options);
4311
+
4312
+ if (_getOption(this, 'runValidators', false)) {
4313
+ await this.validate(this[queryUpdateSymbol], options, true);
4314
+ }
4315
+
4316
+ if (typeof this[queryUpdateSymbol].toBSON === 'function') {
4317
+ this[queryUpdateSymbol] = this[queryUpdateSymbol].toBSON();
4318
+ }
4319
+
4320
+ return this.mongooseCollection.replaceOne(this._conditions, this[queryUpdateSymbol], options);
4164
4321
  };
4165
4322
 
4166
4323
  /**
@@ -4184,23 +4341,24 @@ Query.prototype._replaceOne = async function _replaceOne() {
4184
4341
  *
4185
4342
  * - `updateMany()`
4186
4343
  *
4187
- * @param {Object} [filter]
4188
- * @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
4189
- * @param {Object} [options]
4190
- * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
4191
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
4192
- * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
4193
- * @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
4194
- * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
4195
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
4196
- * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
4197
- * @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
4198
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
4344
+ * @param {object} [filter]
4345
+ * @param {object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
4346
+ * @param {object} [options]
4347
+ * @param {boolean} [options.cloneUpdate=true] if `false`, Mongoose will not clone the update before executing the query
4348
+ * @param {boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
4349
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
4350
+ * @param {boolean} [options.upsert=false] if true, and no documents found, insert a new document
4351
+ * @param {object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
4352
+ * @param {boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
4353
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
4354
+ * @param {boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
4355
+ * @param {boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
4356
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
4199
4357
  * @return {Query} this
4200
4358
  * @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
4201
4359
  * @see Query docs https://mongoosejs.com/docs/queries.html
4202
4360
  * @see update https://www.mongodb.com/docs/manual/reference/method/db.collection.update/
4203
- * @see UpdateResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/UpdateResult.html
4361
+ * @see UpdateResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/UpdateResult.html
4204
4362
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
4205
4363
  * @api public
4206
4364
  */
@@ -4209,13 +4367,13 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
4209
4367
  if (typeof options === 'function') {
4210
4368
  // .update(conditions, doc, callback)
4211
4369
  callback = options;
4212
- options = null;
4370
+ options = undefined;
4213
4371
  } else if (typeof doc === 'function') {
4214
4372
  // .update(doc, callback);
4215
4373
  callback = doc;
4216
4374
  doc = conditions;
4217
4375
  conditions = {};
4218
- options = null;
4376
+ options = undefined;
4219
4377
  } else if (typeof conditions === 'function') {
4220
4378
  // .update(callback)
4221
4379
  callback = conditions;
@@ -4259,23 +4417,24 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
4259
4417
  *
4260
4418
  * - `updateOne()`
4261
4419
  *
4262
- * @param {Object} [filter]
4263
- * @param {Object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
4264
- * @param {Object} [options]
4265
- * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
4266
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
4267
- * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
4268
- * @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
4269
- * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
4270
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
4271
- * @param {Boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
4272
- * @param {Boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
4273
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
4420
+ * @param {object} [filter]
4421
+ * @param {object|Array} [update] the update command. If array, this update will be treated as an update pipeline and not casted.
4422
+ * @param {object} [options]
4423
+ * @param {boolean} [options.cloneUpdate=true] if `false`, Mongoose will not clone the update before executing the query
4424
+ * @param {boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
4425
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
4426
+ * @param {boolean} [options.upsert=false] if true, and no documents found, insert a new document
4427
+ * @param {object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
4428
+ * @param {boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Note that this allows you to overwrite timestamps. Does nothing if schema-level timestamps are not set.
4429
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
4430
+ * @param {boolean} [options.overwriteDiscriminatorKey=false] Mongoose removes discriminator key updates from `update` by default, set `overwriteDiscriminatorKey` to `true` to allow updating the discriminator key
4431
+ * @param {boolean} [options.overwriteImmutable=false] Mongoose removes updated immutable properties from `update` by default (excluding $setOnInsert). Set `overwriteImmutable` to `true` to allow updating immutable properties using other update operators.
4432
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
4274
4433
  * @return {Query} this
4275
4434
  * @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
4276
4435
  * @see Query docs https://mongoosejs.com/docs/queries.html
4277
4436
  * @see update https://www.mongodb.com/docs/manual/reference/method/db.collection.update/
4278
- * @see UpdateResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/UpdateResult.html
4437
+ * @see UpdateResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/UpdateResult.html
4279
4438
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
4280
4439
  * @api public
4281
4440
  */
@@ -4284,13 +4443,13 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
4284
4443
  if (typeof options === 'function') {
4285
4444
  // .update(conditions, doc, callback)
4286
4445
  callback = options;
4287
- options = null;
4446
+ options = undefined;
4288
4447
  } else if (typeof doc === 'function') {
4289
4448
  // .update(doc, callback);
4290
4449
  callback = doc;
4291
4450
  doc = conditions;
4292
4451
  conditions = {};
4293
- options = null;
4452
+ options = undefined;
4294
4453
  } else if (typeof conditions === 'function') {
4295
4454
  // .update(callback)
4296
4455
  callback = conditions;
@@ -4328,21 +4487,22 @@ Query.prototype.updateOne = function(conditions, doc, options, callback) {
4328
4487
  *
4329
4488
  * - `replaceOne()`
4330
4489
  *
4331
- * @param {Object} [filter]
4332
- * @param {Object} [doc] the update command
4333
- * @param {Object} [options]
4334
- * @param {Boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
4335
- * @param {Boolean|String} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
4336
- * @param {Boolean} [options.upsert=false] if true, and no documents found, insert a new document
4337
- * @param {Object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
4338
- * @param {Boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
4339
- * @param {Boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
4340
- * @param {Boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
4490
+ * @param {object} [filter]
4491
+ * @param {object} [doc] the update command
4492
+ * @param {object} [options]
4493
+ * @param {boolean} [options.cloneUpdate=true] if `false`, Mongoose will not clone the update before executing the query
4494
+ * @param {boolean} [options.multipleCastError] by default, mongoose only returns the first error that occurred in casting the query. Turn on this option to aggregate all the cast errors.
4495
+ * @param {boolean|'throw'} [options.strict] overwrites the schema's [strict mode option](https://mongoosejs.com/docs/guide.html#strict)
4496
+ * @param {boolean} [options.upsert=false] if true, and no documents found, insert a new document
4497
+ * @param {object} [options.writeConcern=null] sets the [write concern](https://www.mongodb.com/docs/manual/reference/write-concern/) for replica sets. Overrides the [schema-level write concern](https://mongoosejs.com/docs/guide.html#writeConcern)
4498
+ * @param {boolean} [options.timestamps=null] If set to `false` and [schema-level timestamps](https://mongoosejs.com/docs/guide.html#timestamps) are enabled, skip timestamps for this update. Does nothing if schema-level timestamps are not set.
4499
+ * @param {boolean} [options.translateAliases=null] If set to `true`, translates any schema-defined aliases in `filter`, `projection`, `update`, and `distinct`. Throws an error if there are any conflicts where both alias and raw property are defined on the same object.
4500
+ * @param {boolean} [options.requireFilter=false] If true, throws an error if the filter is empty (`{}`)
4341
4501
  * @return {Query} this
4342
4502
  * @see Model.update https://mongoosejs.com/docs/api/model.html#Model.update()
4343
4503
  * @see Query docs https://mongoosejs.com/docs/queries.html
4344
4504
  * @see update https://www.mongodb.com/docs/manual/reference/method/db.collection.update/
4345
- * @see UpdateResult https://mongodb.github.io/node-mongodb-native/4.9/interfaces/UpdateResult.html
4505
+ * @see UpdateResult https://mongodb.github.io/node-mongodb-native/7.0/interfaces/UpdateResult.html
4346
4506
  * @see MongoDB docs https://www.mongodb.com/docs/manual/reference/command/update/#update-command-output
4347
4507
  * @api public
4348
4508
  */
@@ -4351,13 +4511,13 @@ Query.prototype.replaceOne = function(conditions, doc, options, callback) {
4351
4511
  if (typeof options === 'function') {
4352
4512
  // .update(conditions, doc, callback)
4353
4513
  callback = options;
4354
- options = null;
4514
+ options = undefined;
4355
4515
  } else if (typeof doc === 'function') {
4356
4516
  // .update(doc, callback);
4357
4517
  callback = doc;
4358
4518
  doc = conditions;
4359
4519
  conditions = {};
4360
- options = null;
4520
+ options = undefined;
4361
4521
  } else if (typeof conditions === 'function') {
4362
4522
  // .update(callback)
4363
4523
  callback = conditions;
@@ -4378,10 +4538,10 @@ Query.prototype.replaceOne = function(conditions, doc, options, callback) {
4378
4538
  /**
4379
4539
  * Internal helper for update, updateMany, updateOne, replaceOne
4380
4540
  * @param {Query} query
4381
- * @param {String} op
4382
- * @param {Object} filter
4541
+ * @param {string} op
4542
+ * @param {object} filter
4383
4543
  * @param {Document} [doc]
4384
- * @param {Object} [options]
4544
+ * @param {object} [options]
4385
4545
  * @param {Function} callback
4386
4546
  * @api private
4387
4547
  */
@@ -4389,7 +4549,6 @@ Query.prototype.replaceOne = function(conditions, doc, options, callback) {
4389
4549
  function _update(query, op, filter, doc, options, callback) {
4390
4550
  // make sure we don't send in the whole Document to merge()
4391
4551
  query.op = op;
4392
- query._validateOp();
4393
4552
  doc = doc || {};
4394
4553
 
4395
4554
  // strict is an option used in the update checking, make sure it gets set
@@ -4407,11 +4566,26 @@ function _update(query, op, filter, doc, options, callback) {
4407
4566
  query.merge(filter);
4408
4567
  }
4409
4568
 
4569
+ const updatePipeline = query?.model?.base?.options?.updatePipeline;
4570
+ if (updatePipeline != null && options?.updatePipeline == null) {
4571
+ options = options || {};
4572
+ options.updatePipeline = updatePipeline;
4573
+ }
4574
+
4575
+ if (!options?.updatePipeline && Array.isArray(doc)) {
4576
+ throw new MongooseError('Cannot pass an array to query updates unless the `updatePipeline` option is set.');
4577
+ }
4578
+
4410
4579
  if (utils.isObject(options)) {
4411
4580
  query.setOptions(options);
4412
4581
  }
4413
4582
 
4414
- query._mergeUpdate(doc);
4583
+ if (query[queryUpdateSymbol] == null || utils.isEmptyObject(query[queryUpdateSymbol])) {
4584
+ query[queryUpdateSymbol] = doc;
4585
+ query._updateIsShared = true;
4586
+ } else {
4587
+ query._mergeUpdate(doc);
4588
+ }
4415
4589
 
4416
4590
  // Hooks
4417
4591
  if (callback) {
@@ -4497,7 +4671,7 @@ Query.prototype.orFail = function(err) {
4497
4671
  case 'replaceOne':
4498
4672
  case 'updateMany':
4499
4673
  case 'updateOne':
4500
- if (res && res.matchedCount === 0) {
4674
+ if (res?.matchedCount === 0) {
4501
4675
  throw _orFailError(err, this);
4502
4676
  }
4503
4677
  break;
@@ -4547,8 +4721,8 @@ function _orFailError(err, query) {
4547
4721
 
4548
4722
  /**
4549
4723
  * Wrapper function to call isPathSelectedInclusive on a query.
4550
- * @param {String} path
4551
- * @return {Boolean}
4724
+ * @param {string} path
4725
+ * @return {boolean}
4552
4726
  * @api public
4553
4727
  */
4554
4728
 
@@ -4564,7 +4738,7 @@ Query.prototype.isPathSelectedInclusive = function(path) {
4564
4738
  * const promise = query.exec();
4565
4739
  * const promise = query.exec('update');
4566
4740
  *
4567
- * @param {String|Function} [operation]
4741
+ * @param {string|Function} [operation]
4568
4742
  * @return {Promise}
4569
4743
  * @api public
4570
4744
  */
@@ -4574,6 +4748,7 @@ Query.prototype.exec = async function exec(op) {
4574
4748
  throw new MongooseError('Query.prototype.exec() no longer accepts a callback');
4575
4749
  }
4576
4750
 
4751
+ this._validateOp();
4577
4752
  if (typeof op === 'string') {
4578
4753
  this.op = op;
4579
4754
  }
@@ -4590,27 +4765,22 @@ Query.prototype.exec = async function exec(op) {
4590
4765
  throw new MongooseError('Query has invalid `op`: "' + this.op + '"');
4591
4766
  }
4592
4767
 
4593
- if (this.options && this.options.sort && typeof this.options.sort === 'object' && Object.hasOwn(this.options.sort, '')) {
4594
- throw new Error('Invalid field "" passed to sort()');
4768
+ if (this.options?.sort && typeof this.options.sort === 'object' && Object.hasOwn(this.options.sort, '')) {
4769
+ throw new MongooseError('Invalid field "" passed to sort()');
4595
4770
  }
4596
4771
 
4597
- if (this._executionStack != null) {
4772
+ if (this._execCount > 0) {
4598
4773
  let str = this.toString();
4599
4774
  if (str.length > 60) {
4600
4775
  str = str.slice(0, 60) + '...';
4601
4776
  }
4602
- const err = new MongooseError('Query was already executed: ' + str);
4603
- if (!this.model.base.options.skipOriginalStackTraces) {
4604
- err.originalStack = this._executionStack;
4605
- }
4606
- throw err;
4607
- } else {
4608
- this._executionStack = this.model.base.options.skipOriginalStackTraces ? true : new Error().stack;
4777
+ throw new MongooseError('Query was already executed: ' + str);
4609
4778
  }
4779
+ this._execCount++;
4610
4780
 
4611
4781
  let skipWrappedFunction = null;
4612
4782
  try {
4613
- await _executePreExecHooks(this);
4783
+ await this._hooks.execPre('exec', this, []);
4614
4784
  } catch (err) {
4615
4785
  if (err instanceof Kareem.skipWrappedFunction) {
4616
4786
  skipWrappedFunction = err;
@@ -4641,7 +4811,7 @@ Query.prototype.exec = async function exec(op) {
4641
4811
 
4642
4812
  res = await _executePostHooks(this, res, error);
4643
4813
 
4644
- await _executePostExecHooks(this);
4814
+ await this._hooks.execPost('exec', this, []);
4645
4815
 
4646
4816
  return res;
4647
4817
  };
@@ -4650,56 +4820,27 @@ Query.prototype.exec = async function exec(op) {
4650
4820
  * ignore
4651
4821
  */
4652
4822
 
4653
- function _executePostExecHooks(query) {
4654
- return new Promise((resolve, reject) => {
4655
- query._hooks.execPost('exec', query, [], {}, (error) => {
4656
- if (error) {
4657
- return reject(error);
4658
- }
4659
-
4660
- resolve();
4661
- });
4662
- });
4663
- }
4664
-
4665
- /*!
4666
- * ignore
4667
- */
4668
-
4669
- function _executePostHooks(query, res, error, op) {
4823
+ async function _executePostHooks(query, res, error, op) {
4670
4824
  if (query._queryMiddleware == null) {
4671
4825
  if (error != null) {
4672
4826
  throw error;
4673
4827
  }
4674
4828
  return res;
4675
4829
  }
4830
+ const filter = buildMiddlewareFilter(query.options, 'post');
4831
+ const opts = { filter };
4832
+ if (error) {
4833
+ opts.error = error;
4834
+ }
4676
4835
 
4677
- return new Promise((resolve, reject) => {
4678
- const opts = error ? { error } : {};
4679
-
4680
- query._queryMiddleware.execPost(op || query.op, query, [res], opts, (error, res) => {
4681
- if (error) {
4682
- return reject(error);
4683
- }
4684
-
4685
- resolve(res);
4686
- });
4687
- });
4688
- }
4689
-
4690
- /*!
4691
- * ignore
4692
- */
4693
-
4694
- function _executePreExecHooks(query) {
4695
- return new Promise((resolve, reject) => {
4696
- query._hooks.execPre('exec', query, [], (error) => {
4697
- if (error != null) {
4698
- return reject(error);
4699
- }
4700
- resolve();
4701
- });
4702
- });
4836
+ // `result` is array of return args, but queries only return one result.
4837
+ const [result] = await query._queryMiddleware.execPost(
4838
+ op || query.op,
4839
+ query,
4840
+ [res],
4841
+ opts
4842
+ );
4843
+ return result;
4703
4844
  }
4704
4845
 
4705
4846
  /*!
@@ -4710,15 +4851,27 @@ function _executePreHooks(query, op) {
4710
4851
  if (query._queryMiddleware == null) {
4711
4852
  return;
4712
4853
  }
4854
+ const filter = buildMiddlewareFilter(query.options, 'pre');
4855
+ return query._queryMiddleware.execPre(
4856
+ op || query.op,
4857
+ query,
4858
+ [],
4859
+ { filter }
4860
+ );
4861
+ }
4713
4862
 
4714
- return new Promise((resolve, reject) => {
4715
- query._queryMiddleware.execPre(op || query.op, query, [], (error) => {
4716
- if (error != null) {
4717
- return reject(error);
4718
- }
4719
- resolve();
4720
- });
4863
+ function _cloneUpdateIfShared(query) {
4864
+ if (!query._updateIsShared) {
4865
+ return;
4866
+ }
4867
+ if (query.mongooseOptions().cloneUpdate === false) {
4868
+ return;
4869
+ }
4870
+
4871
+ query[queryUpdateSymbol] = clone(query[queryUpdateSymbol], {
4872
+ flattenDecimals: false
4721
4873
  });
4874
+ query._updateIsShared = false;
4722
4875
  }
4723
4876
 
4724
4877
  /**
@@ -4777,7 +4930,7 @@ Query.prototype.finally = function(onFinally) {
4777
4930
  * const q = Model.find();
4778
4931
  * console.log(q); // Prints "Query { find }"
4779
4932
  *
4780
- * @return {String}
4933
+ * @return {string}
4781
4934
  * @api public
4782
4935
  * @method [Symbol.toStringTag]
4783
4936
  * @memberOf Query
@@ -4842,8 +4995,8 @@ Query.prototype.post = function(fn) {
4842
4995
  /**
4843
4996
  * Casts obj for an update command.
4844
4997
  *
4845
- * @param {Object} obj
4846
- * @return {Object} obj after casting its values
4998
+ * @param {object} obj
4999
+ * @return {object} obj after casting its values
4847
5000
  * @method _castUpdate
4848
5001
  * @memberOf Query
4849
5002
  * @instance
@@ -4854,7 +5007,7 @@ Query.prototype._castUpdate = function _castUpdate(obj) {
4854
5007
  let schema = this.schema;
4855
5008
 
4856
5009
  const discriminatorKey = schema.options.discriminatorKey;
4857
- const baseSchema = schema._baseSchema ? schema._baseSchema : schema;
5010
+ const baseSchema = schema._baseSchema || schema;
4858
5011
  if (this._mongooseOptions.overwriteDiscriminatorKey &&
4859
5012
  obj[discriminatorKey] != null &&
4860
5013
  baseSchema.discriminators) {
@@ -4913,18 +5066,18 @@ Query.prototype._castUpdate = function _castUpdate(obj) {
4913
5066
  * a response for each query has also been returned, the results are passed to
4914
5067
  * the callback.
4915
5068
  *
4916
- * @param {Object|String|String[]} path either the path(s) to populate or an object specifying all parameters
4917
- * @param {Object|String} [select] Field selection for the population query
5069
+ * @param {object|string|Array<string>} path either the path(s) to populate or an object specifying all parameters
5070
+ * @param {object|string} [select] Field selection for the population query
4918
5071
  * @param {Model} [model] The model you wish to use for population. If not specified, populate will look up the model by the name in the Schema's `ref` field.
4919
- * @param {Object} [match] Conditions for the population query
4920
- * @param {Object} [options] Options for the population query (sort, etc)
4921
- * @param {String} [options.path=null] The path to populate.
5072
+ * @param {object} [match] Conditions for the population query
5073
+ * @param {object} [options] Options for the population query (sort, etc)
5074
+ * @param {string} [options.path=null] The path to populate.
4922
5075
  * @param {boolean} [options.retainNullValues=false] by default, Mongoose removes null and undefined values from populated arrays. Use this option to make `populate()` retain `null` and `undefined` array entries.
4923
5076
  * @param {boolean} [options.getters=false] if true, Mongoose will call any getters defined on the `localField`. By default, Mongoose gets the raw value of `localField`. For example, you would need to set this option to `true` if you wanted to [add a `lowercase` getter to your `localField`](https://mongoosejs.com/docs/schematypes.html#schematype-options).
4924
5077
  * @param {boolean} [options.clone=false] When you do `BlogPost.find().populate('author')`, blog posts with the same author will share 1 copy of an `author` doc. Enable this option to make Mongoose clone populated docs before assigning them.
4925
- * @param {Object|Function} [options.match=null] Add an additional filter to the populate query. Can be a filter object containing [MongoDB query syntax](https://www.mongodb.com/docs/manual/tutorial/query-documents/), or a function that returns a filter object.
5078
+ * @param {object|Function} [options.match=null] Add an additional filter to the populate query. Can be a filter object containing [MongoDB query syntax](https://www.mongodb.com/docs/manual/tutorial/query-documents/), or a function that returns a filter object.
4926
5079
  * @param {Function} [options.transform=null] Function that Mongoose will call on every populated document that allows you to transform the populated document.
4927
- * @param {Object} [options.options=null] Additional options like `limit` and `lean`.
5080
+ * @param {object} [options.options=null] Additional options like `limit` and `lean`.
4928
5081
  * @see population https://mongoosejs.com/docs/populate.html
4929
5082
  * @see Query#select https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
4930
5083
  * @see Model.populate https://mongoosejs.com/docs/api/model.html#Model.populate()
@@ -4932,8 +5085,7 @@ Query.prototype._castUpdate = function _castUpdate(obj) {
4932
5085
  * @api public
4933
5086
  */
4934
5087
 
4935
- Query.prototype.populate = function() {
4936
- const args = Array.from(arguments);
5088
+ Query.prototype.populate = function(...args) {
4937
5089
  // Bail when given no truthy arguments
4938
5090
  if (!args.some(Boolean)) {
4939
5091
  return this;
@@ -4946,7 +5098,7 @@ Query.prototype.populate = function() {
4946
5098
  if (opts.lean != null) {
4947
5099
  const lean = opts.lean;
4948
5100
  for (const populateOptions of res) {
4949
- if ((populateOptions && populateOptions.options && populateOptions.options.lean) == null) {
5101
+ if (populateOptions?.options?.lean == null) {
4950
5102
  populateOptions.options = populateOptions.options || {};
4951
5103
  populateOptions.options.lean = lean;
4952
5104
  }
@@ -4961,7 +5113,7 @@ Query.prototype.populate = function() {
4961
5113
 
4962
5114
  for (const populateOptions of res) {
4963
5115
  const path = populateOptions.path;
4964
- if (pop[path] && pop[path].populate && populateOptions.populate) {
5116
+ if (pop[path]?.populate && populateOptions.populate) {
4965
5117
  populateOptions.populate = pop[path].populate.concat(populateOptions.populate);
4966
5118
  }
4967
5119
 
@@ -5029,8 +5181,8 @@ function _getPopulatedPaths(list, arr, prefix) {
5029
5181
  * If `obj` is present, it is cast instead of this query.
5030
5182
  *
5031
5183
  * @param {Model} [model] the model to cast to. If not set, defaults to `this.model`
5032
- * @param {Object} [obj]
5033
- * @return {Object}
5184
+ * @param {object} [obj]
5185
+ * @return {object}
5034
5186
  * @api public
5035
5187
  */
5036
5188
 
@@ -5043,7 +5195,7 @@ Query.prototype.cast = function(model, obj) {
5043
5195
  model = getDiscriminatorByValue(model.discriminators, obj[discriminatorKey]) || model;
5044
5196
  }
5045
5197
 
5046
- const opts = { upsert: this.options && this.options.upsert };
5198
+ const opts = { upsert: this.options?.upsert };
5047
5199
  if (this.options) {
5048
5200
  if ('strict' in this.options) {
5049
5201
  opts.strict = this.options.strict;
@@ -5072,7 +5224,7 @@ Query.prototype.cast = function(model, obj) {
5072
5224
  *
5073
5225
  * query.select({ ids: { $elemMatch: { $in: [hexString] }})
5074
5226
  *
5075
- * @param {Object} fields
5227
+ * @param {object} fields
5076
5228
  * @see https://github.com/Automattic/mongoose/issues/1091
5077
5229
  * @see https://www.mongodb.com/docs/manual/reference/projection/elemMatch/
5078
5230
  * @api private
@@ -5159,7 +5311,7 @@ Query.prototype._applyPaths = function applyPaths() {
5159
5311
  };
5160
5312
 
5161
5313
  /**
5162
- * Returns a wrapper around a [mongodb driver cursor](https://mongodb.github.io/node-mongodb-native/4.9/classes/FindCursor.html).
5314
+ * Returns a wrapper around a [mongodb driver cursor](https://mongodb.github.io/node-mongodb-native/7.0/classes/FindCursor.html).
5163
5315
  * A QueryCursor exposes a Streams3 interface, as well as a `.next()` function.
5164
5316
  *
5165
5317
  * The `.cursor()` function triggers pre find hooks, but **not** post find hooks.
@@ -5193,7 +5345,7 @@ Query.prototype._applyPaths = function applyPaths() {
5193
5345
  * - `transform`: optional function which accepts a mongoose document. The return value of the function will be emitted on `data` and returned by `.next()`.
5194
5346
  *
5195
5347
  * @return {QueryCursor}
5196
- * @param {Object} [options]
5348
+ * @param {object} [options]
5197
5349
  * @see QueryCursor https://mongoosejs.com/docs/api/querycursor.html
5198
5350
  * @api public
5199
5351
  */
@@ -5230,10 +5382,10 @@ Query.prototype.cursor = function cursor(opts) {
5230
5382
  *
5231
5383
  * Cannot be used with `distinct()`
5232
5384
  *
5233
- * @param {Boolean} bool defaults to true
5234
- * @param {Object} [opts] options to set
5235
- * @param {Boolean} [opts.awaitData] false by default. Set to true to keep the cursor open even if there's no data.
5236
- * @param {Number} [opts.maxAwaitTimeMS] the maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `tailable` and `awaitData` to be true
5385
+ * @param {boolean} bool defaults to true
5386
+ * @param {object} [opts] options to set
5387
+ * @param {boolean} [opts.awaitData] false by default. Set to true to keep the cursor open even if there's no data.
5388
+ * @param {number} [opts.maxAwaitTimeMS] the maximum amount of time for the server to wait on new documents to satisfy a tailable cursor query. Requires `tailable` and `awaitData` to be true
5237
5389
  * @see tailable https://www.mongodb.com/docs/manual/tutorial/create-tailable-cursor/
5238
5390
  * @api public
5239
5391
  */
@@ -5241,7 +5393,7 @@ Query.prototype.cursor = function cursor(opts) {
5241
5393
  Query.prototype.tailable = function(val, opts) {
5242
5394
  // we need to support the tailable({ awaitData : true }) as well as the
5243
5395
  // tailable(true, {awaitData :true}) syntax that mquery does not support
5244
- if (val != null && typeof val.constructor === 'function' && val.constructor.name === 'Object') {
5396
+ if (typeof val?.constructor === 'function' && val.constructor.name === 'Object') {
5245
5397
  opts = val;
5246
5398
  val = true;
5247
5399
  }
@@ -5292,7 +5444,7 @@ Query.prototype.tailable = function(val, opts) {
5292
5444
  * @method intersects
5293
5445
  * @memberOf Query
5294
5446
  * @instance
5295
- * @param {Object} [arg]
5447
+ * @param {object} [arg]
5296
5448
  * @return {Query} this
5297
5449
  * @see $geometry https://www.mongodb.com/docs/manual/reference/operator/geometry/
5298
5450
  * @see geoIntersects https://www.mongodb.com/docs/manual/reference/operator/geoIntersects/
@@ -5331,7 +5483,7 @@ Query.prototype.tailable = function(val, opts) {
5331
5483
  * @method geometry
5332
5484
  * @memberOf Query
5333
5485
  * @instance
5334
- * @param {Object} object Must contain a `type` property which is a String and a `coordinates` property which is an Array. See the examples.
5486
+ * @param {object} object Must contain a `type` property which is a String and a `coordinates` property which is an Array. See the examples.
5335
5487
  * @return {Query} this
5336
5488
  * @see $geometry https://www.mongodb.com/docs/manual/reference/operator/geometry/
5337
5489
  * @see Geospatial Support Enhancements https://www.mongodb.com/docs/manual/release-notes/2.4/#geospatial-support-enhancements
@@ -5354,8 +5506,8 @@ Query.prototype.tailable = function(val, opts) {
5354
5506
  * @method near
5355
5507
  * @memberOf Query
5356
5508
  * @instance
5357
- * @param {String} [path]
5358
- * @param {Object} val
5509
+ * @param {string} [path]
5510
+ * @param {object} val
5359
5511
  * @return {Query} this
5360
5512
  * @see $near https://www.mongodb.com/docs/manual/reference/operator/near/
5361
5513
  * @see $nearSphere https://www.mongodb.com/docs/manual/reference/operator/nearSphere/
@@ -5467,26 +5619,17 @@ Query.prototype.nearSphere = function() {
5467
5619
  * console.log(doc.name);
5468
5620
  * }
5469
5621
  *
5470
- * Node.js 10.x supports async iterators natively without any flags. You can
5471
- * enable async iterators in Node.js 8.x using the [`--harmony_async_iteration` flag](https://github.com/tc39/proposal-async-iteration/issues/117#issuecomment-346695187).
5472
- *
5473
- * **Note:** This function is not if `Symbol.asyncIterator` is undefined. If
5474
- * `Symbol.asyncIterator` is undefined, that means your Node.js version does not
5475
- * support async iterators.
5476
- *
5477
5622
  * @method [Symbol.asyncIterator]
5478
5623
  * @memberOf Query
5479
5624
  * @instance
5480
5625
  * @api public
5481
5626
  */
5482
5627
 
5483
- if (Symbol.asyncIterator != null) {
5484
- Query.prototype[Symbol.asyncIterator] = function queryAsyncIterator() {
5485
- // Set so QueryCursor knows it should transform results for async iterators into `{ value, done }` syntax
5486
- this._mongooseOptions._asyncIterator = true;
5487
- return this.cursor();
5488
- };
5489
- }
5628
+ Query.prototype[Symbol.asyncIterator] = function queryAsyncIterator() {
5629
+ // Set so QueryCursor knows it should transform results for async iterators into `{ value, done }` syntax
5630
+ this._mongooseOptions._asyncIterator = true;
5631
+ return this.cursor();
5632
+ };
5490
5633
 
5491
5634
  /**
5492
5635
  * Specifies a `$polygon` condition
@@ -5499,8 +5642,8 @@ if (Symbol.asyncIterator != null) {
5499
5642
  * @method polygon
5500
5643
  * @memberOf Query
5501
5644
  * @instance
5502
- * @param {String|Array} [path]
5503
- * @param {...Array|Object} [coordinatePairs]
5645
+ * @param {string|Array} [path]
5646
+ * @param {...Array|object} [coordinatePairs]
5504
5647
  * @return {Query} this
5505
5648
  * @see $polygon https://www.mongodb.com/docs/manual/reference/operator/polygon/
5506
5649
  * @see MongoDB Geospatial Indexing https://www.mongodb.com/docs/manual/core/geospatial-indexes/
@@ -5524,8 +5667,8 @@ if (Symbol.asyncIterator != null) {
5524
5667
  * @see $box https://www.mongodb.com/docs/manual/reference/operator/box/
5525
5668
  * @see within() Query#within https://mongoosejs.com/docs/api/query.html#Query.prototype.within()
5526
5669
  * @see MongoDB Geospatial Indexing https://www.mongodb.com/docs/manual/core/geospatial-indexes/
5527
- * @param {Object|Array<Number>} val1 Lower Left Coordinates OR a object of lower-left(ll) and upper-right(ur) Coordinates
5528
- * @param {Array<Number>} [val2] Upper Right Coordinates
5670
+ * @param {object|Array<number>} val1 Lower Left Coordinates OR an object of lower-left(ll) and upper-right(ur) Coordinates
5671
+ * @param {Array<number>} [val2] Upper Right Coordinates
5529
5672
  * @return {Query} this
5530
5673
  * @api public
5531
5674
  */
@@ -5568,8 +5711,8 @@ Query.prototype.box = function(ll, ur) {
5568
5711
  * @method circle
5569
5712
  * @memberOf Query
5570
5713
  * @instance
5571
- * @param {String} [path]
5572
- * @param {Object} area
5714
+ * @param {string} [path]
5715
+ * @param {object} area
5573
5716
  * @return {Query} this
5574
5717
  * @see $center https://www.mongodb.com/docs/manual/reference/operator/center/
5575
5718
  * @see $centerSphere https://www.mongodb.com/docs/manual/reference/operator/centerSphere/
@@ -5603,8 +5746,8 @@ Query.prototype.center = Query.base.circle;
5603
5746
  * query.where('loc').within().centerSphere(area);
5604
5747
  *
5605
5748
  * @deprecated
5606
- * @param {String} [path]
5607
- * @param {Object} val
5749
+ * @param {string} [path]
5750
+ * @param {object} val
5608
5751
  * @return {Query} this
5609
5752
  * @see MongoDB Geospatial Indexing https://www.mongodb.com/docs/manual/core/geospatial-indexes/
5610
5753
  * @see $centerSphere https://www.mongodb.com/docs/manual/reference/operator/centerSphere/
@@ -5612,11 +5755,11 @@ Query.prototype.center = Query.base.circle;
5612
5755
  */
5613
5756
 
5614
5757
  Query.prototype.centerSphere = function() {
5615
- if (arguments[0] != null && typeof arguments[0].constructor === 'function' && arguments[0].constructor.name === 'Object') {
5758
+ if (typeof arguments[0]?.constructor === 'function' && arguments[0].constructor.name === 'Object') {
5616
5759
  arguments[0].spherical = true;
5617
5760
  }
5618
5761
 
5619
- if (arguments[1] != null && typeof arguments[1].constructor === 'function' && arguments[1].constructor.name === 'Object') {
5762
+ if (typeof arguments[1]?.constructor === 'function' && arguments[1].constructor.name === 'Object') {
5620
5763
  arguments[1].spherical = true;
5621
5764
  }
5622
5765
 
@@ -5629,7 +5772,7 @@ Query.prototype.centerSphere = function() {
5629
5772
  * @method selected
5630
5773
  * @memberOf Query
5631
5774
  * @instance
5632
- * @return {Boolean}
5775
+ * @return {boolean}
5633
5776
  * @api public
5634
5777
  */
5635
5778
 
@@ -5643,7 +5786,7 @@ Query.prototype.centerSphere = function() {
5643
5786
  * @method selectedInclusively
5644
5787
  * @memberOf Query
5645
5788
  * @instance
5646
- * @return {Boolean}
5789
+ * @return {boolean}
5647
5790
  * @api public
5648
5791
  */
5649
5792
 
@@ -5662,7 +5805,7 @@ Query.prototype.selectedInclusively = function selectedInclusively() {
5662
5805
  * @method selectedExclusively
5663
5806
  * @memberOf Query
5664
5807
  * @instance
5665
- * @return {Boolean}
5808
+ * @return {boolean}
5666
5809
  * @api public
5667
5810
  */
5668
5811
 
@@ -5686,6 +5829,15 @@ Query.prototype.selectedExclusively = function selectedExclusively() {
5686
5829
 
5687
5830
  Query.prototype.model;
5688
5831
 
5832
+ /**
5833
+ * Determine if we can merge the given value as a query filter. Override for mquery.canMerge() to allow null
5834
+ */
5835
+
5836
+ function canMerge(value) {
5837
+ return value instanceof Query || utils.isObject(value) || value === null;
5838
+
5839
+ }
5840
+
5689
5841
  /*!
5690
5842
  * Export
5691
5843
  */