@rvoh/dream 2.18.1 → 2.20.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 (265) hide show
  1. package/dist/cjs/src/Dream.js +186 -0
  2. package/dist/cjs/src/db/DreamDbConnection.js +6 -0
  3. package/dist/cjs/src/decorators/class/SoftDelete.js +12 -0
  4. package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +113 -0
  5. package/dist/cjs/src/dream/Query.js +148 -0
  6. package/dist/cjs/src/dream/QueryDriver/Base.js +84 -0
  7. package/dist/cjs/src/dream/QueryDriver/Kysely.js +420 -81
  8. package/dist/cjs/src/dream/internal/filterRowToKnownColumns.js +41 -0
  9. package/dist/cjs/src/dream/internal/saveDream.js +6 -1
  10. package/dist/cjs/src/dream/internal/sqlResultToDreamInstance.js +9 -2
  11. package/dist/cjs/src/errors/CannotNamespaceAssociationFilterToAnotherTable.js +27 -0
  12. package/dist/cjs/src/errors/schema-builder/CannotIgnoreAssociationColumn.js +38 -0
  13. package/dist/cjs/src/errors/schema-builder/CannotIgnoreEncryptedColumn.js +20 -0
  14. package/dist/cjs/src/errors/schema-builder/CannotIgnorePrimaryKey.js +18 -0
  15. package/dist/cjs/src/errors/schema-builder/CannotIgnoreSoftDeleteColumn.js +21 -0
  16. package/dist/cjs/src/errors/schema-builder/CannotIgnoreSortablePositionColumn.js +20 -0
  17. package/dist/cjs/src/errors/schema-builder/CannotIgnoreSortableScopeColumn.js +24 -0
  18. package/dist/cjs/src/errors/schema-builder/CannotIgnoreStiTypeColumn.js +17 -0
  19. package/dist/cjs/src/errors/schema-builder/ConflictingIgnoredColumns.js +27 -0
  20. package/dist/cjs/src/errors/schema-builder/IgnoredColumnMustBeCamelCase.js +21 -0
  21. package/dist/cjs/src/helpers/cli/ASTConnectionBuilder.js +38 -1
  22. package/dist/cjs/src/helpers/cli/ASTKyselyCodegenEnhancer.js +60 -0
  23. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +21 -13
  24. package/dist/cjs/src/helpers/cli/resolveIgnoredColumns.js +198 -0
  25. package/dist/esm/src/Dream.js +186 -0
  26. package/dist/esm/src/db/DreamDbConnection.js +6 -0
  27. package/dist/esm/src/decorators/class/SoftDelete.js +12 -0
  28. package/dist/esm/src/dream/DreamClassTransactionBuilder.js +113 -0
  29. package/dist/esm/src/dream/Query.js +148 -0
  30. package/dist/esm/src/dream/QueryDriver/Base.js +84 -0
  31. package/dist/esm/src/dream/QueryDriver/Kysely.js +420 -81
  32. package/dist/esm/src/dream/internal/filterRowToKnownColumns.js +41 -0
  33. package/dist/esm/src/dream/internal/saveDream.js +6 -1
  34. package/dist/esm/src/dream/internal/sqlResultToDreamInstance.js +9 -2
  35. package/dist/esm/src/errors/CannotNamespaceAssociationFilterToAnotherTable.js +27 -0
  36. package/dist/esm/src/errors/schema-builder/CannotIgnoreAssociationColumn.js +38 -0
  37. package/dist/esm/src/errors/schema-builder/CannotIgnoreEncryptedColumn.js +20 -0
  38. package/dist/esm/src/errors/schema-builder/CannotIgnorePrimaryKey.js +18 -0
  39. package/dist/esm/src/errors/schema-builder/CannotIgnoreSoftDeleteColumn.js +21 -0
  40. package/dist/esm/src/errors/schema-builder/CannotIgnoreSortablePositionColumn.js +20 -0
  41. package/dist/esm/src/errors/schema-builder/CannotIgnoreSortableScopeColumn.js +24 -0
  42. package/dist/esm/src/errors/schema-builder/CannotIgnoreStiTypeColumn.js +17 -0
  43. package/dist/esm/src/errors/schema-builder/ConflictingIgnoredColumns.js +27 -0
  44. package/dist/esm/src/errors/schema-builder/IgnoredColumnMustBeCamelCase.js +21 -0
  45. package/dist/esm/src/helpers/cli/ASTConnectionBuilder.js +38 -1
  46. package/dist/esm/src/helpers/cli/ASTKyselyCodegenEnhancer.js +60 -0
  47. package/dist/esm/src/helpers/cli/generateMigrationContent.js +21 -13
  48. package/dist/esm/src/helpers/cli/resolveIgnoredColumns.js +198 -0
  49. package/dist/types/src/Dream.d.ts +178 -4
  50. package/dist/types/src/decorators/class/SoftDelete.d.ts +12 -0
  51. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +103 -0
  52. package/dist/types/src/dream/Query.d.ts +138 -0
  53. package/dist/types/src/dream/QueryDriver/Base.d.ts +69 -0
  54. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +187 -8
  55. package/dist/types/src/dream/internal/filterRowToKnownColumns.d.ts +30 -0
  56. package/dist/types/src/errors/CannotNamespaceAssociationFilterToAnotherTable.d.ts +8 -0
  57. package/dist/types/src/errors/schema-builder/CannotIgnoreAssociationColumn.d.ts +12 -0
  58. package/dist/types/src/errors/schema-builder/CannotIgnoreEncryptedColumn.d.ts +7 -0
  59. package/dist/types/src/errors/schema-builder/CannotIgnorePrimaryKey.d.ts +6 -0
  60. package/dist/types/src/errors/schema-builder/CannotIgnoreSoftDeleteColumn.d.ts +7 -0
  61. package/dist/types/src/errors/schema-builder/CannotIgnoreSortablePositionColumn.d.ts +7 -0
  62. package/dist/types/src/errors/schema-builder/CannotIgnoreSortableScopeColumn.d.ts +8 -0
  63. package/dist/types/src/errors/schema-builder/CannotIgnoreStiTypeColumn.d.ts +6 -0
  64. package/dist/types/src/errors/schema-builder/ConflictingIgnoredColumns.d.ts +7 -0
  65. package/dist/types/src/errors/schema-builder/IgnoredColumnMustBeCamelCase.d.ts +7 -0
  66. package/dist/types/src/helpers/cli/ASTConnectionBuilder.d.ts +20 -0
  67. package/dist/types/src/helpers/cli/ASTKyselyCodegenEnhancer.d.ts +13 -0
  68. package/dist/types/src/helpers/cli/resolveIgnoredColumns.d.ts +41 -0
  69. package/dist/types/src/types/associations/shared.d.ts +4 -1
  70. package/dist/types/src/types/dream.d.ts +17 -0
  71. package/dist/types/src/types/types/associations/shared.ts +10 -1
  72. package/dist/types/src/types/types/dream.ts +53 -0
  73. package/dist/types/src/types/types/variadic.ts +179 -140
  74. package/dist/types/src/types/variadic.d.ts +15 -10
  75. package/docs/assets/hierarchy.js +1 -1
  76. package/docs/assets/search.js +1 -1
  77. package/docs/classes/db.DreamMigrationHelpers.html +11 -11
  78. package/docs/classes/db.KyselyQueryDriver.html +96 -34
  79. package/docs/classes/db.PostgresQueryDriver.html +97 -35
  80. package/docs/classes/db.QueryDriverBase.html +77 -33
  81. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  82. package/docs/classes/errors.ColumnOverflow.html +3 -3
  83. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  84. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  85. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  86. package/docs/classes/errors.DecryptionError.html +2 -2
  87. package/docs/classes/errors.DecryptionParseError.html +2 -2
  88. package/docs/classes/errors.DecryptionRotationError.html +3 -3
  89. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  90. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  91. package/docs/classes/errors.InvalidClockTime.html +2 -2
  92. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  93. package/docs/classes/errors.InvalidDateTime.html +2 -2
  94. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  95. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  96. package/docs/classes/errors.NotNullViolation.html +3 -3
  97. package/docs/classes/errors.RecordNotFound.html +3 -3
  98. package/docs/classes/errors.ValidationError.html +3 -3
  99. package/docs/classes/index.CalendarDate.html +33 -33
  100. package/docs/classes/index.ClockTime.html +32 -32
  101. package/docs/classes/index.ClockTimeTz.html +35 -35
  102. package/docs/classes/index.DateTime.html +86 -86
  103. package/docs/classes/index.Decorators.html +19 -19
  104. package/docs/classes/index.Dream.html +247 -119
  105. package/docs/classes/index.DreamApp.html +10 -10
  106. package/docs/classes/index.DreamTransaction.html +2 -2
  107. package/docs/classes/index.Env.html +2 -2
  108. package/docs/classes/index.Query.html +155 -57
  109. package/docs/classes/system.CliFileWriter.html +4 -4
  110. package/docs/classes/system.DreamBin.html +2 -2
  111. package/docs/classes/system.DreamCLI.html +7 -7
  112. package/docs/classes/system.DreamImporter.html +2 -2
  113. package/docs/classes/system.DreamLogos.html +2 -2
  114. package/docs/classes/system.DreamSerializerBuilder.html +11 -11
  115. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  116. package/docs/classes/system.PathHelpers.html +3 -3
  117. package/docs/classes/utils.Encrypt.html +3 -3
  118. package/docs/classes/utils.Range.html +2 -2
  119. package/docs/functions/db.closeAllDbConnections.html +1 -1
  120. package/docs/functions/db.dreamDbConnections.html +1 -1
  121. package/docs/functions/db.untypedDb.html +1 -1
  122. package/docs/functions/db.validateColumn.html +1 -1
  123. package/docs/functions/db.validateTable.html +1 -1
  124. package/docs/functions/errors.pgErrorType.html +1 -1
  125. package/docs/functions/index.DreamSerializer.html +1 -1
  126. package/docs/functions/index.ObjectSerializer.html +1 -1
  127. package/docs/functions/index.ReplicaSafe.html +1 -1
  128. package/docs/functions/index.STI.html +1 -1
  129. package/docs/functions/index.SoftDelete.html +12 -1
  130. package/docs/functions/utils.camelize.html +1 -1
  131. package/docs/functions/utils.capitalize.html +1 -1
  132. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  133. package/docs/functions/utils.compact.html +1 -1
  134. package/docs/functions/utils.groupBy.html +1 -1
  135. package/docs/functions/utils.hyphenize.html +1 -1
  136. package/docs/functions/utils.intersection.html +1 -1
  137. package/docs/functions/utils.isEmpty.html +1 -1
  138. package/docs/functions/utils.normalizeUnicode.html +1 -1
  139. package/docs/functions/utils.pascalize.html +1 -1
  140. package/docs/functions/utils.percent.html +1 -1
  141. package/docs/functions/utils.range.html +1 -1
  142. package/docs/functions/utils.round.html +1 -1
  143. package/docs/functions/utils.sanitizeString.html +1 -1
  144. package/docs/functions/utils.snakeify.html +1 -1
  145. package/docs/functions/utils.sort.html +1 -1
  146. package/docs/functions/utils.sortBy.html +1 -1
  147. package/docs/functions/utils.sortObjectByKey.html +1 -1
  148. package/docs/functions/utils.sortObjectByValue.html +1 -1
  149. package/docs/functions/utils.uncapitalize.html +1 -1
  150. package/docs/functions/utils.uniq.html +1 -1
  151. package/docs/hierarchy.html +1 -1
  152. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  153. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  154. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  155. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  156. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  157. package/docs/interfaces/types.DecoratorContext.html +2 -2
  158. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  159. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  160. package/docs/interfaces/types.DreamDbConfig.html +5 -5
  161. package/docs/interfaces/types.DurationObject.html +2 -2
  162. package/docs/interfaces/types.EncryptOptions.html +2 -2
  163. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  164. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  165. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  166. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  167. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  168. package/docs/types/openapi.OpenapiFormats.html +1 -1
  169. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  170. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  171. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  172. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  173. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  174. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  175. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  176. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  177. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  178. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +2 -2
  179. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +2 -2
  180. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +2 -2
  181. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  182. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  183. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  184. package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
  185. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  186. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  187. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  188. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  189. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
  190. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  191. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  192. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  193. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
  194. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
  195. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  196. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  197. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +2 -2
  198. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +2 -2
  199. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +2 -2
  200. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  201. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  202. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  203. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  204. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  205. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  206. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  207. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  208. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  209. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  210. package/docs/types/types.CalendarDateObject.html +1 -1
  211. package/docs/types/types.Camelized.html +1 -1
  212. package/docs/types/types.ClockTimeObject.html +1 -1
  213. package/docs/types/types.DbConnectionType.html +1 -1
  214. package/docs/types/types.DbTypes.html +1 -1
  215. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  216. package/docs/types/types.DreamAttributes.html +1 -1
  217. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  218. package/docs/types/types.DreamClassColumn.html +1 -1
  219. package/docs/types/types.DreamColumn.html +1 -1
  220. package/docs/types/types.DreamColumnNames.html +1 -1
  221. package/docs/types/types.DreamLogLevel.html +1 -1
  222. package/docs/types/types.DreamLogger.html +2 -2
  223. package/docs/types/types.DreamModelSerializerType.html +1 -1
  224. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  225. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  226. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  227. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  228. package/docs/types/types.DreamSerializable.html +1 -1
  229. package/docs/types/types.DreamSerializableArray.html +1 -1
  230. package/docs/types/types.DreamSerializerKey.html +1 -1
  231. package/docs/types/types.DreamSerializers.html +1 -1
  232. package/docs/types/types.DreamVirtualColumns.html +1 -1
  233. package/docs/types/types.DurationUnit.html +1 -1
  234. package/docs/types/types.EncryptAlgorithm.html +1 -1
  235. package/docs/types/types.HasManyStatement.html +1 -1
  236. package/docs/types/types.HasOneStatement.html +1 -1
  237. package/docs/types/types.Hyphenized.html +1 -1
  238. package/docs/types/types.Pascalized.html +1 -1
  239. package/docs/types/types.PrimaryKeyType.html +1 -1
  240. package/docs/types/types.RoundingPrecision.html +1 -1
  241. package/docs/types/types.SerializerCasing.html +1 -1
  242. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  243. package/docs/types/types.Snakeified.html +1 -1
  244. package/docs/types/types.StrictInterface.html +1 -1
  245. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  246. package/docs/types/types.UpdateableProperties.html +1 -1
  247. package/docs/types/types.ValidationType.html +1 -1
  248. package/docs/types/types.ViewModel.html +2 -2
  249. package/docs/types/types.ViewModelClass.html +1 -1
  250. package/docs/types/types.WeekdayName.html +1 -1
  251. package/docs/types/types.WhereStatementForDream.html +1 -1
  252. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  253. package/docs/variables/index.DreamConst.html +1 -1
  254. package/docs/variables/index.ops.html +1 -1
  255. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  256. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  257. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  258. package/docs/variables/system.primaryKeyTypes.html +1 -1
  259. package/package.json +3 -3
  260. package/dist/cjs/src/dream/internal/associations/throughAssociationHasOptionsBesidesThroughAndSource.js +0 -11
  261. package/dist/cjs/src/errors/associations/ThroughAssociationConditionsIncompatibleWithThroughAssociationSource.js +0 -17
  262. package/dist/esm/src/dream/internal/associations/throughAssociationHasOptionsBesidesThroughAndSource.js +0 -11
  263. package/dist/esm/src/errors/associations/ThroughAssociationConditionsIncompatibleWithThroughAssociationSource.js +0 -17
  264. package/dist/types/src/dream/internal/associations/throughAssociationHasOptionsBesidesThroughAndSource.d.ts +0 -13
  265. package/dist/types/src/errors/associations/ThroughAssociationConditionsIncompatibleWithThroughAssociationSource.d.ts +0 -12
