@lazycatcloud/lzc-cli 1.1.1 → 1.1.4

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 (67) hide show
  1. package/cmds/app.js +137 -0
  2. package/cmds/config.js +55 -0
  3. package/cmds/create.js +55 -0
  4. package/cmds/dev.js +122 -0
  5. package/cmds/init.js +125 -0
  6. package/cmds/log.js +103 -0
  7. package/cmds/publish.js +116 -0
  8. package/lib/api.js +34 -36
  9. package/lib/archiver.js +50 -31
  10. package/lib/box/check_qemu.js +27 -0
  11. package/lib/box/hportal.js +114 -0
  12. package/lib/box/index.js +152 -0
  13. package/lib/box/qemu_vm_mgr.js +625 -0
  14. package/lib/box/schemes/vm_box_system_debian.json +47 -0
  15. package/lib/builder.js +154 -35
  16. package/lib/dev.js +51 -32
  17. package/lib/env.js +276 -57
  18. package/lib/generator.js +31 -0
  19. package/lib/git/git-commit.sh +7 -0
  20. package/lib/git/git-reset.sh +15 -0
  21. package/lib/key.js +14 -11
  22. package/lib/sdk.js +7 -10
  23. package/lib/utils.js +149 -53
  24. package/package.json +18 -5
  25. package/scripts/cli.js +134 -70
  26. package/template/_lazycat/app-config +1 -0
  27. package/template/_lazycat/docker-compose.yml.in +3 -5
  28. package/template/golang/README.md +3 -4
  29. package/template/golang/assets/css/bootstrap-responsive.css +26 -23
  30. package/template/golang/assets/css/bootstrap-responsive.min.css +1065 -1
  31. package/template/golang/assets/css/bootstrap.css +733 -362
  32. package/template/golang/assets/css/bootstrap.min.css +5299 -1
  33. package/template/golang/assets/css/rego.css +17 -17
  34. package/template/golang/assets/js/bootstrap.js +1340 -1311
  35. package/template/golang/assets/js/bootstrap.min.js +1240 -5
  36. package/template/golang/assets/js/rego.js +80 -69
  37. package/template/golang/index.html +61 -59
  38. package/template/ionic_vue3/README.md +46 -0
  39. package/template/ionic_vue3/_eslintrc.cjs +24 -0
  40. package/template/ionic_vue3/_gitignore +29 -0
  41. package/template/ionic_vue3/_vscode/extensions.json +6 -0
  42. package/template/ionic_vue3/capacitor.config.ts +10 -0
  43. package/template/ionic_vue3/env.d.ts +1 -0
  44. package/template/ionic_vue3/index.html +13 -0
  45. package/template/ionic_vue3/ionic.config.json +7 -0
  46. package/template/ionic_vue3/package.json +52 -0
  47. package/template/ionic_vue3/postcss.config.js +6 -0
  48. package/template/ionic_vue3/public/favicon.ico +0 -0
  49. package/template/ionic_vue3/src/App.vue +11 -0
  50. package/template/ionic_vue3/src/assets/logo.svg +1 -0
  51. package/template/ionic_vue3/src/index.css +3 -0
  52. package/template/ionic_vue3/src/main.ts +35 -0
  53. package/template/ionic_vue3/src/router/index.ts +15 -0
  54. package/template/ionic_vue3/src/theme/variables.css +231 -0
  55. package/template/ionic_vue3/src/views/Home.vue +38 -0
  56. package/template/ionic_vue3/tailwind.config.js +7 -0
  57. package/template/ionic_vue3/tsconfig.json +16 -0
  58. package/template/ionic_vue3/tsconfig.vite-config.json +8 -0
  59. package/template/ionic_vue3/vite.config.ts +28 -0
  60. package/template/release/golang/build.sh +1 -2
  61. package/template/release/ionic_vue3/Dockerfile +10 -0
  62. package/template/release/ionic_vue3/build.sh +9 -0
  63. package/template/release/ionic_vue3/docker-compose.yml.in +8 -0
  64. package/template/release/vue/Dockerfile +3 -2
  65. package/template/release/vue/build.sh +4 -2
  66. package/template/vue/README.md +5 -0
  67. package/template/vue/babel.config.js +2 -4
package/lib/utils.js CHANGED
@@ -5,7 +5,6 @@ import os from "os";
5
5
  import chalk from "chalk";
6
6
  import archiver from "archiver";
7
7
  import glob from "fast-glob";
8
- import envsub from "envsub";
9
8
  import yaml from "js-yaml";
