@rvoh/dream 2.35.0 → 2.36.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/src/Dream.js +260 -55
  3. package/dist/cjs/src/bin/index.js +13 -0
  4. package/dist/cjs/src/cli/index.js +28 -17
  5. package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
  6. package/dist/cjs/src/decorators/Decorators.js +26 -4
  7. package/dist/cjs/src/decorators/field/Encrypted.js +35 -6
  8. package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +6 -6
  9. package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +63 -27
  10. package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +3 -3
  11. package/dist/cjs/src/dream/LoadBuilder.js +1 -1
  12. package/dist/cjs/src/dream/Query.js +542 -167
  13. package/dist/cjs/src/dream/QueryDriver/Base.js +72 -0
  14. package/dist/cjs/src/dream/QueryDriver/Kysely.js +216 -50
  15. package/dist/cjs/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
  16. package/dist/cjs/src/dream/internal/associations/associationQuery.js +4 -0
  17. package/dist/cjs/src/dream/internal/reload.js +6 -1
  18. package/dist/cjs/src/dream/internal/saveDream.js +8 -2
  19. package/dist/cjs/src/dream/internal/sqlResultToDreamInstance.js +2 -0
  20. package/dist/cjs/src/dream/internal/undestroyDream.js +1 -1
  21. package/dist/cjs/src/dream-app/index.js +38 -0
  22. package/dist/cjs/src/encrypt/InternalEncrypt.js +77 -4
  23. package/dist/cjs/src/encrypt/defaultEncryptedColumnName.js +10 -0
  24. package/dist/cjs/src/encrypt/index.js +76 -9
  25. package/dist/cjs/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
  26. package/dist/cjs/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
  27. package/dist/cjs/src/helpers/Env.js +28 -0
  28. package/dist/cjs/src/helpers/cli/generateDreamContent.js +2 -1
  29. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +1 -1
  30. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +9 -9
  31. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +21 -8
  32. package/dist/cjs/src/serializer/SerializerRenderer.js +65 -13
  33. package/dist/cjs/src/serializer/builders/DreamSerializerBuilder.js +54 -38
  34. package/dist/cjs/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
  35. package/dist/cjs/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
  36. package/dist/esm/src/Dream.js +260 -55
  37. package/dist/esm/src/bin/index.js +13 -0
  38. package/dist/esm/src/cli/index.js +28 -17
  39. package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
  40. package/dist/esm/src/decorators/Decorators.js +26 -4
  41. package/dist/esm/src/decorators/field/Encrypted.js +35 -6
  42. package/dist/esm/src/dream/DreamClassTransactionBuilder.js +6 -6
  43. package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +63 -27
  44. package/dist/esm/src/dream/LeftJoinLoadBuilder.js +3 -3
  45. package/dist/esm/src/dream/LoadBuilder.js +1 -1
  46. package/dist/esm/src/dream/Query.js +542 -167
  47. package/dist/esm/src/dream/QueryDriver/Base.js +72 -0
  48. package/dist/esm/src/dream/QueryDriver/Kysely.js +216 -50
  49. package/dist/esm/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
  50. package/dist/esm/src/dream/internal/associations/associationQuery.js +4 -0
  51. package/dist/esm/src/dream/internal/reload.js +6 -1
  52. package/dist/esm/src/dream/internal/saveDream.js +8 -2
  53. package/dist/esm/src/dream/internal/sqlResultToDreamInstance.js +2 -0
  54. package/dist/esm/src/dream/internal/undestroyDream.js +1 -1
  55. package/dist/esm/src/dream-app/index.js +38 -0
  56. package/dist/esm/src/encrypt/InternalEncrypt.js +77 -4
  57. package/dist/esm/src/encrypt/defaultEncryptedColumnName.js +10 -0
  58. package/dist/esm/src/encrypt/index.js +76 -9
  59. package/dist/esm/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
  60. package/dist/esm/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
  61. package/dist/esm/src/helpers/Env.js +28 -0
  62. package/dist/esm/src/helpers/cli/generateDreamContent.js +2 -1
  63. package/dist/esm/src/helpers/cli/generateFactoryContent.js +1 -1
  64. package/dist/esm/src/helpers/cli/generateMigrationContent.js +9 -9
  65. package/dist/esm/src/helpers/cli/generateSerializerContent.js +21 -8
  66. package/dist/esm/src/serializer/SerializerRenderer.js +65 -13
  67. package/dist/esm/src/serializer/builders/DreamSerializerBuilder.js +54 -38
  68. package/dist/esm/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
  69. package/dist/esm/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
  70. package/dist/types/src/Dream.d.ts +208 -42
  71. package/dist/types/src/bin/index.d.ts +7 -1
  72. package/dist/types/src/cli/index.d.ts +13 -0
  73. package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +2 -2
  74. package/dist/types/src/decorators/Decorators.d.ts +26 -3
  75. package/dist/types/src/decorators/field/Encrypted.d.ts +6 -1
  76. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +9 -9
  77. package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +52 -25
  78. package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +4 -4
  79. package/dist/types/src/dream/LoadBuilder.d.ts +1 -1
  80. package/dist/types/src/dream/Query.d.ts +272 -33
  81. package/dist/types/src/dream/QueryDriver/Base.d.ts +63 -1
  82. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +85 -1
  83. package/dist/types/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.d.ts +29 -0
  84. package/dist/types/src/dream-app/index.d.ts +56 -2
  85. package/dist/types/src/encrypt/InternalEncrypt.d.ts +29 -1
  86. package/dist/types/src/encrypt/defaultEncryptedColumnName.d.ts +7 -0
  87. package/dist/types/src/encrypt/index.d.ts +75 -6
  88. package/dist/types/src/errors/associations/UnrecognizedAssociationConditionKeys.d.ts +8 -0
  89. package/dist/types/src/helpers/Env.d.ts +28 -0
  90. package/dist/types/src/package-exports/openapi.d.ts +1 -1
  91. package/dist/types/src/package-exports/types.d.ts +2 -2
  92. package/dist/types/src/serializer/SerializerRenderer.d.ts +13 -0
  93. package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +59 -55
  94. package/dist/types/src/serializer/builders/ObjectSerializerBuilder.d.ts +40 -19
  95. package/dist/types/src/serializer/helpers/serializersForAssociatedClass.d.ts +17 -0
  96. package/dist/types/src/types/lifecycle.d.ts +6 -0
  97. package/dist/types/src/types/openapi.d.ts +52 -29
  98. package/dist/types/src/types/serializer.d.ts +43 -2
  99. package/dist/types/src/types/types/lifecycle.ts +6 -0
  100. package/dist/types/src/types/types/openapi.ts +51 -37
  101. package/dist/types/src/types/types/serializer.ts +62 -2
  102. package/dist/types/src/types/types/variadic.ts +99 -43
  103. package/dist/types/src/types/variadic.d.ts +29 -3
  104. package/docs/assets/hierarchy.js +1 -1
  105. package/docs/assets/highlight.css +4 -11
  106. package/docs/assets/navigation.js +1 -1
  107. package/docs/assets/search.js +1 -1
  108. package/docs/classes/db.DreamMigrationHelpers.html +13 -13
  109. package/docs/classes/db.KyselyQueryDriver.html +85 -46
  110. package/docs/classes/db.PostgresQueryDriver.html +86 -47
  111. package/docs/classes/db.QueryDriverBase.html +84 -45
  112. package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
  113. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  114. package/docs/classes/errors.ColumnOverflow.html +3 -3
  115. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  116. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  117. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  118. package/docs/classes/errors.DecryptionError.html +2 -2
  119. package/docs/classes/errors.DecryptionParseError.html +2 -2
  120. package/docs/classes/errors.DecryptionRotationError.html +3 -3
  121. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  122. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  123. package/docs/classes/errors.InvalidClockTime.html +2 -2
  124. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  125. package/docs/classes/errors.InvalidDateTime.html +2 -2
  126. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  127. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  128. package/docs/classes/errors.NotNullViolation.html +3 -3
  129. package/docs/classes/errors.RecordNotFound.html +3 -3
  130. package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
  131. package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
  132. package/docs/classes/errors.ValidationError.html +3 -3
  133. package/docs/classes/index.CalendarDate.html +33 -33
  134. package/docs/classes/index.ClockTime.html +32 -32
  135. package/docs/classes/index.ClockTimeTz.html +35 -35
  136. package/docs/classes/index.DateTime.html +86 -86
  137. package/docs/classes/index.Decorators.html +37 -23
  138. package/docs/classes/index.Dream.html +270 -142
  139. package/docs/classes/index.DreamApp.html +40 -10
  140. package/docs/classes/index.DreamTransaction.html +3 -3
  141. package/docs/classes/index.Env.html +16 -2
  142. package/docs/classes/index.Query.html +331 -129
  143. package/docs/classes/system.CliFileWriter.html +4 -4
  144. package/docs/classes/system.DreamBin.html +6 -2
  145. package/docs/classes/system.DreamCLI.html +7 -7
  146. package/docs/classes/system.DreamImporter.html +2 -2
  147. package/docs/classes/system.DreamLogos.html +2 -2
  148. package/docs/classes/system.DreamSerializerBuilder.html +52 -34
  149. package/docs/classes/system.ObjectSerializerBuilder.html +41 -22
  150. package/docs/classes/system.PathHelpers.html +4 -4
  151. package/docs/classes/utils.Encrypt.html +54 -10
  152. package/docs/classes/utils.Range.html +2 -2
  153. package/docs/functions/db.closeAllDbConnections.html +1 -1
  154. package/docs/functions/db.dreamDbConnections.html +1 -1
  155. package/docs/functions/db.untypedDb.html +1 -1
  156. package/docs/functions/db.validateColumn.html +1 -1
  157. package/docs/functions/db.validateTable.html +1 -1
  158. package/docs/functions/errors.pgErrorType.html +1 -1
  159. package/docs/functions/index.DreamSerializer.html +1 -1
  160. package/docs/functions/index.ObjectSerializer.html +1 -1
  161. package/docs/functions/index.ReplicaSafe.html +1 -1
  162. package/docs/functions/index.STI.html +1 -1
  163. package/docs/functions/index.SoftDelete.html +1 -1
  164. package/docs/functions/utils.camelize.html +1 -1
  165. package/docs/functions/utils.capitalize.html +1 -1
  166. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  167. package/docs/functions/utils.compact.html +1 -1
  168. package/docs/functions/utils.groupBy.html +1 -1
  169. package/docs/functions/utils.hyphenize.html +1 -1
  170. package/docs/functions/utils.intersection.html +1 -1
  171. package/docs/functions/utils.isEmpty.html +1 -1
  172. package/docs/functions/utils.normalizeUnicode.html +1 -1
  173. package/docs/functions/utils.pascalize.html +1 -1
  174. package/docs/functions/utils.percent.html +1 -1
  175. package/docs/functions/utils.range.html +1 -1
  176. package/docs/functions/utils.round.html +1 -1
  177. package/docs/functions/utils.sanitizeString.html +1 -1
  178. package/docs/functions/utils.snakeify.html +1 -1
  179. package/docs/functions/utils.sort.html +1 -1
  180. package/docs/functions/utils.sortBy.html +1 -1
  181. package/docs/functions/utils.sortObjectByKey.html +1 -1
  182. package/docs/functions/utils.sortObjectByValue.html +1 -1
  183. package/docs/functions/utils.uncapitalize.html +1 -1
  184. package/docs/functions/utils.uniq.html +1 -1
  185. package/docs/hierarchy.html +1 -1
  186. package/docs/index.html +1 -1
  187. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  188. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  189. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  190. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  191. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  192. package/docs/interfaces/types.DecoratorContext.html +2 -2
  193. package/docs/interfaces/types.DecryptCallbacks.html +6 -0
  194. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  195. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  196. package/docs/interfaces/types.DreamDbConfig.html +6 -6
  197. package/docs/interfaces/types.DurationObject.html +2 -2
  198. package/docs/interfaces/types.EncryptOptions.html +2 -2
  199. package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +10 -0
  200. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  201. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  202. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  203. package/docs/modules/openapi.html +1 -1
  204. package/docs/modules/types.html +1 -1
  205. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  206. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  207. package/docs/types/openapi.OpenapiFormats.html +1 -1
  208. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  209. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  210. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  211. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  212. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  213. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  214. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  215. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  216. package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +4 -0
  217. package/docs/types/openapi.OpenapiSchemaCommonFields.html +5 -1
  218. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -2
  219. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -2
  220. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -2
  221. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  222. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  223. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  224. package/docs/types/openapi.OpenapiSchemaNull.html +4 -2
  225. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  226. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  227. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +5 -1
  228. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +2 -1
  229. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  230. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  231. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  232. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  233. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -2
  234. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -2
  235. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -2
  236. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  237. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  238. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  239. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  240. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  241. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  242. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  243. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  244. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  245. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  246. package/docs/types/types.CalendarDateObject.html +1 -1
  247. package/docs/types/types.Camelized.html +1 -1
  248. package/docs/types/types.ClockTimeObject.html +1 -1
  249. package/docs/types/types.DbConnectionType.html +1 -1
  250. package/docs/types/types.DbTypes.html +1 -1
  251. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  252. package/docs/types/types.DreamAttributes.html +1 -1
  253. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  254. package/docs/types/types.DreamClassColumn.html +1 -1
  255. package/docs/types/types.DreamColumn.html +1 -1
  256. package/docs/types/types.DreamColumnNames.html +1 -1
  257. package/docs/types/types.DreamLogLevel.html +1 -1
  258. package/docs/types/types.DreamLogger.html +2 -2
  259. package/docs/types/types.DreamModelSerializerType.html +1 -1
  260. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  261. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  262. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  263. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  264. package/docs/types/types.DreamSerializable.html +1 -1
  265. package/docs/types/types.DreamSerializableArray.html +1 -1
  266. package/docs/types/types.DreamSerializerKey.html +1 -1
  267. package/docs/types/types.DreamSerializers.html +1 -1
  268. package/docs/types/types.DreamVirtualColumns.html +1 -1
  269. package/docs/types/types.DurationUnit.html +1 -1
  270. package/docs/types/types.EncryptAlgorithm.html +1 -1
  271. package/docs/types/types.HasManyStatement.html +1 -1
  272. package/docs/types/types.HasOneStatement.html +1 -1
  273. package/docs/types/types.Hyphenized.html +1 -1
  274. package/docs/types/types.Pascalized.html +1 -1
  275. package/docs/types/types.PrimaryKeyType.html +1 -1
  276. package/docs/types/types.RoundingPrecision.html +1 -1
  277. package/docs/types/types.SerializerCasing.html +1 -1
  278. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  279. package/docs/types/types.Snakeified.html +1 -1
  280. package/docs/types/types.StrictInterface.html +1 -1
  281. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  282. package/docs/types/types.UpdateableProperties.html +1 -1
  283. package/docs/types/types.ValidationType.html +1 -1
  284. package/docs/types/types.ViewModel.html +2 -2
  285. package/docs/types/types.ViewModelClass.html +1 -1
  286. package/docs/types/types.WeekdayName.html +1 -1
  287. package/docs/types/types.WhereStatementForDream.html +1 -1
  288. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  289. package/docs/variables/index.DreamConst.html +1 -1
  290. package/docs/variables/index.ops.html +1 -1
  291. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  292. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  293. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  294. package/docs/variables/system.primaryKeyTypes.html +1 -1
  295. package/package.json +1 -1
  296. package/dist/cjs/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
  297. package/dist/esm/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
  298. package/dist/types/src/serializer/helpers/serializerForAssociatedClass.d.ts +0 -9
  299. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +0 -1
  300. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +0 -1
  301. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +0 -1
  302. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +0 -1
