mushroom-cli 1.1.0-alpha.18 → 1.1.0-alpha.19

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/common.js CHANGED
@@ -1,4 +1,6 @@
1
1
  const fs = require("fs");
2
+ const path = require('path');
3
+ const readlineSync = require("readline-sync");
2
4
 
3
5
  function ensureFolder(path, isFolder) {
4
6
  const index = path.lastIndexOf("/");
@@ -125,8 +127,109 @@ function getEntities(projectApiConfiguration, roles, getAll) {
125
127
  return entities;
126
128
  }
127
129
 
130
+ function processTemplate(basePath, templatePath) {
131
+ const templateJsonContent = fs.readFileSync(path.join(basePath, templatePath)).toString();
132
+ const template = JSON.parse(templateJsonContent);
133
+ if (template && typeof template !== "object") {
134
+ throw new TypeError(`Invalid template file ${templatePath}`);
135
+ }
136
+ const commands = template.steps;
137
+ if (!Array.isArray(commands)) {
138
+ throw new TypeError(`Invalid template file ${templatePath}`);
139
+ }
140
+
141
+ const variables = {};
142
+ commands.forEach(command => processCommand(command, basePath, variables));
143
+ return variables;
144
+ }
145
+
146
+ function processCommand(command, basePath, variables) {
147
+ switch (command.command) {
148
+ case "input":
149
+ processInputCommand(command, variables);
150
+ return;
151
+ case "set":
152
+ processSetCommand(command, variables);
153
+ return;
154
+ case "rename":
155
+ processRenameCommand(command, basePath, variables);
156
+ return;
157
+ case "delete":
158
+ processDeleteCommand(command, basePath, variables);
159
+ return;
160
+ case "replace":
161
+ processReplaceCommand(command, basePath, variables);
162
+ return;
163
+ }
164
+ }
165
+
166
+ function processInputCommand(command, variables) {
167
+ const value = readlineSync.question(command.message ?? "");
168
+ if (command.validation) {
169
+ if (command.validation.required) {
170
+ if (value === "") throw new TypeError(`${command.variable} is required`);
171
+ }
172
+ if (command.validation.pattern) {
173
+ if (!new RegExp(command.validation.pattern).test(value)) throw new Error(`${value} is not valid`);
174
+ }
175
+ }
176
+ variables[command.variable] = value;
177
+ }
178
+
179
+ function processSetCommand(command, variables) {
180
+ switch (command["function"]) {
181
+ case "New-GUID":
182
+ processSetGuidCommand(command.variable, variables);
183
+ break;
184
+ }
185
+ }
186
+
187
+ function processSetGuidCommand(variable, variables) {
188
+ variables[variable] = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
189
+ var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
190
+ return v.toString(16);
191
+ }).toUpperCase();
192
+ }
193
+
194
+ function processRenameCommand(command, basePath, variables) {
195
+ const input = replaceVariables(command.input, variables);
196
+ const output = replaceVariables(command.output, variables);
197
+
198
+ fs.renameSync(path.join(basePath, input), path.join(basePath, output));
199
+ }
200
+
201
+ function processDeleteCommand(command, basePath, variables) {
202
+ const input = replaceVariables(command.input, variables);
203
+
204
+ const deletedPath = path.join(basePath, input);
205
+ if (fs.lstatSync(deletedPath).isDirectory()) {
206
+ fs.rmdirSync(deletedPath, {recursive: true, force: true});
207
+ }
208
+ else {
209
+ fs.rmSync(deletedPath, {force: true});
210
+ }
211
+ }
212
+
213
+ function processReplaceCommand(command, basePath, variables) {
214
+ const files = command.input;
215
+ const pattern = new RegExp(command.pattern, "g");
216
+ const replacement = replaceVariables(command.replacement, variables);
217
+
218
+ files.forEach(file => {
219
+ const filePath = replaceVariables(file, variables);
220
+ let content = fs.readFileSync(path.join(basePath, filePath)).toString();
221
+ content = content.replace(pattern, () => replacement);
222
+ fs.writeFileSync(path.join(basePath, filePath), content);
223
+ });
224
+ }
225
+
226
+ function replaceVariables(str, variables) {
227
+ return str.replace(/\$\{(\w+)\}/g, (_, varName) => variables[varName] ?? "");
228
+ }
229
+
128
230
  module.exports = {
129
231
  ensureFolder: ensureFolder,
130
- getRootUrl : getRootUrl,
131
- getEntities : getEntities
232
+ getRootUrl: getRootUrl,
233
+ getEntities: getEntities,
234
+ processTemplate: processTemplate
132
235
  };
