@rvoh/dream 2.34.0 → 2.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (302) hide show
  1. package/README.md +2 -2
  2. package/dist/cjs/src/Dream.js +270 -69
  3. package/dist/cjs/src/bin/index.js +13 -0
  4. package/dist/cjs/src/cli/index.js +28 -17
  5. package/dist/cjs/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
  6. package/dist/cjs/src/decorators/Decorators.js +26 -4
  7. package/dist/cjs/src/decorators/field/Encrypted.js +30 -6
  8. package/dist/cjs/src/dream/DreamClassTransactionBuilder.js +6 -6
  9. package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +63 -27
  10. package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +3 -3
  11. package/dist/cjs/src/dream/LoadBuilder.js +1 -1
  12. package/dist/cjs/src/dream/Query.js +542 -167
  13. package/dist/cjs/src/dream/QueryDriver/Base.js +72 -0
  14. package/dist/cjs/src/dream/QueryDriver/Kysely.js +216 -50
  15. package/dist/cjs/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
  16. package/dist/cjs/src/dream/internal/associations/associationQuery.js +4 -0
  17. package/dist/cjs/src/dream/internal/reload.js +6 -1
  18. package/dist/cjs/src/dream/internal/saveDream.js +8 -2
  19. package/dist/cjs/src/dream/internal/sqlResultToDreamInstance.js +2 -0
  20. package/dist/cjs/src/dream/internal/undestroyDream.js +1 -1
  21. package/dist/cjs/src/dream-app/index.js +38 -0
  22. package/dist/cjs/src/encrypt/InternalEncrypt.js +49 -4
  23. package/dist/cjs/src/encrypt/defaultEncryptedColumnName.js +10 -0
  24. package/dist/cjs/src/encrypt/index.js +76 -9
  25. package/dist/cjs/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
  26. package/dist/cjs/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
  27. package/dist/cjs/src/helpers/Env.js +28 -0
  28. package/dist/cjs/src/helpers/cli/generateDreamContent.js +2 -1
  29. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +1 -1
  30. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +9 -9
  31. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +21 -8
  32. package/dist/cjs/src/serializer/SerializerRenderer.js +65 -13
  33. package/dist/cjs/src/serializer/builders/DreamSerializerBuilder.js +54 -38
  34. package/dist/cjs/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
  35. package/dist/cjs/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
  36. package/dist/esm/src/Dream.js +270 -69
  37. package/dist/esm/src/bin/index.js +13 -0
  38. package/dist/esm/src/cli/index.js +28 -17
  39. package/dist/esm/src/db/migration-helpers/DreamMigrationHelpers.js +23 -21
  40. package/dist/esm/src/decorators/Decorators.js +26 -4
  41. package/dist/esm/src/decorators/field/Encrypted.js +30 -6
  42. package/dist/esm/src/dream/DreamClassTransactionBuilder.js +6 -6
  43. package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +63 -27
  44. package/dist/esm/src/dream/LeftJoinLoadBuilder.js +3 -3
  45. package/dist/esm/src/dream/LoadBuilder.js +1 -1
  46. package/dist/esm/src/dream/Query.js +542 -167
  47. package/dist/esm/src/dream/QueryDriver/Base.js +72 -0
  48. package/dist/esm/src/dream/QueryDriver/Kysely.js +216 -50
  49. package/dist/esm/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.js +48 -0
  50. package/dist/esm/src/dream/internal/associations/associationQuery.js +4 -0
  51. package/dist/esm/src/dream/internal/reload.js +6 -1
  52. package/dist/esm/src/dream/internal/saveDream.js +8 -2
  53. package/dist/esm/src/dream/internal/sqlResultToDreamInstance.js +2 -0
  54. package/dist/esm/src/dream/internal/undestroyDream.js +1 -1
  55. package/dist/esm/src/dream-app/index.js +38 -0
  56. package/dist/esm/src/encrypt/InternalEncrypt.js +49 -4
  57. package/dist/esm/src/encrypt/defaultEncryptedColumnName.js +10 -0
  58. package/dist/esm/src/encrypt/index.js +76 -9
  59. package/dist/esm/src/errors/DoNotSetEncryptedFieldsDirectly.js +4 -0
  60. package/dist/esm/src/errors/associations/UnrecognizedAssociationConditionKeys.js +25 -0
  61. package/dist/esm/src/helpers/Env.js +28 -0
  62. package/dist/esm/src/helpers/cli/generateDreamContent.js +2 -1
  63. package/dist/esm/src/helpers/cli/generateFactoryContent.js +1 -1
  64. package/dist/esm/src/helpers/cli/generateMigrationContent.js +9 -9
  65. package/dist/esm/src/helpers/cli/generateSerializerContent.js +21 -8
  66. package/dist/esm/src/serializer/SerializerRenderer.js +65 -13
  67. package/dist/esm/src/serializer/builders/DreamSerializerBuilder.js +54 -38
  68. package/dist/esm/src/serializer/builders/ObjectSerializerBuilder.js +34 -14
  69. package/dist/esm/src/serializer/helpers/serializersForAssociatedClass.js +43 -0
  70. package/dist/types/src/Dream.d.ts +217 -55
  71. package/dist/types/src/bin/index.d.ts +7 -1
  72. package/dist/types/src/cli/index.d.ts +13 -0
  73. package/dist/types/src/db/migration-helpers/DreamMigrationHelpers.d.ts +2 -2
  74. package/dist/types/src/decorators/Decorators.d.ts +26 -3
  75. package/dist/types/src/decorators/field/Encrypted.d.ts +6 -1
  76. package/dist/types/src/dream/DreamClassTransactionBuilder.d.ts +9 -9
  77. package/dist/types/src/dream/DreamInstanceTransactionBuilder.d.ts +52 -25
  78. package/dist/types/src/dream/LeftJoinLoadBuilder.d.ts +4 -4
  79. package/dist/types/src/dream/LoadBuilder.d.ts +1 -1
  80. package/dist/types/src/dream/Query.d.ts +272 -33
  81. package/dist/types/src/dream/QueryDriver/Base.d.ts +63 -1
  82. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +85 -1
  83. package/dist/types/src/dream/internal/associations/assertRecognizedAssociationConditionKeys.d.ts +29 -0
  84. package/dist/types/src/dream-app/index.d.ts +56 -2
  85. package/dist/types/src/encrypt/InternalEncrypt.d.ts +20 -1
  86. package/dist/types/src/encrypt/defaultEncryptedColumnName.d.ts +7 -0
  87. package/dist/types/src/encrypt/index.d.ts +75 -6
  88. package/dist/types/src/errors/associations/UnrecognizedAssociationConditionKeys.d.ts +8 -0
  89. package/dist/types/src/helpers/Env.d.ts +28 -0
  90. package/dist/types/src/package-exports/openapi.d.ts +1 -1
  91. package/dist/types/src/package-exports/types.d.ts +2 -2
  92. package/dist/types/src/serializer/SerializerRenderer.d.ts +13 -0
  93. package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +59 -55
  94. package/dist/types/src/serializer/builders/ObjectSerializerBuilder.d.ts +40 -19
  95. package/dist/types/src/serializer/helpers/serializersForAssociatedClass.d.ts +17 -0
  96. package/dist/types/src/types/lifecycle.d.ts +6 -0
  97. package/dist/types/src/types/openapi.d.ts +52 -29
  98. package/dist/types/src/types/serializer.d.ts +43 -2
  99. package/dist/types/src/types/types/lifecycle.ts +6 -0
  100. package/dist/types/src/types/types/openapi.ts +51 -37
  101. package/dist/types/src/types/types/serializer.ts +62 -2
  102. package/dist/types/src/types/types/variadic.ts +99 -43
  103. package/dist/types/src/types/variadic.d.ts +29 -3
  104. package/docs/assets/hierarchy.js +1 -1
  105. package/docs/assets/highlight.css +4 -11
  106. package/docs/assets/navigation.js +1 -1
  107. package/docs/assets/search.js +1 -1
  108. package/docs/classes/db.DreamMigrationHelpers.html +13 -13
  109. package/docs/classes/db.KyselyQueryDriver.html +85 -46
  110. package/docs/classes/db.PostgresQueryDriver.html +86 -47
  111. package/docs/classes/db.QueryDriverBase.html +84 -45
  112. package/docs/classes/errors.CannotSaveMissingDream.html +2 -2
  113. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  114. package/docs/classes/errors.ColumnOverflow.html +3 -3
  115. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  116. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  117. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  118. package/docs/classes/errors.DecryptionError.html +2 -2
  119. package/docs/classes/errors.DecryptionParseError.html +2 -2
  120. package/docs/classes/errors.DecryptionRotationError.html +3 -3
  121. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  122. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  123. package/docs/classes/errors.InvalidClockTime.html +2 -2
  124. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  125. package/docs/classes/errors.InvalidDateTime.html +2 -2
  126. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  127. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  128. package/docs/classes/errors.NotNullViolation.html +3 -3
  129. package/docs/classes/errors.RecordNotFound.html +3 -3
  130. package/docs/classes/errors.SortableScopeDidNotStabilize.html +3 -3
  131. package/docs/classes/errors.SortableScopeLockWaitTimedOut.html +3 -3
  132. package/docs/classes/errors.ValidationError.html +3 -3
  133. package/docs/classes/index.CalendarDate.html +33 -33
  134. package/docs/classes/index.ClockTime.html +32 -32
  135. package/docs/classes/index.ClockTimeTz.html +35 -35
  136. package/docs/classes/index.DateTime.html +86 -86
  137. package/docs/classes/index.Decorators.html +37 -23
  138. package/docs/classes/index.Dream.html +281 -155
  139. package/docs/classes/index.DreamApp.html +40 -10
  140. package/docs/classes/index.DreamTransaction.html +3 -3
  141. package/docs/classes/index.Env.html +16 -2
  142. package/docs/classes/index.Query.html +331 -129
  143. package/docs/classes/system.CliFileWriter.html +4 -4
  144. package/docs/classes/system.DreamBin.html +6 -2
  145. package/docs/classes/system.DreamCLI.html +7 -7
  146. package/docs/classes/system.DreamImporter.html +2 -2
  147. package/docs/classes/system.DreamLogos.html +2 -2
  148. package/docs/classes/system.DreamSerializerBuilder.html +52 -34
  149. package/docs/classes/system.ObjectSerializerBuilder.html +41 -22
  150. package/docs/classes/system.PathHelpers.html +4 -4
  151. package/docs/classes/utils.Encrypt.html +54 -10
  152. package/docs/classes/utils.Range.html +2 -2
  153. package/docs/functions/db.closeAllDbConnections.html +1 -1
  154. package/docs/functions/db.dreamDbConnections.html +1 -1
  155. package/docs/functions/db.untypedDb.html +1 -1
  156. package/docs/functions/db.validateColumn.html +1 -1
  157. package/docs/functions/db.validateTable.html +1 -1
  158. package/docs/functions/errors.pgErrorType.html +1 -1
  159. package/docs/functions/index.DreamSerializer.html +1 -1
  160. package/docs/functions/index.ObjectSerializer.html +1 -1
  161. package/docs/functions/index.ReplicaSafe.html +1 -1
  162. package/docs/functions/index.STI.html +1 -1
  163. package/docs/functions/index.SoftDelete.html +1 -1
  164. package/docs/functions/utils.camelize.html +1 -1
  165. package/docs/functions/utils.capitalize.html +1 -1
  166. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  167. package/docs/functions/utils.compact.html +1 -1
  168. package/docs/functions/utils.groupBy.html +1 -1
  169. package/docs/functions/utils.hyphenize.html +1 -1
  170. package/docs/functions/utils.intersection.html +1 -1
  171. package/docs/functions/utils.isEmpty.html +1 -1
  172. package/docs/functions/utils.normalizeUnicode.html +1 -1
  173. package/docs/functions/utils.pascalize.html +1 -1
  174. package/docs/functions/utils.percent.html +1 -1
  175. package/docs/functions/utils.range.html +1 -1
  176. package/docs/functions/utils.round.html +1 -1
  177. package/docs/functions/utils.sanitizeString.html +1 -1
  178. package/docs/functions/utils.snakeify.html +1 -1
  179. package/docs/functions/utils.sort.html +1 -1
  180. package/docs/functions/utils.sortBy.html +1 -1
  181. package/docs/functions/utils.sortObjectByKey.html +1 -1
  182. package/docs/functions/utils.sortObjectByValue.html +1 -1
  183. package/docs/functions/utils.uncapitalize.html +1 -1
  184. package/docs/functions/utils.uniq.html +1 -1
  185. package/docs/hierarchy.html +1 -1
  186. package/docs/index.html +1 -1
  187. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  188. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  189. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  190. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  191. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  192. package/docs/interfaces/types.DecoratorContext.html +2 -2
  193. package/docs/interfaces/types.DecryptCallbacks.html +6 -0
  194. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  195. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  196. package/docs/interfaces/types.DreamDbConfig.html +6 -6
  197. package/docs/interfaces/types.DurationObject.html +2 -2
  198. package/docs/interfaces/types.EncryptOptions.html +2 -2
  199. package/docs/interfaces/types.EncryptionLegacyKeyUsedEvent.html +10 -0
  200. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  201. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  202. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  203. package/docs/modules/openapi.html +1 -1
  204. package/docs/modules/types.html +1 -1
  205. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  206. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  207. package/docs/types/openapi.OpenapiFormats.html +1 -1
  208. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  209. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  210. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  211. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  212. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  213. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  214. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  215. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  216. package/docs/types/openapi.OpenapiSchemaCombinatorFields.html +4 -0
  217. package/docs/types/openapi.OpenapiSchemaCommonFields.html +5 -1
  218. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +1 -2
  219. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +1 -2
  220. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +1 -2
  221. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  222. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  223. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  224. package/docs/types/openapi.OpenapiSchemaNull.html +4 -2
  225. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  226. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  227. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +5 -1
  228. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +2 -1
  229. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  230. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  231. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  232. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  233. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +1 -2
  234. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +1 -2
  235. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +1 -2
  236. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  237. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  238. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  239. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  240. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  241. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  242. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  243. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  244. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  245. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  246. package/docs/types/types.CalendarDateObject.html +1 -1
  247. package/docs/types/types.Camelized.html +1 -1
  248. package/docs/types/types.ClockTimeObject.html +1 -1
  249. package/docs/types/types.DbConnectionType.html +1 -1
  250. package/docs/types/types.DbTypes.html +1 -1
  251. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  252. package/docs/types/types.DreamAttributes.html +1 -1
  253. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  254. package/docs/types/types.DreamClassColumn.html +1 -1
  255. package/docs/types/types.DreamColumn.html +1 -1
  256. package/docs/types/types.DreamColumnNames.html +1 -1
  257. package/docs/types/types.DreamLogLevel.html +1 -1
  258. package/docs/types/types.DreamLogger.html +2 -2
  259. package/docs/types/types.DreamModelSerializerType.html +1 -1
  260. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  261. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  262. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  263. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  264. package/docs/types/types.DreamSerializable.html +1 -1
  265. package/docs/types/types.DreamSerializableArray.html +1 -1
  266. package/docs/types/types.DreamSerializerKey.html +1 -1
  267. package/docs/types/types.DreamSerializers.html +1 -1
  268. package/docs/types/types.DreamVirtualColumns.html +1 -1
  269. package/docs/types/types.DurationUnit.html +1 -1
  270. package/docs/types/types.EncryptAlgorithm.html +1 -1
  271. package/docs/types/types.HasManyStatement.html +1 -1
  272. package/docs/types/types.HasOneStatement.html +1 -1
  273. package/docs/types/types.Hyphenized.html +1 -1
  274. package/docs/types/types.Pascalized.html +1 -1
  275. package/docs/types/types.PrimaryKeyType.html +1 -1
  276. package/docs/types/types.RoundingPrecision.html +1 -1
  277. package/docs/types/types.SerializerCasing.html +1 -1
  278. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  279. package/docs/types/types.Snakeified.html +1 -1
  280. package/docs/types/types.StrictInterface.html +1 -1
  281. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  282. package/docs/types/types.UpdateableProperties.html +1 -1
  283. package/docs/types/types.ValidationType.html +1 -1
  284. package/docs/types/types.ViewModel.html +2 -2
  285. package/docs/types/types.ViewModelClass.html +1 -1
  286. package/docs/types/types.WeekdayName.html +1 -1
  287. package/docs/types/types.WhereStatementForDream.html +1 -1
  288. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  289. package/docs/variables/index.DreamConst.html +1 -1
  290. package/docs/variables/index.ops.html +1 -1
  291. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  292. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  293. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  294. package/docs/variables/system.primaryKeyTypes.html +1 -1
  295. package/package.json +1 -1
  296. package/dist/cjs/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
  297. package/dist/esm/src/serializer/helpers/serializerForAssociatedClass.js +0 -37
  298. package/dist/types/src/serializer/helpers/serializerForAssociatedClass.d.ts +0 -9
  299. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +0 -1
  300. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +0 -1
  301. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +0 -1
  302. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +0 -1
