lightshortcuts 1.0.3 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -26
- package/bin/lsc.js +173 -57
- package/lib/core/API.js +7 -0
- package/lib/defaults.js +1 -1
- package/lib/helpers/file-exists.js +10 -0
- package/lsc.config.json +9 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Light快捷指令
|
|
2
2
|
|
|
3
|
-
仅适用于Light
|
|
3
|
+
仅适用于Light管控台的快捷指令,用于快速处理离线包的一些处理,如发布等。请向相关平台管理员获取API地址和token、AppID。
|
|
4
4
|
|
|
5
5
|
#### 使用说明
|
|
6
6
|
|
|
@@ -18,15 +18,17 @@
|
|
|
18
18
|
npm update -g lightshortcuts
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
2.
|
|
21
|
+
2. 登录管控台系统
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
**发布前需要先登录系统**,需要输入API地址和token:
|
|
24
24
|
|
|
25
|
-
```
|
|
26
|
-
lsc
|
|
25
|
+
```
|
|
26
|
+
lsc login
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
3. 初始化发布配置
|
|
30
|
+
|
|
31
|
+
方式一:交互模式进行创建(推荐方式):
|
|
30
32
|
|
|
31
33
|
```bash
|
|
32
34
|
lsc config
|
|
@@ -36,29 +38,31 @@
|
|
|
36
38
|
|
|
37
39
|
```json
|
|
38
40
|
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"release_desc": "功能更新", //发布日志
|
|
53
|
-
"task_status": "0" //发布当前版本后,对上一版本的处理:0:发布(不处理),1:暂停,2:结束(下架)
|
|
54
|
-
},
|
|
55
|
-
"lightBaseURL": "https://xxx.xxx.xxx/lightadmin/pas-api"//Light管控台地址
|
|
41
|
+
"pkgid": "XXXXX", //离线包唯一ID
|
|
42
|
+
"set_pkg_version": "1.0.1", //指定发布版本
|
|
43
|
+
"publish_app_arr": [3577, 3592], //AppID列表发布到指定App,默认开发版
|
|
44
|
+
"apps_name": {
|
|
45
|
+
"3592": "开发版_iOS",
|
|
46
|
+
"3577": "开发版_安卓"
|
|
47
|
+
},
|
|
48
|
+
"android_version_scope": "7.0.6.0", //Android端离线包兼容版本
|
|
49
|
+
"ios_version_scope": "7.0.6", //iOS端离线包兼容版本
|
|
50
|
+
"pkg_zip_name": "dist.zip",//离线包压缩包文件名
|
|
51
|
+
"pkg_dir": "./dist/", //离线包相对所在路径
|
|
52
|
+
"release_desc": "若干功能更新", //发布日志
|
|
53
|
+
"task_status": "0" //发布当前版本后,对上一版本的处理:0:发布(不处理),1:暂停,2:结束(下架)
|
|
56
54
|
}
|
|
57
55
|
```
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
方式二:使用模板一键初始化:
|
|
60
58
|
|
|
61
|
-
|
|
59
|
+
```bash
|
|
60
|
+
lsc init
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
之后再根据项目进行修改。
|
|
64
|
+
|
|
65
|
+
4. 离线包发布
|
|
62
66
|
|
|
63
67
|
- 单项目发布:
|
|
64
68
|
|
|
@@ -72,4 +76,9 @@
|
|
|
72
76
|
lsc batch #或简写为 lsc b
|
|
73
77
|
```
|
|
74
78
|
|
|
75
|
-
|
|
79
|
+
在配置好发布文件的前提下,可以缩写成以下命令:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
lsc login && lsc publish
|
|
83
|
+
```
|
|
84
|
+
|
package/bin/lsc.js
CHANGED
|
@@ -1,31 +1,103 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const {
|
|
3
|
+
const { writeFile } = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { Command } = require("commander");
|
|
6
6
|
const inquirer = require("inquirer");
|
|
7
7
|
const program = new Command();
|
|
8
8
|
const { LSC } = require("../index");
|
|
9
9
|
const { merge, getZipFileList } = require("../lib/utils");
|
|
10
|
-
const
|
|
10
|
+
const fileExists = require("../lib/helpers/file-exists");
|
|
11
11
|
|
|
12
12
|
// 读取发布配置文件
|
|
13
|
+
const lscrcPath = path.join(
|
|
14
|
+
process.env.HOME || process.env.USERPROFILE,
|
|
15
|
+
".lscrc.json"
|
|
16
|
+
);
|
|
13
17
|
const defaultConfig = require("../lib/defaults");
|
|
14
|
-
const { checkSession } = require("../lib/core/API");
|
|
18
|
+
const { checkSession, initAxiosConfig } = require("../lib/core/API");
|
|
19
|
+
// 主目录下登录配置文件
|
|
15
20
|
let confPath = path.join(process.cwd(), "./lsc.config.json");
|
|
16
21
|
|
|
17
|
-
program.version("0.0.
|
|
22
|
+
program.version("0.0.5");
|
|
23
|
+
|
|
24
|
+
// 登录并保存token
|
|
25
|
+
let lightBaseURL = "";
|
|
26
|
+
let loginQuestions = [
|
|
27
|
+
{
|
|
28
|
+
type: "input",
|
|
29
|
+
message: "请输入API前缀地址:",
|
|
30
|
+
name: "lightBaseURL",
|
|
31
|
+
default: ()=>lightBaseURL || defaultConfig.lightBaseURL,
|
|
32
|
+
validate: async (url) => {
|
|
33
|
+
lightBaseURL = url;
|
|
34
|
+
return true;
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "input",
|
|
39
|
+
message: "请输入token:",
|
|
40
|
+
name: "token",
|
|
41
|
+
validate: async (token) => {
|
|
42
|
+
return await validSession(lightBaseURL, token);
|
|
43
|
+
},
|
|
44
|
+
validatingText: "正在校验token的有效性...",
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
//校验是否已经登录
|
|
48
|
+
const loginAction = async function () {
|
|
49
|
+
fileExists(lscrcPath)
|
|
50
|
+
.then(async (res) => {
|
|
51
|
+
// 是否需要交互处理
|
|
52
|
+
let needLoginProcessF = true;
|
|
53
|
+
if (res) {
|
|
54
|
+
// 存在文件
|
|
55
|
+
let lscRc = require(lscrcPath);
|
|
56
|
+
lightBaseURL = lscRc.lightBaseURL;
|
|
57
|
+
let res = await validSession(lscRc.lightBaseURL, lscRc.token);
|
|
58
|
+
if (!res) {
|
|
59
|
+
// 已有API链接
|
|
60
|
+
// loginQuestions.shift();
|
|
61
|
+
console.log(lscRc)
|
|
62
|
+
} else {
|
|
63
|
+
// token仍有效
|
|
64
|
+
console.log("已登录");
|
|
65
|
+
needLoginProcessF = false;
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
// 不存在文件
|
|
69
|
+
needLoginProcessF = true;
|
|
70
|
+
}
|
|
71
|
+
if (needLoginProcessF) {
|
|
72
|
+
inquirer.prompt(loginQuestions).then(async (answers) => {
|
|
73
|
+
await writeConfig(answers, lscrcPath);
|
|
74
|
+
console.log(JSON.stringify(answers));
|
|
75
|
+
return true;
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.catch((err) => {
|
|
80
|
+
console.log(err);
|
|
81
|
+
return false;
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
program
|
|
85
|
+
.command("login")
|
|
86
|
+
.description("输入登录token")
|
|
87
|
+
.action(async () => {
|
|
88
|
+
await loginAction();
|
|
89
|
+
});
|
|
18
90
|
|
|
19
91
|
program.command("config").action(function () {
|
|
20
92
|
let initConfig = {},
|
|
21
93
|
initAnswers = {};
|
|
22
94
|
inquirer
|
|
23
95
|
.prompt([
|
|
24
|
-
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
96
|
+
// {
|
|
97
|
+
// type: "input",
|
|
98
|
+
// message: "请输入token:",
|
|
99
|
+
// name: "token",
|
|
100
|
+
// },
|
|
29
101
|
{
|
|
30
102
|
type: "input",
|
|
31
103
|
message: "请输入离线包id:",
|
|
@@ -101,18 +173,23 @@ program.command("config").action(function () {
|
|
|
101
173
|
message: "发布日志:",
|
|
102
174
|
name: "release_desc",
|
|
103
175
|
default: "功能更新",
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
type: "input",
|
|
107
|
-
message: "请输入API前缀地址:",
|
|
108
|
-
name: "lightBaseURL",
|
|
109
|
-
default: "https://xxx.xxx.xxx/lightadmin/pas-api",
|
|
110
|
-
when:(answers)=>{
|
|
111
|
-
initAnswers = Object.assign({},answers);
|
|
176
|
+
when: (answers) => {
|
|
177
|
+
initAnswers = Object.assign({}, answers);
|
|
112
178
|
// console.log("initAnswers",initAnswers);
|
|
113
179
|
return true;
|
|
114
|
-
}
|
|
180
|
+
},
|
|
115
181
|
},
|
|
182
|
+
// {
|
|
183
|
+
// type: "input",
|
|
184
|
+
// message: "请输入API前缀地址:",
|
|
185
|
+
// name: "lightBaseURL",
|
|
186
|
+
// default: "https://xxx.xxx.xxx/lightadmin/pas-api",
|
|
187
|
+
// when: (answers) => {
|
|
188
|
+
// initAnswers = Object.assign({}, answers);
|
|
189
|
+
// // console.log("initAnswers",initAnswers);
|
|
190
|
+
// return true;
|
|
191
|
+
// },
|
|
192
|
+
// },
|
|
116
193
|
{
|
|
117
194
|
type: "confirm",
|
|
118
195
|
message: "是否使用以上配置?",
|
|
@@ -130,13 +207,11 @@ program.command("config").action(function () {
|
|
|
130
207
|
},
|
|
131
208
|
])
|
|
132
209
|
.then((asw) => {
|
|
133
|
-
// console.log("initAnswersXXXXX",initAnswers);
|
|
134
|
-
// 用户输入的结果最终会在这里输出
|
|
135
210
|
let { useConfig, saveConfig } = asw;
|
|
136
211
|
if (useConfig) {
|
|
137
212
|
let totalConfig = {
|
|
138
|
-
|
|
139
|
-
|
|
213
|
+
...initAnswers,
|
|
214
|
+
apps_name: defaultConfig.publishInfo.apps_name,
|
|
140
215
|
};
|
|
141
216
|
if (saveConfig) {
|
|
142
217
|
// 保存配置
|
|
@@ -149,23 +224,28 @@ program.command("config").action(function () {
|
|
|
149
224
|
});
|
|
150
225
|
});
|
|
151
226
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
if (
|
|
227
|
+
// 初始化配置模板
|
|
228
|
+
const initConfAction = function () {
|
|
229
|
+
fileExists(confPath).then((res) => {
|
|
230
|
+
if (res) {
|
|
231
|
+
console.log("注意,配置文件已经存在!!!内容如下:");
|
|
232
|
+
console.log(require(confPath));
|
|
156
233
|
// 存在配置文件,唤起交互输入
|
|
157
234
|
inquirer
|
|
158
235
|
.prompt([
|
|
159
236
|
{
|
|
160
237
|
type: "confirm",
|
|
161
|
-
message: "
|
|
238
|
+
message: "是否重新初始化?",
|
|
162
239
|
name: "initConfig",
|
|
163
240
|
default: false,
|
|
164
241
|
},
|
|
165
242
|
])
|
|
166
243
|
.then((answer) => {
|
|
167
244
|
if (answer.initConfig) {
|
|
168
|
-
|
|
245
|
+
let mergeConf = Object.assign(
|
|
246
|
+
defaultConfig.publishInfo
|
|
247
|
+
);
|
|
248
|
+
writeConfig(mergeConf, confPath);
|
|
169
249
|
} else {
|
|
170
250
|
console.log("配置无变化");
|
|
171
251
|
}
|
|
@@ -174,6 +254,9 @@ program.command("init").action(function () {
|
|
|
174
254
|
writeConfig(defaultConfig);
|
|
175
255
|
}
|
|
176
256
|
});
|
|
257
|
+
};
|
|
258
|
+
program.command("init").action(function () {
|
|
259
|
+
initConfAction();
|
|
177
260
|
});
|
|
178
261
|
|
|
179
262
|
// 单项目发布
|
|
@@ -181,23 +264,46 @@ program
|
|
|
181
264
|
.command("publish")
|
|
182
265
|
.alias("p")
|
|
183
266
|
.description("发布离线包")
|
|
184
|
-
.action(() => {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}
|
|
194
|
-
} else {
|
|
195
|
-
// 不存在配置文件,唤起交互输入
|
|
267
|
+
.action(async () => {
|
|
268
|
+
let feLscF = await fileExists(lscrcPath),
|
|
269
|
+
feConF = await fileExists(confPath);
|
|
270
|
+
//是否存在配置文件
|
|
271
|
+
if (feLscF && feConF) {
|
|
272
|
+
const { lightBaseURL, token } = require(lscrcPath);
|
|
273
|
+
const publishConfArgs = require(confPath);
|
|
274
|
+
|
|
275
|
+
if (publishConfArgs.publishInfo) {
|
|
196
276
|
console.log(
|
|
197
|
-
"
|
|
277
|
+
"温馨提示:程序已升级!\n请使用命令lsc config 或 lsc init 重新生成发布配置"
|
|
198
278
|
);
|
|
279
|
+
return;
|
|
199
280
|
}
|
|
200
|
-
|
|
281
|
+
|
|
282
|
+
try {
|
|
283
|
+
// let lscConfig = require(confPath);
|
|
284
|
+
let totalConfig = {
|
|
285
|
+
publishInfo: { ...publishConfArgs, token },
|
|
286
|
+
lightBaseURL,
|
|
287
|
+
};
|
|
288
|
+
// console.log("发布配置:\n", totalConfig);
|
|
289
|
+
LSC(totalConfig);
|
|
290
|
+
} catch (error) {
|
|
291
|
+
console.log("主程序异常", error);
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
// 不存在配置文件,唤起交互输入
|
|
295
|
+
let t = "",
|
|
296
|
+
f = "";
|
|
297
|
+
if (!feLscF) {
|
|
298
|
+
f = "登录";
|
|
299
|
+
t = "lsc login";
|
|
300
|
+
}
|
|
301
|
+
if (!feConF) {
|
|
302
|
+
f = "离线包发布";
|
|
303
|
+
t = "lsc config 或 lsc init";
|
|
304
|
+
}
|
|
305
|
+
console.log(`不存在${f}配置文件,请使用命令创建:${t}`);
|
|
306
|
+
}
|
|
201
307
|
});
|
|
202
308
|
|
|
203
309
|
// 批量离线包发布.已经包名作为pkgid
|
|
@@ -205,35 +311,45 @@ program
|
|
|
205
311
|
.command("batch")
|
|
206
312
|
.alias("b")
|
|
207
313
|
.action(async function () {
|
|
208
|
-
|
|
314
|
+
const { lightBaseURL, token } = require(lscrcPath);
|
|
315
|
+
const publishConfArgs = require(confPath);
|
|
316
|
+
|
|
317
|
+
let currPath = path.join(process.cwd(), publishConfArgs.pkg_dir);
|
|
209
318
|
let zipLists = await getZipFileList(currPath);
|
|
210
319
|
for (let i = 0; i < zipLists.length; i++) {
|
|
211
320
|
const e = zipLists[i],
|
|
212
321
|
s = e.split("."),
|
|
213
322
|
pkgid = s[0];
|
|
214
|
-
let
|
|
215
|
-
|
|
323
|
+
let totalConfig = {
|
|
324
|
+
publishInfo: { ...publishConfArgs, token },
|
|
325
|
+
lightBaseURL,
|
|
326
|
+
};
|
|
216
327
|
let batchConfig = merge(totalConfig, {
|
|
217
328
|
publishInfo: { pkgid, pkg_zip_name: e },
|
|
218
329
|
});
|
|
219
|
-
// console.log("batchConfig", batchConfig);
|
|
330
|
+
// console.log("batchConfig\n", batchConfig);
|
|
220
331
|
await LSC(batchConfig);
|
|
221
332
|
}
|
|
222
333
|
});
|
|
223
334
|
|
|
224
|
-
async function writeConfig(configArgs) {
|
|
335
|
+
async function writeConfig(configArgs, path = "./lsc.config.json") {
|
|
225
336
|
// 写入文件内容(如果文件不存在会创建一个文件)
|
|
226
|
-
writeFile(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
{ flag: "w" },
|
|
230
|
-
function (err) {
|
|
231
|
-
if (err) {
|
|
232
|
-
throw err;
|
|
233
|
-
}
|
|
234
|
-
console.log("创建配置模板成功,请打开文件进行相应修改");
|
|
337
|
+
writeFile(path, JSON.stringify(configArgs), { flag: "w" }, function (err) {
|
|
338
|
+
if (err) {
|
|
339
|
+
throw err;
|
|
235
340
|
}
|
|
236
|
-
|
|
341
|
+
console.log("创建配置模板成功,可根据需要进行相应修改");
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
// 查询会话的有效性
|
|
346
|
+
async function validSession(lightBaseURL, token) {
|
|
347
|
+
await initAxiosConfig(lightBaseURL, token);
|
|
348
|
+
let f = await checkSession(token);
|
|
349
|
+
if (!f) {
|
|
350
|
+
await console.log("\n会话已过期或者无效,请重新确认:", f);
|
|
351
|
+
}
|
|
352
|
+
return f;
|
|
237
353
|
}
|
|
238
354
|
|
|
239
355
|
program.parse(process.argv);
|
package/lib/core/API.js
CHANGED
|
@@ -9,6 +9,12 @@ const { ApiList } = require("./apiUrl");
|
|
|
9
9
|
// 存储APP的离线包
|
|
10
10
|
let allOfflinePkgLists = {};
|
|
11
11
|
|
|
12
|
+
const initAxiosConfig = async function(lightBaseURL,token){
|
|
13
|
+
//全局配置
|
|
14
|
+
axios.defaults.baseURL = lightBaseURL;
|
|
15
|
+
axios.defaults.headers["cookie"] = `token=${token}`;
|
|
16
|
+
};
|
|
17
|
+
|
|
12
18
|
// 添加响应拦截器
|
|
13
19
|
axios.interceptors.response.use(
|
|
14
20
|
function (response) {
|
|
@@ -311,4 +317,5 @@ module.exports = {
|
|
|
311
317
|
queryOfflineTask,
|
|
312
318
|
updateOfflineTask,
|
|
313
319
|
syncPkgList,
|
|
320
|
+
initAxiosConfig
|
|
314
321
|
};
|
package/lib/defaults.js
CHANGED
package/lsc.config.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"task_status": "2"
|
|
12
|
-
},
|
|
13
|
-
"lightBaseURL": "https://XXXXX.XXXXX./lightadmin/pas-api"
|
|
2
|
+
"token": "XXXXX",
|
|
3
|
+
"pkgid": "XXXXX",
|
|
4
|
+
"set_pkg_version": "1.2.1",
|
|
5
|
+
"publish_app_arr": [3592, 3577],
|
|
6
|
+
"android_version_scope": "7.0.7.0",
|
|
7
|
+
"ios_version_scope": "7.0.7",
|
|
8
|
+
"pkg_zip_name": "XXXXX.zip",
|
|
9
|
+
"pkg_dir": "./dist/",
|
|
10
|
+
"task_status": "2"
|
|
14
11
|
}
|