beech-api 3.8.0 → 3.9.75
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/LICENSE +21 -21
- package/README.md +1715 -1244
- package/index.js +2 -2
- package/package.json +92 -83
- package/packages/cli/beech +9 -10
- package/packages/cli/bin/beech-app.js +389 -389
- package/packages/cli/bin/beech-service.js +262 -132
- package/packages/cli/core/auth/Credentials.js +174 -147
- package/packages/cli/core/auth/Passport.js +664 -592
- package/packages/cli/core/auth/_Request.js +12 -12
- package/packages/cli/core/configure/_gitignore +16 -15
- package/packages/cli/core/configure/_sequelizerc +9 -9
- package/packages/cli/core/configure/app.config-basic.js +55 -55
- package/packages/cli/core/configure/app.config-sequelize.js +88 -88
- package/packages/cli/core/configure/beech.config.js +9 -9
- package/packages/cli/core/configure/global.config-basic.js +8 -8
- package/packages/cli/core/configure/global.config-sequelize.js +8 -8
- package/packages/cli/core/configure/jest.config.js +6 -6
- package/packages/cli/core/configure/jsconfig.json +8 -7
- package/packages/cli/core/configure/passport.config.js +97 -97
- package/packages/cli/core/databases/mysql.js +94 -95
- package/packages/cli/core/databases/sequelize.js +187 -179
- package/packages/cli/core/databases/test.js +251 -170
- package/packages/cli/core/file-walk/file-walk.js +35 -35
- package/packages/cli/core/generator/_endpoints +15 -15
- package/packages/cli/core/generator/_endpoints_basic +42 -42
- package/packages/cli/core/generator/_help +26 -18
- package/packages/cli/core/generator/_help_create +10 -10
- package/packages/cli/core/generator/_help_service +10 -10
- package/packages/cli/core/generator/_helpers +9 -9
- package/packages/cli/core/generator/_helpers_basic +22 -22
- package/packages/cli/core/generator/_models +6 -29
- package/packages/cli/core/generator/_models_basic +13 -22
- package/packages/cli/core/generator/_package +23 -20
- package/packages/cli/core/generator/_scheduler +32 -22
- package/packages/cli/core/generator/_spec +29 -29
- package/packages/cli/core/generator/index.js +1081 -738
- package/packages/cli/core/helpers/2fa.js +106 -85
- package/packages/cli/core/helpers/math.js +115 -103
- package/packages/cli/core/helpers/poolEntity.js +103 -59
- package/packages/cli/core/index.js +264 -188
- package/packages/cli/core/middleware/express/duplicateRequest.js +16 -12
- package/packages/cli/core/middleware/express/jwtCheckAllow.js +86 -68
- package/packages/cli/core/middleware/express/rateLimit.js +29 -17
- package/packages/cli/core/middleware/express/slowDown.js +2 -2
- package/packages/cli/core/middleware/index.js +6 -6
- package/packages/cli/core/middleware/origin/guard/advance.js +75 -74
- package/packages/cli/core/middleware/origin/whitelist/cors.js +94 -94
- package/packages/cli/core/services/http.express.js +481 -441
- package/packages/cli/core/test/check-node.js +21 -0
- package/packages/cli/core/test/utils.js +7 -7
- package/packages/cli/entry +10 -0
- package/packages/lib/index.js +6 -6
- package/packages/lib/src/endpoint.js +947 -532
- package/packages/lib/src/guard.js +60 -60
- package/packages/lib/src/salt.js +3 -3
- package/packages/lib/src/schema.js +96 -93
- package/packages/lib/src/specificExpress.js +7 -7
- package/packages/lib/src/user.js +271 -271
|
@@ -1,391 +1,391 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const logUpdate = require("log-update");
|
|
3
|
-
const clear = require("cli-clear");
|
|
4
|
-
const inquirer = require('inquirer');
|
|
5
|
-
|
|
6
|
-
class Beech {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.embed(process.argv)
|
|
9
|
-
.then(() => this.init()
|
|
10
|
-
.then(status => console.log(status))
|
|
11
|
-
.catch(err => {
|
|
12
|
-
throw err;
|
|
13
|
-
})
|
|
14
|
-
);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
init() {
|
|
18
|
-
return new Promise((resolve, reject) => {
|
|
19
|
-
try {
|
|
20
|
-
if (this.option == "-v" || this.option == "--version") {
|
|
21
|
-
// check beech version
|
|
22
|
-
resolve("v" + require(__dirname + "/../../../package.json").version);
|
|
23
|
-
} else if (this.option == "-h" || this.option == "?" || this.option == "--help") {
|
|
24
|
-
// help for see avaliable command
|
|
25
|
-
this.help()
|
|
26
|
-
.then(help => resolve(help))
|
|
27
|
-
.catch(err => reject(err));
|
|
28
|
-
} else if (this.option == "create") {
|
|
29
|
-
// declare temp file and paste file
|
|
30
|
-
let tmpPackageFile = __dirname + '/../core/generator/_package';
|
|
31
|
-
let pastePackageFile = this.argument + '/package.json';
|
|
32
|
-
let tmpConfigFile = __dirname + '/../core/configure/app.config-basic.js';
|
|
33
|
-
let pasteConfigFile = this.argument + '/app.config.js';
|
|
34
|
-
let tmpJestFile = __dirname + '/../core/configure/jest.config.js';
|
|
35
|
-
let pasteJestFile = this.argument + '/jest.config.js';
|
|
36
|
-
let tmpJsConfigFile = __dirname + '/../core/configure/jsconfig.json';
|
|
37
|
-
let pasteJsConfigFile = this.argument + '/jsconfig.json';
|
|
38
|
-
let tmpDotSequelizercFile = __dirname + '/../core/configure/_sequelizerc';
|
|
39
|
-
let pasteDotSequelizercFile = this.argument + '/.sequelizerc';
|
|
40
|
-
let tmpGloablConfigFile = __dirname + '/../core/configure/global.config-basic.js';
|
|
41
|
-
let pasteGloablConfigFile = this.argument + '/global.config.js';
|
|
42
|
-
let tmpGitignoreFile = __dirname + '/../core/configure/_gitignore';
|
|
43
|
-
let pasteGitignoreFile = this.argument + '/.gitignore';
|
|
44
|
-
let tmpBeechConfigFile = __dirname + '/../core/configure/beech.config.js';
|
|
45
|
-
let pasteBeechConfigFile = this.argument + '/beech.config.js';
|
|
46
|
-
// start log clear screen
|
|
47
|
-
clear();
|
|
48
|
-
logUpdate("[94mBeech CLI v" + require(__dirname + "/../../../package.json").version);
|
|
49
|
-
// check argument project name
|
|
50
|
-
if (this.argument) {
|
|
51
|
-
if (!this.fs.existsSync(this.argument)) {
|
|
52
|
-
inquirer.prompt([ {
|
|
53
|
-
type: "list",
|
|
54
|
-
name: "sql",
|
|
55
|
-
message: "[93mPlease pick a
|
|
56
|
-
choices: [ "Basic (mysql only)", "Sequelize (mysql, sqlite, mariadb, postgres, mssql)" ],
|
|
57
|
-
} ]).then(async resSql => {
|
|
58
|
-
if (resSql.sql.split(' ')[ 0 ] != "Basic") {
|
|
59
|
-
tmpGloablConfigFile = await __dirname + '/../core/configure/global.config-sequelize.js';
|
|
60
|
-
tmpConfigFile = await __dirname + '/../core/configure/app.config-sequelize.js';
|
|
61
|
-
}
|
|
62
|
-
inquirer.prompt([ {
|
|
63
|
-
type: "checkbox",
|
|
64
|
-
name: "freature",
|
|
65
|
-
message: "[93mCheck the features needed for your project:[0m",
|
|
66
|
-
choices: [ "Job Scheduler", "Basic Helper", "Passport / JWT / Official Strategy Google, Facebook" ],
|
|
67
|
-
} ]).then(resFreat => {
|
|
68
|
-
logUpdate(": Initialize...");
|
|
69
|
-
setTimeout(() => {
|
|
70
|
-
// init project
|
|
71
|
-
this.makeFolder(this.argument)
|
|
72
|
-
.then(this.copy.bind(this, tmpPackageFile, pastePackageFile))
|
|
73
|
-
//.then(this.contentReplace.bind(this, pastePackageFile, { 'application': this.argument }))
|
|
74
|
-
.then(this.copy.bind(this, tmpConfigFile, pasteConfigFile))
|
|
75
|
-
.then(this.copy.bind(this, tmpJestFile, pasteJestFile))
|
|
76
|
-
.then(this.copy.bind(this, tmpJsConfigFile, pasteJsConfigFile))
|
|
77
|
-
.then(this.copy.bind(this, tmpDotSequelizercFile, pasteDotSequelizercFile))
|
|
78
|
-
.then(this.copy.bind(this, tmpGloablConfigFile, pasteGloablConfigFile))
|
|
79
|
-
.then(this.copy.bind(this, tmpGitignoreFile, pasteGitignoreFile))
|
|
80
|
-
.then(this.copy.bind(this, tmpBeechConfigFile, pasteBeechConfigFile))
|
|
81
|
-
.then(this.contentReplace.bind(this, pastePackageFile, { 'application': this.argument }))
|
|
82
|
-
.then(this.generateKeyConfigFile.bind(this, this.argument))
|
|
83
|
-
.then(this.installPackage.bind(this, this.argument, resFreat.freature))
|
|
84
|
-
.then(console.log("\n[104m [37mProcessing [0m [0m The Application `" + this.argument + "` is creating...\n"))
|
|
85
|
-
.catch((err) => {
|
|
86
|
-
throw err;
|
|
87
|
-
});
|
|
88
|
-
}, 2000);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
} else {
|
|
92
|
-
resolve("\n[103m[90m Warning [0m[0m The project `" + this.argument + "` it's duplicated.");
|
|
93
|
-
}
|
|
94
|
-
} else {
|
|
95
|
-
resolve("\n[103m[90m Warning [0m[0m Please specify your project name.");
|
|
96
|
-
}
|
|
97
|
-
} else if (this.option == "update") {
|
|
98
|
-
// upgrade the beech-api package
|
|
99
|
-
let isGlobalNpm = "npm install beech-api";
|
|
100
|
-
let isGlobalYarn = "yarn add beech-api";
|
|
101
|
-
let processUpdate = null;
|
|
102
|
-
let lineStdout = "";
|
|
103
|
-
if (this.argument == '-g' || this.argument == '--global') {
|
|
104
|
-
isGlobalNpm = "npm install beech-api -g --force";
|
|
105
|
-
isGlobalYarn = "yarn global add beech-api";
|
|
106
|
-
}
|
|
107
|
-
// prompt select
|
|
108
|
-
inquirer.prompt([ {
|
|
109
|
-
type: "list",
|
|
110
|
-
name: "package",
|
|
111
|
-
message: "[93mPlease pick a package control:[0m",
|
|
112
|
-
choices: [ "NPM", "Yarn" ],
|
|
113
|
-
} ]).then(selectedPackage => {
|
|
114
|
-
logUpdate(": Initialize...");
|
|
115
|
-
// delay for update package
|
|
116
|
-
setTimeout(() => {
|
|
117
|
-
if(selectedPackage.package == "NPM") {
|
|
118
|
-
processUpdate = this.cmd.get(isGlobalNpm, (err) => {
|
|
119
|
-
if (err) {
|
|
120
|
-
logUpdate("\n[101m OperationalError [0m The operation was rejected by your operating system. \n[91mEPERM:[0m operation not permitted CMD: '[93mnpm install beech-api -g --force[0m'");
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
// npm install line shoutout
|
|
124
|
-
processUpdate.stdout.on('data', (npmData) => {
|
|
125
|
-
lineStdout += npmData;
|
|
126
|
-
if (lineStdout[ lineStdout.length - 1 ] == '\n') {
|
|
127
|
-
logUpdate('\n' + lineStdout);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
} else if(selectedPackage.package == "Yarn") {
|
|
131
|
-
processUpdate = this.cmd.get(isGlobalYarn, (err) => {
|
|
132
|
-
if (err) { throw err }
|
|
133
|
-
});
|
|
134
|
-
// yarn install line shoutout
|
|
135
|
-
processUpdate.stdout.on('data', (yarnData) => {
|
|
136
|
-
lineStdout += yarnData;
|
|
137
|
-
if (lineStdout[ lineStdout.length - 1 ] == '\n') {
|
|
138
|
-
logUpdate('\n' + lineStdout);
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
} else {
|
|
142
|
-
logUpdate("\n[101m
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
}, 1000);
|
|
146
|
-
});
|
|
147
|
-
} else {
|
|
148
|
-
// help for see avaliable command
|
|
149
|
-
this.help()
|
|
150
|
-
.then(help => resolve(help))
|
|
151
|
-
.catch(err => reject(err));
|
|
152
|
-
}
|
|
153
|
-
} catch (error) {
|
|
154
|
-
throw error;
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
installPackage(argument, freatureArr) {
|
|
160
|
-
return new Promise((resolve, reject) => {
|
|
161
|
-
try {
|
|
162
|
-
// install freature
|
|
163
|
-
this.installFreature(argument, freatureArr)
|
|
164
|
-
.then(res => {
|
|
165
|
-
if (res) {
|
|
166
|
-
let lineStdout = "";
|
|
167
|
-
let processYarn = this.cmd.get('cd ' + argument + ' && yarn install', (err, data) => {
|
|
168
|
-
if (err) {
|
|
169
|
-
this.cmd.get('cd ' + argument + ' && npm install', (err, data) => {
|
|
170
|
-
if (err) { throw err }
|
|
171
|
-
resolve(data);
|
|
172
|
-
this.successfully();
|
|
173
|
-
});
|
|
174
|
-
} else {
|
|
175
|
-
resolve(data);
|
|
176
|
-
this.successfully();
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
// yarn install line shoutout
|
|
180
|
-
processYarn.stdout.on('data', (yarnData) => {
|
|
181
|
-
lineStdout += yarnData;
|
|
182
|
-
if (lineStdout[ lineStdout.length - 1 ] == '\n') {
|
|
183
|
-
logUpdate('\n' + lineStdout);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
} else {
|
|
187
|
-
logUpdate("\n[101m
|
|
188
|
-
}
|
|
189
|
-
})
|
|
190
|
-
.catch(err => reject(err));
|
|
191
|
-
} catch (error) {
|
|
192
|
-
reject(error);
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
installFreature(argument, freatureArr) {
|
|
198
|
-
return new Promise((resolve, reject) => {
|
|
199
|
-
try {
|
|
200
|
-
let helperPath = argument + '/src/helpers/';
|
|
201
|
-
let tmpBasicHelperFile = __dirname + '/../core/generator/_helpers_basic';
|
|
202
|
-
let pasteBasicHelperFile = helperPath + '/Basic.js';
|
|
203
|
-
let freatureLength = freatureArr.length;
|
|
204
|
-
if (freatureLength) {
|
|
205
|
-
freatureArr.map((f, key) => {
|
|
206
|
-
if (f.split(' ')[ 0 ] == "Job") {
|
|
207
|
-
(process.env.NODE_ENV == "development") ? this.cmd.get('cd ' + argument + ' && node cli/bin/beech-app.js skd init') : this.cmd.get('cd ' + argument + ' && beech skd init');
|
|
208
|
-
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Job Scheduler");
|
|
209
|
-
}
|
|
210
|
-
if (f.split(' ')[ 0 ] == "Basic") {
|
|
211
|
-
this.makeFolder(helperPath).then(this.copy.bind(this, tmpBasicHelperFile, pasteBasicHelperFile))
|
|
212
|
-
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Basic helper");
|
|
213
|
-
}
|
|
214
|
-
if (f.split(' ')[ 0 ] == "Passport") {
|
|
215
|
-
(process.env.NODE_ENV == "development") ? this.cmd.get('cd ' + argument + ' && node cli/bin/beech-app.js passport init') : this.cmd.get('cd ' + argument + ' && beech passport init');
|
|
216
|
-
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Passport JWT, Official strategy Google, Facebook");
|
|
217
|
-
}
|
|
218
|
-
if (freatureArr.length == (key + 1)) {
|
|
219
|
-
resolve(true);
|
|
220
|
-
}
|
|
221
|
-
});
|
|
222
|
-
} else {
|
|
223
|
-
resolve(true);
|
|
224
|
-
}
|
|
225
|
-
} catch (error) {
|
|
226
|
-
reject(error);
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
successfully() {
|
|
232
|
-
clear();
|
|
233
|
-
console.log("[94mBeech CLI v" + require(__dirname + "/../../../package.json").version);
|
|
234
|
-
console.log('\n[102m[90m Passed [0m[0m The project has been successfully created.\n\n [37m$[0m [36mcd ' + this.argument + '[0m\n [37m$[0m [36mnpm
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async contentReplace(pathFile, textCondition) {
|
|
238
|
-
return new Promise((resolve, reject) => {
|
|
239
|
-
try {
|
|
240
|
-
// delay for generator
|
|
241
|
-
setTimeout(() => {
|
|
242
|
-
this.fs.readFile(pathFile, 'utf8', (err, data) => {
|
|
243
|
-
if (err) {
|
|
244
|
-
reject(err);
|
|
245
|
-
} else {
|
|
246
|
-
let application = textCondition.application;
|
|
247
|
-
// content replace
|
|
248
|
-
let text = data.replace(new RegExp('application', 'g'), application);
|
|
249
|
-
// writing the file
|
|
250
|
-
this.fs.writeFile(pathFile, text, 'utf8', (err) => {
|
|
251
|
-
if (err) {
|
|
252
|
-
reject(err);
|
|
253
|
-
} else {
|
|
254
|
-
resolve("\n[102m[90m Passed [0m[0m The application `" + application + "` it's create successfully.");
|
|
255
|
-
}
|
|
256
|
-
})
|
|
257
|
-
}
|
|
258
|
-
})
|
|
259
|
-
}, 1500);
|
|
260
|
-
} catch (error) {
|
|
261
|
-
reject(error);
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
async makeFolder(path) {
|
|
267
|
-
/**
|
|
268
|
-
* @param path path to make
|
|
269
|
-
*
|
|
270
|
-
* @return new full path
|
|
271
|
-
*
|
|
272
|
-
*/
|
|
273
|
-
return new Promise((resolve, reject) => {
|
|
274
|
-
try {
|
|
275
|
-
const mkdirp = require("mkdirp");
|
|
276
|
-
mkdirp(path)
|
|
277
|
-
.then(p => resolve(p))
|
|
278
|
-
.catch(err => reject(err));
|
|
279
|
-
} catch (error) {
|
|
280
|
-
reject(error);
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async copy(path, to) {
|
|
286
|
-
/**
|
|
287
|
-
* @param path old path file
|
|
288
|
-
* @param to save to new path file
|
|
289
|
-
*
|
|
290
|
-
* @return new path file
|
|
291
|
-
*/
|
|
292
|
-
return new Promise((resolve, reject) => {
|
|
293
|
-
try {
|
|
294
|
-
if (this.fs.createReadStream(path).pipe(this.fs.createWriteStream(to))) {
|
|
295
|
-
resolve(to);
|
|
296
|
-
} else {
|
|
297
|
-
reject(err);
|
|
298
|
-
}
|
|
299
|
-
} catch (error) {
|
|
300
|
-
reject(error);
|
|
301
|
-
}
|
|
302
|
-
});
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
appKeyGenerator(length) {
|
|
306
|
-
return new Promise((resolve, reject) => {
|
|
307
|
-
try {
|
|
308
|
-
let md5 = require("md5");
|
|
309
|
-
let secret = require(__dirname + "/../../lib/src/salt").salt;
|
|
310
|
-
let result = '';
|
|
311
|
-
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
312
|
-
let charactersLength = characters.length;
|
|
313
|
-
for (var i = 0; i < length; i++) {
|
|
314
|
-
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
315
|
-
}
|
|
316
|
-
resolve(md5(result + secret));
|
|
317
|
-
} catch (error) {
|
|
318
|
-
reject(error);
|
|
319
|
-
}
|
|
320
|
-
});
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
generateKeyConfigFile(pjName) {
|
|
324
|
-
return new Promise((resolve, reject) => {
|
|
325
|
-
try {
|
|
326
|
-
this.fs.readFile(pjName + "/app.config.js", 'utf8', (err, data) => {
|
|
327
|
-
if (err) {
|
|
328
|
-
throw err;
|
|
329
|
-
} else {
|
|
330
|
-
// edit or add property
|
|
331
|
-
let buffer = Buffer.from(data);
|
|
332
|
-
let buf2str = buffer.toString();
|
|
333
|
-
let buf2json = JSON.parse(JSON.stringify(buf2str));
|
|
334
|
-
let buf2eval = eval(buf2json);
|
|
335
|
-
let oldKey = buf2eval.main_config.app_key;
|
|
336
|
-
// generate new key
|
|
337
|
-
this.appKeyGenerator(8).then(newAppKey => {
|
|
338
|
-
// content replace
|
|
339
|
-
let text = data.replace(new RegExp(oldKey, 'g'), newAppKey);
|
|
340
|
-
// writing the file
|
|
341
|
-
this.fs.writeFile(pjName + "/app.config.js", text, 'utf8', (err) => {
|
|
342
|
-
if (err) {
|
|
343
|
-
throw err;
|
|
344
|
-
} else {
|
|
345
|
-
resolve("\n[102m[90m Passed [0m[0m App key it's new generated.");
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
} catch (error) {
|
|
352
|
-
reject(error);
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
help() {
|
|
358
|
-
return new Promise((resolve, reject) => {
|
|
359
|
-
try {
|
|
360
|
-
this.fs.readFile(__dirname + "/../core/generator/_help_create", "utf8", (err, data) => {
|
|
361
|
-
if (err) {
|
|
362
|
-
reject(err);
|
|
363
|
-
} else {
|
|
364
|
-
resolve(data);
|
|
365
|
-
}
|
|
366
|
-
});
|
|
367
|
-
} catch (error) {
|
|
368
|
-
reject(error);
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
embed(argv) {
|
|
374
|
-
return new Promise((resolve, reject) => {
|
|
375
|
-
try {
|
|
376
|
-
this.fs = require("fs");
|
|
377
|
-
this.cmd = require('node-cmd');
|
|
378
|
-
this.argv = argv;
|
|
379
|
-
this.option = argv[ 2 ];
|
|
380
|
-
this.argument = argv[ 3 ];
|
|
381
|
-
this.special = argv[ 4 ];
|
|
382
|
-
this.extra = argv[ 5 ];
|
|
383
|
-
resolve(this);
|
|
384
|
-
} catch (error) {
|
|
385
|
-
reject(error);
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
2
|
+
const logUpdate = require("log-update");
|
|
3
|
+
const clear = require("cli-clear");
|
|
4
|
+
const inquirer = require('inquirer');
|
|
5
|
+
|
|
6
|
+
class Beech {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.embed(process.argv)
|
|
9
|
+
.then(() => this.init()
|
|
10
|
+
.then(status => console.log(status))
|
|
11
|
+
.catch(err => {
|
|
12
|
+
throw err;
|
|
13
|
+
})
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
init() {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
try {
|
|
20
|
+
if (this.option == "-v" || this.option == "--version") {
|
|
21
|
+
// check beech version
|
|
22
|
+
resolve("v" + require(__dirname + "/../../../package.json").version);
|
|
23
|
+
} else if (this.option == "-h" || this.option == "?" || this.option == "--help") {
|
|
24
|
+
// help for see avaliable command
|
|
25
|
+
this.help()
|
|
26
|
+
.then(help => resolve(help))
|
|
27
|
+
.catch(err => reject(err));
|
|
28
|
+
} else if (this.option == "create") {
|
|
29
|
+
// declare temp file and paste file
|
|
30
|
+
let tmpPackageFile = __dirname + '/../core/generator/_package';
|
|
31
|
+
let pastePackageFile = this.argument + '/package.json';
|
|
32
|
+
let tmpConfigFile = __dirname + '/../core/configure/app.config-basic.js';
|
|
33
|
+
let pasteConfigFile = this.argument + '/app.config.js';
|
|
34
|
+
let tmpJestFile = __dirname + '/../core/configure/jest.config.js';
|
|
35
|
+
let pasteJestFile = this.argument + '/jest.config.js';
|
|
36
|
+
let tmpJsConfigFile = __dirname + '/../core/configure/jsconfig.json';
|
|
37
|
+
let pasteJsConfigFile = this.argument + '/jsconfig.json';
|
|
38
|
+
let tmpDotSequelizercFile = __dirname + '/../core/configure/_sequelizerc';
|
|
39
|
+
let pasteDotSequelizercFile = this.argument + '/.sequelizerc';
|
|
40
|
+
let tmpGloablConfigFile = __dirname + '/../core/configure/global.config-basic.js';
|
|
41
|
+
let pasteGloablConfigFile = this.argument + '/global.config.js';
|
|
42
|
+
let tmpGitignoreFile = __dirname + '/../core/configure/_gitignore';
|
|
43
|
+
let pasteGitignoreFile = this.argument + '/.gitignore';
|
|
44
|
+
let tmpBeechConfigFile = __dirname + '/../core/configure/beech.config.js';
|
|
45
|
+
let pasteBeechConfigFile = this.argument + '/beech.config.js';
|
|
46
|
+
// start log clear screen
|
|
47
|
+
clear();
|
|
48
|
+
logUpdate("[94mBeech CLI v" + require(__dirname + "/../../../package.json").version);
|
|
49
|
+
// check argument project name
|
|
50
|
+
if (this.argument) {
|
|
51
|
+
if (!this.fs.existsSync(this.argument)) {
|
|
52
|
+
inquirer.prompt([ {
|
|
53
|
+
type: "list",
|
|
54
|
+
name: "sql",
|
|
55
|
+
message: "[93mPlease pick a pool base engine:[0m",
|
|
56
|
+
choices: [ "Basic (mysql only)", "Sequelize ORM tool (mysql, sqlite, mariadb, postgres, mssql)" ],
|
|
57
|
+
} ]).then(async resSql => {
|
|
58
|
+
if (resSql.sql.split(' ')[ 0 ] != "Basic") {
|
|
59
|
+
tmpGloablConfigFile = await __dirname + '/../core/configure/global.config-sequelize.js';
|
|
60
|
+
tmpConfigFile = await __dirname + '/../core/configure/app.config-sequelize.js';
|
|
61
|
+
}
|
|
62
|
+
inquirer.prompt([ {
|
|
63
|
+
type: "checkbox",
|
|
64
|
+
name: "freature",
|
|
65
|
+
message: "[93mCheck the features needed for your project:[0m",
|
|
66
|
+
choices: [ "Job Scheduler", "Basic Helper", "Passport / JWT / Official Strategy Google, Facebook" ],
|
|
67
|
+
} ]).then(resFreat => {
|
|
68
|
+
logUpdate(": Initialize...");
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
// init project
|
|
71
|
+
this.makeFolder(this.argument)
|
|
72
|
+
.then(this.copy.bind(this, tmpPackageFile, pastePackageFile))
|
|
73
|
+
//.then(this.contentReplace.bind(this, pastePackageFile, { 'application': this.argument }))
|
|
74
|
+
.then(this.copy.bind(this, tmpConfigFile, pasteConfigFile))
|
|
75
|
+
.then(this.copy.bind(this, tmpJestFile, pasteJestFile))
|
|
76
|
+
.then(this.copy.bind(this, tmpJsConfigFile, pasteJsConfigFile))
|
|
77
|
+
.then(this.copy.bind(this, tmpDotSequelizercFile, pasteDotSequelizercFile))
|
|
78
|
+
.then(this.copy.bind(this, tmpGloablConfigFile, pasteGloablConfigFile))
|
|
79
|
+
.then(this.copy.bind(this, tmpGitignoreFile, pasteGitignoreFile))
|
|
80
|
+
.then(this.copy.bind(this, tmpBeechConfigFile, pasteBeechConfigFile))
|
|
81
|
+
.then(this.contentReplace.bind(this, pastePackageFile, { 'application': this.argument }))
|
|
82
|
+
.then(this.generateKeyConfigFile.bind(this, this.argument))
|
|
83
|
+
.then(this.installPackage.bind(this, this.argument, resFreat.freature))
|
|
84
|
+
.then(console.log("\n[104m [37mProcessing [0m [0m The Application `" + this.argument + "` is creating...\n"))
|
|
85
|
+
.catch((err) => {
|
|
86
|
+
throw err;
|
|
87
|
+
});
|
|
88
|
+
}, 2000);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
} else {
|
|
92
|
+
resolve("\n[103m[90m Warning [0m[0m The project `" + this.argument + "` it's duplicated.");
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
resolve("\n[103m[90m Warning [0m[0m Please specify your project name.");
|
|
96
|
+
}
|
|
97
|
+
} else if (this.option == "update") {
|
|
98
|
+
// upgrade the beech-api package
|
|
99
|
+
let isGlobalNpm = "npm install beech-api@latest";
|
|
100
|
+
let isGlobalYarn = "yarn add beech-api@latest";
|
|
101
|
+
let processUpdate = null;
|
|
102
|
+
let lineStdout = "";
|
|
103
|
+
if (this.argument == '-g' || this.argument == '--global') {
|
|
104
|
+
isGlobalNpm = "npm install beech-api@latest -g --force";
|
|
105
|
+
isGlobalYarn = "yarn global add beech-api@latest";
|
|
106
|
+
}
|
|
107
|
+
// prompt select
|
|
108
|
+
inquirer.prompt([ {
|
|
109
|
+
type: "list",
|
|
110
|
+
name: "package",
|
|
111
|
+
message: "[93mPlease pick a package control:[0m",
|
|
112
|
+
choices: [ "NPM", "Yarn" ],
|
|
113
|
+
} ]).then(selectedPackage => {
|
|
114
|
+
logUpdate(": Initialize...");
|
|
115
|
+
// delay for update package
|
|
116
|
+
setTimeout(() => {
|
|
117
|
+
if(selectedPackage.package == "NPM") {
|
|
118
|
+
processUpdate = this.cmd.get(isGlobalNpm, (err) => {
|
|
119
|
+
if (err) {
|
|
120
|
+
logUpdate("\n[101m OperationalError [0m The operation was rejected by your operating system. \n[91mEPERM:[0m operation not permitted CMD: '[93mnpm install beech-api -g --force[0m'");
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
// npm install line shoutout
|
|
124
|
+
processUpdate.stdout.on('data', (npmData) => {
|
|
125
|
+
lineStdout += npmData;
|
|
126
|
+
if (lineStdout[ lineStdout.length - 1 ] == '\n') {
|
|
127
|
+
logUpdate('\n' + lineStdout);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
} else if(selectedPackage.package == "Yarn") {
|
|
131
|
+
processUpdate = this.cmd.get(isGlobalYarn, (err) => {
|
|
132
|
+
if (err) { throw err }
|
|
133
|
+
});
|
|
134
|
+
// yarn install line shoutout
|
|
135
|
+
processUpdate.stdout.on('data', (yarnData) => {
|
|
136
|
+
lineStdout += yarnData;
|
|
137
|
+
if (lineStdout[ lineStdout.length - 1 ] == '\n') {
|
|
138
|
+
logUpdate('\n' + lineStdout);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
} else {
|
|
142
|
+
logUpdate("\n[101m Fatal [0m Catch update package. Try again...");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
}, 1000);
|
|
146
|
+
});
|
|
147
|
+
} else {
|
|
148
|
+
// help for see avaliable command
|
|
149
|
+
this.help()
|
|
150
|
+
.then(help => resolve(help))
|
|
151
|
+
.catch(err => reject(err));
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
installPackage(argument, freatureArr) {
|
|
160
|
+
return new Promise((resolve, reject) => {
|
|
161
|
+
try {
|
|
162
|
+
// install freature
|
|
163
|
+
this.installFreature(argument, freatureArr)
|
|
164
|
+
.then(res => {
|
|
165
|
+
if (res) {
|
|
166
|
+
let lineStdout = "";
|
|
167
|
+
let processYarn = this.cmd.get('cd ' + argument + ' && npm install yarn -g && yarn install && npm install', (err, data) => {
|
|
168
|
+
if (err) {
|
|
169
|
+
this.cmd.get('cd ' + argument + ' && npm install', (err, data) => {
|
|
170
|
+
if (err) { throw err }
|
|
171
|
+
resolve(data);
|
|
172
|
+
this.successfully();
|
|
173
|
+
});
|
|
174
|
+
} else {
|
|
175
|
+
resolve(data);
|
|
176
|
+
this.successfully();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
// yarn install line shoutout
|
|
180
|
+
processYarn.stdout.on('data', (yarnData) => {
|
|
181
|
+
lineStdout += yarnData;
|
|
182
|
+
if (lineStdout[ lineStdout.length - 1 ] == '\n') {
|
|
183
|
+
logUpdate('\n' + lineStdout);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
} else {
|
|
187
|
+
logUpdate("\n[101m Fatal [0m Can't install freature. Try again...");
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
.catch(err => reject(err));
|
|
191
|
+
} catch (error) {
|
|
192
|
+
reject(error);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
installFreature(argument, freatureArr) {
|
|
198
|
+
return new Promise((resolve, reject) => {
|
|
199
|
+
try {
|
|
200
|
+
let helperPath = argument + '/src/helpers/';
|
|
201
|
+
let tmpBasicHelperFile = __dirname + '/../core/generator/_helpers_basic';
|
|
202
|
+
let pasteBasicHelperFile = helperPath + '/Basic.js';
|
|
203
|
+
let freatureLength = freatureArr.length;
|
|
204
|
+
if (freatureLength) {
|
|
205
|
+
freatureArr.map((f, key) => {
|
|
206
|
+
if (f.split(' ')[ 0 ] == "Job") {
|
|
207
|
+
(process.env.NODE_ENV == "development") ? this.cmd.get('cd ' + argument + ' && node cli/bin/beech-app.js skd init') : this.cmd.get('cd ' + argument + ' && beech skd init');
|
|
208
|
+
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Job Scheduler");
|
|
209
|
+
}
|
|
210
|
+
if (f.split(' ')[ 0 ] == "Basic") {
|
|
211
|
+
this.makeFolder(helperPath).then(this.copy.bind(this, tmpBasicHelperFile, pasteBasicHelperFile))
|
|
212
|
+
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Basic helper");
|
|
213
|
+
}
|
|
214
|
+
if (f.split(' ')[ 0 ] == "Passport") {
|
|
215
|
+
(process.env.NODE_ENV == "development") ? this.cmd.get('cd ' + argument + ' && node cli/bin/beech-app.js passport init') : this.cmd.get('cd ' + argument + ' && beech passport init');
|
|
216
|
+
console.log("[" + (key + 1) + "/" + freatureLength + "] Installing Passport JWT, Official strategy Google, Facebook");
|
|
217
|
+
}
|
|
218
|
+
if (freatureArr.length == (key + 1)) {
|
|
219
|
+
resolve(true);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
} else {
|
|
223
|
+
resolve(true);
|
|
224
|
+
}
|
|
225
|
+
} catch (error) {
|
|
226
|
+
reject(error);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
successfully() {
|
|
232
|
+
clear();
|
|
233
|
+
console.log("[94mBeech CLI v" + require(__dirname + "/../../../package.json").version);
|
|
234
|
+
console.log('\n[102m[90m Passed [0m[0m The project has been successfully created.\n\n [37m$[0m [36mcd ' + this.argument + '[0m\n [37m$[0m [36mnpm run dev[0m or [36myarn dev[0m\n');
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async contentReplace(pathFile, textCondition) {
|
|
238
|
+
return new Promise((resolve, reject) => {
|
|
239
|
+
try {
|
|
240
|
+
// delay for generator
|
|
241
|
+
setTimeout(() => {
|
|
242
|
+
this.fs.readFile(pathFile, 'utf8', (err, data) => {
|
|
243
|
+
if (err) {
|
|
244
|
+
reject(err);
|
|
245
|
+
} else {
|
|
246
|
+
let application = textCondition.application;
|
|
247
|
+
// content replace
|
|
248
|
+
let text = data.replace(new RegExp('application', 'g'), application);
|
|
249
|
+
// writing the file
|
|
250
|
+
this.fs.writeFile(pathFile, text, 'utf8', (err) => {
|
|
251
|
+
if (err) {
|
|
252
|
+
reject(err);
|
|
253
|
+
} else {
|
|
254
|
+
resolve("\n[102m[90m Passed [0m[0m The application `" + application + "` it's create successfully.");
|
|
255
|
+
}
|
|
256
|
+
})
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
}, 1500);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
reject(error);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async makeFolder(path) {
|
|
267
|
+
/**
|
|
268
|
+
* @param path path to make
|
|
269
|
+
*
|
|
270
|
+
* @return new full path
|
|
271
|
+
*
|
|
272
|
+
*/
|
|
273
|
+
return new Promise((resolve, reject) => {
|
|
274
|
+
try {
|
|
275
|
+
const mkdirp = require("mkdirp");
|
|
276
|
+
mkdirp(path)
|
|
277
|
+
.then(p => resolve(p))
|
|
278
|
+
.catch(err => reject(err));
|
|
279
|
+
} catch (error) {
|
|
280
|
+
reject(error);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async copy(path, to) {
|
|
286
|
+
/**
|
|
287
|
+
* @param path old path file
|
|
288
|
+
* @param to save to new path file
|
|
289
|
+
*
|
|
290
|
+
* @return new path file
|
|
291
|
+
*/
|
|
292
|
+
return new Promise((resolve, reject) => {
|
|
293
|
+
try {
|
|
294
|
+
if (this.fs.createReadStream(path).pipe(this.fs.createWriteStream(to))) {
|
|
295
|
+
resolve(to);
|
|
296
|
+
} else {
|
|
297
|
+
reject(err);
|
|
298
|
+
}
|
|
299
|
+
} catch (error) {
|
|
300
|
+
reject(error);
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
appKeyGenerator(length) {
|
|
306
|
+
return new Promise((resolve, reject) => {
|
|
307
|
+
try {
|
|
308
|
+
let md5 = require("md5");
|
|
309
|
+
let secret = require(__dirname + "/../../lib/src/salt").salt;
|
|
310
|
+
let result = '';
|
|
311
|
+
let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
312
|
+
let charactersLength = characters.length;
|
|
313
|
+
for (var i = 0; i < length; i++) {
|
|
314
|
+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
315
|
+
}
|
|
316
|
+
resolve(md5(result + secret));
|
|
317
|
+
} catch (error) {
|
|
318
|
+
reject(error);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
generateKeyConfigFile(pjName) {
|
|
324
|
+
return new Promise((resolve, reject) => {
|
|
325
|
+
try {
|
|
326
|
+
this.fs.readFile(pjName + "/app.config.js", 'utf8', (err, data) => {
|
|
327
|
+
if (err) {
|
|
328
|
+
throw err;
|
|
329
|
+
} else {
|
|
330
|
+
// edit or add property
|
|
331
|
+
let buffer = Buffer.from(data);
|
|
332
|
+
let buf2str = buffer.toString();
|
|
333
|
+
let buf2json = JSON.parse(JSON.stringify(buf2str));
|
|
334
|
+
let buf2eval = eval(buf2json);
|
|
335
|
+
let oldKey = buf2eval.main_config.app_key;
|
|
336
|
+
// generate new key
|
|
337
|
+
this.appKeyGenerator(8).then(newAppKey => {
|
|
338
|
+
// content replace
|
|
339
|
+
let text = data.replace(new RegExp(oldKey, 'g'), newAppKey);
|
|
340
|
+
// writing the file
|
|
341
|
+
this.fs.writeFile(pjName + "/app.config.js", text, 'utf8', (err) => {
|
|
342
|
+
if (err) {
|
|
343
|
+
throw err;
|
|
344
|
+
} else {
|
|
345
|
+
resolve("\n[102m[90m Passed [0m[0m App key it's new generated.");
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
} catch (error) {
|
|
352
|
+
reject(error);
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
help() {
|
|
358
|
+
return new Promise((resolve, reject) => {
|
|
359
|
+
try {
|
|
360
|
+
this.fs.readFile(__dirname + "/../core/generator/_help_create", "utf8", (err, data) => {
|
|
361
|
+
if (err) {
|
|
362
|
+
reject(err);
|
|
363
|
+
} else {
|
|
364
|
+
resolve(data);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
} catch (error) {
|
|
368
|
+
reject(error);
|
|
369
|
+
}
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
embed(argv) {
|
|
374
|
+
return new Promise((resolve, reject) => {
|
|
375
|
+
try {
|
|
376
|
+
this.fs = require("fs");
|
|
377
|
+
this.cmd = require('node-cmd');
|
|
378
|
+
this.argv = argv;
|
|
379
|
+
this.option = argv[ 2 ];
|
|
380
|
+
this.argument = argv[ 3 ];
|
|
381
|
+
this.special = argv[ 4 ];
|
|
382
|
+
this.extra = argv[ 5 ];
|
|
383
|
+
resolve(this);
|
|
384
|
+
} catch (error) {
|
|
385
|
+
reject(error);
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
391
|
new Beech();
|