mushroom-cli 1.2.0-alpha.1 → 1.2.0-alpha.11

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 CHANGED
@@ -4,89 +4,217 @@
4
4
 
5
5
  Init a mushroom json file
6
6
 
7
- npx mushroom-cli init json ./api/SampleProject.json [silent]
7
+ ```bash
8
+ npx mushroom-cli init json ./api/SampleProject.json [silent]
9
+ ```
8
10
 
9
11
  Init a DotNet Core project which pre-install Mushroom Server
10
12
 
11
- npx mushroom-cli init netcore [projectName]
13
+ ```bash
14
+ npx mushroom-cli init netcore [projectName]
15
+ ```
12
16
 
13
17
  ## Configure
14
18
 
15
19
  Add the mushroom json file into mushroom-config.json
16
20
 
17
- npx mushroom-cli config add ./api/yourProjectName.json
21
+ ```bash
22
+ npx mushroom-cli config add ./api/yourProjectName.json
23
+ ```
18
24
 
19
25
  Config gen docs api
20
26
 
21
- npx mushroom-cli config gen projectName docs ./wwwroot/docs.html [alias aliasName] [features file,auth,mail,driver] [roles Admin,User-Contributor]
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
+ ```
22
30
 
23
31
  Config gen database docs
24
32
 
25
- npx mushroom-cli config gen projectName db-docs ./wwwroot/db-docs.html [alias aliasName] [features file,auth,mail]
33
+ ```bash
34
+ npx mushroom-cli config gen projectName "db-docs" ./wwwroot/db-docs.html [alias aliasName] [features file,auth,mail]
35
+ ```
26
36
 
27
37
  Config gen javascript driver
28
38
 
29
- npx mushroom-cli config gen projectName js-driver ./src/api/mushroom.api.js [alias aliasName] [roles Admin,User-Contributor] [tarball tarballName]
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
+ ```
30
42
 
31
43
  Config gen typescript driver
32
44
 
33
- npx mushroom-cli config gen projectName ts-driver ./src/api/mushroom.api.ts [alias aliasName] [roles Admin,User-Contributor]
45
+ ```bash
46
+ npx mushroom-cli config gen projectName "ts-driver" ./src/api/mushroom.api.ts [alias aliasName] [roles Admin,User-Contributor]
47
+ ```
34
48
 
35
49
  Config gen entities for Mushroom project in CSharp and using MongoDb
36
50
 
37
- npx mushroom-cli config gen projectName c#-mongo ./API/Generated.cs [alias aliasName]
51
+ ```bash
52
+ npx mushroom-cli config gen projectName "c#-mongo" ./API/Generated.cs [alias aliasName]
53
+ ```
38
54
 
39
55
  Config gen entities for CSharp project which calls Mushroom API
40
56
 
41
- npx mushroom-cli config gen projectName c#-driver ./API/Generated.cs [roles Admin,User-Contributor] [alias aliasName] [access-modifier public] [features file,auth,mail]
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
+ ```
42
60
 
43
61
  ## Genarate
44
62
 
45
63
  Generate docs api (html format)
46
64
 
47
- npx mushroom-cli gen projectName[@aliasName] docs [tmp]
65
+ ```bash
66
+ npx mushroom-cli gen projectName[@aliasName] docs [v1] [tmp]
67
+ ```
48
68
 
49
69
  Generate database docs (html format)
50
70
 
51
- npx mushroom-cli gen projectName[@aliasName] db-docs [tmp]
71
+ ```bash
72
+ npx mushroom-cli gen projectName[@aliasName] "db-docs" [tmp]
73
+ ```
52
74
 
53
75
  Generate npm package (tarball file)
54
76
 
55
- npx mushroom-cli gen projectName[@aliasName] js-driver-tarball
77
+ ```bash
78
+ npx mushroom-cli gen projectName[@aliasName] "js-driver-tarball"
79
+ ```
56
80
 
57
81
  Generate javascript driver
58
82
 
59
- npx mushroom-cli gen projectName[@aliasName] js-driver
83
+ ```bash
84
+ npx mushroom-cli gen projectName[@aliasName] "js-driver"
85
+ ```
60
86
 
61
87
  Generate typescript driver
62
88
 
63
- npx mushroom-cli gen projectName[@aliasName] ts-driver
89
+ ```bash
90
+ npx mushroom-cli gen projectName[@aliasName] "ts-driver"
91
+ ```
64
92
 
65
93
  Generate entities for Mushroom project in CSharp and using MongoDb
66
94
 
67
- npx mushroom-cli gen projectName[@aliasName] c#-mongo
95
+ ```bash
96
+ npx mushroom-cli gen projectName[@aliasName] "c#-mongo"
97
+ ```
68
98
 
69
99
  Generate entities for CSharp project which calls Mushroom API
70
100
 
71
- npx mushroom-cli gen projectName[@aliasName] c#-driver
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
+ ```
72
110
 