@@ -157,6 +157,20 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
157
157
  *
158
158
  */
159
159
  max(columnName: string): Promise<any>;
160
+ /**
161
+ * Retrieves the max value of the specified column within each group,
162
+ * keyed by the value of the provided group column.
163
+ *
164
+ * ```ts
165
+ * await CompositionAsset.query().maxBy('name', 'score')
166
+ * // Map(2) { 'primary' => 9, 'secondary' => 4 }
167
+ * ```
168
+ *
169
+ * @param groupColumn - the column to group by (base or joined-association-namespaced)
170
+ * @param aggregatedColumn - the column to take the max of within each group
171
+ * @returns A Map from each present group value to the max of the aggregated column in that group
172
+ */
173
+ maxBy(groupColumn: string, aggregatedColumn: string): Promise<Map<any, any>>;
160
174
  /**
161
175
  * Retrieves the min value of the specified column
162
176
  * for this Query
@@ -170,6 +184,20 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
170
184
  * @returns the min value of the specified column for this Query
171
185
  */
172
186
  min(columnName: string): Promise<any>;
187
+ /**
188
+ * Retrieves the min value of the specified column within each group,
189
+ * keyed by the value of the provided group column.
190
+ *
191
+ * ```ts
192
+ * await CompositionAsset.query().minBy('name', 'score')
193
+ * // Map(2) { 'primary' => 1, 'secondary' => 4 }
194
+ * ```
195
+ *
196
+ * @param groupColumn - the column to group by (base or joined-association-namespaced)
197
+ * @param aggregatedColumn - the column to take the min of within each group
198
+ * @returns A Map from each present group value to the min of the aggregated column in that group
199
+ */
200
+ minBy(groupColumn: string, aggregatedColumn: string): Promise<Map<any, any>>;
173
201
  /**
174
202
  * Retrieves the sum value of the specified column
175
203
  * for this Query
@@ -183,6 +211,20 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
183
211
  * @returns the sum of the values of the specified column for this Query
184
212
  */
