@rvoh/dream 2.35.0 → 2.36.1

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 (302) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/src/Dream.js +260 -55
  3. package/dist/cjs/src/bin/index.js +13 -0
  4. package/dist/cjs/src/cli/index.js +28 -17
  5. package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
  6. package/dist/cjs/src/decorators/Decorators.js +26 -4
  7. package/dist/cjs/src/decorators/field/Encrypted.js +35 -6
  8. package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +6 -6
  9. package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +63 -27
  10. package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +3 -3
  11. package/dist/cjs/src/dream/LoadBuilder.js +1 -1
  12. package/dist/cjs/src/dream/Query.js +542 -167
  13. package/dist/cjs/src/dream/QueryDriver/Base.js +72 -0
  14. package/dist/cjs/src/dream/QueryDriver/Kysely.js +216 -50
  15. package/dist/cjs/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
  16. package/dist/cjs/src/dream/internal/associations/associationQuery.js +4 -0
  17. package/dist/cjs/src/dream/internal/reload.js +6 -1
  18. package/dist/cjs/src/dream/internal/saveDream.js +8 -2
  19. package/dist/cjs/src/dream/internal/sqlResultToDreamInstance.js +2 -0
  20. package/dist/cjs/src/dream/internal/undestroyDream.js +1 -1
  21. package/dist/cjs/src/dream-app/index.js +38 -0
  22. package/dist/cjs/src/encrypt/InternalEncrypt.js +77 -4
  23. package/dist/cjs/src/encrypt/defaultEncryptedColumnName.js +10 -0
  24. package/dist/cjs/src/encrypt/index.js +76 -9
  25. package/dist/cjs/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
  26. package/dist/cjs/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
  27. package/dist/cjs/src/helpers/Env.js +28 -0
  28. package/dist/cjs/src/helpers/cli/generateDreamContent.js +2 -1
  29. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +1 -1
  30. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +9 -9
  31. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +21 -8
  32. package/dist/cjs/src/serializer/SerializerRenderer.js +65 -13
  33. package/dist/cjs/src/serializer/builders/DreamSerializerBuilder.js +54 -38
  34. package/dist/cjs/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
  35. package/dist/cjs/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
  36. package/dist/esm/src/Dream.js +260 -55
  37. package/dist/esm/src/bin/index.js +13 -0
  38. package/dist/esm/src/cli/index.js +28 -17
  39. package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
  40. package/dist/esm/src/decorators/Decorators.js +26 -4
  41. package/dist/esm/src/decorators/field/Encrypted.js +35 -6
  42. package/dist/esm/src/dream/DreamClassTransactionBuilder.js +6 -6
  43. package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +63 -27
  44. package/dist/esm/src/dream/LeftJoinLoadBuilder.js +3 -3
  45. package/dist/esm/src/dream/LoadBuilder.js +1 -1
  46. package/dist/esm/src/dream/Query.js +542 -167
  47. package/dist/esm/src/dream/QueryDriver/Base.js +72 -0
  48. package/dist/esm/src/dream/QueryDriver/Kysely.js +216 -50
  49. package/dist/esm/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
  50. package/dist/esm/src/dream/internal/associations/associationQuery.js +4 -0
  51. package/dist/esm/src/dream/internal/reload.js +6 -1
  52. package/dist/esm/src/dream/internal/saveDream.js +8 -2
  53. package/dist/esm/src/dream/internal/sqlResultToDreamInstance.js +2 -0
  54. package/dist/esm/src/dream/internal/undestroyDream.js +1 -1
  55. package/dist/esm/src/dream-app/index.js +38 -0
  56. package/dist/esm/src/encrypt/InternalEncrypt.js +77 -4
  57. package/dist/esm/src/encrypt/defaultEncryptedColumnName.js +10 -0
  58. package/dist/esm/src/encrypt/index.js +76 -9
  59. package/dist/esm/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
  60. package/dist/esm/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
  61. package/dist/esm/src/helpers/Env.js +28 -0
  62. package/dist/esm/src/helpers/cli/generateDreamContent.js +2 -1
  63. package/dist/esm/src/helpers/cli/generateFactoryContent.js +1 -1
  64. package/dist/esm/src/helpers/cli/generateMigrationContent.js +9 -9
  65. package/dist/esm/src/helpers/cli/generateSerializerContent.js +21 -8
  66. package/dist/esm/src/serializer/SerializerRenderer.js +65 -13
  67. package/dist/esm/src/serializer/builders/DreamSerializerBuilder.js +54 -38
  68. package/dist/esm/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
  69. package/dist/esm/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
  70. package/dist/types/src/Dream.d.ts +208 -42
  71. package/dist/types/src/bin/index.d.ts +7 -1
  72. package/dist/types/src/cli/index.d.ts +13 -0
  73. package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +2 -2
  74. package/dist/types/src/decorators/Decorators.d.ts +26 -3
  75. package/dist/types/src/decorators/field/Encrypted.d.ts +6 -1
  76. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +9 -9
  77. package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +52 -25
  78. package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +4 -4
  79. package/dist/types/src/dream/LoadBuilder.d.ts +1 -1
  80. package/dist/types/src/dream/Query.d.ts +272 -33
  81. package/dist/types/src/dream/QueryDriver/Base.d.ts +63 -1
  82. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +85 -1
  83. package/dist/types/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.d.ts +29 -0
  84. package/dist/types/src/dream-app/index.d.ts +56 -2
  85. package/dist/types/src/encrypt/InternalEncrypt.d.ts +29 -1
  86. package/dist/types/src/encrypt/defaultEncryptedColumnName.d.ts +7 -0
  87. package/dist/types/src/encrypt/index.d.ts +75 -6
  88. package/dist/types/src/errors/associations/UnrecognizedAssociationConditionKeys.d.ts +8 -0
  89. package/dist/types/src/helpers/Env.d.ts +28 -0
  90. package/dist/types/src/package-exports/openapi.d.ts +1 -1
  91. package/dist/types/src/package-exports/types.d.ts +2 -2
  92. package/dist/types/src/serializer/SerializerRenderer.d.ts +13 -0
  93. package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +59 -55
  94. package/dist/types/src/serializer/builders/ObjectSerializerBuilder.d.ts +40 -19
  95. package/dist/types/src/serializer/helpers/serializersForAssociatedClass.d.ts +17 -0
  96. package/dist/types/src/types/lifecycle.d.ts +6 -0
  97. package/dist/types/src/types/openapi.d.ts +52 -29
  98. package/dist/types/src/types/serializer.d.ts +43 -2
  99. package/dist/types/src/types/types/lifecycle.ts +6 -0
  100. package/dist/types/src/types/types/openapi.ts +51 -37
  101. package/dist/types/src/types/types/serializer.ts +62 -2
  102. package/dist/types/src/types/types/variadic.ts +99 -43
  103. package/dist/types/src/types/variadic.d.ts +29 -3
  104. package/docs/assets/hierarchy.js +1 -1
  105. package/docs/assets/highlight.css +4 -11
  106. package/docs/assets/navigation.js +1 -1
  107. package/docs/assets/search.js +1 -1
  108. package/docs/classes/db.DreamMigrationHelpers.html +13 -13
  109. package/docs/classes/db.KyselyQueryDriver.html +85 -46
  110. package/docs/classes/db.PostgresQueryDriver.html +86 -47
  111. package/docs/classes/db.QueryDriverBase.html +84 -45
  112. package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
  113. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  114. package/docs/classes/errors.ColumnOverflow.html +3 -3
  115. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  116. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  117. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  118. package/docs/classes/errors.DecryptionError.html +2 -2
  119. package/docs/classes/errors.DecryptionParseError.html +2 -2
  120. package/docs/classes/errors.DecryptionRotationError.html +3 -3
  121. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  122. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  123. package/docs/classes/errors.InvalidClockTime.html +2 -2
  124. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  125. package/docs/classes/errors.InvalidDateTime.html +2 -2
  126. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  127. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  128. package/docs/classes/errors.NotNullViolation.html +3 -3
  129. package/docs/classes/errors.RecordNotFound.html +3 -3
  130. package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
  131. package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
  132. package/docs/classes/errors.ValidationError.html +3 -3
  133. package/docs/classes/index.CalendarDate.html +33 -33
  134. package/docs/classes/index.ClockTime.html +32 -32
  135. package/docs/classes/index.ClockTimeTz.html +35 -35
  136. package/docs/classes/index.DateTime.html +86 -86
  137. package/docs/classes/index.Decorators.html +37 -23
  138. package/docs/classes/index.Dream.html +270 -142
  139. package/docs/classes/index.DreamApp.html +40 -10
  140. package/docs/classes/index.DreamTransaction.html +3 -3
  141. package/docs/classes/index.Env.html +16 -2
  142. package/docs/classes/index.Query.html +331 -129
  143. package/docs/classes/system.CliFileWriter.html +4 -4
  144. package/docs/classes/system.DreamBin.html +6 -2
  145. package/docs/classes/system.DreamCLI.html +7 -7
  146. package/docs/classes/system.DreamImporter.html +2 -2
  147. package/docs/classes/system.DreamLogos.html +2 -2
  148. package/docs/classes/system.DreamSerializerBuilder.html +52 -34
  149. package/docs/classes/system.ObjectSerializerBuilder.html +41 -22
  150. package/docs/classes/system.PathHelpers.html +4 -4
  151. package/docs/classes/utils.Encrypt.html +54 -10
  152. package/docs/classes/utils.Range.html +2 -2
  153. package/docs/functions/db.closeAllDbConnections.html +1 -1
  154. package/docs/functions/db.dreamDbConnections.html +1 -1
  155. package/docs/functions/db.untypedDb.html +1 -1
  156. package/docs/functions/db.validateColumn.html +1 -1
  157. package/docs/functions/db.validateTable.html +1 -1
  158. package/docs/functions/errors.pgErrorType.html +1 -1
  159. package/docs/functions/index.DreamSerializer.html +1 -1
  160. package/docs/functions/index.ObjectSerializer.html +1 -1
  161. package/docs/functions/index.ReplicaSafe.html +1 -1
  162. package/docs/functions/index.STI.html +1 -1
  163. package/docs/functions/index.SoftDelete.html +1 -1
  164. package/docs/functions/utils.camelize.html +1 -1
  165. package/docs/functions/utils.capitalize.html +1 -1
  166. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  167. package/docs/functions/utils.compact.html +1 -1
  168. package/docs/functions/utils.groupBy.html +1 -1
  169. package/docs/functions/utils.hyphenize.html +1 -1
  170. package/docs/functions/utils.intersection.html +1 -1
  171. package/docs/functions/utils.isEmpty.html +1 -1
  172. package/docs/functions/utils.normalizeUnicode.html +1 -1
  173. package/docs/functions/utils.pascalize.html +1 -1
  174. package/docs/functions/utils.percent.html +1 -1
  175. package/docs/functions/utils.range.html +1 -1
  176. package/docs/functions/utils.round.html +1 -1
  177. package/docs/functions/utils.sanitizeString.html +1 -1
  178. package/docs/functions/utils.snakeify.html +1 -1
  179. package/docs/functions/utils.sort.html +1 -1
  180. package/docs/functions/utils.sortBy.html +1 -1
  181. package/docs/functions/utils.sortObjectByKey.html +1 -1
  182. package/docs/functions/utils.sortObjectByValue.html +1 -1
  183. package/docs/functions/utils.uncapitalize.html +1 -1
  184. package/docs/functions/utils.uniq.html +1 -1
  185. package/docs/hierarchy.html +1 -1
  186. package/docs/index.html +1 -1
  187. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  188. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  189. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  190. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  191. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  192. package/docs/interfaces/types.DecoratorContext.html +2 -2
  193. package/docs/interfaces/types.DecryptCallbacks.html +6 -0
  194. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  195. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  196. package/docs/interfaces/types.DreamDbConfig.html +6 -6
  197. package/docs/interfaces/types.DurationObject.html +2 -2
  198. package/docs/interfaces/types.EncryptOptions.html +2 -2
  199. package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +10 -0
  200. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  201. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  202. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  203. package/docs/modules/openapi.html +1 -1
  204. package/docs/modules/types.html +1 -1
  205. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  206. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  207. package/docs/types/openapi.OpenapiFormats.html +1 -1
  208. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  209. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  210. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  211. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  212. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  213. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  214. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  215. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  216. package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +4 -0
  217. package/docs/types/openapi.OpenapiSchemaCommonFields.html +5 -1
  218. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -2
  219. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -2
  220. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -2
  221. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  222. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  223. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  224. package/docs/types/openapi.OpenapiSchemaNull.html +4 -2
  225. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  226. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  227. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +5 -1
  228. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +2 -1
  229. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  230. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  231. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  232. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  233. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -2
  234. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -2
  235. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -2
  236. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  237. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  238. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  239. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  240. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  241. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  242. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  243. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  244. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  245. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  246. package/docs/types/types.CalendarDateObject.html +1 -1
  247. package/docs/types/types.Camelized.html +1 -1
  248. package/docs/types/types.ClockTimeObject.html +1 -1
  249. package/docs/types/types.DbConnectionType.html +1 -1
  250. package/docs/types/types.DbTypes.html +1 -1
  251. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  252. package/docs/types/types.DreamAttributes.html +1 -1
  253. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  254. package/docs/types/types.DreamClassColumn.html +1 -1
  255. package/docs/types/types.DreamColumn.html +1 -1
  256. package/docs/types/types.DreamColumnNames.html +1 -1
  257. package/docs/types/types.DreamLogLevel.html +1 -1
  258. package/docs/types/types.DreamLogger.html +2 -2
  259. package/docs/types/types.DreamModelSerializerType.html +1 -1
  260. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  261. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  262. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  263. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  264. package/docs/types/types.DreamSerializable.html +1 -1
  265. package/docs/types/types.DreamSerializableArray.html +1 -1
  266. package/docs/types/types.DreamSerializerKey.html +1 -1
  267. package/docs/types/types.DreamSerializers.html +1 -1
  268. package/docs/types/types.DreamVirtualColumns.html +1 -1
  269. package/docs/types/types.DurationUnit.html +1 -1
  270. package/docs/types/types.EncryptAlgorithm.html +1 -1
  271. package/docs/types/types.HasManyStatement.html +1 -1
  272. package/docs/types/types.HasOneStatement.html +1 -1
  273. package/docs/types/types.Hyphenized.html +1 -1
  274. package/docs/types/types.Pascalized.html +1 -1
  275. package/docs/types/types.PrimaryKeyType.html +1 -1
  276. package/docs/types/types.RoundingPrecision.html +1 -1
  277. package/docs/types/types.SerializerCasing.html +1 -1
  278. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  279. package/docs/types/types.Snakeified.html +1 -1
  280. package/docs/types/types.StrictInterface.html +1 -1
  281. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  282. package/docs/types/types.UpdateableProperties.html +1 -1
  283. package/docs/types/types.ValidationType.html +1 -1
  284. package/docs/types/types.ViewModel.html +2 -2
  285. package/docs/types/types.ViewModelClass.html +1 -1
  286. package/docs/types/types.WeekdayName.html +1 -1
  287. package/docs/types/types.WhereStatementForDream.html +1 -1
  288. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  289. package/docs/variables/index.DreamConst.html +1 -1
  290. package/docs/variables/index.ops.html +1 -1
  291. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  292. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  293. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  294. package/docs/variables/system.primaryKeyTypes.html +1 -1
  295. package/package.json +1 -1
  296. package/dist/cjs/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
  297. package/dist/esm/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
  298. package/dist/types/src/serializer/helpers/serializerForAssociatedClass.d.ts +0 -9
  299. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +0 -1
  300. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +0 -1
  301. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +0 -1
  302. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +0 -1
