@rvoh/dream 0.31.5 → 0.32.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) 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/file-builders/DreamtsBuilder.js +2 -2
  17. package/dist/cjs/src/global-cli/helpers/argAndValue.js +4 -4
  18. package/dist/cjs/src/helpers/CalendarDate.js +1 -1
  19. package/dist/cjs/src/helpers/cli/SchemaBuilder.js +52 -17
  20. package/dist/cjs/src/helpers/cli/generateDreamContent.js +3 -1
  21. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +7 -3
  22. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +53 -21
  23. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +3 -25
  24. package/dist/cjs/src/helpers/objectPathsToArrays.js +2 -1
  25. package/dist/esm/src/Dream.js +9 -9
  26. package/dist/esm/src/bin/helpers/sync.js +4 -4
  27. package/dist/esm/src/cli/logger/loggable/colorize.js +1 -1
  28. package/dist/esm/src/db/DreamDbConnection.js +1 -1
  29. package/dist/esm/src/decorators/field/sortable/hooks/beforeSortableSave.js +6 -3
  30. package/dist/esm/src/dream/DreamInstanceTransactionBuilder.js +3 -3
  31. package/dist/esm/src/dream/LeftJoinLoadBuilder.js +5 -1
  32. package/dist/esm/src/dream/Query.js +74 -12
  33. package/dist/esm/src/dream/internal/associations/associationUpdateQuery.js +3 -0
  34. package/dist/esm/src/dream/internal/associations/createAssociation.js +3 -0
  35. package/dist/esm/src/dream/internal/checkSingleValidation.js +8 -1
  36. package/dist/esm/src/dream/internal/extractAssociationMetadataFromAssociationName.js +7 -3
  37. package/dist/esm/src/errors/MissingTable.js +1 -1
  38. package/dist/esm/src/errors/UnexpectedUndefined.js +11 -0
  39. package/dist/esm/src/errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.js +14 -0
  40. package/dist/esm/src/global-cli/file-builders/DreamtsBuilder.js +2 -2
  41. package/dist/esm/src/global-cli/helpers/argAndValue.js +4 -4
  42. package/dist/esm/src/helpers/CalendarDate.js +1 -1
  43. package/dist/esm/src/helpers/cli/SchemaBuilder.js +52 -17
  44. package/dist/esm/src/helpers/cli/generateDreamContent.js +3 -1
  45. package/dist/esm/src/helpers/cli/generateFactoryContent.js +7 -3
  46. package/dist/esm/src/helpers/cli/generateMigrationContent.js +53 -21
  47. package/dist/esm/src/helpers/cli/generateSerializerContent.js +3 -25
  48. package/dist/esm/src/helpers/objectPathsToArrays.js +2 -1
  49. package/dist/types/src/Dream.d.ts +1 -1
  50. package/dist/types/src/cli/logger/loggable/DreamCliLoggable.d.ts +3 -3
  51. package/dist/types/src/cli/logger/loggable/DreamCliLoggableText.d.ts +5 -5
  52. package/dist/types/src/cli/logger/loggable/colorize.d.ts +3 -3
  53. package/dist/types/src/db/ConnectedToDB.d.ts +3 -3
  54. package/dist/types/src/decorators/field/sortable/helpers/decrementScopedRecordsGreaterThanPosition.d.ts +1 -1
  55. package/dist/types/src/decorators/field/sortable/helpers/positionIsInvalid.d.ts +1 -1
  56. package/dist/types/src/decorators/field/sortable/helpers/setPosition.d.ts +2 -2
  57. package/dist/types/src/decorators/field/sortable/hooks/afterSortableCreate.d.ts +2 -2
  58. package/dist/types/src/decorators/field/sortable/hooks/afterSortableDestroy.d.ts +1 -1
  59. package/dist/types/src/decorators/field/sortable/hooks/afterSortableUpdate.d.ts +2 -2
  60. package/dist/types/src/decorators/field/sortable/hooks/beforeSortableSave.d.ts +1 -1
  61. package/dist/types/src/decorators/field-or-getter/Virtual.d.ts +1 -1
  62. package/dist/types/src/dream/Query.d.ts +26 -26
  63. package/dist/types/src/dream/internal/destroyOptions.d.ts +4 -4
  64. package/dist/types/src/dream/internal/similarity/SimilarityBuilder.d.ts +4 -4
  65. package/dist/types/src/dream-application/index.d.ts +1 -1
  66. package/dist/types/src/errors/UnexpectedUndefined.d.ts +4 -0
  67. package/dist/types/src/errors/associations/AssociationDeclaredWithoutAssociatedDreamClass.d.ts +7 -0
  68. package/dist/types/src/errors/associations/MissingRequiredAssociationOnClause.d.ts +1 -1
  69. package/dist/types/src/helpers/cli/generateDream.d.ts +1 -1
  70. package/dist/types/src/helpers/cli/generateDreamContent.d.ts +1 -1
  71. package/dist/types/src/helpers/cli/generateMigration.d.ts +2 -2
  72. package/dist/types/src/helpers/cli/generateMigrationContent.d.ts +4 -4
  73. package/dist/types/src/helpers/cli/generateSerializer.d.ts +1 -1
  74. package/dist/types/src/helpers/cli/generateSerializerContent.d.ts +2 -2
  75. package/dist/types/src/types/associations/shared.d.ts +1 -6
  76. package/dist/types/src/types/dream.d.ts +2 -13
  77. package/dist/types/src/types/lifecycle.d.ts +2 -2
  78. package/dist/types/src/types/logger.d.ts +3 -3
  79. package/docs/classes/Benchmark.html +2 -2
  80. package/docs/classes/CalendarDate.html +2 -2
  81. package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +3 -3
  82. package/docs/classes/Decorators.html +19 -19
  83. package/docs/classes/Dream.html +127 -127
  84. package/docs/classes/DreamApplication.html +4 -4
  85. package/docs/classes/DreamBin.html +2 -2
  86. package/docs/classes/DreamCLI.html +4 -4
  87. package/docs/classes/DreamDbConnection.html +2 -2
  88. package/docs/classes/DreamGlam.html +2 -2
  89. package/docs/classes/DreamImporter.html +2 -2
  90. package/docs/classes/DreamMigrationHelpers.html +7 -7
  91. package/docs/classes/DreamSerializer.html +2 -2
  92. package/docs/classes/DreamTransaction.html +2 -2
  93. package/docs/classes/Encrypt.html +2 -2
  94. package/docs/classes/Env.html +2 -2
  95. package/docs/classes/GlobalNameNotSet.html +3 -3
  96. package/docs/classes/NonLoadedAssociation.html +3 -3
  97. package/docs/classes/Query.html +51 -51
  98. package/docs/classes/Range.html +2 -2
  99. package/docs/classes/RecordNotFound.html +3 -3
  100. package/docs/classes/ValidationError.html +3 -3
  101. package/docs/functions/Attribute.html +1 -1
  102. package/docs/functions/RendersMany.html +1 -1
  103. package/docs/functions/RendersOne.html +1 -1
  104. package/docs/functions/ReplicaSafe.html +1 -1
  105. package/docs/functions/STI.html +1 -1
  106. package/docs/functions/SoftDelete.html +1 -1
  107. package/docs/functions/camelize.html +1 -1
  108. package/docs/functions/capitalize.html +1 -1
  109. package/docs/functions/closeAllDbConnections.html +1 -1
  110. package/docs/functions/compact.html +1 -1
  111. package/docs/functions/db.html +1 -1
  112. package/docs/functions/debug.html +1 -1
  113. package/docs/functions/dreamDbConnections.html +1 -1
  114. package/docs/functions/dreamPath.html +1 -1
  115. package/docs/functions/generateDream.html +1 -1
  116. package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
  117. package/docs/functions/hyphenize.html +1 -1
  118. package/docs/functions/inferSerializerFromDreamClassOrViewModelClass.html +1 -1
  119. package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
  120. package/docs/functions/isEmpty.html +1 -1
  121. package/docs/functions/loadRepl.html +1 -1
  122. package/docs/functions/lookupClassByGlobalName.html +1 -1
  123. package/docs/functions/pascalize.html +1 -1
  124. package/docs/functions/pgErrorType.html +1 -1
  125. package/docs/functions/range-1.html +1 -1
  126. package/docs/functions/relativeDreamPath.html +1 -1
  127. package/docs/functions/round.html +1 -1
  128. package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
  129. package/docs/functions/sharedPathPrefix.html +1 -1
  130. package/docs/functions/snakeify.html +1 -1
  131. package/docs/functions/sort.html +1 -1
  132. package/docs/functions/sortBy.html +1 -1
  133. package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
  134. package/docs/functions/uncapitalize.html +1 -1
  135. package/docs/functions/uniq.html +1 -1
  136. package/docs/functions/validateColumn.html +1 -1
  137. package/docs/functions/validateTable.html +1 -1
  138. package/docs/interfaces/AttributeStatement.html +2 -2
  139. package/docs/interfaces/DecoratorContext.html +2 -2
  140. package/docs/interfaces/DreamApplicationInitOptions.html +2 -2
  141. package/docs/interfaces/DreamApplicationOpts.html +2 -2
  142. package/docs/interfaces/DreamSerializerAssociationStatement.html +2 -2
  143. package/docs/interfaces/EncryptOptions.html +2 -2
  144. package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
  145. package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
  146. package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
  147. package/docs/types/Camelized.html +1 -1
  148. package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
  149. package/docs/types/DateTime.html +1 -1
  150. package/docs/types/DreamAssociationMetadata.html +1 -1
  151. package/docs/types/DreamAttributes.html +1 -1
  152. package/docs/types/DreamClassColumn.html +1 -1
  153. package/docs/types/DreamColumn.html +1 -1
  154. package/docs/types/DreamColumnNames.html +1 -1
  155. package/docs/types/DreamLogLevel.html +1 -1
  156. package/docs/types/DreamLogger.html +1 -1
  157. package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
  158. package/docs/types/DreamParamSafeAttributes.html +1 -1
  159. package/docs/types/DreamParamSafeColumnNames.html +1 -1
  160. package/docs/types/DreamSerializerKey.html +1 -1
  161. package/docs/types/DreamSerializers.html +1 -1
  162. package/docs/types/DreamTableSchema.html +1 -1
  163. package/docs/types/DreamVirtualColumns.html +1 -1
  164. package/docs/types/EncryptAlgorithm.html +1 -1
  165. package/docs/types/Hyphenized.html +1 -1
  166. package/docs/types/IdType.html +1 -1
  167. package/docs/types/OpenapiAllTypes.html +1 -1
  168. package/docs/types/OpenapiFormats.html +1 -1
  169. package/docs/types/OpenapiNumberFormats.html +1 -1
  170. package/docs/types/OpenapiPrimitiveTypes.html +1 -1
  171. package/docs/types/OpenapiSchemaArray.html +1 -1
  172. package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
  173. package/docs/types/OpenapiSchemaBase.html +1 -1
  174. package/docs/types/OpenapiSchemaBody.html +1 -1
  175. package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
  176. package/docs/types/OpenapiSchemaCommonFields.html +1 -1
  177. package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
  178. package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
  179. package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
  180. package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
  181. package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  182. package/docs/types/OpenapiSchemaInteger.html +1 -1
  183. package/docs/types/OpenapiSchemaNull.html +1 -1
  184. package/docs/types/OpenapiSchemaNumber.html +1 -1
  185. package/docs/types/OpenapiSchemaObject.html +1 -1
  186. package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
  187. package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
  188. package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
  189. package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  190. package/docs/types/OpenapiSchemaObjectBase.html +1 -1
  191. package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
  192. package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
  193. package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
  194. package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
  195. package/docs/types/OpenapiSchemaPartialSegment.html +1 -1
  196. package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
  197. package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  198. package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  199. package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  200. package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  201. package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  202. package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  203. package/docs/types/OpenapiSchemaString.html +1 -1
  204. package/docs/types/OpenapiShorthandAllTypes.html +1 -1
  205. package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
  206. package/docs/types/OpenapiTypeField.html +1 -1
  207. package/docs/types/Pascalized.html +1 -1
  208. package/docs/types/PrimaryKeyType.html +1 -1
  209. package/docs/types/RoundingPrecision.html +1 -1
  210. package/docs/types/SerializableClassOrSerializerCallback.html +1 -1
  211. package/docs/types/SerializableDreamClassOrViewModelClass.html +1 -1
  212. package/docs/types/SerializableDreamOrViewModel.html +1 -1
  213. package/docs/types/SerializableTypes.html +1 -1
  214. package/docs/types/Snakeified.html +1 -1
  215. package/docs/types/Timestamp.html +1 -1
  216. package/docs/types/UpdateableAssociationProperties.html +1 -1
  217. package/docs/types/UpdateableProperties.html +1 -1
  218. package/docs/types/ValidationType.html +1 -1
  219. package/docs/types/ViewModelSerializerKey.html +1 -1
  220. package/docs/types/WhereStatementForDream.html +1 -1
  221. package/docs/types/WhereStatementForDreamClass.html +1 -1
  222. package/docs/variables/DateTime-1.html +1 -1
  223. package/docs/variables/DreamConst.html +1 -1
  224. package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
  225. package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
  226. package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
  227. package/docs/variables/ops.html +1 -1
  228. package/docs/variables/primaryKeyTypes.html +1 -1
  229. package/package.json +1 -1
