@rvoh/dream 2.40.2 → 2.42.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 (269) hide show
  1. package/dist/cjs/src/Dream.js +156 -13
  2. package/dist/cjs/src/cli/index.js +39 -5
  3. package/dist/cjs/src/db/DreamDbConnection.js +19 -1
  4. package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +34 -2
  5. package/dist/cjs/src/dream/Query.js +178 -14
  6. package/dist/cjs/src/dream/QueryDriver/Base.js +80 -0
  7. package/dist/cjs/src/dream/QueryDriver/Kysely.js +35 -29
  8. package/dist/cjs/src/dream/QueryDriver/Postgres.js +83 -1
  9. package/dist/cjs/src/dream/internal/findOrCreateBy.js +5 -1
  10. package/dist/cjs/src/dream/internal/findOrCreateLookupStatement.js +19 -0
  11. package/dist/cjs/src/dream/internal/updateOrCreateBy.js +5 -1
  12. package/dist/cjs/src/encrypt/algorithms/aes-gcm/decryptAESGCM.js +24 -10
  13. package/dist/cjs/src/errors/CreateOrFindByFailedToCreateAndFind.js +63 -6
  14. package/dist/cjs/src/errors/CreateOrUpdateByFailedToCreateAndUpdate.js +41 -6
  15. package/dist/cjs/src/errors/GeneratedFilesAlreadyExist.js +38 -0
  16. package/dist/cjs/src/errors/schema-builder/ColumnNamesDoNotRoundTrip.js +28 -0
  17. package/dist/cjs/src/helpers/cli/ASTConnectionBuilder.js +62 -10
  18. package/dist/cjs/src/helpers/cli/generateDream.js +109 -18
  19. package/dist/cjs/src/helpers/cli/generateMigration.js +12 -8
  20. package/dist/cjs/src/helpers/cli/writeGeneratedFile.js +3 -3
  21. package/dist/cjs/src/helpers/db/normalizeDataForDb.js +33 -4
  22. package/dist/cjs/src/ops/index.js +7 -3
  23. package/dist/esm/src/Dream.js +156 -13
  24. package/dist/esm/src/cli/index.js +39 -5
  25. package/dist/esm/src/db/DreamDbConnection.js +19 -1
  26. package/dist/esm/src/dream/DreamClassTransactionBuilder.js +34 -2
  27. package/dist/esm/src/dream/Query.js +178 -14
  28. package/dist/esm/src/dream/QueryDriver/Base.js +80 -0
  29. package/dist/esm/src/dream/QueryDriver/Kysely.js +35 -29
  30. package/dist/esm/src/dream/QueryDriver/Postgres.js +83 -1
  31. package/dist/esm/src/dream/internal/findOrCreateBy.js +5 -1
  32. package/dist/esm/src/dream/internal/findOrCreateLookupStatement.js +19 -0
  33. package/dist/esm/src/dream/internal/updateOrCreateBy.js +5 -1
  34. package/dist/esm/src/encrypt/algorithms/aes-gcm/decryptAESGCM.js +24 -10
  35. package/dist/esm/src/errors/CreateOrFindByFailedToCreateAndFind.js +63 -6
  36. package/dist/esm/src/errors/CreateOrUpdateByFailedToCreateAndUpdate.js +41 -6
  37. package/dist/esm/src/errors/GeneratedFilesAlreadyExist.js +38 -0
  38. package/dist/esm/src/errors/schema-builder/ColumnNamesDoNotRoundTrip.js +28 -0
  39. package/dist/esm/src/helpers/cli/ASTConnectionBuilder.js +62 -10
  40. package/dist/esm/src/helpers/cli/generateDream.js +109 -18
  41. package/dist/esm/src/helpers/cli/generateMigration.js +12 -8
  42. package/dist/esm/src/helpers/cli/writeGeneratedFile.js +3 -3
  43. package/dist/esm/src/helpers/db/normalizeDataForDb.js +33 -4
  44. package/dist/esm/src/ops/index.js +7 -3
  45. package/dist/types/src/Dream.d.ts +109 -6
  46. package/dist/types/src/bin/index.d.ts +11 -0
  47. package/dist/types/src/cli/index.d.ts +27 -0
  48. package/dist/types/src/db/DreamDbConnection.d.ts +15 -1
  49. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +34 -2
  50. package/dist/types/src/dream/Query.d.ts +101 -6
  51. package/dist/types/src/dream/QueryDriver/Base.d.ts +59 -0
  52. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +9 -0
  53. package/dist/types/src/dream/QueryDriver/Postgres.d.ts +29 -1
  54. package/dist/types/src/dream/internal/executeDatabaseQuery.d.ts +2 -1
  55. package/dist/types/src/dream/internal/findOrCreateLookupStatement.d.ts +14 -0
  56. package/dist/types/src/errors/CreateOrFindByFailedToCreateAndFind.d.ts +40 -1
  57. package/dist/types/src/errors/CreateOrUpdateByFailedToCreateAndUpdate.d.ts +8 -1
  58. package/dist/types/src/errors/GeneratedFilesAlreadyExist.d.ts +18 -0
  59. package/dist/types/src/errors/schema-builder/ColumnNamesDoNotRoundTrip.d.ts +12 -0
  60. package/dist/types/src/helpers/cli/ASTConnectionBuilder.d.ts +23 -1
  61. package/dist/types/src/helpers/cli/generateDream.d.ts +25 -0
  62. package/dist/types/src/helpers/cli/generateMigration.d.ts +20 -2
  63. package/dist/types/src/helpers/cli/syncWithFailureContext.d.ts +7 -2
  64. package/dist/types/src/helpers/cli/writeGeneratedFile.d.ts +6 -1
  65. package/dist/types/src/helpers/db/normalizeDataForDb.d.ts +7 -0
  66. package/dist/types/src/ops/index.d.ts +7 -3
  67. package/dist/types/src/types/associations/shared.d.ts +7 -5
  68. package/dist/types/src/types/types/associations/shared.ts +27 -5
  69. package/docs/assets/hierarchy.js +1 -1
  70. package/docs/assets/search.js +1 -1
  71. package/docs/classes/db.DreamMigrationHelpers.html +11 -11
  72. package/docs/classes/db.KyselyQueryDriver.html +87 -50
  73. package/docs/classes/db.PostgresQueryDriver.html +76 -50
  74. package/docs/classes/db.QueryDriverBase.html +87 -50
  75. package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
  76. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  77. package/docs/classes/errors.ColumnOverflow.html +3 -3
  78. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +6 -3
  79. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  80. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  81. package/docs/classes/errors.DecryptionError.html +2 -2
  82. package/docs/classes/errors.DecryptionParseError.html +2 -2
  83. package/docs/classes/errors.DecryptionRotationError.html +3 -3
  84. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  85. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  86. package/docs/classes/errors.InvalidClockTime.html +2 -2
  87. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  88. package/docs/classes/errors.InvalidDateTime.html +2 -2
  89. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  90. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  91. package/docs/classes/errors.NotNullViolation.html +3 -3
  92. package/docs/classes/errors.RecordNotFound.html +3 -3
  93. package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
  94. package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
  95. package/docs/classes/errors.ValidationError.html +3 -3
  96. package/docs/classes/index.CalendarDate.html +33 -33
  97. package/docs/classes/index.ClockTime.html +32 -32
  98. package/docs/classes/index.ClockTimeTz.html +35 -35
  99. package/docs/classes/index.DateTime.html +86 -86
  100. package/docs/classes/index.Decorators.html +19 -19
  101. package/docs/classes/index.Dream.html +204 -134
  102. package/docs/classes/index.DreamApp.html +13 -13
  103. package/docs/classes/index.DreamTransaction.html +3 -3
  104. package/docs/classes/index.Env.html +5 -5
  105. package/docs/classes/index.Query.html +147 -100
  106. package/docs/classes/system.CliFileWriter.html +4 -4
  107. package/docs/classes/system.DreamBin.html +7 -3
  108. package/docs/classes/system.DreamCLI.html +7 -7
  109. package/docs/classes/system.DreamImporter.html +2 -2
  110. package/docs/classes/system.DreamLogos.html +2 -2
  111. package/docs/classes/system.DreamSerializerBuilder.html +11 -11
  112. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  113. package/docs/classes/system.PathHelpers.html +3 -3
  114. package/docs/classes/utils.Encrypt.html +4 -4
  115. package/docs/classes/utils.Range.html +2 -2
  116. package/docs/functions/db.closeAllDbConnections.html +1 -1
  117. package/docs/functions/db.dreamDbConnections.html +1 -1
  118. package/docs/functions/db.untypedDb.html +1 -1
  119. package/docs/functions/db.validateColumn.html +1 -1
  120. package/docs/functions/db.validateTable.html +1 -1
  121. package/docs/functions/errors.pgErrorType.html +1 -1
  122. package/docs/functions/index.DreamSerializer.html +1 -1
  123. package/docs/functions/index.ObjectSerializer.html +1 -1
  124. package/docs/functions/index.ReplicaSafe.html +1 -1
  125. package/docs/functions/index.STI.html +1 -1
  126. package/docs/functions/index.SoftDelete.html +1 -1
  127. package/docs/functions/utils.camelize.html +1 -1
  128. package/docs/functions/utils.capitalize.html +1 -1
  129. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  130. package/docs/functions/utils.compact.html +1 -1
  131. package/docs/functions/utils.groupBy.html +1 -1
  132. package/docs/functions/utils.hyphenize.html +1 -1
  133. package/docs/functions/utils.intersection.html +1 -1
  134. package/docs/functions/utils.isEmpty.html +3 -3
  135. package/docs/functions/utils.normalizeUnicode.html +1 -1
  136. package/docs/functions/utils.pascalize.html +1 -1
  137. package/docs/functions/utils.percent.html +1 -1
  138. package/docs/functions/utils.range.html +1 -1
  139. package/docs/functions/utils.round.html +1 -1
  140. package/docs/functions/utils.sanitizeString.html +1 -1
  141. package/docs/functions/utils.snakeify.html +1 -1
  142. package/docs/functions/utils.sort.html +1 -1
  143. package/docs/functions/utils.sortBy.html +1 -1
  144. package/docs/functions/utils.sortObjectByKey.html +1 -1
  145. package/docs/functions/utils.sortObjectByValue.html +1 -1
  146. package/docs/functions/utils.uncapitalize.html +1 -1
  147. package/docs/functions/utils.uniq.html +1 -1
  148. package/docs/hierarchy.html +1 -1
  149. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  150. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  151. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  152. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  153. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  154. package/docs/interfaces/types.DecoratorContext.html +2 -2
  155. package/docs/interfaces/types.DecryptCallbacks.html +2 -2
  156. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  157. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  158. package/docs/interfaces/types.DreamDbConfig.html +6 -6
  159. package/docs/interfaces/types.DurationObject.html +2 -2
  160. package/docs/interfaces/types.EncryptOptions.html +2 -2
  161. package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +4 -4
  162. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  163. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  164. package/docs/interfaces/types.IntrospectedColumn.html +7 -7
  165. package/docs/interfaces/types.IntrospectedDatabase.html +2 -2
  166. package/docs/interfaces/types.IntrospectedEnum.html +2 -2
  167. package/docs/interfaces/types.IntrospectedTable.html +5 -5
  168. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  169. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  170. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  171. package/docs/types/openapi.OpenapiFormats.html +1 -1
  172. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  173. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  174. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  175. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  176. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  177. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  178. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  179. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  180. package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +1 -1
  181. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  182. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -1
  183. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
  184. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
  185. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  186. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  187. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  188. package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
  189. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  190. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  191. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  192. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  193. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  194. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.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 +1 -1
  198. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  199. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  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.IntrospectedValueType.html +1 -1
  239. package/docs/types/types.Pascalized.html +1 -1
  240. package/docs/types/types.PrimaryKeyType.html +1 -1
  241. package/docs/types/types.RoundingPrecision.html +1 -1
  242. package/docs/types/types.SerializerCasing.html +1 -1
  243. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  244. package/docs/types/types.Snakeified.html +1 -1
  245. package/docs/types/types.StrictInterface.html +1 -1
  246. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  247. package/docs/types/types.UpdateableProperties.html +1 -1
  248. package/docs/types/types.ValidationType.html +1 -1
  249. package/docs/types/types.ViewModel.html +2 -2
  250. package/docs/types/types.ViewModelClass.html +1 -1
  251. package/docs/types/types.WeekdayName.html +1 -1
  252. package/docs/types/types.WhereStatementForDream.html +1 -1
  253. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  254. package/docs/variables/index.DreamConst.html +1 -1
  255. package/docs/variables/index.ops.html +8 -4
  256. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  257. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  258. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  259. package/docs/variables/system.primaryKeyTypes.html +1 -1
  260. package/package.json +1 -1
  261. package/dist/cjs/src/helpers/cli/generateFactory.js +0 -10
  262. package/dist/cjs/src/helpers/cli/generateSerializer.js +0 -18
  263. package/dist/cjs/src/helpers/cli/generateUnitSpec.js +0 -10
  264. package/dist/esm/src/helpers/cli/generateFactory.js +0 -10
  265. package/dist/esm/src/helpers/cli/generateSerializer.js +0 -18
  266. package/dist/esm/src/helpers/cli/generateUnitSpec.js +0 -10
  267. package/dist/types/src/helpers/cli/generateFactory.d.ts +0 -5
  268. package/dist/types/src/helpers/cli/generateSerializer.d.ts +0 -9
  269. package/dist/types/src/helpers/cli/generateUnitSpec.d.ts +0 -3