73
111
  ## Update
74
112
 
75
- Update ts code
113
+ Update ts code (configuration was stored in mushroom-config.json file)
114
+
115
+ ```bash
116
+ npx mushroom-cli update "ts-code"
117
+ ```
76
118
 
77
- npx mushroom-cli update ts-code [file-path.ts] [remote-ts-code-url]
119
+ Update ts code (simple call)
120
+
121
+ ```bash
122
+ npx mushroom-cli update "ts-code" file-path.ts remote-ts-code-url
123
+ ```
78
124
 
79
125
  ## Other
80
126
 
81
127
  Disable checking for update:
82
128
 
83
- npx mushroom-cli parameters --no-check-update
129
+ ```bash
130
+ npx mushroom-cli parameters --no-check-update
131
+ ```
84
132
 
85
133
  ## Version
86
134
 
135
+ ### 1.2.0-alpha.11
136
+
137
+ Improvement:
138
+
139
+ * gen-docs:
140
+ * allow user add and change API root url
141
+ * filter role list
142
+ * fornat cURL to easy to copy and paste to Postman
143
+ * lighten font on MacOS
144
+ * gen-ts:
145
+ * export type for object fields
146
+
147
+ ### 1.2.0-alpha.10
148
+
149
+ Improvement:
150
+
151
+ * gen-docs: add default-value information of fields
152
+
153
+ ### 1.2.0-alpha.9
154
+
155
+ Improvement:
156
+
157
+ * gen-docs
158
+ * v1.2: minify, fix bug (some fields are not excluded)
159
+
160
+ ### 1.2.0-alpha.8
161
+
162
+ Improvement:
163
+
164
+ * gen-docs
165
+ * v1.2: deal with very big api docs
166
+ * v1: prerender all docs html (need more RAM, less performance)
167
+
168
+ ### 1.2.0-alpha.7
169
+
170
+ New features:
171
+
172
+ * init netcore: Support some new set-functions: `ToLowerCase`, `ToUpperCase`, `Trim`, `Replace`
173
+
174
+ Changes:
175
+
176
+ * init netcore: Operating fail if unknown command or set-function found
177
+
178
+ ### 1.2.0-alpha.6
179
+
180
+ New features:
181
+
182
+ * gen-ts-driver: Support offline mode
183
+
184
+ Changes:
185
+
186
+ * gen-api-docs: Improve generating api-docs
187
+ * gen-csharp: Generate resource classes with `partial`
188
+
189
+ ### 1.2.0-alpha.5
190
+
191
+ New features:
192
+
193
+ * Improve documentation generation: view, custom action.
194
+
195
+ ### 1.2.0-alpha.4
196
+
197
+ Fixed bugs:
198
+
199
+ * Generate api docs: doesn't exclude fields of object in an array
200
+
201
+ ### 1.2.0-alpha.3
202
+
203
+ Fixed bugs:
204
+
205
+ * Generate wrong required field for view parameter
206
+
207
+ ### 1.2.0-alpha.2
208
+
209
+ New features:
210
+
211
+ * Support merge command
212
+
87
213
  ### 1.2.0-alpha.1
88
214
 
