@rvoh/dream 2.34.0 → 2.36.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 (302) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/src/Dream.js +270 -69
  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 +30 -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 +49 -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 +270 -69
  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 +30 -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 +49 -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 +217 -55
  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 +20 -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 +281 -155
  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
@@ -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
  }
@@ -2,7 +2,7 @@ import { CompiledQuery, DeleteQueryBuilder, SelectQueryBuilder, UpdateQueryBuild
2
2
  import type { DreamDbConfig } from '../../dream-app/index.js';
3
3
  import Dream from '../../Dream.js';
4
4
  import { SchemaBuilderAssociationData, SchemaBuilderColumnData } from '../../helpers/cli/ASTBuilder.js';
5
- import { AssociationStatement } from '../../types/associations/shared.js';
5
+ import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
6
6
  import { DbConnectionType, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
7
7
  import { DreamColumnNames, DreamConstructorType, DreamTableSchema } from '../../types/dream.js';
8
8
  import { PreloadedDreamsAndWhatTheyPointTo, QueryToKyselyDBType, QueryToKyselyTableNamesType } from '../../types/query.js';
@@ -435,6 +435,68 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
435
435
  * @returns An array of plucked values
436
436
  */
437
437
  pluck(...fields: DreamColumnNames<DreamInstance>[]): Promise<any[]>;
438
+ /**
439
+ * @internal
440
+ *
441
+ * The order statements that the declared `order` of the associations the
442
+ * Query is built on or joins contributes to its ORDER BY, in the order they
443
+ * sort, each column namespaced by the alias it is read from. Cursor
444
+ * pagination folds these into its cursor.
445
+ *
446
+ * @returns An array of namespaced order statements
447
+ */
448
+ associationOrderStatements(): OrderQueryStatement<string>[];
449
+ /**
450
+ * @internal
451
+ *
452
+ * The primary key of each table the Query reaches through a HasOne or
453
+ * HasMany association (one it joins, one an association it joins goes
454
+ * through, or one its association query is built on), namespaced by the
455
+ * alias it is read from, in join order. Such a join can return a row of the
456
+ * Query's table once for each row it matches, and these keys, with the
457
+ * Query's own primary key, tell those rows apart. Cursor pagination pages by
458
+ * them after the Query's own primary key.
459
+ *
460
+ * @returns An array of namespaced primary key columns
461
+ */
462
+ joinedRowKeyColumns(): string[];
463
+ /**
464
+ * @internal
465
+ *
466
+ * A page of a select that keeps one row of each group (DISTINCT ON, as a
467
+ * Query that calls `distinct`, or an association that declares `distinct`,
468
+ * produces), or null for any other select, whose pages cursor pagination
469
+ * reads as it reads any select's.
470
+ *
471
+ * The page is the values of the Query's order statement columns for each
472
+ * row the select returns that matches any of `rowsAfter` (every row when it
473
+ * is null), sorted by the Query's order statements and limited by its
474
+ * limit. The select chooses each group's row before `rowsAfter` narrows the
475
+ * rows, so that the page holds only rows the select returns.
476
+ *
477
+ * A driver whose selects never keep one row of each group returns null.
478
+ *
479
+ * @param rowsAfter - where statements, any of which a row of the page matches
480
+ * @returns The page's rows, each an array of its order statement columns' values, or null
481
+ */
482
+ pluckDistinctOnPage(rowsAfter: Record<string, unknown>[] | null): Promise<unknown[][] | null>;
483
+ /**
484
+ * @internal
485
+ *
486
+ * For a select that keeps one row of each group (DISTINCT ON, as a Query
487
+ * that calls `distinct`, or an association that declares `distinct`,
488
+ * produces), the values of `rowKeyColumns` for every row it returns, sorted
489
+ * by those columns, ascending; null for any other select. `findEach` and
490
+ * `pluckEach` read a select that keeps one row of each group from these
491
+ * keys rather than by a cursor, which would narrow the select before it
492
+ * chooses each group's row.
493
+ *
494
+ * A driver whose selects never keep one row of each group returns null.
495
+ *
496
+ * @param rowKeyColumns - the namespaced columns that tell the select's rows apart
497
+ * @returns The rows' values of `rowKeyColumns`, or null
498
+ */
499
+ pluckDistinctOnRowKeys(rowKeyColumns: string[]): Promise<unknown[][] | null>;
438
500
  /**
439
501
  * Returns a new Kysely SelectQueryBuilder instance to be used
440
502
  * in a sub Query
@@ -4,7 +4,7 @@ import { DialectProviderCb } from '../../db/DreamDbConnection.js';
4
4
  import { DreamDbConfig } from '../../dream-app/index.js';
5
5
  import Dream from '../../Dream.js';
6
6
  import { SchemaBuilderInformationSchemaRow } from '../../helpers/cli/ASTBuilder.js';
7
- import { AssociationStatement } from '../../types/associations/shared.js';
7
+ import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
8
8
  import { DbConnectionType, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
9
9
  import { DreamColumnNames, DreamTableSchema, OrderDir, SqlCommandType } from '../../types/dream.js';
10
10
  import { PreloadedDreamsAndWhatTheyPointTo, QueryToKyselyDBType, QueryToKyselyTableNamesType } from '../../types/query.js';
@@ -12,6 +12,21 @@ import DreamTransaction from '../DreamTransaction.js';
12
12
  import Query from '../Query.js';
13
13
  import QueryDriverBase from './Base.js';
14
14
  export default class KyselyQueryDriver<DreamInstance extends Dream> extends QueryDriverBase<DreamInstance> {
15
+ /**
16
+ * @internal
17
+ *
18
+ * While `associationOrderStatements` builds a select, the order statements
19
+ * that association joins add to it, in the order they are added.
20
+ */
21
+ private associationOrderCollector;
22
+ /**
23
+ * @internal
24
+ *
25
+ * While `joinedRowKeyColumns` builds a select, the namespaced primary keys of
26
+ * the tables that HasOne and HasMany joins add to it, in the order they are
27
+ * added.
28
+ */
29
+ private joinedRowKeyCollector;
15
30
  dbFor(sqlCommandType: SqlCommandType): Kysely<DreamInstance['DB']> | KyselyTransaction<DreamInstance['DB']>;
16
31
  static dbFor<I extends Dream>(connectionName: string, dbConnectionType: DbConnectionType, dreamTransaction?: DreamTransaction<I> | null): Kysely<I['DB']> | KyselyTransaction<I['DB']>;
17
32
  static dialectProvider(connectionName: string, dbConnectionType: DbConnectionType): DialectProviderCb;
@@ -400,6 +415,75 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
400
415
  }>;
401
416
  private buildDelete;
402
417
  private buildSelect;
418
+ /**
419
+ * @internal
420
+ *
421
+ * The select's source, joins, conditions, DISTINCT ON and similarity
422
+ * ranking, before the Query's own order statements, limit, offset and
423
+ * selection are applied, together with the connection the select runs on.
424
+ */
425
+ private buildSelectCore;
426
+ /**
427
+ * @internal
428
+ *
429
+ * The order statements that the declared `order` of the associations the
430
+ * Query is built on or joins contributes to its ORDER BY, in the order they
431
+ * sort, each column namespaced by the alias it is read from. They are read
432
+ * off the same join code that emits them, by building the select.
433
+ *
434
+ * @returns An array of namespaced order statements
435
+ */
436
+ associationOrderStatements(): OrderQueryStatement<string>[];
437
+ /**
438
+ * @internal
439
+ *
440
+ * The primary key of each table the Query reaches through a HasOne or
441
+ * HasMany association (one it joins, one an association it joins goes
442
+ * through, or one its association query is built on), namespaced by the
443
+ * alias it is read from, in join order. They are read off the same join code
444
+ * that emits the joins, by building the select.
445
+ *
446
+ * @returns An array of namespaced primary key columns
447
+ */
448
+ joinedRowKeyColumns(): string[];
449
+ /**
450
+ * @internal
451
+ *
452
+ * A page of a select that carries DISTINCT ON (as a Query that calls
453
+ * `distinct`, or an association that declares `distinct`, produces), or null
454
+ * for any other select.
455
+ *
456
+ * Such a select keeps the row of each group that sorts first in its ORDER
457
+ * BY, so narrowing it to the rows after a cursor would let it keep a row it
458
+ * does not return (a group's later row, once the cursor has passed the
459
+ * group's first). It is read as a derived table instead, and narrowed to
460
+ * `rowsAfter`, sorted and limited outside it. The Query's order statements
461
+ * follow the select's own ORDER BY, if it has one, so that the select keeps
462
+ * the same row of each group every time it runs, and each of their columns
463
+ * is read out of it under a short alias (as `pluck` reads them), since a
464
+ * joined table's column cannot be named outside it.
465
+ *
466
+ * @param rowsAfter - where statements, any of which a row of the page matches
467
+ * @returns The page's rows, each an array of its order statement columns' values, or null
468
+ */
469
+ pluckDistinctOnPage(rowsAfter: Record<string, unknown>[] | null): Promise<unknown[][] | null>;
470
+ /**
471
+ * @internal
472
+ *
473
+ * For a select that carries DISTINCT ON (as a Query that calls `distinct`,
474
+ * or an association that declares `distinct`, produces), the values of
475
+ * `rowKeyColumns` for every row it returns, sorted by those columns,
476
+ * ascending; null for any other select.
477
+ *
478
+ * The select runs as `all()` runs it, with its own ORDER BY choosing each
479
+ * group's row, and is read as a derived table, sorted outside it. Each of
480
+ * `rowKeyColumns` is read out of it under a short alias (as `pluck` reads
481
+ * them), since a joined table's column cannot be named outside it.
482
+ *
483
+ * @param rowKeyColumns - the namespaced columns that tell the select's rows apart
484
+ * @returns The rows' values of `rowKeyColumns`, or null
485
+ */
486
+ pluckDistinctOnRowKeys(rowKeyColumns: string[]): Promise<unknown[][] | null>;
403
487
  orderByDirection(direction: OrderDir | null): (obj: OrderByItemBuilder) => OrderByItemBuilder;
404
488
  private buildUpdate;
405
489
  /**
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The keys a condition object on an association accepts, whether it is
3
+ * passed in a chain (`preload('posts', { and: { ... } })`), returned from a
4
+ * `preloadFor`/`loadFor` modifier, or passed to `associationQuery`.
5
+ */
6
+ export declare const ASSOCIATION_CONDITION_KEYS: readonly ["and", "andNot", "andAny"];
7
+ /**
8
+ * The keys accepted by `destroyAssociation`, `reallyDestroyAssociation`
9
+ * and `undestroyAssociation`.
10
+ */
11
+ export declare const DESTROY_ASSOCIATION_OPTION_KEYS: readonly ["and", "andNot", "andAny", "bypassAllDefaultScopes", "defaultScopesToBypass", "cascade", "skipHooks"];
12
+ /**
13
+ * The keys accepted by `updateAssociation`.
14
+ */
15
+ export declare const UPDATE_ASSOCIATION_OPTION_KEYS: readonly ["and", "andNot", "andAny", "bypassAllDefaultScopes", "defaultScopesToBypass", "skipHooks"];
16
+ /**
17
+ * Throws UnrecognizedAssociationConditionKeys when `value` is an object
18
+ * carrying any own key outside `acceptedKeys`, including a key whose value
19
+ * is `undefined`. Dream reads only the accepted keys, so an unrecognized key
20
+ * would otherwise be silently ignored (and, for the destroy family, act on
21
+ * every associated row instead of the ones the caller meant to select).
22
+ * Non-object values (`undefined`, `null`) pass through untouched.
23
+ *
24
+ * @param value - The condition object or options object to check
25
+ * @param acceptedKeys - The keys `value` may carry
26
+ * @param associationName - The association the object applies to, for the error message
27
+ * @param methodName - The public method the options were passed to, or null for a chain condition
28
+ */
29
+ export default function assertRecognizedAssociationConditionKeys(value: unknown, acceptedKeys: readonly string[], associationName: string | number | symbol, methodName?: string | null): void;