@@ -264,6 +264,7 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
264
264
  * @returns A Map from each present group value to the average of the aggregated column in that group
265
265
  */
266
266
  avgBy(groupColumn: string, aggregatedColumn: string): Promise<Map<any, any>>;
267
+ exists(): Promise<boolean>;
267
268
  /**
268
269
  * Retrieves the number of records in the database
269
270
  *
@@ -367,6 +368,14 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
367
368
  * every `RETURNING *` / `select *` in this driver.
368
369
  */
369
370
  static saveDream(dream: Dream, txn?: DreamTransaction<Dream> | null): Promise<any>;
371
+ /**
372
+ * @internal
373
+ *
374
+ * Runs a read statement (a select, aggregate, pluck or preload), raising the
375
+ * driver's Dream error for a value the database rejects in place of the
376
+ * database's own error (see `dataIncompatibleWithDatabaseFieldError`).
377
+ */
378
+ private executeReadQuery;
370
379
  dbConnectionType(sqlCommandType: SqlCommandType): DbConnectionType;
371
380
  private isReplicaSafe;
372
381
  /**
@@ -1,6 +1,10 @@
1
1
  import { type SelectQueryBuilder } from 'kysely';
2
+ import CheckConstraintViolation from '../../errors/db/CheckConstraintViolation.js';
3
+ import ColumnOverflow from '../../errors/db/ColumnOverflow.js';
4
+ import DataTypeColumnTypeMismatch from '../../errors/db/DataTypeColumnTypeMismatch.js';
5
+ import NotNullViolation from '../../errors/db/NotNullViolation.js';
2
6
  import Dream from '../../Dream.js';
3
- import { IntrospectedDatabase } from '../../types/db.js';
7
+ import { DbConnectionType, IntrospectedDatabase } from '../../types/db.js';
4
8
  import DreamTransaction from '../DreamTransaction.js';
5
9
  import KyselyQueryDriver from './Kysely.js';
6
10
  import type { TestDatabaseLockSession } from './Base.js';
@@ -57,7 +61,31 @@ export default class PostgresQueryDriver<DreamInstance extends Dream> extends Ky
57
61
  applyRowLock(kyselyQuery: SelectQueryBuilder<any, any, any>, tableAlias: string): SelectQueryBuilder<any, any, any>;
58
62
  static supportsAdvisoryTransactionLocks: boolean;
59
63
  static isUniqueConstraintViolation(error: unknown): boolean;
64
+ /**
65
+ * @internal
66
+ *
67
+ * Postgres implementation of {@link QueryDriverBase.violatedUniqueIndexColumns}.
68
+ * A unique violation names the index it hit in the error's `constraint`
69
+ * field (a unique constraint's index shares its name), and one catalog query
70
+ * reads that index's key columns. `INCLUDE` columns are not keys and are
71
+ * left out.
72
+ */
73
+ static violatedUniqueIndexColumns(connectionName: string, error: unknown, table: string): Promise<string[] | null>;
60
74
  static isDeadlock(error: unknown): boolean;
