@rvoh/dream 0.45.1 → 0.45.2

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 (189) hide show
  1. package/dist/cjs/src/bin/index.js +6 -2
  2. package/dist/cjs/src/cli/index.js +41 -5
  3. package/dist/cjs/src/helpers/cli/generateDream.js +2 -0
  4. package/dist/cjs/src/helpers/cli/generateDreamContent.js +6 -2
  5. package/dist/cjs/src/helpers/cli/generateFactoryContent.js +27 -17
  6. package/dist/cjs/src/helpers/cli/generateMigrationContent.js +45 -39
  7. package/dist/cjs/src/helpers/cli/generateSerializer.js +2 -1
  8. package/dist/cjs/src/helpers/cli/generateSerializerContent.js +20 -8
  9. package/dist/esm/src/bin/index.js +6 -2
  10. package/dist/esm/src/cli/index.js +41 -5
  11. package/dist/esm/src/helpers/cli/generateDream.js +2 -0
  12. package/dist/esm/src/helpers/cli/generateDreamContent.js +6 -2
  13. package/dist/esm/src/helpers/cli/generateFactoryContent.js +27 -17
  14. package/dist/esm/src/helpers/cli/generateMigrationContent.js +45 -39
  15. package/dist/esm/src/helpers/cli/generateSerializer.js +2 -1
  16. package/dist/esm/src/helpers/cli/generateSerializerContent.js +20 -8
  17. package/dist/types/src/helpers/cli/generateDream.d.ts +1 -0
  18. package/dist/types/src/helpers/cli/generateDreamContent.d.ts +2 -1
  19. package/dist/types/src/helpers/cli/generateSerializer.d.ts +2 -1
  20. package/dist/types/src/helpers/cli/generateSerializerContent.d.ts +3 -2
  21. package/docs/classes/Benchmark.html +2 -2
  22. package/docs/classes/CalendarDate.html +2 -2
  23. package/docs/classes/CreateOrFindByFailedToCreateAndFind.html +3 -3
  24. package/docs/classes/Decorators.html +19 -19
  25. package/docs/classes/Dream.html +136 -136
  26. package/docs/classes/DreamApp.html +4 -4
  27. package/docs/classes/DreamBin.html +2 -2
  28. package/docs/classes/DreamCLI.html +4 -4
  29. package/docs/classes/DreamImporter.html +2 -2
  30. package/docs/classes/DreamLogos.html +2 -2
  31. package/docs/classes/DreamMigrationHelpers.html +7 -7
  32. package/docs/classes/DreamSerializerBuilder.html +8 -8
  33. package/docs/classes/DreamTransaction.html +2 -2
  34. package/docs/classes/Encrypt.html +2 -2
  35. package/docs/classes/Env.html +2 -2
  36. package/docs/classes/GlobalNameNotSet.html +3 -3
  37. package/docs/classes/NonLoadedAssociation.html +3 -3
  38. package/docs/classes/ObjectSerializerBuilder.html +8 -8
  39. package/docs/classes/Query.html +60 -60
  40. package/docs/classes/Range.html +2 -2
  41. package/docs/classes/RecordNotFound.html +3 -3
  42. package/docs/classes/ValidationError.html +3 -3
  43. package/docs/functions/DreamSerializer.html +1 -1
  44. package/docs/functions/ObjectSerializer.html +1 -1
  45. package/docs/functions/ReplicaSafe.html +1 -1
  46. package/docs/functions/STI.html +1 -1
  47. package/docs/functions/SoftDelete.html +1 -1
  48. package/docs/functions/camelize.html +1 -1
  49. package/docs/functions/capitalize.html +1 -1
  50. package/docs/functions/cloneDeepSafe.html +1 -1
  51. package/docs/functions/closeAllDbConnections.html +1 -1
  52. package/docs/functions/compact.html +1 -1
  53. package/docs/functions/dreamDbConnections.html +1 -1
  54. package/docs/functions/dreamPath.html +1 -1
  55. package/docs/functions/expandStiClasses.html +1 -1
  56. package/docs/functions/generateDream.html +1 -1
  57. package/docs/functions/globalClassNameFromFullyQualifiedModelName.html +1 -1
  58. package/docs/functions/groupBy.html +1 -1
  59. package/docs/functions/hyphenize.html +1 -1
  60. package/docs/functions/inferSerializerFromDreamOrViewModel.html +1 -1
  61. package/docs/functions/inferSerializersFromDreamClassOrViewModelClass.html +1 -1
  62. package/docs/functions/intersection.html +1 -1
  63. package/docs/functions/isDreamSerializer.html +1 -1
  64. package/docs/functions/isEmpty.html +1 -1
  65. package/docs/functions/loadRepl.html +1 -1
  66. package/docs/functions/lookupClassByGlobalName.html +1 -1
  67. package/docs/functions/normalizeUnicode.html +1 -1
  68. package/docs/functions/pascalize.html +1 -1
  69. package/docs/functions/pgErrorType.html +1 -1
  70. package/docs/functions/range-1.html +1 -1
  71. package/docs/functions/relativeDreamPath.html +1 -1
  72. package/docs/functions/round.html +1 -1
  73. package/docs/functions/serializerNameFromFullyQualifiedModelName.html +1 -1
  74. package/docs/functions/sharedPathPrefix.html +1 -1
  75. package/docs/functions/snakeify.html +1 -1
  76. package/docs/functions/sort.html +1 -1
  77. package/docs/functions/sortBy.html +1 -1
  78. package/docs/functions/sortObjectByKey.html +1 -1
  79. package/docs/functions/sortObjectByValue.html +1 -1
  80. package/docs/functions/standardizeFullyQualifiedModelName.html +1 -1
  81. package/docs/functions/uncapitalize.html +1 -1
  82. package/docs/functions/uniq.html +1 -1
  83. package/docs/functions/untypedDb.html +1 -1
  84. package/docs/functions/validateColumn.html +1 -1
  85. package/docs/functions/validateTable.html +1 -1
  86. package/docs/interfaces/BelongsToStatement.html +2 -2
  87. package/docs/interfaces/DecoratorContext.html +2 -2
  88. package/docs/interfaces/DreamAppInitOptions.html +2 -2
  89. package/docs/interfaces/DreamAppOpts.html +2 -2
  90. package/docs/interfaces/EncryptOptions.html +2 -2
  91. package/docs/interfaces/InternalAnyTypedSerializerRendersMany.html +2 -2
  92. package/docs/interfaces/InternalAnyTypedSerializerRendersOne.html +2 -2
  93. package/docs/interfaces/OpenapiDescription.html +2 -2
  94. package/docs/interfaces/OpenapiSchemaProperties.html +1 -1
  95. package/docs/interfaces/OpenapiSchemaPropertiesShorthand.html +1 -1
  96. package/docs/interfaces/OpenapiTypeFieldObject.html +1 -1
  97. package/docs/interfaces/SerializerRendererOpts.html +2 -2
  98. package/docs/types/Camelized.html +1 -1
  99. package/docs/types/CommonOpenapiSchemaObjectFields.html +1 -1
  100. package/docs/types/DateTime.html +1 -1
  101. package/docs/types/DbConnectionType.html +1 -1
  102. package/docs/types/DbTypes.html +1 -1
  103. package/docs/types/DreamAssociationMetadata.html +1 -1
  104. package/docs/types/DreamAttributes.html +1 -1
  105. package/docs/types/DreamClassAssociationAndStatement.html +1 -1
  106. package/docs/types/DreamClassColumn.html +1 -1
  107. package/docs/types/DreamColumn.html +1 -1
  108. package/docs/types/DreamColumnNames.html +1 -1
  109. package/docs/types/DreamLogLevel.html +1 -1
  110. package/docs/types/DreamLogger.html +1 -1
  111. package/docs/types/DreamModelSerializerType.html +1 -1
  112. package/docs/types/DreamOrViewModelClassSerializerKey.html +1 -1
  113. package/docs/types/DreamOrViewModelSerializerKey.html +1 -1
  114. package/docs/types/DreamParamSafeAttributes.html +1 -1
  115. package/docs/types/DreamParamSafeColumnNames.html +1 -1
  116. package/docs/types/DreamSerializable.html +1 -1
  117. package/docs/types/DreamSerializableArray.html +1 -1
  118. package/docs/types/DreamSerializerKey.html +1 -1
  119. package/docs/types/DreamSerializers.html +1 -1
  120. package/docs/types/DreamTableSchema.html +1 -1
  121. package/docs/types/DreamVirtualColumns.html +1 -1
  122. package/docs/types/EncryptAlgorithm.html +1 -1
  123. package/docs/types/HasManyStatement.html +1 -1
  124. package/docs/types/HasOneStatement.html +1 -1
  125. package/docs/types/Hyphenized.html +1 -1
  126. package/docs/types/IdType.html +1 -1
  127. package/docs/types/OpenapiAllTypes.html +1 -1
  128. package/docs/types/OpenapiFormats.html +1 -1
  129. package/docs/types/OpenapiNumberFormats.html +1 -1
  130. package/docs/types/OpenapiPrimitiveBaseTypes.html +1 -1
  131. package/docs/types/OpenapiPrimitiveTypes.html +1 -1
  132. package/docs/types/OpenapiSchemaArray.html +1 -1
  133. package/docs/types/OpenapiSchemaArrayShorthand.html +1 -1
  134. package/docs/types/OpenapiSchemaBase.html +1 -1
  135. package/docs/types/OpenapiSchemaBody.html +1 -1
  136. package/docs/types/OpenapiSchemaBodyShorthand.html +1 -1
  137. package/docs/types/OpenapiSchemaCommonFields.html +1 -1
  138. package/docs/types/OpenapiSchemaExpressionAllOf.html +1 -1
  139. package/docs/types/OpenapiSchemaExpressionAnyOf.html +1 -1
  140. package/docs/types/OpenapiSchemaExpressionOneOf.html +1 -1
  141. package/docs/types/OpenapiSchemaExpressionRef.html +1 -1
  142. package/docs/types/OpenapiSchemaExpressionRefSchemaShorthand.html +1 -1
  143. package/docs/types/OpenapiSchemaInteger.html +1 -1
  144. package/docs/types/OpenapiSchemaNull.html +1 -1
  145. package/docs/types/OpenapiSchemaNumber.html +1 -1
  146. package/docs/types/OpenapiSchemaObject.html +1 -1
  147. package/docs/types/OpenapiSchemaObjectAllOf.html +1 -1
  148. package/docs/types/OpenapiSchemaObjectAllOfShorthand.html +1 -1
  149. package/docs/types/OpenapiSchemaObjectAnyOf.html +1 -1
  150. package/docs/types/OpenapiSchemaObjectAnyOfShorthand.html +1 -1
  151. package/docs/types/OpenapiSchemaObjectBase.html +1 -1
  152. package/docs/types/OpenapiSchemaObjectBaseShorthand.html +1 -1
  153. package/docs/types/OpenapiSchemaObjectOneOf.html +1 -1
  154. package/docs/types/OpenapiSchemaObjectOneOfShorthand.html +1 -1
  155. package/docs/types/OpenapiSchemaObjectShorthand.html +1 -1
  156. package/docs/types/OpenapiSchemaPrimitiveGeneric.html +1 -1
  157. package/docs/types/OpenapiSchemaShorthandExpressionAllOf.html +1 -1
  158. package/docs/types/OpenapiSchemaShorthandExpressionAnyOf.html +1 -1
  159. package/docs/types/OpenapiSchemaShorthandExpressionOneOf.html +1 -1
  160. package/docs/types/OpenapiSchemaShorthandExpressionSerializableRef.html +1 -1
  161. package/docs/types/OpenapiSchemaShorthandExpressionSerializerRef.html +1 -1
  162. package/docs/types/OpenapiSchemaShorthandPrimitiveGeneric.html +1 -1
  163. package/docs/types/OpenapiSchemaString.html +1 -1
  164. package/docs/types/OpenapiShorthandAllTypes.html +1 -1
  165. package/docs/types/OpenapiShorthandPrimitiveBaseTypes.html +1 -1
  166. package/docs/types/OpenapiShorthandPrimitiveTypes.html +1 -1
  167. package/docs/types/OpenapiTypeField.html +1 -1
  168. package/docs/types/Pascalized.html +1 -1
  169. package/docs/types/PrimaryKeyType.html +1 -1
  170. package/docs/types/RoundingPrecision.html +1 -1
  171. package/docs/types/SerializerCasing.html +1 -1
  172. package/docs/types/SimpleObjectSerializerType.html +1 -1
  173. package/docs/types/Snakeified.html +1 -1
  174. package/docs/types/Timestamp.html +1 -1
  175. package/docs/types/UpdateableAssociationProperties.html +1 -1
  176. package/docs/types/UpdateableProperties.html +1 -1
  177. package/docs/types/ValidationType.html +1 -1
  178. package/docs/types/ViewModel.html +1 -1
  179. package/docs/types/ViewModelClass.html +1 -1
  180. package/docs/types/WhereStatementForDream.html +1 -1
  181. package/docs/types/WhereStatementForDreamClass.html +1 -1
  182. package/docs/variables/DateTime-1.html +1 -1
  183. package/docs/variables/DreamConst.html +1 -1
  184. package/docs/variables/TRIGRAM_OPERATORS.html +1 -1
  185. package/docs/variables/openapiPrimitiveTypes-1.html +1 -1
  186. package/docs/variables/openapiShorthandPrimitiveTypes-1.html +1 -1
  187. package/docs/variables/ops.html +1 -1
  188. package/docs/variables/primaryKeyTypes.html +1 -1
  189. package/package.json +2 -2
