@things-factory/operato-tools 8.0.40 → 9.0.0-9.0.0-beta.59.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_index.html +1 -2
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/views/auth-page.html +1 -2
- package/views/public/home.html +1 -2
- package/installer/config.production.js +0 -40
- package/installer/docker-compose.yml +0 -42
- package/installer/install.sh +0 -54
- package/installer/migrate.sh +0 -1
- package/installer/start.sh +0 -18
- package/installer/stop.sh +0 -1
- package/installer/upgrade.sh +0 -1
- package/server/index.ts +0 -1
- package/server/service/index.ts +0 -15
- package/server/service/tool-entity/create-menu.ts +0 -338
- package/server/service/tool-entity/create-service.ts +0 -1160
- package/server/service/tool-entity/index.ts +0 -4
- package/server/tsconfig.json +0 -9
- package/tsconfig.json +0 -9
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@things-factory/operato-tools",
|
3
|
-
"version": "
|
3
|
+
"version": "9.0.0-9.0.0-beta.59.0",
|
4
4
|
"main": "dist-server/index.js",
|
5
5
|
"browser": "client/index.js",
|
6
6
|
"things-factory": true,
|
@@ -38,8 +38,8 @@
|
|
38
38
|
"@things-factory/operato-license-checker": "^4.0.4"
|
39
39
|
},
|
40
40
|
"devDependencies": {
|
41
|
-
"@things-factory/builder": "^
|
42
|
-
"@things-factory/meta-ui": "^
|
41
|
+
"@things-factory/builder": "^9.0.0-9.0.0-beta.59.0",
|
42
|
+
"@things-factory/meta-ui": "^9.0.0-9.0.0-beta.59.0"
|
43
43
|
},
|
44
|
-
"gitHead": "
|
44
|
+
"gitHead": "cf6ee84b991f469a4e71198b0e6314b45e9e10b8"
|
45
45
|
}
|
package/views/auth-page.html
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
<meta charset="utf-8" />
|
5
5
|
<title>Operato Tools</title>
|
6
6
|
<meta name="generator" content="Things Factory Starter Kit" />
|
7
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
8
8
|
<meta name="description" content="Heart of Logistics" />
|
9
9
|
|
10
10
|
<base href="/" />
|
@@ -50,7 +50,6 @@
|
|
50
50
|
|
51
51
|
<!-- Performance tip: hint to the browser to start the handshake for the fonts site -->
|
52
52
|
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
|
53
|
-
<link href="/node_modules/@material-design-icons/font/index.css" rel="stylesheet" />
|
54
53
|
<link href="/node_modules/material-symbols/index.css" rel="stylesheet" />
|
55
54
|
<link href="/node_modules/@fontsource/roboto/index.css" rel="stylesheet" />
|
56
55
|
<link rel="stylesheet" href="/theme.css" />
|
package/views/public/home.html
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
<meta charset="utf-8" />
|
5
5
|
<title>Operato Tools</title>
|
6
6
|
<meta name="generator" content="Things Factory Starter Kit" />
|
7
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
8
8
|
<meta name="description" content="Heart of Logistics" />
|
9
9
|
|
10
10
|
<base href="/" />
|
@@ -50,7 +50,6 @@
|
|
50
50
|
|
51
51
|
<!-- Performance tip: hint to the browser to start the handshake for the fonts site -->
|
52
52
|
<link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin />
|
53
|
-
<link href="/node_modules/@material-design-icons/font/index.css" rel="stylesheet" />
|
54
53
|
<link href="/node_modules/material-symbols/index.css" rel="stylesheet" />
|
55
54
|
<link href="/node_modules/@fontsource/roboto/index.css" rel="stylesheet" />
|
56
55
|
<link rel="stylesheet" href="/theme.css" />
|
@@ -1,40 +0,0 @@
|
|
1
|
-
module.exports = {
|
2
|
-
SECRET: '0xD58F835B69D207A76CC5F84a70a1D0d4C79dAC95', // should be changed
|
3
|
-
email: {
|
4
|
-
host: 'smtp.office365.com', // your sender-email smtp host
|
5
|
-
port: 587, // smtp server port
|
6
|
-
secure: false, // true for 465, false for other ports
|
7
|
-
auth: {
|
8
|
-
user: 'your sender-email',
|
9
|
-
pass: 'your sender-email password' // generated ethereal password
|
10
|
-
},
|
11
|
-
secureConnection: false,
|
12
|
-
tls: {
|
13
|
-
ciphers: 'SSLv3'
|
14
|
-
}
|
15
|
-
},
|
16
|
-
logger: {
|
17
|
-
file: {
|
18
|
-
filename: 'logs/application-%DATE%.log',
|
19
|
-
datePattern: 'YYYY-MM-DD-HH',
|
20
|
-
zippedArchive: false,
|
21
|
-
maxSize: '20m',
|
22
|
-
maxFiles: '2d',
|
23
|
-
level: 'info'
|
24
|
-
},
|
25
|
-
console: {
|
26
|
-
level: 'silly'
|
27
|
-
}
|
28
|
-
},
|
29
|
-
ormconfig: {
|
30
|
-
name: 'default',
|
31
|
-
type: 'postgres',
|
32
|
-
host: 'postgres',
|
33
|
-
port: 5432,
|
34
|
-
database: 'postgres',
|
35
|
-
username: 'postgres',
|
36
|
-
password: 'abcd1234',
|
37
|
-
synchronize: true,
|
38
|
-
logging: true
|
39
|
-
}
|
40
|
-
}
|
@@ -1,42 +0,0 @@
|
|
1
|
-
version: '3'
|
2
|
-
services:
|
3
|
-
nginx:
|
4
|
-
image: hatiolab/operato-nginx:latest
|
5
|
-
ports:
|
6
|
-
- ${HostPort}:80
|
7
|
-
depends_on:
|
8
|
-
- app
|
9
|
-
app:
|
10
|
-
build: .
|
11
|
-
container_name: operato-tools
|
12
|
-
image: hatiolab/operato-tools:latest
|
13
|
-
privileged: true
|
14
|
-
volumes:
|
15
|
-
- ./logs:/app/logs
|
16
|
-
- ./config.production.js:/app/config.production.js
|
17
|
-
ports:
|
18
|
-
- 4000:3000
|
19
|
-
depends_on:
|
20
|
-
- postgres
|
21
|
-
- mosquitto
|
22
|
-
logging:
|
23
|
-
driver: 'json-file'
|
24
|
-
options:
|
25
|
-
max-size: '100m'
|
26
|
-
max-file: '3'
|
27
|
-
postgres:
|
28
|
-
image: postgres:13.2
|
29
|
-
container_name: db-operato-tools
|
30
|
-
environment:
|
31
|
-
POSTGRES_PASSWORD: abcd1234
|
32
|
-
POSTGRES_USER: postgres
|
33
|
-
PGDATA: /var/lib/postgresql/data/pgdata
|
34
|
-
volumes:
|
35
|
-
- ./postgres_data:/var/lib/postgresql/data/pgdata
|
36
|
-
ports:
|
37
|
-
- '55432:5432'
|
38
|
-
mosquitto:
|
39
|
-
image: eclipse-mosquitto:latest
|
40
|
-
ports:
|
41
|
-
- 1883:1883
|
42
|
-
- 9001:9001
|
package/installer/install.sh
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
if [ -f "config.production.js" ] ; then
|
2
|
-
echo "config.production.js exist"
|
3
|
-
else
|
4
|
-
echo "config.production.js create"
|
5
|
-
curl -O https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/config.production.js
|
6
|
-
fi
|
7
|
-
|
8
|
-
if [ -f "start.sh" ] ; then
|
9
|
-
echo "start.sh exist"
|
10
|
-
else
|
11
|
-
echo "start.sh create"
|
12
|
-
curl -O https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/start.sh
|
13
|
-
fi
|
14
|
-
|
15
|
-
if [ -f "stop.sh" ] ; then
|
16
|
-
echo "stop.sh exist"
|
17
|
-
else
|
18
|
-
echo "stop.sh create"
|
19
|
-
curl -O https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/stop.sh
|
20
|
-
fi
|
21
|
-
|
22
|
-
if [ -f "upgrade.sh" ] ; then
|
23
|
-
echo "upgrade.sh exist"
|
24
|
-
else
|
25
|
-
echo "upgrade.sh create"
|
26
|
-
curl -O https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/upgrade.sh
|
27
|
-
fi
|
28
|
-
|
29
|
-
if [ -f "migrate.sh" ] ; then
|
30
|
-
echo "migrate.sh exist"
|
31
|
-
else
|
32
|
-
echo "migrate.sh create"
|
33
|
-
curl -O https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/migrate.sh
|
34
|
-
fi
|
35
|
-
|
36
|
-
if [ -f "docker-compose.yml" ] ; then
|
37
|
-
echo "docker-compose.yml exist"
|
38
|
-
else
|
39
|
-
echo "docker-compose.yml create"
|
40
|
-
curl -O https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/docker-compose.yml
|
41
|
-
fi
|
42
|
-
|
43
|
-
chmod u+x start.sh
|
44
|
-
chmod u+x stop.sh
|
45
|
-
chmod u+x upgrade.sh
|
46
|
-
chmod u+x migrate.sh
|
47
|
-
|
48
|
-
echo "HostPort=3000" > .env
|
49
|
-
|
50
|
-
docker pull hatiolab/operato-tools:latest
|
51
|
-
|
52
|
-
docker pull hatiolab/operato-nginx:latest
|
53
|
-
|
54
|
-
docker-compose create
|
package/installer/migrate.sh
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
docker exec -it operato-tools npx things-factory-migration --mode=production
|
package/installer/start.sh
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
HOST_PORT=3000
|
2
|
-
|
3
|
-
if [ $# -eq 0 ] ; then
|
4
|
-
echo "Warning: default port 3000"
|
5
|
-
else
|
6
|
-
HOST_PORT=$1
|
7
|
-
fi
|
8
|
-
|
9
|
-
|
10
|
-
echo "HOST_PORT : ${HOST_PORT}"
|
11
|
-
|
12
|
-
echo "HostPort="$HOST_PORT > .env
|
13
|
-
|
14
|
-
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
15
|
-
xhost +"local:docker@"
|
16
|
-
fi
|
17
|
-
|
18
|
-
docker-compose up -d
|
package/installer/stop.sh
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
docker-compose stop
|
package/installer/upgrade.sh
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
curl -fsSL https://raw.githubusercontent.com/things-factory/things-factory/master/packages/operato-tools/installer/install.sh | bash -s
|
package/server/index.ts
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export * from './service'
|
package/server/service/index.ts
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
/* EXPORT ENTITY TYPES */
|
2
|
-
|
3
|
-
/* IMPORT ENTITIES AND RESOLVERS */
|
4
|
-
import { resolvers as entityResolvers } from './tool-entity'
|
5
|
-
|
6
|
-
export const entities = [
|
7
|
-
/* ENTITIES */
|
8
|
-
]
|
9
|
-
|
10
|
-
export const schema = {
|
11
|
-
resolverClasses: [
|
12
|
-
/* RESOLVER CLASSES */
|
13
|
-
...entityResolvers
|
14
|
-
]
|
15
|
-
}
|
@@ -1,338 +0,0 @@
|
|
1
|
-
import { Arg, Ctx, Mutation, Directive, Resolver } from 'type-graphql'
|
2
|
-
import { Entity, EntityColumn } from '@things-factory/resource-base'
|
3
|
-
import { Menu } from '@things-factory/menu-base'
|
4
|
-
const { camelCase, startCase, snakeCase, kebabCase } = require('lodash')
|
5
|
-
const { plural } = require('pluralize')
|
6
|
-
import crypto from 'crypto'
|
7
|
-
|
8
|
-
@Resolver()
|
9
|
-
export class OperatoToolCreateMenu {
|
10
|
-
@Directive('@transaction')
|
11
|
-
@Mutation(returns => Boolean, { description: 'Operato Tool Create Menu' })
|
12
|
-
async toolCreateMenu(@Arg('id') id: string, @Arg('parent_menu_id') parent_menu_id: string, @Ctx() context: any): Promise<Boolean> {
|
13
|
-
const { domain, user, tx } = context.state
|
14
|
-
|
15
|
-
// Entity 조회
|
16
|
-
const entity: Entity = await tx.getRepository(Entity).findOne({
|
17
|
-
where: {
|
18
|
-
domain: { id: domain.id },
|
19
|
-
id
|
20
|
-
}
|
21
|
-
})
|
22
|
-
|
23
|
-
// Entity 컬럼 조회
|
24
|
-
const entityColumns: EntityColumn[] = await tx.getRepository(EntityColumn).find({
|
25
|
-
where: {
|
26
|
-
domain: { id: domain.id },
|
27
|
-
entity: { id: entity.id }
|
28
|
-
}
|
29
|
-
})
|
30
|
-
|
31
|
-
let { name = '' } = entity || {}
|
32
|
-
let serviceName: string = kebabCase(name)
|
33
|
-
|
34
|
-
// 이름 치환 (타이틀 , grapql 관련 서비스 )
|
35
|
-
let pageTemplate = modelTemplate
|
36
|
-
.replace(/{{pascalCase name}}/g, startCase(camelCase(name)).replace(/ /g, ''))
|
37
|
-
.replace(/{{camelCase name}}/g, camelCase(name))
|
38
|
-
.replace(/{{snakeCase name}}/g, snakeCase(name))
|
39
|
-
.replace(/{{pluralPascalCase name}}/g, startCase(camelCase(plural(name))).replace(/ /g, ''))
|
40
|
-
.replace(/{{pluralCamelCase name}}/g, camelCase(plural(name)))
|
41
|
-
.replace(/{{name}}/g, name)
|
42
|
-
|
43
|
-
// 이력조회 버튼 추가
|
44
|
-
let historyButton = ''
|
45
|
-
if (entity.dataProp == 'JSON') {
|
46
|
-
historyButton = `
|
47
|
-
{
|
48
|
-
"name": "history",
|
49
|
-
"type": "basic",
|
50
|
-
"label": "data_history",
|
51
|
-
"icon": "history",
|
52
|
-
"logic": "history_json"
|
53
|
-
}
|
54
|
-
`
|
55
|
-
} else if (entity.dataProp == 'COPY') {
|
56
|
-
historyButton = `
|
57
|
-
{
|
58
|
-
"name": "history",
|
59
|
-
"type": "basic",
|
60
|
-
"label": "data_history",
|
61
|
-
"icon": "history",
|
62
|
-
"logic": "history_copy"
|
63
|
-
}
|
64
|
-
`
|
65
|
-
}
|
66
|
-
pageTemplate = pageTemplate.replace(/{{HistoryButton}}/g, historyButton)
|
67
|
-
|
68
|
-
// 그리드 정렬
|
69
|
-
let sortColumns = this.createSortCols(entityColumns)
|
70
|
-
pageTemplate = pageTemplate.replace(/{{SortColumns}}/g, sortColumns.join(','))
|
71
|
-
|
72
|
-
// 검색 필드
|
73
|
-
let searchColumns = this.createSearchCols(entityColumns)
|
74
|
-
pageTemplate = pageTemplate.replace(/{{SearchColumns}}/g, searchColumns.join(','))
|
75
|
-
|
76
|
-
// 그리드 컬럼
|
77
|
-
let gridColumns = this.createGridColumns(entityColumns)
|
78
|
-
pageTemplate = pageTemplate.replace(/{{GridColumns}}/g, gridColumns.join(','))
|
79
|
-
|
80
|
-
// 암호화
|
81
|
-
pageTemplate = this.enc(pageTemplate)
|
82
|
-
|
83
|
-
// 메뉴 생성
|
84
|
-
await this.createMenuData(tx, domain, user, parent_menu_id, serviceName, pageTemplate)
|
85
|
-
return true
|
86
|
-
}
|
87
|
-
|
88
|
-
/**
|
89
|
-
* 그리드 컬럼
|
90
|
-
* @param entityColumns
|
91
|
-
*/
|
92
|
-
createGridColumns(entityColumns: EntityColumn[]) {
|
93
|
-
return entityColumns
|
94
|
-
.filter(x => x.name != 'id' && x.gridRank > 0)
|
95
|
-
.sort(function (a, b) {
|
96
|
-
return a.gridRank - b.gridRank
|
97
|
-
})
|
98
|
-
.map(x => {
|
99
|
-
let { gridEditor = 'string', name, term, gridWidth = 0, gridAlign = 'left', nullable = false } = x
|
100
|
-
if (gridEditor == null) gridEditor = 'string'
|
101
|
-
if (gridAlign == null) gridAlign = 'left'
|
102
|
-
|
103
|
-
// 생성 자 수정 자 기본 값
|
104
|
-
if (name == 'updater_id' || name == 'creator_id') {
|
105
|
-
name = name == 'updater_id' ? 'updater' : 'creator'
|
106
|
-
return `{"type": "object","name": "${name}","header": "${name}","width": 100,"editable":false, "align": "center","object_opt":{"queryName":"users"}}`
|
107
|
-
}
|
108
|
-
// 생성 시간 수정 시간 기본 값
|
109
|
-
if (name == 'updated_at' || name == 'created_at') {
|
110
|
-
return `{"type": "datetime","name": "${name == 'updated_at' ? 'updatedAt' : 'createdAt'}","header": "${name}","width": 160,"editable":false, "align": "center"}`
|
111
|
-
}
|
112
|
-
|
113
|
-
// 읽기 / 숨김 필드는 수정 불가
|
114
|
-
let editable = gridEditor == 'readonly' || gridEditor == 'hidden' ? false : true
|
115
|
-
// 히든 필드
|
116
|
-
let hidden = gridEditor == 'hidden' ? true : false
|
117
|
-
if (hidden == true || editable == false) {
|
118
|
-
// 히든 필드는 문자열로 변환 숨김
|
119
|
-
gridEditor = 'string'
|
120
|
-
}
|
121
|
-
|
122
|
-
let colTxt = `{"type": "${gridEditor}","name": "${camelCase(
|
123
|
-
name
|
124
|
-
)}","header": "${term}","hidden":${hidden} ,"editable": ${editable},"mandatory": ${!nullable},"sortable":true ,"align": "${gridAlign}","width":${gridWidth} ,"exportable": true`
|
125
|
-
|
126
|
-
// 참조 타입이 공통 코드
|
127
|
-
if (x.refType == 'code') {
|
128
|
-
colTxt = colTxt + `,"select_opt":{"type":"code","name":"${x.refName}"}`
|
129
|
-
}
|
130
|
-
|
131
|
-
// 참조 타입이 시나리오
|
132
|
-
if (x.refType == 'scenario') {
|
133
|
-
colTxt = colTxt + `,"select_opt":{"type":"scenario","name":"${x.refName}"}`
|
134
|
-
}
|
135
|
-
|
136
|
-
// 참조 타입이 엔티티
|
137
|
-
if (x.refType == 'entity') {
|
138
|
-
colTxt = colTxt + `,"select_opt":{"type": "entity","args": {"queryName": "${camelCase(plural(x.refName))}","codeField": "id","dispField": "name"}}`
|
139
|
-
}
|
140
|
-
colTxt = colTxt + '}'
|
141
|
-
return colTxt
|
142
|
-
})
|
143
|
-
}
|
144
|
-
|
145
|
-
/**
|
146
|
-
* 검색 컬럼
|
147
|
-
* @param entityColumns
|
148
|
-
*/
|
149
|
-
createSearchCols(entityColumns: EntityColumn[]) {
|
150
|
-
return entityColumns
|
151
|
-
.filter(x => x.searchRank > 0)
|
152
|
-
.sort(function (a, b) {
|
153
|
-
return a.searchRank - b.searchRank
|
154
|
-
})
|
155
|
-
.map(x => {
|
156
|
-
let operator = x.searchOper
|
157
|
-
|
158
|
-
if (operator == 'filter') {
|
159
|
-
return `"${camelCase(x.name)}"`
|
160
|
-
}
|
161
|
-
|
162
|
-
if (!operator) operator = 'eq'
|
163
|
-
return `{"name": "${camelCase(x.name)}","operator": "${operator}"}`
|
164
|
-
})
|
165
|
-
}
|
166
|
-
|
167
|
-
/**
|
168
|
-
* 그리드 정렬
|
169
|
-
* @param entityColumns
|
170
|
-
* @returns
|
171
|
-
*/
|
172
|
-
createSortCols(entityColumns: EntityColumn[]) {
|
173
|
-
return entityColumns
|
174
|
-
.filter(x => x.sortRank > 0)
|
175
|
-
.sort(function (a, b) {
|
176
|
-
return a.sortRank - b.sortRank
|
177
|
-
})
|
178
|
-
.map(x => {
|
179
|
-
return `{"name":"${camelCase(x.name)}","desc":${x.reverseSort}}`
|
180
|
-
})
|
181
|
-
}
|
182
|
-
|
183
|
-
/**
|
184
|
-
* 메뉴 데이터 생성
|
185
|
-
* @param tx
|
186
|
-
* @param domain
|
187
|
-
* @param user
|
188
|
-
* @param parent_menu_id
|
189
|
-
* @param name
|
190
|
-
* @param pageTemplate
|
191
|
-
*/
|
192
|
-
async createMenuData(tx: any, domain: any, user: any, parent_menu_id: string, name: string, pageTemplate: string) {
|
193
|
-
// 상위 메뉴
|
194
|
-
let parentMenu = await tx.getRepository(Menu).findOne({
|
195
|
-
where: {
|
196
|
-
domain: { id: domain.id },
|
197
|
-
id: parent_menu_id
|
198
|
-
}
|
199
|
-
})
|
200
|
-
|
201
|
-
// 메뉴 랭크
|
202
|
-
let menuRank = await tx.getRepository(Menu).query(`select coalesce(max(rank),0) as rank from menus where parent_id = '${parent_menu_id}' or id = '${parent_menu_id}'`)
|
203
|
-
let rank = menuRank[0].rank + 10
|
204
|
-
|
205
|
-
// 메뉴 저장
|
206
|
-
let menu: Menu = new Menu()
|
207
|
-
menu.name = name
|
208
|
-
menu.menuType = 'SCREEN'
|
209
|
-
menu.category = 'meta-grist-page'
|
210
|
-
menu.rank = rank
|
211
|
-
menu.hiddenFlag = false
|
212
|
-
menu.routing = name
|
213
|
-
menu.template = pageTemplate
|
214
|
-
menu.resourceUrl = '@things-factory/meta-ui/client/pages/meta-grist-page'
|
215
|
-
menu.parent = parentMenu
|
216
|
-
|
217
|
-
await tx.getRepository(Menu).save({
|
218
|
-
...menu,
|
219
|
-
domain,
|
220
|
-
creator: user,
|
221
|
-
updater: user
|
222
|
-
})
|
223
|
-
}
|
224
|
-
|
225
|
-
/**
|
226
|
-
* json 모델 암호화
|
227
|
-
* @param template
|
228
|
-
* @returns
|
229
|
-
*/
|
230
|
-
enc(template: string) {
|
231
|
-
let jsonStr = JSON.stringify(template)
|
232
|
-
let templates = jsonStr.split(/(.{100})/).filter(O => O)
|
233
|
-
let filters = ['aes-256-ecb', 'aes-256-cbc', 'aes-256-cfb', 'aes-256-cfb8', 'aes-256-cfb1', 'aes-256-ofb', 'aes-256-ctr', 'aes256']
|
234
|
-
let salt = crypto.randomBytes(32).toString('hex')
|
235
|
-
let hexKey = Buffer.from(salt, 'hex')
|
236
|
-
let ivBase = salt.substring(0, 16)
|
237
|
-
let iv = ['', ivBase, ivBase, ivBase, ivBase, ivBase, ivBase, ivBase]
|
238
|
-
let filterIdx = 0
|
239
|
-
let encResults = []
|
240
|
-
encResults.push(salt)
|
241
|
-
|
242
|
-
for (var i = 0; i < templates.length; i++, filterIdx++) {
|
243
|
-
if (filterIdx == filters.length) filterIdx = 0
|
244
|
-
|
245
|
-
let cipher = crypto.createCipheriv(filters[filterIdx], hexKey, iv[filterIdx])
|
246
|
-
let encrypted = cipher.update(templates[i], 'utf8', 'hex')
|
247
|
-
encrypted += cipher.final('hex')
|
248
|
-
encResults.push(encrypted)
|
249
|
-
}
|
250
|
-
|
251
|
-
return encResults.join('h1z0q9i9x7q6')
|
252
|
-
}
|
253
|
-
}
|
254
|
-
|
255
|
-
const modelTemplate = `
|
256
|
-
{
|
257
|
-
"menu": {
|
258
|
-
"title": "{{name}}",
|
259
|
-
"name": "",
|
260
|
-
"desc": ""
|
261
|
-
},
|
262
|
-
"gql": {
|
263
|
-
"query": {
|
264
|
-
"list_func": "{{pluralCamelCase name}}",
|
265
|
-
"find_one_func":"{{camelCase name}}"
|
266
|
-
},
|
267
|
-
"mutation":{
|
268
|
-
"multiple":{
|
269
|
-
"func":"updateMultiple{{pascalCase name}}",
|
270
|
-
"type": "{{pascalCase name}}Patch"
|
271
|
-
},
|
272
|
-
"delete":{
|
273
|
-
"func":"delete{{pluralPascalCase name}}"
|
274
|
-
}
|
275
|
-
}
|
276
|
-
},
|
277
|
-
"button": [
|
278
|
-
{
|
279
|
-
"name":"export"
|
280
|
-
},
|
281
|
-
{
|
282
|
-
"name":"add"
|
283
|
-
},
|
284
|
-
{
|
285
|
-
"name":"delete"
|
286
|
-
},
|
287
|
-
{
|
288
|
-
"name":"save"
|
289
|
-
}
|
290
|
-
],
|
291
|
-
"grid_column": [
|
292
|
-
{
|
293
|
-
"type": "string",
|
294
|
-
"name": "id",
|
295
|
-
"header": "id",
|
296
|
-
"hidden": true,
|
297
|
-
"editable": false,
|
298
|
-
"mandatory": false,
|
299
|
-
"sortable": false,
|
300
|
-
"align": "left",
|
301
|
-
"width": 0,
|
302
|
-
"exportable": false
|
303
|
-
},
|
304
|
-
{{GridColumns}}
|
305
|
-
],
|
306
|
-
"grid": {
|
307
|
-
"button":[
|
308
|
-
{{HistoryButton}}
|
309
|
-
],
|
310
|
-
"option": {
|
311
|
-
"mobile_mode": "LIST",
|
312
|
-
"desk_mode": "GRID",
|
313
|
-
"use_row_checker": true,
|
314
|
-
"pages": [
|
315
|
-
20,
|
316
|
-
50,
|
317
|
-
100,
|
318
|
-
300
|
319
|
-
],
|
320
|
-
"view_mode": [
|
321
|
-
"GRID",
|
322
|
-
"LIST",
|
323
|
-
"CARD"
|
324
|
-
],
|
325
|
-
"sorters": [
|
326
|
-
{{SortColumns}}
|
327
|
-
]
|
328
|
-
},
|
329
|
-
"row": {
|
330
|
-
"multiple_select": true,
|
331
|
-
"click": "select-row-toggle"
|
332
|
-
}
|
333
|
-
},
|
334
|
-
"search": [
|
335
|
-
{{SearchColumns}}
|
336
|
-
]
|
337
|
-
}
|
338
|
-
`
|