@rvoh/dream 1.2.0 → 1.3.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 (212) hide show
  1. package/dist/cjs/src/Dream.js +99 -31
  2. package/dist/cjs/src/db/errors.js +5 -1
  3. package/dist/cjs/src/dream/QueryDriver/Kysely.js +46 -31
  4. package/dist/cjs/src/dream/internal/printSerializerHierarchyLevel.js +17 -0
  5. package/dist/cjs/src/dream-app/cache.js +12 -2
  6. package/dist/cjs/src/errors/db/DataTypeColumnTypeMismatch.js +19 -0
  7. package/dist/cjs/src/helpers/cli/generateMigration.js +1 -0
  8. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +20 -5
  9. package/dist/cjs/src/helpers/cli/generateStiMigrationContent.js +8 -2
  10. package/dist/cjs/src/helpers/sqlAttributes.js +7 -1
  11. package/dist/cjs/src/index.js +4 -2
  12. package/dist/cjs/src/serializer/helpers/serializerForAssociatedClass.js +3 -2
  13. package/dist/esm/src/Dream.js +99 -31
  14. package/dist/esm/src/db/errors.js +5 -1
  15. package/dist/esm/src/dream/QueryDriver/Kysely.js +46 -31
  16. package/dist/esm/src/dream/internal/printSerializerHierarchyLevel.js +14 -0
  17. package/dist/esm/src/dream-app/cache.js +12 -2
  18. package/dist/esm/src/errors/db/DataTypeColumnTypeMismatch.js +16 -0
  19. package/dist/esm/src/helpers/cli/generateMigration.js +1 -0
  20. package/dist/esm/src/helpers/cli/generateMigrationContent.js +20 -5
  21. package/dist/esm/src/helpers/cli/generateStiMigrationContent.js +8 -2
  22. package/dist/esm/src/helpers/sqlAttributes.js +7 -1
  23. package/dist/esm/src/index.js +1 -0
  24. package/dist/esm/src/serializer/helpers/serializerForAssociatedClass.js +3 -2
  25. package/dist/types/src/Dream.d.ts +77 -52
  26. package/dist/types/src/db/errors.d.ts +3 -1
  27. package/dist/types/src/dream/QueryDriver/Kysely.d.ts +1 -0
  28. package/dist/types/src/dream/internal/printSerializerHierarchyLevel.d.ts +7 -0
  29. package/dist/types/src/errors/db/DataTypeColumnTypeMismatch.d.ts +10 -0
  30. package/dist/types/src/helpers/cli/generateMigrationContent.d.ts +2 -1
  31. package/dist/types/src/helpers/cli/generateStiMigrationContent.d.ts +2 -1
  32. package/dist/types/src/index.d.ts +1 -0
  33. package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +1 -1
  34. package/dist/types/src/types/dream.d.ts +1 -1
  35. package/dist/types/src/types/dream.ts +2 -2
  36. package/docs/assets/navigation.js +1 -1
  37. package/docs/assets/search.js +1 -1
  38. package/docs/classes/Benchmark.html +2 -2
  39. package/docs/classes/CalendarDate.html +2 -2
  40. package/docs/classes/CliFileWriter.html +2 -2
  41. package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +3 -3
  42. package/docs/classes/DataTypeColumnTypeMismatch.html +14 -0
  43. package/docs/classes/Decorators.html +19 -19
  44. package/docs/classes/Dream.html +209 -308
  45. package/docs/classes/DreamApp.html +4 -4
  46. package/docs/classes/DreamBin.html +2 -2
  47. package/docs/classes/DreamCLI.html +4 -4
  48. package/docs/classes/DreamImporter.html +2 -2
  49. package/docs/classes/DreamLogos.html +2 -2
  50. package/docs/classes/DreamMigrationHelpers.html +7 -7
  51. package/docs/classes/DreamSerializerBuilder.html +8 -8
  52. package/docs/classes/DreamTransaction.html +2 -2
  53. package/docs/classes/Encrypt.html +2 -2
  54. package/docs/classes/Env.html +2 -2
  55. package/docs/classes/GlobalNameNotSet.html +3 -3
  56. package/docs/classes/NonLoadedAssociation.html +3 -3
  57. package/docs/classes/ObjectSerializerBuilder.html +8 -8
  58. package/docs/classes/Query.html +60 -60
  59. package/docs/classes/Range.html +2 -2
  60. package/docs/classes/RecordNotFound.html +3 -3
  61. package/docs/classes/ValidationError.html +3 -3
  62. package/docs/functions/DreamSerializer.html +1 -1
  63. package/docs/functions/ObjectSerializer.html +1 -1
  64. package/docs/functions/ReplicaSafe.html +1 -1
  65. package/docs/functions/STI.html +1 -1
  66. package/docs/functions/SoftDelete.html +1 -1
  67. package/docs/functions/camelize.html +1 -1
  68. package/docs/functions/capitalize.html +1 -1
  69. package/docs/functions/cloneDeepSafe.html +1 -1
  70. package/docs/functions/closeAllDbConnections.html +1 -1
  71. package/docs/functions/compact.html +1 -1
  72. package/docs/functions/dreamDbConnections.html +1 -1
  73. package/docs/functions/dreamPath.html +1 -1
  74. package/docs/functions/expandStiClasses.html +1 -1
  75. package/docs/functions/generateDream.html +1 -1
  76. package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
  77. package/docs/functions/groupBy.html +1 -1
  78. package/docs/functions/hyphenize.html +1 -1
  79. package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
  80. package/docs/functions/inferSerializersFromDreamClassOrViewModelClass.html +1 -1
  81. package/docs/functions/intersection.html +1 -1
  82. package/docs/functions/isDreamSerializer.html +1 -1
  83. package/docs/functions/isEmpty.html +1 -1
  84. package/docs/functions/loadRepl.html +1 -1
  85. package/docs/functions/lookupClassByGlobalName.html +1 -1
  86. package/docs/functions/normalizeUnicode.html +1 -1
  87. package/docs/functions/pascalize.html +1 -1
  88. package/docs/functions/pgErrorType.html +1 -1
  89. package/docs/functions/range-1.html +1 -1
  90. package/docs/functions/relativeDreamPath.html +1 -1
  91. package/docs/functions/round.html +1 -1
  92. package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
  93. package/docs/functions/sharedPathPrefix.html +1 -1
  94. package/docs/functions/snakeify.html +1 -1
  95. package/docs/functions/sort.html +1 -1
  96. package/docs/functions/sortBy.html +1 -1
  97. package/docs/functions/sortObjectByKey.html +1 -1
  98. package/docs/functions/sortObjectByValue.html +1 -1
  99. package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
  100. package/docs/functions/uncapitalize.html +1 -1
  101. package/docs/functions/uniq.html +1 -1
  102. package/docs/functions/untypedDb.html +1 -1
  103. package/docs/functions/validateColumn.html +1 -1
  104. package/docs/functions/validateTable.html +1 -1
  105. package/docs/interfaces/BelongsToStatement.html +2 -2
  106. package/docs/interfaces/DecoratorContext.html +2 -2
  107. package/docs/interfaces/DreamAppInitOptions.html +2 -2
  108. package/docs/interfaces/DreamAppOpts.html +2 -2
  109. package/docs/interfaces/EncryptOptions.html +2 -2
  110. package/docs/interfaces/InternalAnyTypedSerializerRendersMany.html +2 -2
  111. package/docs/interfaces/InternalAnyTypedSerializerRendersOne.html +2 -2
  112. package/docs/interfaces/OpenapiDescription.html +2 -2
  113. package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
  114. package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
  115. package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
  116. package/docs/interfaces/SerializerRendererOpts.html +2 -2
  117. package/docs/modules.html +1 -0
  118. package/docs/types/Camelized.html +1 -1
  119. package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
  120. package/docs/types/DateTime.html +1 -1
  121. package/docs/types/DbConnectionType.html +1 -1
  122. package/docs/types/DbTypes.html +1 -1
  123. package/docs/types/DreamAppAllowedPackageManagersEnum.html +1 -1
  124. package/docs/types/DreamAssociationMetadata.html +1 -1
  125. package/docs/types/DreamAttributes.html +1 -1
  126. package/docs/types/DreamClassAssociationAndStatement.html +1 -1
  127. package/docs/types/DreamClassColumn.html +1 -1
  128. package/docs/types/DreamColumn.html +1 -1
  129. package/docs/types/DreamColumnNames.html +1 -1
  130. package/docs/types/DreamLogLevel.html +1 -1
  131. package/docs/types/DreamLogger.html +1 -1
  132. package/docs/types/DreamModelSerializerType.html +1 -1
  133. package/docs/types/DreamOrViewModelClassSerializerKey.html +1 -1
  134. package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
  135. package/docs/types/DreamParamSafeAttributes.html +1 -1
  136. package/docs/types/DreamParamSafeColumnNames.html +1 -1
  137. package/docs/types/DreamSerializable.html +1 -1
  138. package/docs/types/DreamSerializableArray.html +1 -1
  139. package/docs/types/DreamSerializerKey.html +1 -1
  140. package/docs/types/DreamSerializers.html +1 -1
  141. package/docs/types/DreamTableSchema.html +1 -1
  142. package/docs/types/DreamVirtualColumns.html +1 -1
  143. package/docs/types/EncryptAlgorithm.html +1 -1
  144. package/docs/types/HasManyStatement.html +1 -1
  145. package/docs/types/HasOneStatement.html +1 -1
  146. package/docs/types/Hyphenized.html +1 -1
  147. package/docs/types/IdType.html +1 -1
  148. package/docs/types/OpenapiAllTypes.html +1 -1
  149. package/docs/types/OpenapiFormats.html +1 -1
  150. package/docs/types/OpenapiNumberFormats.html +1 -1
  151. package/docs/types/OpenapiPrimitiveBaseTypes.html +1 -1
  152. package/docs/types/OpenapiPrimitiveTypes.html +1 -1
  153. package/docs/types/OpenapiSchemaArray.html +1 -1
  154. package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
  155. package/docs/types/OpenapiSchemaBase.html +1 -1
  156. package/docs/types/OpenapiSchemaBody.html +1 -1
  157. package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
  158. package/docs/types/OpenapiSchemaCommonFields.html +1 -1
  159. package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
  160. package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
  161. package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
  162. package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
  163. package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  164. package/docs/types/OpenapiSchemaInteger.html +1 -1
  165. package/docs/types/OpenapiSchemaNull.html +1 -1
  166. package/docs/types/OpenapiSchemaNumber.html +1 -1
  167. package/docs/types/OpenapiSchemaObject.html +1 -1
  168. package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
  169. package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
  170. package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
  171. package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  172. package/docs/types/OpenapiSchemaObjectBase.html +1 -1
  173. package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
  174. package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
  175. package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
  176. package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
  177. package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
  178. package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  179. package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  180. package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  181. package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  182. package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  183. package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  184. package/docs/types/OpenapiSchemaString.html +1 -1
  185. package/docs/types/OpenapiShorthandAllTypes.html +1 -1
  186. package/docs/types/OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  187. package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
  188. package/docs/types/OpenapiTypeField.html +1 -1
  189. package/docs/types/Pascalized.html +1 -1
  190. package/docs/types/PrimaryKeyType.html +1 -1
  191. package/docs/types/RoundingPrecision.html +1 -1
  192. package/docs/types/SerializerCasing.html +1 -1
  193. package/docs/types/SimpleObjectSerializerType.html +1 -1
  194. package/docs/types/Snakeified.html +1 -1
  195. package/docs/types/Timestamp.html +1 -1
  196. package/docs/types/UpdateableAssociationProperties.html +1 -1
  197. package/docs/types/UpdateableProperties.html +1 -1
  198. package/docs/types/ValidationType.html +1 -1
  199. package/docs/types/ViewModel.html +1 -1
  200. package/docs/types/ViewModelClass.html +1 -1
  201. package/docs/types/WhereStatementForDream.html +1 -1
  202. package/docs/types/WhereStatementForDreamClass.html +1 -1
  203. package/docs/variables/DateTime-1.html +1 -1
  204. package/docs/variables/DreamAppAllowedPackageManagersEnumValues.html +1 -1
  205. package/docs/variables/DreamConst.html +1 -1
  206. package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
  207. package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
  208. package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
  209. package/docs/variables/ops.html +1 -1
  210. package/docs/variables/primaryKeyTypes.html +1 -1
  211. package/package.json +2 -2
  212. package/CHANGELOG.md +0 -48