185
213
  sum(columnName: string): Promise<any>;
214
+ /**
215
+ * Retrieves the sum of the specified column within each group,
216
+ * keyed by the value of the provided group column.
217
+ *
218
+ * ```ts
219
+ * await CompositionAsset.query().sumBy('name', 'score')
220
+ * // Map(2) { 'primary' => 10, 'secondary' => 4 }
221
+ * ```
222
+ *
223
+ * @param groupColumn - the column to group by (base or joined-association-namespaced)
224
+ * @param aggregatedColumn - the column to sum within each group
225
+ * @returns A Map from each present group value to the sum of the aggregated column in that group
226
+ */
227
+ sumBy(groupColumn: string, aggregatedColumn: string): Promise<Map<any, any>>;
186
228
  /**
187
229
  * Retrieves the average value of the specified column
188
230
  * for this Query
@@ -196,6 +238,20 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
196
238
  * @returns the average of the values of the specified column for this Query
197
239
  */
198
240
  avg(columnName: string): Promise<any>;
241
+ /**
242
+ * Retrieves the average of the specified column within each group,
243
+ * keyed by the value of the provided group column.
244
+ *
245
+ * ```ts
246
+ * await CompositionAsset.query().avgBy('name', 'score')
247
+ * // Map(2) { 'primary' => 5, 'secondary' => 4 }
248
+ * ```
249
+ *
250
+ * @param groupColumn - the column to group by (base or joined-association-namespaced)
251
+ * @param aggregatedColumn - the column to average within each group
252
+ * @returns A Map from each present group value to the average of the aggregated column in that group
253
+ */
254
+ avgBy(groupColumn: string, aggregatedColumn: string): Promise<Map<any, any>>;
199
255
  /**
200
256
  * Retrieves the number of records in the database
201
257
  *
@@ -206,6 +262,38 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
206
262
  * @returns The number of records in the database
207
263
  */