75
+ static dataIncompatibleWithDatabaseFieldError(error: unknown): CheckConstraintViolation | ColumnOverflow | DataTypeColumnTypeMismatch | NotNullViolation | null;
76
+ /**
77
+ * @internal
78
+ *
79
+ * Postgres implementation of {@link QueryDriverBase.rejectsAnyValueForColumnType}.
80
+ * One statement casts every value to its type, so Postgres's own input
81
+ * function for each type is the judge: a cast it rejects raises `22P02` or
82
+ * `22003`. Callers never ask inside a transaction, which a rejected cast
83
+ * would abort.
84
+ */
85
+ static rejectsAnyValueForColumnType(connectionName: string, dbConnectionType: DbConnectionType, values: {
86
+ value: unknown;
87
+ dbType: string;
88
+ }[]): Promise<boolean>;
61
89
  /**
62
90
  * @internal
63
91
  *
@@ -1,2 +1,3 @@
1
- export default function executeDatabaseQuery<Command extends DbQueryCommand, ReturnType extends Command extends 'execute' ? any[] : Command extends 'executeTakeFirst' ? any : Command extends 'executeTakeFirstOrThrow' ? any : never>(kyselyQuery: any, command: Command): Promise<ReturnType>;
1
+ export default function executeDatabaseQuery<Command extends DbQueryCommand, ReturnType extends ExecuteDatabaseQueryReturnType<Command>>(kyselyQuery: any, command: Command): Promise<ReturnType>;
2
2
  export type DbQueryCommand = 'execute' | 'executeTakeFirst' | 'executeTakeFirstOrThrow';
3
+ export type ExecuteDatabaseQueryReturnType<Command extends DbQueryCommand> = Command extends 'execute' ? any[] : Command extends 'executeTakeFirst' ? any : Command extends 'executeTakeFirstOrThrow' ? any : never;
@@ -0,0 +1,14 @@
1
+ import Dream from '../../Dream.js';
2
+ import { WhereStatement } from '../../types/associations/shared.js';
3
+ import { UpdateablePropertiesForClass } from '../../types/dream.js';
4
+ /**
5
+ * Builds the `findBy` statement that findOrCreateBy, createOrFindBy,
6
+ * updateOrCreateBy and createOrUpdateBy use to look up an existing record.
7
+ * Their attributes are both the lookup and the values to persist, so an array
8
+ * given for an array column is the whole array to store: the lookup compares
9
+ * it with `ops.equal`, matching only a record whose array equals it
10
+ * element-for-element, in order, instead of the `IN` a plain list means in a
11
+ * where clause. PostgreSQL defines no equality operator for `json`, so on a
12
+ * `json[]` column this lookup raises at the database, as `ops.equal` does.
13
+ */
14
+ export default function findOrCreateLookupStatement<T extends typeof Dream>(dreamClass: T, attributes: UpdateablePropertiesForClass<T>): WhereStatement<InstanceType<T>>;
@@ -1,6 +1,45 @@
1
1
  import Dream from '../Dream.js';
