mushroom-cli 1.2.0-alpha.2 → 1.2.0-alpha.21
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/README.md +280 -111
- package/dist/check-update.js +6 -0
- package/dist/common.js +272 -0
- package/dist/config.js +394 -0
- package/dist/docs/bootstrap-theme.min.css +6 -0
- package/dist/docs/bootstrap.min.css +6 -0
- package/dist/docs/bootstrap.min.js +7 -0
- package/{docs → dist/docs}/doc-mt.js +103 -1
- package/{docs → dist/docs}/docs.html +83 -22
- package/dist/docs/docs.v2.html +5086 -0
- package/dist/docs/docs.v2.js +1922 -0
- package/dist/docs/jquery.min.js +4 -0
- package/dist/gen/gen-api-docs-v1.js +110 -0
- package/dist/gen/gen-api-docs.js +306 -0
- package/{gen → dist/gen}/gen-csharp.js +1246 -1414
- package/{gen → dist/gen}/gen-db-docs.js +204 -222
- package/{gen → dist/gen}/gen-js-driver-tarball.js +81 -101
- package/{gen → dist/gen}/gen-js-driver.js +116 -133
- package/dist/gen/gen-ts-driver.js +596 -0
- package/{gen.js → dist/gen.js} +109 -120
- package/{help.js → dist/help.js} +53 -55
- package/dist/init/init-json.js +92 -0
- package/dist/init/init-netcore.js +30 -0
- package/dist/init.js +23 -0
- package/dist/master-file/master-file.js +185 -0
- package/dist/merge.js +70 -0
- package/dist/mr.js +77 -0
- package/dist/types.js +1 -0
- package/dist/update/tsCode.js +82 -0
- package/dist/update.js +20 -0
- package/package.json +64 -27
- package/check-update.js +0 -9
- package/common.js +0 -236
- package/config.js +0 -445
- package/gen/gen-api-docs.js +0 -125
- package/gen/gen-ts-driver.js +0 -460
- package/init/init-json.js +0 -106
- package/init/init-netcore.js +0 -32
- package/init.js +0 -28
- package/master-file/master-file.js +0 -234
- package/merge.js +0 -84
- package/mr.js +0 -82
- package/update/tsCode.js +0 -20
- package/update.js +0 -24
- /package/{docs → dist/docs}/mt-dom-1.0.js +0 -0
- /package/{docs → dist/docs}/mt.extension.js +0 -0
package/README.md
CHANGED
|
@@ -1,111 +1,280 @@
|
|
|
1
|
-
# Mushroom CLI
|
|
2
|
-
|
|
3
|
-
## Init
|
|
4
|
-
|
|
5
|
-
Init a mushroom json file
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Config gen
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
Generate
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
1
|
+
# Mushroom CLI
|
|
2
|
+
|
|
3
|
+
## Init
|
|
4
|
+
|
|
5
|
+
Init a mushroom json file
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx mushroom-cli init json ./api/SampleProject.json [silent]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Init a DotNet Core project which pre-install Mushroom Server
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx mushroom-cli init netcore [projectName]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Configure
|
|
18
|
+
|
|
19
|
+
Add the mushroom json file into mushroom-config.json
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx mushroom-cli config add ./api/yourProjectName.json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Config gen docs api
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx mushroom-cli config gen projectName docs ./wwwroot/docs.html [alias aliasName] [features file,auth,mail,driver] [roles Admin,User-Contributor]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Config gen database docs
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npx mushroom-cli config gen projectName "db-docs" ./wwwroot/db-docs.html [alias aliasName] [features file,auth,mail]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Config gen javascript driver
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx mushroom-cli config gen projectName "js-driver" ./src/api/mushroom.api.js [alias aliasName] [roles Admin,User-Contributor] [tarball tarballName]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Config gen typescript driver
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npx mushroom-cli config gen projectName "ts-driver" ./src/api/mushroom.api.ts [alias aliasName] [roles Admin,User-Contributor]
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Config gen entities for Mushroom project in CSharp and using MongoDb
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx mushroom-cli config gen projectName "c#-mongo" ./API/Generated.cs [alias aliasName]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Config gen entities for CSharp project which calls Mushroom API
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npx mushroom-cli config gen projectName "c#-driver" ./API/Generated.cs [roles Admin,User-Contributor] [alias aliasName] [access-modifier public] [features file,auth,mail]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Genarate
|
|
62
|
+
|
|
63
|
+
Generate docs api (html format)
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npx mushroom-cli gen projectName[@aliasName] docs [v1] [tmp]
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Generate database docs (html format)
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx mushroom-cli gen projectName[@aliasName] "db-docs" [tmp]
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Generate npm package (tarball file)
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx mushroom-cli gen projectName[@aliasName] "js-driver-tarball"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Generate javascript driver
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx mushroom-cli gen projectName[@aliasName] "js-driver"
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Generate typescript driver
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npx mushroom-cli gen projectName[@aliasName] "ts-driver"
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Generate entities for Mushroom project in CSharp and using MongoDb
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npx mushroom-cli gen projectName[@aliasName] "c#-mongo"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Generate entities for CSharp project which calls Mushroom API
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx mushroom-cli gen projectName[@aliasName] "c#-driver"
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Merge
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx mushroom-cli merge output-path.json
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Update
|
|
112
|
+
|
|
113
|
+
Update ts code (configuration was stored in mushroom-config.json file)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npx mushroom-cli update "ts-code"
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Update ts code (simple call)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx mushroom-cli update "ts-code" file-path.ts remote-ts-code-url
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Other
|
|
126
|
+
|
|
127
|
+
Disable checking for update:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
npx mushroom-cli parameters --no-check-update
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Version
|
|
134
|
+
|
|
135
|
+
### 1.2.0-alpha.21
|
|
136
|
+
|
|
137
|
+
Improvement:
|
|
138
|
+
|
|
139
|
+
- gen-docs
|
|
140
|
+
- generate docs for response body of custom methods
|
|
141
|
+
|
|
142
|
+
### 1.2.0-alpha.20
|
|
143
|
+
|
|
144
|
+
Improvement:
|
|
145
|
+
|
|
146
|
+
- gen-ts:
|
|
147
|
+
- generate description for fields in view
|
|
148
|
+
- gen-docs
|
|
149
|
+
- curl of custom method is missing header X-HTTP-Method-Override
|
|
150
|
+
|
|
151
|
+
Fixed bugs:
|
|
152
|
+
|
|
153
|
+
- gen csharp:
|
|
154
|
+
- wrong version in Info.cs
|
|
155
|
+
|
|
156
|
+
### 1.2.0-alpha.19
|
|
157
|
+
|
|
158
|
+
Improvement:
|
|
159
|
+
|
|
160
|
+
- gen-ts:
|
|
161
|
+
- generate type for custom methods of action
|
|
162
|
+
- generate description for fields, entities
|
|
163
|
+
|
|
164
|
+
### 1.2.0-alpha.17
|
|
165
|
+
|
|
166
|
+
Improvement:
|
|
167
|
+
|
|
168
|
+
- gen-ts: add null value for nullable field type
|
|
169
|
+
|
|
170
|
+
### 1.2.0-alpha.15
|
|
171
|
+
|
|
172
|
+
Improvement:
|
|
173
|
+
|
|
174
|
+
- gen-docs: donot use css and js files of bootstrap and jquery in CDN, copy file locally to enable to view offline
|
|
175
|
+
|
|
176
|
+
### 1.2.0-alpha.12
|
|
177
|
+
|
|
178
|
+
New:
|
|
179
|
+
|
|
180
|
+
- init netcore:
|
|
181
|
+
- Support new set-functions: `New-RandomNumber`, `New-RandomString`
|
|
182
|
+
|
|
183
|
+
### 1.2.0-alpha.11
|
|
184
|
+
|
|
185
|
+
New:
|
|
186
|
+
|
|
187
|
+
- gen-ts:
|
|
188
|
+
- export type for object fields
|
|
189
|
+
|
|
190
|
+
Improvement:
|
|
191
|
+
|
|
192
|
+
- gen-docs:
|
|
193
|
+
- allow user add and change API root url
|
|
194
|
+
- filter role list
|
|
195
|
+
- format cURL to easy to copy and paste to Postman
|
|
196
|
+
- lighten font on MacOS
|
|
197
|
+
|
|
198
|
+
### 1.2.0-alpha.10
|
|
199
|
+
|
|
200
|
+
Improvement:
|
|
201
|
+
|
|
202
|
+
- gen-docs: add default-value information of fields
|
|
203
|
+
|
|
204
|
+
### 1.2.0-alpha.9
|
|
205
|
+
|
|
206
|
+
Improvement:
|
|
207
|
+
|
|
208
|
+
- gen-docs
|
|
209
|
+
- v1.2: minify, fix bug (some fields are not excluded)
|
|
210
|
+
|
|
211
|
+
### 1.2.0-alpha.8
|
|
212
|
+
|
|
213
|
+
Improvement:
|
|
214
|
+
|
|
215
|
+
- gen-docs
|
|
216
|
+
- v1.2: deal with very big api docs
|
|
217
|
+
- v1: prerender all docs html (need more RAM, less performance)
|
|
218
|
+
|
|
219
|
+
### 1.2.0-alpha.7
|
|
220
|
+
|
|
221
|
+
New features:
|
|
222
|
+
|
|
223
|
+
- init netcore: Support some new set-functions: `ToLowerCase`, `ToUpperCase`, `Trim`, `Replace`
|
|
224
|
+
|
|
225
|
+
Changes:
|
|
226
|
+
|
|
227
|
+
- init netcore: Operating fail if unknown command or set-function found
|
|
228
|
+
|
|
229
|
+
### 1.2.0-alpha.6
|
|
230
|
+
|
|
231
|
+
New features:
|
|
232
|
+
|
|
233
|
+
- gen-ts-driver: Support offline mode
|
|
234
|
+
|
|
235
|
+
Changes:
|
|
236
|
+
|
|
237
|
+
- gen-api-docs: Improve generating api-docs
|
|
238
|
+
- gen-csharp: Generate resource classes with `partial`
|
|
239
|
+
|
|
240
|
+
### 1.2.0-alpha.5
|
|
241
|
+
|
|
242
|
+
New features:
|
|
243
|
+
|
|
244
|
+
- Improve documentation generation: view, custom action.
|
|
245
|
+
|
|
246
|
+
### 1.2.0-alpha.4
|
|
247
|
+
|
|
248
|
+
Fixed bugs:
|
|
249
|
+
|
|
250
|
+
- Generate api docs: doesn't exclude fields of object in an array
|
|
251
|
+
|
|
252
|
+
### 1.2.0-alpha.3
|
|
253
|
+
|
|
254
|
+
Fixed bugs:
|
|
255
|
+
|
|
256
|
+
- Generate wrong required field for view parameter
|
|
257
|
+
|
|
258
|
+
### 1.2.0-alpha.2
|
|
259
|
+
|
|
260
|
+
New features:
|
|
261
|
+
|
|
262
|
+
- Support merge command
|
|
263
|
+
|
|
264
|
+
### 1.2.0-alpha.1
|
|
265
|
+
|
|
266
|
+
New features:
|
|
267
|
+
|
|
268
|
+
- Support type for View result
|
|
269
|
+
|
|
270
|
+
### 1.1.1
|
|
271
|
+
|
|
272
|
+
Improvement:
|
|
273
|
+
|
|
274
|
+
- `mushroom-cli update tsCode` can read the configuration in mushroom-config.json file
|
|
275
|
+
|
|
276
|
+
### 1.1.0
|
|
277
|
+
|
|
278
|
+
Support MushroomServer 0.2.25.4 or later
|
|
279
|
+
|
|
280
|
+
Support mushroomjs 1.1.0 or later
|
package/dist/common.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import readlineSync from 'readline-sync';
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
export function getPackageVersion() {
|
|
8
|
+
try {
|
|
9
|
+
const content = fs.readFileSync(path.join(__dirname, '../package.json')).toString();
|
|
10
|
+
const pkg = JSON.parse(content);
|
|
11
|
+
return pkg.version;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return '<!unable to get package version>';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function ensureFolder(path, isFolder) {
|
|
18
|
+
const index = path.lastIndexOf('/');
|
|
19
|
+
if (!isFolder && index <= 0) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!isFolder)
|
|
23
|
+
path = path.substring(0, index);
|
|
24
|
+
if (path === '.' || path === '..')
|
|
25
|
+
return;
|
|
26
|
+
if (!fs.existsSync(path)) {
|
|
27
|
+
fs.mkdirSync(path, { recursive: true, mode: 0o755 });
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function getRootUrl(projectApiConfiguration) {
|
|
31
|
+
return projectApiConfiguration.codeHint && projectApiConfiguration.codeHint.rootUrl
|
|
32
|
+
? projectApiConfiguration.codeHint.rootUrl
|
|
33
|
+
: projectApiConfiguration.rootUrl;
|
|
34
|
+
}
|
|
35
|
+
export function getEntities(projectApiConfiguration, roles, getAll) {
|
|
36
|
+
if (!projectApiConfiguration || !projectApiConfiguration.entities || !Array.isArray(projectApiConfiguration.entities))
|
|
37
|
+
return {};
|
|
38
|
+
const entities = {};
|
|
39
|
+
projectApiConfiguration.entities.forEach((entity) => {
|
|
40
|
+
if (entity.disabled)
|
|
41
|
+
return;
|
|
42
|
+
if (getAll) {
|
|
43
|
+
entities[entity.name] = entity;
|
|
44
|
+
entity.storageName = entity.storageName ? entity.storageName : entity.name;
|
|
45
|
+
if (!roles || !roles.length)
|
|
46
|
+
roles = ['*'];
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
for (const actionName in entity.actions) {
|
|
50
|
+
entity.actions[actionName].forEach((action) => {
|
|
51
|
+
var _a;
|
|
52
|
+
if (!action.grant || !action.enabled || (action.codeHint && action.codeHint.disabled))
|
|
53
|
+
return;
|
|
54
|
+
let allow = roles?.includes('*') || action.grant === '*';
|
|
55
|
+
if (!allow) {
|
|
56
|
+
action.grant = action.grant.split('|').map(roleGroup => {
|
|
57
|
+
if (!roleGroup)
|
|
58
|
+
return null;
|
|
59
|
+
const ok = roleGroup.split('+').every(grantedRole => roles?.includes(grantedRole));
|
|
60
|
+
return ok ? roleGroup : null;
|
|
61
|
+
}).filter(roleGroup => roleGroup).join('|');
|
|
62
|
+
if (!action.grant)
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (!(entity.name in entities)) {
|
|
66
|
+
entities[entity.name] = {
|
|
67
|
+
name: entity.name,
|
|
68
|
+
description: entity.description,
|
|
69
|
+
storageName: entity.storageName ? entity.storageName : entity.name,
|
|
70
|
+
fields: entity.fields,
|
|
71
|
+
views: {},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const actions = ((_a = entities[entity.name]).actions ?? (_a.actions = {}));
|
|
75
|
+
actions[actionName] ?? (actions[actionName] = []);
|
|
76
|
+
actions[actionName].push(action);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
for (const viewName in entity.views) {
|
|
80
|
+
entity.views[viewName].forEach((view) => {
|
|
81
|
+
var _a;
|
|
82
|
+
if (!view.grant || !view.enabled)
|
|
83
|
+
return;
|
|
84
|
+
let allow = roles?.indexOf('*') !== -1 || view.grant === '*';
|
|
85
|
+
if (!allow) {
|
|
86
|
+
view.grant = view.grant.split('|').map(roleGroup => {
|
|
87
|
+
if (!roleGroup)
|
|
88
|
+
return null;
|
|
89
|
+
const ok = roleGroup.split('+').every(grantedRole => roles?.includes(grantedRole));
|
|
90
|
+
return ok ? roleGroup : null;
|
|
91
|
+
}).filter(roleGroup => roleGroup).join('|');
|
|
92
|
+
if (!view.grant)
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!(entity.name in entities)) {
|
|
96
|
+
entities[entity.name] = {
|
|
97
|
+
name: entity.name,
|
|
98
|
+
description: entity.description,
|
|
99
|
+
storageName: entity.storageName ? entity.storageName : entity.name,
|
|
100
|
+
fields: entity.fields,
|
|
101
|
+
actions: {},
|
|
102
|
+
views: {},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const views = ((_a = entities[entity.name]).views ?? (_a.views = {}));
|
|
106
|
+
views[viewName] ?? (views[viewName] = []);
|
|
107
|
+
views[viewName].push(view);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (entity.name in entities) {
|
|
111
|
+
entities[entity.name].features = entity.features;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
return entities;
|
|
115
|
+
}
|
|
116
|
+
export function filterRoles(roleList, allowRoleList) {
|
|
117
|
+
const roles = !allowRoleList || allowRoleList.includes('*')
|
|
118
|
+
? [...roleList]
|
|
119
|
+
: roleList.filter((role) => allowRoleList.includes(role.name));
|
|
120
|
+
roles.push({
|
|
121
|
+
name: '[Mọi người dùng]',
|
|
122
|
+
description: 'Tất cả người dùng (kể cả chưa đăng nhập)',
|
|
123
|
+
});
|
|
124
|
+
return roles;
|
|
125
|
+
}
|
|
126
|
+
export function processTemplate(basePath, templatePath) {
|
|
127
|
+
const templateJsonContent = fs.readFileSync(path.join(basePath, templatePath)).toString();
|
|
128
|
+
const template = JSON.parse(templateJsonContent);
|
|
129
|
+
if (template && typeof template !== 'object') {
|
|
130
|
+
throw new TypeError(`Invalid template file ${templatePath}`);
|
|
131
|
+
}
|
|
132
|
+
const commands = template.steps;
|
|
133
|
+
if (!Array.isArray(commands)) {
|
|
134
|
+
throw new TypeError(`Invalid template file ${templatePath}`);
|
|
135
|
+
}
|
|
136
|
+
const variables = {};
|
|
137
|
+
commands.forEach((command) => processCommand(command, basePath, variables));
|
|
138
|
+
return variables;
|
|
139
|
+
}
|
|
140
|
+
function processCommand(command, basePath, variables) {
|
|
141
|
+
const commandName = command.command;
|
|
142
|
+
switch (commandName) {
|
|
143
|
+
case 'input':
|
|
144
|
+
processInputCommand(command, variables);
|
|
145
|
+
return;
|
|
146
|
+
case 'set':
|
|
147
|
+
processSetCommand(command, variables);
|
|
148
|
+
return;
|
|
149
|
+
case 'rename':
|
|
150
|
+
processRenameCommand(command, basePath, variables);
|
|
151
|
+
return;
|
|
152
|
+
case 'delete':
|
|
153
|
+
processDeleteCommand(command, basePath, variables);
|
|
154
|
+
return;
|
|
155
|
+
case 'replace':
|
|
156
|
+
processReplaceCommand(command, basePath, variables);
|
|
157
|
+
return;
|
|
158
|
+
default:
|
|
159
|
+
throw new Error(`Unknown command: ${commandName}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function processInputCommand(command, variables) {
|
|
163
|
+
const value = readlineSync.question(command.message ?? '');
|
|
164
|
+
if (command.validation) {
|
|
165
|
+
if (command.validation.required) {
|
|
166
|
+
if (value === '')
|
|
167
|
+
throw new TypeError(`${command.variable} is required`);
|
|
168
|
+
}
|
|
169
|
+
if (command.validation.pattern) {
|
|
170
|
+
if (!new RegExp(command.validation.pattern).test(value))
|
|
171
|
+
throw new Error(`${value} is not valid`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
variables[command.variable] = value;
|
|
175
|
+
}
|
|
176
|
+
function processSetCommand(command, variables) {
|
|
177
|
+
switch (command['function']) {
|
|
178
|
+
case 'New-GUID':
|
|
179
|
+
processSetNewGuidCommand(command.variable, variables);
|
|
180
|
+
break;
|
|
181
|
+
case 'New-RandomNumber':
|
|
182
|
+
processSetNewRandomNumberCommand(command.variable, variables, command.min, command.max);
|
|
183
|
+
break;
|
|
184
|
+
case 'New-RandomString':
|
|
185
|
+
processSetNewRandomStringCommand(command.variable, variables, command.length, command.characterPool);
|
|
186
|
+
break;
|
|
187
|
+
case 'ToLowerCase':
|
|
188
|
+
toLowerCommand(command.variable, variables, command.input);
|
|
189
|
+
break;
|
|
190
|
+
case 'ToUpperCase':
|
|
191
|
+
toUpperCaseCommand(command.variable, variables, command.input);
|
|
192
|
+
break;
|
|
193
|
+
case 'Trim':
|
|
194
|
+
trimCommand(command.variable, variables, command.input);
|
|
195
|
+
break;
|
|
196
|
+
case 'Replace':
|
|
197
|
+
replaceCommand(command.variable, variables, command.input, command.replacement, command.pattern, command.mode);
|
|
198
|
+
break;
|
|
199
|
+
default:
|
|
200
|
+
throw new Error(`Unknown set-command: ${command['function']}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function processSetNewGuidCommand(variable, variables) {
|
|
204
|
+
variables[variable] = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
205
|
+
.replace(/[xy]/g, (c) => {
|
|
206
|
+
const r = (Math.random() * 16) | 0;
|
|
207
|
+
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
208
|
+
return v.toString(16);
|
|
209
|
+
})
|
|
210
|
+
.toUpperCase();
|
|
211
|
+
}
|
|
212
|
+
function processSetNewRandomNumberCommand(variable, variables, min = 0, max = (1 << 30) * 4) {
|
|
213
|
+
variables[variable] = Math.floor(min + Math.random() * (max - min)).toString();
|
|
214
|
+
}
|
|
215
|
+
function processSetNewRandomStringCommand(variable, variables, length, characterPool = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM') {
|
|
216
|
+
let result = '';
|
|
217
|
+
for (let i = 0; i < length; i++) {
|
|
218
|
+
result += characterPool.charAt(Math.floor(Math.random() * characterPool.length));
|
|
219
|
+
}
|
|
220
|
+
variables[variable] = result;
|
|
221
|
+
}
|
|
222
|
+
function toLowerCommand(variable, variables, input) {
|
|
223
|
+
variables[variable] = variables[input].toLowerCase();
|
|
224
|
+
}
|
|
225
|
+
function toUpperCaseCommand(variable, variables, input) {
|
|
226
|
+
variables[variable] = variables[input].toUpperCase();
|
|
227
|
+
}
|
|
228
|
+
function trimCommand(variable, variables, input) {
|
|
229
|
+
variables[variable] = variables[input].trim();
|
|
230
|
+
}
|
|
231
|
+
function replaceCommand(variable, variables, input, replacement, pattern, mode) {
|
|
232
|
+
const regex = new RegExp(pattern, mode);
|
|
233
|
+
variables[variable] = variables[input].replace(regex, replacement);
|
|
234
|
+
}
|
|
235
|
+
function processRenameCommand(command, basePath, variables) {
|
|
236
|
+
const input = replaceVariables(command.input, variables);
|
|
237
|
+
const output = replaceVariables(command.output, variables);
|
|
238
|
+
fs.renameSync(path.join(basePath, input), path.join(basePath, output));
|
|
239
|
+
}
|
|
240
|
+
function processDeleteCommand(command, basePath, variables) {
|
|
241
|
+
const input = replaceVariables(command.input, variables);
|
|
242
|
+
const deletedPath = path.join(basePath, input);
|
|
243
|
+
if (fs.lstatSync(deletedPath).isDirectory()) {
|
|
244
|
+
fs.rmSync(deletedPath, { recursive: true, force: true });
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
fs.rmSync(deletedPath, { force: true });
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function processReplaceCommand(command, basePath, variables) {
|
|
251
|
+
const files = command.input;
|
|
252
|
+
const pattern = new RegExp(command.pattern ?? '', 'g');
|
|
253
|
+
const replacement = replaceVariables(command.replacement ?? '', variables);
|
|
254
|
+
files.forEach((file) => {
|
|
255
|
+
const filePath = replaceVariables(file, variables);
|
|
256
|
+
let content = fs.readFileSync(path.join(basePath, filePath)).toString();
|
|
257
|
+
content = content.replace(pattern, () => replacement);
|
|
258
|
+
fs.writeFileSync(path.join(basePath, filePath), content);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
function replaceVariables(str, variables) {
|
|
262
|
+
return str.replace(/\$\{(\w+)\}/g, (_, varName) => variables[varName] ?? '');
|
|
263
|
+
}
|
|
264
|
+
export function logInfo(message, ...parameters) {
|
|
265
|
+
console.log(message, ...parameters);
|
|
266
|
+
}
|
|
267
|
+
export function logWarning(message, ...parameters) {
|
|
268
|
+
console.warn(message, ...parameters);
|
|
269
|
+
}
|
|
270
|
+
export function logError(message, ...parameters) {
|
|
271
|
+
console.error(message, ...parameters);
|
|
272
|
+
}
|