208
264
  count(): Promise<number>;
265
+ /**
266
+ * Retrieves the number of records in each group, keyed by the
267
+ * value of the provided group column.
268
+ *
269
+ * ```ts
270
+ * await User.query().countBy('name')
271
+ * // Map(2) { 'fred' => 2, 'zed' => 1 }
272
+ * ```
273
+ *
274
+ * @param groupColumn - the column to group by (base or joined-association-namespaced)
275
+ * @returns A Map from each present group value to the number of records in that group
276
+ */
277
+ countBy(groupColumn: string): Promise<Map<any, number>>;
278
+ /**
279
+ * @internal
280
+ *
281
+ * Shared plumbing for grouped aggregates (`countBy` and the value-aggregate
282
+ * siblings `minBy` / `maxBy` / `sumBy` / `avgBy`). Selects the group column
283
+ * alongside a single aggregate expression, groups by the group column, executes,
284
+ * and folds the resulting rows into a Map keyed by the group value.
285
+ *
286
+ * The group column and the aggregate are selected under stable, underscore-free
287
+ * aliases so they can be read back off each row without being affected by
288
+ * Kysely's CamelCasePlugin (which would otherwise mangle a namespaced alias),
289
+ * mirroring the short-alias strategy used by `pluck`.
290
+ *
291
+ * @param groupColumn - the column to GROUP BY (base or joined-association-namespaced)
292
+ * @param aggregateExpression - the Kysely aggregate expression to select per group (e.g. `count(pk)`)
293
+ * @param coerceValue - maps each raw aggregate value to the value stored in the returned Map
294
+ * @returns A Map from each present group value to its coerced aggregate value
295
+ */
296
+ private groupedAggregate;
209
297
  /**
210
298
  * @internal
211
299
  *
@@ -244,6 +332,27 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
244
332
  * is provided as a second argument, it will use that transaction
245
333
  * to encapsulate the persisting of the dream, as well as any
246
334
  * subsequent model hooks that are fired.
335
+ *
336
+ * `RETURNING *` (rather than enumerating the compiled column list) keeps
337
+ * writes working under schema/image skew: during a rolling deploy, a
338
+ * container built before a drop-column migration would otherwise name the
339
+ * dropped column in `RETURNING` and fail with `42703 column does not
340
+ * exist` on every write, even writes that never touch that column. The
341
+ * `SET`/`VALUES` half still names only dirty attributes, so a write that
342
+ * actually sets a dropped column still fails loudly. The returned row is
343
+ * filtered to the compiled column list before hydration (see
344
+ * internal/saveDream.ts), so a column the image doesn't know about never
345
+ * reaches `setAttributes`.
346
+ *
347
+ * KNOWN CONSTRAINT: star-selects are only safe because nothing in this
348
+ * stack uses named prepared statements — node-postgres prepares a
349
+ * statement only when given an explicit `name`, and Kysely never names
350
+ * them, so every query is re-planned. With named prepared statements, a
351
+ * concurrent `ADD COLUMN` changes a cached plan's result shape and
352
+ * Postgres raises `cached plan must not change result type` (the reason
353
+ * Rails added `enumerate_columns_in_select_statements`). If a future
354
+ * driver or pooling layer enables named prepared statements, revisit
355
+ * every `RETURNING *` / `select *` in this driver.
247
356
  */
248
357
  static saveDream(dream: Dream, txn?: DreamTransaction<Dream> | null): Promise<any>;
249
358
  dbConnectionType(sqlCommandType: SqlCommandType): DbConnectionType;
@@ -319,6 +428,48 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
319
428
  private inArrayWithNull_or_notInArrayWithoutNull_ExpressionBuilder;
320
429
  private inArrayWithoutNullExpressionBuilder;
321
430
  private notInArrayWithNullExpressionBuilder;