@@ -10,6 +10,7 @@ const constants_js_1 = require("../../dream/constants.js");
10
10
  const FailedToIdentifyAssociation_js_1 = require("../../errors/schema-builder/FailedToIdentifyAssociation.js");
11
11
  const autogeneratedFileMessage_js_1 = require("../../global-cli/helpers/autogeneratedFileMessage.js");
12
12
  const camelize_js_1 = require("../camelize.js");
13
+ const compact_js_1 = require("../compact.js");
13
14
  const EnvInternal_js_1 = require("../EnvInternal.js");
14
15
  const pascalize_js_1 = require("../pascalize.js");
15
16
  const sortBy_js_1 = require("../sortBy.js");
@@ -52,9 +53,10 @@ export const globalSchema = {
52
53
  }
53
54
  globalModelNames() {
54
55
  const dreamApp = index_js_2.default.getOrFail();
56
+ const models = dreamApp.models;
55
57
  return `{
56
- ${Object.keys(dreamApp.models)
57
- .map(key => `'${key}': '${dreamApp.models[key].prototype.table}'`)
58
+ ${Object.keys(models)
59
+ .map(key => `'${key}': '${models[key]?.prototype?.table}'`)
58
60
  .join(',\n ')}
59
61
  }`;
60
62
  }
@@ -68,9 +70,14 @@ export const schema = {
68
70
  ${Object.keys(schemaData)
69
71
  .map(tableName => {
70
72
  const tableData = schemaData[tableName];
73
+ if (tableData === undefined)
74
+ return '';
71
75
  const defaultScopeNames = tableData.scopes.default;
72
76
  const namedScopeNames = tableData.scopes.named;
73
77
  allDefaultScopeNames = [...allDefaultScopeNames, ...defaultScopeNames];
78
+ const schemaDatum = schemaData[tableName];
79
+ if (schemaDatum === undefined)
80
+ return '';
74
81
  return `\
75
82
  ${tableName}: {
76
83
  primaryKey: '${tableData.primaryKey}',
@@ -83,11 +90,15 @@ ${tableName}: {
83
90
  named: ${stringifyArray(namedScopeNames)},
84
91
  },
85
92
  columns: {
86
- ${Object.keys(schemaData[tableName].columns)
93
+ ${Object.keys(schemaDatum.columns)
87
94
  .sort()
88
95
  .map(columnName => {
89
96
  const columnData = tableData.columns[columnName];
97
+ if (columnData === undefined)
98
+ return '';
90
99
  const kyselyType = this.kyselyType(tableName, columnName, fileContents);
100
+ if (kyselyType === undefined)
101
+ return '';
91
102
  return `${columnName}: {
92
103
  coercedType: {} as ${this.coercedType(kyselyType, columnData.dbType)},
93
104
  enumType: ${columnData.enumType ? `{} as ${columnData.enumType}` : 'null'},
@@ -100,12 +111,14 @@ ${tableName}: {
100
111
  })
101
112
  .join('\n ')}
102
113
  },
103
- virtualColumns: ${stringifyArray(schemaData[tableName].virtualColumns)},
114
+ virtualColumns: ${stringifyArray(schemaDatum.virtualColumns)},
104
115
  associations: {
105
- ${Object.keys(schemaData[tableName].associations)
116
+ ${Object.keys(schemaDatum.associations)
106
117
  .sort()
107
118
  .map(associationName => {
108
119
  const associationMetadata = tableData.associations[associationName];
120
+ if (associationMetadata === undefined)
121
+ return '';
109
122
  const whereStatement = associationMetadata.where;
110
123
  const requiredOnClauses = whereStatement === null
111
124
  ? []
@@ -206,6 +219,8 @@ may need to update the table getter in the corresponding Dream.
206
219
  return Object.keys(columnData)
207
220
  .sort()
208
221
  .reduce((acc, key) => {
222
+ if (columnData[key] === undefined)
223
+ return acc;
209
224
  acc[key] = columnData[key];
210
225
  return acc;
211
226
  }, {});
@@ -235,6 +250,8 @@ may need to update the table getter in the corresponding Dream.
235
250
  for (const model of models.filter(model => model.table === tableName)) {
236
251
  for (const associationName of model.associationNames) {
237
252
  const associationMetaData = model['associationMetadataMap']()[associationName];
253
+ if (associationMetaData === undefined)
254
+ continue;
238
255
  if (targetAssociationType && associationMetaData.type !== targetAssociationType)
239
256
  continue;
240
257
  const dreamClassOrClasses = associationMetaData.modelCB();
@@ -286,6 +303,8 @@ may need to update the table getter in the corresponding Dream.
286
303
  return Object.keys(tableAssociationData)
287
304
  .sort()
288
305
  .reduce((acc, key) => {
306
+ if (tableAssociationData[key] === undefined)
307
+ return acc;
289
308
  acc[key] = tableAssociationData[key];
290
309
  return acc;
291
310
  }, {});
@@ -295,33 +314,49 @@ may need to update the table getter in the corresponding Dream.
295
314
  const exportedConsts = [...fileContents.matchAll(/export\s+const\s+([a-zA-Z0-9_]+)/g)].map(res => res[1]);
296
315
  const exportedTypes = [...fileContents.matchAll(/export\s+type\s+([a-zA-Z0-9_]+)/g)].map(res => res[1]);
297
316
  const exportedInterfaces = [...fileContents.matchAll(/export\s+interface\s+([a-zA-Z0-9_]+)/g)].map(res => res[1]);
298
- const allExports = [...exportedConsts, ...exportedTypes, ...exportedInterfaces];
317
+ const allExports = (0, compact_js_1.default)([...exportedConsts, ...exportedTypes, ...exportedInterfaces]);
299
318
  return allExports;
300
319
  }
301
320
  async getTables() {
302
321
  const fileContents = await this.loadDbSyncFile();
303
322
  const tableLines = /export interface DB {([^}]*)}/.exec(fileContents)[1];
323
+ if (tableLines === undefined)
324
+ return [];
304
325
  const tables = tableLines
305
326
  .split('\n')
306
- .map(line => line.split(':')[0].replace(/\s*/, ''))
327
+ .map(line => {
328
+ const stingArray = line.split(':');
329
+ const substring = stingArray[0];
330
+ if (substring === undefined)
331
+ return '';
332
+ return substring.replace(/\s*/, '');
333
+ })
307
334
  .filter(line => !!line);
308
335
  return tables;
309
336
  }
310
337
  kyselyType(tableName, columnName, fileContents) {
311
- const tableLines = /export interface DB {([^}]*)}/.exec(fileContents)[1];
312
- const interfaceName = tableLines
338
+ const tableLinesString = /export interface DB {([^}]*)}/.exec(fileContents)[1];
339
+ if (tableLinesString === undefined)
340
+ return '';
341
+ const tableLines = tableLinesString
313
342
  .split('\n')
314
343
  .filter(line => !!line)
315
- .filter(line => new RegExp(`^ ${tableName}:`).test(line))[0]
316
- .split(':')[1]
317
- ?.replace(/[\s;]*/g, '');
318
- const interfaceLines = new RegExp(`export interface ${interfaceName} {([^}]*)}`).exec(fileContents)[1];
319
- const kyselyType = interfaceLines
344
+ .filter(line => new RegExp(`^ ${tableName}:`).test(line));
345
+ const tableLine = tableLines[0];
346
+ if (tableLine === undefined)
347
+ return '';
348
+ const interfaceName = tableLine.split(':')[1]?.replace(/[\s;]*/g, '');
349
+ const interfaceLinesString = new RegExp(`export interface ${interfaceName} {([^}]*)}`).exec(fileContents)[1];
350
+ if (interfaceLinesString === undefined)
351
+ return '';
352
+ const interfaceLines = interfaceLinesString
320
353
  .split('\n')
321
354
  .filter(line => !!line)
322
- .filter(line => new RegExp(` ${columnName}:`).test(line))[0]
323
- .split(':')[1]
324
- ?.replace(/[\s;]*/g, '');
355
+ .filter(line => new RegExp(` ${columnName}:`).test(line));
356
+ const interfaceLine = interfaceLines[0];
357
+ if (interfaceLine === undefined)
358
+ return '';
359
+ const kyselyType = interfaceLine.split(':')[1]?.replace(/[\s;]*/g, '');
325
360
  return kyselyType;
326
361
  }
327
362
  coercedType(kyselyType, dbType) {
@@ -28,6 +28,8 @@ function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fully
28
28
  : [importStatementForModel(fullyQualifiedModelName, 'ApplicationModel')];
29
29
  const attributeStatements = columnsWithTypes.map(attribute => {
30
30
  const [attributeName, attributeType, ...descriptors] = attribute.split(':');
31
+ if (attributeName === undefined)
32
+ return '';
31
33
  const fullyQualifiedAssociatedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(attributeName);
32
34
  const associationModelName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedAssociatedModelName);
33
35
  const associationImportStatement = importStatementForModel(fullyQualifiedModelName, fullyQualifiedAssociatedModelName);
@@ -82,7 +84,7 @@ ${isSTI ? `\n@STI(${parentModelClassName})` : ''}
82
84
  export default class ${modelClassName} extends ${isSTI ? parentModelClassName : 'ApplicationModel'} {
83
85
  ${isSTI
84
86
  ? ''
85
- : ` public get table() {
87
+ : ` public override get table() {
86
88
  return '${tableName}' as const
87
89
  }
88
90
 
@@ -17,10 +17,14 @@ function generateFactoryContent({ fullyQualifiedModelName, columnsWithTypes, })
17
17
  let firstStringAttr = true;
18
18
  for (const attribute of columnsWithTypes) {
19
19
  const [attributeName, attributeType, ...descriptors] = attribute.split(':');
20
+ if (attributeName === undefined)
21
+ continue;
20
22
  const fullyQualifiedAssociatedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(attributeName);
21
23
  const associationModelName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedAssociatedModelName);
22
24
  const associationFactoryImportStatement = `import create${associationModelName} from '${(0, relativeDreamPath_js_1.default)('factories', 'factories', fullyQualifiedModelName, fullyQualifiedAssociatedModelName)}'`;
23
25
  const associationName = (0, camelize_js_1.default)(associationModelName);
26
+ if (attributeName === undefined)
27
+ continue;
24
28
  if (/_type$/.test(attributeName))
25
29
  continue;
26
30
  if (!attributeType)
@@ -30,16 +34,16 @@ function generateFactoryContent({ fullyQualifiedModelName, columnsWithTypes, })
30
34
  belongsToNames.push(associationName);
31
35
  belongsToTypedNames.push(`${associationName}: ${associationModelName}`);
32
36
  additionalImports.push(associationFactoryImportStatement);
33
- associationCreationStatements.push(`attrs.${associationName} ||= await create${associationModelName}()`);
37
+ associationCreationStatements.push(`attrs.${associationName} ??= await create${associationModelName}()`);
34
38
  break;
35
39
  case 'string':
36
40
  case 'text':
37
41
  case 'citext':
38
- stringAttributes.push(`attrs.${(0, camelize_js_1.default)(attributeName)} ||= \`${fullyQualifiedModelName} ${(0, camelize_js_1.default)(attributeName)} ${firstStringAttr ? '${++counter}' : '${counter}'}\``);
42
+ stringAttributes.push(`attrs.${(0, camelize_js_1.default)(attributeName)} ??= \`${fullyQualifiedModelName} ${(0, camelize_js_1.default)(attributeName)} ${firstStringAttr ? '${++counter}' : '${counter}'}\``);
39
43
  firstStringAttr = false;
40
44
  break;
41
45
  case 'enum':
42
- stringAttributes.push(`attrs.${(0, camelize_js_1.default)(attributeName)} ||= '${(descriptors[descriptors.length - 1] || '<tbd>').split(',')[0]}'`);
46
+ stringAttributes.push(`attrs.${(0, camelize_js_1.default)(attributeName)} ??= '${(descriptors[descriptors.length - 1] || '<tbd>').split(',')[0]}'`);
43
47
  break;
44
48
  default:
45
49
  // noop
@@ -5,14 +5,19 @@ const pluralize_esm_1 = require("pluralize-esm");
5
5
  const InvalidDecimalFieldPassedToGenerator_js_1 = require("../../errors/InvalidDecimalFieldPassedToGenerator.js");
6
6
  const foreignKeyTypeFromPrimaryKey_js_1 = require("../db/foreignKeyTypeFromPrimaryKey.js");
7
7
  const snakeify_js_1 = require("../snakeify.js");
8
+ const STI_TYPE_COLUMN_NAME = 'type';
9
+ const COLUMNS_TO_INDEX = [STI_TYPE_COLUMN_NAME];
10
+ const NOT_NULL_COLUMNS = [STI_TYPE_COLUMN_NAME];
8
11
  function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType = 'bigserial', createOrAlter = 'create', } = {}) {
9
12
  const altering = createOrAlter === 'alter';
10
13
  let requireCitextExtension = false;
11
- const { columnDefs, columnDrops } = columnsWithTypes.reduce((acc, attribute) => {
12
- const { columnDefs, columnDrops } = acc;
14
+ const { columnDefs, columnDrops, indexDefs, indexDrops } = columnsWithTypes.reduce((acc, attribute) => {
15
+ const { columnDefs, columnDrops, indexDefs, indexDrops } = acc;
13
16
  const [nonStandardAttributeName, attributeType, ...descriptors] = attribute.split(':');
14
17
  let attributeName = (0, snakeify_js_1.default)(nonStandardAttributeName);
15
- if (['has_one', 'has_many'].includes(attributeType))
18
+ if (attributeName === undefined)
19
+ return acc;
20
+ if (attributeType !== undefined && ['has_one', 'has_many'].includes(attributeType))
16
21
  return acc;
17
22
  if (attributeType === 'citext')
18
23
  requireCitextExtension = true;
@@ -38,12 +43,23 @@ function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType
38
43
  columnDefs.push(generateColumnStr(`encrypted_${attributeName}`, 'text', descriptors));
39
44
  break;
40
45
  default:
41
- columnDefs.push(generateColumnStr(attributeName, coercedAttributeType, descriptors));
46
+ if (coercedAttributeType !== undefined) {
47
+ columnDefs.push(generateColumnStr(attributeName, coercedAttributeType, descriptors));
48
+ }
42
49
  break;
43
50
  }
44
51
  columnDrops.push(`.dropColumn('${attributeName}')`);
52
+ if (COLUMNS_TO_INDEX.includes(attributeName)) {
53
+ const indexName = `${table}_${attributeName}`;
54
+ indexDefs.push(`await db.schema
55
+ .createIndex('${indexName}')
56
+ .on('${table}')
57
+ .column('${attributeName}')
58
+ .execute()`);
59
+ indexDrops.push(`await db.schema.dropIndex('${indexName}').execute()`);
60
+ }
45
61
  return acc;
46
- }, { columnDefs: [], columnDrops: [] });
62
+ }, { columnDefs: [], columnDrops: [], indexDefs: [], indexDrops: [] });
47
63
  if (!table) {
48
64
  return `\
49
65
  import { Kysely, sql } from 'kysely'
@@ -64,28 +80,31 @@ export async function down(db: Kysely<any>): Promise<void> {
64
80
  const dreamImports = [];
65
81
  if (requireCitextExtension)
66
82
  dreamImports.push('DreamMigrationHelpers');
67
- const newline = '\n ';
68
- const columnDefLines = columnDefs.length ? newline + columnDefs.join(newline) : '';
69
- const columnDropLines = columnDrops.length ? newline + columnDrops.join(newline) + newline : '';
83
+ const newlineIndent = '\n ';
84
+ const newlineDoubleIndent = '\n ';
85
+ const columnDefLines = columnDefs.length ? newlineDoubleIndent + columnDefs.join(newlineDoubleIndent) : '';
86
+ const columnDropLines = columnDrops.length
87
+ ? newlineDoubleIndent + columnDrops.join(newlineDoubleIndent) + newlineDoubleIndent
88
+ : '';
70
89
  return `\
71
90
  ${dreamImports.length ? `import { ${dreamImports.join(', ')} } from '@rvoh/dream'\n` : ''}import { ${kyselyImports.join(', ')} } from 'kysely'
72
91
 
73
92
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
93
  export async function up(db: Kysely<any>): Promise<void> {
75
94
  ${citextExtension}${generateEnumStatements(columnsWithTypes)} await db.schema
76
- .${altering ? 'alterTable' : 'createTable'}('${table}')${altering ? '' : newline + generateIdStr({ primaryKeyType })}${columnDefLines}${altering
95
+ .${altering ? 'alterTable' : 'createTable'}('${table}')${altering ? '' : newlineDoubleIndent + generateIdStr({ primaryKeyType })}${columnDefLines}${altering
77
96
  ? ''
78
- : newline +
97
+ : newlineDoubleIndent +
79
98
  ".addColumn('created_at', 'timestamp', col => col.notNull())" +
80
- newline +
99
+ newlineDoubleIndent +
81
100
  ".addColumn('updated_at', 'timestamp', col => col.notNull())"}
82
- .execute()
101
+ .execute()${indexDefs.length ? `\n${newlineIndent}` : ''}${indexDefs.join(newlineDoubleIndent)}
83
102
  }
84
103
 
85
104
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
86
105
  export async function down(db: Kysely<any>): Promise<void> {
87
- ${altering
88
- ? `await db.schema${newline}.alterTable('${table}')${columnDropLines}.execute()`
106
+ ${indexDrops.join(newlineIndent)}${indexDrops.length ? newlineIndent : ''}${altering
107
+ ? `await db.schema${newlineDoubleIndent}.alterTable('${table}')${columnDropLines}.execute()`
89
108
  : `await db.schema.dropTable('${table}').execute()`}${generateEnumDropStatements(columnsWithTypes)}
90
109
  }\
91
110
  `;
@@ -112,7 +131,10 @@ function generateEnumStatements(columnsWithTypes) {
112
131
  const enumStatements = columnsWithTypes.filter(attribute => /:enum:.*:/.test(attribute));
113
132
  const finalStatements = enumStatements.map(statement => {
114
133
  const enumName = statement.split(':')[2];
115
- const columnsWithTypes = statement.split(':')[3].split(/,\s{0,}/);
134
+ const columnsWithTypesString = statement.split(':')[3];
135
+ if (columnsWithTypesString === undefined)
136
+ return '';
137
+ const columnsWithTypes = columnsWithTypesString.split(/,\s{0,}/);
116
138
  return ` await db.schema
117
139
  .createType('${enumName}_enum')
118
140
  .asEnum([
@@ -135,7 +157,11 @@ function generateBooleanStr(attributeName) {
135
157
  }
136
158
  function generateEnumStr(attribute) {
137
159
  const computedAttributeType = enumAttributeType(attribute);
138
- return `.addColumn('${attribute.split(':')[0]}', ${computedAttributeType})`;
160
+ const attributeName = attribute.split(':')[0];
161
+ if (attributeName === undefined)
162
+ return '';
163
+ const notNull = NOT_NULL_COLUMNS.includes(attributeName);
164
+ return `.addColumn('${attributeName}', ${computedAttributeType}${notNull ? ', col => col.notNull()' : ''})`;
139
165
  }
140
166
  function generateDecimalStr(attribute) {
141
167
  const [, , ...descriptors] = attribute.split(':');
@@ -148,15 +174,21 @@ function generateColumnStr(attributeName, attributeType, descriptors) {
148
174
  let returnStr = `.addColumn('${attributeName}', ${attributeTypeString(attributeType)}`;
149
175
  const providedDefaultArg = descriptors.find(d => /^default\(/.test(d));
150
176
  const providedDefault = providedDefaultArg?.replace(/^default\(/, '')?.replace(/\)$/, '');
151
- const hasExtraValues = descriptors.includes('primary') || providedDefault;
177
+ const notNull = NOT_NULL_COLUMNS.includes(attributeName);
178
+ const hasExtraValues = providedDefault || notNull;
152
179
  if (hasExtraValues)
153
180
  returnStr += ', col => col';
154
- if (descriptors.includes('primary'))
155
- returnStr += `.defaultTo('${providedDefault}')`;
181
+ if (notNull)
182
+ returnStr += '.notNull()';
156
183
  if (providedDefault)
157
184
  returnStr += `.defaultTo('${providedDefault}')`;
158
- // TODO: handle index
159
- return `${returnStr}${hasExtraValues ? '))' : ')'}`;
185
+ returnStr = `${returnStr})`;
186
+ if (attributeName === STI_TYPE_COLUMN_NAME)
187
+ returnStr = `// CONSIDER: when using type for STI, always use an enum
188
+ // Try using the enum syntax in your generator, e.g.:
189
+ // yarn psy g:model Balloon type:enum:balloon_type:latex,mylar
190
+ ${returnStr}`;
191
+ return returnStr;
160
192
  }
161
193
  function attributeTypeString(attributeType) {
162
194
  const attributeTypesRequiringSql = ['citext'];
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = generateSerializerContent;
4
4
  const camelize_js_1 = require("../camelize.js");
5
5
  const globalClassNameFromFullyQualifiedModelName_js_1 = require("../globalClassNameFromFullyQualifiedModelName.js");
6
- const pascalize_js_1 = require("../pascalize.js");
7
6
  const relativeDreamPath_js_1 = require("../path/relativeDreamPath.js");
8
7
  const serializerNameFromFullyQualifiedModelName_js_1 = require("../serializerNameFromFullyQualifiedModelName.js");
9
8
  const standardizeFullyQualifiedModelName_js_1 = require("../standardizeFullyQualifiedModelName.js");
@@ -74,6 +73,8 @@ export default class ${defaultSerialzerClassName}${dataTypeCapture} extends ${de
74
73
  ${columnsWithTypes
75
74
  .map(attr => {
76
75
  const [name, type] = attr.split(':');
76
+ if (name === undefined)
77
+ return '';
77
78
  const fullyQualifiedAssociatedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(name);
78
79
  const associatedModelName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedAssociatedModelName);
79
80
  const propertyName = (0, camelize_js_1.default)(associatedModelName);
@@ -84,7 +85,7 @@ ${columnsWithTypes
84
85
  return '';
85
86
  default:
86
87
  return ` @Attribute(${modelClassName}${attributeOptionsSpecifier(type, attr)})
87
- public ${propertyName}: ${jsType(type, attr, propertyName, modelClassName)}`;
88
+ public ${propertyName}: ${`DreamColumn<${modelClassName}, '${propertyName}'>`}`;
88
89
  }
89
90
  })
90
91
  .join('\n\n ')}
@@ -99,29 +100,6 @@ function attributeOptionsSpecifier(type, attr) {
99
100
  return '';
100
101
  }
101
102
  }
102
- function jsType(type, originalAttribute, propertyName, modelClass = null) {
103
- if (modelClass)
104
- return `DreamColumn<${modelClass}, '${propertyName}'>`;
105
- switch (type) {
106
- case 'date':
107
- return 'CalendarDate';
108
- case 'datetime':
109
- return 'DateTime';
110
- case 'decimal':
111
- case 'integer':
112
- case 'number':
113
- return 'number';
114
- case 'string':
115
- case 'text':
116
- case 'bigint':
117
- case 'uuid':
118
- return 'string';
119
- case 'enum':
120
- return (0, pascalize_js_1.default)(originalAttribute.split(':')[2]) + 'Enum';
121
- default:
122
- return 'any';
123
- }
124
- }
125
103
  function importStatementForSerializer(originModelName, destinationModelName) {
126
104
  return `\nimport ${(0, globalClassNameFromFullyQualifiedModelName_js_1.default)((0, serializerNameFromFullyQualifiedModelName_js_1.default)(destinationModelName))}, { ${(0, globalClassNameFromFullyQualifiedModelName_js_1.default)((0, serializerNameFromFullyQualifiedModelName_js_1.default)(destinationModelName, 'summary'))} } from '${(0, relativeDreamPath_js_1.default)('serializers', 'serializers', originModelName, destinationModelName)}'`;
127
105
  }
@@ -9,7 +9,8 @@ function objectPathsToArrays(obj) {
9
9
  }
10
10
  function depthFirstSearch(obj, workingPath, completePaths) {
11
11
  return Object.keys(obj).forEach(key => {
12
- if (Object.keys(obj[key]).length) {
12
+ const subObj = obj[key];
13
+ if (subObj && Object.keys(subObj).length) {
13
14
  depthFirstSearch(obj[key], [...workingPath, key], completePaths);
14
15
  }
15
16
  else {
@@ -1406,7 +1406,7 @@ export default class Dream {
1406
1406
  */
1407
1407
  static belongsToAssociationForeignKeys() {
1408
1408
  const associationMap = this.associationMetadataMap();
1409
- return this.belongsToAssociationNames().map(belongsToKey => associationMap[belongsToKey].foreignKey());
1409
+ return this.belongsToAssociationNames().map(belongsToKey => associationMap[belongsToKey]?.foreignKey());
1410
1410
  }
1411
1411
  /**
1412
1412
  * @internal
@@ -1423,8 +1423,8 @@ export default class Dream {
1423
1423
  static polymorphicTypeColumns() {
1424
1424
  const associationMap = this.associationMetadataMap();
1425
1425
  return this.belongsToAssociationNames()
1426
- .filter(key => associationMap[key].polymorphic)
1427
- .map(belongsToKey => associationMap[belongsToKey].foreignKeyTypeField());
1426
+ .filter(key => associationMap[key]?.polymorphic)
1427
+ .map(belongsToKey => associationMap[belongsToKey]?.foreignKeyTypeField());
1428
1428
  }
1429
1429
  /**
1430
1430
  * @internal
@@ -1442,7 +1442,7 @@ export default class Dream {
1442
1442
  */
1443
1443
  static belongsToAssociationNames() {
1444
1444
  const associationMap = this.associationMetadataMap();
1445
- return Object.keys(associationMap).filter(key => associationMap[key].type === 'BelongsTo');
1445
+ return Object.keys(associationMap).filter(key => associationMap[key]?.type === 'BelongsTo');
1446
1446
  }
1447
1447
  /**
1448
1448
  * @internal
@@ -1695,7 +1695,7 @@ export default class Dream {
1695
1695
  get isValid() {
1696
1696
  this._errors = {};
1697
1697
  runValidations(this);
1698
- return !Object.keys(this.errors).filter(key => !!this.errors[key].length).length;
1698
+ return !Object.keys(this.errors).filter(key => !!this.errors[key]?.length).length;
1699
1699
  }
1700
1700
  /**
1701
1701
  * The name of the primary key column on this model.
@@ -1732,7 +1732,7 @@ export default class Dream {
1732
1732
  *
1733
1733
  * ```ts
1734
1734
  * class User extends ApplicationModel {
1735
- * public get table() {
1735
+ * public override get table() {
1736
1736
  * return 'users' as const
1737
1737
  * }
1738
1738
  * }
@@ -2917,7 +2917,7 @@ export default class Dream {
2917
2917
  * @returns void
2918
2918
  */
2919
2919
  async save({ skipHooks } = {}) {
2920
- await saveDream(this, null, { skipHooks });
2920
+ await saveDream(this, null, skipHooks ? { skipHooks } : undefined);
2921
2921
  }
2922
2922
  /**
2923
2923
  * Applies transaction to a new Query instance
@@ -2959,7 +2959,7 @@ export default class Dream {
2959
2959
  async update(attributes, { skipHooks } = {}) {
2960
2960
  // use #assignAttributes to leverage any custom-defined setters
2961
2961
  this.assignAttributes(attributes);
2962
- await this.save({ skipHooks });
2962
+ await this.save(skipHooks ? { skipHooks } : undefined);
2963
2963
  }
2964
2964
  /**
2965
2965
  * Applies all attribute changes passed to the dream,
@@ -2986,7 +2986,7 @@ export default class Dream {
2986
2986
  async updateAttributes(attributes, { skipHooks } = {}) {
2987
2987
  // use #setAttributes to bypass any custom-defined setters
2988
2988
  this.setAttributes(attributes);
2989
- await this.save({ skipHooks });
2989
+ await this.save(skipHooks ? { skipHooks } : undefined);
2990
2990
  }
2991
2991
  /**
2992
2992
  * Flags a dream model so that it does not
@@ -1,6 +1,8 @@
1
1
  import '../../helpers/loadEnv.js';
2
2
  import * as fs from 'fs/promises';
3
3
  import * as path from 'path';
4
+ import DreamCLI from '../../cli/index.js';
5
+ import colorize from '../../cli/logger/loggable/colorize.js';
4
6
  import ConnectionConfRetriever from '../../db/ConnectionConfRetriever.js';
5
7
  import DreamApplication from '../../dream-application/index.js';
6
8
  import autogeneratedFileDisclaimer from '../../global-cli/helpers/autogeneratedFileMessage.js';
@@ -9,8 +11,6 @@ import EnvInternal from '../../helpers/EnvInternal.js';
9
11
  import dreamPath from '../../helpers/path/dreamPath.js';
10
12
  import snakeify from '../../helpers/snakeify.js';
11
13
  import sspawn from '../../helpers/sspawn.js';
12
- import DreamCLI from '../../cli/index.js';
13
- import colorize from '../../cli/logger/loggable/colorize.js';
14
14
  export default async function writeSyncFile() {
15
15
  const dbConf = new ConnectionConfRetriever().getConnectionConf('primary');
16
16
  const dreamApp = DreamApplication.getOrFail();
@@ -104,8 +104,8 @@ export const ${typeDeclaration}Values = [
104
104
  });
105
105
  }
106
106
  function transformName(str) {
107
- const name = str.split(' {')[0].replace(/\s/g, '');
108
- if (name === 'DB')
107
+ const name = str.split(' {')[0]?.replace(/\s/g, '');
108
+ if (name === undefined || name === 'DB')
109
109
  return null;
110
110
  return name;
111
111
  }
@@ -1,5 +1,5 @@
1
1
  import c from 'yoctocolors';
2
- export default function colorize(text, { color, bgColor }) {
2
+ export default function colorize(text, { color, bgColor, }) {
3
3
  const foregroundApplied = color ? c[color](text) : text;
4
4
  return bgColor ? c[bgColor](foregroundApplied) : foregroundApplied;
5
5
  }
@@ -43,7 +43,7 @@ export default class DreamDbConnection {
43
43
  }
44
44
  static async dropAllConnections() {
45
45
  for (const key of Object.keys(connections)) {
46
- await connections[key].destroy();
46
+ await connections[key]?.destroy();
47
47
  delete connections[key];
48
48
  }
49
49
  }
@@ -6,9 +6,12 @@ export default async function beforeSortableSave({ positionField, dream, query,
6
6
  const cacheKey = sortableCacheKeyName(positionField);
7
7
  const cachedValuesName = sortableCacheValuesName(positionField);
8
8
  const dreamAsAny = dream;
9
- const changingScope = scopeArray(scope).filter(scopeField => dream['getAssociationMetadata'](scopeField)
10
- ? dream.willSaveChangeToAttribute(dream['getAssociationMetadata'](scopeField).foreignKey())
11
- : dream.willSaveChangeToAttribute(scopeField)).length;
9
+ const changingScope = scopeArray(scope).filter(scopeField => {
10
+ const association = dream['getAssociationMetadata'](scopeField);
11
+ return association
12
+ ? dream.willSaveChangeToAttribute(association.foreignKey())
13
+ : dream.willSaveChangeToAttribute(scopeField);
14
+ }).length;
12
15
  if (!dream.willSaveChangeToAttribute(positionField) && !changingScope)
13
16
  return;
14
17
  const onlyChangingScope = !dream.willSaveChangeToAttribute(positionField) && changingScope;
@@ -209,7 +209,7 @@ export default class DreamInstanceTransactionBuilder {
209
209
  */
210
210
  async update(attributes, { skipHooks } = {}) {
211
211
  this.dreamInstance.assignAttributes(attributes);
212
- await saveDream(this.dreamInstance, this.dreamTransaction, { skipHooks });
212
+ await saveDream(this.dreamInstance, this.dreamTransaction, skipHooks ? { skipHooks } : undefined);
213
213
  }
214
214
  /**
215
215
  * Applies all attribute changes passed to the dream,
@@ -237,7 +237,7 @@ export default class DreamInstanceTransactionBuilder {
237
237
  */
238
238
  async updateAttributes(attributes, { skipHooks } = {}) {
239
239
  this.dreamInstance.setAttributes(attributes);
240
- await saveDream(this.dreamInstance, this.dreamTransaction, { skipHooks });
240
+ await saveDream(this.dreamInstance, this.dreamTransaction, skipHooks ? { skipHooks } : undefined);
241
241
  }
242
242
  /**
243
243
  * Reloads an instance, refreshing all it's attribute values
@@ -292,7 +292,7 @@ export default class DreamInstanceTransactionBuilder {
292
292
  * @returns void
293
293
  */
294
294
  async save({ skipHooks } = {}) {
295
- await saveDream(this.dreamInstance, this.dreamTransaction, { skipHooks });
295
+ await saveDream(this.dreamInstance, this.dreamTransaction, skipHooks ? { skipHooks } : undefined);
296
296
  }
297
297
  /**
298
298
  * Returns a Query instance for the specified
@@ -1,3 +1,4 @@
1
+ import UnexpectedUndefined from '../errors/UnexpectedUndefined.js';
1
2
  export default class LeftJoinLoadBuilder {
2
3
  dream;
3
4
  dreamTransaction;
@@ -61,7 +62,10 @@ export default class LeftJoinLoadBuilder {
61
62
  }
62
63
  const dreamWithLoadedAssociations = await this.query.firstOrFail();
63
64
  Object.keys(this.query['leftJoinStatements']).forEach(associationName => {
64
- this.query['hydrateAssociation']([this.dream], this.dream['getAssociationMetadata'](associationName), this.associationToPreloadedDreamsAndWhatTheyPointTo({
65
+ const associationMetadata = this.dream['getAssociationMetadata'](associationName);
66
+ if (associationMetadata === undefined)
67
+ throw new UnexpectedUndefined();
68
+ this.query['hydrateAssociation']([this.dream], associationMetadata, this.associationToPreloadedDreamsAndWhatTheyPointTo({
65
69
  pointsToPrimaryKey: this.dream.primaryKeyValue,
66
70
  associatedModels: dreamWithLoadedAssociations[associationName],
67
71
  }));