package/docs/docs.html CHANGED
@@ -4418,7 +4418,7 @@ API.getAuthentication().changePasswordAsync("your account", "your old password",
4418
4418
  Request header
4419
4419
  <pre>FileName: string, optional, tên file
4420
4420
  MD5: string, optional, giá trị băm md5 của file
4421
- Tags: string, optional, giá trị các tag của ảnh, mỗi tag cách nhau bởi dấu phải
4421
+ Tags: string, optional, giá trị các tag của ảnh, mỗi tag cách nhau bởi dấu phảy
4422
4422
  Content-Format: optional, string, định dạng dữ liệu truyền lên, nhận một trong các giá trị: BINARY, BASE64 hoặc FORMDATA, mặc định là BINARY</pre>
4423
4423
  Request body
4424
4424
  <pre>BINARY hoặc BASE64 hoặc FORMDATA</pre>
package/gen/gen-csharp.js CHANGED
@@ -134,8 +134,10 @@ function generateEnumClass(source, out, field, defaultClassName) {
134
134
  strEnumClasses += ` /// <summary>
135
135
  /// ${singleLine(validation.codeHint.validValues.description || field.description)}
136
136
  /// </summary>
137
- public static class ${enumClassName}
137
+ public class ${enumClassName}
138
138
  {
139
+ private ${enumClassName}() { }
140
+
139
141
  `;
140
142
  const enumProperties = validation.codeHint.validValues.nameMap || validation.validValues;
141
143
  for (let i = 0; i < enumProperties.length && i < validation.validValues.length; i++) {
@@ -214,7 +216,7 @@ function generateCSharpClassMongoDb(source, className, fields, isRoot, descripti
214
216
  }
215
217
  content += ` [MongoDB.Bson.Serialization.Attributes.BsonElement("${isRoot && fieldName === "id" ? "_id" : fieldName}")]
216
218
  [MongoDB.Bson.Serialization.Attributes.BsonIgnoreIfNull]
217
- [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
219
+ [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.DateTime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
218
220
  `;
219
221
  if ((field.type === "AutoId" || field.type === "IdRef") && source.idType === "ObjectId") {
220
222
  content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
@@ -471,12 +473,16 @@ ${collectionNames}
471
473
  }
472
474
  }
473
475
 
474
- public static class ResourceNames
476
+ public class ResourceNames
475
477
  {
478
+ private ResourceNames() { }
479
+
476
480
  ${resourceNames}
477
481
  }
478
482
 
479
- public static class RoleNames {
483
+ public class RoleNames {
484
+ private RoleNames() { }
485
+
480
486
  ${roleNames}
481
487
  }
482
488
  }
@@ -584,7 +590,7 @@ function generateCSharpClassMongoDbToFolder(source, className, fields, isRoot, d
584
590
  }
585
591
  content += ` [MongoDB.Bson.Serialization.Attributes.BsonElement("${isRoot && fieldName === "id" ? "_id" : fieldName}")]
586
592
  [MongoDB.Bson.Serialization.Attributes.BsonIgnoreIfNull]
587
- [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
593
+ [Newtonsoft.Json.JsonProperty(PropertyName = "${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.DateTime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
588
594
  `;
589
595
  if ((field.type === "AutoId" || field.type === "IdRef") && source.idType === "ObjectId") {
590
596
  content += " [MongoDB.Bson.Serialization.Attributes.BsonRepresentation(MongoDB.Bson.BsonType.ObjectId)]" + newLine;
@@ -613,7 +619,7 @@ function generateCSharpClassMongoDbToFolder(source, className, fields, isRoot, d
613
619
 
614
620
  let strEnumClasses = generateEnumClass(source, {}, field, `${className.toUpperCase()}_${propertyName.toUpperCase()}_ENUM`);
615
621
 
616
- const match = strEnumClasses.match(/public static class\s+(\w+)/);
622
+ const match = strEnumClasses.match(/public class\s+(\w+)/);
617
623
  if (!match) continue;
618
624
  common.ensureFolder(aliasProject.output + "/Enums", true);
619
625
  strEnumClasses = `${header}
@@ -860,8 +866,10 @@ ${collectionNames}
860
866
 
861
867
  namespace ${namespace}
862
868
  {
863
- public static class ResourceNames
869
+ public class ResourceNames
864
870
  {
871
+ private ResourceNames() { }
872
+
865
873
  ${resourceNames}
866
874
  }
867
875
  }
@@ -871,8 +879,10 @@ const roleNamesFileContent = `${header}
871
879
 
872
880
  namespace ${namespace}
873
881
  {
874
- public static class RoleNames
882
+ public class RoleNames
875
883
  {
884
+ private RoleNames() { }
885
+
876
886
  ${roleNames}
877
887
  }
878
888
  }
@@ -959,7 +969,7 @@ function generateCSharpClassDriver(source, className, fields, description, out)
959
969
  ` /// <summary>
960
970
  /// ${singleLine(field.description)}
961
971
  /// </summary>
962
- [Newtonsoft.Json.JsonProperty(PropertyName ="${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
972
+ [Newtonsoft.Json.JsonProperty(PropertyName ="${fieldName}", NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore${type === "System.Datetime" ? ", DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore" : ""})]
963
973
  public ${type} ${propertyName} { get; set; }
964
974
 
965
975
  `;
package/help.js CHANGED
@@ -13,7 +13,7 @@ function help(key, wrong) {
13
13
  npx mr init json ./api/SampleProject.json [silent]
14
14
 
15
15
  Init a dotnet core project which pre-install Mushroom Server
16
- npx mr init netcore projectName [features file,auth,mail]
16
+ npx mr init netcore
17
17
 
18
18
  Add the mushroom json file into mushroom-config.json
19
19
  npx mr config add ./api/yourProjectName.json
@@ -0,0 +1,106 @@
1
+ const fs = require("fs");
2
+ const fetch = require('node-fetch');
3
+ const readlineSync = require("readline-sync");
4
+ const help = require("../help.js");
5
+ const common = require("../common.js");
6
+
7
+ function initJson(args) {
8
+ const path = args[2];
9
+ if (!path) {
10
+ help(args);
11
+ return;
12
+ }
13
+
14
+ if (fs.existsSync(path)){
15
+ console.error(`File ${path} is already existed`);
16
+ return;
17
+ }
18
+
19
+ if (args[3] === "silent") {
20
+ console.log("Fetch http://api.siten.vn/gen/template/default.json");
21
+ fetch("http://api.siten.vn/gen/template/default.json").then(res => res.text()).then(text => {
22
+ common.ensureFolder(path);
23
+
24
+ fs.writeFile(path, text, err => {
25
+ if (err)
26
+ throw err;
27
+ console.log(`Initialized json at ${path}`);
28
+ });
29
+ });
30
+ return;
31
+ }
32
+
33
+ console.log("Fetch http://api.siten.vn/gen/template/template-def.json");
34
+ fetch("http://api.siten.vn/gen/template/template-def.json").then(res => res.json()).then(templateConfig => {
35
+ const info = {};
36
+ templateConfig.fields.forEach(field => {
37
+ while (true)
38
+ {
39
+ let question = `${field.required ? "[Required] " : ""}${field.label || field.name}`;
40
+ if (Array.isArray(field.list)) {
41
+ question += "\n";
42
+ let i = 1;
43
+ field.list.forEach(item => { question += "\t" + i++ + ". " + item + "\n"; });
44
+ question += "Please choose";
45
+ }
46
+ if (field.defaultValue !== undefined) {
47
+ question += ` (default: '${field.defaultValue}')`;
48
+ }
49
+ question += ": ";
50
+ let choice = readlineSync.question(question);
51
+ if (choice === "") {
52
+ if (field.defaultValue != undefined)
53
+ choice = field.defaultValue;
54
+ }
55
+ else if (Array.isArray(field.list)) {
56
+ if (choice !== null && choice !== "" && !isNaN(choice))
57
+ choice = field.list[choice - 1];
58
+ else
59
+ choice = undefined;
60
+ if (choice === undefined) {
61
+ console.warn("Invalid input");
62
+ continue;
63
+ }
64
+ }
65
+
66
+ if (choice === "" || choice === undefined || choice == null) {
67
+ choice = "";
68
+
69
+ if (field.required) {
70
+ console.warn("Required input value");
71
+ continue;
72
+ }
73
+ }
74
+
75
+ if (choice !== "" && field.pattern) {
76
+ const re = new RegExp(field.pattern, field.patternFlags);
77
+ if (!re.test(choice)) {
78
+ console.warn("Input doesn't match with pattern " + field.pattern);
79
+ continue;
80
+ }
81
+ }
82
+
83
+ info[field.name] = choice;
84
+ break;
85
+ }
86
+ });
87
+ //console.log(info);
88
+
89
+ console.log(`Fetch ${templateConfig.templateUrl}`);
90
+ fetch(templateConfig.templateUrl).then(res => res.text()).then(json => {
91
+ json = json.replace(/\"\$\{([\w]+)\}\"/g, (s0, s1) => JSON.stringify(info[s1]));
92
+ json = json.replace(/\$\{([\w]+)\}/g, (s0, s1) => JSON.stringify(info[s1]).replace(/^\"|\"$/g, ""));
93
+
94
+ common.ensureFolder(path);
95
+ //console.log(json);
96
+
97
+ fs.writeFile(path, json, err => {
98
+ if (err)
99
+ throw err;
100
+ console.log(`Initialized json at ${path}`);
101
+ });
102
+ });
103
+ })
104
+ }
105
+
106
+ module.exports = initJson;
@@ -0,0 +1,32 @@
1
+ const fs = require("fs");
2
+ const { spawn } = require("child_process");
3
+ const common = require("../common.js");
4
+
5
+
6
+ function fetchFromGit() {
7
+ return new Promise((resolve, reject) => {
8
+ const git = spawn("git", ["clone", "https://tfs.siten.vn/tfs/Siten/CodeBase/_git/Mushroom", "-b", "full_extensions", "--single-branch"]);
9
+ git.stdout.on('data', (data) => {
10
+ console.log(`GIT: ${data}`);
11
+ });
12
+
13
+ git.stderr.on('data', (data) => {
14
+ console.error(`GIT: ${data}`);
15
+ });
16
+
17
+ git.on('close', (code) => {
18
+ if (code) {
19
+ reject(new Error(`GIT exited with code ${code}`));
20
+ return;
21
+ }
22
+ resolve();
23
+ });
24
+ })
25
+ }
26
+
27
+ async function initNetCore(args) {
28
+ await fetchFromGit();
29
+ common.processTemplate("Mushroom", "mushroom-template.json");
30
+ }
31
+
32
+ module.exports = initNetCore;
package/init.js CHANGED
@@ -1,120 +1,16 @@
1
- const fs = require("fs");
2
- const fetch = require('node-fetch');
3
- const readlineSync = require("readline-sync");
4
1
  const help = require("./help.js");
5
- const common = require("./common.js");
6
2
 
7
- function initJson(args) {
8
- const path = args[2];
9
- if (!path) {
10
- help(args);
11
- return;
12
- }
13
-
14
- if (fs.existsSync(path)){
15
- console.error(`File ${path} is already existed`);
16
- return;
17
- }
18
-
19
- if (args[3] === "silent") {
20
- console.log("Fetch http://api.siten.vn/gen/template/default.json");
21
- fetch("http://api.siten.vn/gen/template/default.json").then(res => res.text()).then(text => {
22
- common.ensureFolder(path);
23
-
24
- fs.writeFile(path, text, err => {
25
- if (err)
26
- throw err;
27
- console.log(`Initialized json at ${path}`);
28
- });
29
- });
30
- return;
31
- }
32
-
33
- console.log("Fetch http://api.siten.vn/gen/template/template-def.json");
34
- fetch("http://api.siten.vn/gen/template/template-def.json").then(res => res.json()).then(templateConfig => {
35
- const info = {};
36
- templateConfig.fields.forEach(field => {
37
- while (true)
38
- {
39
- let question = `${field.required ? "[Required] " : ""}${field.label || field.name}`;
40
- if (Array.isArray(field.list)) {
41
- question += "\n";
42
- let i = 1;
43
- field.list.forEach(item => { question += "\t" + i++ + ". " + item + "\n"; });
44
- question += "Please choose";
45
- }
46
- if (field.defaultValue !== undefined) {
47
- question += ` (default: '${field.defaultValue}')`;
48
- }
49
- question += ": ";
50
- let choice = readlineSync.question(question);
51
- if (choice === "") {
52
- if (field.defaultValue != undefined)
53
- choice = field.defaultValue;
54
- }
55
- else if (Array.isArray(field.list)) {
56
- if (choice !== null && choice !== "" && !isNaN(choice))
57
- choice = field.list[choice - 1];
58
- else
59
- choice = undefined;
60
- if (choice === undefined) {
61
- console.warn("Invalid input");
62
- continue;
63
- }
64
- }
65
-
66
- if (choice === "" || choice === undefined || choice == null) {
67
- choice = "";
68
-
69
- if (field.required) {
70
- console.warn("Required input value");
71
- continue;
72
- }
73
- }
74
-
75
- if (choice !== "" && field.pattern) {
76
- const re = new RegExp(field.pattern, field.patternFlags);
77
- if (!re.test(choice)) {
78
- console.warn("Input doesn't match with pattern " + field.pattern);
79
- continue;
80
- }
81
- }
82
-
83
- info[field.name] = choice;
84
- break;
85
- }
86
- });
87
- //console.log(info);
88
-
89
- console.log(`Fetch ${templateConfig.templateUrl}`);
90
- fetch(templateConfig.templateUrl).then(res => res.text()).then(json => {
91
- json = json.replace(/\"\$\{([\w]+)\}\"/g, (s0, s1) => JSON.stringify(info[s1]));
92
- json = json.replace(/\$\{([\w]+)\}/g, (s0, s1) => JSON.stringify(info[s1]).replace(/^\"|\"$/g, ""));
93
-
94
- common.ensureFolder(path);
95
- //console.log(json);
96
-
97
- fs.writeFile(path, json, err => {
98
- if (err)
99
- throw err;
100
- console.log(`Initialized json at ${path}`);
101
- });
102
- });
103
- })
104
- }
105
-
106
- function initNetCore(args) {
107
- console.log("init netcore is comming soon");
108
- }
3
+ const initJson = require("./init/init-json");
4
+ const initNetCore = require("./init/init-netcore");
109
5
 
110
- function init(args) {
6
+ async function init(args) {
111
7
  const configCommand = args[1];
112
8
  switch(configCommand) {
113
9
  case "json":
114
10
  initJson(args);
115
11
  break;
116
12
  case "netcore":
117
- initNetCore(args);
13
+ await initNetCore(args);
118
14
  break;
119
15
  case "":
120
16
  case undefined:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mushroom-cli",
3
- "version": "1.1.0-alpha.18",
3
+ "version": "1.1.0-alpha.19",
4
4
  "description": "Mushroom CLI",
5
5
  "main": "mr.js",
6
6
  "scripts": {