@@ -21,6 +21,7 @@ const destroyDream_js_1 = require("./dream/internal/destroyDream.js");
21
21
  const destroyOptions_js_1 = require("./dream/internal/destroyOptions.js");
22
22
  const ensureSTITypeFieldIsSet_js_1 = require("./dream/internal/ensureSTITypeFieldIsSet.js");
23
23
  const findOrCreateBy_js_1 = require("./dream/internal/findOrCreateBy.js");
24
+ const printSerializerHierarchyLevel_js_1 = require("./dream/internal/printSerializerHierarchyLevel.js");
24
25
  const reload_js_1 = require("./dream/internal/reload.js");
25
26
  const runValidations_js_1 = require("./dream/internal/runValidations.js");
26
27
  const saveDream_js_1 = require("./dream/internal/saveDream.js");
@@ -49,10 +50,8 @@ const cloneDeepSafe_js_1 = require("./helpers/cloneDeepSafe.js");
49
50
  const DateTime_js_1 = require("./helpers/DateTime.js");
50
51
  const cachedTypeForAttribute_js_1 = require("./helpers/db/cachedTypeForAttribute.js");
51
52
  const isJsonColumn_js_1 = require("./helpers/db/types/isJsonColumn.js");
52
- const indent_js_1 = require("./helpers/indent.js");
53
53
  const notEqual_js_1 = require("./helpers/notEqual.js");