89
- Support type for View result
215
+ New features:
216
+
217
+ * Support type for View result
90
218
 
91
219
  ### 1.1.0
92
220
 
package/common.js CHANGED
@@ -12,7 +12,7 @@ function ensureFolder(path, isFolder) {
12
12
  return;
13
13
 
14
14
  if (!fs.existsSync(path)) {
15
- fs.mkdirSync(path, { recursive: true, mode: 0755 });
15
+ fs.mkdirSync(path, { recursive: true, mode: 0o755 });
16
16
  }
17
17
  }
18
18
 
@@ -49,7 +49,7 @@ function getEntities(projectApiConfiguration, roles, getAll) {
49
49
  if (!action.grant || !action.enabled || action.codeHint && action.codeHint.disabled)
50
50
  return;
51
51
 
52
- var allow = roles.indexOf("*") !== -1 || action.grant === "*";
52
+ var allow = roles.includes("*") || action.grant === "*";
53
53
 
54
54
  if (!allow)
55
55
  action.grant.split("|").forEach(function (roleGroup) {
@@ -66,6 +66,7 @@ function getEntities(projectApiConfiguration, roles, getAll) {
66
66
 
67
67
  if (!(entity.name in entities))
68
68
  entities[entity.name] = {
69
+ name: entity.name,
69
70
  description: entity.description,
70
71
  storageName: entity.storageName ? entity.storageName : entity.name,
71
72
  fields: entity.fields,
@@ -105,6 +106,7 @@ function getEntities(projectApiConfiguration, roles, getAll) {
105
106
 
106
107
  if (!(entity.name in entities))
107
108
  entities[entity.name] = {
109
+ name: entity.name,
108
110
  description: entity.description,
109
111
  storageName: entity.storageName ? entity.storageName : entity.name,
110
112
  fields: entity.fields,
@@ -127,6 +129,15 @@ function getEntities(projectApiConfiguration, roles, getAll) {
127
129
  return entities;
128
130
  }
129
131
 
132
+ function filterRoles(roleList, allowRoleList) {
133
+ const roles = !allowRoleList || allowRoleList.includes("*") ? [...roleList] : roleList.filter(role => allowRoleList.includes(role.name));
134
+ roles.push({
135
+ name: "[Mọi người dùng]",
136
+ description: "Tất cả người dùng (kể cả chưa đăng nhập)"
137
+ });
138
+ return roles;
139
+ }
140
+
130
141
  function processTemplate(basePath, templatePath) {
131
142
  const templateJsonContent = fs.readFileSync(path.join(basePath, templatePath)).toString();
132
143
  const template = JSON.parse(templateJsonContent);
@@ -160,6 +171,8 @@ function processCommand(command, basePath, variables) {
160
171
  case "replace":
161
172
  processReplaceCommand(command, basePath, variables);
162
173
  return;
174
+ default:
175
+ throw new Error(`Unknown command: ${command.command}`);
163
176
  }
164
177
  }
165
178
 
@@ -181,9 +194,24 @@ function processSetCommand(command, variables) {
181
194
  case "New-GUID":
182
195
  processSetGuidCommand(command.variable, variables);
183
196
  break;
197
+ case "ToLowerCase":
198
+ toLowerCommand(command.variable, variables, command.input);
199
+ break;
200
+ case "ToUpperCase":
201
+ toUpperCaseCommand(command.variable, variables, command.input);
202
+ break;
203
+ case "Trim":
204
+ trimCommand(command.variable, variables, command.input);
205
+ break;
206
+ case "Replace":
207
+ replaceCommand(command.variable, variables, command.input, command.replacement, command.pattern, command.mode);
208
+ break;
209
+ default:
210
+ throw new Error(`Unknown set-command: ${command["function"]}`);
184
211
  }
185
212
  }
186
213
 
214
+ //#region set-commands
187
215
  function processSetGuidCommand(variable, variables) {
188
216
  variables[variable] = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
189
217
  var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
@@ -191,6 +219,24 @@ function processSetGuidCommand(variable, variables) {
191
219
  }).toUpperCase();
192
220
  }
193
221
 
222
+ function toLowerCommand(variable, variables, input) {
223
+ variables[variable] = (variables[input] || "").toLowerCase();
224
+ }
225
+
226
+ function toUpperCaseCommand(variable, variables, input) {
227
+ variables[variable] = (variables[input] || "").toUpperCase();
228
+ }
229
+
230
+ function trimCommand(variable, variables, input) {
231
+ variables[variable] = (variables[input] || "").trim();
232
+ }
233
+
234
+ function replaceCommand(variable, variables, input, replacement, pattern, mode) {
235
+ var regex = new RegExp(pattern, mode);
236
+ variables[variable] = (variables[input] || "").replace(regex, replacement === undefined || replacement === null ? "" : replacement);
237
+ }
238
+ //#endregion
239
+
194
240
  function processRenameCommand(command, basePath, variables) {
195
241
  const input = replaceVariables(command.input, variables);
196
242
  const output = replaceVariables(command.output, variables);
@@ -232,5 +278,6 @@ module.exports = {
232
278
  ensureFolder: ensureFolder,
233
279
  getRootUrl: getRootUrl,
234
280
  getEntities: getEntities,
281
+ filterRoles:filterRoles,
235
282
  processTemplate: processTemplate
236
283
  };
package/docs/doc-mt.js CHANGED
@@ -279,6 +279,107 @@ function formatModal(obj, strIndent, options) {
279
279
  return result;
280
280
  }
281
281
 
282
+ function formatHintModal(obj, strIndent, options) {
283
+ if (!obj)
284
+ return "";
285
+
286
+ strIndent = strIndent || "";
287
+ options = options || {};
288
+
289
+ var result = "";
290
+ var nextIndent = strIndent + " ";
291
+ for (var m in obj) {
292
+ if (!obj.hasOwnProperty(m))
293
+ continue;
294
+
295
+ var child = obj[m];
296
+
297
+ var validation = !options.optionalToAll && child.required ? "required" : "optional";
298
+ if (child.type === "IdRef" && child.reference) {
299
+ validation += ", ref: <a href='#" + encodeHtml(child.reference) + "' onclick='setTimeout(gotoHash, 20)'>" + encodeHtml(child.reference) + "</a>";
300
+ }
301
+
302
+ if (child.validValues && Array.isArray(child.validValues)) {
303
+ validation += ", enum(" + encodeHtml(child.validValues.join(", ")) + ")";
304
+ }
305
+
306
+ if (child.type === "array" && child.items && child.items.type != "object") {
307
+ validation += ", array items: " + (!options.optionalToAll && child.items.required ? "required" : "optional");
308
+ if (child.items.validValues && Array.isArray(child.items.validValues))
309
+ validation += ", enum(" + encodeHtml(child.items.validValues.join(", ")) + ")";
310
+ }
311
+
312
+ var comment = `<span class="code-comment">// ${validation} ${typeof child.description === "string" && child.description !== "" ? "- " + encodeHtml(child.description) : ""}</span>`;
313
+
314
+ if (options.mode === "modal") {
315
+ if (child.type === "object")
316
+ result += "\r\n" + nextIndent + '"' + m + '": ' + comment + formatHintModal(child.fields, nextIndent, options) + ",";
317
+ else if (child.type === "array") {
318
+ result += `\r\n${nextIndent}"${m}": [`;
319
+ if (child.items.type === "object")
320
+ result += " " + comment + formatHintModal(child.items.fields, nextIndent, options);
321
+ else if (child.items.type === "datetime")
322
+ result += `\r\n${nextIndent} ` + JSON.stringify(child.items.defaultValue || "ISODate_ISO_8601") + " " + comment + `\r\n${nextIndent}`;
323
+ else if (child.items.type === "boolean")
324
+ result += `\r\n${nextIndent} ` + child.items.defaultValue || "false" + " " + comment + `\r\n${nextIndent}`;
325
+ else if (child.items.type === "integer" || child.items.type === "long"|| child.items.type === "double")
326
+ result += `\r\n${nextIndent} ` + child.items.defaultValue || "0" + " " + comment + `\r\n${nextIndent}`;
327
+ else
328
+ result += `\r\n${nextIndent} ` + JSON.stringify(child.defaultValue || child.type) + " " + comment + `\r\n${nextIndent}`;
329
+ result += `]`;
330
+ }
331
+ else if (child.type === "datetime")
332
+ result += `\r\n${nextIndent}"${m}": ` + JSON.stringify(child.defaultValue || "ISODate_ISO_8601") + ", " + comment;
333
+ else if (child.type === "boolean")
334
+ result += `\r\n${nextIndent}"${m}": ` + (child.defaultValue || "false") + ", " + comment;
335
+ else if (child.type === "integer" || child.type === "long"|| child.type === "double")
336
+ result += `\r\n${nextIndent}"${m}": ` + (child.defaultValue || "0") + ", " + comment;
337
+ else
338
+ result += `\r\n${nextIndent}"${m}": ` + JSON.stringify(child.defaultValue || child.type) + ", " + comment;
339
+ } else if (options.mode === "modal_null") {
340
+ if (child.type === "object")
341
+ result += "\r\n" + nextIndent + '"' + m + '": ' + comment + formatHintModal(child.fields, nextIndent, options);
342
+ else if (child.type === "array") {
343
+ result += `\r\n${nextIndent}"${m}": [`;
344
+ if (child.items.type === "object")
345
+ result += " " + comment + formatHintModal(child.items.fields, nextIndent, options) + "],";
346
+ else
347
+ result += "], " + comment;
348
+ }
349
+ else
350
+ result += `\r\n${nextIndent}"${m}": null, ${comment}`;
351
+ } else if (options.mode === "modal_undefined") {
352
+ if (child.type === "object")
353
+ result += "\r\n" + nextIndent + '"' + m + '": ' + comment + formatHintModal(child.fields, nextIndent, options);
354
+ else if (child.type === "array") {
355
+ result += `\r\n${nextIndent}"${m}": [`;
356
+ if (child.items.type === "object")
357
+ result += " " + comment + formatHintModal(child.items.fields, nextIndent, options) + "], ";
358
+ else
359
+ result += "], " + comment;
360
+ }
361
+ else
362
+ result += `\r\n${nextIndent}"${m}": undefined, ${comment}`;
363
+ } else {
364
+ result += "\r\n" + strIndent + encodeHtml(m) + ": " + encodeHtml(child.type);
365
+ if (child.type === "array")
366
+ result += child.items.type === "object" ? " of object" : " of " + child.items.type;
367
+ if (child.type === "object")
368
+ result += " " + comment + formatHintModal(child.fields, strIndent + " ", options);
369
+ else if (child.type === "array" && child.items.type === "object")
370
+ result += " " + comment + formatHintModal(child.items.fields, strIndent + " ", options);
371
+ else
372
+ result += ", " + comment;
373
+ }
374
+ }
375
+
376
+ if (options.mode === "modal" || options.mode === "modal_null" || options.mode === "modal_undefined") {
377
+ return (strIndent ? "\r\n" + strIndent : "") + "{" + result + "\r\n" + strIndent + "}";
378
+ }
379
+
380
+ return result;
381
+ }
382
+
282
383
  function explainRoles(strRoles) {
283
384
  if (!strRoles)
284
385
  return "";
@@ -320,6 +421,7 @@ function getModalInput(excludedFields, fields, options) {
320
421
  var obj = fields;
321
422
  var segs = item.split(".");
322
423
  for (var i = 0; i < segs.length; i++) {
424
+ if (!obj) return;
323
425
  var seg = segs[i];
324
426
  if (!(seg in obj))
325
427
  return;
@@ -329,7 +431,7 @@ function getModalInput(excludedFields, fields, options) {
329
431
  else if (obj[seg].type === "object")
330
432
  obj = obj[seg].fields;
331
433
  else if (obj[seg].type === "array")
332
- obj = obj[seg].items;
434
+ obj = obj[seg].items?.fields;
333
435
  else
334
436
  return;
335
437
  }