431
+ /**
432
+ * @internal
433
+ *
434
+ * A Dream instance (or array of Dream instances) as a where-clause value is
435
+ * resolved as an association of the dreamClass whose statement is being
436
+ * compiled, so a key namespaced to a different table (e.g.
437
+ * `where({ 'c.user': user })` after `innerJoin('composition as c')`) would
438
+ * silently resolve the association against the wrong class, emitting invalid
439
+ * SQL or SQL that filters the wrong table. Such keys are already rejected at
440
+ * the type level; this guard rejects them at runtime. Un-namespaced keys and
441
+ * keys namespaced to the alias the statement applies to are unaffected, as
442
+ * are callers that do not declare an expected alias.
443
+ */
444
+ private validateAssociationFilterAlias;
445
+ /**
446
+ * @internal
447
+ *
448
+ * An array under an association name can only be an array of Dream instances
449
+ * (association names are not columns). The every-element check simply avoids
450
+ * changing the handling of invalid runtime input (e.g. an array of ids under
451
+ * an association name), which the type system already rejects.
452
+ */
453
+ private isAssociationInstanceArray;
454
+ /**
455
+ * @internal
456
+ *
457
+ * Expands an array of Dream instances under a BelongsTo association name into
458
+ * foreign key filtering:
459
+ * - non-polymorphic: `foreignKey IN (...)`
460
+ * - polymorphic: instances are grouped by their reference type (STI children
461
+ * collapse into their base class), each group becoming
462
+ * `(foreignKey IN (...) AND foreignKeyTypeField = 'TheType')`, with multiple
463
+ * groups ORed together
464
+ * - empty array: matches nothing (FALSE); when the caller negates, NOT(FALSE)
465
+ * matches everything, mirroring empty `in`/`not in` array semantics
466
+ *
467
+ * When `negate` is set, IS NOT NULL conditions are included so that the
468
+ * caller's negation also matches records in which the foreign key (or type
469
+ * field) is null, consistent with negation of single Dream instances and of
470
+ * `in` arrays.
471
+ */
472
+ private associationInstanceArrayToExpressionWrapper;
322
473
  private dreamWhereStatementToExpressionBuilderParts;
323
474
  private normalizedWhereValue;
324
475
  private recursivelyJoin;
@@ -466,26 +617,54 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
466
617
  * public b