54
54
  const inferSerializerFromDreamOrViewModel_js_1 = require("./serializer/helpers/inferSerializerFromDreamOrViewModel.js");
55
- const serializerForAssociatedClass_js_1 = require("./serializer/helpers/serializerForAssociatedClass.js");
56
55
  class Dream {
57
56
  DB;
58
57
  /**
@@ -489,42 +488,65 @@ class Dream {
489
488
  static recursiveSerializationMap(serializer, { forDisplay = false, forDisplayDepth = 0, } = {}) {
490
489
  const serializerBuilder = serializer(undefined, undefined);
491
490
  const serializerAssociations = serializerBuilder['attributes'].filter(attribute => ['rendersOne', 'rendersMany', 'delegatedAttribute'].includes(attribute.type));
492
- return serializerAssociations.reduce((acc, serializerAssociation) => {
491
+ return serializerAssociations.reduce((accumulator, serializerAssociation) => {
493
492
  const serializerAssociationName = serializerAssociation.targetName ??
494
493
  serializerAssociation.name;
495
494
  const serializerAssociationType = serializerAssociation.type;
496
495
  const association = this['getAssociationMetadata'](serializerAssociationName);
497
496
  if (!association)
498
- return acc;
499
- const associatedClasses = association.modelCB();
500
- const associatedClass = Array.isArray(associatedClasses) ? associatedClasses[0] : associatedClasses;
501
- if (!associatedClass)
497
+ return accumulator;
498
+ const maybeAssociatedClasses = association.modelCB();
499
+ if (!maybeAssociatedClasses)
502
500
  throw new Error(`No class defined on ${serializerAssociationName} association on ${this.sanitizedName}`);
503
- const associationSerializer = (0, serializerForAssociatedClass_js_1.serializerForAssociatedClass)(this.prototype, serializerAssociationName, serializerAssociation.options);
504
- if (!associationSerializer)
505
- throw new Error(`No serializer found to render ${serializerAssociationName} on ${this.sanitizedName}`);
506
- if (forDisplay && serializerAssociationType !== 'delegatedAttribute') {
507
- const hierarchyLine = '└───';
508
- const indentation = (0, indent_js_1.indent)((hierarchyLine.length + 1) * forDisplayDepth, {
509
- tabWidth: 1,
510
- });
511
- const prefix = `${hierarchyLine} `;
512
- const nestedAssociationDisplay = indentation + `${prefix}${serializerAssociationType} ${yoctocolors_1.default.cyan(serializerAssociationName)}`;
513
- console.log(nestedAssociationDisplay);
514
- console.log(yoctocolors_1.default.gray(indentation +
515
- (0, indent_js_1.indent)(prefix.length, { tabWidth: 1 }) +
516
- associationSerializer.globalName));
517
- }
518
- acc[association.as] = {
519
- parentDreamClass: this,
520
- nestedSerializerInfo: serializerAssociation.type === 'delegatedAttribute'
521
- ? {}
522
- : associatedClass['recursiveSerializationMap'](associationSerializer, {
501
+ const associatedClasses = Array.isArray(maybeAssociatedClasses)
502
+ ? maybeAssociatedClasses
503
+ : [maybeAssociatedClasses];
504
+ /////////////////////////////////////////////////
505
+ // map associated classes to their serializers //
506
+ /////////////////////////////////////////////////
507
+ const associatedClassSerializerTuples = associatedClasses.flatMap(associatedClass => {
508
+ /**
509
+ * `serializers` is an array because `associatedClass` may be an STI
510
+ * base, with each of its STI children having its own serializer
511
+ */
512
+ const serializers = serializerAssociation.options.serializer
513
+ ? [serializerAssociation.options.serializer]
514
+ : (0, inferSerializerFromDreamOrViewModel_js_1.inferSerializersFromDreamClassOrViewModelClass)(associatedClass, serializerAssociation.options.serializerKey);
515
+ if (!serializers.length)
516
+ throw new Error(`No serializer found to render ${serializerAssociationName} on ${this.sanitizedName}`);
517
+ return serializers.map(serializer => [associatedClass, serializer]);
518
+ });
519
+ /////////////////////////////////////////////////////
520
+ // end:map associated classes to their serializers //
521
+ /////////////////////////////////////////////////////
522
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
523
+ // reduce over all associated serializers, recursively building out their associated serializers //
524
+ ///////////////////////////////////////////////////////////////////////////////////////////////////
525
+ const innerAssociationSerializerInfo = associatedClassSerializerTuples.reduce((innerAccumulator, [associatedClass, associatedSerializer]) => {
526
+ if (forDisplay && serializerAssociationType !== 'delegatedAttribute') {
527
+ (0, printSerializerHierarchyLevel_js_1.default)({
528
+ serializerAssociationType,
529
+ serializerAssociationName,
530
+ associationSerializer: associatedSerializer,
531
+ forDisplayDepth,
532
+ });
533
+ }
534
+ return {
535
+ ...innerAccumulator,
536
+ ...associatedClass['recursiveSerializationMap'](associatedSerializer, {
523
537
  forDisplay,
524
538
  forDisplayDepth: forDisplayDepth + 1,
525
539
  }),
540
+ };
541
+ }, {});
542
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
543
+ // end:reduce over all associated serializers, recursively building out their associated serializers //
544
+ ///////////////////////////////////////////////////////////////////////////////////////////////////////
545
+ accumulator[association.as] = {
546
+ parentDreamClass: this,
547
+ nestedSerializerInfo: serializerAssociation.type === 'delegatedAttribute' ? {} : innerAssociationSerializerInfo,
526
548
  };
