@things-factory/operato-tools 7.0.0-y.0 → 7.0.1-alpha.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 (63) hide show
  1. package/client/index.js +0 -1
  2. package/client/pages/generator/button-config-tab-mixin.js +336 -2
  3. package/client/pages/generator/column-config-tab-mixin.js +647 -2
  4. package/client/pages/generator/etc-config-tab-mixin.js +116 -2
  5. package/client/pages/generator/form-config-tab-mixin.js +164 -2
  6. package/client/pages/generator/graphql-config-tab-mixin.js +281 -15
  7. package/client/pages/generator/grid-config-tab-mixin.js +190 -28
  8. package/client/pages/generator/grid-emphasized-config-tab-mixin.js +295 -6
  9. package/client/pages/generator/menu-config-tab-mixin.js +94 -8
  10. package/client/pages/generator/meta-generator-page.js +512 -12
  11. package/client/pages/generator/search-config-tab-mixin.js +188 -2
  12. package/client/pages/generator/tab-config-tab-mixin.js +226 -2
  13. package/client/pages/main.js +30 -7
  14. package/client/route.js +5 -10
  15. package/config/config.development.js +1 -1
  16. package/config/config.production.js +1 -0
  17. package/{server/errors → dist-server}/index.js +1 -1
  18. package/dist-server/index.js.map +1 -0
  19. package/{server → dist-server}/service/index.js +0 -2
  20. package/dist-server/service/index.js.map +1 -0
  21. package/dist-server/service/tool-entity/create-menu.js +321 -0
  22. package/dist-server/service/tool-entity/create-menu.js.map +1 -0
  23. package/dist-server/service/tool-entity/create-service.js +1053 -0
  24. package/dist-server/service/tool-entity/create-service.js.map +1 -0
  25. package/dist-server/service/tool-entity/index.js.map +1 -0
  26. package/dist-server/tsconfig.tsbuildinfo +1 -0
  27. package/package.json +21 -14
  28. package/server/index.ts +1 -0
  29. package/server/service/index.ts +15 -0
  30. package/server/service/tool-entity/create-menu.ts +338 -0
  31. package/server/service/tool-entity/create-service.ts +1128 -0
  32. package/server/service/tool-entity/index.ts +4 -0
  33. package/server/tsconfig.json +9 -0
  34. package/things-factory.config.js +1 -3
  35. package/tsconfig.json +9 -0
  36. package/views/auth-page.html +1 -7
  37. package/views/public/home.html +1 -6
  38. package/client/actions/main.js +0 -1
  39. package/client/bootstrap.js +0 -8
  40. package/client/reducers/main.js +0 -1
  41. package/client/themes/grist-theme.css +0 -200
  42. package/client/themes/layout-theme.css +0 -92
  43. package/client/themes/report-theme.css +0 -47
  44. package/schema.graphql +0 -3646
  45. package/server/constants/error-code.js +0 -1
  46. package/server/controllers/index.js +0 -1
  47. package/server/errors/license-error.js +0 -1
  48. package/server/index.js +0 -8
  49. package/server/middlewares/index.js +0 -19
  50. package/server/migrations/index.js +0 -12
  51. package/server/routes.js +0 -1
  52. package/server/service/boxtype/boxtype-mutation.js +0 -1
  53. package/server/service/boxtype/boxtype-query.js +0 -1
  54. package/server/service/boxtype/boxtype-type.js +0 -1
  55. package/server/service/boxtype/boxtype.js +0 -1
  56. package/server/service/boxtype/index.js +0 -9
  57. package/server/service/tool-entity/create-menu.js +0 -1
  58. package/server/service/tool-entity/create-service.js +0 -1
  59. package/server/service/tool-secret/index.js +0 -6
  60. package/server/service/tool-secret/tool-permission.js +0 -1
  61. package/server/service/tool-secret/tool-resolver.js +0 -1
  62. package/translations/ja.json +0 -85
  63. /package/{server → dist-server}/service/tool-entity/index.js +0 -0
