@postxl/generator 0.34.0 → 0.36.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/generator.js +91 -32
  2. package/dist/generators/indices/businesslogic-actiontypes.generator.d.ts +9 -0
  3. package/dist/generators/indices/businesslogic-actiontypes.generator.js +39 -0
  4. package/dist/generators/indices/businesslogic-update-index.generator.d.ts +9 -0
  5. package/dist/generators/indices/businesslogic-update-index.generator.js +20 -0
  6. package/dist/generators/indices/businesslogic-update-module.generator.d.ts +9 -0
  7. package/dist/generators/indices/businesslogic-update-module.generator.js +69 -0
  8. package/dist/generators/indices/businesslogic-update-service.generator.d.ts +9 -0
  9. package/dist/generators/indices/{businesslogicservice.generator.js → businesslogic-update-service.generator.js} +9 -10
  10. package/dist/generators/indices/businesslogic-view-index.generator.d.ts +9 -0
  11. package/dist/generators/indices/businesslogic-view-index.generator.js +19 -0
  12. package/dist/generators/indices/{businesslogicindex.generator.d.ts → businesslogic-view-module.generator.d.ts} +2 -2
  13. package/dist/generators/indices/{businesslogicmodule.generator.js → businesslogic-view-module.generator.js} +22 -26
  14. package/dist/generators/indices/{businesslogicservice.generator.d.ts → businesslogic-view-service.generator.d.ts} +1 -1
  15. package/dist/generators/indices/businesslogic-view-service.generator.js +34 -0
  16. package/dist/generators/indices/{datamockmodule.generator.js → datamock-module.generator.js} +8 -16
  17. package/dist/generators/indices/datamocker.generator.js +46 -40
  18. package/dist/generators/indices/datamodule.generator.js +7 -13
  19. package/dist/generators/indices/{businesslogicmodule.generator.d.ts → dispatcher-service.generator.d.ts} +2 -2
  20. package/dist/generators/indices/dispatcher-service.generator.js +81 -0
  21. package/dist/generators/indices/seed-migration.generator.d.ts +9 -0
  22. package/dist/generators/indices/seed-migration.generator.js +35 -0
  23. package/dist/generators/indices/seed-service.generator.d.ts +1 -1
  24. package/dist/generators/indices/seed-service.generator.js +327 -123
  25. package/dist/generators/indices/seed-template-decoder.generator.js +22 -6
  26. package/dist/generators/indices/{seed.generator.d.ts → seeddata-type.generator.d.ts} +2 -2
  27. package/dist/generators/indices/seeddata-type.generator.js +42 -0
  28. package/dist/generators/indices/types.generator.d.ts +1 -1
  29. package/dist/generators/indices/types.generator.js +8 -6
  30. package/dist/generators/models/businesslogic-update.generator.d.ts +10 -0
  31. package/dist/generators/models/businesslogic-update.generator.js +243 -0
  32. package/dist/generators/models/businesslogic-view.generator.d.ts +10 -0
  33. package/dist/generators/models/{businesslogic.generator.js → businesslogic-view.generator.js} +24 -72
  34. package/dist/generators/models/react.generator/modals.generator.js +2 -2
  35. package/dist/generators/models/repository.generator.d.ts +9 -0
  36. package/dist/generators/models/repository.generator.js +420 -131
  37. package/dist/generators/models/route.generator.js +45 -55
  38. package/dist/generators/models/seed.generator.js +6 -2
  39. package/dist/generators/models/types.generator.js +60 -13
  40. package/dist/lib/attributes.d.ts +5 -0
  41. package/dist/lib/imports.d.ts +23 -2
  42. package/dist/lib/imports.js +19 -1
  43. package/dist/lib/meta.d.ts +287 -34
  44. package/dist/lib/meta.js +87 -16
  45. package/dist/lib/schema/schema.d.ts +24 -6
  46. package/dist/lib/schema/types.d.ts +4 -0
  47. package/dist/lib/utils/jsdoc.d.ts +1 -1
  48. package/dist/lib/utils/jsdoc.js +8 -6
  49. package/dist/lib/utils/string.js +2 -1
  50. package/dist/lib/vfs.d.ts +33 -0
  51. package/dist/lib/vfs.js +157 -0
  52. package/dist/prisma/attributes.js +7 -3
  53. package/dist/prisma/parse.js +25 -5
  54. package/package.json +8 -3
  55. package/dist/generators/indices/businesslogicindex.generator.js +0 -19
  56. package/dist/generators/indices/seed.generator.js +0 -17
  57. package/dist/generators/indices/testdataservice.generator.d.ts +0 -9
  58. package/dist/generators/indices/testdataservice.generator.js +0 -78
  59. package/dist/generators/models/businesslogic.generator.d.ts +0 -9
  60. /package/dist/generators/indices/{datamockmodule.generator.d.ts → datamock-module.generator.d.ts} +0 -0
