@rvoh/dream 2.41.0 → 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 (261) hide show
  1. package/dist/cjs/src/Dream.js +155 -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 +6 -1
  10. package/dist/cjs/src/dream/internal/updateOrCreateBy.js +6 -1
  11. package/dist/cjs/src/encrypt/algorithms/aes-gcm/decryptAESGCM.js +24 -10
  12. package/dist/cjs/src/errors/CreateOrFindByFailedToCreateAndFind.js +63 -6
  13. package/dist/cjs/src/errors/CreateOrUpdateByFailedToCreateAndUpdate.js +41 -6
  14. package/dist/cjs/src/errors/GeneratedFilesAlreadyExist.js +38 -0
  15. package/dist/cjs/src/errors/schema-builder/ColumnNamesDoNotRoundTrip.js +28 -0
  16. package/dist/cjs/src/helpers/cli/ASTConnectionBuilder.js +62 -10
  17. package/dist/cjs/src/helpers/cli/generateDream.js +109 -18
  18. package/dist/cjs/src/helpers/cli/generateMigration.js +12 -8
  19. package/dist/cjs/src/helpers/cli/writeGeneratedFile.js +3 -3
  20. package/dist/cjs/src/helpers/db/normalizeDataForDb.js +17 -2
  21. package/dist/esm/src/Dream.js +155 -13
  22. package/dist/esm/src/cli/index.js +39 -5
  23. package/dist/esm/src/db/DreamDbConnection.js +19 -1
  24. package/dist/esm/src/dream/DreamClassTransactionBuilder.js +34 -2
  25. package/dist/esm/src/dream/Query.js +178 -14
  26. package/dist/esm/src/dream/QueryDriver/Base.js +80 -0
  27. package/dist/esm/src/dream/QueryDriver/Kysely.js +35 -29
  28. package/dist/esm/src/dream/QueryDriver/Postgres.js +83 -1
  29. package/dist/esm/src/dream/internal/findOrCreateBy.js +6 -1
  30. package/dist/esm/src/dream/internal/updateOrCreateBy.js +6 -1
  31. package/dist/esm/src/encrypt/algorithms/aes-gcm/decryptAESGCM.js +24 -10
  32. package/dist/esm/src/errors/CreateOrFindByFailedToCreateAndFind.js +63 -6
  33. package/dist/esm/src/errors/CreateOrUpdateByFailedToCreateAndUpdate.js +41 -6
  34. package/dist/esm/src/errors/GeneratedFilesAlreadyExist.js +38 -0
  35. package/dist/esm/src/errors/schema-builder/ColumnNamesDoNotRoundTrip.js +28 -0
  36. package/dist/esm/src/helpers/cli/ASTConnectionBuilder.js +62 -10
  37. package/dist/esm/src/helpers/cli/generateDream.js +109 -18
  38. package/dist/esm/src/helpers/cli/generateMigration.js +12 -8
  39. package/dist/esm/src/helpers/cli/writeGeneratedFile.js +3 -3
  40. package/dist/esm/src/helpers/db/normalizeDataForDb.js +17 -2
  41. package/dist/types/src/Dream.d.ts +109 -6
  42. package/dist/types/src/bin/index.d.ts +11 -0
  43. package/dist/types/src/cli/index.d.ts +27 -0
  44. package/dist/types/src/db/DreamDbConnection.d.ts +15 -1
  45. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +34 -2
  46. package/dist/types/src/dream/Query.d.ts +101 -6
  47. package/dist/types/src/dream/QueryDriver/Base.d.ts +59 -0
  48. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +9 -0
  49. package/dist/types/src/dream/QueryDriver/Postgres.d.ts +29 -1
  50. package/dist/types/src/dream/internal/executeDatabaseQuery.d.ts +2 -1
  51. package/dist/types/src/errors/CreateOrFindByFailedToCreateAndFind.d.ts +40 -1
  52. package/dist/types/src/errors/CreateOrUpdateByFailedToCreateAndUpdate.d.ts +8 -1
  53. package/dist/types/src/errors/GeneratedFilesAlreadyExist.d.ts +18 -0
  54. package/dist/types/src/errors/schema-builder/ColumnNamesDoNotRoundTrip.d.ts +12 -0
  55. package/dist/types/src/helpers/cli/ASTConnectionBuilder.d.ts +23 -1
  56. package/dist/types/src/helpers/cli/generateDream.d.ts +25 -0
  57. package/dist/types/src/helpers/cli/generateMigration.d.ts +20 -2
  58. package/dist/types/src/helpers/cli/syncWithFailureContext.d.ts +7 -2
  59. package/dist/types/src/helpers/cli/writeGeneratedFile.d.ts +6 -1
  60. package/dist/types/src/helpers/db/normalizeDataForDb.d.ts +7 -0
  61. package/docs/assets/hierarchy.js +1 -1
  62. package/docs/assets/search.js +1 -1
  63. package/docs/classes/db.DreamMigrationHelpers.html +11 -11
  64. package/docs/classes/db.KyselyQueryDriver.html +87 -50
  65. package/docs/classes/db.PostgresQueryDriver.html +76 -50
  66. package/docs/classes/db.QueryDriverBase.html +87 -50
  67. package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
  68. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  69. package/docs/classes/errors.ColumnOverflow.html +3 -3
  70. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +6 -3
  71. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  72. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  73. package/docs/classes/errors.DecryptionError.html +2 -2
  74. package/docs/classes/errors.DecryptionParseError.html +2 -2
  75. package/docs/classes/errors.DecryptionRotationError.html +3 -3
  76. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  77. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  78. package/docs/classes/errors.InvalidClockTime.html +2 -2
  79. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  80. package/docs/classes/errors.InvalidDateTime.html +2 -2
  81. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  82. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  83. package/docs/classes/errors.NotNullViolation.html +3 -3
  84. package/docs/classes/errors.RecordNotFound.html +3 -3
  85. package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
  86. package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
  87. package/docs/classes/errors.ValidationError.html +3 -3
  88. package/docs/classes/index.CalendarDate.html +33 -33
  89. package/docs/classes/index.ClockTime.html +32 -32
  90. package/docs/classes/index.ClockTimeTz.html +35 -35
  91. package/docs/classes/index.DateTime.html +86 -86
  92. package/docs/classes/index.Decorators.html +19 -19
  93. package/docs/classes/index.Dream.html +203 -133
  94. package/docs/classes/index.DreamApp.html +13 -13
  95. package/docs/classes/index.DreamTransaction.html +3 -3
  96. package/docs/classes/index.Env.html +5 -5
  97. package/docs/classes/index.Query.html +147 -100
  98. package/docs/classes/system.CliFileWriter.html +4 -4
  99. package/docs/classes/system.DreamBin.html +7 -3
  100. package/docs/classes/system.DreamCLI.html +7 -7
  101. package/docs/classes/system.DreamImporter.html +2 -2
  102. package/docs/classes/system.DreamLogos.html +2 -2
  103. package/docs/classes/system.DreamSerializerBuilder.html +11 -11
  104. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  105. package/docs/classes/system.PathHelpers.html +3 -3
  106. package/docs/classes/utils.Encrypt.html +4 -4
  107. package/docs/classes/utils.Range.html +2 -2
  108. package/docs/functions/db.closeAllDbConnections.html +1 -1
  109. package/docs/functions/db.dreamDbConnections.html +1 -1
  110. package/docs/functions/db.untypedDb.html +1 -1
  111. package/docs/functions/db.validateColumn.html +1 -1
  112. package/docs/functions/db.validateTable.html +1 -1
  113. package/docs/functions/errors.pgErrorType.html +1 -1
  114. package/docs/functions/index.DreamSerializer.html +1 -1
  115. package/docs/functions/index.ObjectSerializer.html +1 -1
  116. package/docs/functions/index.ReplicaSafe.html +1 -1
  117. package/docs/functions/index.STI.html +1 -1
  118. package/docs/functions/index.SoftDelete.html +1 -1
  119. package/docs/functions/utils.camelize.html +1 -1
  120. package/docs/functions/utils.capitalize.html +1 -1
  121. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  122. package/docs/functions/utils.compact.html +1 -1
  123. package/docs/functions/utils.groupBy.html +1 -1
  124. package/docs/functions/utils.hyphenize.html +1 -1
  125. package/docs/functions/utils.intersection.html +1 -1
  126. package/docs/functions/utils.isEmpty.html +3 -3
  127. package/docs/functions/utils.normalizeUnicode.html +1 -1
  128. package/docs/functions/utils.pascalize.html +1 -1
  129. package/docs/functions/utils.percent.html +1 -1
  130. package/docs/functions/utils.range.html +1 -1
  131. package/docs/functions/utils.round.html +1 -1
  132. package/docs/functions/utils.sanitizeString.html +1 -1
  133. package/docs/functions/utils.snakeify.html +1 -1
  134. package/docs/functions/utils.sort.html +1 -1
  135. package/docs/functions/utils.sortBy.html +1 -1
  136. package/docs/functions/utils.sortObjectByKey.html +1 -1
  137. package/docs/functions/utils.sortObjectByValue.html +1 -1
  138. package/docs/functions/utils.uncapitalize.html +1 -1
  139. package/docs/functions/utils.uniq.html +1 -1
  140. package/docs/hierarchy.html +1 -1
  141. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  142. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  143. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  144. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  145. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  146. package/docs/interfaces/types.DecoratorContext.html +2 -2
  147. package/docs/interfaces/types.DecryptCallbacks.html +2 -2
  148. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  149. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  150. package/docs/interfaces/types.DreamDbConfig.html +6 -6
  151. package/docs/interfaces/types.DurationObject.html +2 -2
  152. package/docs/interfaces/types.EncryptOptions.html +2 -2
  153. package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +4 -4
  154. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  155. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  156. package/docs/interfaces/types.IntrospectedColumn.html +7 -7
  157. package/docs/interfaces/types.IntrospectedDatabase.html +2 -2
  158. package/docs/interfaces/types.IntrospectedEnum.html +2 -2
  159. package/docs/interfaces/types.IntrospectedTable.html +5 -5
  160. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  161. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  162. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  163. package/docs/types/openapi.OpenapiFormats.html +1 -1
  164. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  165. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  166. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  167. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  168. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  169. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  170. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  171. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  172. package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +1 -1
  173. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  174. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -1
  175. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -1
  176. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -1
  177. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  178. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  179. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  180. package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
  181. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  182. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  183. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  184. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  185. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  186. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  187. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  188. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  189. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  190. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  191. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  192. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  193. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  194. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  195. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  196. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  197. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  198. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  199. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  200. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  201. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  202. package/docs/types/types.CalendarDateObject.html +1 -1
  203. package/docs/types/types.Camelized.html +1 -1
  204. package/docs/types/types.ClockTimeObject.html +1 -1
  205. package/docs/types/types.DbConnectionType.html +1 -1
  206. package/docs/types/types.DbTypes.html +1 -1
  207. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  208. package/docs/types/types.DreamAttributes.html +1 -1
  209. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  210. package/docs/types/types.DreamClassColumn.html +1 -1
  211. package/docs/types/types.DreamColumn.html +1 -1
  212. package/docs/types/types.DreamColumnNames.html +1 -1
  213. package/docs/types/types.DreamLogLevel.html +1 -1
  214. package/docs/types/types.DreamLogger.html +2 -2
  215. package/docs/types/types.DreamModelSerializerType.html +1 -1
  216. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  217. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  218. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  219. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  220. package/docs/types/types.DreamSerializable.html +1 -1
  221. package/docs/types/types.DreamSerializableArray.html +1 -1
  222. package/docs/types/types.DreamSerializerKey.html +1 -1
  223. package/docs/types/types.DreamSerializers.html +1 -1
  224. package/docs/types/types.DreamVirtualColumns.html +1 -1
  225. package/docs/types/types.DurationUnit.html +1 -1
  226. package/docs/types/types.EncryptAlgorithm.html +1 -1
  227. package/docs/types/types.HasManyStatement.html +1 -1
  228. package/docs/types/types.HasOneStatement.html +1 -1
  229. package/docs/types/types.Hyphenized.html +1 -1
  230. package/docs/types/types.IntrospectedValueType.html +1 -1
  231. package/docs/types/types.Pascalized.html +1 -1
  232. package/docs/types/types.PrimaryKeyType.html +1 -1
  233. package/docs/types/types.RoundingPrecision.html +1 -1
  234. package/docs/types/types.SerializerCasing.html +1 -1
  235. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  236. package/docs/types/types.Snakeified.html +1 -1
  237. package/docs/types/types.StrictInterface.html +1 -1
  238. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  239. package/docs/types/types.UpdateableProperties.html +1 -1
  240. package/docs/types/types.ValidationType.html +1 -1
  241. package/docs/types/types.ViewModel.html +2 -2
  242. package/docs/types/types.ViewModelClass.html +1 -1
  243. package/docs/types/types.WeekdayName.html +1 -1
  244. package/docs/types/types.WhereStatementForDream.html +1 -1
  245. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  246. package/docs/variables/index.DreamConst.html +1 -1
  247. package/docs/variables/index.ops.html +1 -1
  248. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  249. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  250. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  251. package/docs/variables/system.primaryKeyTypes.html +1 -1
  252. package/package.json +1 -1
  253. package/dist/cjs/src/helpers/cli/generateFactory.js +0 -10
  254. package/dist/cjs/src/helpers/cli/generateSerializer.js +0 -18
  255. package/dist/cjs/src/helpers/cli/generateUnitSpec.js +0 -10
  256. package/dist/esm/src/helpers/cli/generateFactory.js +0 -10
  257. package/dist/esm/src/helpers/cli/generateSerializer.js +0 -18
  258. package/dist/esm/src/helpers/cli/generateUnitSpec.js +0 -10
  259. package/dist/types/src/helpers/cli/generateFactory.d.ts +0 -5
  260. package/dist/types/src/helpers/cli/generateSerializer.d.ts +0 -9
  261. package/dist/types/src/helpers/cli/generateUnitSpec.d.ts +0 -3
