@postxl/generator 0.54.0 → 0.56.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.
- package/dist/generator.js +1 -1
- package/dist/generators/indices/businesslogic-actiontypes.generator.js +18 -7
- package/dist/generators/indices/businesslogic-update-index.generator.js +3 -1
- package/dist/generators/indices/dispatcher-service.generator.js +2 -2
- package/dist/generators/indices/importexport-exporter-class.generator.js +41 -4
- package/dist/generators/indices/importexport-import-service.generator.js +2 -2
- package/dist/generators/indices/seed-migration.generator.js +9 -7
- package/dist/generators/indices/testdata-service.generator.js +9 -3
- package/dist/generators/models/businesslogic-update.generator.js +162 -218
- package/dist/generators/models/businesslogic-view.generator.js +47 -10
- package/dist/generators/models/route.generator.js +28 -31
- package/dist/generators/models/types.generator.js +18 -99
- package/dist/lib/exports.d.ts +4 -0
- package/dist/lib/exports.js +38 -8
- package/dist/lib/meta.d.ts +15 -52
- package/dist/lib/meta.js +6 -15
- package/dist/lib/schema/schema.d.ts +10 -6
- package/dist/lib/schema/types.d.ts +5 -5
- package/dist/lib/utils/jsdoc.d.ts +5 -0
- package/dist/lib/utils/jsdoc.js +22 -1
- package/dist/prisma/parse.js +49 -25
- package/package.json +1 -1
package/dist/generator.js
CHANGED
|
@@ -221,7 +221,7 @@ function generate({ models, enums, config, prismaClientPath, logger, }) {
|
|
|
221
221
|
generated.write(`/${meta.importExport.decoder.fullDecoderFilePath}.ts`, (0, importexport_decoder_generator_1.generateImportExportDecoder)({ models, meta }));
|
|
222
222
|
generated.write(`/${meta.importExport.converterFunctions.filePath}.ts`, (0, importexport_convert_import_functions_generator_1.generateImportExportConvertImportFunctions)({ models, meta }));
|
|
223
223
|
// Actions
|
|
224
|
-
generated.write(`/${meta.actions.
|
|
224
|
+
generated.write(`/${meta.actions.dispatcher.filePath}.ts`, (0, dispatcher_service_generator_1.generateActionsDispatcherService)({ models, meta }));
|
|
225
225
|
// Business Logic
|
|
226
226
|
generated.write(`/${meta.businessLogic.view.indexFilePath}.ts`, (0, businesslogic_view_index_generator_1.generateBusinessLogicViewIndex)({ models, meta }));
|
|
227
227
|
generated.write(`/${meta.businessLogic.view.moduleFilePath}.ts`, (0, businesslogic_view_module_generator_1.generateBusinessLogicViewModule)({ models, meta }));
|
|
@@ -3,27 +3,38 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateBusinessLogicActionTypes = void 0;
|
|
4
4
|
const imports_1 = require("../../lib/imports");
|
|
5
5
|
const meta_1 = require("../../lib/meta");
|
|
6
|
+
const types_1 = require("../../lib/schema/types");
|
|
7
|
+
const file_1 = require("../../lib/utils/file");
|
|
6
8
|
/**
|
|
7
9
|
* Generates the action types for the BusinessLogicModule.
|
|
8
10
|
*/
|
|
9
11
|
function generateBusinessLogicActionTypes({ models, meta }) {
|
|
10
|
-
const imports = imports_1.ImportsGenerator.from(meta.businessLogic.update.actionTypesFilePath)
|
|
12
|
+
const imports = imports_1.ImportsGenerator.from(meta.businessLogic.update.actionTypesFilePath).addImport({
|
|
13
|
+
from: meta.actions.importPath,
|
|
14
|
+
items: [(0, types_1.toTypeName)('ActionDefPayload'), (0, types_1.toTypeName)('ActionDefResult')],
|
|
15
|
+
});
|
|
16
|
+
const updateServiceImports = [];
|
|
11
17
|
const modelNameTypeElements = [];
|
|
12
18
|
const actionsTypeElements = [];
|
|
13
19
|
const actionResultTypeElements = [];
|
|
14
20
|
for (const model of models) {
|
|
15
21
|
const modelMeta = (0, meta_1.getModelMetadata)({ model });
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
const className = modelMeta.businessLogic.update.serviceClassName;
|
|
23
|
+
const scope = modelMeta.businessLogic.update.actionModelDiscriminantName;
|
|
24
|
+
modelNameTypeElements.push(`'${scope}'`);
|
|
25
|
+
const relativeImportPath = (0, file_1.getRelativePath)({
|
|
26
|
+
from: meta.businessLogic.update.actionTypesFilePath,
|
|
27
|
+
to: modelMeta.businessLogic.update.serviceFilePath,
|
|
19
28
|
});
|
|
20
|
-
|
|
21
|
-
actionsTypeElements.push(
|
|
22
|
-
actionResultTypeElements.push(`${
|
|
29
|
+
updateServiceImports.push(`import type * as ${className} from '${relativeImportPath}'`);
|
|
30
|
+
actionsTypeElements.push(`ActionDefPayload<${className}.Scope, ${className}.Actions>`);
|
|
31
|
+
actionResultTypeElements.push(`${scope}: ActionDefResult<${className}.Actions>`);
|
|
23
32
|
}
|
|
24
33
|
return /* ts */ `
|
|
25
34
|
${imports.generate()}
|
|
26
35
|
|
|
36
|
+
${updateServiceImports.join('\n')}
|
|
37
|
+
|
|
27
38
|
/**
|
|
28
39
|
* Used by any of the default actions (create, update, delete) to identify the model.
|
|
29
40
|
*/
|
|
@@ -13,7 +13,9 @@ function generateBusinessLogicUpdateIndex({ models, meta }) {
|
|
|
13
13
|
exports.exportEverythingFromPath(meta.businessLogic.update.actionTypesFilePath);
|
|
14
14
|
for (const model of models) {
|
|
15
15
|
const meta = (0, meta_1.getModelMetadata)({ model });
|
|
16
|
-
exports.
|
|
16
|
+
exports.exportSelectionFromPath(meta.businessLogic.update.serviceFilePath, [
|
|
17
|
+
meta.businessLogic.update.serviceClassName,
|
|
18
|
+
]);
|
|
17
19
|
}
|
|
18
20
|
return exports.generate();
|
|
19
21
|
}
|
|
@@ -8,7 +8,7 @@ const types_1 = require("../../lib/schema/types");
|
|
|
8
8
|
* Generates the action dispatcher service.
|
|
9
9
|
*/
|
|
10
10
|
function generateActionsDispatcherService({ models, meta }) {
|
|
11
|
-
const imports = imports_1.ImportsGenerator.from(meta.actions.
|
|
11
|
+
const imports = imports_1.ImportsGenerator.from(meta.actions.dispatcher.filePath).addImports({
|
|
12
12
|
[meta.seed.importPath]: [meta.seed.serviceClassName],
|
|
13
13
|
[meta.importExport.importPath]: [meta.importExport.importService.name],
|
|
14
14
|
[meta.businessLogic.update.importPath]: [meta.businessLogic.update.serviceClassName],
|
|
@@ -32,7 +32,7 @@ import { Action, ResultOfAction } from './actions.types'
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
@Injectable()
|
|
35
|
-
export class ${meta.actions.
|
|
35
|
+
export class ${meta.actions.dispatcher.class} {
|
|
36
36
|
|
|
37
37
|
// As SeedModule and ImportExportModule get instantiated after the ActionsModule, we use this hack to avoid a circular dependency:
|
|
38
38
|
// we set the seedService and the importService to value and then overwrite it in the services' constructors.
|
|
@@ -9,6 +9,7 @@ const types_1 = require("../../lib/schema/types");
|
|
|
9
9
|
*/
|
|
10
10
|
function generateImportExportExporterClass({ models, meta }) {
|
|
11
11
|
const imports = imports_1.ImportsGenerator.from(meta.importExport.exporterClass.filePath);
|
|
12
|
+
const modelsMap = new Map(models.map((model) => [model.name, model]));
|
|
12
13
|
imports.addImports({
|
|
13
14
|
[meta.businessLogic.view.importPath]: [meta.businessLogic.view.serviceClassName],
|
|
14
15
|
[meta.importExport.decoder.fullDecoderFilePath]: [
|
|
@@ -39,20 +40,50 @@ function generateImportExportExporterClass({ models, meta }) {
|
|
|
39
40
|
}
|
|
40
41
|
const linkedModelMeta = (0, meta_1.getModelMetadata)({ model: field.relationToModel });
|
|
41
42
|
if (field.isRequired) {
|
|
42
|
-
linkedItems.push(`await this.${linkedModelMeta.importExport.exportAddFunctionName}(item.${field.name})`);
|
|
43
|
+
linkedItems.push(`await this.${linkedModelMeta.importExport.exportAddFunctionName}({id: item.${field.name}, includeChildren: false})`);
|
|
43
44
|
}
|
|
44
45
|
else {
|
|
45
46
|
linkedItems.push(`
|
|
46
47
|
if (item.${field.name}) {
|
|
47
|
-
await this.${linkedModelMeta.importExport.exportAddFunctionName}(item.${field.name})
|
|
48
|
+
await this.${linkedModelMeta.importExport.exportAddFunctionName}({id: item.${field.name}, includeChildren: false})
|
|
48
49
|
}`);
|
|
49
50
|
}
|
|
50
51
|
}
|
|
52
|
+
const childItemCalls = [];
|
|
53
|
+
for (const relatedModelCore of model.relatedModels) {
|
|
54
|
+
const relatedModel = modelsMap.get(relatedModelCore.name);
|
|
55
|
+
// This should not happen as the related models are always present
|
|
56
|
+
if (!relatedModel) {
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
for (const field of relatedModel.fields) {
|
|
60
|
+
if (field.kind !== 'relation') {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (field.relationToModel.name !== model.name) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const linkedModelMeta = (0, meta_1.getModelMetadata)({ model: relatedModel });
|
|
67
|
+
const linkedFieldMeta = (0, meta_1.getFieldMetadata)({ field: field });
|
|
68
|
+
childItemCalls.push(`
|
|
69
|
+
// Add all ${linkedModelMeta.userFriendlyNamePlural} that are related to the ${modelMeta.userFriendlyName} via ${field.name}
|
|
70
|
+
for (const ${field.name} of await this.viewService.${linkedModelMeta.businessLogic.view.serviceVariableName}.data.${linkedFieldMeta.getByForeignKeyIdsMethodFnName}(id)) {
|
|
71
|
+
await this.${linkedModelMeta.importExport.exportAddFunctionName}({id: ${field.name}, includeChildren})
|
|
72
|
+
}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
const childItems = childItemCalls.length > 0
|
|
76
|
+
? `
|
|
77
|
+
if (includeChildren) {
|
|
78
|
+
${childItemCalls.join('\n')}
|
|
79
|
+
}`
|
|
80
|
+
: '';
|
|
81
|
+
const signature = `{id, includeChildren = true}: {id: ${model.brandedIdType}, includeChildren?: boolean}`;
|
|
51
82
|
addFunctions.push(`
|
|
52
83
|
/**
|
|
53
84
|
* Adds a ${modelMeta.userFriendlyName} and all related (and nested) dependencies to the export.
|
|
54
85
|
*/
|
|
55
|
-
public async ${modelMeta.importExport.exportAddFunctionName}(
|
|
86
|
+
public async ${modelMeta.importExport.exportAddFunctionName}(${signature}) {
|
|
56
87
|
if (this.${modelMeta.internalPluralName}.has(id)) {
|
|
57
88
|
return
|
|
58
89
|
}
|
|
@@ -64,11 +95,17 @@ function generateImportExportExporterClass({ models, meta }) {
|
|
|
64
95
|
this.${modelMeta.internalPluralName}.set(id, item)
|
|
65
96
|
|
|
66
97
|
${linkedItems.join('\n')}
|
|
98
|
+
|
|
99
|
+
${childItems}
|
|
67
100
|
}
|
|
68
101
|
`);
|
|
69
102
|
addAllCalls.push(`this.${modelMeta.internalPluralName} = await this.viewService.${modelMeta.businessLogic.view.serviceVariableName}.getAll()`);
|
|
70
103
|
}
|
|
71
104
|
return /* ts */ `
|
|
105
|
+
// For consistency, we include \`{ includeChildren = true }\` in the signature of every add function.
|
|
106
|
+
// If the model does not have any related models, the \`includeChildren\` parameter is ignored.
|
|
107
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
108
|
+
|
|
72
109
|
import { Logger } from '@nestjs/common'
|
|
73
110
|
|
|
74
111
|
import { mapValues } from '@backend/common'
|
|
@@ -79,7 +116,7 @@ ${imports.generate()}
|
|
|
79
116
|
*
|
|
80
117
|
* Usage:
|
|
81
118
|
* - Create an instance of the Exporter
|
|
82
|
-
* - Call the \`add{ModelName}(
|
|
119
|
+
* - Call the \`add{ModelName}({id})\` methods to add the items you want to export.
|
|
83
120
|
* This will automatically add all dependencies of the item.
|
|
84
121
|
* - Call the \`exportData()\` method to get the encoded Excel data.
|
|
85
122
|
* - Alternatively, you can call 'exportAll()' to dump all data.
|
|
@@ -22,7 +22,7 @@ function generateImportExportImportService({ models, meta }) {
|
|
|
22
22
|
(0, types_1.toAnnotatedTypeName)(dto.idType),
|
|
23
23
|
(0, types_1.toAnnotatedTypeName)(dto.update),
|
|
24
24
|
],
|
|
25
|
-
[meta.actions.importPath]: [meta.actions.actionExecution.interface, meta.actions.
|
|
25
|
+
[meta.actions.importPath]: [meta.actions.actionExecution.interface, meta.actions.dispatcher.class],
|
|
26
26
|
[types.filePath]: [
|
|
27
27
|
(0, types_1.toAnnotatedTypeName)(delta_Fields),
|
|
28
28
|
(0, types_1.toAnnotatedTypeName)(delta_Model.type),
|
|
@@ -61,7 +61,7 @@ type Delta_Result<Model extends ${dto.genericModel}<ID>, ID extends ${dto.idType
|
|
|
61
61
|
export class ${meta.importExport.importService.name} {
|
|
62
62
|
constructor(
|
|
63
63
|
private readonly data: ${meta.data.dataService.class},
|
|
64
|
-
private readonly dispatcher: ${meta.actions.
|
|
64
|
+
private readonly dispatcher: ${meta.actions.dispatcher.class},
|
|
65
65
|
) {
|
|
66
66
|
// We have a circular dependency between DispatcherService and ${meta.importExport.importService.name}.
|
|
67
67
|
// In order to avoid trouble, instead of using Nest's forwardRef(), we inject the dispatcher service here
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.generateSeedMigration = void 0;
|
|
4
4
|
const imports_1 = require("../../lib/imports");
|
|
5
5
|
const meta_1 = require("../../lib/meta");
|
|
6
|
+
const types_1 = require("../../lib/schema/types");
|
|
6
7
|
/**
|
|
7
8
|
* Generates the initial migration based on the generated seed data.
|
|
8
9
|
*/
|
|
@@ -14,21 +15,22 @@ function generateSeedMigration({ models, meta }) {
|
|
|
14
15
|
imports.addImports({
|
|
15
16
|
[modelMeta.seed.filePath]: [modelMeta.seed.constantName],
|
|
16
17
|
[meta.importExport.importPath]: [meta.importExport.converterFunctions.importedDataToBulkMutations],
|
|
18
|
+
[meta.seed.importPath]: [(0, types_1.toTypeName)('Action_Seed_Data')],
|
|
17
19
|
});
|
|
18
20
|
modelTypes.push(`${modelMeta.seed.constantName}`);
|
|
19
21
|
}
|
|
20
22
|
return /* ts */ `
|
|
21
|
-
import { createActionSeedData } from '${meta.seed.importPath}'
|
|
22
23
|
${imports.generate()}
|
|
23
24
|
|
|
24
|
-
export const MIGRATION_001_BASEDATA =
|
|
25
|
+
export const MIGRATION_001_BASEDATA: Action_Seed_Data = {
|
|
26
|
+
scope: 'seed',
|
|
27
|
+
type: 'data',
|
|
25
28
|
name: 'Base data',
|
|
26
29
|
order: 1,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
})
|
|
30
|
+
payload: ${meta.importExport.converterFunctions.importedDataToBulkMutations}({
|
|
31
|
+
${modelTypes.join(',\n')}
|
|
32
|
+
}),
|
|
33
|
+
}
|
|
32
34
|
`;
|
|
33
35
|
}
|
|
34
36
|
exports.generateSeedMigration = generateSeedMigration;
|
|
@@ -16,7 +16,6 @@ function generateTestDataService({ models, meta: schemaMeta, }) {
|
|
|
16
16
|
(0, types_1.toAnnotatedTypeName)(schemaMeta.data.dataMockDataType),
|
|
17
17
|
],
|
|
18
18
|
[schemaMeta.importExport.importPath]: [schemaMeta.importExport.converterFunctions.mockDataToBulkMutations],
|
|
19
|
-
[schemaMeta.seed.importPath]: [(0, types_1.toClassName)('createActionSeedData')],
|
|
20
19
|
});
|
|
21
20
|
const reInitCalls = [];
|
|
22
21
|
const modelMetas = models.map((model) => ({ model, meta: (0, meta_1.getModelMetadata)({ model }) }));
|
|
@@ -57,12 +56,19 @@ export class TestDataService {
|
|
|
57
56
|
this.logger.log('✍ Setting test data')
|
|
58
57
|
|
|
59
58
|
const mockData = ${schemaMeta.importExport.converterFunctions.mockDataToBulkMutations}(data)
|
|
60
|
-
|
|
59
|
+
|
|
61
60
|
const actionExecution = await this.actionExecutionFactory.create({
|
|
62
|
-
action
|
|
61
|
+
action: {
|
|
62
|
+
scope: 'seed',
|
|
63
|
+
type: 'data',
|
|
64
|
+
name: 'E2E',
|
|
65
|
+
order: 0,
|
|
66
|
+
payload: []
|
|
67
|
+
},
|
|
63
68
|
dbService: this.db,
|
|
64
69
|
user: this.dataService.users.rootUser,
|
|
65
70
|
})
|
|
71
|
+
|
|
66
72
|
try {
|
|
67
73
|
${reInitCalls.join('\n')}
|
|
68
74
|
|