@@ -2,7 +2,7 @@ import { CompiledQuery, DeleteQueryBuilder, SelectQueryBuilder, UpdateQueryBuild
2
2
  import type { DreamDbConfig } from '../../dream-app/index.js';
3
3
  import Dream from '../../Dream.js';
4
4
  import { SchemaBuilderAssociationData, SchemaBuilderColumnData } from '../../helpers/cli/ASTBuilder.js';
5
- import { AssociationStatement } from '../../types/associations/shared.js';
5
+ import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
6
6
  import { DbConnectionType, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
7
7
  import { DreamColumnNames, DreamConstructorType, DreamTableSchema } from '../../types/dream.js';
8
8
  import { PreloadedDreamsAndWhatTheyPointTo, QueryToKyselyDBType, QueryToKyselyTableNamesType } from '../../types/query.js';
@@ -435,6 +435,68 @@ export default class QueryDriverBase<DreamInstance extends Dream> {
435
435
  * @returns An array of plucked values
436
436
  */
437
437
  pluck(...fields: DreamColumnNames<DreamInstance>[]): Promise<any[]>;
438
+ /**
439
+ * @internal
440
+ *
441
+ * The order statements that the declared `order` of the associations the
442
+ * Query is built on or joins contributes to its ORDER BY, in the order they
443
+ * sort, each column namespaced by the alias it is read from. Cursor
444
+ * pagination folds these into its cursor.
445
+ *
446
+ * @returns An array of namespaced order statements
447
+ */
448
+ associationOrderStatements(): OrderQueryStatement<string>[];
449
+ /**
450
+ * @internal
451
+ *
452
+ * The primary key of each table the Query reaches through a HasOne or
453
+ * HasMany association (one it joins, one an association it joins goes
454
+ * through, or one its association query is built on), namespaced by the
455
+ * alias it is read from, in join order. Such a join can return a row of the
456
+ * Query's table once for each row it matches, and these keys, with the
457
+ * Query's own primary key, tell those rows apart. Cursor pagination pages by
458
+ * them after the Query's own primary key.
459
+ *
460
+ * @returns An array of namespaced primary key columns
461
+ */
462
+ joinedRowKeyColumns(): string[];
463
+ /**
464
+ * @internal
465
+ *
466
+ * A page of a select that keeps one row of each group (DISTINCT ON, as a
467
+ * Query that calls `distinct`, or an association that declares `distinct`,
468
+ * produces), or null for any other select, whose pages cursor pagination
469
+ * reads as it reads any select's.
470
+ *
471
+ * The page is the values of the Query's order statement columns for each
472
+ * row the select returns that matches any of `rowsAfter` (every row when it
473
+ * is null), sorted by the Query's order statements and limited by its
474
+ * limit. The select chooses each group's row before `rowsAfter` narrows the
475
+ * rows, so that the page holds only rows the select returns.
476
+ *
477
+ * A driver whose selects never keep one row of each group returns null.
478
+ *
479
+ * @param rowsAfter - where statements, any of which a row of the page matches
480
+ * @returns The page's rows, each an array of its order statement columns' values, or null
481
+ */
482
+ pluckDistinctOnPage(rowsAfter: Record<string, unknown>[] | null): Promise<unknown[][] | null>;
483
+ /**
484
+ * @internal
485
+ *
486
+ * For a select that keeps one row of each group (DISTINCT ON, as a Query
487
+ * that calls `distinct`, or an association that declares `distinct`,
488
+ * produces), the values of `rowKeyColumns` for every row it returns, sorted
489
+ * by those columns, ascending; null for any other select. `findEach` and
490
+ * `pluckEach` read a select that keeps one row of each group from these
491
+ * keys rather than by a cursor, which would narrow the select before it
492
+ * chooses each group's row.
493
+ *
494
+ * A driver whose selects never keep one row of each group returns null.
495
+ *
496
+ * @param rowKeyColumns - the namespaced columns that tell the select's rows apart
497
+ * @returns The rows' values of `rowKeyColumns`, or null
498
+ */
499
+ pluckDistinctOnRowKeys(rowKeyColumns: string[]): Promise<unknown[][] | null>;
438
500
  /**
439
501
  * Returns a new Kysely SelectQueryBuilder instance to be used
440
502
  * in a sub Query
@@ -4,7 +4,7 @@ import { DialectProviderCb } from '../../db/DreamDbConnection.js';
4
4
  import { DreamDbConfig } from '../../dream-app/index.js';
5
5
  import Dream from '../../Dream.js';
6
6
  import { SchemaBuilderInformationSchemaRow } from '../../helpers/cli/ASTBuilder.js';
7
- import { AssociationStatement } from '../../types/associations/shared.js';
7
+ import { AssociationStatement, OrderQueryStatement } from '../../types/associations/shared.js';
8
8
  import { DbConnectionType, LegacyCompatiblePrimaryKeyType } from '../../types/db.js';
9
9
  import { DreamColumnNames, DreamTableSchema, OrderDir, SqlCommandType } from '../../types/dream.js';
10
10
  import { PreloadedDreamsAndWhatTheyPointTo, QueryToKyselyDBType, QueryToKyselyTableNamesType } from '../../types/query.js';
@@ -12,6 +12,21 @@ import DreamTransaction from '../DreamTransaction.js';
12
12
  import Query from '../Query.js';
13
13
  import QueryDriverBase from './Base.js';
14
14
  export default class KyselyQueryDriver<DreamInstance extends Dream> extends QueryDriverBase<DreamInstance> {
15
+ /**
16
+ * @internal
17
+ *
18
+ * While `associationOrderStatements` builds a select, the order statements
19
+ * that association joins add to it, in the order they are added.
20
+ */
21
+ private associationOrderCollector;
22
+ /**
23
+ * @internal
24
+ *
25
+ * While `joinedRowKeyColumns` builds a select, the namespaced primary keys of
26
+ * the tables that HasOne and HasMany joins add to it, in the order they are
27
+ * added.
28
+ */
29
+ private joinedRowKeyCollector;
15
30
  dbFor(sqlCommandType: SqlCommandType): Kysely<DreamInstance['DB']> | KyselyTransaction<DreamInstance['DB']>;
16
31
  static dbFor<I extends Dream>(connectionName: string, dbConnectionType: DbConnectionType, dreamTransaction?: DreamTransaction<I> | null): Kysely<I['DB']> | KyselyTransaction<I['DB']>;
17
32
  static dialectProvider(connectionName: string, dbConnectionType: DbConnectionType): DialectProviderCb;
@@ -400,6 +415,75 @@ export default class KyselyQueryDriver<DreamInstance extends Dream> extends Quer
400
415
  }>;
401
416
  private buildDelete;
402
417
  private buildSelect;
418
+ /**
419
+ * @internal
420
+ *
421
+ * The select's source, joins, conditions, DISTINCT ON and similarity
422
+ * ranking, before the Query's own order statements, limit, offset and
423
+ * selection are applied, together with the connection the select runs on.
424
+ */
425
+ private buildSelectCore;
426
+ /**
427
+ * @internal
428
+ *
429
+ * The order statements that the declared `order` of the associations the
430
+ * Query is built on or joins contributes to its ORDER BY, in the order they
431
+ * sort, each column namespaced by the alias it is read from. They are read
432
+ * off the same join code that emits them, by building the select.
433
+ *
434
+ * @returns An array of namespaced order statements
435
+ */
436
+ associationOrderStatements(): OrderQueryStatement<string>[];
437
+ /**
438
+ * @internal
439
+ *
440
+ * The primary key of each table the Query reaches through a HasOne or
441
+ * HasMany association (one it joins, one an association it joins goes
442
+ * through, or one its association query is built on), namespaced by the
443
+ * alias it is read from, in join order. They are read off the same join code
444
+ * that emits the joins, by building the select.
445
+ *
446
+ * @returns An array of namespaced primary key columns
447
+ */
448
+ joinedRowKeyColumns(): string[];
449
+ /**
450
+ * @internal
451
+ *
452
+ * A page of a select that carries DISTINCT ON (as a Query that calls
453
+ * `distinct`, or an association that declares `distinct`, produces), or null
454
+ * for any other select.
455
+ *
456
+ * Such a select keeps the row of each group that sorts first in its ORDER
457
+ * BY, so narrowing it to the rows after a cursor would let it keep a row it
458
+ * does not return (a group's later row, once the cursor has passed the
459
+ * group's first). It is read as a derived table instead, and narrowed to
460
+ * `rowsAfter`, sorted and limited outside it. The Query's order statements
461
+ * follow the select's own ORDER BY, if it has one, so that the select keeps
462
+ * the same row of each group every time it runs, and each of their columns
463
+ * is read out of it under a short alias (as `pluck` reads them), since a
464
+ * joined table's column cannot be named outside it.
465
+ *
466
+ * @param rowsAfter - where statements, any of which a row of the page matches
467
+ * @returns The page's rows, each an array of its order statement columns' values, or null
468
+ */
469
+ pluckDistinctOnPage(rowsAfter: Record<string, unknown>[] | null): Promise<unknown[][] | null>;
470
+ /**
471
+ * @internal
472
+ *
473
+ * For a select that carries DISTINCT ON (as a Query that calls `distinct`,
474
+ * or an association that declares `distinct`, produces), the values of
475
+ * `rowKeyColumns` for every row it returns, sorted by those columns,
476
+ * ascending; null for any other select.
477
+ *
478
+ * The select runs as `all()` runs it, with its own ORDER BY choosing each
479
+ * group's row, and is read as a derived table, sorted outside it. Each of
480
+ * `rowKeyColumns` is read out of it under a short alias (as `pluck` reads
481
+ * them), since a joined table's column cannot be named outside it.
482
+ *
483
+ * @param rowKeyColumns - the namespaced columns that tell the select's rows apart
484
+ * @returns The rows' values of `rowKeyColumns`, or null
485
+ */
486
+ pluckDistinctOnRowKeys(rowKeyColumns: string[]): Promise<unknown[][] | null>;
403
487
  orderByDirection(direction: OrderDir | null): (obj: OrderByItemBuilder) => OrderByItemBuilder;
404
488
  private buildUpdate;
405
489
  /**
@@ -0,0 +1,29 @@
1
+ /**
2
+ * The keys a condition object on an association accepts, whether it is
3
+ * passed in a chain (`preload('posts', { and: { ... } })`), returned from a
4
+ * `preloadFor`/`loadFor` modifier, or passed to `associationQuery`.
5
+ */
6
+ export declare const ASSOCIATION_CONDITION_KEYS: readonly ["and", "andNot", "andAny"];
7
+ /**
8
+ * The keys accepted by `destroyAssociation`, `reallyDestroyAssociation`
9
+ * and `undestroyAssociation`.
10
+ */
11
+ export declare const DESTROY_ASSOCIATION_OPTION_KEYS: readonly ["and", "andNot", "andAny", "bypassAllDefaultScopes", "defaultScopesToBypass", "cascade", "skipHooks"];
12
+ /**
13
+ * The keys accepted by `updateAssociation`.
14
+ */
15
+ export declare const UPDATE_ASSOCIATION_OPTION_KEYS: readonly ["and", "andNot", "andAny", "bypassAllDefaultScopes", "defaultScopesToBypass", "skipHooks"];
16
+ /**
17
+ * Throws UnrecognizedAssociationConditionKeys when `value` is an object
18
+ * carrying any own key outside `acceptedKeys`, including a key whose value
19
+ * is `undefined`. Dream reads only the accepted keys, so an unrecognized key
20
+ * would otherwise be silently ignored (and, for the destroy family, act on
21
+ * every associated row instead of the ones the caller meant to select).
22
+ * Non-object values (`undefined`, `null`) pass through untouched.
23
+ *
24
+ * @param value - The condition object or options object to check
25
+ * @param acceptedKeys - The keys `value` may carry
26
+ * @param associationName - The association the object applies to, for the error message
27
+ * @param methodName - The public method the options were passed to, or null for a chain condition
28
+ */
29
+ export default function assertRecognizedAssociationConditionKeys(value: unknown, acceptedKeys: readonly string[], associationName: string | number | symbol, methodName?: string | null): void;
@@ -238,9 +238,43 @@ export default class DreamApp {
238
238
  load<RT extends 'models' | 'serializers'>(resourceType: RT, resourcePath: string, importCb: (path: string) => Promise<any>): Promise<void>;
239
239
  plugin(cb: (app: DreamApp) => void | Promise<void>): void;
240
240
  set<ApplyOpt extends DreamAppSetOption>(applyOption: ApplyOpt, options: ApplyOpt extends 'bypassDeprecationChecks' ? boolean : ApplyOpt extends 'db' ? DreamDbCredentialOptions | string : ApplyOpt extends 'encryption' ? DreamAppEncryptionOptions : ApplyOpt extends 'primaryKeyType' ? LegacyCompatiblePrimaryKeyType : ApplyOpt extends 'importExtension' ? GeneratorImportStyle : ApplyOpt extends 'logger' ? DreamLogger : ApplyOpt extends 'projectRoot' ? string : ApplyOpt extends 'inflections' ? () => void | Promise<void> : ApplyOpt extends 'packageManager' ? DreamAppAllowedPackageManagersEnum : ApplyOpt extends 'paths' ? DreamDirectoryPaths : ApplyOpt extends 'parallelTests' ? number : ApplyOpt extends 'unicodeNormalization' ? UnicodeNormalizationForm : ApplyOpt extends 'paginationPageSize' ? number : ApplyOpt extends 'paginationMaxPageSize' ? number : ApplyOpt extends 'sortableScopeLockTimeout' ? number : never, secondaryOptions?: ApplyOpt extends 'db' ? DreamDbCredentialOptions : never): void;
241
- on<T extends DreamHookEventType>(hookEventType: T, cb: T extends 'db:log' ? (event: KyselyLogEvent) => void : T extends 'repl:start' ? (context: Context) => void | Promise<void> : never): void;
241
+ /**
242
+ * Registers a callback for an app-level event. Callbacks for the same
243
+ * event run in the order they were registered.
244
+ *
245
+ * - `'db:log'`: called with a {@link KyselyLogEvent} each time a query on a
246
+ * Dream database connection completes or fails.
247
+ * - `'repl:start'`: called, and awaited, with the console's REPL context
248
+ * when the Dream console starts.
249
+ * - `'encryption:legacy-key-used'`: called with an
250
+ * {@link EncryptionLegacyKeyUsedEvent} when reading an `@deco.Encrypted`
251
+ * property needed the `legacy` column encryption key, not `current`, to
252
+ * open the stored value. Use it during a key rotation to find rows still
253
+ * encrypted with the old key. The property decrypts on every read, so a
254
+ * record whose value is still under the old key fires the event each time
255
+ * the property is read. A row nobody reads never fires it, so a quiet
256
+ * event does not prove that `legacy` is safe to drop;
257
+ * `Model.reencryptEncryptedColumns()` rewrites every row instead. Neither
258
+ * it nor the migration helpers fire the event. The callback runs
259
+ * synchronously inside the property read, and an error it throws
260
+ * propagates from that read. Reading the same property of the same
261
+ * record inside the callback returns its value without firing the event
262
+ * again, so a callback can read the property and assign the value back,
263
+ * which re-encrypts it under `current` for the record's next save. That
264
+ * holds only while the callback runs synchronously: a callback that
265
+ * reads the property after an `await` fires the event again from that
266
+ * read, so an `async` callback should read the property before its
267
+ * first `await`.
268
+ *
269
+ * ```ts
270
+ * dreamApp.on('encryption:legacy-key-used', ({ dream, property }) => {
271
+ * console.warn(`${dream.constructor.name} ${dream.primaryKeyValue()} ${property} still uses the legacy key`)
272
+ * })
273
+ * ```
274
+ */
275
+ on<T extends DreamHookEventType>(hookEventType: T, cb: T extends 'db:log' ? (event: KyselyLogEvent) => void : T extends 'repl:start' ? (context: Context) => void | Promise<void> : T extends 'encryption:legacy-key-used' ? (event: EncryptionLegacyKeyUsedEvent) => void : never): void;
242
276
  }
243
- export type DreamHookEventType = 'db:log' | 'repl:start';
277
+ export type DreamHookEventType = 'db:log' | 'repl:start' | 'encryption:legacy-key-used';
244
278
  export interface DreamAppOpts {
245
279
  projectRoot: string;
246
280
  primaryKeyType: LegacyCompatiblePrimaryKeyType;
@@ -373,6 +407,26 @@ interface SegmentedEncryptionOptions {
373
407
  export interface DreamAppSpecialHooks {
374
408
  dbLog: ((event: KyselyLogEvent) => void)[];
375
409
  replStart: ((context: Context) => void | Promise<void>)[];
410
+ encryptionLegacyKeyUsed: ((event: EncryptionLegacyKeyUsedEvent) => void)[];
411
+ }
412
+ /**
413
+ * Passed to `dreamApp.on('encryption:legacy-key-used', ...)` callbacks.
414
+ */
415
+ export interface EncryptionLegacyKeyUsedEvent {
416
+ /**
417
+ * The record whose `@deco.Encrypted` property was read. Its class and
418
+ * `primaryKeyValue()` identify the row; a record not yet saved has no
419
+ * primary key.
420
+ */
421
+ dream: Dream;
422
+ /**
423
+ * The `@deco.Encrypted` property that was read, e.g. `'phone'`.
424
+ */
425
+ property: string;
426
+ /**
427
+ * The column holding the property's ciphertext, e.g. `'encryptedPhone'`.
428
+ */
429
+ encryptedColumnName: string;
376
430
  }
377
431
  export interface DreamAppInitOptions {
378
432
  bypassDreamIntegrityChecks?: boolean;
@@ -1,6 +1,34 @@
1
+ import { DecryptCallbacks } from './index.js';
1
2
  export default class InternalEncrypt {
2
3
  static encryptColumn(data: any): string | null;
3
- static decryptColumn(data: any): unknown;
4
+ /**
5
+ * Returns `existingCiphertext` when the current column key opens it to a
6
+ * value whose JSON serialization equals `data`'s, the plaintext
7
+ * `encryptColumn(data)` would encrypt, and otherwise `encryptColumn(data)`.
8
+ * A value only the legacy key opens, ciphertext no key opens, and a
9
+ * missing `existingCiphertext` all get fresh ciphertext. It never calls
10
+ * `onLegacyKeyUsed`.
11
+ */
12
+ static reuseOrEncryptColumn(data: any, existingCiphertext: unknown): string | null;
13
+ /**
14
+ * Decrypts `data` with the column keys, current then legacy.
15
+ * `onLegacyKeyUsed` is passed to `Encrypt.decrypt`, so it is called only
16
+ * when the legacy key opened the value.
17
+ */
18
+ static decryptColumn(data: any, callbacks?: DecryptCallbacks): unknown;
19
+ /**
20
+ * Encrypts `data`, a column's ciphertext, again with the current column key
21
+ * (see `Encrypt.reencrypt`), opening it with the current key or, failing
22
+ * that, the legacy one. It does not call `onLegacyKeyUsed`.
23
+ */
24
+ static reencryptColumn(data: any): string | null;
25
+ /**
26
+ * Whether `data` is ciphertext that the column keys (current, then legacy)
27
+ * open to a value `decryptColumn` returns. A missing column encryption
28
+ * config or key still throws, since that is a configuration error rather
29
+ * than a property of `data`.
30
+ */
31
+ static isDecryptableColumnCiphertext(data: string): boolean;
4
32
  private static doEncryption;
5
33
  private static doDecryption;
6
34
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The column that holds an `@deco.Encrypted` property's ciphertext when the
3
+ * decorator is not given one: the property's name, pascalized and prefixed
4
+ * with `encrypted`. `secretPhone`, or `secret_phone`, gives
5
+ * `encryptedSecretPhone`, which is the `encrypted_secret_phone` column.
6
+ */
7
+ export default function defaultEncryptedColumnName(propertyName: string): string;
@@ -19,12 +19,50 @@ export default class Encrypt {
19
19
  *
20
20
  * `MissingEncryptionKey` propagates from either form when a key is missing.
21
21
  *
22
+ * **`onLegacyKeyUsed`** (optional fourth argument): during a key rotation,
23
+ * tells you which values still need the legacy key. It is called with no
24
+ * arguments, synchronously, before a three-arg call returns a value that
25
+ * the legacy key opened. It is not called when the current key opens the
26
+ * value, when decryption throws, or in the two-arg form. An error it
27
+ * throws propagates from `decrypt` as is.
28
+ *
29
+ * ```ts
30
+ * const value = Encrypt.decrypt<string>(
31
+ * encrypted,
32
+ * { algorithm: 'aes-256-gcm', key: newKey },
33
+ * { algorithm: 'aes-256-gcm', key: oldKey },
34
+ * { onLegacyKeyUsed: () => console.warn('this value is still encrypted with the old key') }
35
+ * )
36
+ * ```
37
+ *
38
+ * @throws MissingEncryptionKey
39
+ * @throws DecryptionError
40
+ * @throws DecryptionParseError
41
+ * @throws DecryptionRotationError
42
+ */
43
+ static decrypt<RetType>(encrypted: string, { algorithm, key }: DecryptOptions, legacyOpts?: DecryptOptions, { onLegacyKeyUsed }?: DecryptCallbacks): RetType | null;
44
+ /**
45
+ * Opens `encrypted` as {@link Encrypt.decrypt} does, with `currentOpts` and,
46
+ * when they do not open it, `legacyOpts`, and encrypts the value again with
47
+ * `currentOpts`, so that reading it no longer needs the legacy key. Use it
48
+ * during a key rotation for a value stored outside an `@deco.Encrypted`
49
+ * column, such as a cookie; `Model.reencryptEncryptedColumns()` does this
50
+ * for every value of a model's encrypted properties.
51
+ *
52
+ * ```ts
53
+ * const rewritten = Encrypt.reencrypt(
54
+ * storedValue,
55
+ * { algorithm: 'aes-256-gcm', key: newKey },
56
+ * { algorithm: 'aes-256-gcm', key: oldKey }
57
+ * )
58
+ * ```
59
+ *
22
60
  * @throws MissingEncryptionKey
23
61
  * @throws DecryptionError
24
62
  * @throws DecryptionParseError
25
63
  * @throws DecryptionRotationError
26
64
  */
27
- static decrypt<RetType>(encrypted: string, { algorithm, key }: DecryptOptions, legacyOpts?: DecryptOptions): RetType | null;
65
+ static reencrypt(encrypted: string, currentOpts: EncryptOptions, legacyOpts?: DecryptOptions): string;
28
66
  private static attemptDecryptionWithLegacyKeys;
29
67
  /**
30
68
  * Generates a base64-encoded random key suitable for the given algorithm.
@@ -42,11 +80,26 @@ export default class Encrypt {
42
80
  * to decrypt via `legacy` fallback.
43
81
  * 4. For cookies, wait at least the cookie `maxAge` so all in-flight
44
82
  * cookies have either expired or been re-issued under the new key. For
45
- * `@Encrypted` columns, re-encrypt every existing row under the new
46
- * key (read each row and write it back; the setter re-encrypts with
47
- * `current`).
83
+ * `@Encrypted` columns, re-encrypt every existing row under the new key
84
+ * by calling `reencryptEncryptedColumns()` on each model that has
85
+ * encrypted properties (`await User.reencryptEncryptedColumns()`), in
86
+ * each environment, from a console or a script rather than a migration.
87
+ * Run it only once every server in that environment runs with the new
88
+ * `current`: a server still on the old `current` keeps writing old-key
89
+ * values that its single pass over the table can miss. Writing old-key
90
+ * ciphertext straight into a backing column (`setAttribute`,
91
+ * `setAttributes` or `updateAttributes` given the backing column) after
92
+ * it has run also puts an old-key value back. For any other value
93
+ * encrypted with these keys, {@link Encrypt.reencrypt} rewrites it.
48
94
  * 5. Drop `legacy` from config and deploy again.
49
95
  *
96
+ * To see which values still need the old key while `legacy` is
97
+ * configured, register `dreamApp.on('encryption:legacy-key-used', ...)`,
98
+ * which fires each time reading an `@Encrypted` property needed `legacy`
99
+ * to open the value, or pass `onLegacyKeyUsed` to {@link Encrypt.decrypt}
100
+ * for values you decrypt yourself. A value nobody reads never fires
101
+ * either, so silence alone does not show that `legacy` is safe to drop.
102
+ *
50
103
  * ## When to rotate
51
104
  *
52
105
  * - On a scheduled cadence (90–180 days is a reasonable policy default).
@@ -58,8 +111,15 @@ export default class Encrypt {
58
111
  * - For cookies: at least the cookie `maxAge`, so in-flight sessions are
59
112
  * not forced to re-authenticate.
60
113
  * - For `@Encrypted` columns: until every existing row has been
61
- * re-encrypted under the new key. Dropping `legacy` early will cause
62
- * `DecryptionRotationError` on any not-yet-rewritten row.
114
+ * re-encrypted under the new key. Once `legacy` is dropped, reading the
115
+ * `@Encrypted` property of a row that is still under the old key throws
116
+ * `DecryptionError`, the same error a tampered or corrupted value
117
+ * throws, so the error class alone cannot show that `legacy` was
118
+ * dropped too early. `DecryptionRotationError` is thrown only while
119
+ * `legacy` is configured and neither key opens the value. Neither class
120
+ * extends the other, so code that catches `DecryptionRotationError`
121
+ * during a rotation must also catch `DecryptionError` to handle such a
122
+ * read once `legacy` is dropped.
63
123
  */
64
124
  static generateKey(algorithm: EncryptAlgorithm): string;
65
125
  static validateKey(base64EncodedKey: string, algorithm: EncryptAlgorithm): boolean;
@@ -68,6 +128,15 @@ export interface EncryptOptions extends BaseOptions {
68
128
  }
69
129
  export interface DecryptOptions extends BaseOptions {
70
130
  }
131
+ export interface DecryptCallbacks {
132
+ /**
133
+ * Called with no arguments, synchronously, before a three-arg
134
+ * {@link Encrypt.decrypt} returns a value that the legacy key opened.
135
+ * Never called when the current key opens the value, when decryption
136
+ * throws, or in the two-arg form.
137
+ */
138
+ onLegacyKeyUsed?: () => void;
139
+ }
71
140
  interface BaseOptions {
72
141
  algorithm: EncryptAlgorithm;
73
142
  key: string;
@@ -0,0 +1,8 @@
1
+ export default class UnrecognizedAssociationConditionKeys extends Error {
2
+ private associationName;
3
+ private unrecognizedKeys;
4
+ private acceptedKeys;
5
+ private methodName;
6
+ constructor(associationName: string, unrecognizedKeys: string[], acceptedKeys: readonly string[], methodName: string | null);
7
+ get message(): string;
8
+ }
@@ -18,12 +18,40 @@ export default class Env<T extends {
18
18
  } | undefined, ReturnType extends OptionalConfig extends undefined ? number : OptionalConfig extends {
19
19
  optional: boolean;
20
20
  } ? OptionalConfig['optional'] extends true ? number | undefined : number : number>(env: IntegerEnvs, opts?: OptionalConfig): ReturnType;
21
+ /**
22
+ * Reads a boolean environment variable. Only the exact string `"1"` is
23
+ * true. Every other value is false, including `"true"`, `"TRUE"`, `"yes"`
24
+ * and `""`, and so is an unset variable.
25
+ *
26
+ * ```ts
27
+ * // FEATURE_FLAG=1
28
+ * AppEnv.boolean('FEATURE_FLAG') // true
29
+ *
30
+ * // FEATURE_FLAG=true
31
+ * AppEnv.boolean('FEATURE_FLAG') // false
32
+ * ```
33
+ *
34
+ * @param env - the name of the environment variable
35
+ * @returns `true` when the variable is exactly `"1"`, otherwise `false`
36
+ */
21
37
  boolean(env: BooleanEnvs): boolean;
22
38
  setString(env: StringEnvs, val: string | undefined): void;
23
39
  unsetString(env: StringEnvs): void;
24
40
  setInteger(env: IntegerEnvs, val: number | undefined): void;
25
41
  unsetInteger(env: IntegerEnvs): void;
42
+ /**
43
+ * Sets a boolean environment variable to `"1"`, the only value
44
+ * {@link Env.boolean} reads as true.
45
+ *
46
+ * @param env - the name of the environment variable
47
+ */
26
48
  setBoolean(env: BooleanEnvs): void;
49
+ /**
50
+ * Deletes a boolean environment variable. {@link Env.boolean} reads an
51
+ * unset variable as false, since only the exact string `"1"` is true.
52
+ *
53
+ * @param env - the name of the environment variable
54
+ */
27
55
  unsetBoolean(env: BooleanEnvs): void;
28
56
  protected required(variable: string): string;
29
57
  protected optional(variable: string): string | undefined;
@@ -1,2 +1,2 @@
1
1
  export { openapiPrimitiveTypes, openapiShorthandPrimitiveTypes } from '../dream/constants.js';
2
- export { type CommonOpenapiSchemaObjectFields, type OpenapiAllTypes, type OpenapiDescription, type OpenapiFormats, type OpenapiNumberFormats, type OpenapiPrimitiveBaseTypes, type OpenapiPrimitiveTypes, type OpenapiSchemaArray, type OpenapiSchemaArrayShorthand, type OpenapiSchemaBase, type OpenapiSchemaBody, type OpenapiSchemaBodyShorthand, type OpenapiSchemaCommonFields, type OpenapiSchemaExpressionAllOf, type OpenapiSchemaExpressionAnyOf, type OpenapiSchemaExpressionOneOf, type OpenapiSchemaExpressionRef, type OpenapiSchemaExpressionRefSchemaShorthand, type OpenapiSchemaInteger, type OpenapiSchemaNull, type OpenapiSchemaNumber, type OpenapiSchemaObject, type OpenapiSchemaObjectAllOf, type OpenapiSchemaObjectAllOfShorthand, type OpenapiSchemaObjectAnyOf, type OpenapiSchemaObjectAnyOfShorthand, type OpenapiSchemaObjectBase, type OpenapiSchemaObjectBaseShorthand, type OpenapiSchemaObjectOneOf, type OpenapiSchemaObjectOneOfShorthand, type OpenapiSchemaObjectShorthand, type OpenapiSchemaPrimitiveGeneric, type OpenapiSchemaProperties, type OpenapiSchemaPropertiesShorthand, type OpenapiSchemaShorthandExpressionAllOf, type OpenapiSchemaShorthandExpressionAnyOf, type OpenapiSchemaShorthandExpressionOneOf, type OpenapiSchemaShorthandExpressionSerializableRef, type OpenapiSchemaShorthandExpressionSerializerRef, type OpenapiSchemaShorthandPrimitiveGeneric, type OpenapiSchemaString, type OpenapiShorthandAllTypes, type OpenapiShorthandPrimitiveBaseTypes, type OpenapiShorthandPrimitiveTypes, type OpenapiTypeField, type OpenapiTypeFieldObject, } from '../types/openapi.js';
2
+ export { type CommonOpenapiSchemaObjectFields, type OpenapiAllTypes, type OpenapiDescription, type OpenapiFormats, type OpenapiNumberFormats, type OpenapiPrimitiveBaseTypes, type OpenapiPrimitiveTypes, type OpenapiSchemaArray, type OpenapiSchemaArrayShorthand, type OpenapiSchemaBase, type OpenapiSchemaBody, type OpenapiSchemaBodyShorthand, type OpenapiSchemaCombinatorFields, type OpenapiSchemaCommonFields, type OpenapiSchemaExpressionAllOf, type OpenapiSchemaExpressionAnyOf, type OpenapiSchemaExpressionOneOf, type OpenapiSchemaExpressionRef, type OpenapiSchemaExpressionRefSchemaShorthand, type OpenapiSchemaInteger, type OpenapiSchemaNull, type OpenapiSchemaNumber, type OpenapiSchemaObject, type OpenapiSchemaObjectAllOf, type OpenapiSchemaObjectAllOfShorthand, type OpenapiSchemaObjectBase, type OpenapiSchemaObjectBaseShorthand, type OpenapiSchemaObjectShorthand, type OpenapiSchemaPrimitiveGeneric, type OpenapiSchemaProperties, type OpenapiSchemaPropertiesShorthand, type OpenapiSchemaShorthandExpressionAllOf, type OpenapiSchemaShorthandExpressionAnyOf, type OpenapiSchemaShorthandExpressionOneOf, type OpenapiSchemaShorthandExpressionSerializableRef, type OpenapiSchemaShorthandExpressionSerializerRef, type OpenapiSchemaShorthandPrimitiveGeneric, type OpenapiSchemaString, type OpenapiShorthandAllTypes, type OpenapiShorthandPrimitiveBaseTypes, type OpenapiShorthandPrimitiveTypes, type OpenapiTypeField, type OpenapiTypeFieldObject, } from '../types/openapi.js';
@@ -1,5 +1,5 @@
1
1
  export { type DecoratorContext } from '../decorators/DecoratorContextType.js';
2
- export { type EncryptAlgorithm, type EncryptOptions } from '../encrypt/index.js';
2
+ export { type DecryptCallbacks, type EncryptAlgorithm, type EncryptOptions } from '../encrypt/index.js';
3
3
  export { type RoundingPrecision } from '../helpers/round.js';
4
4
  export { type Camelized, type Hyphenized, type Pascalized, type Snakeified } from '../helpers/stringCasing.js';
5
5
  export { type SerializerRendererOpts } from '../serializer/SerializerRenderer.js';
@@ -14,5 +14,5 @@ export { type DurationObject, type DurationUnit, type WeekdayName } from '../typ
14
14
  export { type DreamAssociationMetadata, type DreamAttributes, type DreamClassAssociationAndStatement, type DreamClassColumn, type DreamColumn, type DreamColumnNames, type DreamOrViewModelClassSerializerKey, type DreamOrViewModelSerializerKey, type DreamParamSafeAttributes, type DreamParamSafeColumnNames, type DreamSerializable, type DreamSerializableArray, type DreamSerializerKey, type DreamSerializers, type DreamVirtualColumns, type UpdateableAssociationProperties, type UpdateableProperties, type ViewModel, type ViewModelClass, } from '../types/dream.js';
15
15
  export { type DreamModelSerializerType, type InternalAnyTypedSerializerRendersMany, type InternalAnyTypedSerializerRendersOne, type SerializerCasing, type SimpleObjectSerializerType, } from '../types/serializer.js';
16
16
  export { type ValidationType } from '../types/validation.js';
17
- export { type DreamAppInitOptions, type DreamAppOpts, type DreamLogger, type DreamLogLevel, type DreamDbConfig, } from '../dream-app/index.js';
17
+ export { type DreamAppInitOptions, type DreamAppOpts, type DreamLogger, type DreamLogLevel, type DreamDbConfig, type EncryptionLegacyKeyUsedEvent, } from '../dream-app/index.js';
18
18
  export { type WhereStatementForDream, type WhereStatementForDreamClass, } from '../types/associations/shared.js';
@@ -10,5 +10,18 @@ export default class SerializerRenderer {
10
10
  private renderOpts;
11
11
  constructor(serializerBuilder: DreamSerializerBuilder<any, any> | ObjectSerializerBuilder<any, any> | null | undefined, passthroughData?: object, { casing }?: SerializerRendererOpts);
12
12
  render(): Record<string, any> | null;
13
+ /**
14
+ * The keys a flattened `rendersOne` adds to the parent's payload when its associated object is
15
+ * null: each key any of `serializers` declares, set to `null`. There are several serializers when
16
+ * the association is a polymorphic BelongsTo, one for each target class, or when the associated
17
+ * class is an STI base, one for each child, and their keys are unioned.
18
+ *
19
+ * Each serializer is built with `undefined` data to read its declarations, as Psychic's OpenAPI
20
+ * generation and `preloadFor` build it, and nothing is rendered: no attribute callback runs and
21
+ * no association of the missing object is read. A flattened `rendersOne` it declares adds its
22
+ * own serializers' keys the same way. A flattened `customAttribute` adds none, since only its
23
+ * callback knows its keys.
24
+ */
25
+ private nullFlattenedAttributes;
13
26
  private setCase;
14
27
  }