mushroom-cli 1.2.8 → 2.0.0-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.
- package/README.md +52 -18
- package/dist/common.js +0 -143
- package/dist/config.js +0 -7
- package/dist/docs/docs.html +2 -2
- package/dist/gen/csharp/extEvents.js +195 -0
- package/dist/gen/gen-api-docs.js +51 -35
- package/dist/gen/gen-csharp.js +188 -421
- package/dist/gen/gen-list-api.js +4 -4
- package/dist/gen.js +4 -9
- package/dist/help.js +5 -5
- package/dist/init/init-netcore.js +26 -5
- package/dist/init/netcore/templateProcessor.js +182 -0
- package/package.json +8 -15
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Mushroom CLI
|
|
2
2
|
|
|
3
|
+
> In the examples below, `[...]` marks an optional argument and `|` separates alternatives. They are notation, not
|
|
4
|
+
> characters to type. Quote any argument containing spaces, for example
|
|
5
|
+
> `npx mushroom-cli config add "./my api/project.json"`.
|
|
6
|
+
|
|
3
7
|
## Init
|
|
4
8
|
|
|
5
9
|
Init a mushroom json file
|
|
@@ -8,10 +12,10 @@ Init a mushroom json file
|
|
|
8
12
|
npx mushroom-cli init json ./api/SampleProject.json [silent]
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
Init a DotNet
|
|
15
|
+
Init a DotNet project
|
|
12
16
|
|
|
13
17
|
```bash
|
|
14
|
-
npx mushroom-cli init netcore [projectName]
|
|
18
|
+
npx mushroom-cli init netcore [projectName] [--version latest|alpha|0.2|0.3]
|
|
15
19
|
```
|
|
16
20
|
|
|
17
21
|
## Configure
|
|
@@ -31,19 +35,19 @@ npx mushroom-cli config gen projectName docs ./wwwroot/docs.html [alias aliasNam
|
|
|
31
35
|
Config gen database docs
|
|
32
36
|
|
|
33
37
|
```bash
|
|
34
|
-
npx mushroom-cli config gen projectName
|
|
38
|
+
npx mushroom-cli config gen projectName db-docs ./wwwroot/db-docs.html [alias aliasName] [features file,auth,mail]
|
|
35
39
|
```
|
|
36
40
|
|
|
37
41
|
Config gen javascript driver
|
|
38
42
|
|
|
39
43
|
```bash
|
|
40
|
-
npx mushroom-cli config gen projectName
|
|
44
|
+
npx mushroom-cli config gen projectName js-driver ./src/api/mushroom.api.js [alias aliasName] [roles Admin,User-Contributor]
|
|
41
45
|
```
|
|
42
46
|
|
|
43
47
|
Config gen typescript driver
|
|
44
48
|
|
|
45
49
|
```bash
|
|
46
|
-
npx mushroom-cli config gen projectName
|
|
50
|
+
npx mushroom-cli config gen projectName ts-driver ./src/api/mushroom.api.ts [alias aliasName] [roles Admin,User-Contributor]
|
|
47
51
|
```
|
|
48
52
|
|
|
49
53
|
Config gen entities for Mushroom project in CSharp and using MongoDb
|
|
@@ -58,36 +62,30 @@ Config gen entities for CSharp project which calls Mushroom API
|
|
|
58
62
|
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
63
|
```
|
|
60
64
|
|
|
61
|
-
##
|
|
65
|
+
## Generate
|
|
62
66
|
|
|
63
67
|
Generate docs api (html format)
|
|
64
68
|
|
|
65
69
|
```bash
|
|
66
|
-
npx mushroom-cli gen projectName[@aliasName] docs [
|
|
70
|
+
npx mushroom-cli gen projectName[@aliasName] docs [tmp]
|
|
67
71
|
```
|
|
68
72
|
|
|
69
73
|
Generate database docs (html format)
|
|
70
74
|
|
|
71
75
|
```bash
|
|
72
|
-
npx mushroom-cli gen projectName[@aliasName]
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Generate npm package (tarball file)
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
npx mushroom-cli gen projectName[@aliasName] "js-driver-tarball"
|
|
76
|
+
npx mushroom-cli gen projectName[@aliasName] db-docs [tmp]
|
|
79
77
|
```
|
|
80
78
|
|
|
81
79
|
Generate javascript driver
|
|
82
80
|
|
|
83
81
|
```bash
|
|
84
|
-
npx mushroom-cli gen projectName[@aliasName]
|
|
82
|
+
npx mushroom-cli gen projectName[@aliasName] js-driver
|
|
85
83
|
```
|
|
86
84
|
|
|
87
85
|
Generate typescript driver
|
|
88
86
|
|
|
89
87
|
```bash
|
|
90
|
-
npx mushroom-cli gen projectName[@aliasName]
|
|
88
|
+
npx mushroom-cli gen projectName[@aliasName] ts-driver
|
|
91
89
|
```
|
|
92
90
|
|
|
93
91
|
Generate entities for Mushroom project in CSharp and using MongoDb
|
|
@@ -113,13 +111,13 @@ npx mushroom-cli merge output-path.json
|
|
|
113
111
|
Update ts code (configuration was stored in mushroom-config.json file)
|
|
114
112
|
|
|
115
113
|
```bash
|
|
116
|
-
npx mushroom-cli update
|
|
114
|
+
npx mushroom-cli update ts-code
|
|
117
115
|
```
|
|
118
116
|
|
|
119
117
|
Update ts code (simple call)
|
|
120
118
|
|
|
121
119
|
```bash
|
|
122
|
-
npx mushroom-cli update
|
|
120
|
+
npx mushroom-cli update ts-code file-path.ts remote-ts-code-url
|
|
123
121
|
```
|
|
124
122
|
|
|
125
123
|
## Other
|
|
@@ -132,6 +130,42 @@ npx mushroom-cli parameters --no-check-update
|
|
|
132
130
|
|
|
133
131
|
## Version
|
|
134
132
|
|
|
133
|
+
### 2.0.0-alpha.0
|
|
134
|
+
|
|
135
|
+
Breaking changes:
|
|
136
|
+
|
|
137
|
+
- gen docs: remove the docs engine v1. The `v1` parameter is now ignored with a warning and the v1.2 engine is always
|
|
138
|
+
used
|
|
139
|
+
- gen js-driver: remove the `js-driver-tarball` command, the `tarball tarballName` option of `config gen js-driver`
|
|
140
|
+
and the `jsDriver.alias.*.tarballName` field in mushroom-config.json
|
|
141
|
+
- gen c#-mongo: generated code now requires Mushroom Server 0.3 or higher
|
|
142
|
+
- require Node.js `>=14.13.1`
|
|
143
|
+
|
|
144
|
+
New features:
|
|
145
|
+
|
|
146
|
+
- init netcore: `npx mushroom-cli init netcore [--version 0.2|0.3|latest|alpha]` to select the template branch
|
|
147
|
+
- init netcore: the `replace` step accepts wildcards in the file name, for example `./api/*.json` or
|
|
148
|
+
`./api/dulich-*.json`, and resolves them recursively including sub-folders
|
|
149
|
+
- gen c#-mongo: support `routes` in the master file (`path`, `pathMode`, `caseInsensitive`, `httpMethod`, `grant`,
|
|
150
|
+
`deny`, `logRetentionMode`, `delegator`, `codeHint`)
|
|
151
|
+
- gen c#-mongo: support `extensions` in the master file (`startup`, `config`, `ensureIndex`, `routes`) and generate
|
|
152
|
+
the matching extension event handlers
|
|
153
|
+
- gen c#-mongo: new registration signatures `RegisterJob`, `RegisterBeforeEvent`, `RegisterAfterEvent`,
|
|
154
|
+
`RegisterCustomLoginAsyncHandler`, `RegisterGetAuthLogInfoAsyncHandler`, `RegisterLoginSuccessHandler`,
|
|
155
|
+
`RegisterSendCodeItemHandler`, `RegisterCustomVnTextBuilderMethod`
|
|
156
|
+
|
|
157
|
+
Improvement/Changes:
|
|
158
|
+
|
|
159
|
+
- gen docs: inline `bootstrap.min.css`, `bootstrap-theme.min.css`, `bootstrap.min.js` and `jquery.min.js` into the
|
|
160
|
+
html. The generated docs is now a single self-contained file and no static file is copied next to it
|
|
161
|
+
- gen docs: build the whole document in memory and write it once, about 4 times faster
|
|
162
|
+
- gen c#-mongo, gen c#-driver: escape descriptions for XML docs comments
|
|
163
|
+
- init netcore: clone the template with `--depth 1`
|
|
164
|
+
- replace `minify` with `html-minifier-terser` and use `open` 8: installing the CLI drops from 84 packages (75 MB) to
|
|
165
|
+
36 packages (20 MB) and works on Node.js 14 again
|
|
166
|
+
- the `only-allow npm` check moved from `preinstall` to `prepare` so it no longer runs when the CLI is installed as a
|
|
167
|
+
dependency
|
|
168
|
+
|
|
135
169
|
### 1.2.8
|
|
136
170
|
|
|
137
171
|
Improvement
|
package/dist/common.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import readlineSync from 'readline-sync';
|
|
5
4
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
5
|
const __dirname = path.dirname(__filename);
|
|
7
6
|
export function getPackageVersion() {
|
|
@@ -131,148 +130,6 @@ export function filterRoles(roleList, allowRoleList) {
|
|
|
131
130
|
});
|
|
132
131
|
return roles;
|
|
133
132
|
}
|
|
134
|
-
export function processTemplate(basePath, templatePath) {
|
|
135
|
-
const templateJsonContent = fs.readFileSync(path.join(basePath, templatePath)).toString();
|
|
136
|
-
const template = JSON.parse(templateJsonContent);
|
|
137
|
-
if (template && typeof template !== 'object') {
|
|
138
|
-
throw new TypeError(`Invalid template file ${templatePath}`);
|
|
139
|
-
}
|
|
140
|
-
const commands = template.steps;
|
|
141
|
-
if (!Array.isArray(commands)) {
|
|
142
|
-
throw new TypeError(`Invalid template file ${templatePath}`);
|
|
143
|
-
}
|
|
144
|
-
const variables = {};
|
|
145
|
-
commands.forEach((command) => processCommand(command, basePath, variables));
|
|
146
|
-
return variables;
|
|
147
|
-
}
|
|
148
|
-
function processCommand(command, basePath, variables) {
|
|
149
|
-
const commandName = command.command;
|
|
150
|
-
switch (commandName) {
|
|
151
|
-
case 'input':
|
|
152
|
-
processInputCommand(command, variables);
|
|
153
|
-
return;
|
|
154
|
-
case 'set':
|
|
155
|
-
processSetCommand(command, variables);
|
|
156
|
-
return;
|
|
157
|
-
case 'rename':
|
|
158
|
-
processRenameCommand(command, basePath, variables);
|
|
159
|
-
return;
|
|
160
|
-
case 'delete':
|
|
161
|
-
processDeleteCommand(command, basePath, variables);
|
|
162
|
-
return;
|
|
163
|
-
case 'replace':
|
|
164
|
-
processReplaceCommand(command, basePath, variables);
|
|
165
|
-
return;
|
|
166
|
-
default:
|
|
167
|
-
throw new Error(`Unknown command: ${commandName}`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
function processInputCommand(command, variables) {
|
|
171
|
-
const value = readlineSync.question(command.message ?? '');
|
|
172
|
-
if (command.validation) {
|
|
173
|
-
if (command.validation.required) {
|
|
174
|
-
if (value === '')
|
|
175
|
-
throw new TypeError(`${command.variable} is required`);
|
|
176
|
-
}
|
|
177
|
-
if (command.validation.pattern) {
|
|
178
|
-
if (!new RegExp(command.validation.pattern).test(value))
|
|
179
|
-
throw new Error(`${value} is not valid`);
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
variables[command.variable] = value;
|
|
183
|
-
}
|
|
184
|
-
function processSetCommand(command, variables) {
|
|
185
|
-
switch (command['function']) {
|
|
186
|
-
case 'New-GUID':
|
|
187
|
-
processSetNewGuidCommand(command.variable, variables);
|
|
188
|
-
break;
|
|
189
|
-
case 'New-RandomNumber':
|
|
190
|
-
processSetNewRandomNumberCommand(command.variable, variables, command.min, command.max);
|
|
191
|
-
break;
|
|
192
|
-
case 'New-RandomString':
|
|
193
|
-
processSetNewRandomStringCommand(command.variable, variables, command.length, command.characterPool);
|
|
194
|
-
break;
|
|
195
|
-
case 'ToLowerCase':
|
|
196
|
-
toLowerCommand(command.variable, variables, command.input);
|
|
197
|
-
break;
|
|
198
|
-
case 'ToUpperCase':
|
|
199
|
-
toUpperCaseCommand(command.variable, variables, command.input);
|
|
200
|
-
break;
|
|
201
|
-
case 'Trim':
|
|
202
|
-
trimCommand(command.variable, variables, command.input);
|
|
203
|
-
break;
|
|
204
|
-
case 'Replace':
|
|
205
|
-
replaceCommand(command.variable, variables, command.input, command.replacement, command.pattern, command.mode);
|
|
206
|
-
break;
|
|
207
|
-
default:
|
|
208
|
-
throw new Error(`Unknown set-command: ${command['function']}`);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
function processSetNewGuidCommand(variable, variables) {
|
|
212
|
-
variables[variable] = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
|
|
213
|
-
.replace(/[xy]/g, (c) => {
|
|
214
|
-
const r = (Math.random() * 16) | 0;
|
|
215
|
-
const v = c == 'x' ? r : (r & 0x3) | 0x8;
|
|
216
|
-
return v.toString(16);
|
|
217
|
-
})
|
|
218
|
-
.toUpperCase();
|
|
219
|
-
}
|
|
220
|
-
function processSetNewRandomNumberCommand(variable, variables, min = 0, max = (1 << 30) * 4) {
|
|
221
|
-
variables[variable] = Math.floor(min + Math.random() * (max - min)).toString();
|
|
222
|
-
}
|
|
223
|
-
function processSetNewRandomStringCommand(variable, variables, length, characterPool = '1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM') {
|
|
224
|
-
let result = '';
|
|
225
|
-
for (let i = 0; i < length; i++) {
|
|
226
|
-
result += characterPool.charAt(Math.floor(Math.random() * characterPool.length));
|
|
227
|
-
}
|
|
228
|
-
variables[variable] = result;
|
|
229
|
-
}
|
|
230
|
-
function toLowerCommand(variable, variables, input) {
|
|
231
|
-
variables[variable] = variables[input].toLowerCase();
|
|
232
|
-
}
|
|
233
|
-
function toUpperCaseCommand(variable, variables, input) {
|
|
234
|
-
variables[variable] = variables[input].toUpperCase();
|
|
235
|
-
}
|
|
236
|
-
function trimCommand(variable, variables, input) {
|
|
237
|
-
variables[variable] = variables[input].trim();
|
|
238
|
-
}
|
|
239
|
-
function replaceCommand(variable, variables, input, replacement, pattern, mode) {
|
|
240
|
-
const regex = new RegExp(pattern, mode);
|
|
241
|
-
variables[variable] = variables[input].replace(regex, replacement);
|
|
242
|
-
}
|
|
243
|
-
function processRenameCommand(command, basePath, variables) {
|
|
244
|
-
const input = replaceVariables(command.input, variables);
|
|
245
|
-
const output = replaceVariables(command.output, variables);
|
|
246
|
-
fs.renameSync(path.join(basePath, input), path.join(basePath, output));
|
|
247
|
-
}
|
|
248
|
-
function processDeleteCommand(command, basePath, variables) {
|
|
249
|
-
const input = replaceVariables(command.input, variables);
|
|
250
|
-
const deletedPath = path.join(basePath, input);
|
|
251
|
-
if (fs.lstatSync(deletedPath).isDirectory()) {
|
|
252
|
-
fs.rmSync(deletedPath, { recursive: true, force: true });
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
fs.rmSync(deletedPath, { force: true });
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
function processReplaceCommand(command, basePath, variables) {
|
|
259
|
-
const files = command.input;
|
|
260
|
-
const pattern = new RegExp(command.pattern ?? '', 'g');
|
|
261
|
-
const replacement = replaceVariables(command.replacement ?? '', variables);
|
|
262
|
-
files.forEach((file) => {
|
|
263
|
-
const filePath = path.join(basePath, replaceVariables(file, variables));
|
|
264
|
-
if (!fs.existsSync(filePath)) {
|
|
265
|
-
console.warn(`File ${file} does not exist, skipping...`);
|
|
266
|
-
return;
|
|
267
|
-
}
|
|
268
|
-
let content = fs.readFileSync(filePath).toString();
|
|
269
|
-
content = content.replace(pattern, () => replacement);
|
|
270
|
-
fs.writeFileSync(filePath, content);
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
function replaceVariables(str, variables) {
|
|
274
|
-
return str.replace(/\$\{(\w+)\}/g, (_, varName) => variables[varName] ?? '');
|
|
275
|
-
}
|
|
276
133
|
export function logInfo(message, ...parameters) {
|
|
277
134
|
console.log(message, ...parameters);
|
|
278
135
|
}
|
package/dist/config.js
CHANGED
|
@@ -170,13 +170,6 @@ function configGenJavascriptDriver(args, mushroomConfig, projectName) {
|
|
|
170
170
|
alias = strAlias;
|
|
171
171
|
break;
|
|
172
172
|
}
|
|
173
|
-
case 'tarball': {
|
|
174
|
-
index++;
|
|
175
|
-
const strTarball = args[index];
|
|
176
|
-
if (strTarball)
|
|
177
|
-
parameters.tarballName = strTarball;
|
|
178
|
-
break;
|
|
179
|
-
}
|
|
180
173
|
}
|
|
181
174
|
index++;
|
|
182
175
|
}
|
package/dist/docs/docs.html
CHANGED
|
@@ -1310,8 +1310,8 @@
|
|
|
1310
1310
|
// fieldName: value
|
|
1311
1311
|
};
|
|
1312
1312
|
try {
|
|
1313
|
-
const
|
|
1314
|
-
console.log("Thêm mới thành công, new id: %o",
|
|
1313
|
+
const response = await mushroom.<span data-mt-attr='{"text": "$entityName"}'></span>.createAsync(<span data-mt-attr='{"text": "$entityName"}'></span>_object);
|
|
1314
|
+
console.log("Thêm mới thành công, new id: %o", response.result);
|
|
1315
1315
|
} catch (error) {
|
|
1316
1316
|
console.error("Có lỗi: %o", error);
|
|
1317
1317
|
}</pre>
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
const extEvents = {
|
|
2
|
+
auth: {
|
|
3
|
+
'Events.Login.Before': {
|
|
4
|
+
type: 'Before',
|
|
5
|
+
},
|
|
6
|
+
'Events.Login.Validate.Before': {
|
|
7
|
+
type: 'Before',
|
|
8
|
+
},
|
|
9
|
+
'Events.Login.Validate.After': {
|
|
10
|
+
type: 'After',
|
|
11
|
+
},
|
|
12
|
+
'Events.Login.CheckLocking.Before': {
|
|
13
|
+
type: 'Before',
|
|
14
|
+
},
|
|
15
|
+
'Events.Login.CheckLocking.After': {
|
|
16
|
+
type: 'After',
|
|
17
|
+
data: 'Mushroom.Extensions.DefaultAuth.UserLock',
|
|
18
|
+
},
|
|
19
|
+
CustomLoginAsyncFunc: {
|
|
20
|
+
type: 'Func',
|
|
21
|
+
registerFunc: 'RegisterCustomLoginAsyncHandler',
|
|
22
|
+
},
|
|
23
|
+
'Events.Login.LogAuth.Before': {
|
|
24
|
+
type: 'Before',
|
|
25
|
+
},
|
|
26
|
+
GetAuthLogInfoAsyncFunc: {
|
|
27
|
+
type: 'Func',
|
|
28
|
+
registerFunc: 'RegisterGetAuthLogInfoAsyncHandler',
|
|
29
|
+
},
|
|
30
|
+
'Events.Login.LogAuth.After': {
|
|
31
|
+
type: 'After',
|
|
32
|
+
data: 'Mushroom.Extensions.DefaultAuth.UserAuthLogResult',
|
|
33
|
+
},
|
|
34
|
+
'Events.Login.LoginFail': {
|
|
35
|
+
type: 'After',
|
|
36
|
+
},
|
|
37
|
+
'Events.Login.LoginSuccess': {
|
|
38
|
+
type: 'Event',
|
|
39
|
+
registerFunc: 'RegisterLoginSuccessHandler',
|
|
40
|
+
},
|
|
41
|
+
'Events.Login.After': {
|
|
42
|
+
type: 'After',
|
|
43
|
+
data: 'string',
|
|
44
|
+
},
|
|
45
|
+
'Events.Logout.Before': {
|
|
46
|
+
type: 'Before',
|
|
47
|
+
},
|
|
48
|
+
'Events.Logout.After': {
|
|
49
|
+
type: 'After',
|
|
50
|
+
data: 'bool',
|
|
51
|
+
},
|
|
52
|
+
'Events.Status.Before': {
|
|
53
|
+
type: 'Before',
|
|
54
|
+
},
|
|
55
|
+
'Events.Status.After': {
|
|
56
|
+
type: 'After',
|
|
57
|
+
data: 'bool',
|
|
58
|
+
},
|
|
59
|
+
'Events.Me.Before': {
|
|
60
|
+
type: 'Before',
|
|
61
|
+
},
|
|
62
|
+
'Events.Me.After': {
|
|
63
|
+
type: 'After',
|
|
64
|
+
data: 'Mushroom.Extensions.DefaultAuth.User',
|
|
65
|
+
},
|
|
66
|
+
'Events.Register.Before': {
|
|
67
|
+
type: 'Before',
|
|
68
|
+
},
|
|
69
|
+
SendCodeItemFunc: {
|
|
70
|
+
type: 'Func',
|
|
71
|
+
registerFunc: 'RegisterSendCodeItemHandler',
|
|
72
|
+
},
|
|
73
|
+
'Events.Register.After': {
|
|
74
|
+
type: 'After',
|
|
75
|
+
data: 'Mushroom.Extensions.DefaultAuth.User',
|
|
76
|
+
},
|
|
77
|
+
'Events.Activate.Before': {
|
|
78
|
+
type: 'Before',
|
|
79
|
+
},
|
|
80
|
+
'Events.Activate.After': {
|
|
81
|
+
type: 'After',
|
|
82
|
+
data: 'Mushroom.Extensions.DefaultAuth.User',
|
|
83
|
+
},
|
|
84
|
+
'Events.RecoverPassword.Before': {
|
|
85
|
+
type: 'Before',
|
|
86
|
+
},
|
|
87
|
+
'Events.RecoverPassword.After': {
|
|
88
|
+
type: 'After',
|
|
89
|
+
data: 'Mushroom.Extensions.DefaultAuth.User',
|
|
90
|
+
},
|
|
91
|
+
'Events.ResetPassword.Before': {
|
|
92
|
+
type: 'Before',
|
|
93
|
+
},
|
|
94
|
+
'Events.ResetPassword.After': {
|
|
95
|
+
type: 'After',
|
|
96
|
+
data: 'Mushroom.Extensions.DefaultAuth.User',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
file: {
|
|
100
|
+
'Events.Upload.Before': {
|
|
101
|
+
type: 'Before',
|
|
102
|
+
},
|
|
103
|
+
'Events.Upload.After': {
|
|
104
|
+
type: 'After',
|
|
105
|
+
},
|
|
106
|
+
'Events.Thumb.Before': {
|
|
107
|
+
type: 'Before',
|
|
108
|
+
},
|
|
109
|
+
'Events.Thumb.After': {
|
|
110
|
+
type: 'After',
|
|
111
|
+
},
|
|
112
|
+
'Events.Download.Before': {
|
|
113
|
+
type: 'Before',
|
|
114
|
+
},
|
|
115
|
+
'Events.Download.After': {
|
|
116
|
+
type: 'After',
|
|
117
|
+
},
|
|
118
|
+
'Events.Zip.Before': {
|
|
119
|
+
type: 'Before',
|
|
120
|
+
},
|
|
121
|
+
'Events.Zip.After': {
|
|
122
|
+
type: 'After',
|
|
123
|
+
},
|
|
124
|
+
LimitFileUploadSizeFunc: {
|
|
125
|
+
type: 'Func',
|
|
126
|
+
data: 'System.Threading.Tasks.Task<long?>',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
mail: {
|
|
130
|
+
AuthorizationFunc: {
|
|
131
|
+
type: 'Func',
|
|
132
|
+
data: 'System.Threading.Tasks.Task<bool>, Mushroom.Extensions.Mailing.MailingAuthorizationArgument',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
export const getExtensionEventsCode = (source, newLine) => {
|
|
137
|
+
const eventCodes = [];
|
|
138
|
+
const addEventCodes = (key, code, source) => {
|
|
139
|
+
const eventCode = eventCodes.find((ec) => ec.key === key);
|
|
140
|
+
if (eventCode) {
|
|
141
|
+
eventCode.source.push(source);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
eventCodes.push({
|
|
145
|
+
key,
|
|
146
|
+
code,
|
|
147
|
+
source: [source],
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
Object.keys(extEvents).forEach((ext) => {
|
|
151
|
+
const extension = source.extensions?.[ext];
|
|
152
|
+
if (!extension?.config)
|
|
153
|
+
return;
|
|
154
|
+
const config = extension.config;
|
|
155
|
+
Object.keys(extEvents[ext]).forEach((configName) => {
|
|
156
|
+
const def = extEvents[ext][configName];
|
|
157
|
+
const configValue = config[configName];
|
|
158
|
+
if (!configValue || typeof configValue !== 'string' || !configValue.startsWith('lib:'))
|
|
159
|
+
return;
|
|
160
|
+
if (def.type == 'Func') {
|
|
161
|
+
const defaultFunc = `RegisterCustomMethod<${def.data || 'System.Threading.Tasks.Task'}>`;
|
|
162
|
+
addEventCodes(ext + '.' + configName, `${def.registerFunc || defaultFunc}(${configValue.substring(4)});`, `extension: ${ext} - config: ${configName}`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
if (def.type == 'Event') {
|
|
166
|
+
configValue.split(',').forEach((lib) => {
|
|
167
|
+
if (!lib || !lib.startsWith('lib:'))
|
|
168
|
+
return;
|
|
169
|
+
addEventCodes(ext + '.' + configName, `${def.registerFunc || 'RegisterEvent'}(${lib.substring(4)});`, `extension: ${ext} - config: ${configName}`);
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (def.type == 'Before') {
|
|
174
|
+
configValue.split(',').forEach((lib) => {
|
|
175
|
+
if (!lib || !lib.startsWith('lib:'))
|
|
176
|
+
return;
|
|
177
|
+
addEventCodes(ext + '.' + configName, `${def.registerFunc || 'RegisterBeforeEvent'}(${lib.substring(4)});`, `extension: ${ext} - config: ${configName}`);
|
|
178
|
+
});
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (def.type == 'After') {
|
|
182
|
+
configValue.split(',').forEach((lib) => {
|
|
183
|
+
if (!lib || !lib.startsWith('lib:'))
|
|
184
|
+
return;
|
|
185
|
+
addEventCodes(ext + '.' + configName, `${def.registerFunc || (def.data ? `RegisterAfterEvent<${def.data}>` : 'RegisterAfterEvent')}(${lib.substring(4)});`, `extension: ${ext} - config: ${configName}`);
|
|
186
|
+
});
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
return '';
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
return eventCodes
|
|
193
|
+
.map((ec) => `${ec.source.map((s) => ' // ' + s).join(newLine)}${newLine} ${ec.code}`)
|
|
194
|
+
.join(newLine);
|
|
195
|
+
};
|
package/dist/gen/gen-api-docs.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import open from 'open';
|
|
3
|
-
import { minify } from '
|
|
3
|
+
import { minify } from 'html-minifier-terser';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import * as common from '../common.js';
|
|
@@ -227,42 +227,58 @@ function filterEntityFields(entity) {
|
|
|
227
227
|
async function writeDocs(filePath, strTemplate, strData) {
|
|
228
228
|
const placeholder = '<script id="INJECT-JAVASCRIPT-HERE"></script>';
|
|
229
229
|
const idx = strTemplate.indexOf(placeholder);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
fs.
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
'jquery.min.js',
|
|
260
|
-
]);
|
|
230
|
+
if (idx === -1) {
|
|
231
|
+
throw new Error(`Docs template does not contain the placeholder ${placeholder}`);
|
|
232
|
+
}
|
|
233
|
+
const docsScript = fs.readFileSync(path.join(__dirname, '../docs/docs.v2.js')).toString();
|
|
234
|
+
let html = strTemplate.substring(0, idx) +
|
|
235
|
+
'<script>window.docs = ' +
|
|
236
|
+
strData +
|
|
237
|
+
';\n' +
|
|
238
|
+
docsScript +
|
|
239
|
+
'</script>' +
|
|
240
|
+
strTemplate.substring(idx + placeholder.length);
|
|
241
|
+
html = await minify(html, {
|
|
242
|
+
removeComments: true,
|
|
243
|
+
collapseWhitespace: true,
|
|
244
|
+
collapseBooleanAttributes: true,
|
|
245
|
+
removeAttributeQuotes: true,
|
|
246
|
+
removeRedundantAttributes: true,
|
|
247
|
+
useShortDoctype: true,
|
|
248
|
+
removeEmptyAttributes: true,
|
|
249
|
+
removeEmptyElements: false,
|
|
250
|
+
removeOptionalTags: true,
|
|
251
|
+
removeScriptTypeAttributes: false,
|
|
252
|
+
removeStyleLinkTypeAttributes: true,
|
|
253
|
+
minifyJS: true,
|
|
254
|
+
minifyCSS: true,
|
|
255
|
+
html5: true,
|
|
256
|
+
});
|
|
257
|
+
html = injectStaticFiles(html, ['bootstrap-theme.min.css', 'bootstrap.min.css', 'bootstrap.min.js', 'jquery.min.js']);
|
|
258
|
+
fs.writeFileSync(filePath, html);
|
|
261
259
|
}
|
|
262
|
-
const
|
|
260
|
+
const injectStaticFiles = (content, files) => {
|
|
261
|
+
let html = content;
|
|
263
262
|
files.forEach((file) => {
|
|
264
|
-
|
|
263
|
+
const sourcePath = path.join(__dirname, '../docs/', file);
|
|
264
|
+
if (!fs.existsSync(sourcePath)) {
|
|
265
|
+
common.logWarning(`Static file ${file} does not exist, skipping...`);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const escapedFile = file.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
269
|
+
const isCss = path.extname(file).toLowerCase() === '.css';
|
|
270
|
+
const tagPattern = isCss
|
|
271
|
+
? new RegExp(`<link[^>]*href=["']?${escapedFile}["']?[^>]*>`, 'gi')
|
|
272
|
+
: new RegExp(`<script[^>]*src=["']?${escapedFile}["']?[^>]*>\\s*</script>`, 'gi');
|
|
273
|
+
if (!tagPattern.test(html)) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
tagPattern.lastIndex = 0;
|
|
277
|
+
const assetContent = fs.readFileSync(sourcePath).toString();
|
|
278
|
+
const inlined = isCss ? `<style>${assetContent}</style>` : `<script>${assetContent}</script>`;
|
|
279
|
+
html = html.replace(tagPattern, () => inlined);
|
|
265
280
|
});
|
|
281
|
+
return html;
|
|
266
282
|
};
|
|
267
283
|
export default async function genDocs(args, projectName, project, alias, source) {
|
|
268
284
|
const aliasProject = ((project.docs || {}).alias || {})[alias];
|
|
@@ -300,6 +316,7 @@ export default async function genDocs(args, projectName, project, alias, source)
|
|
|
300
316
|
environmentVariables: source.environmentVariables,
|
|
301
317
|
entities: entities,
|
|
302
318
|
});
|
|
319
|
+
common.ensureFolder(aliasProject.output);
|
|
303
320
|
const html = fs.readFileSync(__dirname + '/../docs/docs.v2.html').toString();
|
|
304
321
|
if (args[3] === 'tmp') {
|
|
305
322
|
const htmlFilePath = aliasProject.output + '_tmp.html';
|
|
@@ -320,7 +337,6 @@ export default async function genDocs(args, projectName, project, alias, source)
|
|
|
320
337
|
}
|
|
321
338
|
return;
|
|
322
339
|
}
|
|
323
|
-
common.ensureFolder(aliasProject.output);
|
|
324
340
|
common.logInfo('Writing to', aliasProject.output);
|
|
325
341
|
await writeDocs(aliasProject.output, html, data);
|
|
326
342
|
common.logInfo(`Generated API docs for ${projectName}@${alias} to ${aliasProject.output}`);
|