@@ -1,6 +1,6 @@
1
1
  import Dream from '../../Dream.js';
2
2
  import { DreamOrViewModelSerializerKey, ViewModel, ViewModelClass } from '../../types/dream.js';
3
- import { InternalAnyTypedSerializerAttribute, InternalAnyTypedSerializerCustomAttribute, InternalAnyTypedSerializerDelegatedAttribute, InternalAnyTypedSerializerRendersMany, InternalAnyTypedSerializerRendersOne, NonAutomaticSerializerAttributeOptions, NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption, SerializerType } from '../../types/serializer.js';
3
+ import { CustomAttributeOptions, InternalAnyTypedSerializerAttribute, InternalAnyTypedSerializerCustomAttribute, InternalAnyTypedSerializerDelegatedAttribute, InternalAnyTypedSerializerRendersMany, InternalAnyTypedSerializerRendersOne, NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption, SerializerType } from '../../types/serializer.js';
4
4
  import { SerializerRendererOpts } from '../SerializerRenderer.js';
5
5
  import { DreamPropertiesToExclude } from './DreamSerializerBuilder.js';
6
6
  export default class ObjectSerializerBuilder<MaybeNullDataType extends object | null, PassthroughDataType, DataType extends Exclude<MaybeNullDataType, null> = Exclude<MaybeNullDataType, null>> {
@@ -86,9 +86,10 @@ export default class ObjectSerializerBuilder<MaybeNullDataType extends object |
86
86
  * (e.g., delegating `'profile', 'avatarUrl'` with `as: 'avatar'` outputs the value
87
87
  * under `avatar`)
88
88
  * - `default` - Value to use when the target object or its attribute is null/undefined
89
- * - `optional` - Set to `true` to mark the value as nullable in the OpenAPI schema
90
- * (wraps the type in `anyOf: [schema, { type: 'null' }]`). OpenAPI-only — the
91
- * key is still rendered (as `null`)
89
+ * - `optional` - Set to `true` to mark the value as nullable in the OpenAPI schema:
90
+ * Psychic adds `null` to the rendered schema (e.g., `type: 'string'` becomes
91
+ * `type: ['string', 'null']`, and a `$ref` becomes `anyOf: [{ $ref }, { type: 'null' }]`).
92
+ * OpenAPI-only — the key is still rendered (as `null`)
92
93
  * - `precision` - Round decimal values to the specified number of decimal places (0–9)
93
94
  * during rendering; does not affect the OpenAPI shape
94
95
  * - `required` - Set to `false` to omit the key from the rendered output when the
@@ -125,17 +126,23 @@ export default class ObjectSerializerBuilder<MaybeNullDataType extends object |
125
126
  * Executes a callback function to generate a custom attribute value.
126
127
  * The `openapi` option is always required since the return type cannot be inferred.
127
128
  *
128
- * Unlike DreamSerializerBuilder's `customAttribute`, this version does not support `as`
129
- * or `precision`.
129
+ * The callback's return value renders as is, so any fallback belongs in the callback.
130
130
  *
131
131
  * @param name - The attribute name for the computed value
132
132
  * @param fn - Callback function that returns the computed value
133
133
  * @param options - Configuration options:
134
134
  * - `openapi` - (required) OpenAPI schema definition for the computed value
135
- * - `default` - Value to use when the callback returns undefined
136
135
  * - `flatten` - When `true`, spreads the returned object's properties directly into the
137
- * parent serialized output instead of nesting them under `name`; the `openapi` option
138
- * should then define each flattened property individually
136
+ * parent serialized output instead of nesting them under `name`. The `openapi` option
137
+ * then describes the whole returned object, not each property, because Psychic adds it
138
+ * to the parent's schema as an `allOf` branch: either an object schema with full
139
+ * property bodies (`type: 'object'`, `properties`, and `required` listing the keys that
140
+ * are always present), or `{ $serializer: SomeSerializer }` when the callback returns
141
+ * what that serializer renders. A serializer ref with `many: true` does not type-check
142
+ * here, since a list has no properties to spread. A `null` or `undefined` return adds no
143
+ * keys. Attributes render in declaration order, so a key the returned object shares with
144
+ * another attribute takes the value of whichever is declared later; under the `allOf`,
145
+ * that value must match both schemas
139
146
  * - `required` - Set to `false` to mark the attribute as optional in the OpenAPI schema;
140
147
  * when omitted, attributes are required by default
141
148
  * @returns The serializer builder for method chaining
@@ -148,19 +155,21 @@ export default class ObjectSerializerBuilder<MaybeNullDataType extends object |
148
155
  * { openapi: { type: 'string' } }
149
156
  * )