@@ -0,0 +1,1053 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OperatoToolCreateService = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const type_graphql_1 = require("type-graphql");
6
+ const shell_1 = require("@things-factory/shell");
7
+ const resource_base_1 = require("@things-factory/resource-base");
8
+ const { camelCase, startCase, snakeCase, kebabCase } = require('lodash');
9
+ const { plural } = require('pluralize');
10
+ const fs = require('fs');
11
+ let OperatoToolCreateService = class OperatoToolCreateService {
12
+ async toolCreateService(id, context) {
13
+ const { domain } = context.state;
14
+ // Entity 조회
15
+ const entity = await (0, shell_1.getRepository)(resource_base_1.Entity).findOne({
16
+ where: {
17
+ id
18
+ }
19
+ });
20
+ // Entity 컬럼 조회
21
+ const entityColumns = await (0, shell_1.getRepository)(resource_base_1.EntityColumn).find({
22
+ where: {
23
+ domain: { id: domain.id },
24
+ entity: { id: entity.id }
25
+ }
26
+ });
27
+ let { name = '', bundle = '' } = entity || {};
28
+ // 프로젝트 Root Path 구하기
29
+ let appRootPath = this.getProjectRootPath();
30
+ let serviceName = kebabCase(name);
31
+ // 서비스 경로 생성
32
+ await this.createServicePath(appRootPath, bundle, serviceName);
33
+ // 서비스 파일 생성
34
+ await this.createServiceFiles(appRootPath, bundle, name, serviceName, entity, entityColumns);
35
+ return true;
36
+ }
37
+ /**
38
+ * 서비스 연관 파일 생성
39
+ * @param appRootPath
40
+ * @param moduleName
41
+ * @param name
42
+ * @param serviceName
43
+ * @param entity
44
+ * @param entityColumns
45
+ */
46
+ async createServiceFiles(appRootPath, moduleName, name, serviceName, entity, entityColumns) {
47
+ // 이름 케이스 워드 만들기
48
+ let nameMap = {
49
+ name: serviceName,
50
+ tableName: entity.tableName,
51
+ pascalCaseName: startCase(camelCase(name)).replace(/ /g, ''),
52
+ camelCaseName: camelCase(name),
53
+ snakeCaseName: snakeCase(name),
54
+ pluralPascalCaseName: startCase(camelCase(plural(name))).replace(/ /g, ''),
55
+ pluralCamelCaseName: camelCase(plural(name))
56
+ };
57
+ let servicePath = `${appRootPath}/packages/${moduleName}/server/service/`;
58
+ if (['JSON', 'COPY'].includes(entity.dataProp)) {
59
+ await this.createHistoryServiceFiles(servicePath, serviceName, entity, entityColumns, nameMap);
60
+ }
61
+ else {
62
+ await this.createNoHistoryServiceFiels(servicePath, serviceName, entity, entityColumns, nameMap);
63
+ }
64
+ }
65
+ async createHistoryServiceFiles(servicePath, serviceName, entity, entityColumns, nameMap) {
66
+ // 서비스 연관 파일 생성
67
+ await this.writeFile(servicePath + `${serviceName}/index.ts`, serviceHistoryIndex, nameMap);
68
+ // Entity
69
+ let entityText = this.createEntityText(entity, entityColumns);
70
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}.ts`, entityText, nameMap);
71
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-query.ts`, serviceQuery, nameMap);
72
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-mutation.ts`, serviceMutation, nameMap);
73
+ // TYPE
74
+ let typeText = this.createTypeText(entityColumns);
75
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-type.ts`, typeText, nameMap);
76
+ // 이력관리 entity 생성
77
+ let historyText = this.createHistoryEntityText(entity, entityColumns);
78
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-history.ts`, historyText, nameMap);
79
+ let entitySubscriberEntityToJson = '';
80
+ if (entity.dataProp == 'JSON') {
81
+ entitySubscriberEntityToJson =
82
+ `
83
+ public createHistoryEntity(manager, entity) {
84
+ let history = manager.create(this.historyEntity, entity);
85
+ history.historyJson = JSON.stringify(entity);
86
+ return history;
87
+ }
88
+ `;
89
+ await this.writeFile(servicePath + `${serviceName}/event-subscriber.ts`, serviceEntitySubscriber, nameMap);
90
+ }
91
+ else {
92
+ entitySubscriberEntityToJson = '';
93
+ }
94
+ let subscriberTxt = serviceEntitySubscriber.replace(/{{entityToJson}}/g, entitySubscriberEntityToJson);
95
+ await this.writeFile(servicePath + `${serviceName}/event-subscriber.ts`, subscriberTxt, nameMap);
96
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-history-query.ts`, serviceHistoryQuery, nameMap);
97
+ // TYPE
98
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-history-type.ts`, sereviceHistoryType, nameMap);
99
+ // 전체 서비스 index.ts 파일
100
+ let allServiceIdxPath = servicePath + 'index.ts';
101
+ if (await this.existsPath(allServiceIdxPath) == false) {
102
+ await this.writeFile(allServiceIdxPath, allIndex, nameMap);
103
+ }
104
+ let allIdxFileTxt = await fs.readFileSync(allServiceIdxPath, 'utf8');
105
+ if (allIdxFileTxt.indexOf(`export * from './${nameMap.name}/${nameMap.name}-history'`) < 0) {
106
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* EXPORT ENTITY TYPES \*\//, `/* EXPORT ENTITY TYPES */\nexport * from './${nameMap.name}/${nameMap.name}-history'`);
107
+ }
108
+ if (allIdxFileTxt.indexOf(`export * from './${nameMap.name}/${nameMap.name}'`) < 0) {
109
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* EXPORT ENTITY TYPES \*\//, `/* EXPORT ENTITY TYPES */\nexport * from './${nameMap.name}/${nameMap.name}'`);
110
+ }
111
+ if (allIdxFileTxt.indexOf(`import { entities as ${nameMap.pascalCaseName}Entities, resolvers as ${nameMap.pascalCaseName}Resolvers, subscribers as ${nameMap.pascalCaseName}EntitySubscribers } from './${nameMap.name}'`) < 0) {
112
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* IMPORT ENTITIES AND RESOLVERS \*\//, `/* IMPORT ENTITIES AND RESOLVERS */\nimport { entities as ${nameMap.pascalCaseName}Entities, resolvers as ${nameMap.pascalCaseName}Resolvers, subscribers as ${nameMap.pascalCaseName}EntitySubscribers } from './${nameMap.name}'`);
113
+ }
114
+ if (allIdxFileTxt.indexOf(`...${nameMap.pascalCaseName}Entities,`) < 0) {
115
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* ENTITIES \*\//, `/* ENTITIES */\n\t...${nameMap.pascalCaseName}Entities,`);
116
+ }
117
+ if (allIdxFileTxt.indexOf(`...${nameMap.pascalCaseName}Resolvers,`) < 0) {
118
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* RESOLVER CLASSES \*\//, `/* RESOLVER CLASSES */\n\t\t...${nameMap.pascalCaseName}Resolvers,`);
119
+ }
120
+ if (allIdxFileTxt.indexOf(`...${nameMap.pascalCaseName}EntitySubscribers,`) < 0) {
121
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* SUBSCRIBERS \*\//, `/* SUBSCRIBERS */\n\t\t...${nameMap.pascalCaseName}EntitySubscribers,`);
122
+ }
123
+ await this.writeFile(allServiceIdxPath, allIdxFileTxt, nameMap);
124
+ }
125
+ async createNoHistoryServiceFiels(servicePath, serviceName, entity, entityColumns, nameMap) {
126
+ // 서비스 연관 파일 생성
127
+ await this.writeFile(servicePath + `${serviceName}/index.ts`, serviceIndex, nameMap);
128
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-query.ts`, serviceQuery, nameMap);
129
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-mutation.ts`, serviceMutation, nameMap);
130
+ // Entity
131
+ let entityText = this.createEntityText(entity, entityColumns);
132
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}.ts`, entityText, nameMap);
133
+ // TYPE
134
+ let typeText = this.createTypeText(entityColumns);
135
+ await this.writeFile(servicePath + `${serviceName}/${serviceName}-type.ts`, typeText, nameMap);
136
+ // 전체 서비스 index.ts 파일
137
+ let allServiceIdxPath = servicePath + 'index.ts';
138
+ if (await this.existsPath(allServiceIdxPath) == false) {
139
+ await this.writeFile(allServiceIdxPath, allIndex, nameMap);
140
+ }
141
+ let allIdxFileTxt = await fs.readFileSync(allServiceIdxPath, 'utf8');
142
+ if (allIdxFileTxt.indexOf(`export * from './${nameMap.name}/${nameMap.name}'`) < 0) {
143
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* EXPORT ENTITY TYPES \*\//, `/* EXPORT ENTITY TYPES */\nexport * from './${nameMap.name}/${nameMap.name}'`);
144
+ }
145
+ if (allIdxFileTxt.indexOf(`import { entities as ${nameMap.pascalCaseName}Entities, resolvers as ${nameMap.pascalCaseName}Resolvers } from './${nameMap.name}'`) < 0) {
146
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* IMPORT ENTITIES AND RESOLVERS \*\//, `/* IMPORT ENTITIES AND RESOLVERS */\nimport { entities as ${nameMap.pascalCaseName}Entities, resolvers as ${nameMap.pascalCaseName}Resolvers } from './${nameMap.name}'`);
147
+ }
148
+ if (allIdxFileTxt.indexOf(`...${nameMap.pascalCaseName}Entities,`) < 0) {
149
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* ENTITIES \*\//, `/* ENTITIES */\n\t...${nameMap.pascalCaseName}Entities,`);
150
+ }
151
+ if (allIdxFileTxt.indexOf(`...${nameMap.pascalCaseName}Resolvers,`) < 0) {
152
+ allIdxFileTxt = allIdxFileTxt.replace(/\/\* RESOLVER CLASSES \*\//, `/* RESOLVER CLASSES */\n\t\t...${nameMap.pascalCaseName}Resolvers,`);
153
+ }
154
+ await this.writeFile(allServiceIdxPath, allIdxFileTxt, nameMap);
155
+ }
156
+ /**
157
+ * 엔티티 타입 텍스트
158
+ * @param entityColumns
159
+ * @returns
160
+ */
161
+ createTypeText(entityColumns) {
162
+ let typeText = sereviceType;
163
+ let newTypeColumns = entityColumns.map(column => {
164
+ if (column.name == 'id')
165
+ return '';
166
+ if (column.name == 'domain_id')
167
+ return '';
168
+ if (column.name == 'created_at')
169
+ return '';
170
+ if (column.name == 'updated_at')
171
+ return '';
172
+ if (column.name == 'creator_id')
173
+ return '';
174
+ if (column.name == 'updater_id')
175
+ return '';
176
+ let fieldType = this.getFieldType(column);
177
+ let colTxtType = this.getColTxtType(column);
178
+ let colName = camelCase(column.name);
179
+ let fieldAnn = `@Field(${fieldType.length == 0 ? '' : 'type =>' + fieldType + ','} { nullable: ${column.nullable} })`;
180
+ let columnTxt = `${colName}${column.nullable ? '?' : ''}: ${colTxtType}`;
181
+ return " " + fieldAnn + "\n " + columnTxt + "\n";
182
+ });
183
+ typeText = typeText.replace(/{{newTypeColumns}}/g, newTypeColumns.join("\n"));
184
+ let patchTypeColumns = entityColumns.map(column => {
185
+ if (column.name == 'id')
186
+ return '';
187
+ if (column.name == 'domain_id')
188
+ return '';
189
+ if (column.name == 'created_at')
190
+ return '';
191
+ if (column.name == 'updated_at')
192
+ return '';
193
+ if (column.name == 'creator_id')
194
+ return '';
195
+ if (column.name == 'updater_id')
196
+ return '';
197
+ let fieldType = this.getFieldType(column);
198
+ let colTxtType = this.getColTxtType(column);
199
+ // patch ?
200
+ column.nullable = true;
201
+ let colName = camelCase(column.name);
202
+ let fieldAnn = `@Field(${fieldType.length == 0 ? '' : 'type =>' + fieldType + ','} { nullable: ${column.nullable} })`;
203
+ let columnTxt = `${colName}${column.nullable ? '?' : ''}: ${colTxtType}`;
204
+ return " " + fieldAnn + "\n " + columnTxt + "\n";
205
+ });
206
+ typeText = typeText.replace(/{{patchTypeColumns}}/g, patchTypeColumns.join("\n"));
207
+ return typeText;
208
+ }
209
+ /**
210
+ * 엔티티 생성 텍스트
211
+ * @param entity
212
+ * @param entityColumns
213
+ * @returns
214
+ */
215
+ createEntityText(entity, entityColumns) {
216
+ let entityText = serviceEntity;
217
+ // 컬럼 정렬
218
+ let sortedCols = entityColumns.sort(function (a, b) {
219
+ return a.rank - b.rank;
220
+ });
221
+ // 컬럼 정보 txt 변환
222
+ let entityColsText = sortedCols.map(x => {
223
+ return this.columnToEntityColumn(x);
224
+ });
225
+ if (['COPY', 'JSON'].includes(entity.dataProp)) {
226
+ entityColsText.push(`
227
+ @VersionColumn({ default: 1 })
228
+ @Field({ nullable: true })
229
+ dataRevisionNo?: number = 1`);
230
+ }
231
+ entityText = entityText.replace(/{{entityColumns}}/g, entityColsText.join("\n"));
232
+ // index 정보
233
+ let indexAnn = ``;
234
+ let sortedIdxCols = entityColumns.filter(x => x.uniqRank && x.uniqRank > 0).sort(function (a, b) {
235
+ return a.uniqRank - b.uniqRank;
236
+ });
237
+ if (sortedIdxCols.length > 0) {
238
+ indexAnn = `@Index('ix_{{snakeCase name}}_0', ({{camelCase name}}: {{pascalCase name}}) => [{{indexColumns}}], { unique: true })`;
239
+ let idxColumns = sortedIdxCols.map(x => {
240
+ let colName = x.name;
241
+ if (x.name == 'domain_id')
242
+ colName = 'domain';
243
+ if (x.name == 'creator_id')
244
+ colName = 'creator';
245
+ if (x.name == 'updater_id')
246
+ colName = 'updater';
247
+ return '{{camelCase name}}.' + camelCase(colName);
248
+ });
249
+ indexAnn = indexAnn.replace(/{{indexColumns}}/g, idxColumns.join(","));
250
+ }
251
+ entityText = entityText.replace(/{{indexAnn}}/g, indexAnn);
252
+ return entityText;
253
+ }
254
+ /**
255
+ * 이력관리 엔티티 생성 텍스트
256
+ * @param entity
257
+ * @param entityColumns
258
+ * @returns
259
+ */
260
+ createHistoryEntityText(entity, entityColumns) {
261
+ let entityText = entity.dataProp == 'JSON' ? serviceEntityHistJson : serviceEntityHistCopy;
262
+ // 컬럼 정렬
263
+ let sortedCols = entityColumns.sort(function (a, b) {
264
+ return a.rank - b.rank;
265
+ });
266
+ // 컬럼 정보 txt 변환
267
+ let entityColsText = sortedCols.map(x => {
268
+ return this.columnToEntityColumn(x);
269
+ });
270
+ entityText = entityText.replace(/{{entityColumns}}/g, entityColsText.join("\n"));
271
+ return entityText;
272
+ }
273
+ /**
274
+ * EntityColumn to entity column Text
275
+ * @param column
276
+ * @returns
277
+ */
278
+ columnToEntityColumn(column) {
279
+ if (column.name == 'id')
280
+ return '';
281
+ if (column.name == 'domain_id')
282
+ return '';
283
+ if (column.name == 'created_at')
284
+ return '';
285
+ if (column.name == 'updated_at')
286
+ return '';
287
+ if (column.name == 'creator_id')
288
+ return '';
289
+ if (column.name == 'updater_id')
290
+ return '';
291
+ let colType = column.colType;
292
+ if (column.colType == 'double')
293
+ colType = 'double precision';
294
+ if (column.colType == 'long')
295
+ colType = 'bigint';
296
+ if (column.colType == 'string')
297
+ colType = 'character varying';
298
+ if (column.colType == 'datetime')
299
+ colType = 'timestamp without time zone';
300
+ let colSize = '';
301
+ if (column.colType == 'string')
302
+ colSize = column.colSize;
303
+ let fieldType = this.getFieldType(column);
304
+ let colTxtType = this.getColTxtType(column);
305
+ let colName = camelCase(column.name);
306
+ let columnAnn = `@Column({name:'${column.name}', type: '${colType}', nullable: ${column.nullable} ${colSize.length == 0 ? '' : ',length:' + colSize} })`;
307
+ let fieldAnn = `@Field(${fieldType.length == 0 ? '' : 'type =>' + fieldType + ','} { nullable: ${column.nullable} })`;
308
+ let columnTxt = `${colName}${column.nullable ? '?' : ''}: ${colTxtType}`;
309
+ return " " + columnAnn + "\n " + fieldAnn + "\n " + columnTxt + "\n";
310
+ }
311
+ getFieldType(column) {
312
+ let fieldType = '';
313
+ if (column.colType == 'double')
314
+ fieldType = 'Float';
315
+ if (column.colType == 'float')
316
+ fieldType = 'Float';
317
+ if (column.colType == 'long')
318
+ fieldType = 'Int';
319
+ if (column.colType == 'integer')
320
+ fieldType = 'Int';
321
+ return fieldType;
322
+ }
323
+ getColTxtType(column) {
324
+ let colTxtType = column.colType;
325
+ if (column.colType == 'decimal')
326
+ colTxtType = 'number';
327
+ if (column.colType == 'double')
328
+ colTxtType = 'number';
329
+ if (column.colType == 'float')
330
+ colTxtType = 'number';
331
+ if (column.colType == 'integer')
332
+ colTxtType = 'number';
333
+ if (column.colType == 'long')
334
+ colTxtType = 'number';
335
+ if (column.colType == 'datetime')
336
+ colTxtType = 'Date';
337
+ if (column.colType == 'date')
338
+ colTxtType = 'Date';
339
+ if (column.colType == 'text')
340
+ colTxtType = 'string';
341
+ return colTxtType;
342
+ }
343
+ /**
344
+ * 파일 생성
345
+ * @param filePath
346
+ * @param fileText
347
+ * @param nameMap
348
+ */
349
+ async writeFile(filePath, fileText, nameMap) {
350
+ await fs.writeFileSync(filePath, this.replaceNamesMap(fileText, nameMap), 'utf8');
351
+ }
352
+ /**
353
+ * 문자열 치환
354
+ * @param text
355
+ * @param nameMap
356
+ * @returns
357
+ */
358
+ replaceNamesMap(text, nameMap) {
359
+ return text.replace(/{{pascalCase name}}/g, nameMap.pascalCaseName)
360
+ .replace(/{{camelCase name}}/g, nameMap.camelCaseName)
361
+ .replace(/{{snakeCase name}}/g, nameMap.snakeCaseName)
362
+ .replace(/{{pluralPascalCase name}}/g, nameMap.pluralPascalCaseName)
363
+ .replace(/{{pluralCamelCase name}}/g, nameMap.pluralCamelCaseName)
364
+ .replace(/{{tableName}}/g, nameMap.tableName)
365
+ .replace(/{{name}}/g, nameMap.name);
366
+ }
367
+ /**
368
+ * 서비스 경로 만들기
369
+ * @param appRootPath
370
+ * @param moduleName
371
+ * @param serviceName
372
+ */
373
+ async createServicePath(appRootPath, moduleName, serviceName) {
374
+ let path = appRootPath + '/' + 'packages';
375
+ await this.createDir(path);
376
+ path = path + '/' + moduleName;
377
+ await this.createDir(path);
378
+ path = path + '/server';
379
+ await this.createDir(path);
380
+ path = path + '/service';
381
+ await this.createDir(path);
382
+ path = path + '/' + serviceName;
383
+ await this.createDir(path);
384
+ }
385
+ /**
386
+ * 프로젝트 Root Path 구하기
387
+ * @returns String
388
+ */
389
+ getProjectRootPath() {
390
+ let appPath = process.env.PWD;
391
+ let splitPath = appPath.split('/');
392
+ let pathArr = [];
393
+ for (let i = 0; i < splitPath.length; i++) {
394
+ if (splitPath[i] == 'packages') {
395
+ break;
396
+ }
397
+ pathArr.push(splitPath[i]);
398
+ }
399
+ return pathArr.join('/');
400
+ }
401
+ /**
402
+ * 디렉토리 생성
403
+ * @param path
404
+ */
405
+ async createDir(path) {
406
+ if (await this.existsPath(path) == false)
407
+ fs.mkdirSync(path);
408
+ }
409
+ /**
410
+ * Path 존재 여부
411
+ * @param path
412
+ * @returns
413
+ */
414
+ async existsPath(path) {
415
+ return await fs.existsSync(path);
416
+ }
417
+ };
418
+ tslib_1.__decorate([
419
+ (0, type_graphql_1.Query)(returns => Boolean, { description: 'Operato Tool Create Service' }),
420
+ tslib_1.__param(0, (0, type_graphql_1.Arg)('id')),
421
+ tslib_1.__param(1, (0, type_graphql_1.Ctx)()),
422
+ tslib_1.__metadata("design:type", Function),
423
+ tslib_1.__metadata("design:paramtypes", [String, Object]),
424
+ tslib_1.__metadata("design:returntype", Promise)
425
+ ], OperatoToolCreateService.prototype, "toolCreateService", null);
426
+ OperatoToolCreateService = tslib_1.__decorate([
427
+ (0, type_graphql_1.Resolver)()
428
+ ], OperatoToolCreateService);
429
+ exports.OperatoToolCreateService = OperatoToolCreateService;
430
+ /* all service index text index.ts */
431
+ const allIndex = `
432
+ /* EXPORT ENTITY TYPES */
433
+
434
+ /* IMPORT ENTITIES AND RESOLVERS */
435
+
436
+ export const entities = [
437
+ /* ENTITIES */
438
+ ]
439
+
440
+
441
+ export const schema = {
442
+ resolverClasses: [
443
+ /* RESOLVER CLASSES */
444
+ ]
445
+ }
446
+
447
+ export const subscribers = [
448
+ /* SUBSCRIBERS */
449
+ ]
450
+ `;
451
+ /* service index text index.ts */
452
+ const serviceIndex = `
453
+ import { {{pascalCase name}} } from './{{name}}'
454
+ import { {{pascalCase name}}Query } from './{{name}}-query'
455
+ import { {{pascalCase name}}Mutation } from './{{name}}-mutation'
456
+
457
+ export const entities = [{{pascalCase name}}]
458
+ export const resolvers = [{{pascalCase name}}Query, {{pascalCase name}}Mutation]
459
+ `;
460
+ /* service index text index.ts */
461
+ const serviceHistoryIndex = `
462
+ import { {{pascalCase name}} } from './{{name}}'
463
+ import { {{pascalCase name}}Query } from './{{name}}-query'
464
+ import { {{pascalCase name}}HistoryQuery } from './{{name}}-history-query'
465
+ import { {{pascalCase name}}Mutation } from './{{name}}-mutation'
466
+ import { {{pascalCase name}}History } from './{{name}}-history'
467
+ import { {{pascalCase name}}HistoryEntitySubscriber } from './event-subscriber'
468
+
469
+ export const entities = [{{pascalCase name}}, {{pascalCase name}}History]
470
+ export const resolvers = [{{pascalCase name}}Query, {{pascalCase name}}HistoryQuery, {{pascalCase name}}Mutation]
471
+ export const subscribers = [{{pascalCase name}}HistoryEntitySubscriber]
472
+
473
+ `;
474
+ /* service Query text {{name}}-query.ts */
475
+ const serviceQuery = `
476
+ import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
477
+ import { Domain, ListParam, convertListParams, getRepository, getQueryBuilderFromListParams } from '@things-factory/shell'
478
+ import { User } from '@things-factory/auth-base'
479
+ import { {{pascalCase name}} } from './{{name}}'
480
+ import { {{pascalCase name}}List } from './{{name}}-type'
481
+
482
+ @Resolver({{pascalCase name}})
483
+ export class {{pascalCase name}}Query {
484
+ @Query(returns => {{pascalCase name}}, { description: 'To fetch a {{pascalCase name}}' })
485
+ async {{camelCase name}}(@Arg('id') id: string, @Ctx() context: any): Promise<{{pascalCase name}}> {
486
+ const { domain } = context.state
487
+ return await getRepository({{pascalCase name}}).findOne({
488
+ where: { domain: { id: domain.id }, id }
489
+ })
490
+ }
491
+
492
+ @Query(returns => {{pascalCase name}}List, { description: 'To fetch multiple {{pluralPascalCase name}}' })
493
+ async {{pluralCamelCase name}}(@Args() params: ListParam, @Ctx() context: any): Promise<{{pascalCase name}}List> {
494
+ const { domain } = context.state
495
+
496
+ const queryBuilder = getQueryBuilderFromListParams({
497
+ domain,
498
+ params,
499
+ repository: await getRepository({{pascalCase name}})
500
+ })
501
+
502
+ const convertedParams = convertListParams(params, domain.id)
503
+ const [items, total] = await queryBuilder.getManyAndCount()
504
+
505
+ return { items, total }
506
+ }
507
+
508
+ @FieldResolver(type => Domain)
509
+ async domain(@Root() {{camelCase name}}: {{pascalCase name}}): Promise<Domain> {
510
+ return await getRepository(Domain).findOneBy({id:{{camelCase name}}.domainId})
511
+ }
512
+
513
+ @FieldResolver(type => User)
514
+ async updater(@Root() {{camelCase name}}: {{pascalCase name}}): Promise<User> {
515
+ return await getRepository(User).findOneBy({id:{{camelCase name}}.updaterId})
516
+ }
517
+
518
+ @FieldResolver(type => User)
519
+ async creator(@Root() {{camelCase name}}: {{pascalCase name}}): Promise<User> {
520
+ return await getRepository(User).findOneBy({id:{{camelCase name}}.creatorId})
521
+ }
522
+ }
523
+ `;
524
+ /* service Query text {{name}}-query.ts */
525
+ const serviceHistoryQuery = `
526
+ import { Resolver, Query, FieldResolver, Root, Args, Arg, Ctx, Directive } from 'type-graphql'
527
+ import { Domain, ListParam, convertListParams, getRepository, getQueryBuilderFromListParams } from '@things-factory/shell'
528
+ import { User } from '@things-factory/auth-base'
529
+ import { {{pascalCase name}}History } from './{{name}}-history'
530
+ import { {{pascalCase name}}HistoryList } from './{{name}}-history-type'
531
+
532
+ @Resolver({{pascalCase name}}History)
533
+ export class {{pascalCase name}}HistoryQuery {
534
+ @Query(returns => {{pascalCase name}}History, { description: 'To fetch a {{pascalCase name}}History' })
535
+ async {{camelCase name}}History(@Arg('id') id: string, @Ctx() context: any): Promise<{{pascalCase name}}History> {
536
+ const { domain } = context.state
537
+ return await getRepository({{pascalCase name}}History).findOne({
538
+ where: { domain: { id: domain.id }, id }
539
+ })
540
+ }
541
+
542
+ @Query(returns => {{pascalCase name}}HistoryList, { description: 'To fetch multiple {{pluralPascalCase name}}History' })
543
+ async {{camelCase name}}Histories(@Args() params: ListParam, @Ctx() context: any): Promise<{{pascalCase name}}HistoryList> {
544
+ const { domain } = context.state
545
+
546
+ const queryBuilder = getQueryBuilderFromListParams({
547
+ domain,
548
+ params,
549
+ repository: await getRepository({{pascalCase name}}History)
550
+ })
551
+
552
+ const [items, total] = await queryBuilder.getManyAndCount()
553
+
554
+ return { items, total }
555
+ }
556
+
557
+ @FieldResolver(type => Domain)
558
+ async domain(@Root() {{camelCase name}}History: {{pascalCase name}}History): Promise<Domain> {
559
+ return await getRepository(Domain).findOneBy({id:{{camelCase name}}History.domainId})
560
+ }
561
+
562
+ @FieldResolver(type => User)
563
+ async updater(@Root() {{camelCase name}}History: {{pascalCase name}}History): Promise<User> {
564
+ return await getRepository(User).findOneBy({id:{{camelCase name}}History.updaterId})
565
+ }
566
+
567
+ @FieldResolver(type => User)
568
+ async creator(@Root() {{camelCase name}}History: {{pascalCase name}}History): Promise<User> {
569
+ return await getRepository(User).findOneBy({id:{{camelCase name}}History.creatorId})
570
+ }
571
+ }
572
+ `;
573
+ /* service mutation text {{name}}-mutation.ts */
574
+ const serviceMutation = `
575
+ import { Resolver, Mutation, Arg, Ctx, Directive } from 'type-graphql'
576
+ import { In } from 'typeorm'
577
+ import { {{pascalCase name}} } from './{{name}}'
578
+ import { New{{pascalCase name}}, {{pascalCase name}}Patch } from './{{name}}-type'
579
+ import { getRepository } from '@things-factory/shell'
580
+
581
+ @Resolver({{pascalCase name}})
582
+ export class {{pascalCase name}}Mutation {
583
+ @Directive('@transaction')
584
+ @Mutation(returns => {{pascalCase name}}, { description: 'To create new {{pascalCase name}}' })
585
+ async create{{pascalCase name}}(@Arg('{{camelCase name}}') {{camelCase name}}: New{{pascalCase name}}, @Ctx() context: any): Promise<{{pascalCase name}}> {
586
+ const { domain, user, tx } = context.state
587
+
588
+ return await tx.getRepository({{pascalCase name}}).save({
589
+ ...{{camelCase name}},
590
+ domain,
591
+ creator: user,
592
+ updater: user
593
+ })
594
+ }
595
+
596
+ @Directive('@transaction')
597
+ @Mutation(returns => {{pascalCase name}}, { description: 'To modify {{pascalCase name}} information' })
598
+ async update{{pascalCase name}}(
599
+ @Arg('id') id: string,
600
+ @Arg('patch') patch: {{pascalCase name}}Patch,
601
+ @Ctx() context: any
602
+ ): Promise<{{pascalCase name}}> {
603
+ const { domain, user, tx } = context.state
604
+
605
+ const repository = tx.getRepository({{pascalCase name}})
606
+ const {{camelCase name}} = await repository.findOne(
607
+ {
608
+ where: { domain: { id: domain.id }, id },
609
+ relations: ['domain', 'updater', 'creator']
610
+ }
611
+ )
612
+
613
+ return await repository.save({
614
+ ...{{camelCase name}},
615
+ ...patch,
616
+ updater: user
617
+ })
618
+ }
619
+
620
+ @Directive('@transaction')
621
+ @Mutation(returns => [{{pascalCase name}}], { description: "To modify multiple {{pluralPascalCase name}}' information" })
622
+ async updateMultiple{{pascalCase name}}(
623
+ @Arg('patches', type => [{{pascalCase name}}Patch]) patches: {{pascalCase name}}Patch[],
624
+ @Ctx() context: any
625
+ ): Promise<{{pascalCase name}}[]> {
626
+ const { domain, user, tx } = context.state
627
+
628
+ let results = []
629
+ const _createRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === '+')
630
+ const _updateRecords = patches.filter((patch: any) => patch.cuFlag.toUpperCase() === 'M')
631
+ const {{camelCase name}}Repo = tx.getRepository({{pascalCase name}})
632
+
633
+ if (_createRecords.length > 0) {
634
+ for (let i = 0; i < _createRecords.length; i++) {
635
+ const newRecord = _createRecords[i]
636
+
637
+ const result = await {{camelCase name}}Repo.save({
638
+ ...newRecord,
639
+ domain,
640
+ creator: user,
641
+ updater: user
642
+ })
643
+
644
+ results.push({ ...result, cuFlag: '+' })
645
+ }
646
+ }
647
+
648
+ if (_updateRecords.length > 0) {
649
+ for (let i = 0; i < _updateRecords.length; i++) {
650
+ const updRecord = _updateRecords[i]
651
+ const {{camelCase name}} = await {{camelCase name}}Repo.findOne({
652
+ where: { domain: { id: domain.id }, id:updRecord.id },
653
+ relations: ['domain', 'updater', 'creator']
654
+ })
655
+
656
+ const result = await {{camelCase name}}Repo.save({
657
+ ...{{camelCase name}},
658
+ ...updRecord,
659
+ updater: user
660
+ })
661
+
662
+ results.push({ ...result, cuFlag: 'M' })
663
+ }
664
+ }
665
+
666
+ return results
667
+ }
668
+
669
+ @Directive('@transaction')
670
+ @Mutation(returns => Boolean, { description: 'To delete {{pascalCase name}}' })
671
+ async delete{{pascalCase name}}(@Arg('id') id: string, @Ctx() context: any): Promise<boolean> {
672
+ const { domain, tx, user } = context.state
673
+ await tx.getRepository({{pascalCase name}}).remove({ domain, id, updater:user })
674
+ return true
675
+ }
676
+
677
+ @Directive('@transaction')
678
+ @Mutation(returns => Boolean, { description: 'To delete multiple {{camelCase name}}s' })
679
+ async delete{{pluralPascalCase name}}(
680
+ @Arg('ids', type => [String]) ids: string[],
681
+ @Ctx() context: any
682
+ ): Promise<boolean> {
683
+ const { domain, tx, user } = context.state
684
+
685
+ let delEntitis = ids.map(id=>{
686
+ return {domain,id,updater:user}
687
+ })
688
+
689
+ await tx.getRepository({{pascalCase name}}).remove(delEntitis)
690
+
691
+ return true
692
+ }
693
+ }
694
+ `;
695
+ /* service type text {{name}}-type.ts */
696
+ const sereviceType = `
697
+ import { ObjectType, Field, InputType, Int, ID, Float, registerEnumType } from 'type-graphql'
698
+
699
+ import { {{pascalCase name}} } from './{{name}}'
700
+
701
+ @InputType()
702
+ export class New{{pascalCase name}} {
703
+ {{newTypeColumns}}
704
+ }
705
+
706
+ @InputType()
707
+ export class {{pascalCase name}}Patch {
708
+ @Field(type => ID, { nullable: true })
709
+ id?: string
710
+
711
+ {{patchTypeColumns}}
712
+
713
+ @Field()
714
+ cuFlag: string
715
+ }
716
+
717
+ @ObjectType()
718
+ export class {{pascalCase name}}List {
719
+ @Field(type => [{{pascalCase name}}])
720
+ items: {{pascalCase name}}[]
721
+
722
+ @Field(type => Int)
723
+ total: number
724
+ }
725
+ `;
726
+ /* service type text {{name}}-type.ts */
727
+ const sereviceHistoryType = `
728
+ import { ObjectType, Field, InputType, Int, ID, Float, registerEnumType } from 'type-graphql'
729
+
730
+ import { {{pascalCase name}}History } from './{{name}}-history'
731
+
732
+ @ObjectType()
733
+ export class {{pascalCase name}}HistoryList {
734
+ @Field(type => [{{pascalCase name}}History])
735
+ items: {{pascalCase name}}History[]
736
+
737
+ @Field(type => Int)
738
+ total: number
739
+ }
740
+ `;
741
+ /* service entity {{name}}.ts */
742
+ const serviceEntity = `
743
+ import {
744
+ CreateDateColumn,
745
+ UpdateDateColumn,
746
+ Entity,
747
+ Index,
748
+ Column,
749
+ RelationId,
750
+ ManyToOne,
751
+ PrimaryGeneratedColumn,
752
+ VersionColumn
753
+ } from 'typeorm'
754
+ import { ObjectType, Field, Int, ID, Float, registerEnumType } from 'type-graphql'
755
+
756
+ import { Domain } from '@things-factory/shell'
757
+ import { User } from '@things-factory/auth-base'
758
+
759
+ @Entity('{{tableName}}')
760
+ {{indexAnn}}
761
+ @ObjectType({ description: 'Entity for {{pascalCase name}}' })
762
+ export class {{pascalCase name}} {
763
+ @PrimaryGeneratedColumn('uuid')
764
+ @Field(type => ID)
765
+ readonly id: string
766
+
767
+ @ManyToOne(type => Domain, {
768
+ createForeignKeyConstraints: false
769
+ })
770
+ @Field({ nullable: false })
771
+ domain: Domain
772
+
773
+ @RelationId(({{camelCase name}}: {{pascalCase name}}) => {{camelCase name}}.domain)
774
+ domainId: string
775
+
776
+ {{entityColumns}}
777
+
778
+ @CreateDateColumn()
779
+ @Field({ nullable: true })
780
+ createdAt?: Date
781
+
782
+ @UpdateDateColumn()
783
+ @Field({ nullable: true })
784
+ updatedAt?: Date
785
+
786
+ @ManyToOne(type => User, {
787
+ createForeignKeyConstraints: false,
788
+ nullable: true
789
+ })
790
+ @Field({ nullable: true })
791
+ creator?: User
792
+
793
+ @RelationId(({{camelCase name}}: {{pascalCase name}}) => {{camelCase name}}.creator)
794
+ creatorId?: string
795
+
796
+ @ManyToOne(type => User, {
797
+ createForeignKeyConstraints: false,
798
+ nullable: true
799
+ })
800
+ @Field({ nullable: true })
801
+ updater?: User
802
+
803
+ @RelationId(({{camelCase name}}: {{pascalCase name}}) => {{camelCase name}}.updater)
804
+ updaterId?: string
805
+ }
806
+ `;
807
+ /* service entity {{name}}-history.ts */
808
+ const serviceEntityHistCopy = `
809
+ import {
810
+ CreateDateColumn,
811
+ UpdateDateColumn,
812
+ Entity,
813
+ Index,
814
+ Column,
815
+ RelationId,
816
+ ManyToOne,
817
+ PrimaryGeneratedColumn,
818
+ VersionColumn
819
+ } from 'typeorm'
820
+
821
+ import {
822
+ HistoryActionColumn,
823
+ HistoryActionType,
824
+ HistoryEntityInterface,
825
+ HistoryOriginalIdColumn
826
+ } from '@operato/typeorm-history'
827
+
828
+ import { ObjectType, Field, Int, ID, Float, registerEnumType } from 'type-graphql'
829
+
830
+ import { config } from '@things-factory/env'
831
+ import { Domain, ScalarObject } from '@things-factory/shell'
832
+ import { User } from '@things-factory/auth-base'
833
+
834
+ const ORMCONFIG = config.get('ormconfig', {})
835
+ const DATABASE_TYPE = ORMCONFIG.type
836
+
837
+ import { {{pascalCase name}} } from './{{name}}'
838
+
839
+ @Entity('{{tableName}}_histories')
840
+ @Index('ix_{{snakeCase name}}_histories_0', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.originalId,{{camelCase name}}History.dataRevisionNo], { unique: true })
841
+ @Index('ix_{{snakeCase name}}_histories_1', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.originalId ], { unique: false })
842
+ @Index('ix_{{snakeCase name}}_histories_2', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.domain, {{camelCase name}}History.originalId ], { unique: false })
843
+ @Index('ix_{{snakeCase name}}_histories_3', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.domain, {{camelCase name}}History.originalId, {{camelCase name}}History.dataRevisionNo], { unique: true })
844
+ @ObjectType({ description: 'Entity for {{pascalCase name}}History' })
845
+ export class {{pascalCase name}}History implements HistoryEntityInterface<{{pascalCase name}}>{
846
+ @PrimaryGeneratedColumn('uuid')
847
+ @Field(type => ID)
848
+ readonly id: string
849
+
850
+ @ManyToOne(type => Domain, {
851
+ createForeignKeyConstraints: false
852
+ })
853
+ @Field({ nullable: false })
854
+ domain: Domain
855
+
856
+ @RelationId(({{camelCase name}}History: {{pascalCase name}}History) => {{camelCase name}}History.domain)
857
+ domainId: string
858
+
859
+ @HistoryOriginalIdColumn({type: 'character varying', nullable: false ,length:40})
860
+ @Field({ nullable: false })
861
+ public originalId!: string
862
+
863
+
864
+ @HistoryActionColumn({
865
+ nullable: false,
866
+ type:
867
+ DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
868
+ ? 'enum'
869
+ : DATABASE_TYPE == 'oracle'
870
+ ? 'varchar2'
871
+ : 'smallint',
872
+ enum: HistoryActionType
873
+ })
874
+ @Field({ nullable: false })
875
+ public dataRevisionAction!: HistoryActionType
876
+
877
+ @Column({ default: 1, nullable: false })
878
+ @Field({ nullable: false })
879
+ dataRevisionNo?: number = 1
880
+
881
+ {{entityColumns}}
882
+
883
+ @CreateDateColumn()
884
+ @Field({ nullable: true })
885
+ createdAt?: Date
886
+
887
+ @UpdateDateColumn()
888
+ @Field({ nullable: true })
889
+ updatedAt?: Date
890
+
891
+ @ManyToOne(type => User, {
892
+ createForeignKeyConstraints: false,
893
+ nullable: true
894
+ })
895
+ @Field({ nullable: true })
896
+ creator?: User
897
+
898
+ @RelationId(({{camelCase name}}History: {{pascalCase name}}History) => {{camelCase name}}History.creator)
899
+ creatorId?: string
900
+
901
+ @ManyToOne(type => User, {
902
+ createForeignKeyConstraints: false,
903
+ nullable: true
904
+ })
905
+ @Field({ nullable: true })
906
+ updater?: User
907
+
908
+ @RelationId(({{camelCase name}}History: {{pascalCase name}}History) => {{camelCase name}}History.updater)
909
+ updaterId?: string
910
+ }
911
+ `;
912
+ /* service entity {{name}}-history.ts */
913
+ const serviceEntityHistJson = `
914
+ import {
915
+ CreateDateColumn,
916
+ UpdateDateColumn,
917
+ Entity,
918
+ Index,
919
+ Column,
920
+ RelationId,
921
+ ManyToOne,
922
+ PrimaryGeneratedColumn,
923
+ VersionColumn
924
+ } from 'typeorm'
925
+
926
+ import {
927
+ HistoryActionColumn,
928
+ HistoryActionType,
929
+ HistoryEntityInterface,
930
+ HistoryOriginalIdColumn
931
+ } from '@operato/typeorm-history'
932
+
933
+ import { ObjectType, Field, Int, ID, Float, registerEnumType } from 'type-graphql'
934
+
935
+ import { config } from '@things-factory/env'
936
+ import { Domain, ScalarObject } from '@things-factory/shell'
937
+ import { User } from '@things-factory/auth-base'
938
+
939
+ const ORMCONFIG = config.get('ormconfig', {})
940
+ const DATABASE_TYPE = ORMCONFIG.type
941
+
942
+ import { {{pascalCase name}} } from './{{name}}'
943
+
944
+ @Entity('{{tableName}}_histories')
945
+ @Index('ix_{{snakeCase name}}_histories_0', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.originalId,{{camelCase name}}History.dataRevisionNo], { unique: true })
946
+ @Index('ix_{{snakeCase name}}_histories_1', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.originalId ], { unique: false })
947
+ @Index('ix_{{snakeCase name}}_histories_2', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.domain, {{camelCase name}}History.originalId ], { unique: false })
948
+ @Index('ix_{{snakeCase name}}_histories_3', ({{camelCase name}}History: {{pascalCase name}}History) => [{{camelCase name}}History.domain, {{camelCase name}}History.originalId, {{camelCase name}}History.dataRevisionNo], { unique: true })
949
+ @ObjectType({ description: 'Entity for {{pascalCase name}}History' })
950
+ export class {{pascalCase name}}History implements HistoryEntityInterface<{{pascalCase name}}>{
951
+ @PrimaryGeneratedColumn('uuid')
952
+ @Field(type => ID)
953
+ readonly id: string
954
+
955
+ @ManyToOne(type => Domain, {
956
+ createForeignKeyConstraints: false
957
+ })
958
+ @Field({ nullable: false })
959
+ domain: Domain
960
+
961
+ @RelationId(({{camelCase name}}History: {{pascalCase name}}History) => {{camelCase name}}History.domain)
962
+ domainId: string
963
+
964
+ @HistoryOriginalIdColumn({type: 'character varying', nullable: false ,length:40})
965
+ @Field({ nullable: false })
966
+ public originalId!: string
967
+
968
+ @HistoryActionColumn({
969
+ nullable: false,
970
+ type:
971
+ DATABASE_TYPE == 'postgres' || DATABASE_TYPE == 'mysql' || DATABASE_TYPE == 'mariadb'
972
+ ? 'enum'
973
+ : DATABASE_TYPE == 'oracle'
974
+ ? 'varchar2'
975
+ : 'smallint',
976
+ enum: HistoryActionType
977
+ })
978
+ @Field({ nullable: false })
979
+ public dataRevisionAction!: HistoryActionType
980
+
981
+
982
+ @Column({ default: 1, nullable: false })
983
+ @Field({ nullable: false })
984
+ dataRevisionNo?: number = 1
985
+
986
+ @Column('simple-json', { nullable: true })
987
+ @Field(type => ScalarObject, { nullable: true })
988
+ historyJson?: any
989
+
990
+ @CreateDateColumn()
991
+ @Field({ nullable: true })
992
+ createdAt?: Date
993
+
994
+ @UpdateDateColumn()
995
+ @Field({ nullable: true })
996
+ updatedAt?: Date
997
+
998
+ @ManyToOne(type => User, {
999
+ createForeignKeyConstraints: false,
1000
+ nullable: true
1001
+ })
1002
+ @Field({ nullable: true })
1003
+ creator?: User
1004
+
1005
+ @RelationId(({{camelCase name}}History: {{pascalCase name}}History) => {{camelCase name}}History.creator)
1006
+ creatorId?: string
1007
+
1008
+ @ManyToOne(type => User, {
1009
+ createForeignKeyConstraints: false,
1010
+ nullable: true
1011
+ })
1012
+ @Field({ nullable: true })
1013
+ updater?: User
1014
+
1015
+ @RelationId(({{camelCase name}}History: {{pascalCase name}}History) => {{camelCase name}}History.updater)
1016
+ updaterId?: string
1017
+ }
1018
+ `;
1019
+ /* service entity subscriber event-subscriber.ts */
1020
+ const serviceEntitySubscriber = `
1021
+ import { EventSubscriber } from 'typeorm'
1022
+ import { HistoryEntitySubscriber } from '@operato/typeorm-history'
1023
+
1024
+ import { {{pascalCase name}} } from './{{name}}'
1025
+ import { {{pascalCase name}}History } from './{{name}}-history'
1026
+ import { getRepository } from '@things-factory/shell'
1027
+
1028
+ @EventSubscriber()
1029
+ export class {{pascalCase name}}HistoryEntitySubscriber extends HistoryEntitySubscriber<{{pascalCase name}},{{pascalCase name}}History> {
1030
+ public get entity() {
1031
+ return {{pascalCase name}}
1032
+ }
1033
+
1034
+ public get historyEntity() {
1035
+ return {{pascalCase name}}History
1036
+ }
1037
+
1038
+ {{entityToJson}}
1039
+
1040
+ async beforeRemoveHistory(history:{{pascalCase name}}History,entity:{{pascalCase name}}){
1041
+ let repo = getRepository({{pascalCase name}}History);
1042
+ const revNo = await repo.createQueryBuilder()
1043
+ .select('max(data_revision_no)', 'rev_no')
1044
+ .where('domain_id = :domainId', { domainId: entity.domain.id })
1045
+ .andWhere('original_id = :originalId', { originalId: entity.id })
1046
+ .getRawOne()
1047
+
1048
+ history.dataRevisionNo = revNo ? revNo.rev_no + 1 : 1;
1049
+ return history;
1050
+ }
1051
+ }
1052
+ `;
1053
+ //# sourceMappingURL=create-service.js.map