mushroom-cli 1.1.0-alpha.16 → 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 +105 -2
- package/docs/docs.html +9 -1
- package/gen/gen-api-docs.js +2 -2
- package/gen/gen-csharp.js +41 -18
- package/help.js +1 -1
- package/init/init-json.js +106 -0
- package/init/init-netcore.js +32 -0
- package/init.js +4 -108
- package/package.json +1 -1
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
|
|
131
|
-
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
|
|
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>
|
|
@@ -5037,6 +5037,10 @@ creatorId: IdRef - optional, mã người tạo
|
|
|
5037
5037
|
holder.appendChild(copyButton);
|
|
5038
5038
|
$(this).prepend(holder);
|
|
5039
5039
|
copyButton.onclick = function() {
|
|
5040
|
+
if (location.protocol !== 'https:' && location.protocol !== 'file:') {
|
|
5041
|
+
alert("Can not copy, please use https protocol!");
|
|
5042
|
+
return;
|
|
5043
|
+
}
|
|
5040
5044
|
const pre = $(this).parent().parent();
|
|
5041
5045
|
const commandBar = $(this).parent().detach();
|
|
5042
5046
|
const content = pre.text();
|
|
@@ -5052,6 +5056,10 @@ creatorId: IdRef - optional, mã người tạo
|
|
|
5052
5056
|
copyButton.innerHTML = "Copy (without comment)";
|
|
5053
5057
|
$(this).prepend(copyButton);
|
|
5054
5058
|
copyButton.onclick = function() {
|
|
5059
|
+
if (location.protocol !== 'https:' && location.protocol !== 'file:') {
|
|
5060
|
+
alert("Can not copy, please use https protocol!");
|
|
5061
|
+
return;
|
|
5062
|
+
}
|
|
5055
5063
|
const pre = $(this).parent().parent();
|
|
5056
5064
|
const commandBar = $(this).parent().detach();
|
|
5057
5065
|
pre.find(".code-comment").each(function() {
|
package/gen/gen-api-docs.js
CHANGED
|
@@ -12,7 +12,7 @@ function processGenDocs(aliasProject, entities, source, html, args, projectName,
|
|
|
12
12
|
const roles = aliasProject.allowRoles.includes("*") ? source.roles : source.roles?.filter(r => aliasProject.allowRoles.includes(r.name));
|
|
13
13
|
|
|
14
14
|
html = html.replace(/^\uFEFF/, '');
|
|
15
|
-
html = html.replace(/<script src="([^"]+)" data-mt-cond='\{"lazy-load": 1\}'><\/script>/g, (scriptTag, src) => `<script data-mt-cond='{"x": 1}'>${fs.readFileSync("
|
|
15
|
+
html = html.replace(/<script src="([^"]+)" data-mt-cond='\{"lazy-load": 1\}'><\/script>/g, (scriptTag, src) => `<script data-mt-cond='{"x": 1}'>${fs.readFileSync(__dirname + "/../docs/" + src).toString()}</script>`);
|
|
16
16
|
html = html.replace("</body>", `<script data-mt-cond='{"x": 1}'>
|
|
17
17
|
window.data.name = ${JSON.stringify(source.name)};
|
|
18
18
|
window.data.description = ${JSON.stringify(source.description)};
|
|
@@ -118,7 +118,7 @@ async function genDocs(args, projectName, project, alias, source) {
|
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
//const html = await fetch('https://api.siten.vn/gen/docs.html').then(res => res.text());
|
|
121
|
-
const html = fs.readFileSync("
|
|
121
|
+
const html = fs.readFileSync(__dirname + "/../docs/docs.html").toString();
|
|
122
122
|
await processGenDocs(aliasProject, entities, source, html, args, projectName, alias);
|
|
123
123
|
}
|
|
124
124
|
|
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
|
|
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;
|
|
@@ -302,7 +304,7 @@ function genCSharpMongoDbClasses(args, projectName, project, alias, source) {
|
|
|
302
304
|
|
|
303
305
|
const className = toCSharpName(entityName);
|
|
304
306
|
collectionNames += ` public static string ${className}CollectionName => "${entities[entityName].storageName}";
|
|
305
|
-
public static
|
|
307
|
+
public static IMongoCollection<Resources.${className}> ${className}Collection => GetDatabase().GetCollection<Resources.${className}>(${className}CollectionName);
|
|
306
308
|
`;
|
|
307
309
|
resourceNames += ` public static string ${className} => "${entityName}";${newLine}`;
|
|
308
310
|
strClasses += generateCSharpClassMongoDb(source, className, entities[entityName].fields, true, entities[entityName].description, out);
|
|
@@ -455,28 +457,32 @@ namespace ${namespace}
|
|
|
455
457
|
${collectionNames}
|
|
456
458
|
public static IMongoDatabase GetDatabase() => Mushroom.MushroomDaoFactory.GetDbAdapter() as IMongoDatabase;
|
|
457
459
|
|
|
458
|
-
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this
|
|
460
|
+
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id) where T : Mushroom.Models.IResource<TId>
|
|
459
461
|
{
|
|
460
462
|
return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id))).FirstOrDefaultAsync();
|
|
461
463
|
}
|
|
462
464
|
|
|
463
|
-
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this
|
|
465
|
+
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id, FindOptions<T> findOptions) where T : Mushroom.Models.IResource<TId>
|
|
464
466
|
{
|
|
465
467
|
return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), findOptions)).FirstOrDefaultAsync();
|
|
466
468
|
}
|
|
467
469
|
|
|
468
|
-
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this
|
|
470
|
+
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id, ProjectionDefinition<T> projection) where T : Mushroom.Models.IResource<TId>
|
|
469
471
|
{
|
|
470
472
|
return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), new FindOptions<T> { Projection = projection })).FirstOrDefaultAsync();
|
|
471
473
|
}
|
|
472
474
|
}
|
|
473
475
|
|
|
474
|
-
public
|
|
476
|
+
public class ResourceNames
|
|
475
477
|
{
|
|
478
|
+
private ResourceNames() { }
|
|
479
|
+
|
|
476
480
|
${resourceNames}
|
|
477
481
|
}
|
|
478
482
|
|
|
479
|
-
public
|
|
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
|
|
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}
|
|
@@ -645,7 +651,20 @@ ${content}
|
|
|
645
651
|
}
|
|
646
652
|
`;
|
|
647
653
|
|
|
648
|
-
|
|
654
|
+
out.allClasses = out.allClasses || [];
|
|
655
|
+
|
|
656
|
+
const normalizedName = className.toLowerCase();
|
|
657
|
+
const duplicate = out.allClasses.find(c => c.normalizedName == normalizedName);
|
|
658
|
+
if (duplicate) {
|
|
659
|
+
fs.appendFileSync(aliasProject.output + "/Resources/" + duplicate.className + ".cs", content);
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
out.allClasses.push({
|
|
663
|
+
className,
|
|
664
|
+
normalizedName
|
|
665
|
+
});
|
|
666
|
+
fs.writeFileSync(aliasProject.output + "/Resources/" + className + ".cs", content);
|
|
667
|
+
}
|
|
649
668
|
}
|
|
650
669
|
|
|
651
670
|
function genCSharpMongoDbClassesToFolder(projectName, alias, source, aliasProject) {
|
|
@@ -685,7 +704,7 @@ function genCSharpMongoDbClassesToFolder(projectName, alias, source, aliasProjec
|
|
|
685
704
|
|
|
686
705
|
const className = toCSharpName(entityName);
|
|
687
706
|
collectionNames += ` public static string ${className}CollectionName => "${entities[entityName].storageName}";
|
|
688
|
-
public static
|
|
707
|
+
public static IMongoCollection<Resources.${className}> ${className}Collection => GetDatabase().GetCollection<Resources.${className}>(${className}CollectionName);
|
|
689
708
|
`;
|
|
690
709
|
resourceNames += ` public static string ${className} => "${entityName}";
|
|
691
710
|
`;
|
|
@@ -825,17 +844,17 @@ namespace ${namespace}
|
|
|
825
844
|
${collectionNames}
|
|
826
845
|
public static IMongoDatabase GetDatabase() => Mushroom.MushroomDaoFactory.GetDbAdapter() as IMongoDatabase;
|
|
827
846
|
|
|
828
|
-
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this
|
|
847
|
+
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id) where T : Mushroom.Models.IResource<TId>
|
|
829
848
|
{
|
|
830
849
|
return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id))).FirstOrDefaultAsync();
|
|
831
850
|
}
|
|
832
851
|
|
|
833
|
-
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this
|
|
852
|
+
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id, FindOptions<T> findOptions) where T : Mushroom.Models.IResource<TId>
|
|
834
853
|
{
|
|
835
854
|
return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), findOptions)).FirstOrDefaultAsync();
|
|
836
855
|
}
|
|
837
856
|
|
|
838
|
-
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this
|
|
857
|
+
public static async System.Threading.Tasks.Task<T> FindByIdAsync<T, TId>(this IMongoCollection<T> collection, TId id, ProjectionDefinition<T> projection) where T : Mushroom.Models.IResource<TId>
|
|
839
858
|
{
|
|
840
859
|
return await (await collection.FindAsync(Builders<T>.Filter.Eq(doc => doc.Id, id), new FindOptions<T> { Projection = projection })).FirstOrDefaultAsync();
|
|
841
860
|
}
|
|
@@ -847,8 +866,10 @@ ${collectionNames}
|
|
|
847
866
|
|
|
848
867
|
namespace ${namespace}
|
|
849
868
|
{
|
|
850
|
-
public
|
|
869
|
+
public class ResourceNames
|
|
851
870
|
{
|
|
871
|
+
private ResourceNames() { }
|
|
872
|
+
|
|
852
873
|
${resourceNames}
|
|
853
874
|
}
|
|
854
875
|
}
|
|
@@ -858,8 +879,10 @@ const roleNamesFileContent = `${header}
|
|
|
858
879
|
|
|
859
880
|
namespace ${namespace}
|
|
860
881
|
{
|
|
861
|
-
public
|
|
882
|
+
public class RoleNames
|
|
862
883
|
{
|
|
884
|
+
private RoleNames() { }
|
|
885
|
+
|
|
863
886
|
${roleNames}
|
|
864
887
|
}
|
|
865
888
|
}
|
|
@@ -946,7 +969,7 @@ function generateCSharpClassDriver(source, className, fields, description, out)
|
|
|
946
969
|
` /// <summary>
|
|
947
970
|
/// ${singleLine(field.description)}
|
|
948
971
|
/// </summary>
|
|
949
|
-
[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" : ""})]
|
|
950
973
|
public ${type} ${propertyName} { get; set; }
|
|
951
974
|
|
|
952
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
|
|
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
|
-
|
|
8
|
-
|
|
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:
|