@rvoh/dream 0.31.5 → 0.32.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 (235) hide show
  1. package/dist/cjs/src/Dream.js +9 -9
  2. package/dist/cjs/src/bin/helpers/sync.js +7 -7
  3. package/dist/cjs/src/cli/logger/loggable/colorize.js +1 -1
  4. package/dist/cjs/src/db/DreamDbConnection.js +1 -1
  5. package/dist/cjs/src/decorators/field/sortable/hooks/beforeSortableSave.js +6 -3
  6. package/dist/cjs/src/dream/DreamInstanceTransactionBuilder.js +3 -3
  7. package/dist/cjs/src/dream/LeftJoinLoadBuilder.js +5 -1
  8. package/dist/cjs/src/dream/Query.js +74 -12
  9. package/dist/cjs/src/dream/internal/associations/associationUpdateQuery.js +3 -0
  10. package/dist/cjs/src/dream/internal/associations/createAssociation.js +3 -0
  11. package/dist/cjs/src/dream/internal/checkSingleValidation.js +8 -1
  12. package/dist/cjs/src/dream/internal/extractAssociationMetadataFromAssociationName.js +7 -3
  13. package/dist/cjs/src/errors/MissingTable.js +1 -1
  14. package/dist/cjs/src/errors/UnexpectedUndefined.js +14 -0
  15. package/dist/cjs/src/errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.js +17 -0
  16. package/dist/cjs/src/global-cli/helpers/argAndValue.js +4 -4
  17. package/dist/cjs/src/helpers/CalendarDate.js +1 -1
  18. package/dist/cjs/src/helpers/cli/SchemaBuilder.js +52 -17
  19. package/dist/cjs/src/helpers/cli/generateDreamContent.js +3 -1
  20. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +7 -3
  21. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +53 -21
  22. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +3 -25
  23. package/dist/cjs/src/helpers/objectPathsToArrays.js +2 -1
  24. package/dist/esm/src/Dream.js +9 -9
  25. package/dist/esm/src/bin/helpers/sync.js +4 -4
  26. package/dist/esm/src/cli/logger/loggable/colorize.js +1 -1
  27. package/dist/esm/src/db/DreamDbConnection.js +1 -1
  28. package/dist/esm/src/decorators/field/sortable/hooks/beforeSortableSave.js +6 -3
  29. package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +3 -3
  30. package/dist/esm/src/dream/LeftJoinLoadBuilder.js +5 -1
  31. package/dist/esm/src/dream/Query.js +74 -12
  32. package/dist/esm/src/dream/internal/associations/associationUpdateQuery.js +3 -0
  33. package/dist/esm/src/dream/internal/associations/createAssociation.js +3 -0
  34. package/dist/esm/src/dream/internal/checkSingleValidation.js +8 -1
  35. package/dist/esm/src/dream/internal/extractAssociationMetadataFromAssociationName.js +7 -3
  36. package/dist/esm/src/errors/MissingTable.js +1 -1
  37. package/dist/esm/src/errors/UnexpectedUndefined.js +11 -0
  38. package/dist/esm/src/errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.js +14 -0
  39. package/dist/esm/src/global-cli/dream.js +0 -0
  40. package/dist/esm/src/global-cli/helpers/argAndValue.js +4 -4
  41. package/dist/esm/src/helpers/CalendarDate.js +1 -1
  42. package/dist/esm/src/helpers/cli/SchemaBuilder.js +52 -17
  43. package/dist/esm/src/helpers/cli/generateDreamContent.js +3 -1
  44. package/dist/esm/src/helpers/cli/generateFactoryContent.js +7 -3
  45. package/dist/esm/src/helpers/cli/generateMigrationContent.js +53 -21
  46. package/dist/esm/src/helpers/cli/generateSerializerContent.js +3 -25
  47. package/dist/esm/src/helpers/objectPathsToArrays.js +2 -1
  48. package/dist/types/src/Dream.d.ts +1 -1
  49. package/dist/types/src/cli/logger/loggable/DreamCliLoggable.d.ts +3 -3
  50. package/dist/types/src/cli/logger/loggable/DreamCliLoggableText.d.ts +5 -5
  51. package/dist/types/src/cli/logger/loggable/colorize.d.ts +3 -3
  52. package/dist/types/src/db/ConnectedToDB.d.ts +3 -3
  53. package/dist/types/src/decorators/field/sortable/helpers/decrementScopedRecordsGreaterThanPosition.d.ts +1 -1
  54. package/dist/types/src/decorators/field/sortable/helpers/positionIsInvalid.d.ts +1 -1
  55. package/dist/types/src/decorators/field/sortable/helpers/setPosition.d.ts +2 -2
  56. package/dist/types/src/decorators/field/sortable/hooks/afterSortableCreate.d.ts +2 -2
  57. package/dist/types/src/decorators/field/sortable/hooks/afterSortableDestroy.d.ts +1 -1
  58. package/dist/types/src/decorators/field/sortable/hooks/afterSortableUpdate.d.ts +2 -2
  59. package/dist/types/src/decorators/field/sortable/hooks/beforeSortableSave.d.ts +1 -1
  60. package/dist/types/src/decorators/field-or-getter/Virtual.d.ts +1 -1
  61. package/dist/types/src/dream/Query.d.ts +26 -26
  62. package/dist/types/src/dream/internal/destroyOptions.d.ts +4 -4
  63. package/dist/types/src/dream/internal/similarity/SimilarityBuilder.d.ts +4 -4
  64. package/dist/types/src/errors/UnexpectedUndefined.d.ts +4 -0
  65. package/dist/types/src/errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.d.ts +7 -0
  66. package/dist/types/src/errors/associations/MissingRequiredAssociationOnClause.d.ts +1 -1
  67. package/dist/types/src/helpers/cli/generateDream.d.ts +1 -1
  68. package/dist/types/src/helpers/cli/generateDreamContent.d.ts +1 -1
  69. package/dist/types/src/helpers/cli/generateMigration.d.ts +2 -2
  70. package/dist/types/src/helpers/cli/generateMigrationContent.d.ts +4 -4
  71. package/dist/types/src/helpers/cli/generateSerializer.d.ts +1 -1
  72. package/dist/types/src/helpers/cli/generateSerializerContent.d.ts +2 -2
  73. package/dist/types/src/types/associations/shared.d.ts +1 -6
  74. package/dist/types/src/types/dream.d.ts +2 -13
  75. package/dist/types/src/types/lifecycle.d.ts +2 -2
  76. package/dist/types/src/types/logger.d.ts +3 -3
  77. package/docs/assets/icons.js +1 -1
  78. package/docs/assets/icons.svg +1 -1
  79. package/docs/assets/main.js +1 -1
  80. package/docs/assets/navigation.js +1 -1
  81. package/docs/assets/search.js +1 -1
  82. package/docs/assets/style.css +66 -21
  83. package/docs/classes/Benchmark.html +2 -2
  84. package/docs/classes/CalendarDate.html +2 -2
  85. package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +6 -5
  86. package/docs/classes/Decorators.html +19 -19
  87. package/docs/classes/Dream.html +131 -131
  88. package/docs/classes/DreamApplication.html +4 -4
  89. package/docs/classes/DreamBin.html +2 -2
  90. package/docs/classes/DreamCLI.html +4 -4
  91. package/docs/classes/DreamDbConnection.html +2 -2
  92. package/docs/classes/DreamGlam.html +2 -2
  93. package/docs/classes/DreamImporter.html +2 -2
  94. package/docs/classes/DreamMigrationHelpers.html +7 -7
  95. package/docs/classes/DreamSerializer.html +2 -2
  96. package/docs/classes/DreamTransaction.html +2 -2
  97. package/docs/classes/Encrypt.html +2 -2
  98. package/docs/classes/Env.html +2 -2
  99. package/docs/classes/GlobalNameNotSet.html +6 -5
  100. package/docs/classes/NonLoadedAssociation.html +6 -5
  101. package/docs/classes/Query.html +51 -51
  102. package/docs/classes/Range.html +2 -2
  103. package/docs/classes/RecordNotFound.html +6 -5
  104. package/docs/classes/ValidationError.html +6 -5
  105. package/docs/functions/Attribute.html +1 -1
  106. package/docs/functions/RendersMany.html +1 -1
  107. package/docs/functions/RendersOne.html +1 -1
  108. package/docs/functions/ReplicaSafe.html +1 -1
  109. package/docs/functions/STI.html +1 -1
  110. package/docs/functions/SoftDelete.html +1 -1
  111. package/docs/functions/camelize.html +1 -1
  112. package/docs/functions/capitalize.html +1 -1
  113. package/docs/functions/closeAllDbConnections.html +1 -1
  114. package/docs/functions/compact.html +1 -1
  115. package/docs/functions/db.html +1 -1
  116. package/docs/functions/debug.html +1 -1
  117. package/docs/functions/dreamDbConnections.html +1 -1
  118. package/docs/functions/dreamPath.html +1 -1
  119. package/docs/functions/generateDream.html +1 -1
  120. package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
  121. package/docs/functions/hyphenize.html +1 -1
  122. package/docs/functions/inferSerializerFromDreamClassOrViewModelClass.html +1 -1
  123. package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
  124. package/docs/functions/isEmpty.html +1 -1
  125. package/docs/functions/loadRepl.html +1 -1
  126. package/docs/functions/lookupClassByGlobalName.html +1 -1
  127. package/docs/functions/pascalize.html +1 -1
  128. package/docs/functions/pgErrorType.html +1 -1
  129. package/docs/functions/range-1.html +1 -1
  130. package/docs/functions/relativeDreamPath.html +1 -1
  131. package/docs/functions/round.html +1 -1
  132. package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
  133. package/docs/functions/sharedPathPrefix.html +1 -1
  134. package/docs/functions/snakeify.html +1 -1
  135. package/docs/functions/sort.html +1 -1
  136. package/docs/functions/sortBy.html +1 -1
  137. package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
  138. package/docs/functions/uncapitalize.html +1 -1
  139. package/docs/functions/uniq.html +1 -1
  140. package/docs/functions/validateColumn.html +1 -1
  141. package/docs/functions/validateTable.html +1 -1
  142. package/docs/index.html +7 -7
  143. package/docs/interfaces/AttributeStatement.html +2 -2
  144. package/docs/interfaces/DecoratorContext.html +2 -2
  145. package/docs/interfaces/DreamApplicationInitOptions.html +2 -2
  146. package/docs/interfaces/DreamApplicationOpts.html +2 -2
  147. package/docs/interfaces/DreamSerializerAssociationStatement.html +2 -2
  148. package/docs/interfaces/EncryptOptions.html +2 -2
  149. package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
  150. package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
  151. package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
  152. package/docs/modules.html +8 -8
  153. package/docs/types/Camelized.html +1 -1
  154. package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
  155. package/docs/types/DateTime.html +1 -1
  156. package/docs/types/DreamAssociationMetadata.html +1 -1
  157. package/docs/types/DreamAttributes.html +1 -1
  158. package/docs/types/DreamClassColumn.html +1 -1
  159. package/docs/types/DreamColumn.html +1 -1
  160. package/docs/types/DreamColumnNames.html +1 -1
  161. package/docs/types/DreamLogLevel.html +1 -1
  162. package/docs/types/DreamLogger.html +1 -1
  163. package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
  164. package/docs/types/DreamParamSafeAttributes.html +1 -1
  165. package/docs/types/DreamParamSafeColumnNames.html +1 -1
  166. package/docs/types/DreamSerializerKey.html +1 -1
  167. package/docs/types/DreamSerializers.html +1 -1
  168. package/docs/types/DreamTableSchema.html +1 -1
  169. package/docs/types/DreamVirtualColumns.html +1 -1
  170. package/docs/types/EncryptAlgorithm.html +1 -1
  171. package/docs/types/Hyphenized.html +1 -1
  172. package/docs/types/IdType.html +1 -1
  173. package/docs/types/OpenapiAllTypes.html +1 -1
  174. package/docs/types/OpenapiFormats.html +1 -1
  175. package/docs/types/OpenapiNumberFormats.html +1 -1
  176. package/docs/types/OpenapiPrimitiveTypes.html +1 -1
  177. package/docs/types/OpenapiSchemaArray.html +1 -1
  178. package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
  179. package/docs/types/OpenapiSchemaBase.html +1 -1
  180. package/docs/types/OpenapiSchemaBody.html +1 -1
  181. package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
  182. package/docs/types/OpenapiSchemaCommonFields.html +1 -1
  183. package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
  184. package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
  185. package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
  186. package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
  187. package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  188. package/docs/types/OpenapiSchemaInteger.html +1 -1
  189. package/docs/types/OpenapiSchemaNull.html +1 -1
  190. package/docs/types/OpenapiSchemaNumber.html +1 -1
  191. package/docs/types/OpenapiSchemaObject.html +1 -1
  192. package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
  193. package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
  194. package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
  195. package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  196. package/docs/types/OpenapiSchemaObjectBase.html +1 -1
  197. package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
  198. package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
  199. package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
  200. package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
  201. package/docs/types/OpenapiSchemaPartialSegment.html +1 -1
  202. package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
  203. package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  204. package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  205. package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  206. package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  207. package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  208. package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  209. package/docs/types/OpenapiSchemaString.html +1 -1
  210. package/docs/types/OpenapiShorthandAllTypes.html +1 -1
  211. package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
  212. package/docs/types/OpenapiTypeField.html +1 -1
  213. package/docs/types/Pascalized.html +1 -1
  214. package/docs/types/PrimaryKeyType.html +1 -1
  215. package/docs/types/RoundingPrecision.html +1 -1
  216. package/docs/types/SerializableClassOrSerializerCallback.html +1 -1
  217. package/docs/types/SerializableDreamClassOrViewModelClass.html +1 -1
  218. package/docs/types/SerializableDreamOrViewModel.html +1 -1
  219. package/docs/types/SerializableTypes.html +1 -1
  220. package/docs/types/Snakeified.html +1 -1
  221. package/docs/types/Timestamp.html +1 -1
  222. package/docs/types/UpdateableAssociationProperties.html +1 -1
  223. package/docs/types/UpdateableProperties.html +1 -1
  224. package/docs/types/ValidationType.html +1 -1
  225. package/docs/types/ViewModelSerializerKey.html +1 -1
  226. package/docs/types/WhereStatementForDream.html +1 -1
  227. package/docs/types/WhereStatementForDreamClass.html +1 -1
  228. package/docs/variables/DateTime-1.html +1 -1
  229. package/docs/variables/DreamConst.html +1 -1
  230. package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
  231. package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
  232. package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
  233. package/docs/variables/ops.html +1 -1
  234. package/docs/variables/primaryKeyTypes.html +1 -1
  235. package/package.json +2 -2
