@rvoh/dream 2.5.1 → 2.5.3

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 +0 -9
  2. package/dist/cjs/src/cli/index.js +38 -10
  3. package/dist/cjs/src/cli/logger/DreamCliLogger.js +107 -6
  4. package/dist/cjs/src/db/helpers/syncDbTypesFiles.js +2 -2
  5. package/dist/cjs/src/decorators/field/Encrypted.js +2 -1
  6. package/dist/cjs/src/dream/QueryDriver/Postgres.js +2 -2
  7. package/dist/cjs/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -2
  8. package/dist/cjs/src/dream/QueryDriver/helpers/pg/dropDb.js +2 -2
  9. package/dist/cjs/src/helpers/db/columnAllowsNull.js +3 -0
  10. package/dist/cjs/src/helpers/db/normalizeDataForDb.js +2 -1
  11. package/dist/cjs/src/helpers/db/types/isDatabaseArrayColumn.js +2 -1
  12. package/dist/cjs/src/helpers/db/types/isDatetimeOrDatetimeArrayColumn.js +2 -1
  13. package/dist/cjs/src/helpers/db/types/isJsonColumn.js +2 -1
  14. package/dist/cjs/src/ops/index.js +2 -1
  15. package/dist/esm/src/Dream.js +0 -9
  16. package/dist/esm/src/cli/index.js +38 -10
  17. package/dist/esm/src/cli/logger/DreamCliLogger.js +107 -6
  18. package/dist/esm/src/db/helpers/syncDbTypesFiles.js +2 -2
  19. package/dist/esm/src/decorators/field/Encrypted.js +2 -1
  20. package/dist/esm/src/dream/QueryDriver/Postgres.js +2 -2
  21. package/dist/esm/src/dream/QueryDriver/helpers/kysely/runMigration.js +2 -2
  22. package/dist/esm/src/dream/QueryDriver/helpers/pg/dropDb.js +2 -2
  23. package/dist/esm/src/helpers/db/columnAllowsNull.js +3 -0
  24. package/dist/esm/src/helpers/db/normalizeDataForDb.js +2 -1
  25. package/dist/esm/src/helpers/db/types/isDatabaseArrayColumn.js +2 -1
  26. package/dist/esm/src/helpers/db/types/isDatetimeOrDatetimeArrayColumn.js +2 -1
  27. package/dist/esm/src/helpers/db/types/isJsonColumn.js +2 -1
  28. package/dist/esm/src/ops/index.js +2 -1
  29. package/dist/types/src/Dream.d.ts +0 -6
  30. package/dist/types/src/cli/logger/DreamCliLogger.d.ts +6 -1
  31. package/dist/types/src/helpers/db/columnAllowsNull.d.ts +2 -0
  32. package/dist/types/src/serializer/builders/DreamSerializerBuilder.d.ts +2 -2
  33. package/dist/types/src/types/serializer.d.ts +4 -4
  34. package/dist/types/src/types/serializer.ts +4 -14
  35. package/docs/classes/db.DreamMigrationHelpers.html +9 -9
  36. package/docs/classes/db.KyselyQueryDriver.html +32 -32
  37. package/docs/classes/db.PostgresQueryDriver.html +33 -33
  38. package/docs/classes/db.QueryDriverBase.html +31 -31
  39. package/docs/classes/errors.CheckConstraintViolation.html +3 -3
  40. package/docs/classes/errors.ColumnOverflow.html +3 -3
  41. package/docs/classes/errors.CreateOrFindByFailedToCreateAndFind.html +3 -3
  42. package/docs/classes/errors.DataIncompatibleWithDatabaseField.html +3 -3
  43. package/docs/classes/errors.DataTypeColumnTypeMismatch.html +3 -3
  44. package/docs/classes/errors.GlobalNameNotSet.html +3 -3
  45. package/docs/classes/errors.InvalidCalendarDate.html +2 -2
  46. package/docs/classes/errors.InvalidClockTime.html +2 -2
  47. package/docs/classes/errors.InvalidClockTimeTz.html +2 -2
  48. package/docs/classes/errors.InvalidDateTime.html +2 -2
  49. package/docs/classes/errors.MissingSerializersDefinition.html +3 -3
  50. package/docs/classes/errors.NonLoadedAssociation.html +3 -3
  51. package/docs/classes/errors.NotNullViolation.html +3 -3
  52. package/docs/classes/errors.RecordNotFound.html +3 -3
  53. package/docs/classes/errors.ValidationError.html +3 -3
  54. package/docs/classes/index.CalendarDate.html +33 -33
  55. package/docs/classes/index.ClockTime.html +32 -32
  56. package/docs/classes/index.ClockTimeTz.html +35 -35
  57. package/docs/classes/index.DateTime.html +86 -86
  58. package/docs/classes/index.Decorators.html +19 -19
  59. package/docs/classes/index.Dream.html +118 -118
  60. package/docs/classes/index.DreamApp.html +5 -5
  61. package/docs/classes/index.DreamTransaction.html +2 -2
  62. package/docs/classes/index.Env.html +2 -2
  63. package/docs/classes/index.Query.html +56 -56
  64. package/docs/classes/system.CliFileWriter.html +4 -4
  65. package/docs/classes/system.DreamBin.html +2 -2
  66. package/docs/classes/system.DreamCLI.html +6 -6
  67. package/docs/classes/system.DreamImporter.html +2 -2
  68. package/docs/classes/system.DreamLogos.html +2 -2
  69. package/docs/classes/system.DreamSerializerBuilder.html +13 -13
  70. package/docs/classes/system.ObjectSerializerBuilder.html +8 -8
  71. package/docs/classes/system.PathHelpers.html +3 -3
  72. package/docs/classes/utils.Encrypt.html +2 -2
  73. package/docs/classes/utils.Range.html +2 -2
  74. package/docs/functions/db.closeAllDbConnections.html +1 -1
  75. package/docs/functions/db.dreamDbConnections.html +1 -1
  76. package/docs/functions/db.untypedDb.html +1 -1
  77. package/docs/functions/db.validateColumn.html +1 -1
  78. package/docs/functions/db.validateTable.html +1 -1
  79. package/docs/functions/errors.pgErrorType.html +1 -1
  80. package/docs/functions/index.DreamSerializer.html +1 -1
  81. package/docs/functions/index.ObjectSerializer.html +1 -1
  82. package/docs/functions/index.ReplicaSafe.html +1 -1
  83. package/docs/functions/index.STI.html +1 -1
  84. package/docs/functions/index.SoftDelete.html +1 -1
  85. package/docs/functions/utils.camelize.html +1 -1
  86. package/docs/functions/utils.capitalize.html +1 -1
  87. package/docs/functions/utils.cloneDeepSafe.html +1 -1
  88. package/docs/functions/utils.compact.html +1 -1
  89. package/docs/functions/utils.groupBy.html +1 -1
  90. package/docs/functions/utils.hyphenize.html +1 -1
  91. package/docs/functions/utils.intersection.html +1 -1
  92. package/docs/functions/utils.isEmpty.html +1 -1
  93. package/docs/functions/utils.normalizeUnicode.html +1 -1
  94. package/docs/functions/utils.pascalize.html +1 -1
  95. package/docs/functions/utils.percent.html +1 -1
  96. package/docs/functions/utils.range.html +1 -1
  97. package/docs/functions/utils.round.html +1 -1
  98. package/docs/functions/utils.sanitizeString.html +1 -1
  99. package/docs/functions/utils.snakeify.html +1 -1
  100. package/docs/functions/utils.sort.html +1 -1
  101. package/docs/functions/utils.sortBy.html +1 -1
  102. package/docs/functions/utils.sortObjectByKey.html +1 -1
  103. package/docs/functions/utils.sortObjectByValue.html +1 -1
  104. package/docs/functions/utils.uncapitalize.html +1 -1
  105. package/docs/functions/utils.uniq.html +1 -1
  106. package/docs/interfaces/openapi.OpenapiDescription.html +2 -2
  107. package/docs/interfaces/openapi.OpenapiSchemaProperties.html +1 -1
  108. package/docs/interfaces/openapi.OpenapiSchemaPropertiesShorthand.html +1 -1
  109. package/docs/interfaces/openapi.OpenapiTypeFieldObject.html +1 -1
  110. package/docs/interfaces/types.BelongsToStatement.html +2 -2
  111. package/docs/interfaces/types.DecoratorContext.html +2 -2
  112. package/docs/interfaces/types.DreamAppInitOptions.html +2 -2
  113. package/docs/interfaces/types.DreamAppOpts.html +2 -2
  114. package/docs/interfaces/types.DurationObject.html +2 -2
  115. package/docs/interfaces/types.EncryptOptions.html +2 -2
  116. package/docs/interfaces/types.InternalAnyTypedSerializerRendersMany.html +2 -2
  117. package/docs/interfaces/types.InternalAnyTypedSerializerRendersOne.html +2 -2
  118. package/docs/interfaces/types.SerializerRendererOpts.html +2 -2
  119. package/docs/types/openapi.CommonOpenapiSchemaObjectFields.html +1 -1
  120. package/docs/types/openapi.OpenapiAllTypes.html +1 -1
  121. package/docs/types/openapi.OpenapiFormats.html +1 -1
  122. package/docs/types/openapi.OpenapiNumberFormats.html +1 -1
  123. package/docs/types/openapi.OpenapiPrimitiveBaseTypes.html +1 -1
  124. package/docs/types/openapi.OpenapiPrimitiveTypes.html +1 -1
  125. package/docs/types/openapi.OpenapiSchemaArray.html +1 -1
  126. package/docs/types/openapi.OpenapiSchemaArrayShorthand.html +1 -1
  127. package/docs/types/openapi.OpenapiSchemaBase.html +1 -1
  128. package/docs/types/openapi.OpenapiSchemaBody.html +1 -1
  129. package/docs/types/openapi.OpenapiSchemaBodyShorthand.html +1 -1
  130. package/docs/types/openapi.OpenapiSchemaCommonFields.html +1 -1
  131. package/docs/types/openapi.OpenapiSchemaExpressionAllOf.html +2 -2
  132. package/docs/types/openapi.OpenapiSchemaExpressionAnyOf.html +2 -2
  133. package/docs/types/openapi.OpenapiSchemaExpressionOneOf.html +2 -2
  134. package/docs/types/openapi.OpenapiSchemaExpressionRef.html +2 -2
  135. package/docs/types/openapi.OpenapiSchemaExpressionRefSchemaShorthand.html +2 -2
  136. package/docs/types/openapi.OpenapiSchemaInteger.html +1 -1
  137. package/docs/types/openapi.OpenapiSchemaNull.html +2 -2
  138. package/docs/types/openapi.OpenapiSchemaNumber.html +1 -1
  139. package/docs/types/openapi.OpenapiSchemaObject.html +1 -1
  140. package/docs/types/openapi.OpenapiSchemaObjectAllOf.html +1 -1
  141. package/docs/types/openapi.OpenapiSchemaObjectAllOfShorthand.html +1 -1
  142. package/docs/types/openapi.OpenapiSchemaObjectAnyOf.html +1 -1
  143. package/docs/types/openapi.OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  144. package/docs/types/openapi.OpenapiSchemaObjectBase.html +1 -1
  145. package/docs/types/openapi.OpenapiSchemaObjectBaseShorthand.html +1 -1
  146. package/docs/types/openapi.OpenapiSchemaObjectOneOf.html +1 -1
  147. package/docs/types/openapi.OpenapiSchemaObjectOneOfShorthand.html +1 -1
  148. package/docs/types/openapi.OpenapiSchemaObjectShorthand.html +1 -1
  149. package/docs/types/openapi.OpenapiSchemaPrimitiveGeneric.html +1 -1
  150. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAllOf.html +2 -2
  151. package/docs/types/openapi.OpenapiSchemaShorthandExpressionAnyOf.html +2 -2
  152. package/docs/types/openapi.OpenapiSchemaShorthandExpressionOneOf.html +2 -2
  153. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializableRef.html +2 -2
  154. package/docs/types/openapi.OpenapiSchemaShorthandExpressionSerializerRef.html +2 -2
  155. package/docs/types/openapi.OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  156. package/docs/types/openapi.OpenapiSchemaString.html +1 -1
  157. package/docs/types/openapi.OpenapiShorthandAllTypes.html +1 -1
  158. package/docs/types/openapi.OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  159. package/docs/types/openapi.OpenapiShorthandPrimitiveTypes.html +1 -1
  160. package/docs/types/openapi.OpenapiTypeField.html +1 -1
  161. package/docs/types/system.DreamAppAllowedPackageManagersEnum.html +1 -1
  162. package/docs/types/types.CalendarDateDurationUnit.html +1 -1
  163. package/docs/types/types.CalendarDateObject.html +1 -1
  164. package/docs/types/types.Camelized.html +1 -1
  165. package/docs/types/types.ClockTimeObject.html +1 -1
  166. package/docs/types/types.DbConnectionType.html +1 -1
  167. package/docs/types/types.DbTypes.html +1 -1
  168. package/docs/types/types.DreamAssociationMetadata.html +1 -1
  169. package/docs/types/types.DreamAttributes.html +1 -1
  170. package/docs/types/types.DreamClassAssociationAndStatement.html +1 -1
  171. package/docs/types/types.DreamClassColumn.html +1 -1
  172. package/docs/types/types.DreamColumn.html +1 -1
  173. package/docs/types/types.DreamColumnNames.html +1 -1
  174. package/docs/types/types.DreamLogLevel.html +1 -1
  175. package/docs/types/types.DreamLogger.html +2 -2
  176. package/docs/types/types.DreamModelSerializerType.html +1 -1
  177. package/docs/types/types.DreamOrViewModelClassSerializerKey.html +1 -1
  178. package/docs/types/types.DreamOrViewModelSerializerKey.html +1 -1
  179. package/docs/types/types.DreamParamSafeAttributes.html +1 -1
  180. package/docs/types/types.DreamParamSafeColumnNames.html +1 -1
  181. package/docs/types/types.DreamSerializable.html +1 -1
  182. package/docs/types/types.DreamSerializableArray.html +1 -1
  183. package/docs/types/types.DreamSerializerKey.html +1 -1
  184. package/docs/types/types.DreamSerializers.html +1 -1
  185. package/docs/types/types.DreamVirtualColumns.html +1 -1
  186. package/docs/types/types.DurationUnit.html +1 -1
  187. package/docs/types/types.EncryptAlgorithm.html +1 -1
  188. package/docs/types/types.HasManyStatement.html +1 -1
  189. package/docs/types/types.HasOneStatement.html +1 -1
  190. package/docs/types/types.Hyphenized.html +1 -1
  191. package/docs/types/types.Pascalized.html +1 -1
  192. package/docs/types/types.PrimaryKeyType.html +1 -1
  193. package/docs/types/types.RoundingPrecision.html +1 -1
  194. package/docs/types/types.SerializerCasing.html +1 -1
  195. package/docs/types/types.SimpleObjectSerializerType.html +1 -1
  196. package/docs/types/types.Snakeified.html +1 -1
  197. package/docs/types/types.StrictInterface.html +1 -1
  198. package/docs/types/types.UpdateableAssociationProperties.html +1 -1
  199. package/docs/types/types.UpdateableProperties.html +1 -1
  200. package/docs/types/types.ValidationType.html +1 -1
  201. package/docs/types/types.ViewModel.html +2 -2
  202. package/docs/types/types.ViewModelClass.html +1 -1
  203. package/docs/types/types.WeekdayName.html +1 -1
  204. package/docs/types/types.WhereStatementForDream.html +1 -1
  205. package/docs/types/types.WhereStatementForDreamClass.html +1 -1
  206. package/docs/variables/index.DreamConst.html +1 -1
  207. package/docs/variables/index.ops.html +1 -1
  208. package/docs/variables/openapi.openapiPrimitiveTypes.html +1 -1
  209. package/docs/variables/openapi.openapiShorthandPrimitiveTypes.html +1 -1
  210. package/docs/variables/system.DreamAppAllowedPackageManagersEnumValues.html +1 -1
  211. package/docs/variables/system.primaryKeyTypes.html +1 -1
  212. package/package.json +6 -8