150
157
  *
151
- * // Flattened object properties
158
+ * // Flattened object properties: `openapi` describes the whole returned object
152
159
  * .customAttribute('coordinates', () => ({ lat: 40.7, lng: -74.0 }), {
153
160
  * flatten: true,
154
161
  * openapi: {
155
- * lat: { type: 'number' },
156
- * lng: { type: 'number' }
162
+ * type: 'object',
163
+ * required: ['lat', 'lng'],
164
+ * properties: {
165
+ * lat: { type: 'number' },
166
+ * lng: { type: 'number' }
167
+ * }
157
168
  * }
158
169
  * })
159
170
  * ```
160
171
  */
161
- customAttribute(name: string, fn: () => unknown, options: Omit<NonAutomaticSerializerAttributeOptions, 'as'> & {
162
- flatten?: boolean;
163
- }): this;
172
+ customAttribute(name: string, fn: () => unknown, options: CustomAttributeOptions): this;
164
173
  /**
165
174
  * Includes a single associated object in the serialized output.
166
175
  *
@@ -171,9 +180,18 @@ export default class ObjectSerializerBuilder<MaybeNullDataType extends object |
171
180
  * @param options - Configuration options:
172
181
  * - `as` - Rename the association key in the serialized output
173
182
  * - `flatten` - When `true`, spreads the rendered association's attributes directly into
174
- * the parent serialized output instead of nesting them under `name`. Be aware of
175
- * attribute shadowing: if the parent and flattened association share attribute names
176
- * (e.g., `id`), the flattened association's values overwrite the parent's
183
+ * the parent serialized output instead of nesting them under `name`. Attributes render in
184
+ * declaration order, so when the parent and the association share a key (e.g., `id`),
185
+ * whichever is declared later wins: the association's value replaces an attribute declared
186
+ * before the `rendersOne`, and an attribute declared after it replaces the association's.
187
+ * When the association is `null`, every key its serializer declares renders as `null`
188
+ * (for a polymorphic `BelongsTo`, every key the serializer of any of its target classes
189
+ * declares, and for an association to an STI base, every key the serializer of any of its
190
+ * STI children declares), in the same order (so an `id` declared before the `rendersOne` becomes
191
+ * `null`); nothing in that serializer is rendered, so its custom attribute callbacks do
192
+ * not run, and a flattened `customAttribute` in it adds no keys. Psychic adds the association's OpenAPI
193
+ * schema to the parent's as an `allOf` branch, so a shared key's value must match both
194
+ * schemas, whichever declaration wins
177
195
  * - `optional` - When `true`, allows the association to be null/missing without causing
178
196
  * an `OpenapiResponseValidationFailure` during Psychic controller unit specs. By default,
179
197
  * `rendersOne` expects the association to be present (mirroring the `optional` option on
@@ -229,7 +247,10 @@ export default class ObjectSerializerBuilder<MaybeNullDataType extends object |
229
247
  as?: string;
230
248
  /**
231
249
  * If `true`, the rendered association's attributes are merged directly into
232
- * the parent object instead of being nested under the association key.
250
+ * the parent object instead of being nested under the association key. A key
251
+ * the parent shares with the association takes the value of whichever is
252
+ * declared later, and when the association is `null`, every key its serializer
253
+ * declares renders as `null`. See the `flatten` option of `rendersOne`.
233
254
  */
234
255
  flatten?: boolean;
235
256
  /**
@@ -0,0 +1,17 @@
1
+ import Dream from '../../Dream.js';
2
+ import { DreamModelSerializerType, InternalAnyRendersOneOrManyOpts, SimpleObjectSerializerType } from '../../types/serializer.js';
3
+ /**
4
+ * Only used when flatten: true, and the associated object is null, in which case there is no
5
+ * object to resolve a serializer from, but the renderer still needs the serializers whose keys it
6
+ * renders as null in the parent's payload.
7
+ *
8
+ * Resolves, in order, to the `serializer` option, the serializers of the `dreamClass` or
9
+ * `viewModelClass` option, or the serializers of each class `parentClass` declares the association
10
+ * to: the one class of most associations, or every target class of a polymorphic BelongsTo. A
11
+ * class that is an STI base contributes the serializer of every one of its children, since the
12
+ * association renders with whichever child it holds when present. The renderer renders the union
13
+ * of all their keys, each key once. Returns no serializers when none applies, e.g. a
14
+ * non-association property without a `serializer` option, so the flattened association adds no
15
+ * keys.
16
+ */
17
+ export declare function serializersForAssociatedClass(parentClass: typeof Dream | null, associationName: string, options: InternalAnyRendersOneOrManyOpts): (DreamModelSerializerType | SimpleObjectSerializerType)[];
@@ -55,6 +55,12 @@ export interface AfterHookOpts<T extends Dream | null = null> {
55
55
  * Only run this hook if one of the specified columns was changed in the
56
56
  * most recent save operation.
57
57
  *
58
+ * On a create, a column counts when, just before the insert, it holds a
59
+ * value other than `undefined` (for an instance from `dup`, other than the
60
+ * copied value), whether the caller or a before hook assigned it; values
61
+ * the insert fills in, such as the primary key, timestamps, database
62
+ * defaults and `null` for a column nobody assigned, do not count.
63
+ *
58
64
  * ```ts