@@ -21,26 +21,29 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
21
21
  /**
22
22
  * Loads the requested associations upon execution
23
23
  *
24
+ * **IMPORTANT:** `load().execute()` returns a **new clone** of the model with the
25
+ * associations loaded. It does NOT modify the original instance.
26
+ *
24
27
  * NOTE: {@link Dream#preload} is often a preferrable way of achieving the
25
28
  * same goal.
26
29
  *
27
30
  * ```ts
28
31
  * await ApplicationModel.transaction(async txn => {
29
- * await user
32
+ * const loadedUser = await user
30
33
  * .txn(txn)
31
- * .load('posts', { body: ops.ilike('%hello world%') }, 'comments', 'replies')
34
+ * .load('posts', { and: { body: ops.ilike('%hello world%') } }, 'comments', 'replies')
32
35
  * .load('images')
33
36
  * .execute()
34
37
  *
35
- * user.posts[0].comments[0].replies[0]
38
+ * loadedUser.posts[0].comments[0].replies[0]
36
39
  * // Reply{}
37
40
  *
38
- * user.images[0]
41
+ * loadedUser.images[0]
39
42
  * // Image{}
40
43
  * })
41
44
  * ```
42
45
  *
43
- * @param args - A list of associations (and optional where clauses) to load
46
+ * @param args - A chain of association names and and/andNot/andAny clauses
44
47
  * @returns A chainable LoadBuilder instance
45
48
  */