@@ -47,7 +47,6 @@ import MissingSerializersDefinition from './errors/serializers/MissingSerializer
47
47
  import areEqual from './helpers/areEqual.js';
48
48
  import cloneDeepSafe from './helpers/cloneDeepSafe.js';
49
49
  import compact from './helpers/compact.js';
50
- import cachedTypeForAttribute from './helpers/db/cachedTypeForAttribute.js';
51
50
  import isJsonColumn from './helpers/db/types/isJsonColumn.js';
52
51
  import notEqual from './helpers/notEqual.js';
53
52
  import { inferSerializersFromDreamClassOrViewModelClass } from './serializer/helpers/inferSerializerFromDreamOrViewModel.js';
@@ -2701,14 +2700,6 @@ export default class Dream {
2701
2700
  getAttributes() {
2702
2701
  return { ...this.currentAttributes };
2703
2702
  }
2704
- /**
2705
- * @internal
2706
- *
2707
- * Returns the db type stored within the database
2708
- */
2709
- static cachedTypeFor(attribute) {
2710
- return cachedTypeForAttribute(this, attribute);
2711
- }
2712
2703
  /**
2713
2704
  * Returns the attributes that have changed since
2714
2705
  * being persisted to the database, with the values
@@ -7,6 +7,7 @@ import EnvInternal from '../helpers/EnvInternal.js';
7
7
  import loadRepl from '../helpers/loadRepl.js';
8
8
  import sspawn from '../helpers/sspawn.js';
9
9
  import DreamCliLogger from './logger/DreamCliLogger.js';
10
+ import colorize from './logger/loggable/colorize.js';
10
11
  export const CLI_INDENT = ' ';
11
12
  const INDENT = CLI_INDENT;
12
13
  export const baseColumnsWithTypesDescription = `space separated snake-case (except for belongs_to model name) properties like this:
@@ -90,8 +91,8 @@ export default class DreamCLI {
90
91
  program
91
92
  .command('sync')
92
93
  .description('Generates types from the current state of the database.')
93
- .option('--schema-only')
94
- .action(async (options = {}) => {
94
+ .option('--schema-only', 'sync database schema types only', false)
95
+ .action(async (options) => {
95
96
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
96
97
  await DreamBin.sync(() => { }, options);
97
98
  process.exit();
@@ -135,11 +136,11 @@ export default class DreamCLI {
135
136
  .description('Generates a Dream model with corresponding spec factory, serializer, and migration.')
136
137
  .option('--no-serializer')
137
138
  .option('--connection-name <connectionName>', 'the db connection you want this attached to (defaults to the default db connection)', 'default')
138
- .option('--sti-base-serializer')
139
+ .option('--sti-base-serializer', 'creates a generically typed base serializer that includes the child type in the output so consuming applications can determine shape based on type', false)
139
140
  .option('--table-name <tableName>', 'explicit table name to use instead of the auto-generated one (useful when model namespaces produce long names)')
140
141
  .option('--model-name <modelName>', 'explicit model class name to use instead of the auto-generated one (e.g. --model-name=Kitchen for Room/Kitchen)')
141
- .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers')
142
- .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers')
142
+ .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers', false)
143
+ .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers', false)
143
144
  .argument('<modelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
144
145
  .argument('[columnsWithTypes...]', columnsWithTypesDescription)
145
146
  .action(async (modelName, columnsWithTypes, options) => {
@@ -154,8 +155,8 @@ export default class DreamCLI {
154
155
  .option('--no-serializer')
155
156
  .option('--connection-name', 'the db connection you want this model attached to (defaults to the default connection)', 'default')
156
157
  .option('--model-name <modelName>', 'explicit model class name to use instead of the auto-generated one (e.g. --model-name=Kitchen for Room/Kitchen)')
157
- .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers')
158
- .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers')
158
+ .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers', false)
159
+ .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers', false)
159
160
  .argument('<childModelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
160
161
  .argument('<extends>', 'just the word "extends"')
161
162
  .argument('<parentModelName>', `fully qualified name of the parent model, e.g.:
@@ -200,7 +201,7 @@ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Co
200
201
  program
201
202
  .command('db:migrate')
202
203
  .description('Runs any outstanding database migrations.')
203
- .option('--skip-sync', 'skips syncing local schema after running migrations')
204
+ .option('--skip-sync', 'skips syncing local schema after running migrations', false)
204
205
  .action(async ({ skipSync }) => {
205
206
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
206
207
  await DreamBin.dbMigrate();
@@ -213,7 +214,7 @@ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Co
213
214
  .command('db:rollback')
214
215
  .description('Rolls back the specified number of migration steps (defaults to 1)')
215
216
  .option('--steps <number>', 'number of steps back to travel', myParseInt, 1)
216
- .option('--skip-sync', 'skips syncing local schema after running migrations')
217
+ .option('--skip-sync', 'skips syncing local schema after running migrations', false)
217
218
  .action(async ({ steps, skipSync }) => {
218
219
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
219
220
  await DreamBin.dbRollback({ steps });
@@ -235,12 +236,39 @@ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Co
235
236
  .description('Runs db:drop (safely), db:create, db:migrate, and db:seed')
236
237
  .action(async () => {
237
238
  await initializeDreamApp({ bypassDreamIntegrityChecks: true, bypassDbConnectionsDuringInit: true });
239
+ const arrows = colorize('⭣⭣⭣', { color: 'green' }) + '\n';
240
+ DreamCLI.logger.log(colorize('db:drop', { color: 'green' }), {
241
+ logPrefix: ' ',
242
+ logPrefixColor: 'green',
243
+ });
238
244
  await DreamBin.dbDrop();
245
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
246
+ DreamCLI.logger.log(colorize('db:create', { color: 'green' }), {
247
+ logPrefix: ' ',
248
+ logPrefixColor: 'green',
249
+ });
239
250
  await DreamBin.dbCreate();
251
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
240
252
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
253
+ DreamCLI.logger.log(colorize('db:migrate', { color: 'green' }), {
254
+ logPrefix: ' ',
255
+ logPrefixColor: 'green',
256
+ });
241
257
  await DreamBin.dbMigrate();
258
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
259
+ DreamCLI.logger.log(colorize('sync', { color: 'green' }), {
260
+ logPrefix: ' ',
261
+ logPrefixColor: 'green',
262
+ });
242
263
  await DreamBin.sync(onSync);
243
- await seedDb();
264
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
265
+ DreamCLI.logger.log(colorize('db:seed', { color: 'green' }), {
266
+ logPrefix: ' ',
267
+ logPrefixColor: 'green',
268
+ });
269
+ await DreamCLI.logger.logProgress('seeding db...', async () => {
270
+ await seedDb();
271
+ });
244
272
  process.exit();
245
273
  });
246
274
  program
@@ -1,25 +1,126 @@
1
+ import c from 'yoctocolors';
1
2
  import DreamCliLoggableText from './loggable/DreamCliLoggableText.js';
3
+ const SPINNER_FRAMES = ['✺', '✹', '✸', '✷', '✶', '✵', '✴', '✵', '✶', '✷', '✸', '✹'];
4
+ const EYE_FRAMES = ['─', '◡', '◯', '◉', '●', '◉', '◯', '◡'];
5
+ const SPINNER_INTERVAL_MS = 200;
6
+ function formatElapsed(ms) {
7
+ if (ms < 1000)
8
+ return `${ms}ms`;
9
+ return `${(ms / 1000).toFixed(1)}s`;
10
+ }
2
11
  export default class DreamCliLogger {
12
+ spinner = null;
3
13
  log(text, { logPrefix, logPrefixColor, logPrefixBgColor } = {}) {
4
14
  const loggable = new DreamCliLoggableText(text, {
5
15
  logPrefix,
6
- logPrefixColor: logPrefixColor || 'green',
16
+ logPrefixColor: logPrefixColor || 'greenBright',
7
17
  logPrefixBgColor,
8
18
  });
9
19
  loggable.render();
10
20
  }
11
21
  async logProgress(text, cb, { logPrefix = '✺ ┌', logPrefixColor, logPrefixBgColor } = {}) {
12
- this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
22
+ this.logStartProgress(text, { logPrefix, logPrefixColor, logPrefixBgColor });
13
23
  await cb();
14
24
  this.logEndProgress();
15
25
  }
16
- logStartProgress(text, { logPrefix = '✺ ┌', logPrefixColor, logPrefixBgColor } = {}) {
17
- this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
26
+ logStartProgress(text, { logPrefixColor, logPrefixBgColor } = {}) {
27
+ if (!process.stdout.isTTY) {
28
+ this.log(text, { logPrefix: '✺ ┌', logPrefixColor: logPrefixColor || 'greenBright', logPrefixBgColor });
29
+ return;
30
+ }
31
+ this.startTopSpinner(text);
32
+ }
33
+ startTopSpinner(text) {
34
+ const renderFrame = (frameIndex) => {
35
+ const star = SPINNER_FRAMES[frameIndex % SPINNER_FRAMES.length];
36
+ process.stdout.write(`${this.escapeSequence('clearLine')}${c.yellow(`${star} ┌`)} ${c.yellow(text)}`);
37
+ };
38
+ renderFrame(0);
39
+ const interval = setInterval(() => {
40
+ if (this.spinner && !this.spinner.committed) {
41
+ this.spinner.frameIndex++;
42
+ renderFrame(this.spinner.frameIndex);
43
+ }
44
+ }, SPINNER_INTERVAL_MS);
45
+ this.spinner = {
46
+ actionText: text,
47
+ startTime: Date.now(),
48
+ frameIndex: 0,
49
+ interval,
50
+ committed: false,
51
+ };
52
+ }
53
+ startBottomSpinner() {
54
+ if (!process.stdout.isTTY || !this.spinner)
55
+ return;
56
+ const renderFrame = (frameIndex) => {
57
+ const eye = EYE_FRAMES[frameIndex % EYE_FRAMES.length];
58
+ process.stdout.write(`${this.escapeSequence('clearLine')}${c.yellow(eye)} ${c.yellow(`└ ${this.spinner.actionText}`)}`);
59
+ };
60
+ this.spinner.frameIndex = 0;
61
+ renderFrame(0);
62
+ this.spinner.interval = setInterval(() => {
63
+ if (this.spinner) {
64
+ this.spinner.frameIndex++;
65
+ renderFrame(this.spinner.frameIndex);
66
+ }
67
+ }, SPINNER_INTERVAL_MS);
18
68
  }
19
69
  logContinueProgress(text, { logPrefix = ' ├', logPrefixColor, logPrefixBgColor } = {}) {
20
- this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
70
+ if (this.spinner && !this.spinner.committed) {
71
+ clearInterval(this.spinner.interval);
72
+ // Overwrite the yellow animated header with green past-tense text before marking
73
+ // the spinner as committed
74
+ process.stdout.write(`${this.escapeSequence('clearLine')}${c.greenBright('✺ ┌')} ${c.greenBright(this.spinner.actionText)}\n`);
75
+ this.spinner.committed = true;
76
+ this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
77
+ this.startBottomSpinner();
78
+ }
79
+ else if (this.spinner?.committed) {
80
+ // Clear the bottom running... spinner, log sub-line, then re-show it
81
+ clearInterval(this.spinner.interval);
82
+ this.clearLine();
83
+ this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
84
+ this.startBottomSpinner();
85
+ }
86
+ else {
87
+ this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
88
+ }
21
89
  }
22
90
  logEndProgress(text = 'complete', { logPrefix = ' └', logPrefixColor, logPrefixBgColor } = {}) {
23
- this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
91
+ if (!this.spinner) {
92
+ this.log(text, { logPrefix, logPrefixColor, logPrefixBgColor });
93
+ return;
94
+ }
95
+ const spinner = this.spinner;
96
+ this.spinner = null;
97
+ clearInterval(spinner.interval);
98
+ const elapsed = Date.now() - spinner.startTime;
99
+ const elapsedStr = formatElapsed(elapsed);
100
+ if (!spinner.committed) {
101
+ // No sub-lines: overwrite the spinner in-place with the green completed header
102
+ process.stdout.write(`${this.escapeSequence('clearLine')}${c.greenBright('✺ ┌')} ${c.greenBright(spinner.actionText)}\n`);
103
+ }
104
+ else {
105
+ // Has sub-lines: clear the bottom running... spinner line
106
+ if (process.stdout.isTTY)
107
+ this.clearLine();
108
+ }
109
+ this.log(c.greenBright(`done in ${elapsedStr}\n`), {
110
+ logPrefix,
111
+ logPrefixColor: logPrefixColor || 'greenBright',
112
+ logPrefixBgColor,
113
+ });
114
+ }
115
+ clearLine() {
116
+ process.stdout.write(this.escapeSequence('clearLine'));
117
+ }
118
+ escapeSequence(sequence) {
119
+ switch (sequence) {
120
+ case 'clearLine':
121
+ return `\r\x1b[2K`;
122
+ default:
123
+ throw new Error(`unexpected sequence: ${sequence}`);
124
+ }
24
125
  }
25
126
  }
@@ -28,8 +28,8 @@ export default async function syncDbTypesFiles(connectionName) {
28
28
  const kyselyCodegenCmd = `kysely-codegen ${dialect} ${url} ${includePattern} ${excludePattern} ${outfile}`;
29
29
  await sspawn(kyselyCodegenCmd, {
30
30
  onStdout: message => {
31
- DreamCLI.logger.logContinueProgress(colorize(`[db]`, { color: 'cyan' }) + ' ' + message, {
32
- logPrefixColor: 'cyan',
31
+ DreamCLI.logger.logContinueProgress(colorize(`[db]`, { color: 'greenBright' }) + ' ' + message, {
32
+ logPrefixColor: 'greenBright',
33
33
  });
34
34
  },
35
35
  });
@@ -1,5 +1,6 @@
1
1
  import InternalEncrypt from '../../encrypt/InternalEncrypt.js';
2
2
  import DoNotSetEncryptedFieldsDirectly from '../../errors/DoNotSetEncryptedFieldsDirectly.js';
3
+ import columnAllowsNull from '../../helpers/db/columnAllowsNull.js';
3
4
  import pascalize from '../../helpers/pascalize.js';
4
5
  export default function Encrypted(encryptedColumnName) {
5
6
  return function (_, context) {
@@ -29,7 +30,7 @@ export default function Encrypted(encryptedColumnName) {
29
30
  ;
30
31
  dreamClass['virtualAttributes'].push({
31
32
  property: key,
32
- type: 'string',
33
+ type: columnAllowsNull(dreamClass, encryptedKey) ? ['string', 'null'] : 'string',
33
34
  });
34
35
  if (!Object.getOwnPropertyDescriptor(dreamClass, 'explicitUnsafeParamColumns')) {
35
36
  // This pattern allows `explicitUnsafeParamColumns` on a base STI class and on
@@ -157,13 +157,13 @@ export default class PostgresQueryDriver extends KyselyQueryDriver {
157
157
  const client = await loadPgClient({ useSystemDb: true, connectionName });
158
158
  if (EnvInternal.boolean('DREAM_CORE_DEVELOPMENT')) {
159
159
  const replicaTestWorkerDatabaseName = `replica_test_${dbConf.name}`;
160
- DreamCLI.logger.logContinueProgress(`creating fake replica test database ${replicaTestWorkerDatabaseName}...`, { logPrefix: ' ├ [db]', logPrefixColor: 'cyan' });
160
+ DreamCLI.logger.logContinueProgress(`creating fake replica test database ${replicaTestWorkerDatabaseName}...`, { logPrefix: ' ├ [db]', logPrefixColor: 'greenBright' });
161
161
  await client.query(`DROP DATABASE IF EXISTS ${replicaTestWorkerDatabaseName};`);
162
162
  await client.query(`CREATE DATABASE ${replicaTestWorkerDatabaseName} TEMPLATE ${dbConf.name};`);
163
163
  }
164
164
  for (let i = 2; i <= parallelTests; i++) {
165
165
  const workerDatabaseName = `${dbConf.name}_${i}`;
166
- DreamCLI.logger.logContinueProgress(`creating duplicate test database ${workerDatabaseName} for concurrent tests...`, { logPrefix: ' ├ [db]', logPrefixColor: 'cyan' });
166
+ DreamCLI.logger.logContinueProgress(`creating duplicate test database ${workerDatabaseName} for concurrent tests...`, { logPrefix: ' ├ [db]', logPrefixColor: 'greenBright' });
167
167
  await client.query(`DROP DATABASE IF EXISTS ${workerDatabaseName};`);
168
168
  await client.query(`CREATE DATABASE ${workerDatabaseName} TEMPLATE ${dbConf.name};`);
169
169
  }
@@ -88,8 +88,8 @@ function migratedActionPastTense(mode) {
88
88
  function logResults(results, mode) {
89
89
  results?.forEach(it => {
90
90
  if (it.status === 'Success') {
91
- DreamCLI.logger.logContinueProgress(colorize(`[db]`, { color: 'cyan' }) +
92
- ` migration "${it.migrationName}" was ${migratedActionPastTense(mode)} successfully`, { logPrefixColor: 'cyan' });
91
+ DreamCLI.logger.logContinueProgress(colorize(`[db]`, { color: 'greenBright' }) +
92
+ ` migration "${it.migrationName}" was ${migratedActionPastTense(mode)} successfully`, { logPrefixColor: 'greenBright' });
93
93
  }
94
94
  else if (it.status === 'Error') {
95
95
  DreamCLI.logger.logContinueProgress(JSON.stringify(it, null, 2));
@@ -22,14 +22,14 @@ async function maybeDropDuplicateDatabases(client, dbName) {
22
22
  return;
23
23
  if (EnvInternal.boolean('DREAM_CORE_DEVELOPMENT')) {
24
24
  const replicaTestWorkerDatabaseName = `replica_test_${dbName}`;
25
- DreamCLI.logger.logContinueProgress(`dropping fake replica test database ${replicaTestWorkerDatabaseName}`, { logPrefix: ' ├ [db]', logPrefixColor: 'cyan' });
25
+ DreamCLI.logger.logContinueProgress(`dropping fake replica test database ${replicaTestWorkerDatabaseName}`, { logPrefix: ' ├ [db]', logPrefixColor: 'greenBright' });
26
26
  await client.query(`DROP DATABASE IF EXISTS ${replicaTestWorkerDatabaseName};`);
27
27
  }
28
28
  for (let i = 2; i <= parallelTests; i++) {
29
29
  const workerDatabaseName = `${dbName}_${i}`;
30
30
  DreamCLI.logger.logContinueProgress(`dropping duplicate test database ${workerDatabaseName}`, {
31
31
  logPrefix: ' ├ [db]',
32
- logPrefixColor: 'cyan',
32
+ logPrefixColor: 'greenBright',
33
33
  });
34
34
  await client.query(`DROP DATABASE IF EXISTS ${workerDatabaseName};`);
35
35
  }
@@ -0,0 +1,3 @@
1
+ export default function columnAllowsNull(dreamClass, attribute) {
2
+ return dreamClass.prototype.schema[dreamClass.table]?.['columns']?.[attribute]?.['allowNull'] ?? false;
3
+ }
@@ -1,3 +1,4 @@
1
+ import cachedTypeForAttribute from './cachedTypeForAttribute.js';
1
2
  import DataTypeColumnTypeMismatch from '../../errors/db/DataTypeColumnTypeMismatch.js';
2
3
  import BaseClockTime from '../../utils/datetime/BaseClockTime.js';
3
4
  import CalendarDate from '../../utils/datetime/CalendarDate.js';
@@ -7,7 +8,7 @@ import { DateTime } from '../../utils/datetime/DateTime.js';
7
8
  import normalizeUnicode from '../normalizeUnicode.js';
8
9
  import { DATE_OR_DATE_ARRAY_COLUMN_CHECK_REGEXP, DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP, STRING_OR_STRING_ARRAY_COLUMN_CHECK_REGEXP, TIME_WITH_TIMEZONE_COLUMN_CHECK_REGEXP, TIME_WITHOUT_TIMEZONE_COLUMN_CHECK_REGEXP, } from './types/helpers.js';
9
10
  export function normalizeDataForDb({ val, dreamClass, column, }) {
10
- const columnType = dreamClass['cachedTypeFor'](column);
11
+ const columnType = cachedTypeForAttribute(dreamClass, column);
11
12
  if (val instanceof DateTime || DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP.test(columnType)) {
12
13
  return dateTimeOrDateToSql(DateTime, val);
13
14
  //
@@ -1,3 +1,4 @@
1
+ import cachedTypeForAttribute from '../cachedTypeForAttribute.js';
1
2
  export default function isDatabaseArrayColumn(dreamClass, column) {
2
- return /\[\]$/.test(dreamClass['cachedTypeFor'](column));
3
+ return /\[\]$/.test(cachedTypeForAttribute(dreamClass, column));
3
4
  }
@@ -1,4 +1,5 @@
1
+ import cachedTypeForAttribute from '../cachedTypeForAttribute.js';
1
2
  import { DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP } from './helpers.js';
2
3
  export default function isDatetimeOrDatetimeArrayColumn(dreamClass, column) {
3
- return DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP.test(dreamClass['cachedTypeFor'](column));
4
+ return DATETIME_OR_DATETIME_ARRAY_COLUMN_CHECK_REGEXP.test(cachedTypeForAttribute(dreamClass, column));
4
5
  }
@@ -1,3 +1,4 @@
1
+ import cachedTypeForAttribute from '../cachedTypeForAttribute.js';
1
2
  export default function isJsonColumn(dreamClass, column) {
2
- return ['json', 'jsonb'].includes(dreamClass['cachedTypeFor'](column));
3
+ return ['json', 'jsonb'].includes(cachedTypeForAttribute(dreamClass, column));
3
4
  }
@@ -1,5 +1,6 @@
1
1
  import { sql } from 'kysely';
2
2
  import AnyRequiresArrayColumn from '../errors/ops/AnyRequiresArrayColumn.js';
3
+ import cachedTypeForAttribute from '../helpers/db/cachedTypeForAttribute.js';
3
4
  import isDatabaseArrayColumn from '../helpers/db/types/isDatabaseArrayColumn.js';
4
5
  import CurriedOpsStatement from './curried-ops-statement.js';
5
6
  import OpsStatement from './ops-statement.js';
@@ -10,7 +11,7 @@ const ops = {
10
11
  const column = fieldName.replace(/^.*\./, '');
11
12
  if (!isDatabaseArrayColumn(dreamClass, column))
12
13
  throw new AnyRequiresArrayColumn(dreamClass, column);
13
- const castType = dreamClass['cachedTypeFor'](column);
14
+ const castType = cachedTypeForAttribute(dreamClass, column);
14
15
  return new OpsStatement('@>', sql `ARRAY[${sql.join([value])}]::${sql.raw(castType)}`);
15
16
  }),
16
17
  like: (like) => new OpsStatement('like', like),
@@ -47,7 +47,6 @@ import MissingSerializersDefinition from './errors/serializers/MissingSerializer
47
47
  import areEqual from './helpers/areEqual.js';
48
48
  import cloneDeepSafe from './helpers/cloneDeepSafe.js';
49
49
  import compact from './helpers/compact.js';
50
- import cachedTypeForAttribute from './helpers/db/cachedTypeForAttribute.js';
51
50
  import isJsonColumn from './helpers/db/types/isJsonColumn.js';
52
51
  import notEqual from './helpers/notEqual.js';
53
52
  import { inferSerializersFromDreamClassOrViewModelClass } from './serializer/helpers/inferSerializerFromDreamOrViewModel.js';
@@ -2701,14 +2700,6 @@ export default class Dream {
2701
2700
  getAttributes() {
2702
2701
  return { ...this.currentAttributes };
2703
2702
  }
2704
- /**
2705
- * @internal
2706
- *
2707
- * Returns the db type stored within the database
2708
- */
2709
- static cachedTypeFor(attribute) {
2710
- return cachedTypeForAttribute(this, attribute);
2711
- }
2712
2703
  /**
2713
2704
  * Returns the attributes that have changed since
2714
2705
  * being persisted to the database, with the values
@@ -7,6 +7,7 @@ import EnvInternal from '../helpers/EnvInternal.js';
7
7
  import loadRepl from '../helpers/loadRepl.js';
8
8
  import sspawn from '../helpers/sspawn.js';
9
9
  import DreamCliLogger from './logger/DreamCliLogger.js';
10
+ import colorize from './logger/loggable/colorize.js';
10
11
  export const CLI_INDENT = ' ';
11
12
  const INDENT = CLI_INDENT;
12
13
  export const baseColumnsWithTypesDescription = `space separated snake-case (except for belongs_to model name) properties like this:
@@ -90,8 +91,8 @@ export default class DreamCLI {
90
91
  program
91
92
  .command('sync')
92
93
  .description('Generates types from the current state of the database.')
93
- .option('--schema-only')
94
- .action(async (options = {}) => {
94
+ .option('--schema-only', 'sync database schema types only', false)
95
+ .action(async (options) => {
95
96
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
96
97
  await DreamBin.sync(() => { }, options);
97
98
  process.exit();
@@ -135,11 +136,11 @@ export default class DreamCLI {
135
136
  .description('Generates a Dream model with corresponding spec factory, serializer, and migration.')
136
137
  .option('--no-serializer')
137
138
  .option('--connection-name <connectionName>', 'the db connection you want this attached to (defaults to the default db connection)', 'default')
138
- .option('--sti-base-serializer')
139
+ .option('--sti-base-serializer', 'creates a generically typed base serializer that includes the child type in the output so consuming applications can determine shape based on type', false)
139
140
  .option('--table-name <tableName>', 'explicit table name to use instead of the auto-generated one (useful when model namespaces produce long names)')
140
141
  .option('--model-name <modelName>', 'explicit model class name to use instead of the auto-generated one (e.g. --model-name=Kitchen for Room/Kitchen)')
141
- .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers')
142
- .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers')
142
+ .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers', false)
143
+ .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers', false)
143
144
  .argument('<modelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
144
145
  .argument('[columnsWithTypes...]', columnsWithTypesDescription)
145
146
  .action(async (modelName, columnsWithTypes, options) => {
@@ -154,8 +155,8 @@ export default class DreamCLI {
154
155
  .option('--no-serializer')
155
156
  .option('--connection-name', 'the db connection you want this model attached to (defaults to the default connection)', 'default')
156
157
  .option('--model-name <modelName>', 'explicit model class name to use instead of the auto-generated one (e.g. --model-name=Kitchen for Room/Kitchen)')
157
- .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers')
158
- .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers')
158
+ .option('--admin-serializers', 'generate admin serializer variants (AdminSerializer and AdminSummarySerializer) in addition to the default serializers', false)
159
+ .option('--internal-serializers', 'generate internal serializer variants (InternalSerializer and InternalSummarySerializer) in addition to the default serializers', false)
159
160
  .argument('<childModelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
160
161
  .argument('<extends>', 'just the word "extends"')
161
162
  .argument('<parentModelName>', `fully qualified name of the parent model, e.g.:
@@ -200,7 +201,7 @@ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Co
200
201
  program
201
202
  .command('db:migrate')
202
203
  .description('Runs any outstanding database migrations.')
203
- .option('--skip-sync', 'skips syncing local schema after running migrations')
204
+ .option('--skip-sync', 'skips syncing local schema after running migrations', false)
204
205
  .action(async ({ skipSync }) => {
205
206
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
206
207
  await DreamBin.dbMigrate();
@@ -213,7 +214,7 @@ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Co
213
214
  .command('db:rollback')
214
215
  .description('Rolls back the specified number of migration steps (defaults to 1)')
215
216
  .option('--steps <number>', 'number of steps back to travel', myParseInt, 1)
216
- .option('--skip-sync', 'skips syncing local schema after running migrations')
217
+ .option('--skip-sync', 'skips syncing local schema after running migrations', false)
217
218
  .action(async ({ steps, skipSync }) => {
218
219
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
219
220
  await DreamBin.dbRollback({ steps });
@@ -235,12 +236,39 @@ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Co
235
236
  .description('Runs db:drop (safely), db:create, db:migrate, and db:seed')
236
237
  .action(async () => {
237
238
  await initializeDreamApp({ bypassDreamIntegrityChecks: true, bypassDbConnectionsDuringInit: true });
239
+ const arrows = colorize('⭣⭣⭣', { color: 'green' }) + '\n';
240
+ DreamCLI.logger.log(colorize('db:drop', { color: 'green' }), {
241
+ logPrefix: ' ',
242
+ logPrefixColor: 'green',
243
+ });
238
244
  await DreamBin.dbDrop();
245
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
246
+ DreamCLI.logger.log(colorize('db:create', { color: 'green' }), {
247
+ logPrefix: ' ',
248
+ logPrefixColor: 'green',
249
+ });
239
250
  await DreamBin.dbCreate();
251
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
240
252
  await initializeDreamApp({ bypassDreamIntegrityChecks: true });
253
+ DreamCLI.logger.log(colorize('db:migrate', { color: 'green' }), {
254
+ logPrefix: ' ',
255
+ logPrefixColor: 'green',
256
+ });
241
257
  await DreamBin.dbMigrate();
258
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
259
+ DreamCLI.logger.log(colorize('sync', { color: 'green' }), {
260
+ logPrefix: ' ',
261
+ logPrefixColor: 'green',
262
+ });
242
263
  await DreamBin.sync(onSync);
243
- await seedDb();
264
+ DreamCLI.logger.log(arrows, { logPrefix: ' ' });
265
+ DreamCLI.logger.log(colorize('db:seed', { color: 'green' }), {
266
+ logPrefix: ' ',
267
+ logPrefixColor: 'green',
268
+ });
269
+ await DreamCLI.logger.logProgress('seeding db...', async () => {
270
+ await seedDb();
271
+ });
244
272
  process.exit();
245
273
  });
246
274
  program