59
65
  * @deco.AfterUpdate({ ifChanged: ['email'] })
60
66
  * public sendEmailVerification() { ... }
@@ -5,15 +5,15 @@ import { DreamModelSerializerType, SimpleObjectSerializerType } from './serializ
5
5
  export type OpenapiSchemaBody = OpenapiSchemaBase | OpenapiSchemaPrimitiveGeneric | OpenapiSchemaExpressionAnyOf | OpenapiSchemaExpressionOneOf | OpenapiSchemaExpressionAllOf | OpenapiSchemaObject | OpenapiSchemaArray;
6
6
  export type OpenapiSchemaBodyShorthand = OpenapiSchemaBase | OpenapiSchemaShorthandPrimitiveGeneric | OpenapiSchemaShorthandExpressionAnyOf | OpenapiSchemaShorthandExpressionOneOf | OpenapiSchemaShorthandExpressionAllOf | OpenapiSchemaObjectShorthand | OpenapiSchemaArrayShorthand | OpenapiSchemaNull | OpenapiSchemaExpressionRefSchemaShorthand | OpenapiSchemaShorthandExpressionSerializerRef | OpenapiSchemaShorthandExpressionSerializableRef;
7
7
  export type OpenapiSchemaBase = OpenapiSchemaString | OpenapiSchemaInteger | OpenapiSchemaNumber | OpenapiSchemaNull | OpenapiSchemaExpressionRef;