@@ -938,6 +938,18 @@ export default class Dream {
938
938
  * IMPORTANT: A unique index/uniqueness constraint must exist on
939
939
  * at least one of the provided attributes
940
940
  *
941
+ * The lookup applies the model's default scopes, so a conflicting
942
+ * record they hide (for example, a soft-deleted one under a plain
943
+ * unique index) is never returned. When the lookup finds nothing,
944
+ * `CreateOrFindByFailedToCreateAndFind` is thrown. When the database
945
+ * identifies the violated unique index (Postgres does, unless it is an
946
+ * expression or partial index), its message names the `createWith`
947
+ * attributes that index covers as the likely cause, unless the index
948
+ * also covers every find attribute. When the index covers only find
949
+ * attributes, or every find attribute, and the record is found with the
950
+ * model's default scopes removed, the message names the default scope
951
+ * likely hiding it. Otherwise it lists the possible causes.
952
+ *
941
953
  * ```ts
942
954
  * const logEntry = await LogEntry.createOrFindBy({ externalId }, { createWith: params })
943
955
  * ```
@@ -977,6 +989,18 @@ export default class Dream {
977
989
  * IMPORTANT: A unique index/uniqueness constraint must exist on
978
990
  * at least one of the provided attributes
979
991
  *
992
+ * The lookup applies the model's default scopes, so a conflicting
993
+ * record they hide (for example, a soft-deleted one under a plain
994
+ * unique index) is never updated. When the lookup finds nothing,
995
+ * `CreateOrUpdateByFailedToCreateAndUpdate` is thrown. When the database
996
+ * identifies the violated unique index (Postgres does, unless it is an
997
+ * expression or partial index), its message names the `with`
998
+ * attributes that index covers as the likely cause, unless the index
999
+ * also covers every find attribute. When the index covers only find
1000
+ * attributes, or every find attribute, and the record is found with the
1001
+ * model's default scopes removed, the message names the default scope
1002
+ * likely hiding it. Otherwise it lists the possible causes.
1003
+ *
980
1004
  * @param attributes - The base attributes for finding which record to update, also used when creating
981
1005
  * @param extraOpts - Additional options
982
1006
  * @param extraOpts.with - additional attributes to persist when updating and creating, but not used for finding
@@ -984,6 +1008,30 @@ export default class Dream {
984
1008
  * @returns A dream instance
985
1009
  */
986
1010
  static createOrUpdateBy<T extends typeof Dream>(this: T, attributes: FindablePropertiesForClass<T>, extraOpts?: UpdateOrCreateByExtraOpts<T>): Promise<InstanceType<T>>;
1011
+ /**
1012
+ * @internal
1013
+ *
1014
+ * Used by createOrFindBy and createOrUpdateBy after their default-scoped
1015
+ * lookup finds nothing, to tell why. The driver names the columns of the
1016
+ * unique index the insert violated, when it can. When that index covers a
1017
+ * `createWith`/`with` attribute but not every find attribute, one of those
1018
+ * values likely conflicted with another record. When it covers only find
1019
+ * attributes, or every find attribute, a record matching them that the
1020
+ * default scopes hide is the record the insert conflicted with. Otherwise
1021
+ * the cause is undetermined, and a hidden record matching the find
1022
+ * attributes is only a candidate.
1023
+ */
1024
+ private static createOrFindFailureCause;
1025
+ /**
1026
+ * @internal
1027
+ *
1028
+ * Used by createOrFindFailureCause. Returns the model's removable default scopes when a
1029
+ * record matching `lookup` exists once they are all removed, and an empty
1030
+ * array otherwise. The STI type discriminator is never removed. One probe
1031
+ * with every removable scope removed cannot tell which of several scopes
1032
+ * hid the record, so all of them are returned as candidates.
1033
+ */
1034
+ private static defaultScopesHidingLookup;
987
1035
  /**
988
1036
  * Returns a new query instance with the distinct query applied.
989
1037
  * If no columnName is provided, then distinct will apply to the
@@ -1008,12 +1056,25 @@ export default class Dream {
1008
1056
  }>>;
1009
1057
  /**
1010
1058
  * Finds a record for the corresponding model with the
1011
- * specified primary key. Returns null if not found.
1059
+ * specified primary key. Returns null if not found,
1060
+ * including when the primary key is a value its column
1061
+ * cannot hold (for example, `'abc'` for an integer
1062
+ * primary key).
1063
+ *
1064
+ * When the database rejects a value elsewhere in the query (for
1065
+ * example, in a `whereNot`, `whereAny` or `leftJoinPreload`
1066
+ * clause), that rejection is raised as `DataTypeColumnTypeMismatch`
1067
+ * or `ColumnOverflow`, since a record may still match. Inside a
1068
+ * transaction, a primary key the database rejects is raised that
1069
+ * way too, because the database has then aborted the transaction.
1012
1070
  *
1013
1071
  * ```ts
1014
1072
  * await User.find(123)
1015
1073
  * // User{id: 123}
1016
1074
  *
1075
+ * await User.find('abc')
1076
+ * // null
1077
+ *
1017
1078
  * await User.find(null)
1018
1079
  * // null
1019
1080
  *
@@ -1027,15 +1088,26 @@ export default class Dream {
1027
1088
  static find<T extends typeof Dream, I extends InstanceType<T>>(this: T, primaryKey: PrimaryKeyForFind<I>): Promise<InstanceType<T> | null>;
1028
1089
  /**
1029
1090
  * Finds a record for the corresponding model with the
1030
- * specified primary key. If not found, an exception is raised.
1091
+ * specified primary key. If not found, `RecordNotFound` is
1092
+ * raised, including when the primary key is a value its
1093
+ * column cannot hold (for example, `'abc'` for an integer
1094
+ * primary key).
1095
+ *
1096
+ * When the database rejects a value elsewhere in the query (for
1097
+ * example, in a `whereNot`, `whereAny` or `leftJoinPreload`
1098
+ * clause), that rejection is raised as `DataTypeColumnTypeMismatch`
1099
+ * or `ColumnOverflow`, since a record may still match. Inside a
1100
+ * transaction, a primary key the database rejects is raised that
1101
+ * way too, because the database has then aborted the transaction.
1031
1102
  *
1032
1103
  * ```ts
1033
- * await User.query().findOrFail(123)
1104
+ * await User.findOrFail(123)
1034
1105
  * // User{id: 123}
1035
1106
  * ```
1036
1107
  *
1037
1108
  * @param primaryKey - The primaryKey of the record to look up
1038
- * @returns Either the found record, or else null
1109
+ * @returns The found record
1110
+ * @throws RecordNotFound if no record is found
1039
1111
  */
1040
1112
  static findOrFail<T extends typeof Dream, I extends InstanceType<T>>(this: T, primaryKey: PrimaryKeyForFind<I>): Promise<InstanceType<T>>;
1041
1113
  /**
@@ -1139,7 +1211,22 @@ export default class Dream {
1139
1211
  /**
1140
1212
  * Finds the first record—ordered by primary key—matching
1141
1213
  * the corresponding model and the specified where statement.
1142
- * If not found, null is returned.
1214
+ * If not found, null is returned, including when a value the where
1215
+ * statement compares for equality (a plain value or
1216
+ * `ops.equal`) is one its column cannot hold: for example,
1217
+ * `'abc'` for a uuid column, or a date string Dream cannot
1218
+ * parse for a date column.
1219
+ *
1220
+ * A value the database rejects anywhere else (in a list of values,
1221
+ * under another operator such as `ops.not.equal` or `ops.lessThan`,
1222
+ * or elsewhere in the query, such as a `whereNot` or `whereAny`
1223
+ * clause) is raised as `DataTypeColumnTypeMismatch` or
1224
+ * `ColumnOverflow`, since a record may still match; so is a date,
1225
+ * datetime or time string there that Dream cannot parse. Inside a
1226
+ * transaction, an equality value the database rejects is raised that
1227
+ * way too, because the database has then aborted the transaction; a
1228
+ * date, datetime or time string Dream cannot parse never reaches the
1229
+ * database, so it is treated as not found there as well.
1143
1230
  *
1144
1231
  * ```ts
1145
1232
  * await User.findBy({ email: 'how@yadoin' })
@@ -1153,7 +1240,22 @@ export default class Dream {
1153
1240
  /**
1154
1241
  * Finds the first record—ordered by primary key—matching
1155
1242
  * the corresponding model and the specified where statement.
1156
- * If not found, an exception is raised.
1243
+ * If not found, `RecordNotFound` is raised, including when
1244
+ * a value the where statement compares for equality (a plain
1245
+ * value or `ops.equal`) is one its column cannot hold: for
1246
+ * example, `'abc'` for a uuid column, or a date string Dream
1247
+ * cannot parse for a date column.
1248
+ *
1249
+ * A value the database rejects anywhere else (in a list of values,
1250
+ * under another operator such as `ops.not.equal` or `ops.lessThan`,
1251
+ * or elsewhere in the query, such as a `whereNot` or `whereAny`
1252
+ * clause) is raised as `DataTypeColumnTypeMismatch` or
1253
+ * `ColumnOverflow`, since a record may still match; so is a date,
1254
+ * datetime or time string there that Dream cannot parse. Inside a
1255
+ * transaction, an equality value the database rejects is raised that
1256
+ * way too, because the database has then aborted the transaction; a
1257
+ * date, datetime or time string Dream cannot parse never reaches the
1258
+ * database, so it is treated as not found there as well.
1157
1259
  *
1158
1260
  * ```ts
1159
1261
  * await User.findOrFailBy({ email: 'how@yadoin' })
@@ -1162,6 +1264,7 @@ export default class Dream {
1162
1264
  *
1163
1265
  * @param whereStatement - The where statement used to locate the record
1164
1266
  * @returns The first model found matching the whereStatement
1267
+ * @throws RecordNotFound if no record is found
1165
1268
  */
1166
1269
  static findOrFailBy<T extends typeof Dream, I extends InstanceType<T>>(this: T, whereStatement: WhereStatement<I>): Promise<InstanceType<T>>;
1167
1270
  /**
@@ -1,3 +1,4 @@
1
+ import { type GenerateDreamExistingFiles } from '../helpers/cli/generateDream.js';
1
2
  export default class DreamBin {
2
3
  static sync(onSync: () => Promise<void> | void, options?: {
3
4
  schemaOnly?: boolean;
@@ -18,6 +19,11 @@ export default class DreamBin {
18
19
  internalSerializers?: boolean;
19
20
  modelName?: string;
20
21
  softDelete?: boolean;
22
+ /**
23
+ * What to do when a file the generator would write already exists.
24
+ * Defaults to `'refuse'`. See {@link GenerateDreamExistingFiles}.
25
+ */
26
+ existingFiles?: GenerateDreamExistingFiles;
21
27
  }): Promise<void>;
22
28
  static generateStiChild(fullyQualifiedModelName: string, fullyQualifiedParentName: string, columnsWithTypes: string[], options: {
23
29
  serializer: boolean;
@@ -31,6 +37,11 @@ export default class DreamBin {
31
37
  adminSerializers?: boolean;
32
38
  internalSerializers?: boolean;
33
39
  modelName?: string;
40
+ /**
41
+ * What to do when a file the generator would write already exists.
42
+ * Defaults to `'refuse'`. See {@link GenerateDreamExistingFiles}.
43
+ */
44
+ existingFiles?: GenerateDreamExistingFiles;
34
45
  }): Promise<void>;
35
46
  static generateMigration(migrationName: string, columnsWithTypes: string[], connectionName: string): Promise<void>;
36
47
  private static buildDocs;
@@ -79,6 +79,33 @@ export default class DreamCLI {
79
79
  * point — the CLI layer opts users in by default.
80
80
  */
81
81
  softDelete?: boolean;
82
+ /**
83
+ * What to do when a file the generator would write already exists:
84
+ * - `'refuse'` (the default): write nothing and throw an error listing
85
+ * the existing files
86
+ * - `'overwrite'`: replace the model, spec, factory and serializer files
87
+ * - `'skip'`: keep every existing file, write only the missing ones, and
88
+ * log each file kept
89
+ *
90
+ * An existing migration with the name the generator would give the
91
+ * model's migration is kept under `'overwrite'` and `'skip'`, never
92
+ * rewritten or duplicated. Under `'skip'`, no migration is written when
93
+ * the model file already exists, even if no migration has that name,
94
+ * since the model's schema may come from a migration with another name.
95
+ */
96
+ existingFiles?: 'refuse' | 'overwrite' | 'skip';
97
+ /**
98
+ * The caller's own flags for `existingFiles: 'overwrite'` and
99
+ * `existingFiles: 'skip'`, named in the refusal in place of Dream's
100
+ * `--overwrite` and `--skip-existing`. With them, the refusal names
101
+ * these two flags and no Dream command. For example, a caller whose
102
+ * flags are `--overwrite` and `--overwrite-psychic-only` passes
103
+ * `{ overwrite: '--overwrite', skip: '--overwrite-psychic-only' }`.
104
+ */
105
+ existingFilesFlags?: {
106
+ overwrite: string;
107
+ skip: string;
108
+ };
82
109
  };
83
110
  fullyQualifiedParentName?: string | undefined;
84
111
  }): Promise<void>;
