1 | const fs = require('fs');
|
2 | const fse = require("fs-extra");
|
3 | const path = require("path");
|
4 | const urls = require("url");
|
5 | const chalk = require('chalk');
|
6 | const lodash = require("lodash");
|
7 | const child_process = require('child_process');
|
8 | const inquirer = require('inquirer');
|
9 | const ora = require('ora');
|
10 | const request = require('request');
|
11 | const tmp = require('tmp');
|
12 | const compressing = require('compressing');
|
13 | const config = require('../../config');
|
14 | const logger = require('../utils/logger');
|
15 |
|
16 |
|
17 | const utils = {
|
18 |
|
19 | consoleUrl(support) {
|
20 | if (support === true) {
|
21 | let configFile = path.resolve(process.cwd(), "eeui.config.js");
|
22 | if (fs.existsSync(configFile)) {
|
23 | let releaseConfig = {};
|
24 | try{
|
25 | releaseConfig = require(configFile);
|
26 | }catch (e) {
|
27 |
|
28 | }
|
29 | if (releaseConfig['consoleUrl'] && this.leftExists(releaseConfig['consoleUrl'], 'http')) {
|
30 | return releaseConfig['consoleUrl'];
|
31 | }
|
32 | }
|
33 | }
|
34 | return 'https://console.eeui.app/';
|
35 | },
|
36 |
|
37 | apiUrl(support) {
|
38 | return this.consoleUrl(support) + 'api/';
|
39 | },
|
40 |
|
41 | buildJS(cmd = 'build') {
|
42 | console.log(` => ${chalk.blue.bold('npm install&build')}`);
|
43 | return this.exec('npm install', true).then(() => {
|
44 | return this.exec('webpack --env.NODE_ENV=' + cmd);
|
45 | })
|
46 | },
|
47 |
|
48 | exec(command, quiet) {
|
49 | return new Promise((resolve, reject) => {
|
50 | try {
|
51 | let child = child_process.exec(command, {encoding: 'utf8'}, () => {
|
52 | resolve();
|
53 | });
|
54 | if (!quiet) {
|
55 | child.stdout.pipe(process.stdout);
|
56 | }
|
57 | child.stderr.pipe(process.stderr);
|
58 | } catch (e) {
|
59 | console.error('execute command failed :', command);
|
60 | reject(e);
|
61 | }
|
62 | })
|
63 | },
|
64 |
|
65 | parseDevicesResult(result) {
|
66 | if (!result) {
|
67 | return [];
|
68 | }
|
69 | const devices = [];
|
70 | const lines = result.trim().split(/\r?\n/);
|
71 | for (let i = 0; i < lines.length; i++) {
|
72 | let words = lines[i].split(/[ ,\t]+/).filter((w) => w !== '');
|
73 |
|
74 | if (words[1] === 'device') {
|
75 | devices.push(words[0]);
|
76 | }
|
77 | }
|
78 | return devices;
|
79 | },
|
80 |
|
81 | mkdirsSync(dirname) {
|
82 | if (fse.existsSync(dirname)) {
|
83 | return true;
|
84 | } else {
|
85 | if (this.mkdirsSync(path.dirname(dirname))) {
|
86 | fse.mkdirSync(dirname);
|
87 | return true;
|
88 | }
|
89 | }
|
90 | },
|
91 |
|
92 | getMiddle(string, start, end) {
|
93 | if (this.isHave(start) && this.strExists(string, start)) {
|
94 | string = string.substring(string.indexOf(start) + start.length);
|
95 | } else if (start !== null) {
|
96 | return "";
|
97 | }
|
98 | if (this.isHave(end) && this.strExists(string, end)) {
|
99 | string = string.substring(0, string.indexOf(end));
|
100 | } else if (end !== null) {
|
101 | return "";
|
102 | }
|
103 | return string;
|
104 | },
|
105 |
|
106 | isHave(set) {
|
107 | return !!(set !== null && set !== "null" && set !== undefined && set !== "undefined" && set);
|
108 | },
|
109 |
|
110 | isNullOrUndefined(obj) {
|
111 | return typeof obj === "undefined" || obj === null;
|
112 | },
|
113 |
|
114 | isObject(obj) {
|
115 | return this.isNullOrUndefined(obj) ? false : typeof obj === "object";
|
116 | },
|
117 |
|
118 | likeArray(obj) {
|
119 | return this.isObject(obj) && typeof obj.length === 'number';
|
120 | },
|
121 |
|
122 | isJson(obj) {
|
123 | return this.isObject(obj) && !this.likeArray(obj);
|
124 | },
|
125 |
|
126 | strExists(string, find, lower) {
|
127 | string += "";
|
128 | find += "";
|
129 | if (lower !== true) {
|
130 | string = string.toLowerCase();
|
131 | find = find.toLowerCase();
|
132 | }
|
133 | return (string.indexOf(find) !== -1);
|
134 | },
|
135 |
|
136 | leftExists(string, find) {
|
137 | string += "";
|
138 | find += "";
|
139 | return (string.substring(0, find.length) === find);
|
140 | },
|
141 |
|
142 | rightExists(string, find) {
|
143 | string += "";
|
144 | find += "";
|
145 | return (string.substring(string.length - find.length) === find);
|
146 | },
|
147 |
|
148 | leftDelete(string, find) {
|
149 | string += "";
|
150 | find += "";
|
151 | if (this.leftExists(string, find)) {
|
152 | string = string.substring(find.length)
|
153 | }
|
154 | return string ? string : '';
|
155 | },
|
156 |
|
157 | rightDelete(string, find) {
|
158 | string += "";
|
159 | find += "";
|
160 | if (this.rightExists(string, find)) {
|
161 | string = string.substring(0, string.length - find.length)
|
162 | }
|
163 | return string ? string : '';
|
164 | },
|
165 |
|
166 | findIndexOf(str, cha, num) {
|
167 | str+= "";
|
168 | cha+= "";
|
169 | let x = str.indexOf(cha);
|
170 | for (let i = 0; i < num; i++) {
|
171 | x = str.indexOf(cha, x + 1);
|
172 | if (x === -1) {
|
173 | break;
|
174 | }
|
175 | }
|
176 | return x;
|
177 | },
|
178 |
|
179 | clone(myObj) {
|
180 | if (typeof(myObj) !== 'object') return myObj;
|
181 | if (myObj === null) return myObj;
|
182 |
|
183 | if (this.likeArray(myObj)) {
|
184 | let [...myNewObj] = myObj;
|
185 | return myNewObj;
|
186 | } else {
|
187 | let {...myNewObj} = myObj;
|
188 | return myNewObj;
|
189 | }
|
190 | },
|
191 |
|
192 | count(obj) {
|
193 | try {
|
194 | if (typeof obj === "undefined") {
|
195 | return 0;
|
196 | }
|
197 | if (typeof obj === "number") {
|
198 | obj+= "";
|
199 | }
|
200 | if (typeof obj.length === 'number') {
|
201 | return obj.length;
|
202 | } else {
|
203 | let i = 0, key;
|
204 | for (key in obj) {
|
205 | i++;
|
206 | }
|
207 | return i;
|
208 | }
|
209 | }catch (e) {
|
210 | return 0;
|
211 | }
|
212 | },
|
213 |
|
214 | each(elements, callback) {
|
215 | let i, key;
|
216 | if (this.likeArray(elements)) {
|
217 | if (typeof elements.length === "number") {
|
218 | for (i = 0; i < elements.length; i++) {
|
219 | if (callback.call(elements[i], i, elements[i]) === false) return elements
|
220 | }
|
221 | }
|
222 | } else {
|
223 | for (key in elements) {
|
224 | if (!elements.hasOwnProperty(key)) continue;
|
225 | if (callback.call(elements[key], key, elements[key]) === false) return elements
|
226 | }
|
227 | }
|
228 |
|
229 | return elements
|
230 | },
|
231 |
|
232 | getObject(obj, keys) {
|
233 | let object = obj;
|
234 | if (this.count(obj) === 0 || this.count(keys) === 0) {
|
235 | return "";
|
236 | }
|
237 | let arr = keys.replace(/,/g, "|").replace(/\./g, "|").split("|");
|
238 | this.each(arr, (index, key) => {
|
239 | object = typeof object[key] === "undefined" ? "" : object[key];
|
240 | });
|
241 | return object;
|
242 | },
|
243 |
|
244 | moveEmptyDirParent(dirPath) {
|
245 | let lists = this.fileDirDisplay(dirPath);
|
246 | if (lists.dir.length === 0 && lists.file.length === 0) {
|
247 | if (fs.existsSync(dirPath)) {
|
248 | fse.removeSync(dirPath);
|
249 | }
|
250 | this.moveEmptyDirParent(path.resolve(dirPath, '../'));
|
251 | }
|
252 | },
|
253 |
|
254 | fileDirDisplay(dirPath, currentDir) {
|
255 | let lists = {
|
256 | 'dir': [],
|
257 | 'file': [],
|
258 | };
|
259 | let stats = this.pathType(dirPath);
|
260 | switch (stats) {
|
261 | case 1:
|
262 | lists.file.push(dirPath);
|
263 | return lists;
|
264 | case 0:
|
265 | return lists;
|
266 | }
|
267 | let files = fs.readdirSync(dirPath);
|
268 | files.some((filename) => {
|
269 | let filedir = path.join(dirPath, filename);
|
270 | if ([".git", ".DS_Store", "__MACOSX"].indexOf(filename) !== -1) {
|
271 | return false;
|
272 | }
|
273 | if (this.rightExists(filename, ".iml") || this.rightExists(filename, ".xcuserdatad")) {
|
274 | return false;
|
275 | }
|
276 | if (this.rightExists(filedir, path.join("android", "build"))) {
|
277 | return false;
|
278 | }
|
279 | let stats = this.pathType(filedir);
|
280 | if (stats === 1) {
|
281 | lists.file.push(filedir);
|
282 | } else if (stats === 2 && currentDir !== true) {
|
283 | lists.dir.push(filedir);
|
284 | let tmps = this.fileDirDisplay(filedir);
|
285 | lists.dir = lists.dir.concat(tmps.dir);
|
286 | lists.file = lists.file.concat(tmps.file);
|
287 | }
|
288 | });
|
289 | return lists;
|
290 | },
|
291 |
|
292 | replaceDictString(path, key, value) {
|
293 | if (!fs.existsSync(path)) {
|
294 | return;
|
295 | }
|
296 | let content = fs.readFileSync(path, 'utf8');
|
297 | let matchs = content.match(/<dict>(.*?)<\/dict>/gs);
|
298 | if (matchs) {
|
299 | matchs.forEach((oldText) => {
|
300 | oldText = oldText.substring(oldText.lastIndexOf('<dict>'), oldText.length);
|
301 | if (this.strExists(oldText, '<string>' + key + '</string>', true)) {
|
302 | let searchValue = this.getMiddle(oldText, '<array>', '</array>');
|
303 | if (searchValue) {
|
304 | searchValue = '<array>' + searchValue + '</array>';
|
305 | let stringValue = '<string>' + this.getMiddle(searchValue, '<string>', '</string>') + '</string>';
|
306 | let replaceValue = searchValue.replace(new RegExp(stringValue, "g"), '<string>' + value + '</string>');
|
307 | let newText = oldText.replace(new RegExp(searchValue, "g"), replaceValue);
|
308 | let result = fs.readFileSync(path, 'utf8').replace(new RegExp(oldText, "g"), newText);
|
309 | if (result) {
|
310 | fs.writeFileSync(path, result, 'utf8');
|
311 | }
|
312 | }
|
313 | }
|
314 | });
|
315 | }
|
316 | },
|
317 |
|
318 | replaceEeuiLog(source) {
|
319 | let rege = new RegExp("((\\s|{|\\[|\\(|,|;)console)\\.(debug|log|info|warn|error)\\((.*?)\\)", "g");
|
320 | let result;
|
321 | while ((result = rege.exec(source)) != null) {
|
322 | let newString = result[0].replace(result[1], result[2] + "eeuiLog");
|
323 | source = source.replace(result[0], newString);
|
324 | }
|
325 | return source;
|
326 | },
|
327 |
|
328 | replaceModule(source) {
|
329 | var rege = new RegExp("\\.(requireModule|isRegisteredModule)\\(([\'\"])(.*?)\\2\\)", "g");
|
330 | var result;
|
331 | while ((result = rege.exec(source)) != null) {
|
332 | var name = result[3];
|
333 | if ([
|
334 | 'websocket',
|
335 | 'screenshots',
|
336 | 'citypicker',
|
337 | 'picture',
|
338 | 'rongim',
|
339 | 'umeng',
|
340 | 'pay',
|
341 | 'audio',
|
342 | 'deviceInfo',
|
343 | 'communication',
|
344 | 'geolocation',
|
345 | 'recorder',
|
346 | 'accelerometer',
|
347 | 'compass',
|
348 | 'amap',
|
349 | 'seekbar',
|
350 | 'network',
|
351 | ].indexOf(name) !== -1) {
|
352 | name = 'eeui/' + name;
|
353 | }
|
354 | if (utils.strExists(name, "/")) {
|
355 | var newString = result[0].replace(result[3], utils.spritUpperCase(name));
|
356 | source = source.replace(result[0], newString);
|
357 | }
|
358 | }
|
359 | return source;
|
360 | },
|
361 |
|
362 | getQueryString: (search, name) => {
|
363 | let reg = new RegExp("(^|&|\\?)" + name + "=([^&]*)", "i");
|
364 | let r = search.match(reg);
|
365 | if (r != null) return (r[2]);
|
366 | return "";
|
367 | },
|
368 |
|
369 | removeRubbish(dirPath) {
|
370 | let lists = [];
|
371 | try {
|
372 | let files = fs.readdirSync(dirPath);
|
373 | files.some((filename) => {
|
374 | let filedir = path.join(dirPath, filename);
|
375 | if ([".git", ".DS_Store", "__MACOSX"].indexOf(filename) !== -1) {
|
376 | fse.removeSync(filedir);
|
377 | lists.push(filedir);
|
378 | return false;
|
379 | }
|
380 | if (this.rightExists(filename, ".iml") || this.rightExists(filename, ".xcuserdatad")) {
|
381 | fse.removeSync(filedir);
|
382 | lists.push(filedir);
|
383 | return false;
|
384 | }
|
385 | if (this.rightExists(filedir, path.join("android", "build"))) {
|
386 | fse.removeSync(filedir);
|
387 | lists.push(filedir);
|
388 | return false;
|
389 | }
|
390 |
|
391 | let stats = this.pathType(filedir);
|
392 | if (stats === 2) {
|
393 | this.removeRubbish(filedir);
|
394 | }
|
395 | });
|
396 | return lists;
|
397 | }catch (e) {
|
398 | return lists;
|
399 | }
|
400 | },
|
401 |
|
402 | |
403 |
|
404 |
|
405 |
|
406 |
|
407 | jsonParse(str, defaultVal) {
|
408 | try{
|
409 | return JSON.parse(str);
|
410 | }catch (e) {
|
411 | return defaultVal ? defaultVal : {};
|
412 | }
|
413 | },
|
414 |
|
415 | |
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 | jsonStringify(json, defaultVal) {
|
422 | try{
|
423 | return JSON.stringify(json);
|
424 | }catch (e) {
|
425 | return defaultVal ? defaultVal : "";
|
426 | }
|
427 | },
|
428 |
|
429 | runNum(str, fixed) {
|
430 | let _s = Number(str);
|
431 | if (_s + "" === "NaN") {
|
432 | _s = 0;
|
433 | }
|
434 | if (/^[0-9]*[1-9][0-9]*$/.test(fixed)) {
|
435 | _s = _s.toFixed(fixed);
|
436 | let rs = _s.indexOf('.');
|
437 | if (rs < 0) {
|
438 | _s += ".";
|
439 | for (let i = 0; i < fixed; i++) {
|
440 | _s += "0";
|
441 | }
|
442 | }
|
443 | }
|
444 | return _s;
|
445 | },
|
446 |
|
447 | zeroFill(str, length, after) {
|
448 | str += "";
|
449 | if (str.length >= length) {
|
450 | return str;
|
451 | }
|
452 | let _str = '', _ret = '';
|
453 | for (let i = 0; i < length; i++) {
|
454 | _str += '0';
|
455 | }
|
456 | if (after || typeof after === 'undefined') {
|
457 | _ret = (_str + "" + str).substr(length * -1);
|
458 | } else {
|
459 | _ret = (str + "" + _str).substr(0, length);
|
460 | }
|
461 | return _ret;
|
462 | },
|
463 |
|
464 | timeStamp() {
|
465 | return Math.round(new Date().getTime() / 1000);
|
466 | },
|
467 |
|
468 | formatDate(format, v) {
|
469 | if (format === '') {
|
470 | format = 'Y-m-d H:i:s';
|
471 | }
|
472 | if (typeof v === 'undefined') {
|
473 | v = new Date().getTime();
|
474 | } else if (/^(-)?\d{1,10}$/.test(v)) {
|
475 | v = v * 1000;
|
476 | } else if (/^(-)?\d{1,13}$/.test(v)) {
|
477 | v = v * 1000;
|
478 | } else if (/^(-)?\d{1,14}$/.test(v)) {
|
479 | v = v * 100;
|
480 | } else if (/^(-)?\d{1,15}$/.test(v)) {
|
481 | v = v * 10;
|
482 | } else if (/^(-)?\d{1,16}$/.test(v)) {
|
483 | v = v * 1;
|
484 | } else {
|
485 | return v;
|
486 | }
|
487 | let dateObj = new Date(v);
|
488 | if (parseInt(dateObj.getFullYear()) + "" === "NaN") {
|
489 | return v;
|
490 | }
|
491 |
|
492 | format = format.replace(/Y/g, dateObj.getFullYear());
|
493 | format = format.replace(/m/g, this.zeroFill(dateObj.getMonth() + 1, 2));
|
494 | format = format.replace(/d/g, this.zeroFill(dateObj.getDate(), 2));
|
495 | format = format.replace(/H/g, this.zeroFill(dateObj.getHours(), 2));
|
496 | format = format.replace(/i/g, this.zeroFill(dateObj.getMinutes(), 2));
|
497 | format = format.replace(/s/g, this.zeroFill(dateObj.getSeconds(), 2));
|
498 | return format;
|
499 | },
|
500 |
|
501 | renderSize(value) {
|
502 | if (null == value || value === '') {
|
503 | return "0B";
|
504 | }
|
505 | let unitArr = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
506 | let index,
|
507 | srcsize = parseFloat(value);
|
508 | index = Math.floor(Math.log(srcsize) / Math.log(1024));
|
509 | let size = srcsize / Math.pow(1024, index);
|
510 | if (srcsize > 1024 * 1024) {
|
511 | size = size.toFixed(2);
|
512 | }else{
|
513 | size = Math.round(size);
|
514 | }
|
515 | let ret = (size + unitArr[index]) + "";
|
516 | return (ret.indexOf("NaN") !== -1) ? "0B" : ret;
|
517 | },
|
518 |
|
519 | execPath(originPath) {
|
520 | return !/(\.web\.map|\.DS_Store|__MACOSX|Thumbs\.db|\.vue)$/.exec(originPath);
|
521 | },
|
522 |
|
523 | setToken(token) {
|
524 | let cachePath = path.join(require('os').homedir(), '.' + config.cacheDirName, 'token.cache');
|
525 | fse.ensureFileSync(cachePath);
|
526 | let cache = this.jsonParse(fs.readFileSync(cachePath, 'utf8'));
|
527 | cache.token = token;
|
528 | fs.writeFileSync(cachePath, this.jsonStringify(cache), 'utf8');
|
529 | },
|
530 |
|
531 | getToken() {
|
532 | let cachePath = path.join(require('os').homedir(), '.' + config.cacheDirName, 'token.cache');
|
533 | fse.ensureFileSync(cachePath);
|
534 | let cache = this.jsonParse(fs.readFileSync(cachePath, 'utf8'));
|
535 | return this.getObject(cache, 'token');
|
536 | },
|
537 |
|
538 | login(support, callback) {
|
539 | if (typeof support === 'function') {
|
540 | callback = support;
|
541 | support = false;
|
542 | }
|
543 | logger.warn('请使用' + utils.consoleUrl(support) + '账号登录');
|
544 | inquirer.prompt([{
|
545 | type: 'input',
|
546 | name: 'username',
|
547 | message: "请输入用户名:",
|
548 | }, {
|
549 | type: 'password',
|
550 | name: 'userpass',
|
551 | message: "请输入登录密码:",
|
552 | }]).then((answers) => {
|
553 | let spinFetch = ora('正在登录...').start();
|
554 | request(utils.apiUrl(support) + 'users/login?username=' + answers.username + "&userpass=" + answers.userpass, (err, res, body) => {
|
555 | spinFetch.stop();
|
556 | let data = this.jsonParse(body);
|
557 | if (data.ret !== 1) {
|
558 | logger.fatal(`登录失败:${data.msg}`);
|
559 | }
|
560 | this.setToken(data.data.token);
|
561 |
|
562 | if (typeof callback === "function") {
|
563 | callback(data.data);
|
564 | }
|
565 | });
|
566 | }).catch(console.error);
|
567 | },
|
568 |
|
569 | logout(callback) {
|
570 | this.setToken("");
|
571 | if (typeof callback === "function") {
|
572 | callback();
|
573 | }
|
574 | },
|
575 |
|
576 | projectVersion() {
|
577 | let file = path.resolve(process.cwd(), "eeui.config.js");
|
578 | let pack = path.resolve(process.cwd(), "package.json");
|
579 | let vers = "";
|
580 | if (fse.existsSync(file) && fse.existsSync(pack)) {
|
581 | vers = require(path.resolve(process.cwd(), "package.json")).version;
|
582 | }
|
583 | return vers;
|
584 | },
|
585 |
|
586 | versionFunegt(version1, version2) {
|
587 |
|
588 | version1 = (version1 + ".").toLowerCase().replace(/(^\s+)|(\s+$)/gi, "");
|
589 | version2 = (version2 + ".").toLowerCase().replace(/(^\s+)|(\s+$)/gi, "");
|
590 | if (version1 === "." || version2 === ".") {
|
591 | return true;
|
592 | }
|
593 | let array1 = version1.split(".");
|
594 | let array2 = version2.split(".");
|
595 | let result = false;
|
596 | let v2;
|
597 | array1.some((v1, i) => {
|
598 | v1 = v1.trim();
|
599 | v2 = (array2[i] || '').trim();
|
600 | if (v1 === v2) {
|
601 | return false;
|
602 | }
|
603 | result = v1 === [v1, v2].sort()[1];
|
604 | return true;
|
605 | });
|
606 | return result;
|
607 | },
|
608 |
|
609 | verifyeeuiProject() {
|
610 |
|
611 | let file = path.resolve(process.cwd(), "eeui.config.js");
|
612 | if (!fs.existsSync(file)) {
|
613 | logger.fatal(`当前目录非eeui项目,无法进行此操作!`);
|
614 | }
|
615 |
|
616 | file = path.resolve(process.cwd(), "package.json");
|
617 | if (fs.existsSync(file)) {
|
618 | let packageInfo = utils.jsonParse(fs.readFileSync(file, 'utf8'));
|
619 | let current = require('../../package.json').version;
|
620 | let eeuiclimin = packageInfo.eeuiclimin;
|
621 | if (utils.isHave(eeuiclimin) && utils.versionFunegt(eeuiclimin, current)) {
|
622 | logger.fatal(`当前${chalk.underline(`eeui-cli@${current}`)}版本过低,请升级至${chalk.underline(`eeui-cli@${eeuiclimin}`)}或以上!${chalk.underline(`https://www.npmjs.com/package/eeui-cli`)}`);
|
623 | }
|
624 | }
|
625 | },
|
626 |
|
627 | verifyeeuiTemplate() {
|
628 |
|
629 | if (utils.versionFunegt("2.0.0", utils.projectVersion())) {
|
630 | logger.fatal(`当前${chalk.underline(`主程序@${utils.projectVersion()}`)}版本过低,请升级主程序!${chalk.underline(`https://eeui.app/guide/update.html`)}`);
|
631 | }
|
632 | },
|
633 |
|
634 | pluginsJson(isInstall, op) {
|
635 | let configFile = path.resolve(op.rootDir, "plugins/config.json");
|
636 | let configInfo = utils.jsonParse(!fs.existsSync(configFile) ? {} : fs.readFileSync(configFile, 'utf8'));
|
637 | if (!utils.isJson(configInfo['dependencies'])) {
|
638 | configInfo['dependencies'] = {};
|
639 | }
|
640 | if (isInstall) {
|
641 | if (typeof configInfo['dependencies'][op.name] !== 'object') {
|
642 | configInfo['dependencies'][op.name] = {};
|
643 | }
|
644 | configInfo['dependencies'][op.name]['requireName'] = op.requireName || op.name;
|
645 | configInfo['dependencies'][op.name]['name'] = op.name;
|
646 | configInfo['dependencies'][op.name]['url'] = op.url || "local";
|
647 | } else {
|
648 | if (typeof configInfo['dependencies'][op.name] !== "undefined") {
|
649 | delete configInfo['dependencies'][op.name];
|
650 | }
|
651 | }
|
652 | fs.writeFileSync(configFile, JSON.stringify(this.sortObject(configInfo), null, "\t"), 'utf8')
|
653 | },
|
654 |
|
655 | sortObject(obj) {
|
656 | return Object.keys(obj).sort().reduce((a, v) => {
|
657 | a[v] = obj[v];
|
658 | return a;
|
659 | }, {});
|
660 | },
|
661 |
|
662 | sendWebSocket(ws, ver, data) {
|
663 | if (data == null || typeof data !== "object") {
|
664 | data = {};
|
665 | }
|
666 | data.version = ver;
|
667 | if (ver === 2) {
|
668 | ws.send(this.jsonStringify(data));
|
669 | }else{
|
670 | ws.send(data.type + ':' + data.value);
|
671 | }
|
672 | },
|
673 |
|
674 | getAllAppboards(rundir) {
|
675 | let lists = fs.readdirSync(path.resolve(rundir, 'appboard'));
|
676 | let array = [];
|
677 | lists.forEach((item) => {
|
678 | let sourcePath = path.resolve(rundir, 'appboard/' + item);
|
679 | if (utils.rightExists(sourcePath, ".js")) {
|
680 | let content = fs.readFileSync(sourcePath, 'utf8');
|
681 | let sourceName = path.relative(path.resolve(rundir), sourcePath);
|
682 | if (/^win/.test(process.platform)) {
|
683 | sourceName = sourceName.replace(/\\/g, "/");
|
684 | }
|
685 | array.push({
|
686 | path: sourceName,
|
687 | content: this.replaceModule(this.replaceEeuiLog(content)),
|
688 | });
|
689 | }
|
690 | });
|
691 | return array;
|
692 | },
|
693 |
|
694 | |
695 |
|
696 |
|
697 |
|
698 | getOnlineDemoLists(callback) {
|
699 | let array = [];
|
700 | let loading = ora('正在获取演示模板列表...').start();
|
701 | try {
|
702 | request(utils.apiUrl() + 'editor/case/cli_lists', (err, res, body) => {
|
703 | loading.stop();
|
704 | let data = utils.jsonParse(body);
|
705 | if (data.ret === 1) {
|
706 | data.data.forEach((item) => {
|
707 | array.push({
|
708 | name: item.desc + ' (' + item.release + ')',
|
709 | value: item
|
710 | });
|
711 | });
|
712 | callback('', array);
|
713 | }else{
|
714 | callback(data.msg);
|
715 | }
|
716 | });
|
717 | }catch (e) {
|
718 | loading.stop();
|
719 | callback('获取演示模板失败!');
|
720 | }
|
721 | },
|
722 |
|
723 | |
724 |
|
725 |
|
726 |
|
727 |
|
728 | downOnlineDemo(tree, callback) {
|
729 | let loadText = `正在下载演示模板...`;
|
730 | let loading = ora(loadText);
|
731 | loading.start();
|
732 | try {
|
733 | request(utils.apiUrl() + 'editor/case/cli_downzip?tree=' + tree, (err, res, body) => {
|
734 | loading.stop();
|
735 | let data = utils.jsonParse(body);
|
736 | if (data.ret === 1) {
|
737 | let savePath = path.join(require('os').homedir(), '.' + config.cacheDirName, 'demo');
|
738 | utils.mkdirsSync(savePath);
|
739 | savePath = path.join(savePath, tree + '.zip');
|
740 | loading.start();
|
741 | utils._downloadOnlineDemo(data.data.zipurl, savePath, (err) => {
|
742 | loading.stop();
|
743 | if (err) {
|
744 | callback(err);
|
745 | }else{
|
746 | callback('', savePath);
|
747 | }
|
748 | }, (res) => {
|
749 | loading.text = loadText + `(${res.progress}, ${res.speed})`;
|
750 | })
|
751 | }else{
|
752 | callback(data.msg || '下载演示模板失败!');
|
753 | }
|
754 | });
|
755 | }catch (e) {
|
756 | loading.stop();
|
757 | callback('下载演示模板错误!');
|
758 | }
|
759 | },
|
760 |
|
761 | |
762 |
|
763 |
|
764 |
|
765 |
|
766 |
|
767 |
|
768 | _downloadOnlineDemo(url, savePath, callback, progressCall) {
|
769 | let file = fs.createWriteStream(savePath);
|
770 | file.on("close", () => {
|
771 | callback()
|
772 | }).on("error", (err) => {
|
773 | callback(err)
|
774 | });
|
775 |
|
776 | let receivedBytes = 0;
|
777 | let totalBytes = 0;
|
778 | let speedBytes = 0;
|
779 | let speedPer = "0B/S";
|
780 | let speedInt = setInterval(() => {
|
781 | speedPer = utils.renderSize(Math.max(0, receivedBytes - speedBytes)) + "/S";
|
782 | speedBytes = receivedBytes;
|
783 | }, 1000);
|
784 | request.get(url)
|
785 | .on("error", function (err) {
|
786 | callback(`下载模板错误: ${err}`);
|
787 | })
|
788 | .on("response", function (res) {
|
789 | if (res.statusCode !== 200) {
|
790 | callback("Get zipUrl return a non-200 response.");
|
791 | }
|
792 | totalBytes = parseInt(res.headers['content-length'], 10);
|
793 | if (isNaN(totalBytes)) totalBytes = 0;
|
794 | })
|
795 | .on('data', (chunk) => {
|
796 | receivedBytes += chunk.length;
|
797 | let progress = "0%";
|
798 | if (totalBytes > 0) {
|
799 | progress = parseFloat(Math.max(0, receivedBytes / totalBytes * 100).toFixed(2)) + "%";
|
800 | }else{
|
801 | progress = utils.renderSize(receivedBytes);
|
802 | }
|
803 | progressCall && progressCall({
|
804 | received: receivedBytes,
|
805 | total: totalBytes,
|
806 | speed: speedPer,
|
807 | progress: progress
|
808 | });
|
809 | })
|
810 | .on("end", function () {
|
811 | clearInterval(speedInt);
|
812 | })
|
813 | .pipe(file);
|
814 | },
|
815 |
|
816 | |
817 |
|
818 |
|
819 |
|
820 |
|
821 | zipCompress(params, callback) {
|
822 | let output = this.getObject(params, 'output');
|
823 | let entry = this.getObject(params, 'entry');
|
824 | if (this.count(output) === 0) {
|
825 | output = tmp.tmpNameSync({dir: require('os').tmpdir()}) + ".zip";
|
826 | }
|
827 | if (typeof entry === "string") {
|
828 | entry = [{
|
829 | type: 'dir',
|
830 | root: entry,
|
831 | path: entry
|
832 | }];
|
833 | }
|
834 | if (!this.likeArray(entry)) {
|
835 | entry = [entry];
|
836 | }
|
837 |
|
838 | let tmpPath = tmp.tmpNameSync({dir: require('os').tmpdir()});
|
839 | entry.forEach((item) => {
|
840 | let filePath = item.path;
|
841 | let fileRoot = item.root;
|
842 | let leftPath = path.join(path.resolve(fileRoot || filePath), "/");
|
843 | switch (item.type) {
|
844 | case 'dir':
|
845 | let lists = this.fileDirDisplay(path.resolve(filePath));
|
846 | lists.dir.forEach((tmpItem) => {
|
847 | fse.ensureDirSync(path.resolve(tmpPath, this.leftDelete(tmpItem, leftPath)));
|
848 | });
|
849 | lists.file.forEach((tmpItem) => {
|
850 | fse.copySync(tmpItem, path.resolve(tmpPath, this.leftDelete(tmpItem, leftPath)));
|
851 | });
|
852 | break;
|
853 |
|
854 | case 'file':
|
855 | fse.copySync(filePath, path.resolve(tmpPath, this.leftDelete(filePath, leftPath)));
|
856 | break;
|
857 | }
|
858 | });
|
859 |
|
860 | compressing.zip.compressDir(tmpPath, output, {
|
861 | ignoreBase: true
|
862 | }).then(() => {
|
863 | fse.removeSync(tmpPath);
|
864 | typeof callback === 'function' && callback(output, null);
|
865 | }).catch((err) => {
|
866 | fse.removeSync(tmpPath);
|
867 | typeof callback === 'function' && callback(null, err);
|
868 | });
|
869 | },
|
870 |
|
871 | |
872 |
|
873 |
|
874 |
|
875 |
|
876 | editConfig(rundir, config) {
|
877 | if (config === null || typeof config !== 'object') {
|
878 | return;
|
879 | }
|
880 | let configPath = path.resolve(rundir, 'eeui.config.js');
|
881 | if (fs.existsSync(configPath)) {
|
882 | let newConfig = lodash.merge(require(configPath), config);
|
883 | if (newConfig !== null && typeof newConfig === 'object' && typeof newConfig.appKey !== 'undefined') {
|
884 | let content = '';
|
885 | content += "/**\n * 配置文件\n * 参数详细说明:https://eeui.app/guide/config.html\n */\n";
|
886 | content += "module.exports = ";
|
887 | content += JSON.stringify(newConfig, null, "\t");
|
888 | content += ";";
|
889 | fs.writeFileSync(configPath, content, 'utf8');
|
890 | }
|
891 | }
|
892 | },
|
893 |
|
894 | |
895 |
|
896 |
|
897 |
|
898 |
|
899 | spritUpperCase(string) {
|
900 | try {
|
901 | return string.replace(/\/+(\w)/g, function ($1) {
|
902 | return $1.toLocaleUpperCase()
|
903 | }).replace(/\//g, '');
|
904 | } catch (e) {
|
905 | return string;
|
906 | }
|
907 | },
|
908 |
|
909 | |
910 |
|
911 |
|
912 |
|
913 |
|
914 | parseURL(url) {
|
915 | let a = urls.parse(url);
|
916 | return {
|
917 | source: url,
|
918 | protocol: (a.protocol || "").replace(':', ''),
|
919 | host: a.hostname || "",
|
920 | port: a.port || "",
|
921 | query: decodeURIComponent(a.search || ""),
|
922 | params: (function() {
|
923 | let params = {},
|
924 | seg = (a.search || "").replace(/^\?/, '').split('&'),
|
925 | len = seg.length,
|
926 | p;
|
927 | for (let i = 0; i < len; i++) {
|
928 | if (seg[i]) {
|
929 | p = seg[i].split('=');
|
930 | params[p[0]] = decodeURIComponent(p[1]);
|
931 | }
|
932 | }
|
933 | return params;
|
934 | })(),
|
935 | hash: (a.hash || "").replace('#', ''),
|
936 | path: (a.pathname || "").replace(/^([^\/])/, '/$1')
|
937 | };
|
938 | },
|
939 |
|
940 | |
941 |
|
942 |
|
943 | syncConfigToPlatforms() {
|
944 | let file = path.resolve(process.cwd(), "eeui.config.js");
|
945 | if (!fs.existsSync(file)) {
|
946 | return;
|
947 | }
|
948 |
|
949 | let eeuiConfig = {};
|
950 | try{
|
951 | delete require.cache[file];
|
952 | eeuiConfig = require(file);
|
953 | }catch (e) {
|
954 | return;
|
955 | }
|
956 |
|
957 | let androidFile = path.resolve(process.cwd(), "platforms/android/eeuiApp/app/src/main/assets/eeui/config.json");
|
958 | if (fs.existsSync(androidFile)) {
|
959 | let tempConfig = lodash.merge(utils.jsonParse(fs.readFileSync(androidFile, 'utf8')), eeuiConfig);
|
960 | fs.writeFileSync(androidFile, JSON.stringify(tempConfig, null, "\t"), 'utf8')
|
961 | }
|
962 |
|
963 | let iosFile = path.resolve(process.cwd(), "platforms/ios/eeuiApp/bundlejs/eeui/config.json");
|
964 | if (fs.existsSync(iosFile)) {
|
965 | let tempConfig = lodash.merge(utils.jsonParse(fs.readFileSync(iosFile, 'utf8')), eeuiConfig);
|
966 | fs.writeFileSync(iosFile, JSON.stringify(tempConfig, null, "\t"), 'utf8')
|
967 | }
|
968 | },
|
969 |
|
970 | |
971 |
|
972 |
|
973 |
|
974 |
|
975 | pathType(p) {
|
976 | try {
|
977 | let s = fs.statSync(p);
|
978 | if (s.isFile()) {
|
979 | return 1;
|
980 | } else if (s.isDirectory()) {
|
981 | return 2;
|
982 | }
|
983 | } catch (e) {
|
984 |
|
985 | }
|
986 | return 0;
|
987 | },
|
988 |
|
989 | |
990 |
|
991 |
|
992 |
|
993 | onlyOneDirMoveToParent(dirPath) {
|
994 | let tempArray = fs.readdirSync(dirPath);
|
995 | if (utils.count(tempArray) === 1) {
|
996 | tempArray.forEach((tempName) => {
|
997 | let originalDir = path.join(dirPath, tempName);
|
998 | let stats = utils.pathType(originalDir);
|
999 | if (stats === 2) {
|
1000 | let tempDir = path.resolve(dirPath, "../__temp-" + Math.random().toString(36).substring(2));
|
1001 | fse.removeSync(tempDir);
|
1002 | fse.moveSync(originalDir, tempDir, {overwrite: true});
|
1003 | fse.removeSync(dirPath);
|
1004 | fse.moveSync(tempDir, dirPath, {overwrite: true});
|
1005 | fse.removeSync(tempDir);
|
1006 | }
|
1007 | });
|
1008 | }
|
1009 | }
|
1010 | };
|
1011 |
|
1012 | module.exports = utils;
|