2
+ /**
3
+ * What `createOrFindBy` and `createOrUpdateBy` could tell about why the
4
+ * record that blocked their insert was not found:
5
+ *
6
+ * - `conflictingAttributes`: the violated unique index covers these
7
+ * `createWith`/`with` attributes but not every find attribute, so one of
8
+ * their values likely conflicts with a different record
9
+ * - `hiddenByDefaultScope`: the violated unique index covers only find
10
+ * attributes, or every find attribute, and a record matching them exists
11
+ * once these default scopes are removed, so that record is the one the
12
+ * insert conflicted with
13
+ * - `undetermined`: neither could be established. `hidingDefaultScopes` lists
14
+ * the default scopes hiding a record that matches the find attributes, if
15
+ * there is one, and `extraAttributesMayConflict` is true when a
16
+ * `createWith`/`with` value may be what conflicted
17
+ */
18
+ export type CreateOrFindFailureCause = {
19
+ kind: 'conflictingAttributes';
20
+ attributes: string[];
21
+ } | {
22
+ kind: 'hiddenByDefaultScope';
23
+ defaultScopes: string[];
24
+ } | {
25
+ kind: 'undetermined';
26
+ hidingDefaultScopes: string[];
27
+ extraAttributesMayConflict: boolean;
28
+ };
29
+ export declare const UNDETERMINED_CREATE_OR_FIND_FAILURE: CreateOrFindFailureCause;
2
30
  export default class CreateOrFindByFailedToCreateAndFind extends Error {
3
31
  private dreamClass;
4
- constructor(dreamClass: typeof Dream);
32
+ private failureCause;
33
+ /**
34
+ * @param dreamClass - the model `createOrFindBy` was called on
35
+ * @param failureCause - what could be told about why the record that
36
+ * blocked the insert was not found
37
+ */
38
+ constructor(dreamClass: typeof Dream, failureCause?: CreateOrFindFailureCause);
5
39
  get message(): string;
6
40
  }
41
+ export declare function describeDefaultScopes(scopeNames: string[]): string;
42
+ export declare function describeAttributes(attributes: string[]): string;
43
+ export declare function describePossibleCauses(failureCause: Extract<CreateOrFindFailureCause, {
44
+ kind: 'undetermined';
45
+ }>, extraAttributesOption: string): string;
@@ -1,6 +1,13 @@
1
1
  import Dream from '../Dream.js';
2
+ import { CreateOrFindFailureCause } from './CreateOrFindByFailedToCreateAndFind.js';
2
3
  export default class CreateOrUpdateByFailedToCreateAndUpdate extends Error {
3
4
  private dreamClass;
4
- constructor(dreamClass: typeof Dream);
5
+ private failureCause;
6
+ /**
7
+ * @param dreamClass - the model `createOrUpdateBy` was called on
8
+ * @param failureCause - what could be told about why the record that
9
+ * blocked the insert was not found
10
+ */
11
+ constructor(dreamClass: typeof Dream, failureCause?: CreateOrFindFailureCause);
5
12
  get message(): string;
6
13
  }