@@ -3,6 +3,7 @@ import pluralize from 'pluralize-esm';
3
3
  import ConnectedToDB from '../db/ConnectedToDB.js';
4
4
  import { SOFT_DELETE_SCOPE_NAME } from '../decorators/class/SoftDelete.js';
5
5
  import associationToGetterSetterProp from '../decorators/field/association/associationToGetterSetterProp.js';
6
+ import AssociationDeclaredWithoutAssociatedDreamClass from '../errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.js';
6
7
  import CannotAssociateThroughPolymorphic from '../errors/associations/CannotAssociateThroughPolymorphic.js';
7
8
  import CannotJoinPolymorphicBelongsToError from '../errors/associations/CannotJoinPolymorphicBelongsToError.js';
8
9
  import JoinAttemptedOnMissingAssociation from '../errors/associations/JoinAttemptedOnMissingAssociation.js';
@@ -19,6 +20,7 @@ import MissingRequiredCallbackFunctionToPluckEach from '../errors/MissingRequire
19
20
  import NoUpdateAllOnJoins from '../errors/NoUpdateAllOnJoins.js';
20
21
  import NoUpdateOnAssociationQuery from '../errors/NoUpdateOnAssociationQuery.js';
21
22
  import RecordNotFound from '../errors/RecordNotFound.js';
