lightshortcuts 1.0.8 → 1.0.9

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 CHANGED
@@ -128,10 +128,13 @@ lsc login && lsc publish
128
128
  init 快速初始化配置模板
129
129
  publish|p 发布离线包
130
130
  batch|b 发布离线包
131
- help [command] display help for command
131
+ deal <version> 处理离线包兼容版本相互重叠的情况,谨慎使用!
132
+ clean <all> 批量处理离线包兼容版本相互重叠的情况,谨慎使用!
132
133
  ```
133
-
134
134
 
135
+ 8. 清理指定离线包兼容版本范围:`lsc deal version`
136
+
137
+ 9. 批量清理指定离线包兼容版本范围(需管理员权限):`lsc clean all`
135
138
 
136
139
  附:
137
140
 
package/bin/lsc.js CHANGED
@@ -16,11 +16,17 @@ const lscrcPath = path.join(
16
16
  );
17
17
 
18
18
  const defaultConfig = require("../lib/defaults");
19
- const { checkSession, initAxiosConfig, logout } = require("../lib/core/API");
19
+ const {
20
+ checkSession,
21
+ initAxiosConfig,
22
+ logout,
23
+ dealVersionList,
24
+ batchDealVersionList
25
+ } = require("../lib/core/API");
20
26
  // 主目录下登录配置文件
21
27
  let confPath = path.join(process.cwd(), "./lsc.config.json");
22
28
 
23
- program.version("0.0.7");
29
+ program.version("0.0.8");
24
30
 
25
31
  // 登录并保存token
26
32
  let lightBaseURL = "";
@@ -175,10 +181,9 @@ program
175
181
  await initAxiosConfig(baseUrl, authToken);
176
182
  let f = await logout(token);
177
183
  console.log(`注销${f ? "成功" : "失败"}`);
178
- }else{
184
+ } else {
179
185
  console.log("不存在本地会话,请传入url,token");
180
186
  }
181
-
182
187
  });
183
188
 
184
189
  // 设置当前发布版本
@@ -200,141 +205,144 @@ program
200
205
  }
201
206
  });
202
207
 
203
- program.command("config").description("交互式配置离线包发布参数").action(function () {
204
- let initConfig = {},
205
- initAnswers = {};
206
- inquirer
207
- .prompt([
208
- // {
209
- // type: "input",
210
- // message: "请输入token:",
211
- // name: "token",
212
- // },
213
- {
214
- type: "input",
215
- message: "请输入离线包id:",
216
- name: "pkgid",
217
- },
218
- {
219
- type: "input",
220
- message: "请指定离线包发布版本号:",
221
- name: "set_pkg_version",
222
- default: "1.0.1",
223
- },
224
- {
225
- type: "input",
226
- message: "APP版本iOS版本范围:",
227
- name: "ios_version_scope",
228
- default: "7.0.6",
229
- },
230
- {
231
- type: "input",
232
- message: "APP版本Android版本范围:",
233
- name: "android_version_scope",
234
- default: "7.0.6.0",
235
- },
236
- {
237
- type: "checkbox",
238
- message: "请选择发布的APP:",
239
- name: "publish_app_arr",
240
- choices: [
241
- {
242
- key: "3577",
243
- value: "3592",
244
- name: "开发版_iOS",
245
- checked: true,
208
+ program
209
+ .command("config")
210
+ .description("交互式配置离线包发布参数")
211
+ .action(function () {
212
+ let initConfig = {},
213
+ initAnswers = {};
214
+ inquirer
215
+ .prompt([
216
+ // {
217
+ // type: "input",
218
+ // message: "请输入token:",
219
+ // name: "token",
220
+ // },
221
+ {
222
+ type: "input",
223
+ message: "请输入离线包id:",
224
+ name: "pkgid",
225
+ },
226
+ {
227
+ type: "input",
228
+ message: "请指定离线包发布版本号:",
229
+ name: "set_pkg_version",
230
+ default: "1.0.1",
231
+ },
232
+ {
233
+ type: "input",
234
+ message: "APP版本iOS版本范围:",
235
+ name: "ios_version_scope",
236
+ default: "7.0.6",
237
+ },
238
+ {
239
+ type: "input",
240
+ message: "APP版本Android版本范围:",
241
+ name: "android_version_scope",
242
+ default: "7.0.6.0",
243
+ },
244
+ {
245
+ type: "checkbox",
246
+ message: "请选择发布的APP:",
247
+ name: "publish_app_arr",
248
+ choices: [
249
+ {
250
+ key: "3577",
251
+ value: "3592",
252
+ name: "开发版_iOS",
253
+ checked: true,
254
+ },
255
+ {
256
+ key: "3577",
257
+ value: "3577",
258
+ name: "开发版_安卓",
259
+ checked: true,
260
+ },
261
+ ],
262
+ validate(answer) {
263
+ if (answer.length < 1) {
264
+ return "请至少选择一项";
265
+ }
266
+ return true;
246
267
  },
247
- {
248
- key: "3577",
249
- value: "3577",
250
- name: "开发版_安卓",
251
- checked: true,
268
+ },
269
+ {
270
+ type: "input",
271
+ message: "离线包压缩包存放相对位置:",
272
+ name: "pkg_dir",
273
+ default: "./dist/",
274
+ },
275
+ {
276
+ type: "input",
277
+ message: "离线包名称:",
278
+ name: "pkg_zip_name",
279
+ default: "dist.zip",
280
+ },
281
+ {
282
+ type: "list",
283
+ message: "是否处理上一版本离线包?",
284
+ name: "task_status",
285
+ choices: [
286
+ { key: 0, value: 0, name: "保留", checked: true },
287
+ { key: 1, value: 1, name: "暂停" },
288
+ { key: 2, value: 2, name: "结束" },
289
+ ],
290
+ },
291
+ {
292
+ type: "input",
293
+ message: "发布日志:",
294
+ name: "release_desc",
295
+ default: "功能更新",
296
+ when: (answers) => {
297
+ initAnswers = Object.assign({}, answers);
298
+ // console.log("initAnswers",initAnswers);
299
+ return true;
252
300
  },
253
- ],
254
- validate(answer) {
255
- if (answer.length < 1) {
256
- return "请至少选择一项";
257
- }
258
- return true;
259
301
  },
260
- },
261
- {
262
- type: "input",
263
- message: "离线包压缩包存放相对位置:",
264
- name: "pkg_dir",
265
- default: "./dist/",
266
- },
267
- {
268
- type: "input",
269
- message: "离线包名称:",
270
- name: "pkg_zip_name",
271
- default: "dist.zip",
272
- },
273
- {
274
- type: "list",
275
- message: "是否处理上一版本离线包?",
276
- name: "task_status",
277
- choices: [
278
- { key: 0, value: 0, name: "保留", checked: true },
279
- { key: 1, value: 1, name: "暂停" },
280
- { key: 2, value: 2, name: "结束" },
281
- ],
282
- },
283
- {
284
- type: "input",
285
- message: "发布日志:",
286
- name: "release_desc",
287
- default: "功能更新",
288
- when: (answers) => {
289
- initAnswers = Object.assign({}, answers);
290
- // console.log("initAnswers",initAnswers);
291
- return true;
302
+ // {
303
+ // type: "input",
304
+ // message: "请输入API前缀地址:",
305
+ // name: "lightBaseURL",
306
+ // default: "https://xxx.xxx.xxx/lightadmin/pas-api",
307
+ // when: (answers) => {
308
+ // initAnswers = Object.assign({}, answers);
309
+ // // console.log("initAnswers",initAnswers);
310
+ // return true;
311
+ // },
312
+ // },
313
+ {
314
+ type: "confirm",
315
+ message: "是否使用以上配置?",
316
+ name: "useConfig",
317
+ default: true,
292
318
  },
293
- },
294
- // {
295
- // type: "input",
296
- // message: "请输入API前缀地址:",
297
- // name: "lightBaseURL",
298
- // default: "https://xxx.xxx.xxx/lightadmin/pas-api",
299
- // when: (answers) => {
300
- // initAnswers = Object.assign({}, answers);
301
- // // console.log("initAnswers",initAnswers);
302
- // return true;
303
- // },
304
- // },
305
- {
306
- type: "confirm",
307
- message: "是否使用以上配置?",
308
- name: "useConfig",
309
- default: true,
310
- },
311
- {
312
- type: "confirm",
313
- message: "是否保存配置?",
314
- name: "saveConfig",
315
- default: true,
316
- when: function (answers) {
317
- return answers.useConfig;
319
+ {
320
+ type: "confirm",
321
+ message: "是否保存配置?",
322
+ name: "saveConfig",
323
+ default: true,
324
+ when: function (answers) {
325
+ return answers.useConfig;
326
+ },
318
327
  },
319
- },
320
- ])
321
- .then((asw) => {
322
- let { useConfig, saveConfig } = asw;
323
- if (useConfig) {
324
- let totalConfig = {
325
- ...initAnswers,
326
- apps_name: defaultConfig.publishInfo.apps_name,
327
- };
328
- if (saveConfig) {
329
- // 保存配置
330
- writeConfig(totalConfig);
328
+ ])
329
+ .then((asw) => {
330
+ let { useConfig, saveConfig } = asw;
331
+ if (useConfig) {
332
+ let totalConfig = {
333
+ ...initAnswers,
334
+ apps_name: defaultConfig.publishInfo.apps_name,
335
+ };
336
+ if (saveConfig) {
337
+ // 保存配置
338
+ writeConfig(totalConfig);
339
+ }
340
+ console.log(totalConfig);
341
+ } else {
342
+ console.log("已结束!");
331
343
  }
332
- console.log(totalConfig);
333
- } else {
334
- console.log("已结束!");
335
- }
336
- });
337
- });
344
+ });
345
+ });
338
346
 
339
347
  // 初始化配置模板
340
348
  const initConfAction = function () {
@@ -367,9 +375,12 @@ const initConfAction = function () {
367
375
  }
368
376
  });
369
377
  };
370
- program.command("init").description("快速初始化配置模板").action(function () {
371
- initConfAction();
372
- });
378
+ program
379
+ .command("init")
380
+ .description("快速初始化配置模板")
381
+ .action(function () {
382
+ initConfAction();
383
+ });
373
384
 
374
385
  // 单项目发布
375
386
  program
@@ -449,6 +460,71 @@ program
449
460
  }
450
461
  });
451
462
 
463
+ // 处理离线包兼容版本相互重叠的情况
464
+ program
465
+ .command("deal version")
466
+ .description("处理离线包兼容版本相互重叠的情况,谨慎使用!")
467
+ .action(async function () {
468
+ let dv = [
469
+ {
470
+ type: "input",
471
+ message: "请输入app_id:",
472
+ name: "app_id",
473
+ default:3592
474
+ },
475
+ {
476
+ type: "input",
477
+ message: "请输入pkg_id:",
478
+ name: "pkg_id",
479
+ default:2307
480
+ },
481
+ ];
482
+ inquirer.prompt(dv).then(async function (aws) {
483
+ const {app_id, pkg_id} = aws;
484
+ let f = await fileExists(lscrcPath);
485
+ if (f) {
486
+ let lscRc = require(lscrcPath),
487
+ { currentEnv } = lscRc;
488
+ const { lightBaseURL, token } = lscRc[`${currentEnv}`];
489
+ await initAxiosConfig(lightBaseURL, token);
490
+ await dealVersionList({app_id, pkg_id});
491
+ } else {
492
+ console.log("登录文件不存在,请先进行登录:lsc login");
493
+ }
494
+ });
495
+ });
496
+
497
+ // 处理离线包兼容版本相互重叠的情况
498
+ program
499
+ .command("clean all")
500
+ .description("批量处理离线包兼容版本相互重叠的情况,谨慎使用!")
501
+ .action(async function () {
502
+ console.log("批量处理离线包兼容版本相互重叠的情况,谨慎使用!")
503
+ let dv = [
504
+ {
505
+ type: "input",
506
+ message: "请输入app_id列表,以逗号分隔:",
507
+ name: "app_id",
508
+ default:"3592,3577,3580,3562"
509
+ }
510
+ ];
511
+ inquirer.prompt(dv).then(async function (aws) {
512
+ const {app_id} = aws;
513
+ console.log((app_id+'').split(','));
514
+ let ids = (app_id+'').split(',');
515
+ let f = await fileExists(lscrcPath);
516
+ if (f) {
517
+ let lscRc = require(lscrcPath),
518
+ { currentEnv } = lscRc;
519
+ const { lightBaseURL, token } = lscRc[`${currentEnv}`];
520
+ await initAxiosConfig(lightBaseURL, token);
521
+ await batchDealVersionList(ids);
522
+ } else {
523
+ console.log("登录文件不存在,请先进行登录:lsc login");
524
+ }
525
+ });
526
+ });
527
+
452
528
  async function writeConfig(configArgs, path = "./lsc.config.json") {
453
529
  // 写入文件内容(如果文件不存在会创建一个文件)
454
530
  writeFile(path, JSON.stringify(configArgs), { flag: "w" }, function (err) {
package/lib/LSC.js CHANGED
@@ -29,6 +29,7 @@ const {
29
29
  queryOfflinePkgList,
30
30
  queryOfflineVersionlist,
31
31
  syncPkgList,
32
+ dealVersionList
32
33
  } = require("./core/API");
33
34
 
34
35
  //在APP上发布指定离线包主逻辑
@@ -85,16 +86,7 @@ async function publish(h5pkgid, app_id) {
85
86
  // 处理上一版本的问题:保持、暂停、下架
86
87
  if (task_status != 0) {
87
88
  let sm = { 0: "发布", 1: "暂停", 2: "下架" };
88
- const uotRes = await updateOfflineTask({
89
- id: f.id,
90
- status: task_status, //0发布,1暂停,2下架
91
- app_id,
92
- });
93
- console.log(
94
- `版本${prevVerInfo.version}${sm[task_status]}${
95
- uotRes ? "成功" : "失败"
96
- }`
97
- );
89
+ await dealVersionList({ app_id, pkg_id, status: task_status });
98
90
  }
99
91
  }
100
92
  }
package/lib/core/API.js CHANGED
@@ -9,16 +9,31 @@ const { ApiList } = require("./apiUrl");
9
9
  // 存储APP的离线包
10
10
  let allOfflinePkgLists = {};
11
11
 
12
- const initAxiosConfig = async function(lightBaseURL,token){
12
+ const initAxiosConfig = async function (lightBaseURL, token) {
13
13
  //全局配置
14
14
  axios.defaults.baseURL = lightBaseURL;
15
15
  axios.defaults.headers["cookie"] = `token=${token}`;
16
+ axios.defaults.headers["User-Agent"] = "LightShortcuts Pro";
16
17
  };
17
18
 
19
+ // 添加请求拦截器
20
+ axios.interceptors.request.use(
21
+ function (config) {
22
+ // 在发送请求之前做些什么
23
+ // console.log(config)
24
+ return config;
25
+ },
26
+ function (error) {
27
+ // 对请求错误做些什么
28
+ return Promise.reject(error);
29
+ }
30
+ );
31
+
18
32
  // 添加响应拦截器
19
33
  axios.interceptors.response.use(
20
34
  function (response) {
21
35
  // 2xx 范围内的状态码都会触发该函数。
36
+ // console.log(response.data);
22
37
  return response;
23
38
  },
24
39
  function (error) {
@@ -29,8 +44,7 @@ axios.interceptors.response.use(
29
44
 
30
45
  //校验会话有效性
31
46
  const checkSession = async function (token) {
32
- if(token){
33
-
47
+ if (token) {
34
48
  }
35
49
  return new Promise((resolve, reject) => {
36
50
  axios
@@ -51,7 +65,7 @@ const checkSession = async function (token) {
51
65
  };
52
66
 
53
67
  // 注销会话
54
- const logout = async function (token){
68
+ const logout = async function (token) {
55
69
  return new Promise((resolve, reject) => {
56
70
  axios
57
71
  .get(ApiList.logout)
@@ -64,11 +78,13 @@ const logout = async function (token){
64
78
  }
65
79
  })
66
80
  .catch((err) => {
67
- console.warn(`注销会话报错!${err.response.data.data[0].error_info}`);
81
+ console.warn(
82
+ `注销会话报错,原因是:${err.response.data.data[0].error_info}`
83
+ );
68
84
  resolve(false);
69
85
  });
70
86
  });
71
- }
87
+ };
72
88
 
73
89
  // 上传文件,__filePath:绝对路径
74
90
  const fileUpload = async function (__filePath) {
@@ -193,7 +209,9 @@ const addOfflineH5pkg = async function (app_id, h5app_id, name) {
193
209
  ),
194
210
  copFlag = copRes.data.data;
195
211
  let conRes = await axios.get(
196
- `${ApiList.checkOfflinePkgname}?app_id=${app_id}&name=${encodeURI(name)}`
212
+ `${ApiList.checkOfflinePkgname}?app_id=${app_id}&name=${encodeURI(
213
+ name
214
+ )}`
197
215
  ),
198
216
  conFlag = conRes.data.data;
199
217
  if (copFlag || conFlag) {
@@ -284,7 +302,6 @@ const queryOfflineTask = async function (args) {
284
302
  )}&page_no=1&page_size=5`