467
618
  * ```
468
619
  *
620
+ * Options declared on a through association (`and`/`andAny`/`andNot`/`selfAnd`/
621
+ * `selfAndNot`/`order`/`distinct`) are applied at the join of the table where the
622
+ * through association's target model materializes. When a source is itself a
623
+ * through association, that join is only reached after bridging further through
624
+ * associations, so each through association is pushed onto the
625
+ * `previousThroughAssociations` stack (along with the alias `selfAnd`/`selfAndNot`
626
+ * clauses reference) before the terminal `applyOneJoin` call, and the stack is
627
+ * threaded through every recursion until `addAssociationJoinStatementToQuery`
628
+ * reaches a concrete (non-through) association, where every stacked entry is
629
+ * applied to that join.
630
+ *
469
631
  * Then `MyModel.leftJoinPreload('myB')` is processed as follows:
470
632
  * - `applyOneJoin` is called with the `myB` association
471
633
  * - `joinsBridgeThroughAssociations` is called with the `myB` association
472
634
  * - `joinsBridgeThroughAssociations` is called with the `myA` association
473
635
  * - `addAssociationJoinStatementToQuery` is called with the `otherModel` association
474
- * - `applyOneJoin` is called with the `a` association from OtherModel
475
- * - `joinsBridgeThroughAssociations` is called with the `a` association from OtherModel
476
- * // throw ThroughAssociationConditionsIncompatibleWithThroughAssociationSource if
477
- * // myA in MyModel defines conditions, distinct, or order
636
+ * - `applyOneJoin` is called with the `a` association from OtherModel, with `myA` pushed
637
+ * onto the previousThroughAssociations stack
638
+ * - `joinsBridgeThroughAssociations` is called with the `a` association from OtherModel,
639
+ * inheriting the stack
478
640
  * - `addAssociationJoinStatementToQuery` is called with the `aToOtherModelJoinModel` association
479
- * - `applyOneJoin` is called with the `a` association from AToOtherModelJoinModel with conditions (if present) on `a` defined on OtherModel
480
- * - `addAssociationJoinStatementToQuery` is called with the `myA` association
481
- * - `applyOneJoin` is called with the `b` association from A with conditions (if present) from `myB` defined on MyModel
482
- * - `addAssociationJoinStatementToQuery` is called with the `myB` association
641
+ * - `applyOneJoin` is called with the `a` association from AToOtherModelJoinModel, with the
642
+ * `a` association from OtherModel pushed onto the stack
643
+ * - `addAssociationJoinStatementToQuery` is called with the `a` association from
644
+ * AToOtherModelJoinModel, applying the options (if present) of every stacked through
645
+ * association (`myA` defined on MyModel, `a` defined on OtherModel) to the `through_as` join
646
+ * - `applyOneJoin` is called with the `b` association from A, with `myB` pushed onto the stack
647
+ * - `addAssociationJoinStatementToQuery` is called with the `b` association from A, applying
648
+ * the options (if present) of `myB` defined on MyModel to the `through_bs` join
483
649
  */
484
650
  private joinsBridgeThroughAssociations;
485
651
  private applyOneJoin;
486
652
  private addAssociationJoinStatementToQuery;
487
653
  private applyOrderStatementForAssociation;
488
654
  private distinctColumnNameForAssociation;
655
+ /**
656
+ * Applies the and-family clauses (`and`/`andAny`/`andNot`/`selfAnd`/`selfAndNot`)
657
+ * of every pending through association to the terminal concrete join of a
658
+ * through association chain.
659
+ *
660
+ * The first entry in the stack is the association the developer named in the
661
+ * join/preload/associationQuery statement, so it is the association the
662
+ * developer-supplied joinAndStatement corresponds to (used to satisfy
663
+ * `DreamConst.required` clauses); `DreamConst.required` on any other stacked
664
+ * through association cannot be satisfied and will throw
665
+ * `MissingRequiredAssociationAndClause`.
666
+ */
667
+ private applyPreviousThroughAssociationAndStatementsToJoinStatement;
489
668
  private applyAssociationAndStatementsToJoinStatement;
490
669
  private throwUnlessAllRequiredWhereClausesProvided;
491
670
  private conditionallyApplyDefaultScopesDependentOnAssociation;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @internal
3
+ *
4
+ * Returns an object containing only the keys of `row` that are columns
5
+ * the compiled schema knows about (per the provided column set).
6
+ *
7
+ * Under schema/image skew (e.g. a rolling deploy in which a migration adds
8
+ * a column while containers built against the previous schema are still
9
+ * draining, or application code is rolled back after an add-column
10
+ * migration), a `RETURNING *` / `select *` row can include columns this
11
+ * build has never heard of. Passing such keys to `setAttributes` would
12
+ * assign them as plain properties — invoking a same-named user-defined
13
+ * setter, or throwing on a getter-only property — so they must be dropped
14
+ * before hydration.
15
+ *
16
+ * Keys are intersected rather than enumerated from the column set so that
17
+ * a column missing from the row (the dropped-column direction of skew)
18
+ * simply does not appear, rather than appearing with an `undefined` value.
19
+ *
20
+ * Identity fast path: when every key of `row` is a known column (the
21
+ * no-skew steady state), `row` itself is returned unchanged, without
22
+ * allocating a copy; a filtered copy is built only when at least one
23
+ * unknown key is present.
24
+ *
25
+ * @param row - a raw database row
26
+ * @param columns - the compiled column set for the Dream class being hydrated
27
+ * @returns `row` itself when every key is a known column; otherwise a new
28
+ * object containing only the known-column entries of `row`
29
+ */
30
+ export default function filterRowToKnownColumns(row: Record<string, any>, columns: Set<string>): Record<string, any>;
@@ -0,0 +1,8 @@
1
+ import Dream from '../Dream.js';
2
+ export default class CannotNamespaceAssociationFilterToAnotherTable extends Error {
3
+ private dreamClass;
4
+ private key;
5
+ private expectedAlias;
6
+ constructor(dreamClass: typeof Dream, key: string, expectedAlias: string);
7
+ get message(): string;
8
+ }
@@ -0,0 +1,12 @@
1
+ import Dream from '../../Dream.js';
2
+ import { AssociationStatement } from '../../types/associations/shared.js';
3
+ export default class CannotIgnoreAssociationColumn extends Error {
4
+ private tableName;
5
+ private columnName;
6
+ private modelClass;
7
+ private association;
8
+ private columnRole;
9
+ constructor(tableName: string, columnName: string, modelClass: typeof Dream, association: AssociationStatement, columnRole: 'foreign key' | 'polymorphic type field' | 'primary key override');
10
+ get message(): string;
11
+ private get consequence();
12
+ }
@@ -0,0 +1,7 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class CannotIgnoreEncryptedColumn extends Error {
3
+ private modelClass;
4
+ private columnName;
5
+ constructor(modelClass: typeof Dream, columnName: string);
6
+ get message(): string;
7
+ }
@@ -0,0 +1,6 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class CannotIgnorePrimaryKey extends Error {
3
+ private modelClass;
4
+ constructor(modelClass: typeof Dream);
5
+ get message(): string;
6
+ }
@@ -0,0 +1,7 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class CannotIgnoreSoftDeleteColumn extends Error {
3
+ private modelClass;
4
+ private columnName;
5
+ constructor(modelClass: typeof Dream, columnName: string);
6
+ get message(): string;
7
+ }
@@ -0,0 +1,7 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class CannotIgnoreSortablePositionColumn extends Error {
3
+ private modelClass;
4
+ private columnName;
5
+ constructor(modelClass: typeof Dream, columnName: string);
6
+ get message(): string;
7
+ }
@@ -0,0 +1,8 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class CannotIgnoreSortableScopeColumn extends Error {
3
+ private modelClass;
4
+ private columnName;
5
+ private positionField;
6
+ constructor(modelClass: typeof Dream, columnName: string, positionField: string);
7
+ get message(): string;
8
+ }
@@ -0,0 +1,6 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class CannotIgnoreStiTypeColumn extends Error {
3
+ private modelClass;
4
+ constructor(modelClass: typeof Dream);
5
+ get message(): string;
6
+ }
@@ -0,0 +1,7 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class ConflictingIgnoredColumns extends Error {
3
+ private tableName;
4
+ private modelClasses;
5
+ constructor(tableName: string, modelClasses: (typeof Dream)[]);
6
+ get message(): string;
7
+ }
@@ -0,0 +1,7 @@
1
+ import Dream from '../../Dream.js';
2
+ export default class IgnoredColumnMustBeCamelCase extends Error {
3
+ private modelClass;
4
+ private columnName;
5
+ constructor(modelClass: typeof Dream, columnName: string);
6
+ get message(): string;
7
+ }
@@ -94,6 +94,26 @@ export default class ASTConnectionBuilder extends ASTBuilder {
94
94
  * Can be used to build up types
95
95
  */
96
96
  private tableData;
97
+ /**
98
+ * @internal
99
+ *
100
+ * resolves the ignored columns declared by the models backed by the
101
+ * given table (validating the declarations; see resolveIgnoredColumns)
102
+ */
103
+ protected ignoredColumnsForTable(tableName: string): Set<string>;
104
+ /**
105
+ * @internal
106
+ *
107
+ * returns the provided column data without the columns that the table's
108
+ * models declare in ignoredColumns. This is what removes ignored columns
109
+ * from the generated dream schema file: `columns()` reads the generated
110
+ * schema at runtime, so every column enumeration built from `columns()`
111
+ * (preload and join-load select lists, save hydration, attribute
112
+ * definition) inherits this filtering. A column that is ignored but not
113
+ * present in the introspected table (e.g. after the drop migration has
114
+ * run but before the declaration is removed) is a no-op.
115
+ */
116
+ private withoutIgnoredColumns;
97
117
  /**
98
118
  * @internal
99
119
  *
@@ -70,6 +70,19 @@ export default class ASTKyselyCodegenEnhancer extends ASTConnectionBuilder {
70
70
  * (since the DB interface is indexed by table name, which must not be camelized)
71
71
  */
72
72
  private camelizeKeys;
73
+ /**
74
+ * @internal
75
+ *
76
+ * removes columns declared in model `ignoredColumns` getters from the
77
+ * table interfaces generated by kysely-codegen. This is what removes
78
+ * ignored columns from the generated db types file: every column-name
79
+ * level type (`DreamColumnNames`, `UpdateableProperties`, where-clause
80
+ * statements) derives from the Kysely `DB` interface, so filtering here
81
+ * turns any remaining code reference to an ignored column into a type
82
+ * error. Runs after camelizeKeys so that member names align with the
83
+ * camelCase column names models declare in ignoredColumns.
84
+ */
85
+ private removeIgnoredColumns;
73
86
  /**
74
87
  * @internal
75
88
  *
@@ -0,0 +1,41 @@
1
+ import Dream from '../../Dream.js';
2
+ /**
3
+ * @internal
4
+ *
5
+ * Resolves the set of ignored columns for a table from the `ignoredColumns`
6
+ * declarations of every model backed by that table, validating the
7
+ * declarations along the way. Called while `sync` builds the generated types
8
+ * files (the declarations have no runtime behavior; see the `ignoredColumns`
9
+ * getter on Dream), so each of these guards fails the sync command loudly
10
+ * rather than surfacing as broken behavior at runtime:
11
+ *
12
+ * - ignored columns must be declared in camelCase, since generated column
13
+ * names are camelized, so any other shape can never match a generated
14
+ * column and would be silently inert
15
+ * - a model may never ignore its primary key
16
+ * - an STI model may never ignore the STI "type" column
17
+ * - a model may never ignore an @Sortable position field or a plain-column
18
+ * @Sortable scope, the backing column of an @Encrypted property, or (on a
19
+ * SoftDelete model) its deletedAtField — the framework reads and writes
20
+ * those columns by name
21
+ * - models sharing a table must agree on their ignored columns, since there
22
+ * is only one generated schema per table (STI children inherit the base
23
+ * model's getter, so agreement is automatic unless a child overrides it)
24
+ * - no association anywhere in the app may name an ignored column as the
25
+ * foreign key (or polymorphic type field) it reads and writes on this
26
+ * table — a BelongsTo on a model backed by this table names a foreign key
27
+ * on this table, and so does a HasMany/HasOne on any other model that
28
+ * points at a model backed by this table
29
+ * - no association anywhere in the app may name an ignored column as its
30
+ * primaryKeyOverride — the column the association's foreign key points
31
+ * at, which lives on the associated model's table for a BelongsTo and on
32
+ * the declaring model's own table for a HasMany/HasOne
33
+ *
34
+ * @param models - every model backed by the table
35
+ * @param tableName - the table whose ignored columns are being resolved
36
+ * @param allModels - every model in the app (on the table's connection);
37
+ * required because associations declared on other models can name foreign
38
+ * keys on this table
39
+ * @returns the set of column names to omit from the table's generated types
40
+ */
41
+ export default function resolveIgnoredColumns(models: (typeof Dream)[], tableName: string, allModels: (typeof Dream)[]): Set<string>;
@@ -34,8 +34,11 @@ type JoinedAssociationColumnNames<JoinedAssociations extends Readonly<JoinedAsso
34
34
  type Whereable<R> = {
35
35
  [K in keyof Selectable<R>]?: Selectable<R>[K] | Selectable<R>[K][];
36
36
  };
37
+ type WhereableAssociatedModelParam<I extends Dream> = {
38
+ [K in keyof AssociatedModelParam<I>]: AssociatedModelParam<I>[K] | NonNullable<AssociatedModelParam<I>[K]>[];
39
+ };
37
40
  export type WhereStatement<I extends Dream> = InternalWhereStatement<I, I['DB'], I['schema'], I['table']>;
38
- export type InternalWhereStatement<I extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<MergeUnionOfRecordTypes<Whereable<DB[TableName]> | DreamSelectable<DB, Schema, TableName> | AssociatedModelParam<I>>>;
41
+ export type InternalWhereStatement<I extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<MergeUnionOfRecordTypes<Whereable<DB[TableName]> | DreamSelectable<DB, Schema, TableName> | WhereableAssociatedModelParam<I>>>;
39
42
  export type OnStatementForAssociation<I extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB, RequiredOnClauseKeysForThisAssociation, OnStatement extends InternalWhereStatement<I, DB, Schema, TableName> = InternalWhereStatement<I, DB, Schema, TableName>> = RequiredOnClauseKeysForThisAssociation extends null ? InternalWhereStatement<I, DB, Schema, TableName> : RequiredOnClauseKeysForThisAssociation extends string[] ? Required<Pick<OnStatement, RequiredOnClauseKeysForThisAssociation[number] & keyof OnStatement>> & Partial<Omit<OnStatement, RequiredOnClauseKeysForThisAssociation[number] & keyof OnStatement>> : never;
40
43
  export type OnStatementForSpecificColumns<I extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB, Columns extends string[], OnStatement extends InternalWhereStatement<I, DB, Schema, TableName> = InternalWhereStatement<I, DB, Schema, TableName>> = Pick<OnStatement, Columns[number] & keyof OnStatement>;
41
44
  type OnStatementForAssociationDefinition<DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<MergeUnionOfRecordTypes<Partial<Selectable<DB[TableName]>> | Partial<{
@@ -51,6 +51,23 @@ export type PassthroughOnClauseKeys<Schema, TableName, AssociationName, Associat
51
51
  * must be forbidden at compile time for the hydrating load variants.
52
52
  */
53
53
  export type IsNonOptionalBelongsToAssociation<Schema, TableName, AssociationName, Associations = TableName extends null ? null : TableName extends keyof Schema & string ? Schema[TableName]['associations' & keyof Schema[TableName]] : null, Association = Associations extends null ? null : AssociationName extends keyof Associations ? Associations[AssociationName] : null> = Association extends null ? false : Association['type' & keyof Association] extends 'BelongsTo' ? Association['optional' & keyof Association] extends false ? true : false : false;
54
+ /**
55
+ * Resolves to `true` when the named association on the given table is a
56
+ * polymorphic BelongsTo. Joining a polymorphic BelongsTo raises
57
+ * CannotJoinPolymorphicBelongsToError at runtime, so the variadic join types
58
+ * (innerJoin / leftJoin / leftJoinPreload / leftJoinLoad) reject these
59
+ * association names at compile time.
60
+ */
61
+ export type IsPolymorphicBelongsToAssociation<Schema, TableName, AssociationName, Associations = TableName extends null ? null : TableName extends keyof Schema & string ? Schema[TableName]['associations' & keyof Schema[TableName]] : null, Association = Associations extends null ? null : AssociationName extends keyof Associations ? Associations[AssociationName] : null> = Association extends null ? false : Association['type' & keyof Association] extends 'BelongsTo' ? Association['foreignKeyTypeColumn' & keyof Association] extends string ? true : false : false;
62
+ /**
63
+ * Union of the association names on the given table that are polymorphic
64
+ * BelongsTo associations. Used by the variadic join types to exclude these
65
+ * names from the allowed argument values, since joining a polymorphic
66
+ * BelongsTo raises CannotJoinPolymorphicBelongsToError at runtime.
67
+ */
68
+ export type PolymorphicBelongsToAssociationNames<Schema, TableName extends keyof Schema, AssociationMetadata = AssociationMetadataForTable<Schema, TableName>> = IsAny<AssociationMetadata> extends true ? never : {
69
+ [K in keyof AssociationMetadata]: AssociationMetadata[K]['type' & keyof AssociationMetadata[K]] extends 'BelongsTo' ? AssociationMetadata[K]['foreignKeyTypeColumn' & keyof AssociationMetadata[K]] extends string ? K : never : never;
70
+ }[keyof AssociationMetadata];
54
71
  export type DreamAssociationNames<DreamInstance extends Dream, SchemaAssociations = DreamAssociationMetadata<DreamInstance>> = keyof SchemaAssociations;
55
72
  export type DreamBelongsToAssociationNames<DreamInstance extends Dream> = keyof DreamBelongsToAssociationMetadata<DreamInstance>;
56
73
  export type DreamHasOneAssociationNames<DreamInstance extends Dream> = keyof DreamHasOneAssociationMetadata<DreamInstance>;
@@ -221,6 +221,15 @@ type Whereable<R> = {
221
221
  [K in keyof Selectable<R>]?: Selectable<R>[K] | Selectable<R>[K][]
222
222
  }
223
223
 
224
+ // For filtering by BelongsTo model instance(s) in a where/and statement, e.g.
225
+ // `await Room.where({ place: [place1, place2] }).all()`. Unlike
226
+ // `AssociatedModelParam` (the create/update param type, where an array of
227
+ // instances would be meaningless), each association also accepts an array
228
+ // of associated model instances.
229
+ type WhereableAssociatedModelParam<I extends Dream> = {
230
+ [K in keyof AssociatedModelParam<I>]: AssociatedModelParam<I>[K] | NonNullable<AssociatedModelParam<I>[K]>[]
231
+ }
232
+
224
233
  export type WhereStatement<I extends Dream> = InternalWhereStatement<I, I['DB'], I['schema'], I['table']>
225
234
 
226
235
  export type InternalWhereStatement<
@@ -230,7 +239,7 @@ export type InternalWhereStatement<
230
239
  TableName extends AssociationTableNames<DB, Schema> & keyof DB,
231
240
  > = Partial<
232
241
  MergeUnionOfRecordTypes<
233
- Whereable<DB[TableName]> | DreamSelectable<DB, Schema, TableName> | AssociatedModelParam<I>
242
+ Whereable<DB[TableName]> | DreamSelectable<DB, Schema, TableName> | WhereableAssociatedModelParam<I>
234
243
  >
235
244
  >
236
245
 
@@ -254,6 +254,59 @@ export type IsNonOptionalBelongsToAssociation<
254
254
  : false
255
255
  : false
256
256
 
257
+ /**
258
+ * Resolves to `true` when the named association on the given table is a
259
+ * polymorphic BelongsTo. Joining a polymorphic BelongsTo raises
260
+ * CannotJoinPolymorphicBelongsToError at runtime, so the variadic join types
261
+ * (innerJoin / leftJoin / leftJoinPreload / leftJoinLoad) reject these
262
+ * association names at compile time.
263
+ */
264
+ export type IsPolymorphicBelongsToAssociation<
265
+ Schema,
266
+ TableName,
267
+ AssociationName,
268
+ Associations = TableName extends null
269
+ ? null
270
+ : TableName extends keyof Schema & string
271
+ ? Schema[TableName]['associations' & keyof Schema[TableName]]
272
+ : null,
273
+ Association = Associations extends null
274
+ ? null
275
+ : AssociationName extends keyof Associations
276
+ ? Associations[AssociationName]
277
+ : null,
278
+ > = Association extends null
279
+ ? false
280
+ : Association['type' & keyof Association] extends 'BelongsTo'
281
+ ? Association['foreignKeyTypeColumn' & keyof Association] extends string
282
+ ? true
283
+ : false
284
+ : false
285
+
286
+ /**
287
+ * Union of the association names on the given table that are polymorphic
288
+ * BelongsTo associations. Used by the variadic join types to exclude these
289
+ * names from the allowed argument values, since joining a polymorphic
290
+ * BelongsTo raises CannotJoinPolymorphicBelongsToError at runtime.
291
+ */
292
+ export type PolymorphicBelongsToAssociationNames<
293
+ Schema,
294
+ TableName extends keyof Schema,
295
+ AssociationMetadata = AssociationMetadataForTable<Schema, TableName>,
296
+ > =
297
+ // when the schema is untyped (`any`), resolve to `never` so nothing is
298
+ // excluded from the allowed association names
299
+ IsAny<AssociationMetadata> extends true
300
+ ? never
301
+ : {
302
+ [K in keyof AssociationMetadata]: AssociationMetadata[K]['type' &
303
+ keyof AssociationMetadata[K]] extends 'BelongsTo'
304
+ ? AssociationMetadata[K]['foreignKeyTypeColumn' & keyof AssociationMetadata[K]] extends string
305
+ ? K
306
+ : never
307
+ : never
308
+ }[keyof AssociationMetadata]
309
+
257
310
  export type DreamAssociationNames<
258
311
  DreamInstance extends Dream,
259
312
  SchemaAssociations = DreamAssociationMetadata<DreamInstance>,