527
- return acc;
549
+ return accumulator;
528
550
  }, {});
529
551
  }
530
552
  /**
@@ -659,11 +681,57 @@ class Dream {
659
681
  return map;
660
682
  }
661
683
  /**
662
- * @internal
684
+ * Checks whether the specified association has been defined on this Dream model.
685
+ *
686
+ * ```ts
687
+ * const user = User.new()
688
+ *
689
+ * user.hasAssociation('posts')
690
+ * // true (if User has a posts association defined)
691
+ *
692
+ * user.hasAssociation('nonExistentAssociation')
693
+ * // false
694
+ *
695
+ * // Useful for conditional association handling
696
+ * if (user.hasAssociation('posts')) {
697
+ * user = await user.load('posts').execute()
698
+ * }
699
+ * ```
700
+ *
701
+ * @param associationName - The name of the association to check for
702
+ * @returns `true` if the association exists on this model, `false` otherwise
703
+ */
704
+ hasAssociation(associationName) {
705
+ return !!(this.associationMetadataByType.belongsTo.find(association => association.as === associationName) ||
706
+ this.associationMetadataByType.hasOne.find(association => association.as === associationName) ||
707
+ this.associationMetadataByType.hasMany.find(association => association.as === associationName));
708
+ }
709
+ /**
710
+ * Returns all of the association names for this Dream class.
711
+ * This includes all BelongsTo, HasOne, and HasMany associations
712
+ * defined on the model.
663
713
  *
664
- * Returns all of the association names for this dream class
714
+ * This is useful for introspection, debugging, or dynamically working
715
+ * with all associations on a model.
716
+ *
717
+ * ```ts
718
+ * class User extends ApplicationModel {
719
+ * @deco.HasMany('Post')
720
+ * public posts: Post[]
721
+ *
722
+ * @deco.HasOne('Profile')
723
+ * public profile: Profile
724
+ *
725
+ * @deco.BelongsTo('Company')
726
+ * public company: Company
727
+ * }
728
+ *
729
+ * User.associationNames
730
+ * // ['posts', 'profile', 'company']
731
+ * })
732
+ * ```
665
733
  *
666
- * @returns All of the association names for this dream class
734
+ * @returns An array containing all association names defined on this Dream class
667
735
  */