8
- export type OpenapiSchemaShorthandExpressionAnyOf = {
8
+ export type OpenapiSchemaShorthandExpressionAnyOf = OpenapiSchemaCombinatorFields<{
9
9
  anyOf: OpenapiSchemaBodyShorthand[];
10
- };
11
- export type OpenapiSchemaShorthandExpressionOneOf = {
10
+ }>;
11
+ export type OpenapiSchemaShorthandExpressionOneOf = OpenapiSchemaCombinatorFields<{
12
12
  oneOf: OpenapiSchemaBodyShorthand[];
13
- };
14
- export type OpenapiSchemaShorthandExpressionAllOf = {
13
+ }>;
14
+ export type OpenapiSchemaShorthandExpressionAllOf = OpenapiSchemaCombinatorFields<{
15
15
  allOf: OpenapiSchemaBodyShorthand[];
16
- };
16
+ }>;
17
17
  export type OpenapiSchemaShorthandExpressionSerializerRef = {
18
18
  $serializer: DreamModelSerializerType | SimpleObjectSerializerType;
19
19
  many?: boolean;
@@ -32,18 +32,36 @@ export type OpenapiSchemaExpressionRef = {
32
32
  export type OpenapiSchemaExpressionRefSchemaShorthand = {
33
33
  $schema: string;
34
34
  };
35
- export type OpenapiSchemaExpressionAllOf = {
35
+ export type OpenapiSchemaExpressionAllOf = OpenapiSchemaCombinatorFields<{
36
36
  allOf: OpenapiSchemaBody[];
37
- };
38
- export type OpenapiSchemaExpressionAnyOf = {
37
+ }>;
38
+ export type OpenapiSchemaExpressionAnyOf = OpenapiSchemaCombinatorFields<{
39
39
  anyOf: OpenapiSchemaBody[];
40
- };
41
- export type OpenapiSchemaExpressionOneOf = {
40
+ }>;
41
+ export type OpenapiSchemaExpressionOneOf = OpenapiSchemaCombinatorFields<{
42
42
  oneOf: OpenapiSchemaBody[];
43
- };
43
+ }>;
44
+ /**
45
+ * The fields of a schema that declares a `type`. `anyOf` and `oneOf` are not
46
+ * among them: they apply to every value, `null` included, so a nullable `type`
47
+ * beside one cannot admit `null`. A schema that may be null lists a
48
+ * `{ type: 'null' }` branch in its `anyOf` or `oneOf` instead.
49
+ */
44
50
  export type OpenapiSchemaCommonFields<T> = T & {
45
51
  description?: string;
46
52
  summary?: string;
53
+ anyOf?: never;
54
+ oneOf?: never;
55
+ };
56
+ /**
57
+ * The fields of a schema that is an `allOf`, `anyOf` or `oneOf`: the
58
+ * combinator and the fields that describe it, but no `type` (see
59
+ * `OpenapiSchemaCommonFields`).
60
+ */
61
+ export type OpenapiSchemaCombinatorFields<T> = T & {
62
+ description?: string;
63
+ summary?: string;
64
+ type?: never;
47
65
  };
48
66
  export type OpenapiSchemaString = OpenapiSchemaCommonFields<{
49
67
  type: 'string' | ['string', 'null'] | ['null', 'string'];
@@ -67,38 +85,43 @@ export type OpenapiSchemaNumber = OpenapiSchemaCommonFields<{
67
85
  }>;
68
86
  export type OpenapiSchemaNull = {
69
87
  type: 'null';
88
+ anyOf?: never;
89
+ oneOf?: never;
70
90
  };
71
91
  export type OpenapiNumberFormats = 'decimal' | 'double';
72
- export type OpenapiSchemaObject = OpenapiSchemaObjectBase | OpenapiSchemaObjectOneOf | OpenapiSchemaObjectAnyOf | OpenapiSchemaObjectAllOf;
92
+ export type OpenapiSchemaObject = OpenapiSchemaObjectBase | OpenapiSchemaObjectAllOf;
73
93
  export type OpenapiSchemaObjectBase = CommonOpenapiSchemaObjectFields<{
74
94
  minProperties?: number;
75
95
  maxProperties?: number;
76
96
  properties?: OpenapiSchemaProperties | OpenapiSchemaExpressionOneOf | OpenapiSchemaExpressionAnyOf | OpenapiSchemaExpressionAllOf;
77
97
  additionalProperties?: OpenapiSchemaObject | OpenapiSchemaExpressionOneOf | OpenapiSchemaExpressionAnyOf | OpenapiSchemaExpressionAllOf | false;
78
- }>;
79
- export type OpenapiSchemaObjectOneOf = CommonOpenapiSchemaObjectFields<{
80
- oneOf?: OpenapiSchemaBody[];
81
- }>;
82
- export type OpenapiSchemaObjectAnyOf = CommonOpenapiSchemaObjectFields<{
83
- anyOf?: OpenapiSchemaBody[];
84
- }>;
85
- export type OpenapiSchemaObjectAllOf = CommonOpenapiSchemaObjectFields<{
98
+ allOf?: never;
99
+ }>;
100
+ /**
101
+ * An object schema that is also an `allOf`. Its `type` cannot be nullable:
102
+ * `allOf` applies to every value, so `null` would have to match each of its
103
+ * object members. A schema that may be null is an `anyOf` or `oneOf` with a
104
+ * `{ type: 'null' }` branch.
105
+ */
106
+ export type OpenapiSchemaObjectAllOf = OpenapiSchemaCommonFields<{
107
+ type: 'object';
108
+ required?: string[];
86
109
  allOf?: OpenapiSchemaBody[];
87
110
  }>;
88
- export type OpenapiSchemaObjectShorthand = OpenapiSchemaObjectBaseShorthand | OpenapiSchemaObjectOneOfShorthand | OpenapiSchemaObjectAnyOfShorthand | OpenapiSchemaObjectAllOfShorthand;
111
+ export type OpenapiSchemaObjectShorthand = OpenapiSchemaObjectBaseShorthand | OpenapiSchemaObjectAllOfShorthand;
89
112
  export type OpenapiSchemaObjectBaseShorthand = CommonOpenapiSchemaObjectFields<{
90
113
  minProperties?: number;
91
114
  maxProperties?: number;
92
115
  properties?: OpenapiSchemaPropertiesShorthand | OpenapiSchemaShorthandExpressionOneOf | OpenapiSchemaShorthandExpressionAnyOf | OpenapiSchemaShorthandExpressionAllOf | OpenapiSchemaShorthandExpressionSerializerRef | OpenapiSchemaShorthandExpressionSerializableRef;
93
116
  additionalProperties?: OpenapiShorthandPrimitiveTypes | OpenapiSchemaBodyShorthand | OpenapiSchemaShorthandExpressionOneOf | OpenapiSchemaShorthandExpressionAnyOf | OpenapiSchemaShorthandExpressionAllOf | OpenapiSchemaShorthandExpressionSerializerRef | OpenapiSchemaShorthandExpressionSerializableRef | false;
117
+ allOf?: never;
94
118
  }>;
95
- export type OpenapiSchemaObjectOneOfShorthand = CommonOpenapiSchemaObjectFields<{
96
- oneOf?: OpenapiSchemaBodyShorthand[];
97
- }>;
98
- export type OpenapiSchemaObjectAnyOfShorthand = CommonOpenapiSchemaObjectFields<{
99
- anyOf?: OpenapiSchemaBodyShorthand[];
100
- }>;
101
- export type OpenapiSchemaObjectAllOfShorthand = CommonOpenapiSchemaObjectFields<{
119
+ /**
120
+ * The shorthand form of `OpenapiSchemaObjectAllOf`.
121
+ */
122
+ export type OpenapiSchemaObjectAllOfShorthand = OpenapiSchemaCommonFields<{
123
+ type: 'object';
124
+ required?: string[];
102
125
  allOf?: OpenapiSchemaBodyShorthand[];
103
126
  }>;
104
127
  export type CommonOpenapiSchemaObjectFields<T> = OpenapiSchemaCommonFields<T & {
@@ -2,7 +2,7 @@ import Dream from '../Dream.js';
2
2
  import { RoundingPrecision } from '../helpers/round.js';
3
3
  import DreamSerializerBuilder from '../serializer/builders/DreamSerializerBuilder.js';
4
4
  import ObjectSerializerBuilder from '../serializer/builders/ObjectSerializerBuilder.js';
5
- import { DreamSerializable, DreamSerializableArray, ViewModelClass } from './dream.js';
5
+ import { DreamSerializable, DreamSerializableArray, DreamVirtualColumns, NonJsonDreamColumnNames, ViewModelClass } from './dream.js';
6
6
  import { OpenapiDescription, OpenapiSchemaBodyShorthand, OpenapiShorthandPrimitiveTypes } from './openapi.js';
7
7
  export type SerializerCasing = 'camel' | 'snake';
8
8
  export type DreamsOrSerializersOrViewModels = DreamSerializable | DreamSerializableArray;
@@ -28,7 +28,9 @@ export interface InternalAnyTypedSerializerCustomAttribute {
28
28
  type: 'customAttribute';
29
29
  name: string;
30
30
  fn: (x?: any, y?: any) => any;
31
- options: Omit<NonAutomaticSerializerAttributeOptions, 'as'> & {
31
+ options: {
32
+ openapi: CustomAttributeOpenapi;
33
+ required?: false;
32
34
  flatten?: boolean;
33
35
  };
34
36
  }
@@ -119,6 +121,45 @@ export type NonAutomaticSerializerAttributeOptions = {
119
121
  export type NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption = NonAutomaticSerializerAttributeOptions & {
120
122
  precision?: RoundingPrecision;
121
123
  };
124
+ /**
125
+ * The options argument of `DreamSerializer#delegatedAttribute`. A Dream model's non-json
126
+ * column infers its OpenAPI shape, so its `openapi` takes only a description and the
127
+ * argument may be left out. A json/jsonb column or a non-Dream target has no shape to
128
+ * infer, so the argument is required and its `openapi` takes a full shape.
129
+ */
130
+ export type DelegatedAttributeOptionsArgs<AssociatedModelType, TargetAttributeName> = DelegatedAttributeOptions<AssociatedModelType, TargetAttributeName> extends infer Options ? Partial<Options> extends Options ? [options?: Options] : [options: Options] : never;
131
+ type DelegatedAttributeOptions<AssociatedModelType, TargetAttributeName> = AssociatedModelType extends Dream ? TargetAttributeName extends NonJsonDreamColumnNames<AssociatedModelType> & keyof AssociatedModelType & 'type' ? AutomaticSerializerAttributeOptionsForType & {
132
+ optional?: boolean;
133
+ required?: false;
134
+ } : TargetAttributeName extends DreamVirtualColumns<AssociatedModelType>[number] ? SerializerAttributeOptionsForVirtualColumn & {
135
+ optional?: boolean;
136
+ } : TargetAttributeName extends NonJsonDreamColumnNames<AssociatedModelType> & keyof AssociatedModelType & string ? AutomaticSerializerAttributeOptions & {
137
+ optional?: boolean;
138
+ } : NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption & {
139
+ optional?: boolean;
140
+ } : NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption & {
141
+ optional?: boolean;
142
+ };
143
+ type CustomAttributeOpenapi = OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes;
144
+ /**
145
+ * The options of `customAttribute`. The callback's return value renders as is, so there is
146
+ * no `as`, `default` or `precision`. With `flatten: true`, `openapi` may be anything but a
147
+ * serializer ref with `many: true`: flattening spreads one object's properties into the
148
+ * parent, and a list has none to spread.
149
+ */
150
+ export type CustomAttributeOptions = {
151
+ openapi: CustomAttributeOpenapi;
152
+ required?: false;
153
+ flatten?: false;
154
+ } | {
155
+ openapi: OpenapiForFlattening<CustomAttributeOpenapi>;
156
+ required?: false;
157
+ flatten: true;
158
+ };
159
+ type OpenapiForFlattening<Openapi> = Openapi extends unknown ? 'many' extends keyof Openapi ? Omit<Openapi, 'many'> & {
160
+ many?: false;
161
+ } : Openapi : never;
122
162
  export type DreamModelSerializerType = (data: any, passthroughData?: any) => DreamSerializerBuilder<any, any>;
123
163
  export type SimpleObjectSerializerType = (data: any, passthroughData?: any) => ObjectSerializerBuilder<any, any>;
124
164
  export type SerializerType = DreamModelSerializerType | SimpleObjectSerializerType;
165
+ export {};
@@ -90,6 +90,12 @@ export interface AfterHookOpts<T extends Dream | null = null> {
90
90
  * Only run this hook if one of the specified columns was changed in the
91
91
  * most recent save operation.
92
92
  *
93
+ * On a create, a column counts when, just before the insert, it holds a
94
+ * value other than `undefined` (for an instance from `dup`, other than the
95
+ * copied value), whether the caller or a before hook assigned it; values
96
+ * the insert fills in, such as the primary key, timestamps, database
97
+ * defaults and `null` for a column nobody assigned, do not count.
98
+ *
93
99
  * ```ts
94
100
  * @deco.AfterUpdate({ ifChanged: ['email'] })
95
101
  * public sendEmailVerification() { ... }
@@ -32,17 +32,17 @@ export type OpenapiSchemaBase =
32
32
  | OpenapiSchemaNull
33
33
  | OpenapiSchemaExpressionRef
34
34
 
35
- export type OpenapiSchemaShorthandExpressionAnyOf = {
35
+ export type OpenapiSchemaShorthandExpressionAnyOf = OpenapiSchemaCombinatorFields<{
36
36
  anyOf: OpenapiSchemaBodyShorthand[]
37
- }
37
+ }>
38
38
 
39
- export type OpenapiSchemaShorthandExpressionOneOf = {
39
+ export type OpenapiSchemaShorthandExpressionOneOf = OpenapiSchemaCombinatorFields<{
40
40
  oneOf: OpenapiSchemaBodyShorthand[]
41
- }
41
+ }>
42
42
 
43
- export type OpenapiSchemaShorthandExpressionAllOf = {
43
+ export type OpenapiSchemaShorthandExpressionAllOf = OpenapiSchemaCombinatorFields<{
44
44
  allOf: OpenapiSchemaBodyShorthand[]
45
- }
45
+ }>
46
46
 
47
47
  export type OpenapiSchemaShorthandExpressionSerializerRef = {
48
48
  $serializer: DreamModelSerializerType | SimpleObjectSerializerType
@@ -66,21 +66,40 @@ export type OpenapiSchemaExpressionRefSchemaShorthand = {
66
66
  $schema: string
67
67
  }
68
68
 
69
- export type OpenapiSchemaExpressionAllOf = {
69
+ export type OpenapiSchemaExpressionAllOf = OpenapiSchemaCombinatorFields<{
70
70
  allOf: OpenapiSchemaBody[]
71
- }
71
+ }>
72
72
 
73
- export type OpenapiSchemaExpressionAnyOf = {
73
+ export type OpenapiSchemaExpressionAnyOf = OpenapiSchemaCombinatorFields<{
74
74
  anyOf: OpenapiSchemaBody[]
75
- }
75
+ }>
76
76
 
77
- export type OpenapiSchemaExpressionOneOf = {
77
+ export type OpenapiSchemaExpressionOneOf = OpenapiSchemaCombinatorFields<{
78
78
  oneOf: OpenapiSchemaBody[]
79
- }
79
+ }>
80
80
 
81
+ /**
82
+ * The fields of a schema that declares a `type`. `anyOf` and `oneOf` are not
83
+ * among them: they apply to every value, `null` included, so a nullable `type`
84
+ * beside one cannot admit `null`. A schema that may be null lists a
85
+ * `{ type: 'null' }` branch in its `anyOf` or `oneOf` instead.
86
+ */
81
87
  export type OpenapiSchemaCommonFields<T> = T & {
82
88
  description?: string
83
89
  summary?: string
90
+ anyOf?: never
91
+ oneOf?: never
92
+ }
93
+
94
+ /**
95
+ * The fields of a schema that is an `allOf`, `anyOf` or `oneOf`: the
96
+ * combinator and the fields that describe it, but no `type` (see
97
+ * `OpenapiSchemaCommonFields`).
98
+ */
99
+ export type OpenapiSchemaCombinatorFields<T> = T & {
100
+ description?: string
101
+ summary?: string
102
+ type?: never
84
103
  }
85
104
 
86
105
  export type OpenapiSchemaString = OpenapiSchemaCommonFields<{
@@ -108,15 +127,13 @@ export type OpenapiSchemaNumber = OpenapiSchemaCommonFields<{
108
127
 
109
128
  export type OpenapiSchemaNull = {
110
129
  type: 'null'
130
+ anyOf?: never
131
+ oneOf?: never
111
132
  }
112
133
 
113
134
  export type OpenapiNumberFormats = 'decimal' | 'double'
114
135
 
115
- export type OpenapiSchemaObject =
116
- | OpenapiSchemaObjectBase
117
- | OpenapiSchemaObjectOneOf
118
- | OpenapiSchemaObjectAnyOf
119
- | OpenapiSchemaObjectAllOf
136
+ export type OpenapiSchemaObject = OpenapiSchemaObjectBase | OpenapiSchemaObjectAllOf
120
137
 
121
138
  export type OpenapiSchemaObjectBase = CommonOpenapiSchemaObjectFields<{
122
139
  minProperties?: number
@@ -132,24 +149,23 @@ export type OpenapiSchemaObjectBase = CommonOpenapiSchemaObjectFields<{
132
149
  | OpenapiSchemaExpressionAnyOf
133
150
  | OpenapiSchemaExpressionAllOf
134
151
  | false
152
+ allOf?: never
135
153
  }>
136
154
 
137
- export type OpenapiSchemaObjectOneOf = CommonOpenapiSchemaObjectFields<{
138
- oneOf?: OpenapiSchemaBody[]
139
- }>
140
-
141
- export type OpenapiSchemaObjectAnyOf = CommonOpenapiSchemaObjectFields<{
142
- anyOf?: OpenapiSchemaBody[]
143
- }>
144
-
145
- export type OpenapiSchemaObjectAllOf = CommonOpenapiSchemaObjectFields<{
155
+ /**
156
+ * An object schema that is also an `allOf`. Its `type` cannot be nullable:
157
+ * `allOf` applies to every value, so `null` would have to match each of its
158
+ * object members. A schema that may be null is an `anyOf` or `oneOf` with a
159
+ * `{ type: 'null' }` branch.
160
+ */
161
+ export type OpenapiSchemaObjectAllOf = OpenapiSchemaCommonFields<{
162
+ type: 'object'
163
+ required?: string[]
146
164
  allOf?: OpenapiSchemaBody[]
147
165
  }>
148
166
 
149
167
  export type OpenapiSchemaObjectShorthand =
150
168
  | OpenapiSchemaObjectBaseShorthand
151
- | OpenapiSchemaObjectOneOfShorthand
152
- | OpenapiSchemaObjectAnyOfShorthand
153
169
  | OpenapiSchemaObjectAllOfShorthand
154
170
 
155
171
  export type OpenapiSchemaObjectBaseShorthand = CommonOpenapiSchemaObjectFields<{
@@ -171,17 +187,15 @@ export type OpenapiSchemaObjectBaseShorthand = CommonOpenapiSchemaObjectFields<{
171
187
  | OpenapiSchemaShorthandExpressionSerializerRef
172
188
  | OpenapiSchemaShorthandExpressionSerializableRef
173
189
  | false
190
+ allOf?: never
174
191
  }>
175
192
 
176
- export type OpenapiSchemaObjectOneOfShorthand = CommonOpenapiSchemaObjectFields<{
177
- oneOf?: OpenapiSchemaBodyShorthand[]
178
- }>
179
-
180
- export type OpenapiSchemaObjectAnyOfShorthand = CommonOpenapiSchemaObjectFields<{
181
- anyOf?: OpenapiSchemaBodyShorthand[]
182
- }>
183
-
184
- export type OpenapiSchemaObjectAllOfShorthand = CommonOpenapiSchemaObjectFields<{
193
+ /**
194
+ * The shorthand form of `OpenapiSchemaObjectAllOf`.
195
+ */
196
+ export type OpenapiSchemaObjectAllOfShorthand = OpenapiSchemaCommonFields<{
197
+ type: 'object'
198
+ required?: string[]
185
199
  allOf?: OpenapiSchemaBodyShorthand[]
186
200
  }>
187
201
 
@@ -2,7 +2,13 @@ import Dream from '../Dream.js'
2
2
  import { RoundingPrecision } from '../helpers/round.js'
3
3
  import DreamSerializerBuilder from '../serializer/builders/DreamSerializerBuilder.js'
4
4
  import ObjectSerializerBuilder from '../serializer/builders/ObjectSerializerBuilder.js'
5
- import { DreamSerializable, DreamSerializableArray, ViewModelClass } from './dream.js'
5
+ import {
6
+ DreamSerializable,
7
+ DreamSerializableArray,
8
+ DreamVirtualColumns,
9
+ NonJsonDreamColumnNames,
10
+ ViewModelClass,
11
+ } from './dream.js'
6
12
  import { OpenapiDescription, OpenapiSchemaBodyShorthand, OpenapiShorthandPrimitiveTypes } from './openapi.js'
7
13
 
8
14
  export type SerializerCasing = 'camel' | 'snake'
@@ -32,7 +38,11 @@ export interface InternalAnyTypedSerializerCustomAttribute {
32
38
  type: 'customAttribute'
33
39
  name: string
34
40
  fn: (x?: any, y?: any) => any
35
- options: Omit<NonAutomaticSerializerAttributeOptions, 'as'> & { flatten?: boolean }
41
+ options: {
42
+ openapi: CustomAttributeOpenapi
43
+ required?: false
44
+ flatten?: boolean
45
+ }
36
46
  }
37
47
 
38
48
  export interface InternalAnyRendersOneOrManyOpts {
@@ -143,6 +153,56 @@ export type NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOptio
143
153
  precision?: RoundingPrecision
144
154
  }
145
155
 
156
+ /**
157
+ * The options argument of `DreamSerializer#delegatedAttribute`. A Dream model's non-json
158
+ * column infers its OpenAPI shape, so its `openapi` takes only a description and the
159
+ * argument may be left out. A json/jsonb column or a non-Dream target has no shape to
160
+ * infer, so the argument is required and its `openapi` takes a full shape.
161
+ */
162
+ export type DelegatedAttributeOptionsArgs<AssociatedModelType, TargetAttributeName> =
163
+ DelegatedAttributeOptions<AssociatedModelType, TargetAttributeName> extends infer Options
164
+ ? Partial<Options> extends Options
165
+ ? [options?: Options]
166
+ : [options: Options]
167
+ : never
168
+
169
+ type DelegatedAttributeOptions<AssociatedModelType, TargetAttributeName> = AssociatedModelType extends Dream
170
+ ? TargetAttributeName extends NonJsonDreamColumnNames<AssociatedModelType> &
171
+ keyof AssociatedModelType &
172
+ 'type'
173
+ ? AutomaticSerializerAttributeOptionsForType & {
174
+ optional?: boolean
175
+ required?: false
176
+ }
177
+ : TargetAttributeName extends DreamVirtualColumns<AssociatedModelType>[number]
178
+ ? SerializerAttributeOptionsForVirtualColumn & { optional?: boolean }
179
+ : TargetAttributeName extends NonJsonDreamColumnNames<AssociatedModelType> &
180
+ keyof AssociatedModelType &
181
+ string
182
+ ? AutomaticSerializerAttributeOptions & { optional?: boolean }
183
+ : NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption & {
184
+ optional?: boolean
185
+ }
186
+ : NonAutomaticSerializerAttributeOptionsWithPossibleDecimalRenderOption & { optional?: boolean }
187
+
188
+ type CustomAttributeOpenapi = OpenapiSchemaBodyShorthand | OpenapiShorthandPrimitiveTypes
189
+
190
+ /**
191
+ * The options of `customAttribute`. The callback's return value renders as is, so there is
192
+ * no `as`, `default` or `precision`. With `flatten: true`, `openapi` may be anything but a
193
+ * serializer ref with `many: true`: flattening spreads one object's properties into the
194
+ * parent, and a list has none to spread.
195
+ */
196
+ export type CustomAttributeOptions =
197
+ | { openapi: CustomAttributeOpenapi; required?: false; flatten?: false }
198
+ | { openapi: OpenapiForFlattening<CustomAttributeOpenapi>; required?: false; flatten: true }
199
+
200
+ type OpenapiForFlattening<Openapi> = Openapi extends unknown
201
+ ? 'many' extends keyof Openapi
202
+ ? Omit<Openapi, 'many'> & { many?: false }
203
+ : Openapi
204
+ : never
205
+
146
206
  export type DreamModelSerializerType = (data: any, passthroughData?: any) => DreamSerializerBuilder<any, any>
147
207
 
148
208
  export type SimpleObjectSerializerType = (