@lazycatcloud/lzc-cli 1.1.8 → 1.1.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.
Files changed (105) hide show
  1. package/README.md +69 -11
  2. package/lib/api.js +71 -39
  3. package/lib/app/index.js +76 -21
  4. package/lib/app/lpk_build.js +95 -63
  5. package/lib/app/lpk_create.js +63 -41
  6. package/lib/app/lpk_create_generator.js +202 -0
  7. package/lib/app/lpk_devshell.js +393 -328
  8. package/lib/app/lpk_devshell_docker.js +211 -0
  9. package/lib/app/lpk_installer.js +63 -26
  10. package/lib/app/lpk_log.js +68 -0
  11. package/lib/app/lpk_status.js +18 -0
  12. package/lib/app/lpk_uninstall.js +19 -0
  13. package/lib/appstore/index.js +37 -0
  14. package/lib/appstore/login.js +96 -93
  15. package/lib/appstore/publish.js +62 -0
  16. package/lib/autologin.js +0 -78
  17. package/lib/box/api/clientapi.js +1322 -0
  18. package/lib/box/api/empty.js +35 -0
  19. package/lib/box/check_qemu.js +1 -0
  20. package/lib/box/index.js +41 -94
  21. package/lib/box/qemu_vm_mgr.js +208 -239
  22. package/lib/box/schemes/vm_box_system_debian.json +1 -1
  23. package/lib/docker-compose.js +1 -2
  24. package/lib/env.js +19 -101
  25. package/lib/key.js +1 -0
  26. package/lib/sdk.js +10 -25
  27. package/lib/utils.js +156 -132
  28. package/package.json +19 -10
  29. package/scripts/cli.js +14 -135
  30. package/template/_lpk/README.md +31 -0
  31. package/template/_lpk/exec.sh +19 -0
  32. package/template/_lpk/golang.manifest.yml.in +16 -0
  33. package/template/_lpk/lazycat.png +0 -0
  34. package/template/_lpk/lite.manifest.yml.in +19 -0
  35. package/template/_lpk/local_devshell/Dockerfile +16 -0
  36. package/template/_lpk/local_devshell/build.sh +5 -0
  37. package/template/_lpk/local_devshell/entrypoint.sh +87 -0
  38. package/template/{_lazycat/debug/shell → _lpk/local_devshell}/sshd_config +8 -8
  39. package/template/_lpk/manifest.yml.in +0 -1
  40. package/template/{vue/lzc-build.yml → _lpk/vue.lzc-build.yml.in} +9 -1
  41. package/template/golang/README.md +0 -2
  42. package/template/golang/_gitignore +2 -0
  43. package/template/golang/build.sh +6 -0
  44. package/template/golang/lazycat.png +0 -0
  45. package/template/golang/lzc-build.yml +9 -1
  46. package/template/golang/rego.go +15 -16
  47. package/template/golang/rego_test.go +13 -0
  48. package/template/ionic_vue3/lazycat.png +0 -0
  49. package/template/ionic_vue3/lzc-build.yml +9 -1
  50. package/template/lite/error_pages/502.html.tpl +13 -0
  51. package/template/lite/lazycat.png +0 -0
  52. package/template/lite/lzc-build.yml +60 -0
  53. package/cmds/app.js +0 -133
  54. package/cmds/config.js +0 -55
  55. package/cmds/create.js +0 -55
  56. package/cmds/dev.js +0 -130
  57. package/cmds/init.js +0 -125
  58. package/cmds/log.js +0 -103
  59. package/cmds/publish.js +0 -116
  60. package/lib/archiver.js +0 -105
  61. package/lib/box/hportal.js +0 -120
  62. package/lib/builder.js +0 -313
  63. package/lib/dev.js +0 -314
  64. package/lib/generator.js +0 -146
  65. package/template/_lazycat/_gitignore +0 -1
  66. package/template/_lazycat/app-config +0 -1
  67. package/template/_lazycat/debug/devforward/50x.html +0 -30
  68. package/template/_lazycat/debug/devforward/Dockerfile +0 -16
  69. package/template/_lazycat/debug/devforward/docker-compose.override.yml.in +0 -11
  70. package/template/_lazycat/debug/devforward/entrypoint.sh +0 -10
  71. package/template/_lazycat/debug/devforward/nginx.conf.template +0 -56
  72. package/template/_lazycat/debug/devforward/sshd_config +0 -116
  73. package/template/_lazycat/debug/shell/50x.html +0 -32
  74. package/template/_lazycat/debug/shell/Dockerfile +0 -18
  75. package/template/_lazycat/debug/shell/build.sh +0 -15
  76. package/template/_lazycat/debug/shell/docker-compose.override.yml.in +0 -13
  77. package/template/_lazycat/debug/shell/entrypoint.sh +0 -12
  78. package/template/_lazycat/docker-compose.yml.in +0 -15
  79. package/template/_lazycat/icon.svg +0 -1
  80. package/template/_lazycat/screenshot.png +0 -0
  81. package/template/_lpk/sync/Dockerfile +0 -16
  82. package/template/_lpk/sync/build.sh +0 -5
  83. package/template/_lpk/sync/entrypoint.sh +0 -8
  84. package/template/_lpk/sync/sshd_config +0 -117
  85. package/template/_lpk/sync.manifest.yml.in +0 -3
  86. package/template/release/golang/Dockerfile +0 -18
  87. package/template/release/golang/build.sh +0 -13
  88. package/template/release/ionic_vue3/Dockerfile +0 -10
  89. package/template/release/ionic_vue3/build.sh +0 -7
  90. package/template/release/ionic_vue3/docker-compose.yml.in +0 -3
  91. package/template/release/vue/Dockerfile +0 -10
  92. package/template/release/vue/build.sh +0 -10
  93. package/template/release/vue/docker-compose.yml.in +0 -3
  94. package/template/vue/README.md +0 -29
  95. package/template/vue/_dockerignore +0 -1
  96. package/template/vue/babel.config.js +0 -3
  97. package/template/vue/package.json +0 -43
  98. package/template/vue/public/favicon.ico +0 -0
  99. package/template/vue/public/index.html +0 -33
  100. package/template/vue/src/App.vue +0 -39
  101. package/template/vue/src/main.js +0 -8
  102. package/template/vue/src/todo.vue +0 -640
  103. package/template/vue/src/top-bar.vue +0 -100
  104. package/template/vue/src/webdav.vue +0 -183
  105. package/template/vue/vue.config.js +0 -21