46
49
  load<I extends DreamInstanceTransactionBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[]>(this: I, ...args: [...Arr, VariadicLoadArgs<DreamInstance, DB, Schema, TableName, Arr>]): LoadBuilder<DreamInstance>;
@@ -96,32 +99,34 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
96
99
  * Load each specified association using a single SQL query.
97
100
  * See {@link #load} for loading in separate queries.
98
101
  *
99
- * Note: since leftJoinPreload loads via single query, it has
100
- * some downsides and that may be avoided using {@link #load}:
102
+ * **IMPORTANT:** Like `load()`, `leftJoinLoad().execute()` returns a **new clone** of the
103
+ * model with associations loaded. It does NOT modify the original instance.
104
+ *
105
+ * Note: since leftJoinLoad loads via single query, it has
106
+ * some downsides that may be avoided using {@link #load}:
101
107
  * 1. `limit` and `offset` will be automatically removed
102
108
  * 2. `through` associations will bring additional namespaces into the query that can conflict with through associations from other associations, creating an invalid query
103
- * 3. each nested association will result in an additional record which duplicates data from the outer record. E.g., given `.leftJoinPreload('a', 'b', 'c')`, if each `a` has 10 `b` and each `b` has 10 `c`, then for one `a`, 100 records will be returned, each of which has all of the columns of `a`. `.load('a', 'b', 'c')` would perform three separate SQL queries, but the data for a single `a` would only be returned once.
109
+ * 3. each nested association will result in an additional record which duplicates data from the outer record. E.g., given `.leftJoinLoad('a', 'b', 'c')`, if each `a` has 10 `b` and each `b` has 10 `c`, then for one `a`, 100 records will be returned, each of which has all of the columns of `a`. `.load('a', 'b', 'c')` would perform three separate SQL queries, but the data for a single `a` would only be returned once.
104
110
  * 4. the individual query becomes more complex the more associations are included
105
111
  * 5. associations loading associations loading associations could result in exponential amounts of data; in those cases, `.load(...).findEach(...)` avoids instantiating massive amounts of data at once
106
- * Loads the requested associations upon execution
107
- *
108
- * NOTE: {@link Dream#leftJoinPreload} is often a preferrable way of achieving the
109
- * same goal.
110
112
  *
111
113
  * ```ts
112
- * await user.txn(txn)
113
- * .leftJoinLoad('posts', { body: ops.ilike('%hello world%') }, 'comments', 'replies')
114
- * .leftJoinLoad('images')
115
- * .execute()
114
+ * await ApplicationModel.transaction(async txn => {
115
+ * const loadedUser = await user
116
+ * .txn(txn)
117
+ * .leftJoinLoad('posts', { and: { body: ops.ilike('%hello world%') } }, 'comments', 'replies')
118
+ * .leftJoinLoad('images')
119
+ * .execute()
116
120
  *
117
- * user.posts[0].comments[0].replies[0]
118
- * // Reply{}
121
+ * loadedUser.posts[0].comments[0].replies[0]
122
+ * // Reply{}
119
123
  *
120
- * user.images[0]
121
- * // Image{}
124
+ * loadedUser.images[0]
125
+ * // Image{}
126
+ * })
122
127
  * ```
123
128
  *
124
- * @param args - A list of associations (and optional where clauses) to load
129
+ * @param args - A chain of association names and and/andNot/andAny clauses
125
130
  * @returns A chainable LeftJoinLoadBuilder instance
126
131
  */
127
132
  leftJoinLoad<I extends DreamInstanceTransactionBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[]>(this: I, ...args: [...Arr, VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr>]): LeftJoinLoadBuilder<DreamInstance>;
@@ -135,10 +140,10 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
135
140
  * })
136
141
  * ```
137
142
  *
138
- * @param args - A chain of association names and where clauses
143
+ * @param args - A chain of association names and and/andNot/andAny clauses
139
144
  * @returns A Query for this model with the inner join clause applied
140
145
  */
141
- innerJoin<I extends DreamInstanceTransactionBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
146
+ innerJoin<I extends DreamInstanceTransactionBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
142
147
  ...Arr,
143
148
  LastArg
144
149
  ]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = QueryWithJoinedAssociationsType<Query<DreamInstance>, JoinedAssociations>>(this: I, ...args: [...Arr, LastArg]): RetQuery;
@@ -152,10 +157,10 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
152
157
  * })
153
158
  * ```
154
159
  *
155
- * @param args - A chain of association names and where clauses
160
+ * @param args - A chain of association names and and/andNot/andAny clauses
156
161
  * @returns A Query for this model with the left join clause applied
157
162
  */
158
- leftJoin<I extends DreamInstanceTransactionBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
163
+ leftJoin<I extends DreamInstanceTransactionBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
159
164
  ...Arr,
160
165
  LastArg
161
166
  ]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = QueryWithJoinedAssociationsType<Query<DreamInstance>, JoinedAssociations>>(this: I, ...args: [...Arr, LastArg]): RetQuery;
@@ -228,6 +233,12 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
228
233
  * See {@link Dream.save | save} for details on
229
234
  * the side effects of saving.
230
235
  *
236
+ * A column whose value is still `undefined` after setters run is
237
+ * skipped, not written (see {@link Dream.save | save}), with two
238
+ * `@Encrypted` exceptions: `undefined` for an encrypted property (e.g.
239
+ * `secret`) is encrypted to `null`, so it clears the column, and
240
+ * `undefined` for its backing column (e.g. `encryptedSecret`) throws.
241
+ *
231
242
  * NOTE:
232
243
  * To bypass custom-defined setters, use {@link Dream.updateAttributes | updateAttributes} instead.
233
244
  *
@@ -252,6 +263,18 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
252
263
  * See {@link Dream.save | save} for details on
253
264
  * the side effects of saving.
254
265
  *
266
+ * An encrypted property (e.g. `secret`) is still encrypted. Its
267
+ * `@Encrypted` backing column (e.g. `encryptedSecret`) accepts only
268
+ * ciphertext that decrypts with this app's column encryption keys, or
269
+ * `null`; anything else throws before anything is saved (see
270
+ * {@link Dream.setAttribute | setAttribute}).
271
+ *
272
+ * A column whose value is still `undefined` after setters run is
273
+ * skipped, not written (see {@link Dream.save | save}), with two
274
+ * `@Encrypted` exceptions: `undefined` for an encrypted property (e.g.
275
+ * `secret`) is encrypted to `null`, so it clears the column, and
276
+ * `undefined` for its backing column (e.g. `encryptedSecret`) throws.
277
+ *
255
278
  * NOTE:
256
279
  * To update the values without bypassing any custom-defined
257
280
  * setters, use {@link Dream.update | update} instead.
@@ -297,6 +320,10 @@ export default class DreamInstanceTransactionBuilder<DreamInstance extends Dream
297
320
  * Upon updating an instance, the update timestamp (if defined)
298
321
  * will be updated on the model.
299
322
  *
323
+ * A column whose value is `undefined` is skipped, not written: a new
324
+ * record gets the column's database default, and a persisted record
325
+ * keeps the value stored for it. Set a column to `null` to clear it.
326
+ *
300
327
  * ```ts
301
328
  * const user = User.new({ email: 'how@yadoin' })
302
329
  *
@@ -23,17 +23,17 @@ export default class LeftJoinLoadBuilder<DreamInstance extends Dream> {
23
23
  constructor(dream: Dream, dreamTransaction?: (DreamTransaction<any> | null) | undefined);
24
24
  passthrough<I extends LeftJoinLoadBuilder<DreamInstance>, PassthroughColumns extends PassthroughColumnNames<DreamInstance>>(this: I, passthroughWhereStatement: PassthroughOnClause<PassthroughColumns>): I;
25
25
  /**
26
- * Attaches a load statement to the load builder
26
+ * Attaches a leftJoinLoad statement to the load builder
27
27
  *
28
28
  * ```ts
29
29
  * const user = await User.firstOrFail()
30
30
  * await user
31
- * .load('settings')
32
- * .load('posts', 'comments', 'replies', ['image', 'localizedText'])
31
+ * .leftJoinLoad('settings')
32
+ * .leftJoinLoad('posts', 'comments', 'replies', ['image', 'localizedText'])
33
33
  * .execute()
34
34
  * ```
35
35
  */
36
- leftJoinLoad<I extends LeftJoinLoadBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[], const LastArg extends VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr>>(this: I, ...args: [...Arr, LastArg]): I;
36
+ leftJoinLoad<I extends LeftJoinLoadBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[], const LastArg extends VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>>(this: I, ...args: [...Arr, LastArg]): I;
37
37
  /**
38
38
  * Executes the left-join load query, returning a **clone** of the original model
39
39
  * with all requested associations loaded. The original instance is not modified.
@@ -84,7 +84,7 @@ export default class LoadBuilder<DreamInstance extends Dream> {
84
84
  * .execute()
85
85
  * ```
86
86
  *
87
- * @param args - A list of associations (and optional where clauses) to load
87
+ * @param args - A chain of association names and and/andNot/andAny clauses to load
88
88
  * @returns A chainable LoadBuilder instance
89
89
  */
90
90
  load<I extends LoadBuilder<DreamInstance>, DB extends DreamInstance['DB'], TableName extends DreamInstance['table'], Schema extends DreamInstance['schema'], const Arr extends readonly unknown[]>(this: I, ...args: [...Arr, VariadicLoadArgs<DreamInstance, DB, Schema, TableName, Arr>]): I;
@@ -177,6 +177,16 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
177
177
  * The distinct column to apply to the Query
178
178
  */
179
179
  private readonly distinctColumn;
180
+ /**
181
+ * @internal
182
+ *
183
+ * Whether the Query is ordered by its own order statements alone. The
184
+ * driver otherwise sorts by a similarity condition's rank, and by the
185
+ * declared `order` of the associations the Query is built on or joins,
186
+ * ahead of those statements. The keyset walks and cursor pagination set
187
+ * this, since their cursors compare only the Query's order statements.
188
+ */
189
+ private readonly bypassImplicitOrder;
180
190
  /**
181
191
  * @internal
182
192
  *
@@ -303,25 +313,49 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
303
313
  *
304
314
  * IMPORTANT: `findEach` always iterates in ascending primary key order.
305
315
  * Any `order` applied to the Query is discarded; passing one has no effect
306
- * on the order records are visited in.
316
+ * on the order records are visited in. The same goes for the `order` an
317
+ * association declares, when the Query is an `associationQuery` or joins
318
+ * that association, and for the relevance ranking of a similarity condition
319
+ * (`ops.similarity`, `ops.wordSimilarity`, `ops.strictWordSimilarity`),
320
+ * which still decides which records are visited, but not in what order.
321
+ * `findEach` visits the records {@link Query.all} returns: a Query that
322
+ * joins a HasOne or HasMany association (directly, through an association
323
+ * it joins, or as the association an `associationQuery` goes through)
324
+ * returns a record once for each row the join matches, and `findEach`
325
+ * visits it once for each of those rows, the rows of one record in
326
+ * ascending order of the joined rows' primary keys. Call `distinct()` to
327
+ * visit each record once.
307
328
  *
308
329
  * This is not a limitation that can be lifted. `findEach` guarantees that
309
- * every matching record is visited exactly once, and it delivers that by
310
- * paginating on a keyset: each batch selects the next `batchSize` records
311
- * with a primary key greater than the last record of the previous batch.
312
- * That guarantee only holds over a stable, unique key. Ordering by a
313
- * mutable, non-unique column would mean a record whose sort value changed
314
- * partway through the iteration could be skipped entirely or visited twice.
315
- * ({@link Query.cursorPaginate} can honor an arbitrary order precisely
316
- * because a paginated UI tolerates that anomaly; a full traversal cannot.)
330
+ * every matching row is visited exactly once, and it delivers that by
331
+ * paginating on a keyset: each batch selects the next `batchSize` rows
332
+ * whose primary keys (the record's, then the joined rows') sort after the
333
+ * last row of the previous batch. That guarantee only holds over a stable,
334
+ * unique key. Ordering by a mutable, non-unique column would mean a record
335
+ * whose sort value changed partway through the iteration could be skipped
336
+ * entirely or visited twice. ({@link Query.cursorPaginate} can honor an
337
+ * arbitrary order precisely because a paginated UI tolerates that anomaly;
338
+ * a full traversal cannot.)
339
+ *
340
+ * A Query that keeps one record of each group (one that calls `distinct`,
341
+ * or an `associationQuery` of an association that declares `distinct`, or
342
+ * a Query that joins one) cannot be paginated that way: its own `order`, or
343
+ * the association's, chooses which record of each group it returns, and a
344
+ * batch that narrowed it to the rows after the previous batch would let it
345
+ * choose another. So `findEach` reads the keys of all of its rows before
346
+ * visiting the first, and visits those whose rows still match when their
347
+ * batch is read. It visits the rows the Query returned when the walk began,
348
+ * less any destroyed or changed so that they no longer match the Query's
349
+ * conditions, and not a row the Query returns only after the walk began,
350
+ * such as the next record of a group whose record the callback destroyed.
317
351
  *
318
352
  * If you need records processed in a particular order, load them with a
319
353
  * regular ordered query instead of `findEach`.
320
354
  *
321
- * A `limit` or `offset` on the Query cannot compose with the batch windows
322
- * — each batch re-applies the Query's conditions, so the limit would be
355
+ * A `limit` or `offset` on the Query cannot compose with the batches —
356
+ * each batch re-applies the Query's conditions, so the limit would be
323
357
  * silently replaced by `batchSize` and the offset re-applied to every
324
- * window — so a limit- or offset-carrying Query throws at runtime.
358
+ * batch — so a limit- or offset-carrying Query throws at runtime.
325
359
  *
326
360
  * @param cb - The callback to call for each found record
327
361
  * @param __namedParameters - Options for batch processing
@@ -332,6 +366,80 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
332
366
  findEach(this: Query<DreamInstance, QueryTypeOpts>, cb: (instance: DreamInstance) => void | Promise<void>, { batchSize }?: {
333
367
  batchSize?: number;
334
368
  }): Promise<void>;
369
+ /**
370
+ * @internal
371
+ *
372
+ * `findEach`, visiting each record once rather than once for each row a
373
+ * HasOne or HasMany join returns it in, for the operations that act on each
374
+ * record it visits (`destroy`, `reallyDestroy`, `undestroy` and `update`
375
+ * without `lock: true`).
376
+ */
377
+ private findEachRecordOnce;
378
+ /**
379
+ * @internal
380
+ *
381
+ * Calls `cb` with the record of each row this Query returns, telling its
382
+ * rows apart by `rowKeyColumns` (see `walkRowBatches`).
383
+ */
384
+ private findEachRow;
385
+ /**
386
+ * @internal
387
+ *
388
+ * The columns that tell apart the rows this Query returns: its primary key,
389
+ * then the primary keys of the rows HasOne and HasMany joins add (see
390
+ * `rowKeyColumnsOfJoinedRows`).
391
+ */
392
+ private rowKeyColumns;
393
+ /**
394
+ * @internal
395
+ *
396
+ * A HasOne or HasMany join returns a record once for each row it matches,
397
+ * and the primary keys of the joined rows, with the Query's own, tell those
398
+ * rows apart. These are those primary keys, namespaced, other than the
399
+ * Query's own. A Query that calls `distinct` returns one row for each value
400
+ * of its distinct column rather than one for each row the join matches, so
401
+ * it has none.
402
+ */
403
+ private rowKeyColumnsOfJoinedRows;
404
+ /**
405
+ * @internal
406
+ *
407
+ * Walks the rows this Query returns in batches, for `findEach` and
408
+ * `pluckEach`, and calls `visit` with what `readBatch` reads for each row,
409
+ * in ascending order of `rowKeyColumns`, the columns that tell its rows
410
+ * apart. `readBatch` reads a Query that returns a batch's rows, and returns
411
+ * each row's values of `rowKeyColumns` with what to visit for it, if
412
+ * anything. A row whose keys appear again in the same batch is visited once.
413
+ *
414
+ * A select that keeps one row of each group (DISTINCT ON) is walked from the
415
+ * keys of all of its rows, read before the first batch (see
416
+ * `walkRowBatchesFromKeys`); any other, by a cursor (see
417
+ * `walkRowBatchesByCursor`).
418
+ */
419
+ private walkRowBatches;
420
+ /**
421
+ * @internal
422
+ *
423
+ * Walks the rows this Query returns in batches of the next `batchSize` rows
424
+ * after the last row of the batch before, compared on `rowKeyColumns` by a
425
+ * where clause, which every driver applies (see `walkRowBatches`).
426
+ */
427
+ private walkRowBatchesByCursor;
428
+ /**
429
+ * @internal
430
+ *
431
+ * Walks a select that keeps one row of each group (DISTINCT ON), whose rows'
432
+ * values of `rowKeyColumns` are `distinctOnRowKeys`, read before the first
433
+ * batch (see `walkRowBatches`). Such a select cannot be walked by a cursor:
434
+ * narrowing it to the rows after the cursor before it chooses each group's
435
+ * row would let it choose a row it does not return. So each batch reads the
436
+ * rows of the next of those keys that still match, by their keys alone and
437
+ * unordered, since each group's row is chosen already, and puts them back
438
+ * in the order of those keys. The walk visits the rows the select returned
439
+ * when it began, less any destroyed or changed so that they no longer match;
440
+ * a row the select returns only after the walk began is not visited.
441
+ */
442
+ private walkRowBatchesFromKeys;
335
443
  /**
336
444
  * Load each specified association using a single SQL query.
337
445
  * See {@link Query.preload} for preloading in separate queries.
@@ -357,7 +465,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
357
465
  *
358
466
  *
359
467
  * ```ts
360
- * const posts = await user.associationQuery('posts').leftJoinPreload('comments', { visibilty: 'public' }, 'replies').all()
468
+ * const posts = await user.associationQuery('posts').leftJoinPreload('comments', { and: { visibility: 'public' } }, 'replies').all()
361
469
  * console.log(posts[0].comments[0].replies[0])
362
470
  * // [Reply{id: 1}, Reply{id: 2}]
363
471
  * ```
@@ -365,7 +473,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
365
473
  * @param args - A chain of association names and and/andNot/andAny clauses
366
474
  * @returns A cloned Query with the joinLoad statement applied
367
475
  */
368
- leftJoinPreload<Q extends Query<DreamInstance, any>, DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr>, Incompatible extends Q['queryTypeOpts'] extends Readonly<{
476
+ leftJoinPreload<Q extends Query<DreamInstance, any>, DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicLeftJoinLoadArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, Incompatible extends Q['queryTypeOpts'] extends Readonly<{
369
477
  allowLeftJoinPreload: false;
370
478
  }> ? true : false, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, Incompatible extends true ? [] : [...Arr, LastArg]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = Query<DreamInstance, ExtendQueryType<QueryTypeOpts, Readonly<{
371
479
  joinedAssociations: JoinedAssociations;
@@ -379,7 +487,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
379
487
  * See {@link Query.leftJoinPreload} for preloading in a single query.
380
488
  *
381
489
  * ```ts
382
- * const user = await User.query().preload('posts', 'comments', { visibilty: 'public' }, 'replies').first()
490
+ * const user = await User.query().preload('posts', 'comments', { and: { visibility: 'public' } }, 'replies').first()
383
491
  * console.log(user.posts[0].comments[0].replies[0])
384
492
  * // [Reply{id: 1}, Reply{id: 2}]
385
493
  * ```
@@ -450,7 +558,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
450
558
  * @param args - A chain of association names and and/andNot/andAny clauses
451
559
  * @returns A cloned Query with the joins clause applied
452
560
  */
453
- innerJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
561
+ innerJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
454
562
  ...Arr,
455
563
  LastArg
456
564
  ]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = Query<DreamInstance, ExtendQueryType<QueryTypeOpts, Readonly<{
@@ -462,7 +570,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
462
570
  * @param args - A chain of association names and and/andNot/andAny clauses
463
571
  * @returns A cloned Query with the joins clause applied
464
572
  */
465
- leftJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
573
+ leftJoin<DB extends DreamInstance['DB'], Schema extends DreamInstance['schema'], TableName extends DreamInstance['table'], const Arr extends readonly unknown[], const LastArg extends VariadicJoinsArgs<DreamInstance, DB, Schema, TableName, Arr, LastArg>, const JoinedAssociationsCandidate = JoinedAssociationsTypeFromAssociations<DB, Schema, TableName, [
466
574
  ...Arr,
467
575
  LastArg
468
576
  ]>, const JoinedAssociations extends readonly JoinedAssociation[] = JoinedAssociationsCandidate extends readonly JoinedAssociation[] ? JoinedAssociationsCandidate : never, RetQuery = Query<DreamInstance, ExtendQueryType<QueryTypeOpts, Readonly<{
@@ -1007,10 +1115,20 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1007
1115
  * // 3
1008
1116
  * ```
1009
1117
  *
1010
- * A `limit` or `offset` on the Query cannot compose with the batch windows
1011
- * — each window replaces the limit with the batch size and the offset with
1012
- * the running window offset, silently ignoring both — so a limit- or
1013
- * offset-carrying Query throws at runtime.
1118
+ * `pluckEach` reads the rows {@link Query.findEach} visits, in the same
1119
+ * batches and the same order: ascending primary key, then, for a Query
1120
+ * that joins a HasOne or HasMany association, the joined rows' primary
1121
+ * keys, so each row the join returns is plucked once. Like `findEach`, it
1122
+ * discards the Query's `order`, an association's declared `order` and the
1123
+ * relevance ranking of a similarity condition, and it reads a Query that
1124
+ * keeps one record of each group (one that calls `distinct`, or over an
1125
+ * association that declares `distinct`) from the keys of all of its rows,
1126
+ * read before the first batch.
1127
+ *
1128
+ * A `limit` or `offset` on the Query cannot compose with the batches —
1129
+ * each batch re-applies the Query's conditions, so the limit would be
1130
+ * silently replaced by the batch size and the offset re-applied to every
1131
+ * batch — so a limit- or offset-carrying Query throws at runtime.
1014
1132
  *
1015
1133
  * @param args - a list of column names to pluck, followed by a callback function to call for each set of found fields
1016
1134
  * @returns void
@@ -1077,6 +1195,13 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1077
1195
  * // 2
1078
1196
  * ```
1079
1197
  *
1198
+ * Under a similarity condition (`ops.similarity`, `ops.wordSimilarity`,
1199
+ * `ops.strictWordSimilarity`), pages come best match first: records are
1200
+ * ordered by relevance ahead of the Query's `order` (or, without one, the
1201
+ * descending primary key). For best-match-first pages, use `paginate`
1202
+ * rather than {@link Query.cursorPaginate}, which does not order by
1203
+ * relevance.
1204
+ *
1080
1205
  * @param opts - Pagination options
1081
1206
  * @param opts.page - the page number that you want to fetch results for
1082
1207
  * @param opts.pageSize - the number of results per page (optional)
@@ -1096,9 +1221,47 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1096
1221
  * provides better performance for large datasets by using cursor-based
1097
1222
  * pagination instead of offset-based pagination.
1098
1223
  *
1099
- * Default order is ascending primary key. If an order has already been
1100
- * set on the query, and it includes the primary key (e.g.: `id: 'asc'`),
1101
- * then the implicit primary key ordering will be omitted.
1224
+ * Pages follow the Query's `order`, preceded by the `order` declared on any
1225
+ * association the Query is built on or joins (so an `associationQuery` of
1226
+ * an ordered association pages in that association's order), with
1227
+ * ascending primary key as the final tiebreaker; with neither, pages run in
1228
+ * ascending primary key order. If those orders already include the primary
1229
+ * key (e.g.: `id: 'asc'`), the implicit primary key ordering is omitted.
1230
+ *
1231
+ * A Query that joins a HasOne or HasMany association (directly, through an
1232
+ * association it joins, or as the association an `associationQuery` goes
1233
+ * through) returns a record once for each row the join matches, as
1234
+ * {@link Query.all} does, and the pages return each of those rows once,
1235
+ * sorting the rows of one record by the joined rows' primary keys after the
1236
+ * primary key. The cursor of such a Query is an opaque string that names
1237
+ * its last row by primary keys, the record's and the joined rows' (readable
1238
+ * by whoever holds it; it is not encrypted), and the next page starts after
1239
+ * that row, or, if the row is gone, after the record's first row. Any other
1240
+ * Query's cursor is its last record's primary key. A record's primary key
1241
+ * is always accepted as a cursor: the next page starts after that record's
1242
+ * first row. A cursor carries no other value its row sorts by: those are
1243
+ * read from the database when the next page is.
1244
+ *
1245
+ * A Query that calls `distinct` on its primary key (as `distinct()` does,
1246
+ * e.g.: `User.innerJoin('posts').distinct()`) returns each record once, as
1247
+ * {@link Query.all} does, and so do its pages, whose cursor is the last
1248
+ * record's primary key. A Query that calls `distinct` on another column has
1249
+ * to be ordered by that column first (e.g.:
1250
+ * `Post.distinct('category').order({ category: 'asc', createdAt: 'desc' })`),
1251
+ * or the database rejects its pages. Its pages return the records
1252
+ * {@link Query.all} returns, the one its order keeps for each value of that
1253
+ * column (the newest post of each category), and its cursor is also the
1254
+ * last record's primary key. Over an association that declares `distinct`
1255
+ * and an `order` led by its distinct column (an `associationQuery` of it, or
1256
+ * a Query that joins it), the pages return the rows {@link Query.all}
1257
+ * returns: the row the association's `order` keeps for each value of its
1258
+ * distinct column.
1259
+ *
1260
+ * A similarity condition (`ops.similarity`, `ops.wordSimilarity`,
1261
+ * `ops.strictWordSimilarity`) still decides which records match, but its
1262
+ * relevance ranking does not order the pages: a cursor can only resume from
1263
+ * values it compares, and the rank is not one of them. For best-match-first
1264
+ * pages, use {@link Query.paginate}.
1102
1265
  *
1103
1266
  * ```ts
1104
1267
  * // First page (using undefined to start from beginning)
@@ -1131,9 +1294,48 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1131
1294
  * provides better performance for large datasets by using cursor-based
1132
1295
  * pagination instead of offset-based pagination.
1133
1296
  *
1134
- * Default order is descending primary key. If an order has already been
1135
- * set on the query, and it includes the primary key (e.g.: `id: 'asc'`),
1136
- * then the implicit primary key ordering will be omitted.
1297
+ * Pages follow the Query's `order`, preceded by the `order` declared on any
1298
+ * association the Query is built on or joins (so an `associationQuery` of
1299
+ * an ordered association pages in that association's order), with
1300
+ * descending primary key as the final tiebreaker; with neither, pages run
1301
+ * in descending primary key order. If those orders already include the
1302
+ * primary key (e.g.: `id: 'asc'`), the implicit primary key ordering is
1303
+ * omitted.
1304
+ *
1305
+ * A Query that joins a HasOne or HasMany association (directly, through an
1306
+ * association it joins, or as the association an `associationQuery` goes
1307
+ * through) returns a record once for each row the join matches, as
1308
+ * {@link Query.all} does, and the pages return each of those rows once,
1309
+ * sorting the rows of one record by the joined rows' primary keys after the
1310
+ * primary key. The cursor of such a Query is an opaque string that names
1311
+ * its last row by primary keys, the record's and the joined rows' (readable
1312
+ * by whoever holds it; it is not encrypted), and the next page starts after
1313
+ * that row, or, if the row is gone, after the record's first row. Any other
1314
+ * Query's cursor is its last record's primary key. A record's primary key
1315
+ * is always accepted as a cursor: the next page starts after that record's
1316
+ * first row. A cursor carries no other value its row sorts by: those are
1317
+ * read from the database when the next page is.
1318
+ *
1319
+ * A Query that calls `distinct` on its primary key (as `distinct()` does,
1320
+ * e.g.: `User.innerJoin('posts').distinct()`) returns each record once, as
1321
+ * {@link Query.all} does, and so do its pages, whose cursor is the last
1322
+ * record's primary key. A Query that calls `distinct` on another column has
1323
+ * to be ordered by that column first (e.g.:
1324
+ * `Post.distinct('category').order({ category: 'asc', createdAt: 'desc' })`),
1325
+ * or the database rejects its pages. Its pages return the records
1326
+ * {@link Query.all} returns, the one its order keeps for each value of that
1327
+ * column (the newest post of each category), and its cursor is also the
1328
+ * last record's primary key. Over an association that declares `distinct`
1329
+ * and an `order` led by its distinct column (an `associationQuery` of it, or
1330
+ * a Query that joins it), the pages return the rows {@link Query.all}
1331
+ * returns: the row the association's `order` keeps for each value of its
1332
+ * distinct column.
1333
+ *
1334
+ * A similarity condition (`ops.similarity`, `ops.wordSimilarity`,
1335
+ * `ops.strictWordSimilarity`) still decides which records match, but its
1336
+ * relevance ranking does not order the pages: a cursor can only resume from
1337
+ * values it compares, and the rank is not one of them. For best-match-first
1338
+ * pages, use {@link Query.paginate}.
1137
1339
  *
1138
1340
  * ```ts
1139
1341
  * // First page (using undefined to start from beginning)
@@ -1160,6 +1362,21 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1160
1362
  cursorPaginate<Q extends Query<DreamInstance, any>, Incompatible extends Q['queryTypeOpts'] extends Readonly<{
1161
1363
  allowPaginate: false;
1162
1364
  }> ? true : false>(this: Q, opts: Incompatible extends true ? 'scrollPaginate is incompatible with limit, offset, and leftJoinPreload'[] : CursorPaginatedDreamQueryOptions): Promise<CursorPaginatedDreamQueryResult<DreamInstance>>;
1365
+ /**
1366
+ * @internal
1367
+ *
1368
+ * The values the row a cursor names sorts by now, in the order of
1369
+ * `orderStatements`, or undefined when no such row is found.
1370
+ *
1371
+ * Unless the primary key is the only order statement, the values are read
1372
+ * from the database, a soft-deleted record included, so that a page can
1373
+ * follow a record removed since the cursor was issued. A cursor that names its row by keys this Query's rows carry is
1374
+ * resumed from that row. Any other cursor (a primary key, as every cursor
1375
+ * issued before 2.36.0 is, or a cursor from a Query that joins other
1376
+ * associations), and a cursor whose row is gone, is resumed from the first
1377
+ * row of the record whose primary key it is or carries.
1378
+ */
1379
+ private cursorBoundaryValues;
1163
1380
  /**
1164
1381
  * Forces use of a database connection (e.g. 'primary') during the query.
1165
1382
  *
@@ -1700,12 +1917,32 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1700
1917
  * record (`reload`, `associationQuery`, ...) likewise run on a separate
1701
1918
  * connection and snapshot. Derive the attributes and return them; Dream
1702
1919
  * performs the write inside the batch's transaction.
1703
- * - **`lock: false` can throw mid-run when racing a deleter.** On the
1704
- * unlocked paths, a matched record that a concurrent transaction destroys
1705
- * between a batch's read and that record's write aborts the run with an
1706
- * error: earlier batches stay committed, and no count is returned. Use
1707
- * `lock: true` when deleters may race the update — claimed rows are held
1708
- * under their locks until written.
1920
+ * - **Without `lock: true`, a record is not re-checked before it is
1921
+ * written.** The unlocked per-record paths — an attributes object without
1922
+ * `lock: true` or `skipHooks: true`, and a callback under `lock: false` —
1923
+ * read a batch, then write each record by its primary key alone, with no
1924
+ * compare-and-set. What a concurrent delete between that read and a
1925
+ * record's write does depends on what the delete leaves behind. A soft
1926
+ * delete (`destroy()` on a `@SoftDelete` model, which generated models are
1927
+ * by default) leaves the row in place, so the write lands on the
1928
+ * soft-deleted record: its update hooks run, it is counted, and its
1929
+ * `deletedAt` stays set. A hard delete (`reallyDestroy()`, a Query's
1930
+ * `delete()`, or `destroy()` on a model without `@SoftDelete`) removes the
1931
+ * row, so that record's write throws `CannotSaveMissingDream` — after its
1932
+ * `beforeUpdate` and `beforeSave` hooks have run — and the run rejects
1933
+ * without returning a count. Every record written before it, in its own
1934
+ * batch as well as earlier ones, stays committed, unless the Query carries
1935
+ * `.txn(txn)`, which puts those writes in the caller's transaction. (A
1936
+ * record whose write turns out to be a no-op emits no SQL, so it does not
1937
+ * throw even if its row is gone, and it is counted.) The single-statement
1938
+ * `skipHooks` attributes form is one `UPDATE ... WHERE` that carries the
1939
+ * Query's default scopes, so it never writes a soft-deleted record and
1940
+ * cannot fail part-way through. Use `lock: true` when deleters may race
1941
+ * the update: its locked re-read re-applies the Query's conditions and
1942
+ * default scopes, so a soft- or hard-deleted record drops out of the run,
1943
+ * neither written nor counted. (A Query that removes the
1944
+ * `dream:SoftDelete` default scope reads and writes soft-deleted records
1945
+ * on every path.)
1709
1946
  * - **A `limit` or `offset` on the Query is incompatible with `update` on
1710
1947
  * every path.** The batched paths re-apply the Query's conditions to each
1711
1948
  * batch window, where a limit or offset would skip or truncate rows
@@ -1753,6 +1990,7 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
1753
1990
  * @throws MissingRequiredLockOptionForUpdateCallback if a callback is passed without an options object carrying a boolean `lock`
1754
1991
  * @throws BatchingIncompatibleWithLimitOrOffset if the query carries a `limit` or `offset`
1755
1992
  * @throws CannotSetEncryptedColumnInQueryUpdate if the single-statement `skipHooks` form's attributes name an `@Encrypted` backing column with anything other than `null`
1993
+ * @throws CannotSaveMissingDream if, on an unlocked per-record path, a record's row is hard-deleted between its batch's read and a write that is not a no-op
1756
1994
  */
1757
1995
  update(cb: (record: DreamInstance) => UpdateableProperties<DreamInstance> | undefined | Promise<UpdateableProperties<DreamInstance> | undefined>, options: {
1758
1996
  lock: boolean;
@@ -1830,4 +2068,5 @@ export interface QueryOpts<DreamInstance extends Dream, ColumnType extends Dream
1830
2068
  transaction?: DreamTransaction<Dream> | null | undefined;
1831
2069
  connection?: DbConnectionType | undefined;
1832
2070
  shouldReallyDestroy?: boolean | undefined;
2071
+ bypassImplicitOrder?: boolean | undefined;
1833
2072
  }