@@ -1,6 +1,20 @@
1
- import { Kysely } from 'kysely';
1
+ import { CamelCasePlugin, Kysely } from 'kysely';
2
2
  import { DreamDbConfig } from '../dream-app/index.js';
3
3
  import { DbConnectionType } from '../types/db.js';
4
+ /**
5
+ * @internal
6
+ *
7
+ * the CamelCasePlugin every Dream connection carries: it turns each
8
+ * attribute name a query names into the column name it queries, and each
9
+ * column name a result row carries into a camelized key
10
+ */
11
+ export declare class DreamCamelCasePlugin extends CamelCasePlugin {
12
+ constructor();
13
+ /**
14
+ * the column name a query naming the given attribute targets
15
+ */
16
+ columnNameForAttribute(attributeName: string): string;
17
+ }
4
18
  export default class DreamDbConnection {
5
19
  static getConnection<DB>(connectionName: string, connectionType: DbConnectionType, dialectProvider: DialectProviderCb): Kysely<DB>;
6
20
  private static getConnectionTypeName;
@@ -269,6 +269,12 @@ export default class DreamClassTransactionBuilder<DreamClass extends typeof Drea
269
269
  * Finds a record for the corresponding model with the
270
270
  * specified primary key. If not found, null is returned.
271
271
  *
272
+ * A value the database rejects as one its column cannot hold,
273
+ * whether the primary key (for example, `'abc'` for an integer
274
+ * primary key) or a value elsewhere in the query, raises
275
+ * `DataTypeColumnTypeMismatch` or `ColumnOverflow`, because the
276
+ * database has then aborted the transaction.
277
+ *
272
278
  * ```ts
273
279
  * await ApplicationModel.transaction(async txn => {
274
280
  * await User.txn(txn).find(123)
@@ -290,6 +296,12 @@ export default class DreamClassTransactionBuilder<DreamClass extends typeof Drea
290
296
  * Finds a record for the corresponding model with the
291
297
  * specified primary key. If not found, an exception is raised.
292
298
  *
299
+ * A value the database rejects as one its column cannot hold,
300
+ * whether the primary key (for example, `'abc'` for an integer
301
+ * primary key) or a value elsewhere in the query, raises
302
+ * `DataTypeColumnTypeMismatch` or `ColumnOverflow`, because the
303
+ * database has then aborted the transaction.
304
+ *
293
305
  * ```ts
294
306
  * await ApplicationModel.transaction(async txn => {
295
307
  * await User.txn(txn).findOrFail(123)
@@ -304,7 +316,17 @@ export default class DreamClassTransactionBuilder<DreamClass extends typeof Drea
304
316
  /**
305
317
  * Finds the first record—ordered by primary key—matching
306
318
  * the corresponding model and the specified where statement.
307
- * If not found, null is returned.
319
+ * If not found, null is returned, including when a value the where
320
+ * statement compares for equality (a plain value or `ops.equal`)
321
+ * is a date, datetime or time string Dream cannot parse for its
322
+ * column, which never reaches the database.
323
+ *
324
+ * A value the database rejects as one its column cannot hold
325
+ * (for example, `'abc'` for a uuid column) raises
326
+ * `DataTypeColumnTypeMismatch` or `ColumnOverflow`, because the
327
+ * database has then aborted the transaction. A date, datetime or
328
+ * time string Dream cannot parse anywhere else in the query raises
329
+ * `DataTypeColumnTypeMismatch`.
308
330
  *
309
331
  * ```ts
310
332
  * await ApplicationModel.transaction(async txn => {
@@ -320,7 +342,17 @@ export default class DreamClassTransactionBuilder<DreamClass extends typeof Drea
320
342
  /**
321
343
  * Finds the first record—ordered by primary key—matching
322
344
  * the corresponding model and the specified where statement.
323
- * If not found, an exception is raised.
345
+ * If not found, `RecordNotFound` is raised, including when a
346
+ * value the where statement compares for equality (a plain value
347
+ * or `ops.equal`) is a date, datetime or time string Dream cannot
348
+ * parse for its column, which never reaches the database.
349
+ *
350
+ * A value the database rejects as one its column cannot hold
351
+ * (for example, `'abc'` for a uuid column) raises
352
+ * `DataTypeColumnTypeMismatch` or `ColumnOverflow`, because the
353
+ * database has then aborted the transaction. A date, datetime or
354
+ * time string Dream cannot parse anywhere else in the query raises
355
+ * `DataTypeColumnTypeMismatch`.
324
356
  *
325
357
  * ```ts
326
358
  * await ApplicationModel.transaction(async txn => {
@@ -237,12 +237,25 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
237
237
  clone<Q extends Query<DreamInstance, QueryTypeOpts>>(this: Q, opts?: QueryOpts<DreamInstance, any>): Q;
238
238
  /**
239
239
  * Finds a record matching the Query with the
240
- * specified primary key. Returns null if not found.
240
+ * specified primary key. Returns null if not found,
241
+ * including when the primary key is a value its column
242
+ * cannot hold (for example, `'abc'` for an integer
243
+ * primary key).
244
+ *
245
+ * When the database rejects a value elsewhere in the Query (for
246
+ * example, in a `whereNot`, `whereAny` or `leftJoinPreload`
247
+ * clause), that rejection is raised as `DataTypeColumnTypeMismatch`
248
+ * or `ColumnOverflow`, since a record may still match. Inside a
249
+ * transaction, a primary key the database rejects is raised that
250
+ * way too, because the database has then aborted the transaction.
241
251
  *
242
252
  * ```ts
243
253
  * await User.query().find(123)
244
254
  * // User{id: 123}
245
255
  *
256
+ * await User.query().find('abc')
257
+ * // null
258
+ *
246
259
  * await User.query().find(null)
247
260
  * // null
248
261
  *
@@ -256,8 +269,17 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
256
269
  find(primaryKey: PrimaryKeyForFind<DreamInstance>): Promise<DreamInstance | null>;
257
270
  /**
258
271
  * Finds a record matching the Query with the
259
- * specified primary key. If not found, an exception
260
- * is raised.
272
+ * specified primary key. If not found, `RecordNotFound`
273
+ * is raised, including when the primary key is a value
274
+ * its column cannot hold (for example, `'abc'` for an
275
+ * integer primary key).
276
+ *
277
+ * When the database rejects a value elsewhere in the Query (for
278
+ * example, in a `whereNot`, `whereAny` or `leftJoinPreload`
279
+ * clause), that rejection is raised as `DataTypeColumnTypeMismatch`
280
+ * or `ColumnOverflow`, since a record may still match. Inside a
281
+ * transaction, a primary key the database rejects is raised that
282
+ * way too, because the database has then aborted the transaction.
261
283
  *
262
284
  * ```ts
263
285
  * await User.query().findOrFail(123)
@@ -266,12 +288,28 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
266
288
  *
267
289
  * @param primaryKey - The primary key of the record to look up
268
290
  * @returns The found record
291
+ * @throws RecordNotFound if no record is found
269
292
  */
270
293
  findOrFail(primaryKey: PrimaryKeyForFind<DreamInstance>): Promise<DreamInstance>;
271
294
  /**
272
295
  * Finds a record matching the Query and the
273
296
  * specified where statement. If not found, null
274
- * is returned.
297
+ * is returned, including when a value the where
298
+ * statement compares for equality (a plain value or
299
+ * `ops.equal`) is one its column cannot hold: for example,
300
+ * `'abc'` for a uuid column, or a date string Dream cannot
301
+ * parse for a date column.
302
+ *
303
+ * A value the database rejects anywhere else (in a list of values,
304
+ * under another operator such as `ops.not.equal` or `ops.lessThan`,
305
+ * or elsewhere in the Query, such as a `whereNot` or `whereAny`
306
+ * clause) is raised as `DataTypeColumnTypeMismatch` or
307
+ * `ColumnOverflow`, since a record may still match; so is a date,
308
+ * datetime or time string there that Dream cannot parse. Inside a
309
+ * transaction, an equality value the database rejects is raised that
310
+ * way too, because the database has then aborted the transaction; a
311
+ * date, datetime or time string Dream cannot parse never reaches the
312
+ * database, so it is treated as not found there as well.
275
313
  *
276
314
  * ```ts
277
315
  * await User.query().findBy({ email: 'how@yadoin' })
@@ -284,8 +322,23 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
284
322
  findBy(whereStatement: WhereStatement<DreamInstance>): Promise<DreamInstance | null>;
285
323
  /**
286
324
  * Finds a record matching the Query and the
287
- * specified where statement. If not found, an exception
288
- * is raised.
325
+ * specified where statement. If not found, `RecordNotFound`
326
+ * is raised, including when a value the where
327
+ * statement compares for equality (a plain value or
328
+ * `ops.equal`) is one its column cannot hold: for example,
329
+ * `'abc'` for a uuid column, or a date string Dream cannot
330
+ * parse for a date column.
331
+ *
332
+ * A value the database rejects anywhere else (in a list of values,
333
+ * under another operator such as `ops.not.equal` or `ops.lessThan`,
334
+ * or elsewhere in the Query, such as a `whereNot` or `whereAny`
335
+ * clause) is raised as `DataTypeColumnTypeMismatch` or
336
+ * `ColumnOverflow`, since a record may still match; so is a date,
337
+ * datetime or time string there that Dream cannot parse. Inside a
338
+ * transaction, an equality value the database rejects is raised that
339
+ * way too, because the database has then aborted the transaction; a
340
+ * date, datetime or time string Dream cannot parse never reaches the
341
+ * database, so it is treated as not found there as well.
289
342
  *
290
343
  * ```ts
291
344
  * await User.query().findOrFailBy({ email: 'how@yadoin' })
@@ -294,8 +347,50 @@ export default class Query<DreamInstance extends Dream, QueryTypeOpts extends Re
294
347
  *
295
348
  * @param whereStatement - The where statement used to locate the record
296
349
  * @returns The first record found matching the attributes
350
+ * @throws RecordNotFound if no record is found
297
351
  */
298
352
  findOrFailBy(whereStatement: WhereStatement<DreamInstance>): Promise<DreamInstance>;
353
+ /**
354
+ * @internal
355
+ *
356
+ * The first record of this Query, for `find` and `findBy`, whose `lookup`
357
+ * (the primary key or where statement they were given) is already applied.
358
+ * Returns null when the lookup's own values tell that no record can match
359
+ * (see `lookupValueCannotBeHeld`); every other error is raised. Preloads
360
+ * run after the lookup's statement, so a rejected value in a preload clause
361
+ * is raised.
362
+ */
363
+ private firstForLookup;
364
+ /**
365
+ * @internal
366
+ *
367
+ * Whether `error`, raised by a `find` or `findBy` statement, is a value of
368
+ * the lookup's own equality comparisons (see `lookupEqualityValues`) that
369
+ * its column cannot hold. Every matching record must equal each of those
370
+ * values, so when one cannot be held, no record can match. A rejected value
371
+ * anywhere else (a negated or OR'd clause, a join's `and` clause, a list of
372
+ * values, a negated or ordering operator) does not tell that, so it is
373
+ * raised.
374
+ *
375
+ * When Dream itself could not convert a value (a date, datetime or time
376
+ * string it cannot parse), nothing reached the database, and Dream's
377
+ * conversion of the lookup's values alone tells whether one of them was
378
+ * the value. When the database rejected the statement, the driver is asked
379
+ * whether it rejects one of the lookup's values on its own; inside a
380
+ * transaction it cannot be asked, since the database has aborted the
381
+ * transaction, so the error is raised.
382
+ */
383
+ private lookupValueCannotBeHeld;
384
+ /**
385
+ * @internal
386
+ *
387
+ * The values a `find` or `findBy` lookup compares a column of this model
388
+ * with `=`, as a plain value or `ops.equal`: the primary key for `find`.
389
+ * Lists of values, other operators, ranges, associations, subqueries and
390
+ * nulls are left out, since a value there that its column cannot hold does
391
+ * not stop a record from matching the lookup.
392
+ */
393
+ private lookupEqualityValues;
299
394
  /**
300
395
  * Finds all records matching the Query in batches,
301
396
  * and then calls the provided callback for each found record.
@@ -1,5 +1,6 @@
1
1
  import { CompiledQuery, DeleteQueryBuilder, SelectQueryBuilder, UpdateQueryBuilder } from 'kysely';
2
2
  import Dream from '../../Dream.js';
3
+ import DataIncompatibleWithDatabaseField from '../../errors/db/DataIncompatibleWithDatabaseField.js';
3
4
  import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
4
5
  import { DbConnectionType, IntrospectedDatabase, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
5
6
  import { DreamColumnNames, DreamConstructorType, DreamTableSchema } from '../../types/dream.js';
@@ -170,6 +171,22 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
170
171
  * is retried.
171
172
  */
172
173
  static isUniqueConstraintViolation(error: unknown): boolean;
174
+ /**
175
+ * @internal
176
+ *
177
+ * The columns of the unique index whose violation `error` reports, in index
178
+ * order, when that index is on `table` and is a plain one: every key is a
179
+ * column and it has no predicate. `createOrFindBy` and `createOrUpdateBy`
180
+ * ask this after a failed insert to tell which of their attributes
181
+ * conflicted. Returns null when the driver cannot tell, when the index is
182
+ * on another table, or when it is an expression or partial index; the
183
+ * default returns null.
184
+ *
185
+ * @param connectionName - the connection the insert ran on
186
+ * @param error - the error the insert raised
187
+ * @param table - the table the insert wrote to
188
+ */
189
+ static violatedUniqueIndexColumns(connectionName: string, error: unknown, table: string): Promise<string[] | null>;
173
190
  /**
174
191
  * @internal
175
192
  *
@@ -179,6 +196,38 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
179
196
  * false, and nothing is retried.
180
197
  */
181
198
  static isDeadlock(error: unknown): boolean;
199
+ /**
200
+ * @internal
201
+ *
202
+ * The Dream error to raise in place of `error` when `error` is the database
203
+ * rejecting a value for the column it is written to or compared with: a value
204
+ * the column's type cannot represent, a null in a NOT NULL column, or a CHECK
205
+ * constraint violation. Saves and reads (selects, aggregates, plucks and
206
+ * preloads) raise the returned error; bulk `Query#update` and `Query#delete`
207
+ * do not consult this. A driver that does not recognize the error returns
208
+ * null, and the original error propagates unchanged.
209
+ */
210
+ static dataIncompatibleWithDatabaseFieldError(error: unknown): DataIncompatibleWithDatabaseField | null;
211
+ /**
212
+ * @internal
213
+ *
214
+ * Whether the database rejects any of `values` as input for its `dbType`
215
+ * (the column type in the model's schema), judged by the database's own
216
+ * input rules. `find` and `findBy` ask this, outside a transaction, after
217
+ * the database rejected their statement, passing the values their lookup
218
+ * compares for equality: when one of those is rejected, no record can match
219
+ * the lookup, which then returns null; otherwise the rejected value was
220
+ * elsewhere in the Query, and the statement's error is raised. A driver that
221
+ * cannot tell returns false; the default does.
222
+ *
223
+ * @param connectionName - the connection the lookup ran on
224
+ * @param dbConnectionType - the connection type to ask on
225
+ * @param values - each value as sent to the database, with its column's type
226
+ */
227
+ static rejectsAnyValueForColumnType(connectionName: string, dbConnectionType: DbConnectionType, values: {
228
+ value: unknown;
229
+ dbType: string;
230
+ }[]): Promise<boolean>;
182
231
  /**
183
232
  * @internal
184
233
  *
@@ -405,6 +454,16 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
405
454
  * @returns A Map from each present group value to the average of the aggregated column in that group
406
455
  */
407
456
  avgBy(groupColumn: string, aggregatedColumn: string): Promise<Map<any, any>>;
457
+ /**
458
+ * Returns true if a record matches the Query, false otherwise
459
+ *
460
+ * ```ts
461
+ * await User.where({ email: 'how@yadoin' }).exists()
462
+ * ```
463
+ *
464
+ * @returns true if any records match the Query, false otherwise
465
+ */
466
+ exists(): Promise<boolean>;
408
467
  /**
409
468
  * Retrieves the number of records in the database
410
469
  *
@@ -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;