@@ -0,0 +1,18 @@
1
+ export interface GeneratedFilesAlreadyExistFlags {
2
+ overwrite: string;
3
+ skip: string;
4
+ }
5
+ export default class GeneratedFilesAlreadyExist extends Error {
6
+ modelName: string;
7
+ existingFiles: string[];
8
+ existingMigrations: string[];
9
+ flags: GeneratedFilesAlreadyExistFlags | undefined;
10
+ /**
11
+ * @param modelName - the fully qualified model name the generator was invoked with
12
+ * @param existingFiles - project-relative paths of the model, spec, factory and serializer files that already exist
13
+ * @param existingMigrations - project-relative paths of existing migrations with the name the generator would give the model's migration
14
+ * @param flags - the caller's flags for overwriting and for skipping existing files; when omitted, the message names Dream's `--overwrite` and `--skip-existing` and the commands that accept them
15
+ */
16
+ constructor(modelName: string, existingFiles: string[], existingMigrations: string[], flags?: GeneratedFilesAlreadyExistFlags);
17
+ get message(): string;
18
+ }
@@ -0,0 +1,12 @@
1
+ export interface ColumnNameThatDoesNotRoundTrip {
2
+ tableName: string;
3
+ columnName: string;
4
+ attributeName: string;
5
+ mappedColumnName: string;
6
+ modelName: string;
7
+ }
8
+ export default class ColumnNamesDoNotRoundTrip extends Error {
9
+ private columns;
10
+ constructor(columns: ColumnNameThatDoesNotRoundTrip[]);
11
+ get message(): string;
12
+ }
@@ -32,9 +32,31 @@ export default class ASTConnectionBuilder extends ASTBuilder {
32
32
  * the connection's tables, sorted by their key in the DB interface, and its
33
33
  * enums, read through the query driver once, by this builder or by the one
34
34
  * it takes its introspection from. The tables that `tableIncludePattern`
35
- * leaves out, or `tableExcludePattern` names, are left out.
35
+ * leaves out, or `tableExcludePattern` names, are left out. Fails, before
36
+ * either type file is written, when a column of a model's table does not
37
+ * round-trip through its attribute name (see guardColumnNamesRoundTrip).
36
38
  */
37
39
  protected introspectedDatabase(): Promise<IntrospectedDatabase>;
40
+ /**
41
+ * @internal
42
+ *
43
+ * fails the sync when a column of a table that one of the connection's
44
+ * models is backed by is not the column its attribute maps back to: Dream
45
+ * names the attribute by camelizing the column name, and each query naming
46
+ * the attribute targets the column the connection's CamelCasePlugin derives
47
+ * from it, so `address_line_1` (attribute `addressLine1`, which maps back to
48
+ * `address_line1`) could only be written, filtered on or join-loaded as a
49
+ * column that does not exist. A column the table's models ignore is
50
+ * skipped, since nothing queries it. A table no model is backed by is left
51
+ * to tableData, which fails the sync on it.
52
+ */
53
+ private guardColumnNamesRoundTrip;
54
+ /**
55
+ * @internal
56
+ *
57
+ * the models on the builder's connection
58
+ */
59
+ private connectionModels;
38
60
  /**
39
61
  * @internal
40
62
  *
@@ -1,3 +1,17 @@
1
+ import { type GeneratedFilesAlreadyExistFlags } from '../../errors/GeneratedFilesAlreadyExist.js';
2
+ /**
3
+ * What the model generators do when a file they would write already exists:
4
+ * - `'refuse'`: write nothing and throw an error listing the existing files
5
+ * - `'overwrite'`: replace the model, spec, factory and serializer files
6
+ * - `'skip'`: keep every existing file and write only the missing ones
7
+ *
8
+ * An existing migration with the name the generator would give the model's
9
+ * migration is never rewritten or duplicated, since it may already have run.
10
+ * Under `'skip'`, no migration is written at all when the model file already
11
+ * exists, since its table may have been created by a migration with another
12
+ * name.
13
+ */
14
+ export type GenerateDreamExistingFiles = 'refuse' | 'overwrite' | 'skip';
1
15
  export interface GenerateDreamOptions {
2
16
  connectionName: string;
3
17
  serializer: boolean;
@@ -14,6 +28,17 @@ export interface GenerateDreamOptions {
14
28
  * allows opt-out via `--no-soft-delete`.
15
29
  */
16
30
  softDelete?: boolean;
31
+ /**
32
+ * What to do when a file the generator would write already exists.
33
+ * Defaults to `'refuse'`. See {@link GenerateDreamExistingFiles}.
34
+ */
35
+ existingFiles?: GenerateDreamExistingFiles | undefined;
36
+ /**
37
+ * The caller's flags that select `existingFiles: 'overwrite'` and
38
+ * `existingFiles: 'skip'`, which the refusal names. Defaults to Dream's
39
+ * `--overwrite` and `--skip-existing`.
40
+ */
41
+ existingFilesFlags?: GeneratedFilesAlreadyExistFlags | undefined;
17
42
  }
18
43
  export default function generateDream({ fullyQualifiedModelName, columnsWithTypes, options, fullyQualifiedParentName, }: {
19
44
  fullyQualifiedModelName: string;
@@ -1,4 +1,21 @@
1
- export default function generateMigration({ migrationName, columnsWithTypes, connectionName, fullyQualifiedModelName, fullyQualifiedParentName, tableName: explicitTableName, modelClassName, softDelete, }: {
1
+ export interface GeneratedMigration {
2
+ /** The project-relative migrations folder the file goes in */
3
+ basePath: string;
4
+ /** `<version>-<fileStem>.ts` */
5
+ fileName: string;
6
+ /**
7
+ * The file name without its version prefix and extension, e.g.
8
+ * `create-room-bedroom` for the migration name `CreateRoom/Bedroom`
9
+ */
10
+ fileStem: string;
11
+ content: string;
12
+ }
13
+ export type GenerateMigrationArgs = Parameters<typeof buildMigration>[0];
14
+ /**
15
+ * Builds and validates a migration without writing it, so a caller writing
16
+ * several files can build them all before writing any.
17
+ */
18
+ export declare function buildMigration({ migrationName, columnsWithTypes, connectionName, fullyQualifiedModelName, fullyQualifiedParentName, tableName: explicitTableName, modelClassName, softDelete, }: {
2
19
  migrationName: string;
3
20
  columnsWithTypes: string[];
4
21
  connectionName: string;
@@ -17,4 +34,5 @@ export default function generateMigration({ migrationName, columnsWithTypes, con
17
34
  * `created_at` / `updated_at` timestamps.
18
35
  */
19
36
  softDelete?: boolean;
20
- }): Promise<void>;
37
+ }): GeneratedMigration;
38
+ export default function generateMigration(args: GenerateMigrationArgs): Promise<void>;
@@ -29,8 +29,13 @@ export interface SyncFailureContext {
29
29
  * work is already committed by the time the sync runs, so re-running it rolls
30
30
  * back a *further* migration rather than retrying the step that failed.
31
31
  *
32
- * Defaults to ``run `sync` on its own`` — the retry that is safe after any of
33
- * these commands, since it repeats only the step that actually failed.
32
+ * Defaults to ``run `sync` on its own``, which is not safe after every
33
+ * command: a failed sync reverts the generated types to what they were
34
+ * before the command ran, and a Psychic app's `psy sync` boots with the
35
+ * integrity checks on, so it fails against those types whenever a model or
36
+ * serializer already uses a table or column the command just added. A
37
+ * command that adds schema passes advice that re-runs `db:migrate`, which
38
+ * boots with the checks bypassed and goes straight to the sync.
34
39
  */
35
40
  recoveryAdvice?: string | undefined;
36
41
  }
@@ -10,9 +10,14 @@ export interface WriteGeneratedFileArgs {
10
10
  content: string;
11
11
  /** Label for CLI output (e.g. 'dream', 'serializer', 'factory', 'spec', 'migration') */
12
12
  logLabel: string;
13
+ /**
14
+ * When true, an existing file at the path is replaced. Otherwise the write
15
+ * fails if a file is already there.
16
+ */
17
+ overwrite?: boolean | undefined;
13
18
  }
14
19
  /**
15
20
  * Common file-writing helper used by all Dream generators.
16
21
  * Handles directory creation, file writing, logging, and error wrapping.
17
22
  */
18
- export default function writeGeneratedFile({ dreamPathKey, basePath, fileName, content, logLabel, }: WriteGeneratedFileArgs): Promise<void>;
23
+ export default function writeGeneratedFile({ dreamPathKey, basePath, fileName, content, logLabel, overwrite, }: WriteGeneratedFileArgs): Promise<void>;
@@ -1,4 +1,11 @@
1
1
  import Dream from '../../Dream.js';
2
+ /**
3
+ * Whether `error` is the `DataTypeColumnTypeMismatch` raised here for a date,
4
+ * datetime or time value Dream cannot convert for its column. Values are
5
+ * converted while a statement is built, so such an error means the statement
6
+ * was never sent to the database.
7
+ */
8
+ export declare function isMismatchRaisedBeforeQuerying(error: unknown): boolean;
2
9
  export declare function normalizeDataForDb({ val, dreamClass, column, }: {
3
10
  val: unknown;
4
11
  dreamClass: typeof Dream;
@@ -114,9 +114,13 @@ declare const ops: {
114
114
  *
115
115
  * **Array columns:** passing an array means literal array equality — the
116
116
  * whole array is bound as a single parameter, so the column must match
117
- * element-for-element, in order. This is the opt-in counterpart to a bare
118
- * array in a where clause (`Post.where({ tags: ['a', 'b'] })`), which means
119
- * `IN`, and to `ops.any`, which tests for containment of a single element.
117
+ * element-for-element, in order. The plain value form of a where clause
118
+ * targets regular (scalar) columns, so comparing an array column against an
119
+ * array value goes through `ops`: a flat list against an array column
120
+ * (`Post.where({ tags: ['a', 'b'] })`) is a compile error. A list of whole
121
+ * arrays (`Post.where({ tags: [['a', 'b'], ['c']] })`) means `IN`, matching
122
+ * rows whose column equals any one of them, and `ops.any` tests for
123
+ * containment of a single element.
120
124
  * Element types are constrained by the column, so an enum array column
121
125
  * rejects a string that is not a member of its enum.
122
126
  *
@@ -25,23 +25,25 @@ export type PassthroughOnClause<PassthroughColumns extends string[]> = Partial<R
25
25
  type DreamSelectable<DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<{
26
26
  [ColumnName in keyof DB[TableName]]: NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, ColumnName>;
27
27
  }>;
28
- type NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, Column, ModelPropertyType = ModelColumnType<Schema, TableName, Column>, ColumnType = TableColumnType<Schema, TableName, Column>, EnumTypeArray extends string[] | null = TableColumnEnumTypeArray<Schema, TableName, Column>, IsArrayColumn = TableColumnIsArray<Schema, TableName, Column>, PermanentOpsValTypes = null | readonly [], ArrayElementType = ModelPropertyType extends readonly (infer ElementType)[] ? ElementType : never, ArrayOpsValType = readonly ArrayElementType[] | PermanentOpsValTypes | RawBuilder<unknown>, OpsValType = IsArrayColumn extends true ? ArrayElementType | PermanentOpsValTypes : EnumTypeArray extends null ? ColumnType extends 'bigint' ? TypesAllowedForBigintAgainstTheDb | PermanentOpsValTypes : ModelPropertyType extends DateTime | CalendarDate ? DateTime | CalendarDate | null : ModelPropertyType extends ClockTime ? ClockTime | null : ModelPropertyType extends ClockTimeTz ? ClockTimeTz | null : ModelPropertyType extends number | string ? ModelPropertyType | PermanentOpsValTypes : never : EnumTypeArray extends string[] ? EnumTypeArray[number] | PermanentOpsValTypes : never, ResolvedOpsValType = OpsValType | RawBuilder<unknown>, PartialTypes = IsArrayColumn extends true ? (EnumTypeArray extends string[] ? EnumTypeArray : never) | OpsStatement<'=' | '!=' | '<>', ArrayOpsValType, any> | OpsStatement<KyselyComparisonOperatorExpression, PermanentOpsValTypes | RawBuilder<unknown>, any> : EnumTypeArray extends null ? ModelPropertyType extends DateTime ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTime ? Range<ClockTime> | Range<null, ClockTime> | (() => Range<ClockTime>) | (() => Range<null, ClockTime>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTimeTz ? Range<ClockTimeTz> | Range<null, ClockTimeTz> | (() => Range<ClockTimeTz>) | (() => Range<null, ClockTimeTz>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends CalendarDate ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType> : ColumnType extends 'bigint' ? Range<TypesAllowedForBigintAgainstTheDb> | Range<null, TypesAllowedForBigintAgainstTheDb> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends number ? Range<ModelPropertyType> | Range<null, ModelPropertyType> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends string ? Range<string> | Range<null, string> | OpsStatement<KyselyComparisonOperatorExpression, string, any> | OpsStatement<TrigramOperator, ResolvedOpsValType, ExtraSimilarityArgs> : never : EnumTypeArray extends string[] ? EnumTypeArray | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : never> = PartialTypes extends never ? OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any> : PartialTypes | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any>;
28
+ type NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, Column, ModelPropertyType = ModelColumnType<Schema, TableName, Column>, ColumnType = TableColumnType<Schema, TableName, Column>, EnumTypeArray extends string[] | null = TableColumnEnumTypeArray<Schema, TableName, Column>, IsArrayColumn = TableColumnIsArray<Schema, TableName, Column>, PermanentOpsValTypes = null | readonly [], ArrayElementType = ModelPropertyType extends readonly (infer ElementType)[] ? ElementType : never, ArrayOpsValType = readonly ArrayElementType[] | PermanentOpsValTypes | RawBuilder<unknown>, OpsValType = IsArrayColumn extends true ? ArrayElementType | PermanentOpsValTypes : EnumTypeArray extends null ? ColumnType extends 'bigint' ? TypesAllowedForBigintAgainstTheDb | PermanentOpsValTypes : ModelPropertyType extends DateTime | CalendarDate ? DateTime | CalendarDate | null : ModelPropertyType extends ClockTime ? ClockTime | null : ModelPropertyType extends ClockTimeTz ? ClockTimeTz | null : ModelPropertyType extends number | string ? ModelPropertyType | PermanentOpsValTypes : never : EnumTypeArray extends string[] ? EnumTypeArray[number] | PermanentOpsValTypes : never, ResolvedOpsValType = OpsValType | RawBuilder<unknown>, PartialTypes = IsArrayColumn extends true ? OpsStatement<'=' | '!=' | '<>', ArrayOpsValType, any> | OpsStatement<KyselyComparisonOperatorExpression, PermanentOpsValTypes | RawBuilder<unknown>, any> : EnumTypeArray extends null ? ModelPropertyType extends DateTime ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTime ? Range<ClockTime> | Range<null, ClockTime> | (() => Range<ClockTime>) | (() => Range<null, ClockTime>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends ClockTimeTz ? Range<ClockTimeTz> | Range<null, ClockTimeTz> | (() => Range<ClockTimeTz>) | (() => Range<null, ClockTimeTz>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends CalendarDate ? Range<DateTime | CalendarDate> | Range<null, DateTime | CalendarDate> | (() => Range<DateTime | CalendarDate>) | (() => Range<null, DateTime | CalendarDate>) | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType> : ColumnType extends 'bigint' ? Range<TypesAllowedForBigintAgainstTheDb> | Range<null, TypesAllowedForBigintAgainstTheDb> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends number ? Range<ModelPropertyType> | Range<null, ModelPropertyType> | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : ModelPropertyType extends string ? Range<string> | Range<null, string> | OpsStatement<KyselyComparisonOperatorExpression, string, any> | OpsStatement<TrigramOperator, ResolvedOpsValType, ExtraSimilarityArgs> : never : EnumTypeArray extends string[] ? EnumTypeArray | OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> : never> = PartialTypes extends never ? OpsStatement<KyselyComparisonOperatorExpression, ResolvedOpsValType, any> | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any> : PartialTypes | CurriedOpsStatement<any, any, any, ResolvedOpsValType> | SelectQueryBuilder<DB, keyof DB, any>;
29
29
  export type WhereStatementForDreamClass<DreamClass extends typeof Dream> = WhereStatement<InstanceType<DreamClass>>;
30
30
  export type WhereStatementForDream<DreamInstance extends Dream> = WhereStatement<DreamInstance>;
31
31
  type AssociationNameToDotReferencedColumns<DB, TableName extends keyof DB, AssociationName> = `${AssociationName & string}.${TableColumnNames<DB, TableName>}`;
32
32
  export type ColumnNamesAccountingForJoinedAssociations<JoinedAssociations extends Readonly<JoinedAssociation[]>, DB, RootTableName extends keyof DB, RootTableAlias extends string> = JoinedAssociations['length'] extends 0 ? TableColumnNames<DB, RootTableName> : TableColumnNames<DB, RootTableName> | JoinedAssociationColumnNames<JoinedAssociations, DB, AssociationNameToDotReferencedColumns<DB, RootTableName & keyof DB, RootTableAlias>>;
33
33
  type JoinedAssociationColumnNames<JoinedAssociations extends Readonly<JoinedAssociation[]>, DB, AllColumnNames, Depth extends number = 0, CurrentJoinedAssociation = Readonly<JoinedAssociations[0]>, NextTableName = CurrentJoinedAssociation extends Readonly<JoinedAssociation> ? CurrentJoinedAssociation['table'] : never, NextAssociationName = CurrentJoinedAssociation extends Readonly<JoinedAssociation> ? CurrentJoinedAssociation['alias'] : never> = JoinedAssociations['length'] extends 0 ? AllColumnNames : Depth extends MAX_JOINED_TABLES_DEPTH ? AllColumnNames : JoinedAssociationColumnNames<ReadonlyTail<JoinedAssociations>, DB, AllColumnNames | AssociationNameToDotReferencedColumns<DB, NextTableName & keyof DB, NextAssociationName>, Inc<Depth>>;
34
- type Whereable<R> = {
35
- [K in keyof Selectable<R>]?: Selectable<R>[K] | Selectable<R>[K][];
34
+ type Whereable<DB, Schema, TableName extends keyof DB, R = DB[TableName]> = {
35
+ [K in keyof Selectable<R>]?: TableColumnIsArray<Schema, TableName, K> extends true ? Extract<Selectable<R>[K], null> | Selectable<R>[K][] : Selectable<R>[K] | Selectable<R>[K][];
36
36
  };
37
37
  type WhereableAssociatedModelParam<I extends Dream> = {
38
38
  [K in keyof AssociatedModelParam<I>]: AssociatedModelParam<I>[K] | NonNullable<AssociatedModelParam<I>[K]>[];
39
39
  };
40
40
  export type WhereStatement<I extends Dream> = InternalWhereStatement<I, I['DB'], I['schema'], I['table']>;
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>>>;
41
+ export type InternalWhereStatement<I extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<MergeUnionOfRecordTypes<Whereable<DB, Schema, TableName> | DreamSelectable<DB, Schema, TableName> | WhereableAssociatedModelParam<I>>>;
42
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;
43
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>;
44
- type OnStatementForAssociationDefinition<DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<MergeUnionOfRecordTypes<Partial<Selectable<DB[TableName]>> | Partial<{
44
+ type OnStatementForAssociationDefinition<DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<MergeUnionOfRecordTypes<Partial<{
45
+ [K in keyof Selectable<DB[TableName]>]: TableColumnIsArray<Schema, TableName, K> extends true ? Extract<Selectable<DB[TableName]>[K], null> | readonly [] : Selectable<DB[TableName]>[K];
46
+ }> | Partial<{
45
47
  [ColumnName in keyof DB[TableName]]: NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, ColumnName> | typeof DreamConst.passthrough | typeof DreamConst.required;
46
48
  }>>>;
47
49
  export type SelfOnStatement<BaseInstance extends Dream, DB, Schema, TableName extends AssociationTableNames<DB, Schema> & keyof DB> = Partial<Record<keyof DB[TableName], DreamColumnNames<BaseInstance>>>;
@@ -134,7 +134,6 @@ type NonKyselySupportedSupplementalWhereClauseValues<
134
134
  // a database error.
135
135
  PartialTypes = IsArrayColumn extends true
136
136
  ?
137
- | (EnumTypeArray extends string[] ? EnumTypeArray : never)
138
137
  | OpsStatement<'=' | '!=' | '<>', ArrayOpsValType, any>
139
138
  | OpsStatement<KyselyComparisonOperatorExpression, PermanentOpsValTypes | RawBuilder<unknown>, any>
140
139
  : EnumTypeArray extends null
@@ -248,8 +247,22 @@ type JoinedAssociationColumnNames<
248
247
  Inc<Depth>
249
248
  >
250
249
 
251
- type Whereable<R> = {
252
- [K in keyof Selectable<R>]?: Selectable<R>[K] | Selectable<R>[K][]
250
+ // The plain value form of a where clause targets regular (scalar) columns: a
251
+ // value means `=`, a list of values means `IN`, and `null` means `IS NULL`.
252
+ // Comparing an array column against an array value goes through `ops`, e.g.
253
+ // `Post.where({ tags: ops.equal(['a', 'b']) })`. An array column's plain value
254
+ // is therefore limited to `null` and a list whose entries are each a whole
255
+ // array or `null` (an `IN` of whole arrays, where `[]` matches nothing). A flat
256
+ // list of elements against an array column, e.g.
257
+ // `Post.where({ tags: ['a', 'b'] })`, is a compile error, since it is rendered
258
+ // as the value list `IN ('a', 'b')`, which PostgreSQL rejects for an array
259
+ // column unless every element is itself an array literal such as `'{a}'`.
260
+ // Array-ness comes from the schema (`TableColumnIsArray`), not from the
261
+ // Kysely column type, which also admits arrays for jsonb columns.
262
+ type Whereable<DB, Schema, TableName extends keyof DB, R = DB[TableName]> = {
263
+ [K in keyof Selectable<R>]?: TableColumnIsArray<Schema, TableName, K> extends true
264
+ ? Extract<Selectable<R>[K], null> | Selectable<R>[K][]
265
+ : Selectable<R>[K] | Selectable<R>[K][]
253
266
  }
254
267
 
255
268
  // For filtering by BelongsTo model instance(s) in a where/and statement, e.g.
@@ -270,7 +283,9 @@ export type InternalWhereStatement<
270
283
  TableName extends AssociationTableNames<DB, Schema> & keyof DB,
271
284
  > = Partial<
272
285
  MergeUnionOfRecordTypes<
273
- Whereable<DB[TableName]> | DreamSelectable<DB, Schema, TableName> | WhereableAssociatedModelParam<I>
286
+ | Whereable<DB, Schema, TableName>
287
+ | DreamSelectable<DB, Schema, TableName>
288
+ | WhereableAssociatedModelParam<I>
274
289
  >
275
290
  >
276
291
 
@@ -314,7 +329,14 @@ type OnStatementForAssociationDefinition<
314
329
  TableName extends AssociationTableNames<DB, Schema> & keyof DB,
315
330
  > = Partial<
316
331
  MergeUnionOfRecordTypes<
317
- | Partial<Selectable<DB[TableName]>>
332
+ // As in `Whereable`, the plain value form targets regular (scalar) columns.
333
+ // An array column accepts only `null` and `[]` as a plain value here;
334
+ // every other comparison against it goes through `ops`.
335
+ | Partial<{
336
+ [K in keyof Selectable<DB[TableName]>]: TableColumnIsArray<Schema, TableName, K> extends true
337
+ ? Extract<Selectable<DB[TableName]>[K], null> | readonly []
338
+ : Selectable<DB[TableName]>[K]
339
+ }>
318
340
  | Partial<{
319
341
  [ColumnName in keyof DB[TableName]]:
320
342
  | NonKyselySupportedSupplementalWhereClauseValues<DB, Schema, TableName, ColumnName>
@@ -1 +1 @@
1
- window.hierarchyData = "eJyVkkFvwjAMhf+Lz4EppQq0x4EmTdPYJk3bAXEIrVkj0gTFKVOF+O9TxqUwWMPJUeTn9+XFe3DWeoJ8wUU6ZpzzJQOHa42FV9YQ5HvgnIdiZI2Qw1uDrp05tUN3LwmBwUaZEnKeTBg0TkMOhZZESHflanjWPax8rYEdOyAHT+UgyAfHCwZFpXTp0EC+SLJseWCQZFnH/akl1G1nao//n/5bCPhoJAJCqB2GV0v+yyHFU1xQ9HAEV3GS+7TCYjO1hryTyvgPZbUMX/SfNTpnHQ2vSWMYkm76U6ub2rzs0K21/Y5xPhHE+KXjjt9MevloCltvpVcrjZ/KV+FuJQkfFOoyAqF3xk0bIThnIRTGhRCMi0n6uyBCiDPs93aLx9eH07OiWvqiiuS9LI6Jb5J2OObWzxutb1mVc0mf5+HwAx1tbyM="
1
+ window.hierarchyData = "eJyVksFuAiEQht9lzmjFNcvKsZomTVPbJk17MB5wd+wSWTDA2myM795QL9TaLp6GkPn5PmAOYI3xDviSstGUUEpXBCxuFJZeGu2AH4BSGooWDQKHlxZtN7dyj/ZWOAQCW6kr4HRcEGitAg6lEs6hu6nWw7PuYe0bBeTUARy8qwYhPjhtEChrqSqLGvgyo2x1JJBRFtEfOoeqi07t4f/qv8aAZqwICqFGDs/G+Q+LLt3iQqLHI1BzlkXUWY3ldma081ZI7d+kUSJ80X9otNZYN/wrmuIwjf9+ZlTb6Kc92o0ynynkH4EEHhtNI95ceHGvS9PshJdrhe/S12FvLRzeSVRVgkLvGVdNRM4yEh6FUDYuCGWT/HtA2Lg4037tdni6fVg9StcIX9aJvpfDKc83ySOPhfGLVqlrRuU80sc8Hr8AEqNvJQ=="