23
+ import UnexpectedUndefined from '../errors/UnexpectedUndefined.js';
22
24
  import CalendarDate from '../helpers/CalendarDate.js';
23
25
  import camelize from '../helpers/camelize.js';
24
26
  import cloneDeepSafe from '../helpers/cloneDeepSafe.js';
@@ -573,7 +575,10 @@ export default class Query extends ConnectedToDB {
573
575
  associationNamesToDreamClassesMap(associationNames, associationsToDreamClassesMap = {}) {
574
576
  const namesToAssociationsAndDreamClasses = this.associationNamesToAssociationDataAndDreamClassesMap(associationNames);
575
577
  return Object.keys(namesToAssociationsAndDreamClasses).reduce((remap, associationName) => {
576
- remap[associationName] = namesToAssociationsAndDreamClasses[associationName].dreamClass;
578
+ const associationAndDreamClass = namesToAssociationsAndDreamClasses[associationName];
579
+ if (associationAndDreamClass === undefined)
580
+ throw new UnexpectedUndefined();
581
+ remap[associationName] = associationAndDreamClass.dreamClass;
577
582
  return remap;
578
583
  }, associationsToDreamClassesMap);
579
584
  }
@@ -585,7 +590,10 @@ export default class Query extends ConnectedToDB {
585
590
  associationNamesToAssociationsMap(associationNames, associationsToAssociations = {}) {
586
591
  const namesToAssociationsAndDreamClasses = this.associationNamesToAssociationDataAndDreamClassesMap(associationNames);
587
592
  return Object.keys(namesToAssociationsAndDreamClasses).reduce((remap, associationName) => {
588
- remap[associationName] = namesToAssociationsAndDreamClasses[associationName].association;
593
+ const associationAndDreamClass = namesToAssociationsAndDreamClasses[associationName];
594
+ if (associationAndDreamClass === undefined)
595
+ throw new UnexpectedUndefined();
596
+ remap[associationName] = associationAndDreamClass.association;
589
597
  return remap;
590
598
  }, associationsToAssociations);
591
599
  }
@@ -597,6 +605,8 @@ export default class Query extends ConnectedToDB {
597
605
  associationNames.reduce((dreamClass, associationName) => {
598
606
  const { name, alias } = extractAssociationMetadataFromAssociationName(associationName);
599
607
  const association = dreamClass['getAssociationMetadata'](name);
608
+ if (association === undefined)
609
+ throw new UnexpectedUndefined();
600
610
  const through = association.through;
601
611
  if (through) {
602
612
  const { throughAssociation, throughAssociationDreamClass } = this.throughAssociationDetails(dreamClass, through);
@@ -606,6 +616,8 @@ export default class Query extends ConnectedToDB {
606
616
  };
607
617
  }
608
618
  const nextDreamClass = association.modelCB();
619
+ if (alias === undefined)
620
+ throw new UnexpectedUndefined();
609
621
  associationsToDreamClassesMap[alias] = { association, dreamClass: nextDreamClass };
610
622
  return nextDreamClass;
611
623
  }, this.dreamClass);
@@ -616,6 +628,8 @@ export default class Query extends ConnectedToDB {
616
628
  */
617
629
  throughAssociationDetails(dreamClass, through) {
618
630
  const throughAssociation = dreamClass['getAssociationMetadata'](through);
631
+ if (throughAssociation === undefined)
632
+ throw new UnexpectedUndefined();
619
633
  const throughAssociationDreamClass = throughAssociation.modelCB();
620
634
  return { throughAssociation, throughAssociationDreamClass };
621
635
  }
@@ -654,7 +668,10 @@ export default class Query extends ConnectedToDB {
654
668
  this.addThroughAssociatedDreamClassToInnerJoinDreamClasses(previousDreamClass, association, innerJoinDreamClasses);
655
669
  const dreamClasses = [association.modelCB()].flat();
656
670
  dreamClasses.forEach(dreamClass => innerJoinDreamClasses.push(dreamClass));
657
- return dreamClasses[0];
671
+ const dreamClass = dreamClasses[0];
672
+ if (dreamClass === undefined)
673
+ throw new AssociationDeclaredWithoutAssociatedDreamClass(previousDreamClass, association.as);
674
+ return dreamClass;
658
675
  }
659
676
  addThroughAssociatedDreamClassToInnerJoinDreamClasses(dreamClass, _association, innerJoinDreamClasses) {
660
677
  const association = _association;
@@ -665,6 +682,8 @@ export default class Query extends ConnectedToDB {
665
682
  if (!throughAssociation)
666
683
  return;
667
684
  const throughDreamClass = [throughAssociation.modelCB()].flat()[0];
685
+ if (throughDreamClass === undefined)
686
+ throw new AssociationDeclaredWithoutAssociatedDreamClass(dreamClass, throughAssociation.as);
668
687
  innerJoinDreamClasses.push(throughDreamClass);
669
688
  this.addThroughAssociatedDreamClassToInnerJoinDreamClasses(dreamClass, throughAssociation, innerJoinDreamClasses);
670
689
  }
@@ -1123,8 +1142,12 @@ export default class Query extends ConnectedToDB {
1123
1142
  let nextColumnAliasCounter = 0;
1124
1143
  aliases.forEach((aliasOrExpression) => {
1125
1144
  const alias = extractAssociationMetadataFromAssociationName(aliasOrExpression).alias;
1145
+ if (alias === undefined)
1146
+ throw new UnexpectedUndefined();
1126
1147
  associationAliasToColumnAliasMap[alias] ||= {};
1127
1148
  const aliasedDreamClass = aliasToDreamClassesMap[alias];
1149
+ if (aliasedDreamClass === undefined)
1150
+ throw new UnexpectedUndefined();
1128
1151
  const association = aliasToAssociationsMap[alias];
1129
1152
  const columns = alias === this.baseSqlAlias
1130
1153
  ? options.columns
@@ -1134,12 +1157,18 @@ export default class Query extends ConnectedToDB {
1134
1157
  columns.forEach((column) => {
1135
1158
  const columnAlias = `dr${nextColumnAliasCounter++}`;
1136
1159
  kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(column, alias)} as ${columnAlias}`);
1137
- associationAliasToColumnAliasMap[alias][column] = columnAlias;
1160
+ const columnAliasMap = associationAliasToColumnAliasMap[alias];
1161
+ if (columnAliasMap === undefined)
1162
+ throw new UnexpectedUndefined();
1163
+ columnAliasMap[column] = columnAlias;
1138
1164
  });
1139
1165
  if (association?.type === 'HasOne' || association?.type === 'HasMany') {
1140
1166
  const setupPreloadData = (dbColumnName) => {
1141
1167
  const columnAlias = `dr${nextColumnAliasCounter++}`;
1142
- associationAliasToColumnAliasMap[association.through][dbColumnName] = columnAlias;
1168
+ const columnAliasMap = associationAliasToColumnAliasMap[association.through];
1169
+ if (columnAliasMap === undefined)
1170
+ throw new UnexpectedUndefined();
1171
+ columnAliasMap[dbColumnName] = columnAlias;
1143
1172
  kyselyQuery = kyselyQuery.select(`${this.namespaceColumn(dbColumnName, association.through)} as ${columnAlias}`);
1144
1173
  };
1145
1174
  if (association.through && association.preloadThroughColumns) {
@@ -1172,20 +1201,35 @@ export default class Query extends ConnectedToDB {
1172
1201
  }
1173
1202
  fleshOutJoinLoadExecutionResults({ currentAlias, singleSqlResult, aliasToDreamIdMap, associationAliasToColumnAliasMap, aliasToAssociationsMap, aliasToDreamClassesMap, leftJoinStatements, }) {
1174
1203
  const dreamClass = aliasToDreamClassesMap[currentAlias];
1204
+ if (dreamClass === undefined)
1205
+ throw new UnexpectedUndefined();
1175
1206
  const columnToColumnAliasMap = associationAliasToColumnAliasMap[currentAlias];
1176
- const primaryKeyValue = singleSqlResult[columnToColumnAliasMap[dreamClass.primaryKey]];
1207
+ if (columnToColumnAliasMap === undefined)
1208
+ throw new UnexpectedUndefined();
1209
+ const primaryKeyName = dreamClass.primaryKey;
1210
+ if (primaryKeyName === undefined)
1211
+ throw new UnexpectedUndefined();
1212
+ const columnAlias = columnToColumnAliasMap[primaryKeyName];
1213
+ if (columnAlias === undefined)
1214
+ throw new UnexpectedUndefined();
1215
+ const primaryKeyValue = singleSqlResult[columnAlias];
1177
1216
  if (!primaryKeyValue)
1178
1217
  return null;
1179
1218
  aliasToDreamIdMap[currentAlias] ||= new Map();
1180
1219
  if (!aliasToDreamIdMap[currentAlias].get(primaryKeyValue)) {
1181
1220
  const columnValueMap = Object.keys(columnToColumnAliasMap).reduce((columnNameValueMap, columnName) => {
1182
- columnNameValueMap[columnName] = singleSqlResult[columnToColumnAliasMap[columnName]];
1221
+ const columnAlias = columnToColumnAliasMap[columnName];
1222
+ if (columnAlias === undefined)
1223
+ throw new UnexpectedUndefined();
1224
+ columnNameValueMap[columnName] = singleSqlResult[columnAlias];
1183
1225
  return columnNameValueMap;
1184
1226
  }, {});
1185
1227
  const dream = sqlResultToDreamInstance(dreamClass, columnValueMap);
1186
1228
  const association = aliasToAssociationsMap[currentAlias];
1187
1229
  if (association && association.through && association.preloadThroughColumns) {
1188
1230
  const throughAssociationColumnToColumnAliasMap = associationAliasToColumnAliasMap[association.through];
1231
+ if (throughAssociationColumnToColumnAliasMap === undefined)
1232
+ throw new UnexpectedUndefined();
1189
1233
  this.hydratePreloadedThroughColumns({
1190
1234
  association,
1191
1235
  columnToColumnAliasMap: throughAssociationColumnToColumnAliasMap,
@@ -1193,12 +1237,14 @@ export default class Query extends ConnectedToDB {
1193
1237
  singleSqlResult,
1194
1238
  });
1195
1239
  }
1196
- aliasToDreamIdMap[protectAgainstPollutingAssignment(currentAlias)].set(primaryKeyValue, dream);
1240
+ aliasToDreamIdMap[protectAgainstPollutingAssignment(currentAlias)]?.set(primaryKeyValue, dream);
1197
1241
  }
1198
1242
  const dream = aliasToDreamIdMap[currentAlias].get(primaryKeyValue);
1199
1243
  Object.keys(leftJoinStatements).forEach(nextAlias => {
1200
1244
  const { name: associationName, alias } = extractAssociationMetadataFromAssociationName(nextAlias);
1201
1245
  const association = dreamClass['getAssociationMetadata'](associationName);
1246
+ if (association === undefined)
1247
+ throw new UnexpectedUndefined();
1202
1248
  const associatedDream = this.fleshOutJoinLoadExecutionResults({
1203
1249
  currentAlias: alias,
1204
1250
  singleSqlResult,
@@ -1251,8 +1297,17 @@ export default class Query extends ConnectedToDB {
1251
1297
  return columnName;
1252
1298
  });
1253
1299
  }
1254
- columnNames.forEach(columnName => (dream.preloadedThroughColumns[columnNameToPreloadedThroughColumnNameMap[columnName]] =
1255
- singleSqlResult[columnToColumnAliasMap[columnName]]));
1300
+ columnNames.forEach(columnName => {
1301
+ const preloadedThroughColumnName = columnNameToPreloadedThroughColumnNameMap[columnName];
1302
+ if (preloadedThroughColumnName === undefined)
1303
+ throw new UnexpectedUndefined();
1304
+ const columnAlias = columnToColumnAliasMap[columnName];
1305
+ if (columnAlias === undefined) {
1306
+ throw new UnexpectedUndefined();
1307
+ }
1308
+ ;
1309
+ dream.preloadedThroughColumns[preloadedThroughColumnName] = singleSqlResult[columnAlias];
1310
+ });
1256
1311
  }
1257
1312
  /**
1258
1313
  * Plucks the provided fields from the given dream class table
@@ -1805,6 +1860,8 @@ export default class Query extends ConnectedToDB {
1805
1860
  return;
1806
1861
  const { name, alias } = extractAssociationMetadataFromAssociationName(associationName);
1807
1862
  const association = dream['getAssociationMetadata'](name);
1863
+ if (association === undefined)
1864
+ throw new UnexpectedUndefined();
1808
1865
  const dreamClass = dream.constructor;
1809
1866
  const dreamClassToHydrate = association.modelCB();
1810
1867
  if ((association.polymorphic && association.type === 'BelongsTo') || Array.isArray(dreamClassToHydrate))
@@ -1894,6 +1951,8 @@ export default class Query extends ConnectedToDB {
1894
1951
  return undefined;
1895
1952
  return Object.keys(preloadOnStatements).reduce((agg, key) => {
1896
1953
  const value = preloadOnStatements[key];
1954
+ if (value === undefined)
1955
+ throw new UnexpectedUndefined();
1897
1956
  // filter out plain objects, but not ops and not on/notOn/onAny statements
1898
1957
  // because plain objects are just the next level of nested preload
1899
1958
  if (key === 'on' ||
@@ -2009,7 +2068,7 @@ export default class Query extends ConnectedToDB {
2009
2068
  query = results.query;
2010
2069
  dreamClass = results.dreamClass;
2011
2070
  association = results.association;
2012
- const timeToApplyThroughAssociations = throughAssociations.length && throughAssociations[0].source === association.as;
2071
+ const timeToApplyThroughAssociations = throughAssociations.length && throughAssociations[0]?.source === association.as;
2013
2072
  const originalPreviousAssociationTableOrAlias = previousAssociationTableOrAlias;
2014
2073
  previousAssociationTableOrAlias = results.previousAssociationTableOrAlias;
2015
2074
  const throughClass = results.throughClass;
@@ -2501,7 +2560,10 @@ export default class Query extends ConnectedToDB {
2501
2560
  checkForQueryViolations() {
2502
2561
  const invalidWhereNotClauses = this.similarityStatementBuilder().whereNotStatementsWithSimilarityClauses();
2503
2562
  if (invalidWhereNotClauses.length) {
2504
- const { tableName, columnName, opsStatement } = invalidWhereNotClauses[0];
2563
+ const invalidWhereNotClause = invalidWhereNotClauses[0];
2564
+ if (invalidWhereNotClause === undefined)
2565
+ throw new UnexpectedUndefined();
2566
+ const { tableName, columnName, opsStatement } = invalidWhereNotClause;
2505
2567
  throw new CannotNegateSimilarityClause(tableName, columnName, opsStatement.value);
2506
2568
  }
2507
2569
  }
@@ -1,7 +1,10 @@
1
+ import UnexpectedUndefined from '../../../errors/UnexpectedUndefined.js';
1
2
  import namespaceColumn from '../../../helpers/namespaceColumn.js';
2
3
  import applyScopeBypassingSettingsToQuery from '../applyScopeBypassingSettingsToQuery.js';
3
4
  export default function associationUpdateQuery(dream, txn = null, associationName, { joinOnStatements, bypassAllDefaultScopes, defaultScopesToBypass, }) {
4
5
  const association = dream['associationMetadataMap']()[associationName];
6
+ if (association === undefined)
7
+ throw new UnexpectedUndefined();
5
8
  const associationClass = association.modelCB();
6
9
  if (Array.isArray(associationClass)) {
7
10
  throw new Error('Cannot update a polymorphic association using associationUpdateQuery');
@@ -1,6 +1,9 @@
1
1
  import CannotCreateAssociationWithThroughContext from '../../../errors/associations/CannotCreateAssociationWithThroughContext.js';
2
+ import UnexpectedUndefined from '../../../errors/UnexpectedUndefined.js';
2
3
  export default async function createAssociation(dream, txn = null, associationName, opts = {}) {
3
4
  const association = dream['associationMetadataMap']()[associationName];
5
+ if (association === undefined)
6
+ throw new UnexpectedUndefined();
4
7
  if (Array.isArray(association.modelCB())) {
5
8
  throw new Error(`
6
9
  Cannot create polymorphic associations using createAssociation
@@ -1,4 +1,5 @@
1
1
  import NonLoadedAssociation from '../../errors/associations/NonLoadedAssociation.js';
2
+ import UnexpectedUndefined from '../../errors/UnexpectedUndefined.js';
2
3
  export default function checkSingleValidation(dream, validation) {
3
4
  let value;
4
5
  try {
@@ -9,6 +10,8 @@ export default function checkSingleValidation(dream, validation) {
9
10
  throw error;
10
11
  }
11
12
  let parsedFloat;
13
+ let metadataMap;
14
+ let associationMetadata;
12
15
  switch (validation.type) {
13
16
  case 'presence':
14
17
  return !isBlank(value);
@@ -39,7 +42,11 @@ export default function checkSingleValidation(dream, validation) {
39
42
  validation.options.length.max &&
40
43
  value.length <= validation.options.length.max);
41
44
  case 'requiredBelongsTo':
42
- return !!(value || dream[dream['associationMetadataMap']()[validation.column].foreignKey()]);
45
+ metadataMap = dream['associationMetadataMap']();
46
+ associationMetadata = metadataMap[validation.column];
47
+ if (associationMetadata === undefined)
48
+ throw new UnexpectedUndefined();
49
+ return !!(value || dream[associationMetadata.foreignKey()]);
43
50
  default:
44
51
  throw new Error(`Unhandled validation type found while running validations: ${validation.type}`);
45
52
  }
@@ -1,5 +1,9 @@
1
1
  export default function extractAssociationMetadataFromAssociationName(associationName) {
2
- const name = / as /.test(associationName) ? associationName.split(/ as /)[0] : associationName;
3
- const alias = / as /.test(associationName) ? associationName.split(/ as /)[1] : associationName;
4
- return { name, alias };
2
+ if (/ as /.test(associationName)) {
3
+ const [name, alias] = associationName.split(/ as /);
4
+ return { name: name ?? associationName, alias: alias ?? associationName };
5
+ }
6
+ else {
7
+ return { name: associationName, alias: associationName };
8
+ }
5
9
  }
@@ -15,7 +15,7 @@ Try something like this in your ${this.dreamClass.sanitizedName}'s table getter:
15
15
 
16
16
  class ${this.dreamClass.sanitizedName} {
17
17
  ...
18
- public get table() {
18
+ public override get table() {
19
19
  return '${pluralize(snakeify(this.dreamClass.sanitizedName))}'
20
20
  }
21
21
  }
@@ -0,0 +1,11 @@
1
+ export default class UnexpectedUndefined extends Error {
2
+ constructor() {
3
+ super();
4
+ }
5
+ get message() {
6
+ return `Undefined detected where it should never happen since we are iterating
7
+ over keys of an internal object that should not have undefined values.
8
+
9
+ This was added as part of activating noUncheckedIndexedAccess in tsconfig.`;
10
+ }
11
+ }
@@ -0,0 +1,14 @@
1
+ export default class AssociationDeclaredWithoutAssociatedDreamClass extends Error {
2
+ dreamClass;
3
+ associationName;
4
+ constructor(dreamClass, associationName) {
5
+ super();
6
+ this.dreamClass = dreamClass;
7
+ this.associationName = associationName;
8
+ }
9
+ get message() {
10
+ return `Association ${String(this.associationName)} on Dream class
11
+ ${this.dreamClass.sanitizedName} was declared without the global name
12
+ of a Dream class.`;
13
+ }
14
+ }
File without changes
@@ -2,11 +2,11 @@ export default function argAndValue(arg, args) {
2
2
  const argIndex = args.findIndex(a => a === arg);
3
3
  const foundArg = argIndex === -1 ? null : args[argIndex];
4
4
  const foundValue = argIndex === -1 ? null : valueOrNull(argIndex, args);
5
- return [foundArg, foundValue];
5
+ return [foundArg ?? null, foundValue];
6
6
  }
7
7
  function valueOrNull(argIndex, args) {
8
- let value = args[argIndex + 1];
9
- if (/--/.test(value))
10
- value = null;
8
+ const value = args[argIndex + 1];
9
+ if (value === undefined || /--/.test(value))
10
+ return null;
11
11
  return value;
12
12
  }
@@ -18,7 +18,7 @@ export default class CalendarDate {
18
18
  return new CalendarDate(dateTime);
19
19
  }
20
20
  static fromJSDate(javascriptDate, { zone } = {}) {
21
- return new CalendarDate(DateTime.fromJSDate(javascriptDate, { zone }));
21
+ return new CalendarDate(DateTime.fromJSDate(javascriptDate, zone ? { zone } : undefined));
22
22
  }
23
23
  static newInvalidDate() {
24
24
  return new CalendarDate(null);
@@ -8,6 +8,7 @@ import { DreamConst } from '../../dream/constants.js';
8
8
  import FailedToIdentifyAssociation from '../../errors/schema-builder/FailedToIdentifyAssociation.js';
9
9
  import autogeneratedFileDisclaimer from '../../global-cli/helpers/autogeneratedFileMessage.js';
10
10
  import camelize from '../camelize.js';
11
+ import compact from '../compact.js';
11
12
  import EnvInternal from '../EnvInternal.js';
12
13
  import pascalize from '../pascalize.js';
13
14
  import sortBy from '../sortBy.js';
@@ -50,9 +51,10 @@ export const globalSchema = {
50
51
  }
51
52
  globalModelNames() {
52
53
  const dreamApp = DreamApplication.getOrFail();
54
+ const models = dreamApp.models;
53
55
  return `{
54
- ${Object.keys(dreamApp.models)
55
- .map(key => `'${key}': '${dreamApp.models[key].prototype.table}'`)
56
+ ${Object.keys(models)
57
+ .map(key => `'${key}': '${models[key]?.prototype?.table}'`)
56
58
  .join(',\n ')}
57
59
  }`;
58
60
  }
@@ -66,9 +68,14 @@ export const schema = {
66
68
  ${Object.keys(schemaData)
67
69
  .map(tableName => {
68
70
  const tableData = schemaData[tableName];
71
+ if (tableData === undefined)
72
+ return '';
69
73
  const defaultScopeNames = tableData.scopes.default;
70
74
  const namedScopeNames = tableData.scopes.named;
71
75
  allDefaultScopeNames = [...allDefaultScopeNames, ...defaultScopeNames];
76
+ const schemaDatum = schemaData[tableName];
77
+ if (schemaDatum === undefined)
78
+ return '';
72
79
  return `\
73
80
  ${tableName}: {
74
81
  primaryKey: '${tableData.primaryKey}',
@@ -81,11 +88,15 @@ ${tableName}: {
81
88
  named: ${stringifyArray(namedScopeNames)},
82
89
  },
83
90
  columns: {
84
- ${Object.keys(schemaData[tableName].columns)
91
+ ${Object.keys(schemaDatum.columns)
85
92
  .sort()
86
93
  .map(columnName => {
87
94
  const columnData = tableData.columns[columnName];
95
+ if (columnData === undefined)
96
+ return '';
88
97
  const kyselyType = this.kyselyType(tableName, columnName, fileContents);
98
+ if (kyselyType === undefined)
99
+ return '';
89
100
  return `${columnName}: {
90
101
  coercedType: {} as ${this.coercedType(kyselyType, columnData.dbType)},
91
102
  enumType: ${columnData.enumType ? `{} as ${columnData.enumType}` : 'null'},
@@ -98,12 +109,14 @@ ${tableName}: {
98
109
  })
99
110
  .join('\n ')}
100
111
  },
101
- virtualColumns: ${stringifyArray(schemaData[tableName].virtualColumns)},
112
+ virtualColumns: ${stringifyArray(schemaDatum.virtualColumns)},
102
113
  associations: {
103
- ${Object.keys(schemaData[tableName].associations)
114
+ ${Object.keys(schemaDatum.associations)
104
115
  .sort()
105
116
  .map(associationName => {
106
117
  const associationMetadata = tableData.associations[associationName];
118
+ if (associationMetadata === undefined)
119
+ return '';
107
120
  const whereStatement = associationMetadata.where;
108
121
  const requiredOnClauses = whereStatement === null
109
122
  ? []
@@ -204,6 +217,8 @@ may need to update the table getter in the corresponding Dream.
204
217
  return Object.keys(columnData)
205
218
  .sort()
206
219
  .reduce((acc, key) => {
220
+ if (columnData[key] === undefined)
221
+ return acc;
207
222
  acc[key] = columnData[key];
208
223
  return acc;
209
224
  }, {});
@@ -233,6 +248,8 @@ may need to update the table getter in the corresponding Dream.
233
248
  for (const model of models.filter(model => model.table === tableName)) {
234
249
  for (const associationName of model.associationNames) {
235
250
  const associationMetaData = model['associationMetadataMap']()[associationName];
251
+ if (associationMetaData === undefined)
252
+ continue;
236
253
  if (targetAssociationType && associationMetaData.type !== targetAssociationType)
237
254
  continue;
238
255
  const dreamClassOrClasses = associationMetaData.modelCB();
@@ -284,6 +301,8 @@ may need to update the table getter in the corresponding Dream.
284
301
  return Object.keys(tableAssociationData)
285
302
  .sort()
286
303
  .reduce((acc, key) => {
304
+ if (tableAssociationData[key] === undefined)
305
+ return acc;
287
306
  acc[key] = tableAssociationData[key];
288
307
  return acc;
289
308
  }, {});
@@ -293,33 +312,49 @@ may need to update the table getter in the corresponding Dream.
293
312
  const exportedConsts = [...fileContents.matchAll(/export\s+const\s+([a-zA-Z0-9_]+)/g)].map(res => res[1]);
294
313
  const exportedTypes = [...fileContents.matchAll(/export\s+type\s+([a-zA-Z0-9_]+)/g)].map(res => res[1]);
295
314
  const exportedInterfaces = [...fileContents.matchAll(/export\s+interface\s+([a-zA-Z0-9_]+)/g)].map(res => res[1]);
296
- const allExports = [...exportedConsts, ...exportedTypes, ...exportedInterfaces];
315
+ const allExports = compact([...exportedConsts, ...exportedTypes, ...exportedInterfaces]);
297
316
  return allExports;
298
317
  }
299
318
  async getTables() {
300
319
  const fileContents = await this.loadDbSyncFile();
301
320
  const tableLines = /export interface DB {([^}]*)}/.exec(fileContents)[1];
321
+ if (tableLines === undefined)
322
+ return [];
302
323
  const tables = tableLines
303
324
  .split('\n')
304
- .map(line => line.split(':')[0].replace(/\s*/, ''))
325
+ .map(line => {
326
+ const stingArray = line.split(':');
327
+ const substring = stingArray[0];
328
+ if (substring === undefined)
329
+ return '';
330
+ return substring.replace(/\s*/, '');
331
+ })
305
332
  .filter(line => !!line);
306
333
  return tables;
307
334
  }
308
335
  kyselyType(tableName, columnName, fileContents) {
309
- const tableLines = /export interface DB {([^}]*)}/.exec(fileContents)[1];
310
- const interfaceName = tableLines
336
+ const tableLinesString = /export interface DB {([^}]*)}/.exec(fileContents)[1];
337
+ if (tableLinesString === undefined)
338
+ return '';
339
+ const tableLines = tableLinesString
311
340
  .split('\n')
312
341
  .filter(line => !!line)
313
- .filter(line => new RegExp(`^ ${tableName}:`).test(line))[0]
314
- .split(':')[1]
315
- ?.replace(/[\s;]*/g, '');
316
- const interfaceLines = new RegExp(`export interface ${interfaceName} {([^}]*)}`).exec(fileContents)[1];
317
- const kyselyType = interfaceLines
342
+ .filter(line => new RegExp(`^ ${tableName}:`).test(line));
343
+ const tableLine = tableLines[0];
344
+ if (tableLine === undefined)
345
+ return '';
346
+ const interfaceName = tableLine.split(':')[1]?.replace(/[\s;]*/g, '');
347
+ const interfaceLinesString = new RegExp(`export interface ${interfaceName} {([^}]*)}`).exec(fileContents)[1];
348
+ if (interfaceLinesString === undefined)
349
+ return '';
350
+ const interfaceLines = interfaceLinesString
318
351
  .split('\n')
319
352
  .filter(line => !!line)
320
- .filter(line => new RegExp(` ${columnName}:`).test(line))[0]
321
- .split(':')[1]
322
- ?.replace(/[\s;]*/g, '');
353
+ .filter(line => new RegExp(` ${columnName}:`).test(line));
354
+ const interfaceLine = interfaceLines[0];
355
+ if (interfaceLine === undefined)
356
+ return '';
357
+ const kyselyType = interfaceLine.split(':')[1]?.replace(/[\s;]*/g, '');
323
358
  return kyselyType;
324
359
  }
325
360
  coercedType(kyselyType, dbType) {
@@ -25,6 +25,8 @@ export default function generateDreamContent({ fullyQualifiedModelName, columnsW
25
25
  : [importStatementForModel(fullyQualifiedModelName, 'ApplicationModel')];
26
26
  const attributeStatements = columnsWithTypes.map(attribute => {
27
27
  const [attributeName, attributeType, ...descriptors] = attribute.split(':');
28
+ if (attributeName === undefined)
29
+ return '';
28
30
  const fullyQualifiedAssociatedModelName = standardizeFullyQualifiedModelName(attributeName);
29
31
  const associationModelName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedAssociatedModelName);
30
32
  const associationImportStatement = importStatementForModel(fullyQualifiedModelName, fullyQualifiedAssociatedModelName);
@@ -79,7 +81,7 @@ ${isSTI ? `\n@STI(${parentModelClassName})` : ''}
79
81
  export default class ${modelClassName} extends ${isSTI ? parentModelClassName : 'ApplicationModel'} {
80
82
  ${isSTI
81
83
  ? ''
82
- : ` public get table() {
84
+ : ` public override get table() {
83
85
  return '${tableName}' as const
84
86
  }
85
87
 
@@ -14,10 +14,14 @@ export default function generateFactoryContent({ fullyQualifiedModelName, column
14
14
  let firstStringAttr = true;
15
15
  for (const attribute of columnsWithTypes) {
16
16
  const [attributeName, attributeType, ...descriptors] = attribute.split(':');
17
+ if (attributeName === undefined)
18
+ continue;
17
19
  const fullyQualifiedAssociatedModelName = standardizeFullyQualifiedModelName(attributeName);
18
20
  const associationModelName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedAssociatedModelName);
19
21
  const associationFactoryImportStatement = `import create${associationModelName} from '${relativeDreamPath('factories', 'factories', fullyQualifiedModelName, fullyQualifiedAssociatedModelName)}'`;
20
22
  const associationName = camelize(associationModelName);
23
+ if (attributeName === undefined)
24
+ continue;
21
25
  if (/_type$/.test(attributeName))
22
26
  continue;
23
27
  if (!attributeType)
@@ -27,16 +31,16 @@ export default function generateFactoryContent({ fullyQualifiedModelName, column
27
31
  belongsToNames.push(associationName);
28
32
  belongsToTypedNames.push(`${associationName}: ${associationModelName}`);
29
33
  additionalImports.push(associationFactoryImportStatement);
30
- associationCreationStatements.push(`attrs.${associationName} ||= await create${associationModelName}()`);
34
+ associationCreationStatements.push(`attrs.${associationName} ??= await create${associationModelName}()`);
31
35
  break;
32
36
  case 'string':
33
37
  case 'text':
34
38
  case 'citext':
35
- stringAttributes.push(`attrs.${camelize(attributeName)} ||= \`${fullyQualifiedModelName} ${camelize(attributeName)} ${firstStringAttr ? '${++counter}' : '${counter}'}\``);
39
+ stringAttributes.push(`attrs.${camelize(attributeName)} ??= \`${fullyQualifiedModelName} ${camelize(attributeName)} ${firstStringAttr ? '${++counter}' : '${counter}'}\``);
36
40
  firstStringAttr = false;
37
41
  break;
38
42
  case 'enum':
39
- stringAttributes.push(`attrs.${camelize(attributeName)} ||= '${(descriptors[descriptors.length - 1] || '<tbd>').split(',')[0]}'`);
43
+ stringAttributes.push(`attrs.${camelize(attributeName)} ??= '${(descriptors[descriptors.length - 1] || '<tbd>').split(',')[0]}'`);
40
44
  break;
41
45
  default:
42
46
  // noop