@@ -30,21 +30,13 @@ const Types = __importStar(require("../../lib/schema/types"));
30
30
  /**
31
31
  * Generates a mocking class
32
32
  */
33
- // TODO: https://github.com/PostXL/PostXL/issues/347
34
33
  function generateDataMockModule({ models, meta }) {
35
34
  const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
36
- const imports = imports_1.ImportsGenerator.from(meta.data.dataMockModuleFilePath)
37
- .addImport({
38
- items: [Types.toVariableName('DataModule')],
39
- from: meta.data.dataModuleFilePath,
40
- })
41
- .addImport({
42
- items: [Types.toVariableName('DataService')],
43
- from: meta.data.dataServiceFilePath,
44
- })
45
- .addImport({
46
- items: [Types.toVariableName('TestDataService')],
47
- from: meta.data.testDataServiceFilePath,
35
+ const imports = imports_1.ImportsGenerator.from(meta.data.dataMockModuleFilePath).addImports({
36
+ [meta.data.dataModuleFilePath]: [Types.toVariableName('DataModule')],
37
+ [meta.data.dataServiceFilePath]: [Types.toVariableName('DataService')],
38
+ // we need to import the file directly instead via the normal index file as this would cause a circular dependency else
39
+ [meta.actions.actionExecutionInterfaceFilePath]: [meta.actions.actionExecutionMock],
48
40
  });
49
41
  for (const { model, meta } of mm) {
50
42
  imports.addImport({ items: [model.typeName], from: meta.types.importPath });
@@ -57,7 +49,7 @@ function generateDataMockModule({ models, meta }) {
57
49
  useFactory: async () => {
58
50
  const repository = new ${meta.data.mockRepositoryClassName}()
59
51
  if (!!seed && !!seed.${meta.seed.constantName}) {
60
- await repository.reInit(seed.${meta.seed.constantName})
52
+ await repository.reInit({items: seed.${meta.seed.constantName}, execution })
61
53
  }
62
54
  return repository
63
55
  }
@@ -70,11 +62,11 @@ import { DbModule } from '@${meta.config.project}/db'
70
62
  ${imports.generate()}
71
63
 
72
64
  export class DataMockModule {
73
-
74
65
  static mock(seed?: MockData): DynamicModule {
66
+ const execution = new MockActionExecution()
67
+
75
68
  const providers = [
76
69
  DataService,
77
- TestDataService,
78
70
  ${providers}
79
71
  ]
80
72
 
@@ -11,13 +11,9 @@ function generateDataMocker({ models, meta: schemaMeta }) {
11
11
  const modelMetas = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
12
12
  const imports = imports_1.ImportsGenerator.from(schemaMeta.data.dataMockerFilePath);
13
13
  for (const { model, meta } of modelMetas) {
14
- imports.addImport({
15
- items: [model.typeName],
16
- from: meta.types.importPath,
17
- });
18
- imports.addImport({
19
- items: [meta.data.stubGenerationFnName],
20
- from: schemaMeta.data.dataMockerStubImportPath,
14
+ imports.addImports({
15
+ [meta.types.importPath]: [model.typeName],
16
+ [schemaMeta.data.dataMockerStubImportPath]: [meta.data.stubGenerationFnName],
21
17
  });
22
18
  }
23
19
  const publicVariables = modelMetas
@@ -27,13 +23,15 @@ function generateDataMocker({ models, meta: schemaMeta }) {
27
23
  .map(({ model, meta }) => `private ${meta.data.dataServiceIdName}Ids = new IdTracker<${model.typeName}>()`)
28
24
  .join('\n');
29
25
  const addDataFunctions = modelMetas.map(({ model, meta }) => generateAddDataFunction(model, meta)).join('\n');
30
- // const timeNow = new Date().toLocaleTimeString('en-US', { hour12: false, hour: 'numeric', minute: 'numeric' })
31
- // const todayDate = new Date().toLocaleDateString('en-US', { year: 'numeric', month: 'numeric', day: 'numeric' })
32
26
  return `
27
+ /* eslint-disable @typescript-eslint/no-unused-vars */
33
28
  import type { MockData } from '@pxl/data'
34
- import { IdTracker } from './id-tracker.class'
29
+
35
30
  ${imports.generate()}
36
31
 
32
+ import { IdTracker } from './id-tracker.class'
33
+
34
+
37
35
  export class DataMocker implements MockData {
38
36
  ${publicVariables}
39
37
 
@@ -44,38 +42,46 @@ export class DataMocker implements MockData {
44
42
  `;
45
43
  }
46
44
  exports.generateDataMocker = generateDataMocker;
47
- // Generated time stamp: ${todayDate} ${timeNow}
48
45
  function generateAddDataFunction(model, meta) {
49
46
  const { fields, idField } = model;
50
- const relations = fields.filter(schema_1.isFieldRelation).map((field) => (Object.assign(Object.assign({}, field), { meta: (0, meta_1.getModelMetadata)({ model: field.relationToModel }), fieldMeta: (0, meta_1.getFieldMetadata)({ field }), model: field.relationToModel })));
51
- return `public add${model.typeName}(item?: Partial<Omit<${model.typeName}, '${idField.name}'> & { ${idField.name}: ${idField.unbrandedTypeName}}>): DataMocker {
52
- const initial${meta.data.dataServiceIdName} = stub${model.typeName}(item ?? {})
53
- this.${meta.data.dataServiceName}.push(this.${meta.data.dataServiceIdName}Ids.ensureId(initial${meta.data.dataServiceIdName}))
54
- const ${meta.data.dataServiceIdName} = this.${meta.data.dataServiceName}[this.${meta.data.dataServiceName}.length - 1]
55
- ${relations
56
- .map((r) => `
57
- ${r.isRequired
58
- ? `
59
- if (${meta.data.dataServiceIdName}.${r.name}) {
60
- if (this.${r.meta.data.dataServiceName}.findIndex((x) => x.id === ${meta.data.dataServiceIdName}.${r.name}) === -1 ) {
61
- this.add${r.model.typeName}({ id: ${meta.data.dataServiceIdName}.${r.name} })
62
- }
63
- } else {
64
- if (this.${r.meta.data.dataServiceName}.length === 0) {
65
- this.add${r.model.typeName}()
66
- }
67
- ${meta.data.dataServiceIdName}.${r.name} = this.${r.meta.data.dataServiceName}[0].id
68
- }
69
- `
70
- : `
71
- if (${meta.data.dataServiceIdName}.${r.name}) {
72
- if (this.${r.meta.data.dataServiceName}.findIndex((x) => x.id === ${meta.data.dataServiceIdName}.${r.name}) === -1 ) {
73
- this.add${r.model.typeName}({ id: ${meta.data.dataServiceIdName}.${r.name} })
74
- }
75
- }
76
- `}
77
- `)
78
- .join('\n')}
47
+ const relations = fields
48
+ .filter(schema_1.isFieldRelation)
49
+ .map((field) => (Object.assign(Object.assign({}, field), { meta: (0, meta_1.getModelMetadata)({ model: field.relationToModel }), fieldMeta: (0, meta_1.getFieldMetadata)({ field }), model: field.relationToModel })))
50
+ .map((r) => {
51
+ if (r.isRequired) {
52
+ return `
53
+ if (_item.${r.name}) {
54
+ if (this.${r.meta.data.dataServiceName}.findIndex((x) => x.id === _item.${r.name}) === -1) {
55
+ this.add${r.model.typeName}({ id: _item.${r.name} })
56
+ }
57
+ } else {
58
+ if (this.${r.meta.data.dataServiceName}.length === 0) {
59
+ this.add${r.model.typeName}()
60
+ }
61
+ _item.${r.name} = this.${r.meta.data.dataServiceName}[0].id
62
+ }
63
+ `;
64
+ }
65
+ return `
66
+ if (_item.${r.name}) {
67
+ if (this.${r.meta.data.dataServiceName}.findIndex((x) => x.id === _item.${r.name}) === -1) {
68
+ this.add${r.model.typeName}({ id: _item.${r.name} })
69
+ }
70
+ }
71
+ `;
72
+ });
73
+ // TODO: Move the publicly accessible function's name to the metadata definition!
74
+ return `
75
+ public add${model.typeName}(
76
+ item?: Partial<Omit<${model.typeName}, '${idField.name}'> & { ${idField.name}: ${idField.unbrandedTypeName} }>
77
+ ): DataMocker {
78
+ const _stub = stub${model.typeName}(item ?? {})
79
+ const _item = this.${meta.data.dataServiceIdName}Ids.ensureId(_stub)
80
+
81
+ this.${meta.data.dataServiceName}.push(_item)
82
+
83
+ ${relations.join('\n')}
84
+
79
85
  return this
80
86
  }`;
81
87
  }
@@ -30,17 +30,10 @@ const Types = __importStar(require("../../lib/schema/types"));
30
30
  /**
31
31
  * Generates a data module class.
32
32
  */
33
- // TODO: https://github.com/PostXL/PostXL/issues/347
34
33
  function generateDataModule({ models, meta }) {
35
34
  const mm = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
36
- const imports = imports_1.ImportsGenerator.from(meta.data.dataModuleFilePath)
37
- .addImport({
38
- items: [Types.toVariableName('TestDataService')],
39
- from: meta.data.testDataServiceFilePath,
40
- })
41
- .addImport({
42
- items: [Types.toVariableName('DataService')],
43
- from: meta.data.dataServiceFilePath,
35
+ const imports = imports_1.ImportsGenerator.from(meta.data.dataModuleFilePath).addImports({
36
+ [meta.data.dataServiceFilePath]: [Types.toVariableName('DataService')],
44
37
  });
45
38
  for (const { meta } of mm) {
46
39
  imports.addImport({
@@ -65,7 +58,9 @@ export class ${moduleName} {
65
58
  * The getInstance method should be called by any module that needs the module.
66
59
  */
67
60
  static getInstance(): DynamicModule {
68
- if (!${moduleName}.cachedModule) throw new Error('${moduleName} must be called via .provide first!')
61
+ if (!${moduleName}.cachedModule) {
62
+ throw new Error('${moduleName} must be called via .provide first!')
63
+ }
69
64
  return ${moduleName}.cachedModule
70
65
  }
71
66
 
@@ -106,11 +101,10 @@ export class ${moduleName} {
106
101
  return ${moduleName}.cachedModule
107
102
  }
108
103
 
109
- const repositoryProviders = [
104
+ const providers = [
110
105
  ${mm.map(({ meta }) => meta.data.repositoryClassName).join(',')}
111
106
  ]
112
- const providers = [TestDataService, ...repositoryProviders]
113
-
107
+
114
108
  ${moduleName}.cachedModule = {
115
109
  module: ${moduleName},
116
110
  global: true,
@@ -1,9 +1,9 @@
1
1
  import { SchemaMetaData } from '../../lib/meta';
2
2
  import { Model } from '../../lib/schema/schema';
3
3
  /**
4
- * Generates a business Logic module class.
4
+ * Generates the action dispatcher service.
5
5
  */
6
- export declare function generateBusinessLogicModule({ models, meta }: {
6
+ export declare function generateActionsDispatcherService({ models, meta }: {
7
7
  models: Model[];
8
8
  meta: SchemaMetaData;
9
9
  }): string;
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateActionsDispatcherService = void 0;
4
+ const imports_1 = require("../../lib/imports");
5
+ const meta_1 = require("../../lib/meta");
6
+ /**
7
+ * Generates the action dispatcher service.
8
+ */
9
+ function generateActionsDispatcherService({ models, meta }) {
10
+ const imports = imports_1.ImportsGenerator.from(meta.seed.serviceFilePath).addImports({
11
+ [meta.seed.importPath]: [meta.seed.serviceClassName],
12
+ [meta.businessLogic.update.importPath]: [meta.businessLogic.update.serviceClassName],
13
+ [meta.types.importPath]: meta.config.userType,
14
+ });
15
+ const dataLoader = [];
16
+ for (const model of models) {
17
+ const modelMeta = (0, meta_1.getModelMetadata)({ model });
18
+ dataLoader.push(`await this.upload({ name: '${modelMeta.userFriendlyName}', data: data.${modelMeta.seed.constantName}, repo: this.dataService.${modelMeta.data.dataServiceName}, log })`);
19
+ }
20
+ return `
21
+ import { Injectable } from '@nestjs/common'
22
+
23
+ import { ExhaustiveSwitchCheck } from '@pxl/common'
24
+ import { DbService } from '@pxl/db'
25
+
26
+ ${imports.generate()}
27
+
28
+ import { ActionExecution, createActionExecution } from './actionExecution.class'
29
+ import { Action, ResultOfAction } from './actions.types'
30
+
31
+
32
+ @Injectable()
33
+ export class DispatcherService {
34
+ // as the SeedModule gets instantiated after the ActionsModule, we use this hack to avoid a circular dependency:
35
+ // we set the seedService to a dummy value and then overwrite it in the ${meta.seed.serviceClassName} constructor.
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
37
+ public seedService: ${meta.seed.serviceClassName} = {} as unknown as any
38
+ constructor(
39
+ private readonly updateService: ${meta.businessLogic.update.serviceClassName},
40
+ private readonly dbService: DbService
41
+ ) {}
42
+
43
+ public async dispatch<A extends Action>({ action, user }: {
44
+ action: A;
45
+ user: ${meta.config.userType}
46
+ }): Promise<ResultOfAction<A>> {
47
+ const execution = await createActionExecution({ action, dbService: this.dbService, user })
48
+
49
+ try {
50
+ const result = await (this.execute({ action, execution }) as Promise<ResultOfAction<A>>)
51
+
52
+ await execution.success()
53
+
54
+ return result
55
+ } catch (e) {
56
+ await execution.error(e)
57
+ throw e
58
+ }
59
+ }
60
+
61
+ private async execute({ action, execution }: { action: Action; execution: ActionExecution }) {
62
+ switch (action.scope) {
63
+ ${models
64
+ .map((model) => {
65
+ const modelMeta = (0, meta_1.getModelMetadata)({ model });
66
+ return `
67
+ case '${modelMeta.businessLogic.scopeName}':
68
+ return this.updateService.${modelMeta.businessLogic.update.serviceVariableName}.dispatch({ action, execution })
69
+ `;
70
+ })
71
+ .join('\n')}
72
+ case 'seed':
73
+ return this.seedService.dispatch({ action, execution })
74
+ default:
75
+ throw new ExhaustiveSwitchCheck(action)
76
+ }
77
+ }
78
+ }
79
+ `;
80
+ }
81
+ exports.generateActionsDispatcherService = generateActionsDispatcherService;
@@ -0,0 +1,9 @@
1
+ import { SchemaMetaData } from '../../lib/meta';
2
+ import { Model } from '../../lib/schema/schema';
3
+ /**
4
+ * Generates the initial migration based on the generated seed data.
5
+ */
6
+ export declare function generateSeedMigration({ models, meta }: {
7
+ models: Model[];
8
+ meta: SchemaMetaData;
9
+ }): string;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSeedMigration = void 0;
4
+ const imports_1 = require("../../lib/imports");
5
+ const meta_1 = require("../../lib/meta");
6
+ /**
7
+ * Generates the initial migration based on the generated seed data.
8
+ */
9
+ function generateSeedMigration({ models, meta }) {
10
+ const imports = imports_1.ImportsGenerator.from(meta.seedData.initialMigrationFilePath);
11
+ const modelTypes = [];
12
+ for (const model of models) {
13
+ const modelMeta = (0, meta_1.getModelMetadata)({ model });
14
+ imports.addImport({
15
+ items: [modelMeta.seed.constantName],
16
+ from: modelMeta.seed.filePath,
17
+ });
18
+ modelTypes.push(`${modelMeta.seed.constantName}: { create: ${modelMeta.seed.constantName} }`);
19
+ }
20
+ return `
21
+ import { createActionSeedData } from '${meta.seed.importPath}'
22
+ ${imports.generate()}
23
+
24
+ export const MIGRATION_001_BASEDATA = createActionSeedData({
25
+ name: 'Base data',
26
+ order: 1,
27
+ data: [
28
+ {
29
+ ${modelTypes.join(',\n')}
30
+ },
31
+ ],
32
+ })
33
+ `;
34
+ }
35
+ exports.generateSeedMigration = generateSeedMigration;
@@ -3,7 +3,7 @@ import { Model } from '../../lib/schema/schema';
3
3
  /**
4
4
  * Generates index file for all seed files.
5
5
  */
6
- export declare function generateSeedService({ models, meta }: {
6
+ export declare function generateSeedService({ models }: {
7
7
  models: Model[];
8
8
  meta: SchemaMetaData;
9
9
  }): string;