10
9
  import mergeWith from "lodash.mergewith";
11
10
  import isArray from "lodash.isarray";
@@ -13,44 +12,130 @@ import fetch from "node-fetch";
13
12
  import { dirname } from "path";
14
13
  import { fileURLToPath } from "url";
15
14
  import ignore from "ignore";
15
+ import ora from "ora";
16
+ import { desireStatusTimer } from "../lib/api.js";
17
+ import { warn } from "console";
16
18
 
17
- const controller = new AbortController();
18
19
  const META_MARK = "x-lazycat-app";
19
20
  const APP_FOLDER = ".lazycat";
20
21
  const APP_CONFIG_FILE = "app-config";
21
22
  const APP_SDK_HOSTNAME = "box";
22
- export const GLOBAL_CONFIG_DIR = path.join(os.homedir(), "/.config/lazycat")
23
+ export const GLOBAL_CONFIG_DIR = path.join(os.homedir(), "/.config/lazycat");
23
24
 
24
25
  export const envsubstr = async (templateContents, args) => {
25
26
  const parse = await importDefault("envsub/js/envsub-parser.js");
26
27
  return parse(templateContents, args);
27
28
  };
28
-
29
- // commander passes the Command object itself as options,
30
- // extract only actual options into a fresh object.
31
- async function checkURL(url) {
32
- const timeout = setTimeout(() => {
33
- controller.abort();
34
- }, 5000);
35
-
29
+ /**
30
+ * 为盒子安装SDK应用
31
+ * @param box_url 盒子入口地址
32
+ **/
33
+ async function InstallSDK(box_url) {
36
34
  try {
37
- const resp = await fetch(url, { signal: controller.signal });
35
+ let url = `${box_url}/api/app/apply?id=sdk`;
36
+ const resp = await fetch(url, { method: "post" });
38
37
  if (resp.status != 200) {
39
- throw new Error(chalk.red(
40
- `无法连接 sdk 服务, 请确保 ${chalk.yellow(
41
- new URL(url).origin
42
- )} 可以访问或者在应用商店安装 sdk`
43
- ));
38
+ throw new Error(
39
+ chalk.red(
40
+ `无法安装, 请确保 ${chalk.yellow(
41
+ new URL(url).origin
42
+ )} 可以访问或者在应用商店安装 sdk`
43
+ )
44
+ );
45
+ }
46
+ } catch (err) {
47
+ throw err;
48
+ }
49
+ }
50
+ /**
51
+ * 检查SDK安装部署的状态
52
+ * @param box_url 盒子入口地址
53
+ **/
54
+ async function checkSDKInstallStatus(box_url) {
55
+ const checkSDKstatus = async function (box_url) {
56
+ let url = `${box_url}/api/app/status?id=sdk`;
57
+ const resp = await fetch(url);
58
+ if (resp.status == 200) {
59
+ const status = await resp.json();
60
+ return status;
61
+ } else {
62
+ let text = await resp.text();
63
+ throw text;
64
+ }
65
+ };
66
+ const spinner = ora().start();
67
+ let { status, info } = await checkSDKstatus(box_url);
68
+ spinner.text = "部署进度";
69
+ switch (status) {
70
+ case "running":
71
+ console.log(chalk.yellow("应用正在运行中"));
72
+ break;
73
+ case "error":
74
+ spinner.stop();
75
+ console.log(status, info);
76
+ throw info.msg;
77
+ default:
78
+ try {
79
+ await desireStatusTimer(
80
+ (result) => {
81
+ spinner.text = "部署进度 " + result.status;
82
+ return result.status === "running";
83
+ },
84
+ () => {
85
+ return checkSDKstatus(box_url);
86
+ }
87
+ );
88
+ } catch (error) {
89
+ throw error;
90
+ } finally {
91
+ spinner.stop();
92
+ }
93
+ break;
94
+ }
95
+ spinner.stop();
96
+ }
97
+
98
+ /**
99
+ * 获取所有已安装的app
100
+ * @param box_url 盒子入口地址
101
+ **/
102
+ async function getInstalledApps(box_url) {
103
+ try {
104
+ let url = `${box_url}/api/app/dump`;
105
+ const resp = await fetch(url);
106
+ if (resp.status != 200) throw new Error(chalk.red("获取所有已安装App失败"));
107
+ return await resp.json();
108
+ } catch (e) {
109
+ console.log(e);
110
+ }
111
+ }
112
+ /**
113
+ * 查找某个app是否已安装]
114
+ * @param box_url 盒子入口地址
115
+ * @param app_id app名
116
+ * */
117
+ async function findAppIsInstalled(box_url, app_id) {
118
+ const apps = await getInstalledApps(box_url);
119
+ for (let app in apps) {
120
+ if (app == app_id) {
121
+ return true;
44
122
  }
45
- } catch (error) {
46
- throw error;
47
- } finally {
48
- clearTimeout(timeout);
49
123
  }
124
+ return false;
50
125
  }
51
126
 
127
+ /**
128
+ * 确保文件夹存在
129
+ * @param filePath {string} 如果为文件路径 确保其文件夹存在; 如果为文件夹, 则确保该文件夹存在
130
+ *
131
+ */
52
132
  function ensureDir(filePath) {
53
- const dirPath = path.dirname(filePath);
133
+ let dirPath;
134
+ if (filePath.endsWith("/")) {
135
+ dirPath = filePath;
136
+ } else {
137
+ dirPath = path.dirname(filePath);
138
+ }
54
139
  if (!fs.existsSync(dirPath)) {
55
140
  fs.mkdirSync(dirPath, { recursive: true });
56
141
  }
@@ -118,7 +203,7 @@ function getMetaInfo(composeFile) {
118
203
  return doc[META_MARK];
119
204
  }
120
205
 
121
- async function convertTemplateFile(templateFile, outputFile, env) {
206
+ async function createTemplateFile(templateFile, outputFile, env) {
122
207
  const template = yaml.load(fs.readFileSync(templateFile, "utf8"));
123
208
  // const meta = template[META_MARK];
124
209
  // if (
@@ -135,7 +220,7 @@ async function convertTemplateFile(templateFile, outputFile, env) {
135
220
  // authcallback: "/lzcapis/oidc-callback",
136
221
  // });
137
222
  // template["services"]["lazycat-apis-sidecar"] = {
138
- // image: "registry.linakesi.com/lazycat-apis-sidecar",
223
+ // image: "registry.lazycat.cloud/lazycat-apis-sidecar",
139
224
  // // volumes_from: ["${APP_NAME}:rw"],
140
225
  // volumes: ["lzcapis-lzcapp:/lzcapp"],
141
226
  // command: [
@@ -192,7 +277,7 @@ async function copyDotAppDir(from, to, opts = {}) {
192
277
  }
193
278
  ensureDir(outputFile);
194
279
  if (needConvert) {
195
- await convertTemplateFile(templateFile, outputFile, env);
280
+ await createTemplateFile(templateFile, outputFile, env);
196
281
  } else {
197
282
  fs.copyFileSync(templateFile, outputFile);
198
283
  }
@@ -256,8 +341,8 @@ function archiveFolder(appDir, format = "zip") {
256
341
  });
257
342
  }
258
343
 
259
- function contextDirname() {
260
- return dirname(fileURLToPath(import.meta.url));
344
+ function contextDirname(url = import.meta.url) {
345
+ return dirname(fileURLToPath(url));
261
346
  }
262
347
 
263
348
  async function importDefault(pkgPath) {
@@ -266,39 +351,39 @@ async function importDefault(pkgPath) {
266
351
  }
267
352
 
268
353
  class GitIgnore {
269
- constructor() {
270
- this.ig = ignore({ allowRelativePaths: true });
354
+ constructor(root) {
355
+ this.root = root;
356
+ this.ignores = [];
271
357
  }
272
358
 
273
- // 扫面一个指定的文件夹, 将.gitignore中的规则添加到this.gitignore
274
- scan(dir) {
275
- try {
276
- let data = fs.readFileSync(path.join(dir, ".gitignore"), "utf8");
277
- this.ig.add(data.split("\n"));
278
- } catch {
279
- // if not exist .gitignore
280
- }
281
- }
359
+ async collect() {
360
+ const files = await glob(["**/.gitignore"], {
361
+ cwd: this.root,
362
+ dot: true,
363
+ deep: 3,
364
+ });
282
365
 
283
- contain(filepath) {
284
- return this.ig.ignores(filepath);
366
+ files.forEach((f) => this._add(f));
285
367
  }
286
368
 
287
- // node.js fs.readdir的封装,会自动扫描.gitignore并过滤
288
- async readdir(dir, callback) {
289
- await this.scan(dir);
290
-
291
- if (this.ig.ignores(dir)) {
292
- return callback("", []);
293
- }
369
+ _add(ignoreFile) {
370
+ let data = fs.readFileSync(ignoreFile, "utf8");
371
+ let ig = ignore({ allowRelativePaths: true });
372
+ ig.add(data.split("\n"));
373
+ this.ignores.push({
374
+ ig,
375
+ dir: path.dirname(ignoreFile),
376
+ });
377
+ }
294
378
 
295
- return fs.readdir(dir, { withFileTypes: true }, (err, files) => {
296
- if (err) {
297
- return callback(err, []);
379
+ contain(filepath) {
380
+ return this.ignores.some(({ ig, dir }) => {
381
+ // 去除不应该计算ignore 的文件
382
+ if (!filepath.startsWith(dir)) {
383
+ return false;
298
384
  }
299
385
 
300
- let validFiles = files.filter((f) => !this.ig.ignores(f.name));
301
- return callback(err, validFiles);
386
+ return ig.ignores(path.relative(dir, filepath));
302
387
  });
303
388
  }
304
389
  }
@@ -325,6 +410,12 @@ function urlHostname(url) {
325
410
  return u.hostname;
326
411
  }
327
412
 
413
+ // REVIEW: 用户输入的app-id 空格替换为减号并且转换为全小写。
414
+ // 这会影响默认的app-name,因为app-name的默认值依赖app-id,但是如果特定输入了app-name则正常
415
+ function parse2CorrectName(name) {
416
+ return name.replaceAll(" ", "-").toLowerCase();
417
+ }
418
+
328
419
  export {
329
420
  ensureDir,
330
421
  copyDotAppDir,
@@ -333,7 +424,6 @@ export {
333
424
  findAppRootPath,
334
425
  archiveFolder,
335
426
  mergeYaml,
336
- checkURL,
337
427
  loadFromYaml,
338
428
  dumpToYaml,
339
429
  importDefault,
@@ -347,4 +437,10 @@ export {
347
437
  GitIgnore,
348
438
  isFileExist,
349
439
  urlHostname,
440
+ InstallSDK,
441
+ findAppIsInstalled,
442
+ getInstalledApps,
443
+ checkSDKInstallStatus,
444
+ createTemplateFile,
445
+ parse2CorrectName,
350
446
  };
package/package.json CHANGED
@@ -1,14 +1,21 @@
1
1
  {
2
2
  "name": "@lazycatcloud/lzc-cli",
3
- "version": "1.1.1",
3
+ "version": "1.1.4",
4
4
  "description": "lazycat cloud developer kit",
5
5
  "scripts": {
6
- "test": "echo \"Error: no test specified\" && exit 1"
6
+ "test": "mocha",
7
+ "publish": "npm publish --access public"
8
+ },
9
+ "mocha": {
10
+ "recursive": true,
11
+ "reporter": "spec",
12
+ "timeout": 5000
7
13
  },
8
14
  "files": [
9
15
  "template",
10
16
  "scripts",
11
- "lib"
17
+ "lib",
18
+ "cmds"
12
19
  ],
13
20
  "bin": {
14
21
  "lzc-cli": "./scripts/cli.js"
@@ -23,7 +30,8 @@
23
30
  "@balena/dockerignore": "^1.0.2",
24
31
  "archiver": "^5.3.0",
25
32
  "chalk": "^4.1.2",
26
- "commander": "^8.3.0",
33
+ "chokidar": "^3.5.3",
34
+ "command-exists": "^1.2.9",
27
35
  "dockerfile-ast": "^0.4.1",
28
36
  "dockerode": "^3.3.1",
29
37
  "ejs": "^3.1.6",
@@ -40,14 +48,19 @@
40
48
  "lodash.merge": "^4.6.2",
41
49
  "lodash.mergewith": "^4.6.2",
42
50
  "log-update": "^5.0.0",
51
+ "lz4": "^0.6.5",
43
52
  "minimist": "^1.2.5",
44
53
  "node-fetch": "^2.6.6",
54
+ "node-stream-zip": "^1.15.0",
45
55
  "ora": "^6.0.1",
46
56
  "semver": "^7.3.5",
47
57
  "ssh2": "^1.5.0",
48
- "ssh2-promise": "^1.0.2"
58
+ "ssh2-promise": "^1.0.2",
59
+ "yargs": "^17.5.1"
49
60
  },
50
61
  "devDependencies": {
62
+ "chai": "^4.3.6",
63
+ "mocha": "^9.2.2",
51
64
  "prettier": "^2.5.0"
52
65
  }
53
66
  }
package/scripts/cli.js CHANGED
@@ -1,98 +1,162 @@
1
1
  #!/usr/bin/env node
2
-
3
- import program from "commander";
4
2
  import process from "process";
5
3
  import path from "path";
6
4
  import fs from "fs";
7
5
  import { contextDirname, importDefault } from "../lib/utils.js";
8
- import Env from "../lib/env.js";
6
+ import yargs from "yargs";
7
+ import { hideBin } from "yargs/helpers";
9
8
 
9
+ import Env from "../lib/env.js";
10
+ import { boxCommand } from "../lib/box/index.js";
10
11
  const pkgInfo = JSON.parse(
11
- fs.readFileSync(path.join(contextDirname(), "../package.json"))
12
+ fs.readFileSync(path.join(contextDirname(import.meta.url), "../package.json"))
12
13
  );
13
14
 
14
- program.usage("<command> [options]");
15
-
16
- program
17
- .version(`lzc-cli ${pkgInfo.version}`)
15
+ const program = yargs(hideBin(process.argv))
16
+ .scriptName("lzc-cli")
18
17
  .usage("<command> [options]")
19
- .command("create <name>")
20
- .description("创建懒猫云应用")
21
- .action(async (name, cmd) => {
18
+ .version(`lzc-cli ${pkgInfo.version}`)
19
+ .completion("completion", "生成bash/zsh补全脚本");
20
+
21
+ program.command({
22
+ command: "create <name>",
23
+ desc: "创建懒猫云应用",
24
+ aliases: ["c"],
25
+ handler: async ({ name }) => {
22
26
  let create = await importDefault("../cmds/create.js");
23
27
  await create({ name });
24
- });
28
+ },
29
+ });
25
30
 
26
- program
27
- .command("init")
28
- .description("初始化懒猫云应用配置")
29
- .action(async (options) => {
31
+ program.command({
32
+ command: "init",
33
+ desc: "初始化懒猫云应用配置",
34
+ handler: async () => {
30
35
  const { Init } = await import("../cmds/init.js");
31
36
  new Init({ cwd: process.cwd() }).create();
32
- });
37
+ },
38
+ });
33
39
 
34
- program
35
- .command("uninstall")
36
- .description("卸载应用")
37
- .action(async (options) => {
40
+ program.command({
41
+ command: "uninstall",
42
+ desc: "卸载应用",
43
+ handler: async () => {
38
44
  const { uninstall } = await importDefault("../cmds/app.js");
39
45
  await uninstall();
40
- });
46
+ },
47
+ });
48
+
49
+ program.command({
50
+ command: "publish",
51
+ desc: "发布应用",
52
+ handler: async () => {
53
+ // 第一步 打包镜像
54
+ const Publisher = await importDefault("../cmds/publish.js");
55
+ const publisher = new Publisher();
56
+ await publisher.run();
57
+ // const b = builder();
58
+ // const contextDir = process.cwd()
59
+ // const dockerfile = Env.get("BUILD_CONTEXT")
60
+ // b.dockerRemoteBuildV2()
61
+ // 第二步
62
+ },
63
+ });
41
64
 
42
- program
43
- .command("deploy")
44
- .description("部署应用至设备")
45
- .action(async (url, _options) => {
65
+ program.command({
66
+ command: "deploy",
67
+ desc: "部署应用至设备",
68
+ handler: async () => {
46
69
  const { deploy } = await importDefault("../cmds/app.js");
47
70
  await deploy();
48
- });
49
-
50
- program
51
- .command("build")
52
- .argument("[context]", "integer argument")
53
- .option("-f, --file <file>", "", "Dockerfile")
54
- .action(async (context, options) => {
55
- const builder = await importDefault("../lib/builder.js");
56
- const b = builder({ env: Env(process.cwd()).all });
57
- b.dockerRemoteBuildV2(context, options.file);
58
- });
71
+ },
72
+ });
59
73
 
60
- let dev = program.command("dev").description("dev [forward [addr] | shell]");
74
+ program.command({
75
+ command: "build [context]",
76
+ desc: "构建",
77
+ builder: (args) => {
78
+ args.option("f", {
79
+ alias: "file",
80
+ describe: "Dockerfile",
81
+ default: "Dockerfile",
82
+ });
83
+ },
84
+ handler: async ({ context, file }) => {
85
+ const Builder = await importDefault("../lib/builder.js");
86
+ Env.load(process.cwd());
87
+ const b = new Builder({ env: Env.all });
88
+ b.dockerRemoteBuildV2(context, file);
89
+ },
90
+ });
61
91
 
62
- dev
63
- .command("forward [addr]")
64
- .description("本地端口转发")
65
- .action(async (addr) => {
66
- const { dev } = await importDefault("../cmds/dev.js");
67
- await dev(addr);
68
- });
92
+ let devSubCommands = [
93
+ {
94
+ command: "forward [addr]",
95
+ desc: "本地端口转发",
96
+ handler: async ({ addr }) => {
97
+ const { dev } = await importDefault("../cmds/dev.js");
98
+ await dev(addr);
99
+ },
100
+ },
101
+ {
102
+ command: "shell",
103
+ desc: "远程连接盒子",
104
+ builder: (args) => {
105
+ args.option("b", {
106
+ alias: "build",
107
+ desc: "重新部署应用",
108
+ type: "boolean",
109
+ });
110
+ },
111
+ handler: async (args) => {
112
+ const { devShell } = await importDefault("../cmds/dev.js");
113
+ await devShell(args);
114
+ },
115
+ },
116
+ ];
117
+ program.command({
118
+ command: "dev",
119
+ desc: "dev [forward [addr] | shell]",
120
+ builder: (args) => {
121
+ args.command(devSubCommands);
122
+ },
123
+ });
69
124
 
70
- dev
71
- .command("shell")
72
- .option("-b, --build", "重新部署应用")
73
- .description("本地开发应用")
74
- .action(async (options) => {
75
- const { devShell } = await importDefault("../cmds/dev.js");
76
- await devShell(options);
77
- });
78
-
79
- program
80
- .command("log [project]")
81
- .description("查看应用日志")
82
- .action(async (projectName) => {
125
+ program.command({
126
+ command: "log [project]",
127
+ desc: "查看应用日志",
128
+ builder: (args) => {
129
+ args.option("u", {
130
+ alias: "user",
131
+ describe: "多实例对应的用户",
132
+ demandOption: false,
133
+ type: "string",
134
+ });
135
+ },
136
+ handler: async (args) => {
83
137
  const { monitor } = await importDefault("../cmds/log.js");
84
- await monitor(projectName);
85
- });
138
+ await monitor(args.project, args);
139
+ },
140
+ });
86
141
 
87
- program
88
- .command("config")
89
- .description("应用配置项")
90
- .argument("[key]", "key argument")
91
- .argument("[value]", "integer argument")
92
- .option("-g, --global", "global config", false)
93
- .action(async (key, value, options) => {
142
+ program.command({
143
+ command: "config [key] [value]",
144
+ desc: "应用配置项",
145
+ builder: (args) => {
146
+ args.implies("key", "value");
147
+ args.option("g", {
148
+ alias: "global",
149
+ describe: "global config",
150
+ type: "boolean",
151
+ default: false,
152
+ });
153
+ },
154
+ handler: async (args) => {
94
155
  const { config } = await importDefault("../cmds/config.js");
95
- await config([key, value, options]);
96
- });
156
+ await config([args.key, args.value, args]);
157
+ },
158
+ });
159
+
160
+ boxCommand(program);
97
161
 
98
- program.parse(process.argv);
162
+ program.showHelpOnFail(false, "使用 lzc-cli help 查看更多帮助").parse();
@@ -0,0 +1 @@
1
+ {}
@@ -1,8 +1,8 @@
1
1
  version: "3.9"
2
2
  x-lazycat-app:
3
3
  id: ${APP_ID}
4
- title: ${APP_NAME}
5
- version: 1.0.0
4
+ title: ${APP_DESCRIPTION}
5
+ version: ${APP_VERSION}
6
6
  description:
7
7
  icon: icon.svg
8
8
  categories:
@@ -12,6 +12,4 @@ x-lazycat-app:
12
12
  - service: ${APP_ID}
13
13
  port: ${HTTP_SERVICE_PORT}
14
14
  subdomain: ${APP_ID}
15
- permissions:
16
- - lzcapis
17
-
15
+ auth: auto
@@ -1,5 +1,4 @@
1
- rego
2
- ====
1
+ # rego
3
2
 
4
3
  Rego is an online Go regular expression tester
5
4
 
@@ -9,5 +8,5 @@ It's currently deployed on Heroku at [http://regoio.herokuapp.com/](http://regoi
9
8
 
10
9
  ## TODO
11
10
 
12
- * Sharing (permalink)
13
- * Add developer documentation
11
+ - Sharing (permalink)
12
+ - Add developer documentation