668
736
  static get associationNames() {
669
737
  const allAssociations = [
@@ -11,8 +11,12 @@ exports.pgErrorType = pgErrorType;
11
11
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
12
  // @ts-ignore
13
13
  const pg_1 = require("pg");
14
+ const UNIQUE_CONSTRAINT_VIOLATION = 'UNIQUE_CONSTRAINT_VIOLATION';
15
+ const INVALID_INPUT_SYNTAX = 'INVALID_INPUT_SYNTAX';
14
16
  exports.PG_ERRORS = {
15
- 23505: 'UNIQUE_CONSTRAINT_VIOLATION',
17
+ '23505': UNIQUE_CONSTRAINT_VIOLATION,
18
+ '22P02': INVALID_INPUT_SYNTAX,
19
+ '22007': INVALID_INPUT_SYNTAX,
16
20
  };
17
21
  function pgErrorFromCode(code) {
18
22
  return exports.PG_ERRORS[code] || null;
@@ -5,6 +5,7 @@ const pluralize_esm_1 = require("pluralize-esm");
5
5
  const sync_js_1 = require("../../bin/helpers/sync.js");
6
6
  const CliFileWriter_js_1 = require("../../cli/CliFileWriter.js");
7
7
  const index_js_1 = require("../../cli/index.js");
8
+ const errors_js_1 = require("../../db/errors.js");
8
9
  const index_js_2 = require("../../db/index.js");
9
10
  const associationToGetterSetterProp_js_1 = require("../../decorators/field/association/associationToGetterSetterProp.js");
10
11
  const PackageManager_js_1 = require("../../dream-app/helpers/PackageManager.js");
@@ -19,6 +20,7 @@ const MissingThroughAssociationSource_js_1 = require("../../errors/associations/
19
20
  const ThroughAssociationConditionsIncompatibleWithThroughAssociationSource_js_1 = require("../../errors/associations/ThroughAssociationConditionsIncompatibleWithThroughAssociationSource.js");
20
21
  const CannotNegateSimilarityClause_js_1 = require("../../errors/CannotNegateSimilarityClause.js");
21
22
  const CannotPassUndefinedAsAValueToAWhereClause_js_1 = require("../../errors/CannotPassUndefinedAsAValueToAWhereClause.js");
23
+ const DataTypeColumnTypeMismatch_js_1 = require("../../errors/db/DataTypeColumnTypeMismatch.js");
22
24
  const UnexpectedUndefined_js_1 = require("../../errors/UnexpectedUndefined.js");
23
25
  const CalendarDate_js_1 = require("../../helpers/CalendarDate.js");
24
26
  const camelize_js_1 = require("../../helpers/camelize.js");
@@ -31,6 +33,7 @@ const dropDb_js_1 = require("../../helpers/db/dropDb.js");
31
33
  const loadPgClient_js_1 = require("../../helpers/db/loadPgClient.js");
32
34
  const runMigration_js_1 = require("../../helpers/db/runMigration.js");
33
35
  const EnvInternal_js_1 = require("../../helpers/EnvInternal.js");
36
+ const groupBy_js_1 = require("../../helpers/groupBy.js");
34
37
  const isEmpty_js_1 = require("../../helpers/isEmpty.js");
35
38
  const namespaceColumn_js_1 = require("../../helpers/namespaceColumn.js");
36
39
  const normalizeUnicode_js_1 = require("../../helpers/normalizeUnicode.js");
@@ -415,19 +418,31 @@ class KyselyQueryDriver extends Base_js_1.default {
415
418
  static async saveDream(dream, txn = null) {
416
419
  const db = txn?.kyselyTransaction ?? (0, index_js_2.default)('primary');
417
420
  const sqlifiedAttributes = (0, sqlAttributes_js_1.default)(dream);
418
- if (dream.isPersisted) {
419
- const query = db
420
- .updateTable(dream.table)
421
- .set(sqlifiedAttributes)
422
- .where((0, namespaceColumn_js_1.default)(dream.primaryKey, dream.table), '=', dream.primaryKeyValue);
423
- return await (0, executeDatabaseQuery_js_1.default)(query.returning([...dream.columns()]), 'executeTakeFirstOrThrow');
421
+ try {
422
+ if (dream.isPersisted) {
423
+ const query = db
424
+ .updateTable(dream.table)
425
+ .set(sqlifiedAttributes)
426
+ .where((0, namespaceColumn_js_1.default)(dream.primaryKey, dream.table), '=', dream.primaryKeyValue);
427
+ return await (0, executeDatabaseQuery_js_1.default)(query.returning([...dream.columns()]), 'executeTakeFirstOrThrow');
428
+ }
429
+ else {
430
+ const query = db
431
+ .insertInto(dream.table)
432
+ .values(sqlifiedAttributes)
433
+ .returning([...dream.columns()]);
434
+ return await (0, executeDatabaseQuery_js_1.default)(query, 'executeTakeFirstOrThrow');
435
+ }
424
436
  }
425
- else {
426
- const query = db
427
- .insertInto(dream.table)
428
- .values(sqlifiedAttributes)
429
- .returning([...dream.columns()]);
430
- return await (0, executeDatabaseQuery_js_1.default)(query, 'executeTakeFirstOrThrow');
437
+ catch (error) {
438
+ switch ((0, errors_js_1.pgErrorType)(error)) {
439
+ case 'INVALID_INPUT_SYNTAX':
440
+ throw new DataTypeColumnTypeMismatch_js_1.default({
441
+ dream,
442
+ error: error instanceof Error ? error : new Error('database column type error'),
443
+ });
444
+ }
445
+ throw error;
431
446
  }
432
447
  }
433
448
  dbConnectionType(sqlCommandType) {
@@ -1190,7 +1205,7 @@ class KyselyQueryDriver extends Base_js_1.default {
1190
1205
  const keys = Object.keys(preloadStatement);
1191
1206
  for (const key of keys) {
1192
1207
  const nestedDreams = await this.applyOnePreload(key, dream, this.applyablePreloadOnStatements(preloadOnStatements[key]));
1193
- if (nestedDreams) {
1208
+ if (nestedDreams.length) {
1194
1209
  await this.applyPreload(preloadStatement[key], preloadOnStatements[key], nestedDreams);
1195
1210
  }
1196
1211
  }
@@ -1685,18 +1700,10 @@ class KyselyQueryDriver extends Base_js_1.default {
1685
1700
  *
1686
1701
  * Used to preload polymorphic belongs to associations
1687
1702
  */
1688
- async preloadPolymorphicBelongsTo(association, dreams) {
1689
- if (!association.polymorphic)
1690
- throw new Error(`Association ${association.as} points to an array of models but is not designated polymorphic`);
1691
- if (association.type !== 'BelongsTo')
1692
- throw new Error(`Polymorphic association ${association.as} points to an array of models but is ${association.type}. Only BelongsTo associations may point to an array of models.`);
1693
- const nestedDreamsForNextRoundOfPreloading = [];
1694
- for (const associatedModel of association.modelCB()) {
1695
- await this.preloadPolymorphicAssociationModel(dreams, association, associatedModel, nestedDreamsForNextRoundOfPreloading);
1696
- }
1697
- return nestedDreamsForNextRoundOfPreloading;
1703
+ async preloadPolymorphicBelongsTo(association, associatedModels, dreams) {
1704
+ return (0, compact_js_1.default)(await Promise.all(associatedModels.map(associatedModel => this.preloadPolymorphicAssociationModel(dreams, association, associatedModel)))).flat();
1698
1705
  }
1699
- async preloadPolymorphicAssociationModel(dreams, association, associatedDreamClass, nestedDreamsForNextRoundOfPreloading) {
1706
+ async preloadPolymorphicAssociationModel(dreams, association, associatedDreamClass) {
1700
1707
  const relevantAssociatedModels = dreams.filter((dream) => {
1701
1708
  const field = association.foreignKeyTypeField();
1702
1709
  return dream[field] === associatedDreamClass['stiBaseClassOrOwnClassName'] || dream[field] === null;
@@ -1715,7 +1722,6 @@ class KyselyQueryDriver extends Base_js_1.default {
1715
1722
  [associatedDreamClass.primaryKey]: relevantAssociatedModels.map((dream) => dream[association.foreignKey()]),
1716
1723
  })
1717
1724
  .all();
1718
- loadedAssociations.forEach((loadedAssociation) => nestedDreamsForNextRoundOfPreloading.push(loadedAssociation));
1719
1725
  //////////////////////////////////////////////////////////////////////////////////////////////
1720
1726
  // Associate each loaded association with each dream based on primary key and foreign key type
1721
1727
  //////////////////////////////////////////////////////////////////////////////////////////////
@@ -1730,6 +1736,7 @@ class KyselyQueryDriver extends Base_js_1.default {
1730
1736
  ///////////////////////////////////////////////////////////////////////////////////////////////////
1731
1737
  // end: Associate each loaded association with each dream based on primary key and foreign key type
1732
1738
  ///////////////////////////////////////////////////////////////////////////////////////////////////
1739
+ return loadedAssociations;
1733
1740
  }
1734
1741
  }
1735
1742
  /**
@@ -1768,12 +1775,18 @@ class KyselyQueryDriver extends Base_js_1.default {
1768
1775
  *
1769
1776
  * Applies a preload statement
1770
1777
  */
1771
- async applyOnePreload(associationName, dreams, onStatement = {}) {
1778
+ async applyOnePreload(associationNameAndMaybeAlias, dreams, onStatement = {}) {
1772
1779
  if (!Array.isArray(dreams))
1773
1780
  dreams = [dreams];
1774
- const dream = dreams.find(dream => dream['getAssociationMetadata'](associationName));
1775
- if (!dream)
1776
- return;
1781
+ const { name: associationName } = (0, associationStringToNameAndAlias_js_1.default)(associationNameAndMaybeAlias);
1782
+ dreams = dreams.filter(dream => dream.hasAssociation(associationName));
1783
+ const groupedDreams = (0, groupBy_js_1.default)(dreams, dream => dream.sanitizedConstructorName);
1784
+ return (await Promise.all(Object.keys(groupedDreams).map(key => this._applyOnePreload(associationName, groupedDreams[key], onStatement)))).flat();
1785
+ }
1786
+ async _applyOnePreload(associationName, dreams, onStatement = {}) {
1787
+ if (!dreams.length)
1788
+ return [];
1789
+ const dream = dreams[0];
1777
1790
  const { name, alias: _alias } = (0, associationStringToNameAndAlias_js_1.default)(associationName);
1778
1791
  const alias = _alias || name;
1779
1792
  const association = dream['getAssociationMetadata'](name);
@@ -1781,8 +1794,10 @@ class KyselyQueryDriver extends Base_js_1.default {
1781
1794
  throw new UnexpectedUndefined_js_1.default();
1782
1795
  const dreamClass = dream.constructor;
1783
1796
  const dreamClassToHydrate = association.modelCB();
1784
- if ((association.polymorphic && association.type === 'BelongsTo') || Array.isArray(dreamClassToHydrate))
1785
- return this.preloadPolymorphicBelongsTo(association, dreams);
1797
+ if (Array.isArray(dreamClassToHydrate)) {
1798
+ const preloadedPolymorphicBelongsTos = await this.preloadPolymorphicBelongsTo(association, dreamClassToHydrate, dreams);
1799
+ return preloadedPolymorphicBelongsTos;
1800
+ }
1786
1801
  const dreamClassToHydrateColumns = [...dreamClassToHydrate.columns()];
1787
1802
  const columnsToPluck = dreamClassToHydrateColumns.map(column => this.namespaceColumn(column.toString(), alias));
1788
1803
  columnsToPluck.push(this.namespaceColumn(dreamClass.primaryKey, dreamClass.table));
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = printSerializerHierarchyLevel;
4
+ const yoctocolors_1 = require("yoctocolors");
5
+ const indent_js_1 = require("../../helpers/indent.js");
6
+ function printSerializerHierarchyLevel({ serializerAssociationType, serializerAssociationName, associationSerializer, forDisplayDepth, }) {
7
+ const hierarchyLine = '└───';
8
+ const indentation = (0, indent_js_1.indent)((hierarchyLine.length + 1) * forDisplayDepth, {
9
+ tabWidth: 1,
10
+ });
11
+ const prefix = `${hierarchyLine} `;
12
+ const nestedAssociationDisplay = indentation + `${prefix}${serializerAssociationType} ${yoctocolors_1.default.cyan(serializerAssociationName)}`;
13
+ console.log(nestedAssociationDisplay);
14
+ console.log(yoctocolors_1.default.gray(indentation +
15
+ (0, indent_js_1.indent)(prefix.length, { tabWidth: 1 }) +
16
+ associationSerializer.globalName));
17
+ }
@@ -2,12 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.cacheDreamApp = cacheDreamApp;
4
4
  exports.getCachedDreamAppOrFail = getCachedDreamAppOrFail;
5
+ const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
5
6
  let _dreamApp = undefined;
6
7
  function cacheDreamApp(dreamconf) {
7
8
  _dreamApp = dreamconf;
8
9
  }
9
10
  function getCachedDreamAppOrFail() {
10
- if (!_dreamApp)
11
- throw new Error('Must call `initializeDreamApp` or `initializePsychicApp` before loading cached DreamApp.getOrFail()');
11
+ if (!_dreamApp) {
12
+ const baseErrorMessage = 'Must call `initializeDreamApp` or `initializePsychicApp` before loading cached DreamApp.getOrFail().';
13
+ if (EnvInternal_js_1.default.isTest) {
14
+ throw new Error(`${baseErrorMessage}
15
+
16
+ Check for specs running directly in a \`describe\` or \`context\` block rather than nested within an \`it\` block.`);
17
+ }
18
+ else {
19
+ throw new Error(baseErrorMessage);
20
+ }
21
+ }
12
22
  return _dreamApp;
13
23
  }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ class DataTypeColumnTypeMismatch extends Error {
4
+ dream;
5
+ error;
6
+ constructor({ dream, error }) {
7
+ super();
8
+ this.dream = dream;
9
+ this.error = error;
10
+ }
11
+ get message() {
12
+ return `\
13
+ Failed to save ${this.dream.sanitizedConstructorName}:
14
+
15
+ ${this.error.message}
16
+ `;
17
+ }
18
+ }
19
+ exports.default = DataTypeColumnTypeMismatch;
@@ -22,6 +22,7 @@ async function generateMigration({ migrationName, columnsWithTypes, fullyQualifi
22
22
  table: (0, snakeify_js_1.default)((0, pluralize_esm_1.default)((0, pascalizePath_js_1.default)(fullyQualifiedParentName))),
23
23
  columnsWithTypes,
24
24
  primaryKeyType: (0, primaryKeyType_js_1.default)(),
25
+ stiChildClassName: (0, pascalizePath_js_1.default)(fullyQualifiedModelName),
25
26
  });
26
27
  }
27
28
  else if (fullyQualifiedModelName) {
@@ -9,13 +9,17 @@ const foreignKeyTypeFromPrimaryKey_js_1 = require("../db/foreignKeyTypeFromPrima
9
9
  const snakeify_js_1 = require("../snakeify.js");
10
10
  const STI_TYPE_COLUMN_NAME = 'type';
11
11
  const COLUMNS_TO_INDEX = [STI_TYPE_COLUMN_NAME];
12
- function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType = 'bigserial', createOrAlter = 'create', } = {}) {
12
+ function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType = 'bigserial', createOrAlter = 'create', stiChildClassName, } = {}) {
13
13
  const altering = createOrAlter === 'alter';
14
14
  let requireCitextExtension = false;
15
- const { columnDefs, columnDrops, indexDefs, indexDrops } = columnsWithTypes.reduce((acc, attribute) => {
15
+ const checkConstraints = [];
16
+ const { columnDefs, columnDrops, indexDefs, indexDrops } = columnsWithTypes.reduce((acc, attributeDeclaration) => {
16
17
  const { columnDefs, columnDrops, indexDefs, indexDrops } = acc;
17
- const [nonStandardAttributeName, attributeType, ...descriptors] = attribute.split(':');
18
- const optional = optionalFromDescriptors(descriptors);
18
+ const [nonStandardAttributeName, attributeType, ...descriptors] = attributeDeclaration.split(':');
19
+ const userWantsThisOptional = optionalFromDescriptors(descriptors);
20
+ // when creating a migration for an STI child, we don't want to include notNull;
21
+ // instead, we'll add a check constraint that uses the STI child class name
22
+ const optional = userWantsThisOptional || !!stiChildClassName;
19
23
  const sqlAttributeType = getAttributeType(attributeType, descriptors);
20
24
  let attributeName = (0, snakeify_js_1.default)(nonStandardAttributeName);
21
25
  if (attributeName === undefined)
@@ -24,6 +28,17 @@ function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType
24
28
  return acc;
25
29
  if (attributeType === 'citext')
26
30
  requireCitextExtension = true;
31
+ if (stiChildClassName && !userWantsThisOptional) {
32
+ checkConstraints.push(`
33
+
34
+ await db.schema
35
+ .alterTable('${table}')
36
+ .addCheckConstraint(
37
+ '${table}_not_null_${attributeName}',
38
+ sql\`type != '${stiChildClassName}' OR ${attributeName} IS NOT NULL\`,
39
+ )
40
+ .execute()`);
41
+ }
27
42
  switch (attributeType) {
28
43
  case 'belongs_to':
29
44
  columnDefs.push(generateBelongsToStr(attributeName, {
@@ -100,7 +115,7 @@ ${citextExtension}${generateEnumStatements(columnsWithTypes)} await db.schema
100
115
  ".addColumn('created_at', 'timestamp', col => col.notNull())" +
101
116
  newlineDoubleIndent +
102
117
  ".addColumn('updated_at', 'timestamp', col => col.notNull())"}
103
- .execute()${indexDefs.length ? `\n${newlineIndent}` : ''}${indexDefs.join(newlineDoubleIndent)}
118
+ .execute()${indexDefs.length ? `\n${newlineIndent}` : ''}${indexDefs.join(newlineDoubleIndent)}${checkConstraints.join('')}
104
119
  }
105
120
 
106
121
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -2,6 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = generateStiMigrationContent;
4
4
  const generateMigrationContent_js_1 = require("./generateMigrationContent.js");
5
- function generateStiMigrationContent({ table, columnsWithTypes = [], primaryKeyType = 'bigserial', } = {}) {
6
- return (0, generateMigrationContent_js_1.default)({ table, columnsWithTypes, primaryKeyType, createOrAlter: 'alter' });
5
+ function generateStiMigrationContent({ table, columnsWithTypes = [], primaryKeyType = 'bigserial', stiChildClassName, }) {
6
+ return (0, generateMigrationContent_js_1.default)({
7
+ table,
8
+ columnsWithTypes,
9
+ primaryKeyType,
10
+ createOrAlter: 'alter',
11
+ stiChildClassName,
12
+ });
7
13
  }
@@ -40,6 +40,12 @@ function sqlAttributes(dream) {
40
40
  return result;
41
41
  }, {});
42
42
  }
43
+ /**
44
+ * Convert datetimes to UTC
45
+ */
43
46
  function valueToDatetime(val) {
44
- return typeof val === 'string' ? DateTime_js_1.DateTime.fromISO(val, { zone: 'UTC' }) : val;
47
+ if (typeof val !== 'string')
48
+ return val;
49
+ const datetime = DateTime_js_1.DateTime.fromISO(val, { zone: 'UTC' });
50
+ return datetime.isValid ? datetime : val;
45
51
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.relativeDreamPath = exports.dreamPath = exports.pascalize = exports.normalizeUnicode = exports.loadRepl = exports.isEmpty = exports.intersection = exports.hyphenize = exports.groupBy = exports.globalClassNameFromFullyQualifiedModelName = exports.Env = exports.DreamLogos = exports.DateTime = exports.compact = exports.cloneDeepSafe = exports.generateDream = exports.capitalize = exports.camelize = exports.CalendarDate = exports.Benchmark = exports.ValidationError = exports.RecordNotFound = exports.GlobalNameNotSet = exports.CreateOrFindByFailedToCreateAndFind = exports.NonLoadedAssociation = exports.Encrypt = exports.Query = exports.DreamTransaction = exports.openapiShorthandPrimitiveTypes = exports.openapiPrimitiveTypes = exports.DreamConst = exports.Dream = exports.DreamAppAllowedPackageManagersEnumValues = exports.DreamApp = exports.lookupClassByGlobalName = exports.DreamImporter = exports.Decorators = exports.STI = exports.SoftDelete = exports.ReplicaSafe = exports.validateTable = exports.validateColumn = exports.DreamMigrationHelpers = exports.untypedDb = exports.pgErrorType = exports.dreamDbConnections = exports.closeAllDbConnections = exports.DreamCLI = exports.CliFileWriter = exports.DreamBin = void 0;
4
- exports.ObjectSerializerBuilder = exports.DreamSerializerBuilder = exports.ObjectSerializer = exports.DreamSerializer = exports.serializerNameFromFullyQualifiedModelName = exports.isDreamSerializer = exports.inferSerializersFromDreamClassOrViewModelClass = exports.inferSerializerFromDreamOrViewModel = exports.ops = exports.uniq = exports.uncapitalize = exports.expandStiClasses = exports.standardizeFullyQualifiedModelName = exports.sortObjectByValue = exports.sortObjectByKey = exports.sortBy = exports.sort = exports.snakeify = exports.round = exports.range = exports.Range = exports.sharedPathPrefix = void 0;
3
+ exports.dreamPath = exports.pascalize = exports.normalizeUnicode = exports.loadRepl = exports.isEmpty = exports.intersection = exports.hyphenize = exports.groupBy = exports.globalClassNameFromFullyQualifiedModelName = exports.Env = exports.DreamLogos = exports.DateTime = exports.compact = exports.cloneDeepSafe = exports.generateDream = exports.capitalize = exports.camelize = exports.CalendarDate = exports.Benchmark = exports.ValidationError = exports.RecordNotFound = exports.GlobalNameNotSet = exports.DataTypeColumnTypeMismatch = exports.CreateOrFindByFailedToCreateAndFind = exports.NonLoadedAssociation = exports.Encrypt = exports.Query = exports.DreamTransaction = exports.openapiShorthandPrimitiveTypes = exports.openapiPrimitiveTypes = exports.DreamConst = exports.Dream = exports.DreamAppAllowedPackageManagersEnumValues = exports.DreamApp = exports.lookupClassByGlobalName = exports.DreamImporter = exports.Decorators = exports.STI = exports.SoftDelete = exports.ReplicaSafe = exports.validateTable = exports.validateColumn = exports.DreamMigrationHelpers = exports.untypedDb = exports.pgErrorType = exports.dreamDbConnections = exports.closeAllDbConnections = exports.DreamCLI = exports.CliFileWriter = exports.DreamBin = void 0;
4
+ exports.ObjectSerializerBuilder = exports.DreamSerializerBuilder = exports.ObjectSerializer = exports.DreamSerializer = exports.serializerNameFromFullyQualifiedModelName = exports.isDreamSerializer = exports.inferSerializersFromDreamClassOrViewModelClass = exports.inferSerializerFromDreamOrViewModel = exports.ops = exports.uniq = exports.uncapitalize = exports.expandStiClasses = exports.standardizeFullyQualifiedModelName = exports.sortObjectByValue = exports.sortObjectByKey = exports.sortBy = exports.sort = exports.snakeify = exports.round = exports.range = exports.Range = exports.sharedPathPrefix = exports.relativeDreamPath = void 0;
5
5
  var index_js_1 = require("./bin/index.js");
6
6
  Object.defineProperty(exports, "DreamBin", { enumerable: true, get: function () { return index_js_1.default; } });
7
7
  var CliFileWriter_js_1 = require("./cli/CliFileWriter.js");
@@ -52,6 +52,8 @@ var NonLoadedAssociation_js_1 = require("./errors/associations/NonLoadedAssociat
52
52
  Object.defineProperty(exports, "NonLoadedAssociation", { enumerable: true, get: function () { return NonLoadedAssociation_js_1.default; } });
53
53
  var CreateOrFindByFailedToCreateAndFind_js_1 = require("./errors/CreateOrFindByFailedToCreateAndFind.js");
54
54
  Object.defineProperty(exports, "CreateOrFindByFailedToCreateAndFind", { enumerable: true, get: function () { return CreateOrFindByFailedToCreateAndFind_js_1.default; } });
55
+ var DataTypeColumnTypeMismatch_js_1 = require("./errors/db/DataTypeColumnTypeMismatch.js");
56
+ Object.defineProperty(exports, "DataTypeColumnTypeMismatch", { enumerable: true, get: function () { return DataTypeColumnTypeMismatch_js_1.default; } });
55
57
  var GlobalNameNotSet_js_1 = require("./errors/dream-app/GlobalNameNotSet.js");
56
58
  Object.defineProperty(exports, "GlobalNameNotSet", { enumerable: true, get: function () { return GlobalNameNotSet_js_1.default; } });
57
59
  var RecordNotFound_js_1 = require("./errors/RecordNotFound.js");
@@ -14,7 +14,8 @@ function serializerForAssociatedClass(object, associationName, options) {
14
14
  return null;
15
15
  const dream = object;
16
16
  const association = dream['getAssociationMetadata'](associationName);
17
- const associatedClasses = association.modelCB();
18
- const associatedClass = Array.isArray(associatedClasses) ? associatedClasses[0] : associatedClasses;
17
+ const associatedClass = association.modelCB();
18
+ if (Array.isArray(associatedClass))
19
+ throw new Error('rendersOne flatten is incompatible with a polymorphic belongs-to association');
19
20
  return (0, inferSerializerFromDreamOrViewModel_js_1.inferSerializersFromDreamClassOrViewModelClass)(associatedClass, options.serializerKey)[0] ?? null;
20
21
  }