285
303
  )
286
304
  .then(function (res) {
287
- // console.log("获取指定版本下的发布任务列表:", JSON.stringify(res.data));
288
305
  const { err_no, data } = res.data;
289
306
  if (err_no == 0) {
290
307
  resolve(data.list);
@@ -309,7 +326,6 @@ const updateOfflineTask = async function (uotArgs = {}) {
309
326
  data: qs.stringify(uotArgs),
310
327
  })
311
328
  .then(function (res) {
312
- console.log("更新发布任务状态:", res.data);
313
329
  const { err_no } = res.data;
314
330
  if (err_no == 0) {
315
331
  resolve(true);
@@ -324,6 +340,99 @@ const updateOfflineTask = async function (uotArgs = {}) {
324
340
  });
325
341
  };
326
342
 
343
+ // 处理版本范围相互覆盖的离线包
344
+ const dealVersionList = async function ({ app_id, pkg_id, status = 2, name }) {
345
+ if (pkg_id == null) {
346
+ return false;
347
+ }
348
+ let qovRes = await axios.get(
349
+ `${ApiList.queryOfflineVersionlist}?app_id=${app_id}&pkg_id=${pkg_id}&page_no=1&page_size=30`
350
+ );
351
+ let { list } = qovRes.data.data;
352
+ let versionList = [];
353
+ // 获取要下架的版本号ID;
354
+ let toDoId = list.reduce((acc, cur) => {
355
+ let {
356
+ id,
357
+ ios_version_scope,
358
+ android_version_scope,
359
+ status,
360
+ version,
361
+ release_type,
362
+ } = cur;
363
+ // if (ios_version_scope == "") {
364
+ // console.warn(`ios_version_scope == ""`, cur);
365
+ // }
366
+ if (status == 1 && release_type == 0) {
367
+ if (versionList.includes(ios_version_scope)) {
368
+ let o = acc[`${ios_version_scope}`];
369
+ acc[`${ios_version_scope}`] = [...o, { id, version }];
370
+ } else {
371
+ acc[`${ios_version_scope}`] = [];
372
+ versionList.push(ios_version_scope);
373
+ }
374
+ }
375
+
376
+ return acc;
377
+ }, {});
378
+
379
+ for (const key in toDoId) {
380
+ if (Object.hasOwnProperty.call(toDoId, key)) {
381
+ const vl = toDoId[key];
382
+ if (vl.length > 0) {
383
+ for (let index = 0; index < vl.length; index++) {
384
+ const val = vl[index];
385
+ try {
386
+ let t = await todoVersion(app_id, val.id);
387
+ let sm = { 0: "发布", 1: "暂停", 2: "下架" },tips=sm[`${status}`];
388
+ console.log(
389
+ `${app_id}${name ? name : ""}版本范围:${key},版本号:${
390
+ val.version
391
+ },版本ID:${val.id},处理情况:${tips}${t ? "成功" : "失败"}`
392
+ );
393
+ } catch (error) {}
394
+ }
395
+ }
396
+ }
397
+ }
398
+
399
+ async function todoVersion(app_id, version_id) {
400
+ const qot = await queryOfflineTask({ app_id, version_id });
401
+ // console.log("qot",qot)
402
+ // return;
403
+ let tmp = qot.reduce((acc, cur) => {
404
+ if (cur.status == 0) {
405
+ acc = [...acc, cur.id];
406
+ }
407
+ return acc;
408
+ }, []);
409
+ let taskId = tmp[0];
410
+ // 下架
411
+ return await updateOfflineTask({
412
+ id: taskId,
413
+ status: 2,
414
+ app_id,
415
+ });
416
+ }
417
+ };
418
+
419
+ // 批处理版本范围相互覆盖的离线包
420
+ const batchDealVersionList = async function (ids, h5app_id, status = 2) {
421
+ const pkgLists = await queryOfflinePkgList(ids);
422
+ for (const key in pkgLists) {
423
+ if (Object.hasOwnProperty.call(pkgLists, key)) {
424
+ const ele = pkgLists[key];
425
+ for (let index = 0; index < ele.length; index++) {
426
+ const f = ele[index];
427
+ let { app_id, pkg_id, name } = f;
428
+ if (pkg_id != null) {
429
+ await dealVersionList({ app_id, pkg_id, status: 2, name });
430
+ }
431
+ }
432
+ }
433
+ }
434
+ };
435
+
327
436
  module.exports = {
328
437
  allOfflinePkgLists,
329
438
  logout,
@@ -338,5 +447,7 @@ module.exports = {
338
447
  queryOfflineTask,
339
448
  updateOfflineTask,
340
449
  syncPkgList,
341
- initAxiosConfig
450
+ initAxiosConfig,
451
+ dealVersionList,
452
+ batchDealVersionList,
342
453
  };
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "inquirer": "^8.2.0",
10
10
  "qs": "^6.10.3"
11
11
  },
12
- "version": "1.0.8",
12
+ "version": "1.0.9",
13
13
  "description": "Light离线包自动发布工具",
14
14
  "main": "index.js",
15
15
  "devDependencies": {},