@@ -1,134 +1,137 @@
1
1
  import fetch from "node-fetch";
2
2
  import path from "path";
3
+ import logger from "loglevel";
4
+ import env from "../env.js";
5
+ import inquirer from "inquirer";
3
6
  import FormData from "form-data";
4
- import process from "process";
5
- import fs from "fs";
6
- import { APP_FOLDER, APP_CONFIG_FILE } from "../utils.js"
7
7
 
8
- const server = "https://account.lazycat.cloud"
9
-
10
- function genFormData(data) {
11
- const form = new FormData();
12
- for (const name in data) {
13
- form.append(name, data[name]);
14
- }
15
- return form
16
- }
8
+ const accountServerUrl = "https://account.lazycat.cloud";
17
9
 
18
10
  function join(...params) {
19
11
  var x = path.join(...params);
20
12
  return x;
21
13
  }
22
14
 
23
- function Login(username, password) {
24
- let form = genFormData({ username, password })
25
- return fetch(join(server, "/api/login/signin"), {
15
+ function login(username, password) {
16
+ const form = new FormData();
17
+ form.append("username", username);
18
+ form.append("password", password);
19
+
20
+ return fetch(join(accountServerUrl, "/api/login/signin"), {
26
21
  method: "POST",
27
22
  headers: {
28
- "content-type": `multipart/form-data; boundary=${form.getBoundary()}`
23
+ "content-type": `multipart/form-data; boundary=${form.getBoundary()}`,
29
24
  },
30
- body: form
31
- }).then(async res => {
32
- let bodyText = await res.text();
33
- let body = JSON.parse(bodyText)
34
- if (body.success) {
35
- return Promise.resolve(body.data)
36
- }
37
- return Promise.reject(body.message)
38
- }).then(data => {
39
- setToken(username, password, data.token)
25
+ body: form,
40
26
  })
27
+ .then(async (res) => {
28
+ let bodyText = await res.text();
29
+ let body = JSON.parse(bodyText);
30
+ if (body.success) {
31
+ return Promise.resolve(body.data);
32
+ }
33
+ return Promise.reject(body.message);
34
+ })
35
+ .then((data) => {
36
+ env.set({ token: data.token }, true);
37
+ logger.info("登录成功!");
38
+ });
41
39
  }
42
40
 
43
- async function IsLogin() {
41
+ async function isLogin() {
44
42
  try {
45
- let token = getToken()
43
+ let token = env.get("token");
46
44
  if (!token) {
47
- return false
45
+ return false;
48
46
  }
49
- return fetch(join(server, "/api/user/current"), {
47
+ return fetch(join(accountServerUrl, "/api/user/current"), {
50
48
  method: "GET",
51
49
  headers: {
52
- "X-User-Token": token
50
+ "X-User-Token": token,
53
51
  },
54
- }).then(async res => {
52
+ }).then(async (res) => {
55
53
  let bodyText = await res.text();
56
- let body = JSON.parse(bodyText)
54
+ let body = JSON.parse(bodyText);
57
55
  if (body.success) {
58
- return token
56
+ return token;
59
57
  }
60
- console.log(body.message);
61
- return false
62
- })
58
+ logger.debug(body.message);
59
+ return false;
60
+ });
63
61
  } catch (e) {
64
- console.log(e);
62
+ logger.trace(e);
63
+ return false;
65
64
  }
66
-
67
- return false
68
65
  }
69
66
 
70
- async function AutoLogin() {
71
- try {
72
- let token = await IsLogin()
73
- if (!!token) {
74
- return true
75
- }
67
+ async function askUserInfo() {
68
+ const noEmpty = (value) => value != "";
69
+ return await inquirer.prompt([
70
+ {
71
+ type: "input",
72
+ name: "username",
73
+ message: "请输入登录用户名",
74
+ validate: noEmpty,
75
+ },
76
+ {
77
+ type: "password",
78
+ mask: "*",
79
+ name: "password",
80
+ message: "请输入登录密码",
81
+ validate: noEmpty,
82
+ },
83
+ ]);
84
+ }
76
85
 
77
- console.log("token错误,尝试自动登录");
78
- let obj = getLocalObj()
79
- if (!!obj && !!obj.username && !!obj.password) {
80
- let l = await Login(obj.username, obj.password)
81
- return true
86
+ export async function reLogin() {
87
+ let token = await isLogin();
88
+ if (token) {
89
+ const questions = [
90
+ {
91
+ name: "relogin",
92
+ type: "input",
93
+ default: "n",
94
+ message: "检测到已经登录,是否重新登录(y/n):",
95
+ },
96
+ ];
97
+ const answers = await inquirer.prompt(questions);
98
+ if (answers.relogin.toLowerCase() === "n") {
99
+ logger.info(`token: ${token}`);
100
+ return;
82
101
  }
83
- } catch (e) {
84
- console.log(e);
85
102
  }
86
- removeToken()
87
- throw "自动登录失败"
88
- }
89
103
 
90
- const TokenFile = "user.json"
91
- const encoding = "utf8"
92
- function setToken(username, password, token) {
93
- let configHome = join(process.cwd(), APP_FOLDER, APP_CONFIG_FILE)
94
- if (!fs.existsSync(configHome)) {
95
- fs.mkdirSync(configHome, { recursive: true })
96
- }
97
- let tokenFile = join(configHome, TokenFile)
98
- let content = JSON.stringify({ username, password, token })
99
- fs.writeFileSync(tokenFile, content, {
100
- encoding,
101
- flag: "w",
102
- mode: 0o666
103
- })
104
+ let info = await askUserInfo();
105
+ await login(info.username, info.password);
104
106
  }
105
107
 
106
- function getToken() {
107
- let tokenFile = join(process.cwd(), APP_FOLDER, APP_CONFIG_FILE, TokenFile)
108
- let buf = fs.readFileSync(tokenFile, { encoding, flag: 'r' })
109
- let obj = JSON.parse(buf)
110
- if (!obj || !obj.token) {
111
- throw "读取本地文件失败"
108
+ export async function autoLogin() {
109
+ let token = await isLogin();
110
+ if (token) {
111
+ logger.debug("appstore 已经登录");
112
+ return;
112
113
  }
113
- return obj.token
114
+
115
+ logger.debug("token错误,尝试自动登录");
116
+ let info = await askUserInfo();
117
+ await login(info.username, info.password);
114
118
  }
115
119
 
116
- function getLocalObj() {
117
- let tokenFile = join(process.cwd(), APP_FOLDER, APP_CONFIG_FILE, TokenFile)
118
- let buf = fs.readFileSync(tokenFile, { encoding, flag: 'r' })
119
- let obj = JSON.parse(buf)
120
- if (!obj || !obj.token) {
121
- throw "读取本地文件失败"
120
+ export async function request(url, options = {}) {
121
+ await autoLogin();
122
+
123
+ const token = env.get("token");
124
+
125
+ let headers = {
126
+ "X-User-Token": token,
127
+ cookie: `userToken=${token}`,
128
+ };
129
+ if (options.headers) {
130
+ headers = Object.assign({}, options.headers, headers);
122
131
  }
123
- return obj
124
- }
125
132
 
126
- function removeToken() {
127
- let tokenFile = join(process.cwd(), APP_FOLDER, APP_CONFIG_FILE, TokenFile)
128
- return fs.rmSync(tokenFile)
129
- }
133
+ options = Object.assign({}, options, { headers });
134
+ logger.trace(`fetch ${url}`, options);
130
135
 
131
- export default {
132
- Login,
133
- AutoLogin
134
- }
136
+ return fetch(url, options);
137
+ }
@@ -0,0 +1,62 @@
1
+ import { request } from "./login.js";
2
+ import logger from "loglevel";
3
+ import FormData from "form-data";
4
+ import fs from "node:fs";
5
+ import inquirer from "inquirer";
6
+ import { spawnSync } from "node:child_process";
7
+ import path from "node:path";
8
+ import { isFileExist } from "../utils.js";
9
+
10
+ async function askChangeLog() {
11
+ const noEmpty = (value) => value != "";
12
+ return await inquirer.prompt([
13
+ {
14
+ name: "changelog",
15
+ type: "editor",
16
+ message: "填写 changelog 内容",
17
+ validate: noEmpty,
18
+ },
19
+ ]);
20
+ }
21
+
22
+ export class Publish {
23
+ constructor(baseUrl = "https://developer.lazycat.cloud/api/app") {
24
+ this.baseUrl = baseUrl;
25
+ }
26
+
27
+ async publish(pkgPath, changelog) {
28
+ const tempDir = fs.mkdtempSync(".lzc-cli-publish");
29
+ try {
30
+ spawnSync("unzip", ["-d", tempDir, pkgPath]);
31
+ if (isFileExist(path.join(tempDir, "devshell"))) {
32
+ throw "不能发布一个devshell的版本,请重新使用 `lzc-cli project build` 构建";
33
+ }
34
+ } finally {
35
+ fs.rmSync(tempDir, { recursive: true });
36
+ }
37
+
38
+ if (!changelog) {
39
+ const answer = await askChangeLog();
40
+ changelog = answer.changelog;
41
+ }
42
+
43
+ logger.info("正在发布...");
44
+ const form = new FormData();
45
+ form.append("files", fs.createReadStream(pkgPath));
46
+ form.append("changelog", changelog);
47
+
48
+ return request(this.baseUrl + "/update", {
49
+ method: "POST",
50
+ body: form,
51
+ }).then(async (res) => {
52
+ if (res.status != 200) {
53
+ logger.error(await res.text());
54
+ return;
55
+ }
56
+
57
+ logger.info("发布成功!");
58
+ logger.debug("publish response", await res.json());
59
+ return;
60
+ });
61
+ }
62
+ }
package/lib/autologin.js CHANGED
@@ -1,82 +1,4 @@
1
1
  import fetch from "node-fetch";
2
-
3
- // autologin.js 提供一个封装好的 fetch request 请求方法,通过这个中间件,可以不用考虑
4
- // auth:auto 所做的授权验证。
5
- let AutoLoginToken = "";
6
- let AutoLoginFailed = false;
7
-
8
- function fetchTokenAction(url) {
9
- return fetch(url).then(async (res) => {
10
- const body = await res.text();
11
- const token = body.match(/name=\"token\" value=\"(.*?)\"/i)[1];
12
- const action = body.match(/action=\"(.*?)\"/i)[1];
13
-
14
- return { token, action };
15
- });
16
- }
17
-
18
- function fetchTokenActionAndRedirect(dataToken, dataAction) {
19
- return fetch(dataAction, {
20
- method: "POST",
21
- body: `token=${dataToken}`,
22
- redirect: "follow",
23
- headers: {
24
- accept:
25
- "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
26
- "accept-language": "en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7",
27
- "content-type": "application/x-www-form-urlencoded",
28
- },
29
- }).then(async (res) => {
30
- let body = await res.text();
31
- const token = body.match(/name=\"token\" value=\"(.*?)\"/i)[1];
32
- const action = body.match(/action=\"(.*?)\"/i)[1];
33
- const redirect = body.match(/name=\"redirect\" value=\"(.*?)\"/i)[1];
34
-
35
- return { token, action, redirect };
36
- });
37
- }
38
-
39
2
  export async function request(url, options = {}) {
40
- if (AutoLoginFailed) {
41
- return fetch(url, options);
42
- }
43
-
44
- await tryAuthLogin(url);
45
-
46
- if (!AutoLoginToken) {
47
- return fetch(url, options);
48
- }
49
-
50
- let headers = { cookie: `HC-Auth-Token=${AutoLoginToken}` };
51
- if (options.headers) {
52
- headers = Object.assign({}, options.headers, headers);
53
- }
54
-
55
- options = Object.assign({}, options, { headers });
56
3
  return fetch(url, options);
57
4
  }
58
-
59
- export async function tryAuthLogin(url) {
60
- if (!url.startsWith("http")) {
61
- url = "https://" + url;
62
- }
63
-
64
- try {
65
- if (!AutoLoginToken) {
66
- let _url = new URL(url);
67
- let u = "sdk."+_url.host.split(".").reverse().slice(0, 3).reverse().join(".");
68
-
69
- console.log(`登陆到 ${u}`);
70
-
71
- let data = await fetchTokenAction(`${_url.protocol}//${u}`);
72
- let data2 = await fetchTokenActionAndRedirect(data.token, data.action);
73
-
74
- AutoLoginToken = data2.token;
75
- return AutoLoginToken;
76
- }
77
- } catch (e) {
78
- console.log(`无法登陆`);
79
- AutoLoginFailed = true;
80
- return "";
81
- }
82
- }