@things-factory/operato-tools 9.0.0-beta.26 → 9.0.0-beta.27

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