@@ -21,13 +21,17 @@ class DreamBin {
21
21
  await Query_js_1.default.dbDriverClass().rollback(opts);
22
22
  }
23
23
  static async generateDream(fullyQualifiedModelName, columnsWithTypes, options) {
24
- await (0, generateDream_js_1.default)({ fullyQualifiedModelName, columnsWithTypes, options });
24
+ await (0, generateDream_js_1.default)({
25
+ fullyQualifiedModelName,
26
+ columnsWithTypes,
27
+ options: { includeAdminSerializers: false, ...options },
28
+ });
25
29
  }
26
30
  static async generateStiChild(fullyQualifiedModelName, fullyQualifiedParentName, columnsWithTypes, options) {
27
31
  await (0, generateDream_js_1.default)({
28
32
  fullyQualifiedModelName,
29
33
  columnsWithTypes,
30
- options: { ...options, stiBaseSerializer: false },
34
+ options: { includeAdminSerializers: false, ...options, stiBaseSerializer: false },
31
35
  fullyQualifiedParentName,
32
36
  });
33
37
  }
@@ -6,6 +6,40 @@ const index_js_2 = require("../dream-app/index.js");
6
6
  const EnvInternal_js_1 = require("../helpers/EnvInternal.js");
7
7
  const sspawn_js_1 = require("../helpers/sspawn.js");
