@postxl/generator 0.39.0 → 0.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generator.js +37 -21
- package/dist/generators/indices/businesslogic-update-module.generator.js +1 -1
- package/dist/generators/indices/businesslogic-view-module.generator.js +1 -1
- package/dist/generators/indices/{seed-service.generator.d.ts → data-types.generator.d.ts} +2 -2
- package/dist/generators/indices/data-types.generator.js +48 -0
- package/dist/generators/indices/datamock-module.generator.js +7 -7
- package/dist/generators/indices/datamodule.generator.js +13 -34
- package/dist/generators/indices/dataservice.generator.js +201 -8
- package/dist/generators/indices/dispatcher-service.generator.js +14 -5
- package/dist/generators/indices/importexport-convert-import-functions.generator.d.ts +9 -0
- package/dist/generators/indices/importexport-convert-import-functions.generator.js +528 -0
- package/dist/generators/indices/{seed-template-decoder.generator.d.ts → importexport-exporter-class.generator.d.ts} +2 -2
- package/dist/generators/indices/importexport-exporter-class.generator.js +116 -0
- package/dist/generators/indices/importexport-import-service.generator.d.ts +9 -0
- package/dist/generators/indices/importexport-import-service.generator.js +563 -0
- package/dist/generators/indices/{seeddata-type.generator.d.ts → importexport-types.generator.d.ts} +2 -2
- package/dist/generators/indices/importexport-types.generator.js +234 -0
- package/dist/generators/indices/repositories.generator.js +7 -7
- package/dist/generators/indices/seed-template.generator.js +1 -1
- package/dist/generators/indices/testdata-service.generator.js +5 -4
- package/dist/generators/models/businesslogic-update.generator.js +5 -5
- package/dist/generators/models/businesslogic-view.generator.js +3 -3
- package/dist/generators/models/importexport-decoder.generator.d.ts +23 -0
- package/dist/generators/models/importexport-decoder.generator.js +234 -0
- package/dist/generators/models/repository.generator.js +50 -21
- package/dist/lib/imports.d.ts +1 -1
- package/dist/lib/meta.d.ts +468 -134
- package/dist/lib/meta.js +187 -80
- package/dist/lib/schema/schema.d.ts +54 -43
- package/dist/lib/schema/types.d.ts +63 -12
- package/dist/lib/schema/types.js +27 -7
- package/dist/lib/utils/string.d.ts +1 -0
- package/dist/lib/utils/string.js +4 -0
- package/dist/prisma/parse.js +4 -4
- package/package.json +1 -1
- package/dist/generators/indices/seed-service.generator.js +0 -354
- package/dist/generators/indices/seed-template-decoder.generator.js +0 -151
- package/dist/generators/indices/seeddata-type.generator.js +0 -42
|
@@ -14,8 +14,8 @@ const string_1 = require("../../lib/utils/string");
|
|
|
14
14
|
function generateRepository({ model, meta }) {
|
|
15
15
|
const { idField } = model;
|
|
16
16
|
const schemaMeta = (0, meta_1.getSchemaMetadata)({ config: model.schemaConfig });
|
|
17
|
-
const imports = imports_1.ImportsGenerator.from(meta.data.
|
|
18
|
-
[schemaMeta.data.
|
|
17
|
+
const imports = imports_1.ImportsGenerator.from(meta.data.repository.filePath).addImports({
|
|
18
|
+
[schemaMeta.data.repository.typeFilePath]: schemaMeta.data.repository.typeName,
|
|
19
19
|
[meta.types.importPath]: [
|
|
20
20
|
model.typeName,
|
|
21
21
|
model.brandedIdType,
|
|
@@ -24,7 +24,7 @@ function generateRepository({ model, meta }) {
|
|
|
24
24
|
meta.types.dto.update,
|
|
25
25
|
meta.types.dto.upsert,
|
|
26
26
|
],
|
|
27
|
-
[schemaMeta.actions.importPath]: [schemaMeta.actions.
|
|
27
|
+
[schemaMeta.actions.importPath]: [schemaMeta.actions.actionExecution.interface],
|
|
28
28
|
});
|
|
29
29
|
// NOTE: We first generate different parts of the code responsible for a particular task
|
|
30
30
|
// and then we combine them into the final code block.
|
|
@@ -37,7 +37,7 @@ function generateRepository({ model, meta }) {
|
|
|
37
37
|
// and allow being called with an id,
|
|
38
38
|
// 3.) unique string fields are ensured to be unique,
|
|
39
39
|
// 4.) max length string fields are ensured to not exceed their max length,
|
|
40
|
-
// 5.) index for fields marked with index attribute,
|
|
40
|
+
// 5.) index for fields marked with index or unique attribute,
|
|
41
41
|
// 6.) relations are indexed by the foreign key.
|
|
42
42
|
//
|
|
43
43
|
// The repository is generated differently based on whether the model is stored in the database or in memory.
|
|
@@ -47,6 +47,7 @@ function generateRepository({ model, meta }) {
|
|
|
47
47
|
const defaultValueBlocks = generateDefaultBlocks({ model, meta });
|
|
48
48
|
const uniqueStringFieldsBlocks = generateUniqueFieldsBlocks({ model, meta });
|
|
49
49
|
const maxLengthBlocks = generateMaxLengthBlocks({ model, meta });
|
|
50
|
+
const validationBlocks = generateValidationBlocks({ model, meta });
|
|
50
51
|
const indexBlocks = generateIndexBlocks({ model, meta, imports });
|
|
51
52
|
const relationsBlocks = generateRelationsBlocks({ model, meta, imports });
|
|
52
53
|
let mainBlocks;
|
|
@@ -62,6 +63,7 @@ function generateRepository({ model, meta }) {
|
|
|
62
63
|
idBlocks,
|
|
63
64
|
indexBlocks,
|
|
64
65
|
maxLengthBlocks,
|
|
66
|
+
validationBlocks,
|
|
65
67
|
},
|
|
66
68
|
});
|
|
67
69
|
}
|
|
@@ -77,6 +79,7 @@ function generateRepository({ model, meta }) {
|
|
|
77
79
|
idBlocks,
|
|
78
80
|
indexBlocks,
|
|
79
81
|
maxLengthBlocks,
|
|
82
|
+
validationBlocks,
|
|
80
83
|
},
|
|
81
84
|
});
|
|
82
85
|
}
|
|
@@ -86,9 +89,9 @@ ${idBlocks.libraryImports}
|
|
|
86
89
|
${imports.generate()}
|
|
87
90
|
|
|
88
91
|
@Injectable()
|
|
89
|
-
export class ${meta.data.
|
|
92
|
+
export class ${meta.data.repository.className} implements Repository<${model.typeName}, ${idField.unbrandedTypeName}> {
|
|
90
93
|
protected data: Map<${model.brandedIdType}, ${model.typeName}> = new Map()
|
|
91
|
-
protected logger = new Logger(${meta.data.
|
|
94
|
+
protected logger = new Logger(${meta.data.repository.className}.name)
|
|
92
95
|
|
|
93
96
|
${relationsBlocks.mapDeclarations.join('\n')}
|
|
94
97
|
|
|
@@ -97,9 +100,9 @@ export class ${meta.data.repositoryClassName} implements Repository<${model.type
|
|
|
97
100
|
${idBlocks.generateNextIdFunctionName}
|
|
98
101
|
|
|
99
102
|
protected uniqueIds = {
|
|
100
|
-
${uniqueStringFieldsBlocks.mapDeclarations.join(',\n')}
|
|
103
|
+
${uniqueStringFieldsBlocks.mapDeclarations.join(',\n')}
|
|
101
104
|
}
|
|
102
|
-
|
|
105
|
+
|
|
103
106
|
${indexBlocks.nestedMapDeclarations.join('\n')}
|
|
104
107
|
|
|
105
108
|
${mainBlocks.userRepositorySpecificBlocks.rootUserNameConst}
|
|
@@ -133,6 +136,8 @@ export class ${meta.data.repositoryClassName} implements Repository<${model.type
|
|
|
133
136
|
|
|
134
137
|
${indexBlocks.getterFunctions.join('\n')}
|
|
135
138
|
|
|
139
|
+
${uniqueStringFieldsBlocks.getByFunctions.join('\n')}
|
|
140
|
+
|
|
136
141
|
public async filter(predicate: (item: ${model.typeName}) => boolean): Promise<${model.typeName}[]> {
|
|
137
142
|
return (await this.getAllAsArray()).filter(predicate)
|
|
138
143
|
}
|
|
@@ -204,7 +209,7 @@ exports.generateRepository = generateRepository;
|
|
|
204
209
|
*/
|
|
205
210
|
function generateMockRepository({ model: modelSource, meta: metaSource, }) {
|
|
206
211
|
// We re-use the repository block, but we change the meta data to use the mock repository name and the model to be in memory only
|
|
207
|
-
const meta = Object.assign(Object.assign({}, metaSource), { data: Object.assign(Object.assign({}, metaSource.data), {
|
|
212
|
+
const meta = Object.assign(Object.assign({}, metaSource), { data: Object.assign(Object.assign({}, metaSource.data), { repository: Object.assign(Object.assign({}, metaSource.data.repository), { className: metaSource.data.mockRepository.className, filePath: metaSource.data.mockRepository.filePath }) }) });
|
|
208
213
|
const model = Object.assign(Object.assign({}, modelSource), { attributes: Object.assign(Object.assign({}, modelSource.attributes), { inMemoryOnly: true }) });
|
|
209
214
|
return generateRepository({ model, meta });
|
|
210
215
|
}
|
|
@@ -256,6 +261,8 @@ function _generateMainBuildingBlocks_InMemoryOnly({ model, meta, imports, blocks
|
|
|
256
261
|
|
|
257
262
|
${blocks.uniqueStringFieldsBlocks.verifyCode.join('\n')}
|
|
258
263
|
|
|
264
|
+
${blocks.validationBlocks.verifyCode.join('\n')}
|
|
265
|
+
|
|
259
266
|
return {
|
|
260
267
|
${model.idField.name},
|
|
261
268
|
${model.fields
|
|
@@ -527,6 +534,8 @@ function generateMainBuildingBlocks_InDatabase({ model, meta, imports, blocks, }
|
|
|
527
534
|
${blocks.maxLengthBlocks.verifyCode.join('\n')}
|
|
528
535
|
|
|
529
536
|
${blocks.uniqueStringFieldsBlocks.verifyCode.join('\n')}
|
|
537
|
+
|
|
538
|
+
${blocks.validationBlocks.verifyCode.join('\n')}
|
|
530
539
|
|
|
531
540
|
return {
|
|
532
541
|
${idField.name},
|
|
@@ -780,7 +789,7 @@ function generateUserRepositorySpecificBlocks_InDatabase({ model, meta, imports,
|
|
|
780
789
|
initCall: `await this.initializeRootUser()`,
|
|
781
790
|
rootUserInitializeBlock: `
|
|
782
791
|
private async initializeRootUser(): Promise<void> {
|
|
783
|
-
const existingRootUser = await this.get(${meta.data.
|
|
792
|
+
const existingRootUser = await this.get(${meta.data.repository.className}.ROOT_USER_ID)
|
|
784
793
|
if (existingRootUser) {
|
|
785
794
|
this._rootUser = existingRootUser
|
|
786
795
|
return
|
|
@@ -788,7 +797,7 @@ function generateUserRepositorySpecificBlocks_InDatabase({ model, meta, imports,
|
|
|
788
797
|
|
|
789
798
|
const rawUser = await this.db.user.create({
|
|
790
799
|
data: {
|
|
791
|
-
id: ${meta.data.
|
|
800
|
+
id: ${meta.data.repository.className}.ROOT_USER_ID,
|
|
792
801
|
name: 'System',
|
|
793
802
|
email: 'system@postxl.com',
|
|
794
803
|
role: UserRole.Admin,
|
|
@@ -828,14 +837,14 @@ function generateUserRepositorySpecificBlocks_InMemoryOnly({ model, meta, import
|
|
|
828
837
|
initCall: `await this.initializeRootUser()`,
|
|
829
838
|
rootUserInitializeBlock: `
|
|
830
839
|
private async initializeRootUser(): Promise<void> {
|
|
831
|
-
const existingRootUser = await this.get(${meta.data.
|
|
840
|
+
const existingRootUser = await this.get(${meta.data.repository.className}.ROOT_USER_ID)
|
|
832
841
|
if (existingRootUser) {
|
|
833
842
|
this._rootUser = existingRootUser
|
|
834
843
|
return
|
|
835
844
|
}
|
|
836
845
|
|
|
837
846
|
const rawUser = {
|
|
838
|
-
id: ${meta.data.
|
|
847
|
+
id: ${meta.data.repository.className}.ROOT_USER_ID,
|
|
839
848
|
name: 'System',
|
|
840
849
|
email: 'system@postxl.com',
|
|
841
850
|
role: UserRole.Admin,
|
|
@@ -877,42 +886,42 @@ function getRepositoryMethodsTypeSignatures({ model, meta }) {
|
|
|
877
886
|
return {
|
|
878
887
|
create: {
|
|
879
888
|
jsDoc: [`Creates a new ${meta.userFriendlyName} and returns it.`],
|
|
880
|
-
parameters: [`{item: ${meta.types.dto.create}, execution: ${schemaMeta.actions.
|
|
889
|
+
parameters: [`{item: ${meta.types.dto.create}, execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
881
890
|
returnType: `Promise<${model.typeName}>`,
|
|
882
891
|
},
|
|
883
892
|
createMany: {
|
|
884
893
|
jsDoc: [`Creates multiple new ${meta.userFriendlyNamePlural} and returns them.`],
|
|
885
|
-
parameters: [`{items: ${meta.types.dto.create}[], execution: ${schemaMeta.actions.
|
|
894
|
+
parameters: [`{items: ${meta.types.dto.create}[], execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
886
895
|
returnType: `Promise<${model.typeName}[]>`,
|
|
887
896
|
},
|
|
888
897
|
update: {
|
|
889
898
|
jsDoc: [`Updates a ${meta.userFriendlyName} and returns it.`],
|
|
890
|
-
parameters: [`{item: ${meta.types.dto.update}, execution: ${schemaMeta.actions.
|
|
899
|
+
parameters: [`{item: ${meta.types.dto.update}, execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
891
900
|
returnType: `Promise<${model.typeName}>`,
|
|
892
901
|
},
|
|
893
902
|
updateMany: {
|
|
894
903
|
jsDoc: [`Updates multiple ${meta.userFriendlyNamePlural} and returns them.`],
|
|
895
|
-
parameters: [`{items: ${meta.types.dto.update}[], execution: ${schemaMeta.actions.
|
|
904
|
+
parameters: [`{items: ${meta.types.dto.update}[], execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
896
905
|
returnType: `Promise<${model.typeName}[]>`,
|
|
897
906
|
},
|
|
898
907
|
upsert: {
|
|
899
908
|
jsDoc: [`Creates or updates a ${meta.userFriendlyName} and returns it.`],
|
|
900
|
-
parameters: [`{item: ${meta.types.dto.upsert}, execution: ${schemaMeta.actions.
|
|
909
|
+
parameters: [`{item: ${meta.types.dto.upsert}, execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
901
910
|
returnType: `Promise<${model.typeName}>`,
|
|
902
911
|
},
|
|
903
912
|
upsertMany: {
|
|
904
913
|
jsDoc: [`Creates or updates multiple ${meta.userFriendlyNamePlural} and returns them.`],
|
|
905
|
-
parameters: [`{items: ${meta.types.dto.upsert}[], execution: ${schemaMeta.actions.
|
|
914
|
+
parameters: [`{items: ${meta.types.dto.upsert}[], execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
906
915
|
returnType: `Promise<${model.typeName}[]>`,
|
|
907
916
|
},
|
|
908
917
|
delete: {
|
|
909
918
|
jsDoc: [`Deletes a ${meta.userFriendlyName} and returns its id.`],
|
|
910
|
-
parameters: [`{id: ${model.brandedIdType}, execution: ${schemaMeta.actions.
|
|
919
|
+
parameters: [`{id: ${model.brandedIdType}, execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
911
920
|
returnType: `Promise<${model.brandedIdType}>`,
|
|
912
921
|
},
|
|
913
922
|
deleteMany: {
|
|
914
923
|
jsDoc: [`Deletes multiple ${meta.userFriendlyNamePlural} and returns their ids.`],
|
|
915
|
-
parameters: [`{ids: ${model.brandedIdType}[], execution: ${schemaMeta.actions.
|
|
924
|
+
parameters: [`{ids: ${model.brandedIdType}[], execution: ${schemaMeta.actions.actionExecution.interface}}`],
|
|
916
925
|
returnType: `Promise<${model.brandedIdType}[]>`,
|
|
917
926
|
},
|
|
918
927
|
};
|
|
@@ -1038,6 +1047,7 @@ function generateUniqueFieldsBlocks({ model }) {
|
|
|
1038
1047
|
const fields = model.fields.filter(fields_1.isUniqueStringField);
|
|
1039
1048
|
const result = {
|
|
1040
1049
|
mapDeclarations: [],
|
|
1050
|
+
getByFunctions: [],
|
|
1041
1051
|
clearCode: [],
|
|
1042
1052
|
verifyFunctionComment: '',
|
|
1043
1053
|
verifyCode: [],
|
|
@@ -1048,6 +1058,10 @@ function generateUniqueFieldsBlocks({ model }) {
|
|
|
1048
1058
|
};
|
|
1049
1059
|
for (const f of fields) {
|
|
1050
1060
|
result.mapDeclarations.push(`'${f.name}': new Map<string, ${model.typeName}>()`);
|
|
1061
|
+
result.getByFunctions.push(`
|
|
1062
|
+
public async getBy${(0, string_1.toPascalCase)(f.name)}(${f.name}: string): Promise<${model.typeName} | undefined> {
|
|
1063
|
+
return Promise.resolve(this.uniqueIds.${f.name}.get(${(0, string_1.toCamelCase)(f.name)}))
|
|
1064
|
+
}`);
|
|
1051
1065
|
result.clearCode.push(`this.uniqueIds.${f.name}.clear()`);
|
|
1052
1066
|
result.verifyCode.push(`this.${getEnsureUniqueFnName(f)}(item)`);
|
|
1053
1067
|
result.updateCode.push(`
|
|
@@ -1134,6 +1148,21 @@ function generateMaxLengthBlocks({ model }) {
|
|
|
1134
1148
|
function getEnsureMaxLengthFnName(field) {
|
|
1135
1149
|
return `ensureMaxLength${(0, string_1.toPascalCase)(field.name)}`;
|
|
1136
1150
|
}
|
|
1151
|
+
function generateValidationBlocks({ model }) {
|
|
1152
|
+
const fields = model.fields.filter((f) => f.kind === 'scalar' && f.validation && f.validation.type === 'int');
|
|
1153
|
+
const result = {
|
|
1154
|
+
verifyCode: [],
|
|
1155
|
+
};
|
|
1156
|
+
for (const f of fields) {
|
|
1157
|
+
const itemExists = f.isRequired ? '' : `item.${f.name} !== null && `;
|
|
1158
|
+
result.verifyCode.push(`
|
|
1159
|
+
// ensure that ${f.name} is an integer
|
|
1160
|
+
if (${itemExists}item.${f.name} !== Math.floor(item.${f.name})) {
|
|
1161
|
+
throw new Error(\`Invalid value for field ${f.name}: \${item.${f.name}}. Value must be an integer.\`)
|
|
1162
|
+
}`);
|
|
1163
|
+
}
|
|
1164
|
+
return result;
|
|
1165
|
+
}
|
|
1137
1166
|
function generateIndexBlocks({ model, imports, }) {
|
|
1138
1167
|
const indexes = model.attributes.index ? [getIndexDefinition({ fieldNames: model.attributes.index, model })] : [];
|
|
1139
1168
|
if (indexes.length > 0) {
|
package/dist/lib/imports.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import * as Types from './schema/types';
|
|
|
6
6
|
* Example:
|
|
7
7
|
* ```
|
|
8
8
|
* {
|
|
9
|
-
* [meta.data.importPath]: meta.data.
|
|
9
|
+
* [meta.data.importPath]: meta.data.repository.className,
|
|
10
10
|
* [meta.types.importPath]: [model.brandedIdType, meta.types.typeName],
|
|
11
11
|
* }
|
|
12
12
|
* ```
|