8
8
  const DreamCliLogger_js_1 = require("./logger/DreamCliLogger.js");
9
+ const INDENT = ' ';
10
+ const columnsWithTypesDescription = `space separated snake-case (except for belongs_to model name) properties like this:
11
+ ${INDENT} title:citext subtitle:string body_markdown:text style:enum:post_styles:formal,informal User:belongs_to
12
+ ${INDENT}
13
+ ${INDENT}all properties default to not nullable; null can be allowed by appending ':optional':
14
+ ${INDENT} subtitle:string:optional
15
+ ${INDENT}
16
+ ${INDENT}supported types:
17
+ ${INDENT} - citext:
18
+ ${INDENT} case insensitive text (indexes and queries are automatically case insensitive)
19
+ ${INDENT}
20
+ ${INDENT} - string:
21
+ ${INDENT} varchar; allowed length defaults to 255, but may be customized, e.g.: subtitle:string:128 or subtitle:string:128:optional
22
+ ${INDENT}
23
+ ${INDENT} - text
24
+ ${INDENT}
25
+ ${INDENT} - integer
26
+ ${INDENT}
27
+ ${INDENT} - decimal:
28
+ ${INDENT} scale,precision is required, e.g.: volume:decimal:3,2 or volume:decimal:3,2:optional
29
+ ${INDENT}
30
+ ${INDENT} - enum:
31
+ ${INDENT} include the enum name to automatically create the enum:
32
+ ${INDENT} type:enum:room_types:bathroom,kitchen,bedroom or type:enum:room_types:bathroom,kitchen,bedroom:optional
33
+ ${INDENT}
34
+ ${INDENT} omit the enum values to leverage an existing enum (omits the enum type creation):
35
+ ${INDENT} type:enum:room_types or type:enum:room_types:optional
36
+ ${INDENT}
37
+ ${INDENT} - belongs_to:
38
+ ${INDENT} Not only updates the migration but also adds a BelongsTo association to the generated model:
39
+ ${INDENT} Place:belongs_to
40
+ ${INDENT}
41
+ ${INDENT} Include the full Path to the model. E.g., if the Coach model is in src/app/models/Health/Coach:
42
+ ${INDENT} Health/Coach:belongs_to`;
9
43
  class DreamCLI {
10
44
  /**
11
45
  * use this method for initializing a standalone dream application. If using Psychic and Dream together,
@@ -35,7 +69,7 @@ class DreamCLI {
35
69
  .alias('g:migration')
36
70
  .description('create a new migration')
37
71
  .argument('<migrationName>', 'end with -to-table-name to prepopulate with an alterTable command')
38
- .argument('[columnsWithTypes...]', 'properties of the model column1:text/string/enum/etc. column2:text/string/enum/etc. ... columnN:text/string/enum/etc.')
72
+ .argument('[columnsWithTypes...]', columnsWithTypesDescription)
39
73
  .action(async (migrationName, columnsWithTypes) => {
40
74
  await initializeDreamApp();
41
75
  await index_js_1.default.generateMigration(migrationName, columnsWithTypes);
@@ -47,7 +81,7 @@ class DreamCLI {
47
81
  .alias('generate:dream')
48
82
  .alias('g:dream')
49
83
  .option('--no-serializer')
50
- .option('--sti-base-serializer', 'Omits the serializer from the dream model, but does create the serializer so it can be extended by STI children')
84
+ .option('--sti-base-serializer', 'omits the serializer from the dream model, but does create the serializer so it can be extended by STI children')
51
85
  .description('create a new Dream model')
52
86
  .argument('<modelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
53
87
  .argument('[columnsWithTypes...]', 'properties of the model property1:text/string/enum/etc. property2:text/string/enum/etc. ... propertyN:text/string/enum/etc.')
@@ -62,9 +96,11 @@ class DreamCLI {
62
96
  .description('create a new Dream model that extends another Dream model, leveraging STI (single table inheritance)')
63
97
  .option('--no-serializer')
64
98
  .argument('<childModelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
65
- .argument('<extends>', 'just the word extends')
66
- .argument('<parentModelName>', 'name of the parent model')
67
- .argument('[columnsWithTypes...]', 'properties of the model property1:text/string/enum/etc. property2:text/string/enum/etc. ... propertyN:text/string/enum/etc.')
99
+ .argument('<extends>', 'just the word "extends"')
100
+ .argument('<parentModelName>', `fully qualified name of the parent model, e.g.:
101
+ ${INDENT} to extend the Room model in src/app/models/Room: Room
102
+ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Coach`)
103
+ .argument('[columnsWithTypes...]', columnsWithTypesDescription)
68
104
  .action(async (childModelName, extendsWord, parentModelName, columnsWithTypes, options) => {
69
105
  await initializeDreamApp();
70
106
  if (extendsWord !== 'extends')
@@ -21,6 +21,7 @@ async function generateDream({ fullyQualifiedModelName, columnsWithTypes, option
21
21
  columnsWithTypes,
22
22
  fullyQualifiedParentName,
23
23
  serializer: options.serializer && !options.stiBaseSerializer,
24
+ includeAdminSerializers: options.includeAdminSerializers,
24
25
  }));
25
26
  }
26
27
  catch (error) {
@@ -40,6 +41,7 @@ async function generateDream({ fullyQualifiedModelName, columnsWithTypes, option
40
41
  columnsWithTypes,
41
42
  fullyQualifiedParentName,
42
43
  stiBaseSerializer: options.stiBaseSerializer,
44
+ includeAdminSerializers: options.includeAdminSerializers,
43
45
  });
44
46
  const isSTI = !!fullyQualifiedParentName;
45
47
  if (columnsWithTypes.length || !isSTI) {
@@ -9,7 +9,7 @@ const relativeDreamPath_js_1 = require("../path/relativeDreamPath.js");
9
9
  const snakeify_js_1 = require("../snakeify.js");
10
10
  const standardizeFullyQualifiedModelName_js_1 = require("../standardizeFullyQualifiedModelName.js");
11
11
  const uniq_js_1 = require("../uniq.js");
12
- function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, }) {
12
+ function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, includeAdminSerializers, }) {
13
13
  fullyQualifiedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName);
14
14
  const modelClassName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName);
15
15
  let parentModelClassName;
@@ -92,7 +92,11 @@ ${isSTI
92
92
  ? ` public ${isSTI ? 'override ' : ''}get serializers(): DreamSerializers<${modelClassName}> {
93
93
  return {
94
94
  default: '${(0, serializerGlobalNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName)}',
95
- summary: '${(0, serializerGlobalNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName, 'summary')}',
95
+ summary: '${(0, serializerGlobalNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName, 'summary')}',${!includeAdminSerializers
96
+ ? ''
97
+ : `
98
+ admin: '${(0, serializerGlobalNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName).replace(/Serializer$/, 'AdminSerializer')}',
99
+ adminSummary: '${(0, serializerGlobalNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName, 'summary').replace(/SummarySerializer$/, 'AdminSummarySerializer')}',`}
96
100
  }
97
101
  }
98
102
 
@@ -13,37 +13,47 @@ function generateFactoryContent({ fullyQualifiedModelName, columnsWithTypes, })
13
13
  const belongsToNames = [];
14
14
  const belongsToTypedNames = [];
15
15
  const associationCreationStatements = [];
16
- const stringAttributes = [];
17
- let firstStringAttr = true;
16
+ const attributeDefaults = [];
17
+ let counterVariableIncremented = false;
18
18
  for (const attribute of columnsWithTypes) {
19
19
  const [attributeName, attributeType, ...descriptors] = attribute.split(':');
20
20
  if (attributeName === undefined)
21
21
  continue;
22
- const fullyQualifiedAssociatedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(attributeName);
23
- const associationModelName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedAssociatedModelName);
24
- const associationFactoryImportStatement = `import create${associationModelName} from '${(0, relativeDreamPath_js_1.default)('factories', 'factories', fullyQualifiedModelName, fullyQualifiedAssociatedModelName)}'`;
25
- const associationName = (0, camelize_js_1.default)(associationModelName);
26
22
  if (attributeName === undefined)
27
23
  continue;
28
- if (/_type$/.test(attributeName))
24
+ const attributeVariable = (0, camelize_js_1.default)(attributeName.replace(/\//g, ''));
25
+ if (/(_type|_id)$/.test(attributeName))
29
26
  continue;
30
27
  if (!attributeType)
31
- throw new Error(`Must pass a column type for ${fullyQualifiedAssociatedModelName} (i.e. ${fullyQualifiedAssociatedModelName}:string)`);
28
+ throw new Error(`Must pass a column type for ${attributeName} (i.e. ${attributeName}:string)`);
32
29
  switch (attributeType) {
33
- case 'belongs_to':
34
- belongsToNames.push(associationName);
35
- belongsToTypedNames.push(`${associationName}: ${associationModelName}`);
30
+ case 'belongs_to': {
31
+ const fullyQualifiedAssociatedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(attributeName);
32
+ const associationModelName = (0, globalClassNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedAssociatedModelName);
33
+ const associationFactoryImportStatement = `import create${associationModelName} from '${(0, relativeDreamPath_js_1.default)('factories', 'factories', fullyQualifiedModelName, fullyQualifiedAssociatedModelName)}'`;
34
+ belongsToNames.push(attributeVariable);
35
+ belongsToTypedNames.push(`${attributeVariable}: ${associationModelName}`);
36
36
  additionalImports.push(associationFactoryImportStatement);
37
- associationCreationStatements.push(`${associationName}: await create${associationModelName}(),`);
37
+ associationCreationStatements.push(`${attributeVariable}: attrs.${attributeVariable} ? null : await create${associationModelName}(),`);
38
38
  break;
39
+ }
39
40
  case 'string':
40
41
  case 'text':
41
42
  case 'citext':
42
- stringAttributes.push(`${(0, camelize_js_1.default)(attributeName)}: \`${fullyQualifiedModelName} ${(0, camelize_js_1.default)(attributeName)} ${firstStringAttr ? '${++counter}' : '${counter}'}\`,`);
43
- firstStringAttr = false;
43
+ attributeDefaults.push(`${attributeVariable}: \`${fullyQualifiedModelName} ${attributeVariable} ${counterVariableIncremented ? '${counter}' : '${++counter}'}\`,`);
44
+ counterVariableIncremented = true;
44
45
  break;
45
46
  case 'enum':
46
- stringAttributes.push(`${(0, camelize_js_1.default)(attributeName)}: '${(descriptors.at(-1) || '<tbd>').split(',')[0]}',`);
47
+ attributeDefaults.push(`${attributeVariable}: '${(descriptors.at(-1) || '<tbd>').split(',')[0]}',`);
48
+ break;
49
+ case 'integer':
50
+ attributeDefaults.push(`${attributeVariable}: 1,`);
51
+ break;
52
+ case 'bigint':
53
+ attributeDefaults.push(`${attributeVariable}: '11111111111111111',`);
54
+ break;
55
+ case 'decimal':
56
+ attributeDefaults.push(`${attributeVariable}: 1.1,`);
47
57
  break;
48
58
  default:
49
59
  // noop
@@ -54,10 +64,10 @@ function generateFactoryContent({ fullyQualifiedModelName, columnsWithTypes, })
54
64
  return `\
55
65
  import { ${(0, uniq_js_1.default)(dreamImports).join(', ')} } from '@rvoh/dream'
56
66
  import ${modelClassName} from '${relativePath}'${additionalImports.length ? '\n' + (0, uniq_js_1.default)(additionalImports).join('\n') : ''}
57
- ${stringAttributes.length ? '\nlet counter = 0\n' : ''}
67
+ ${counterVariableIncremented ? '\nlet counter = 0\n' : ''}
58
68
  export default async function create${modelClassName}(attrs: UpdateableProperties<${modelClassName}> = {}) {
59
69
  return await ${modelClassName}.create({
60
- ${associationCreationStatements.length ? associationCreationStatements.join('\n ') + '\n ' : ''}${stringAttributes.length ? stringAttributes.join('\n ') + '\n ' : ''}...attrs,
70
+ ${associationCreationStatements.length ? associationCreationStatements.join('\n ') + '\n ' : ''}${attributeDefaults.length ? attributeDefaults.join('\n ') + '\n ' : ''}...attrs,
61
71
  })
62
72
  }
63
73
  `;
@@ -3,17 +3,19 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = generateMigrationContent;
4
4
  const pluralize_esm_1 = require("pluralize-esm");
5
5
  const InvalidDecimalFieldPassedToGenerator_js_1 = require("../../errors/InvalidDecimalFieldPassedToGenerator.js");
6
+ const compact_js_1 = require("../compact.js");
6
7
  const foreignKeyTypeFromPrimaryKey_js_1 = require("../db/foreignKeyTypeFromPrimaryKey.js");
7
8
  const snakeify_js_1 = require("../snakeify.js");
8
9
  const STI_TYPE_COLUMN_NAME = 'type';
9
10
  const COLUMNS_TO_INDEX = [STI_TYPE_COLUMN_NAME];
10
- const NOT_NULL_COLUMNS = [STI_TYPE_COLUMN_NAME];
11
11
  function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType = 'bigserial', createOrAlter = 'create', } = {}) {
12
12
  const altering = createOrAlter === 'alter';
13
13
  let requireCitextExtension = false;
14
14
  const { columnDefs, columnDrops, indexDefs, indexDrops } = columnsWithTypes.reduce((acc, attribute) => {
15
15
  const { columnDefs, columnDrops, indexDefs, indexDrops } = acc;
16
16
  const [nonStandardAttributeName, attributeType, ...descriptors] = attribute.split(':');
17
+ const optional = optionalFromDescriptors(descriptors);
18
+ const sqlAttributeType = getAttributeType(attributeType, descriptors);
17
19
  let attributeName = (0, snakeify_js_1.default)(nonStandardAttributeName);
18
20
  if (attributeName === undefined)
19
21
  return acc;
@@ -21,30 +23,29 @@ function generateMigrationContent({ table, columnsWithTypes = [], primaryKeyType
21
23
  return acc;
22
24
  if (attributeType === 'citext')
23
25
  requireCitextExtension = true;
24
- const coercedAttributeType = getAttributeType(attribute);
25
26
  switch (attributeType) {
26
27
  case 'belongs_to':
27
28
  columnDefs.push(generateBelongsToStr(attributeName, {
28
29
  primaryKeyType,
29
- optional: descriptors.includes('optional'),
30
+ optional,
30
31
  }));
31
32
  attributeName = associationNameToForeignKey(attributeName);
32
33
  break;
33
34
  case 'enum':
34
- columnDefs.push(generateEnumStr(attribute));
35
+ columnDefs.push(generateEnumStr(attributeName, { descriptors, optional }));
35
36
  break;
36
37
  case 'decimal':
37
- columnDefs.push(generateDecimalStr(attribute));
38
+ columnDefs.push(generateDecimalStr(attributeName, { descriptors, optional }));
38
39
  break;
39
40
  case 'boolean':
40
- columnDefs.push(generateBooleanStr(attributeName));
41
+ columnDefs.push(generateBooleanStr(attributeName, { optional }));
41
42
  break;
42
43
  case 'encrypted':
43
- columnDefs.push(generateColumnStr(`encrypted_${attributeName}`, 'text', descriptors));
44
+ columnDefs.push(generateColumnStr(`encrypted_${attributeName}`, 'text', descriptors, { optional }));
44
45
  break;
45
46
  default:
46
- if (coercedAttributeType !== undefined) {
47
- columnDefs.push(generateColumnStr(attributeName, coercedAttributeType, descriptors));
47
+ if (sqlAttributeType !== undefined) {
48
+ columnDefs.push(generateColumnStr(attributeName, sqlAttributeType, descriptors, { optional }));
48
49
  }
49
50
  break;
50
51
  }
@@ -109,31 +110,29 @@ export async function down(db: Kysely<any>): Promise<void> {
109
110
  }\
110
111
  `;
111
112
  }
112
- function getAttributeType(attribute) {
113
- const [, attributeType, ...descriptors] = attribute.split(':');
114
- if (attributeType === 'enum') {
115
- return enumAttributeType(attribute)[0];
116
- }
113
+ function getAttributeType(attributeType, descriptors) {
117
114
  switch (attributeType) {
118
- case 'datetime':
119
- return 'timestamp';
120
115
  case 'string':
121
116
  return `varchar(${descriptors[0] || 255})`;
117
+ case 'enum':
118
+ return enumAttributeType(descriptors);
119
+ case 'datetime':
120
+ return 'timestamp';
122
121
  default:
123
122
  return attributeType;
124
123
  }
125
124
  }
126
- function enumAttributeType(attribute) {
127
- const [, , ...descriptors] = attribute.split(':');
125
+ function enumAttributeType(descriptors) {
128
126
  return `sql\`${descriptors[0]}_enum\``;
129
127
  }
130
128
  function generateEnumStatements(columnsWithTypes) {
131
129
  const enumStatements = columnsWithTypes.filter(attribute => /:enum:.*:/.test(attribute));
132
- const finalStatements = enumStatements.map(statement => {
133
- const enumName = statement.split(':')[2];
134
- const columnsWithTypesString = statement.split(':')[3];
130
+ const finalStatements = (0, compact_js_1.default)(enumStatements.map(statement => {
131
+ const [, , enumName, ...descriptors] = statement.split(':');
132
+ optionalFromDescriptors(descriptors);
133
+ const columnsWithTypesString = descriptors[0];
135
134
  if (columnsWithTypesString === undefined)
136
- return '';
135
+ return;
137
136
  const columnsWithTypes = columnsWithTypesString.split(/,\s{0,}/);
138
137
  return ` await db.schema
139
138
  .createType('${enumName}_enum')
@@ -141,40 +140,41 @@ function generateEnumStatements(columnsWithTypes) {
141
140
  ${columnsWithTypes.map(attr => `'${attr}'`).join(',\n ')}
142
141
  ])
143
142
  .execute()`;
144
- });
143
+ }));
145
144
  return finalStatements.length ? finalStatements.join('\n\n') + '\n\n' : '';
146
145
  }
147
146
  function generateEnumDropStatements(columnsWithTypes) {
148
147
  const enumStatements = columnsWithTypes.filter(attribute => /:enum:.*:/.test(attribute));
149
- const finalStatements = enumStatements.map(statement => {
150
- const enumName = statement.split(':')[2];
148
+ const finalStatements = (0, compact_js_1.default)(enumStatements.map(statement => {
149
+ const [, , enumName, ...descriptors] = statement.split(':');
150
+ optionalFromDescriptors(descriptors);
151
+ const columnsWithTypesString = descriptors[0];
152
+ if (columnsWithTypesString === undefined)
153
+ return;
151
154
  return `await db.schema.dropType('${enumName}_enum').execute()`;
152
- });
155
+ }));
153
156
  return finalStatements.length ? '\n\n ' + finalStatements.join('\n ') : '';
154
157
  }
155
- function generateBooleanStr(attributeName) {
156
- return `.addColumn('${attributeName}', 'boolean', col => col.notNull().defaultTo(false))`;
158
+ function generateBooleanStr(attributeName, { optional }) {
159
+ return `.addColumn('${attributeName}', 'boolean'${optional ? '' : ', col => col.notNull().defaultTo(false)'})`;
157
160
  }
158
- function generateEnumStr(attribute) {
159
- const computedAttributeType = enumAttributeType(attribute);
160
- const attributeName = attribute.split(':')[0];
161
+ function generateEnumStr(attributeName, { descriptors, optional }) {
162
+ const computedAttributeType = enumAttributeType(descriptors);
161
163
  if (attributeName === undefined)
162
164
  return '';
163
- const notNull = NOT_NULL_COLUMNS.includes(attributeName);
164
- return `.addColumn('${attributeName}', ${computedAttributeType}${notNull ? ', col => col.notNull()' : ''})`;
165
+ return `.addColumn('${attributeName}', ${computedAttributeType}${optional ? '' : ', col => col.notNull()'})`;
165
166
  }
166
- function generateDecimalStr(attribute) {
167
- const [, , ...descriptors] = attribute.split(':');
167
+ function generateDecimalStr(attributeName, { descriptors, optional }) {
168
168
  const [scale, precision] = descriptors[0]?.split(',') || [null, null];
169
169
  if (!scale || !precision)
170
- throw new InvalidDecimalFieldPassedToGenerator_js_1.default(attribute);
171
- return `.addColumn('${attribute.split(':')[0]}', 'decimal(${scale}, ${precision})')`;
170
+ throw new InvalidDecimalFieldPassedToGenerator_js_1.default(attributeName);
171
+ return `.addColumn('${attributeName}', 'decimal(${scale}, ${precision})'${optional ? '' : ', col => col.notNull()'})`;
172
172
  }
173
- function generateColumnStr(attributeName, attributeType, descriptors) {
173
+ function generateColumnStr(attributeName, attributeType, descriptors, { optional }) {
174
174
  let returnStr = `.addColumn('${attributeName}', ${attributeTypeString(attributeType)}`;
175
175
  const providedDefaultArg = descriptors.find(d => /^default\(/.test(d));
176
176
  const providedDefault = providedDefaultArg?.replace(/^default\(/, '')?.replace(/\)$/, '');
177
- const notNull = NOT_NULL_COLUMNS.includes(attributeName);
177
+ const notNull = !optional;
178
178
  const hasExtraValues = providedDefault || notNull;
179
179
  if (hasExtraValues)
180
180
  returnStr += ', col => col';
@@ -226,3 +226,9 @@ function generateIdStr({ primaryKeyType }) {
226
226
  function associationNameToForeignKey(associationName) {
227
227
  return (0, snakeify_js_1.default)(associationName.replace(/\//g, '_').replace(/_id$/, '') + '_id');
228
228
  }
229
+ function optionalFromDescriptors(descriptors) {
230
+ const optional = descriptors.at(-1) === 'optional';
231
+ if (optional)
232
+ descriptors.pop();
233
+ return optional;
234
+ }
@@ -6,7 +6,7 @@ const dreamFileAndDirPaths_js_1 = require("../path/dreamFileAndDirPaths.js");
6
6
  const dreamPath_js_1 = require("../path/dreamPath.js");
7
7
  const standardizeFullyQualifiedModelName_js_1 = require("../standardizeFullyQualifiedModelName.js");
8
8
  const generateSerializerContent_js_1 = require("./generateSerializerContent.js");
9
- async function generateSerializer({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, stiBaseSerializer, }) {
9
+ async function generateSerializer({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, stiBaseSerializer, includeAdminSerializers, }) {
10
10
  fullyQualifiedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName);
11
11
  const { relFilePath, absDirPath, absFilePath } = (0, dreamFileAndDirPaths_js_1.default)((0, dreamPath_js_1.default)('serializers'), `${fullyQualifiedModelName}Serializer.ts`);
12
12
  try {
@@ -17,6 +17,7 @@ async function generateSerializer({ fullyQualifiedModelName, columnsWithTypes, f
17
17
  columnsWithTypes,
18
18
  fullyQualifiedParentName,
19
19
  stiBaseSerializer,
20
+ includeAdminSerializers,
20
21
  }));
21
22
  }
22
23
  catch (error) {
@@ -7,7 +7,7 @@ const globalClassNameFromFullyQualifiedModelName_js_1 = require("../globalClassN
7
7
  const relativeDreamPath_js_1 = require("../path/relativeDreamPath.js");
8
8
  const standardizeFullyQualifiedModelName_js_1 = require("../standardizeFullyQualifiedModelName.js");
9
9
  const uniq_js_1 = require("../uniq.js");
10
- function generateSerializerContent({ fullyQualifiedModelName, columnsWithTypes = [], fullyQualifiedParentName, stiBaseSerializer = false, }) {
10
+ function generateSerializerContent({ fullyQualifiedModelName, columnsWithTypes = [], fullyQualifiedParentName, stiBaseSerializer, includeAdminSerializers, }) {
11
11
  fullyQualifiedModelName = (0, standardizeFullyQualifiedModelName_js_1.default)(fullyQualifiedModelName);
12
12
  const additionalImports = [];
13
13
  const dreamImports = [];
@@ -27,7 +27,7 @@ function generateSerializerContent({ fullyQualifiedModelName, columnsWithTypes =
27
27
  : `(${modelInstanceName}: ${modelClassName})`;
28
28
  const modelSerializerArgs = `${modelInstanceName}`;
29
29
  const dreamSerializerArgs = `${stiBaseSerializer ? 'StiChildClass' : modelClassName}, ${modelInstanceName}`;
30
- const serialzerClassName = (0, serializerNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName));
30
+ const serializerClassName = (0, serializerNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName));
31
31
  const summarySerializerClassName = (0, serializerNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedModelName), 'summary');
32
32
  const defaultSerializerExtends = isSTI
33
33
  ? `${(0, serializerNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedParentName))}(${modelClassName}, ${modelSerializerArgs})`
@@ -35,16 +35,18 @@ function generateSerializerContent({ fullyQualifiedModelName, columnsWithTypes =
35
35
  const summarySerializerExtends = isSTI
36
36
  ? `${(0, serializerNameFromFullyQualifiedModelName_js_1.default)(fullyQualifiedModelNameToSerializerBaseName(fullyQualifiedParentName), 'summary')}(${modelClassName}, ${modelSerializerArgs})`
37
37
  : `DreamSerializer(${dreamSerializerArgs})`;
38
+ // Admin variants
39
+ const adminSerializerClassName = serializerClassName.replace(/Serializer$/, 'AdminSerializer');
40
+ const adminSummarySerializerClassName = summarySerializerClassName.replace(/SummarySerializer$/, 'AdminSummarySerializer');
41
+ // end:Admin variants
38
42
  const additionalModelImports = [];
39
43
  const dreamImport = dreamImports.length
40
44
  ? `import { ${(0, uniq_js_1.default)(dreamImports).join(', ')} } from '@rvoh/dream'\n`
41
45
  : '';
42
46
  const additionalImportsStr = (0, uniq_js_1.default)(additionalImports).join('');
43
- return `${dreamImport}${additionalImportsStr}${relatedModelImport}${additionalModelImports.join('')}
44
- export const ${summarySerializerClassName} = ${modelSerializerSignature} =>
45
- ${summarySerializerExtends}${isSTI ? '' : `\n .attribute('id')`}
46
-
47
- export const ${serialzerClassName} = ${modelSerializerSignature} =>
47
+ const summarySerializer = `export const ${summarySerializerClassName} = ${modelSerializerSignature} =>
48
+ ${summarySerializerExtends}${isSTI ? '' : `\n .attribute('id')`}`;
49
+ const defaultSerializer = `export const ${serializerClassName} = ${modelSerializerSignature} =>
48
50
  ${defaultSerializerExtends}${columnsWithTypes
49
51
  .map(attr => {
50
52
  const [name, type] = attr.split(':');
@@ -54,7 +56,17 @@ export const ${serialzerClassName} = ${modelSerializerSignature} =>
54
56
  return '';
55
57
  return `\n ${attribute(name, type, attr)}`;
56
58
  })
57
- .join('\n\n ')}
59
+ .join('')}`;
60
+ return `${dreamImport}${additionalImportsStr}${relatedModelImport}${additionalModelImports.join('')}
61
+ ${summarySerializer}
62
+
63
+ ${defaultSerializer}${!includeAdminSerializers
64
+ ? ''
65
+ : `
66
+
67
+ ${summarySerializer.replace(summarySerializerClassName, adminSummarySerializerClassName)}
68
+
69
+ ${defaultSerializer.replace(serializerClassName, adminSerializerClassName).replace(summarySerializerClassName, adminSummarySerializerClassName)}`}
58
70
  `;
59
71
  }
60
72
  function attribute(name, type, attr) {
@@ -19,13 +19,17 @@ export default class DreamBin {
19
19
  await Query.dbDriverClass().rollback(opts);
20
20
  }
21
21
  static async generateDream(fullyQualifiedModelName, columnsWithTypes, options) {
22
- await generateDream({ fullyQualifiedModelName, columnsWithTypes, options });
22
+ await generateDream({
23
+ fullyQualifiedModelName,
24
+ columnsWithTypes,
25
+ options: { includeAdminSerializers: false, ...options },
26
+ });
23
27
  }
24
28
  static async generateStiChild(fullyQualifiedModelName, fullyQualifiedParentName, columnsWithTypes, options) {
25
29
  await generateDream({
26
30
  fullyQualifiedModelName,
27
31
  columnsWithTypes,
28
- options: { ...options, stiBaseSerializer: false },
32
+ options: { includeAdminSerializers: false, ...options, stiBaseSerializer: false },
29
33
  fullyQualifiedParentName,
30
34
  });
31
35
  }
@@ -4,6 +4,40 @@ import DreamApp from '../dream-app/index.js';
4
4
  import EnvInternal from '../helpers/EnvInternal.js';
5
5
  import sspawn from '../helpers/sspawn.js';
6
6
  import DreamCliLogger from './logger/DreamCliLogger.js';
7
+ const INDENT = ' ';
8
+ const columnsWithTypesDescription = `space separated snake-case (except for belongs_to model name) properties like this:
9
+ ${INDENT} title:citext subtitle:string body_markdown:text style:enum:post_styles:formal,informal User:belongs_to
10
+ ${INDENT}
11
+ ${INDENT}all properties default to not nullable; null can be allowed by appending ':optional':
12
+ ${INDENT} subtitle:string:optional
13
+ ${INDENT}
14
+ ${INDENT}supported types:
15
+ ${INDENT} - citext:
16
+ ${INDENT} case insensitive text (indexes and queries are automatically case insensitive)
17
+ ${INDENT}
18
+ ${INDENT} - string:
19
+ ${INDENT} varchar; allowed length defaults to 255, but may be customized, e.g.: subtitle:string:128 or subtitle:string:128:optional
20
+ ${INDENT}
21
+ ${INDENT} - text
22
+ ${INDENT}
23
+ ${INDENT} - integer
24
+ ${INDENT}
25
+ ${INDENT} - decimal:
26
+ ${INDENT} scale,precision is required, e.g.: volume:decimal:3,2 or volume:decimal:3,2:optional
27
+ ${INDENT}
28
+ ${INDENT} - enum:
29
+ ${INDENT} include the enum name to automatically create the enum:
30
+ ${INDENT} type:enum:room_types:bathroom,kitchen,bedroom or type:enum:room_types:bathroom,kitchen,bedroom:optional
31
+ ${INDENT}
32
+ ${INDENT} omit the enum values to leverage an existing enum (omits the enum type creation):
33
+ ${INDENT} type:enum:room_types or type:enum:room_types:optional
34
+ ${INDENT}
35
+ ${INDENT} - belongs_to:
36
+ ${INDENT} Not only updates the migration but also adds a BelongsTo association to the generated model:
37
+ ${INDENT} Place:belongs_to
38
+ ${INDENT}
39
+ ${INDENT} Include the full Path to the model. E.g., if the Coach model is in src/app/models/Health/Coach:
40
+ ${INDENT} Health/Coach:belongs_to`;
7
41
  export default class DreamCLI {
8
42
  /**
9
43
  * use this method for initializing a standalone dream application. If using Psychic and Dream together,
@@ -33,7 +67,7 @@ export default class DreamCLI {
33
67
  .alias('g:migration')
34
68
  .description('create a new migration')
35
69
  .argument('<migrationName>', 'end with -to-table-name to prepopulate with an alterTable command')
36
- .argument('[columnsWithTypes...]', 'properties of the model column1:text/string/enum/etc. column2:text/string/enum/etc. ... columnN:text/string/enum/etc.')
70
+ .argument('[columnsWithTypes...]', columnsWithTypesDescription)
37
71
  .action(async (migrationName, columnsWithTypes) => {
38
72
  await initializeDreamApp();
39
73
  await DreamBin.generateMigration(migrationName, columnsWithTypes);
@@ -45,7 +79,7 @@ export default class DreamCLI {
45
79
  .alias('generate:dream')
46
80
  .alias('g:dream')
47
81
  .option('--no-serializer')
48
- .option('--sti-base-serializer', 'Omits the serializer from the dream model, but does create the serializer so it can be extended by STI children')
82
+ .option('--sti-base-serializer', 'omits the serializer from the dream model, but does create the serializer so it can be extended by STI children')
49
83
  .description('create a new Dream model')
50
84
  .argument('<modelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
51
85
  .argument('[columnsWithTypes...]', 'properties of the model property1:text/string/enum/etc. property2:text/string/enum/etc. ... propertyN:text/string/enum/etc.')
@@ -60,9 +94,11 @@ export default class DreamCLI {
60
94
  .description('create a new Dream model that extends another Dream model, leveraging STI (single table inheritance)')
61
95
  .option('--no-serializer')
62
96
  .argument('<childModelName>', 'the name of the model to create, e.g. Post or Settings/CommunicationPreferences')
63
- .argument('<extends>', 'just the word extends')
64
- .argument('<parentModelName>', 'name of the parent model')
65
- .argument('[columnsWithTypes...]', 'properties of the model property1:text/string/enum/etc. property2:text/string/enum/etc. ... propertyN:text/string/enum/etc.')
97
+ .argument('<extends>', 'just the word "extends"')
98
+ .argument('<parentModelName>', `fully qualified name of the parent model, e.g.:
99
+ ${INDENT} to extend the Room model in src/app/models/Room: Room
100
+ ${INDENT} to extend the Coach model in src/app/models/Health/Coach: Health/Coach`)
101
+ .argument('[columnsWithTypes...]', columnsWithTypesDescription)
66
102
  .action(async (childModelName, extendsWord, parentModelName, columnsWithTypes, options) => {
67
103
  await initializeDreamApp();
68
104
  if (extendsWord !== 'extends')
@@ -18,6 +18,7 @@ export default async function generateDream({ fullyQualifiedModelName, columnsWi
18
18
  columnsWithTypes,
19
19
  fullyQualifiedParentName,
20
20
  serializer: options.serializer && !options.stiBaseSerializer,
21
+ includeAdminSerializers: options.includeAdminSerializers,
21
22
  }));
22
23
  }
23
24
  catch (error) {
@@ -37,6 +38,7 @@ export default async function generateDream({ fullyQualifiedModelName, columnsWi
37
38
  columnsWithTypes,
38
39
  fullyQualifiedParentName,
39
40
  stiBaseSerializer: options.stiBaseSerializer,
41
+ includeAdminSerializers: options.includeAdminSerializers,
40
42
  });
41
43
  const isSTI = !!fullyQualifiedParentName;
42
44
  if (columnsWithTypes.length || !isSTI) {
@@ -6,7 +6,7 @@ import relativeDreamPath from '../path/relativeDreamPath.js';
6
6
  import snakeify from '../snakeify.js';
7
7
  import standardizeFullyQualifiedModelName from '../standardizeFullyQualifiedModelName.js';
8
8
  import uniq from '../uniq.js';
9
- export default function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, }) {
9
+ export default function generateDreamContent({ fullyQualifiedModelName, columnsWithTypes, fullyQualifiedParentName, serializer, includeAdminSerializers, }) {
10
10
  fullyQualifiedModelName = standardizeFullyQualifiedModelName(fullyQualifiedModelName);
11
11
  const modelClassName = globalClassNameFromFullyQualifiedModelName(fullyQualifiedModelName);
12
12
  let parentModelClassName;
@@ -89,7 +89,11 @@ ${isSTI
89
89
  ? ` public ${isSTI ? 'override ' : ''}get serializers(): DreamSerializers<${modelClassName}> {
90
90
  return {
91
91
  default: '${serializerGlobalNameFromFullyQualifiedModelName(fullyQualifiedModelName)}',
92
- summary: '${serializerGlobalNameFromFullyQualifiedModelName(fullyQualifiedModelName, 'summary')}',
92
+ summary: '${serializerGlobalNameFromFullyQualifiedModelName(fullyQualifiedModelName, 'summary')}',${!includeAdminSerializers
93
+ ? ''
94
+ : `
95
+ admin: '${serializerGlobalNameFromFullyQualifiedModelName(fullyQualifiedModelName).replace(/Serializer$/, 'AdminSerializer')}',
96
+ adminSummary: '${serializerGlobalNameFromFullyQualifiedModelName(fullyQualifiedModelName, 'summary').replace(/SummarySerializer$/, 'AdminSummarySerializer')}',`}
93
97
  }
94
98
  }
95
99