@lazycatcloud/lzc-cli 2.0.0-pre.0 → 2.0.0-pre.2

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 (92) hide show
  1. package/README.md +46 -7
  2. package/changelog.md +56 -19
  3. package/lib/app/apkshell.js +7 -44
  4. package/lib/app/index.js +5 -1
  5. package/lib/app/lpk_build.js +266 -56
  6. package/lib/app/lpk_build_images.js +424 -229
  7. package/lib/app/lpk_build_images_local.js +425 -0
  8. package/lib/app/lpk_build_images_pack_local.js +409 -0
  9. package/lib/app/lpk_create.js +158 -83
  10. package/lib/app/lpk_create_generator.js +35 -42
  11. package/lib/app/lpk_devshell.js +6 -2
  12. package/lib/app/lpk_installer.js +4 -3
  13. package/lib/app/manifest_build.js +259 -0
  14. package/lib/app/project_cp.js +5 -10
  15. package/lib/app/project_deploy.js +80 -11
  16. package/lib/app/project_exec.js +48 -11
  17. package/lib/app/project_info.js +59 -59
  18. package/lib/app/project_log.js +5 -10
  19. package/lib/app/project_runtime.js +113 -18
  20. package/lib/app/project_start.js +6 -11
  21. package/lib/app/project_sync.js +499 -0
  22. package/lib/appstore/apkshell.js +50 -0
  23. package/lib/appstore/publish.js +54 -15
  24. package/lib/build_remote.js +0 -1
  25. package/lib/config/index.js +1 -1
  26. package/lib/debug_bridge.js +217 -47
  27. package/lib/i18n/locales/en/translation.json +262 -262
  28. package/lib/i18n/locales/zh/translation.json +262 -262
  29. package/lib/lpk/core.js +2 -1
  30. package/lib/migrate/index.js +52 -0
  31. package/lib/package_info.js +135 -0
  32. package/lib/shellapi.js +35 -1
  33. package/lib/sig/core.js +2 -2
  34. package/lib/utils.js +92 -15
  35. package/package.json +89 -89
  36. package/scripts/cli.js +2 -0
  37. package/scripts/smoke/frontend-dev-entry.mjs +104 -0
  38. package/scripts/smoke/template-project.mjs +311 -0
  39. package/template/_lpk/README.md +6 -3
  40. package/template/_lpk/gui-vnc.manifest.yml.in +0 -9
  41. package/template/_lpk/hello-vue.manifest.yml.in +38 -0
  42. package/template/_lpk/manifest.yml.in +0 -9
  43. package/template/_lpk/package.yml.in +7 -0
  44. package/template/_lpk/todolist-golang.manifest.yml.in +23 -9
  45. package/template/_lpk/todolist-java.manifest.yml.in +23 -9
  46. package/template/_lpk/todolist-python.manifest.yml.in +31 -9
  47. package/template/_lpk/todolist-serverless.manifest.yml.in +38 -0
  48. package/template/blank/lzc-build.dev.yml +4 -0
  49. package/template/blank/lzc-build.yml +0 -2
  50. package/template/blank/lzc-manifest.yml +3 -12
  51. package/template/blank/package.yml +7 -0
  52. package/template/golang/Dockerfile +1 -1
  53. package/template/golang/Dockerfile.dev +20 -0
  54. package/template/golang/README.md +22 -11
  55. package/template/golang/_lzcdevignore +21 -0
  56. package/template/golang/lzc-build.dev.yml +12 -0
  57. package/template/golang/lzc-build.yml +0 -5
  58. package/template/golang/main.go +1 -1
  59. package/template/golang/manifest.dev.page.js +24 -0
  60. package/template/golang/run.sh +7 -0
  61. package/template/gui-vnc/README.md +5 -1
  62. package/template/gui-vnc/lzc-build.dev.yml +4 -0
  63. package/template/gui-vnc/lzc-build.yml +0 -5
  64. package/template/python/Dockerfile +2 -2
  65. package/template/python/Dockerfile.dev +18 -0
  66. package/template/python/README.md +28 -11
  67. package/template/python/_lzcdevignore +21 -0
  68. package/template/python/app.py +1 -1
  69. package/template/python/lzc-build.dev.yml +12 -0
  70. package/template/python/lzc-build.yml +0 -5
  71. package/template/python/manifest.dev.page.js +25 -0
  72. package/template/python/run.sh +12 -1
  73. package/template/springboot/Dockerfile +1 -1
  74. package/template/springboot/Dockerfile.dev +20 -0
  75. package/template/springboot/README.md +22 -11
  76. package/template/springboot/_lzcdevignore +21 -0
  77. package/template/springboot/lzc-build.dev.yml +12 -0
  78. package/template/springboot/lzc-build.yml +0 -5
  79. package/template/springboot/manifest.dev.page.js +24 -0
  80. package/template/springboot/run.sh +7 -0
  81. package/template/vue/README.md +14 -27
  82. package/template/vue/_gitignore +0 -1
  83. package/template/vue/lzc-build.dev.yml +7 -0
  84. package/template/vue/lzc-build.yml +0 -2
  85. package/template/vue/manifest.dev.page.js +50 -0
  86. package/template/vue/src/App.vue +1 -1
  87. package/template/vue-minidb/README.md +11 -19
  88. package/template/vue-minidb/_gitignore +0 -1
  89. package/template/vue-minidb/lzc-build.dev.yml +7 -0
  90. package/template/vue-minidb/lzc-build.yml +0 -2
  91. package/template/vue-minidb/manifest.dev.page.js +50 -0
  92. package/template/blank/_gitignore +0 -1
@@ -0,0 +1,52 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import logger from 'loglevel';
4
+ import { LpkBuild } from '../app/lpk_build.js';
5
+ import { dumpToYaml, loadFromYaml } from '../utils.js';
6
+ import { PACKAGE_FILE_NAME, splitManifestAndPackageInfo } from '../package_info.js';
7
+
8
+ async function migrateHandler({ context, file }) {
9
+ const cwd = context ? path.resolve(context) : process.cwd();
10
+ const build = new LpkBuild(cwd, file || 'lzc-build.yml');
11
+ const manifestPath = build.manifestFilePath;
12
+ const packageFilePath = build.packageFilePath;
13
+
14
+ if (fs.existsSync(packageFilePath)) {
15
+ logger.info(`package metadata already exists at ${packageFilePath}`);
16
+ return;
17
+ }
18
+
19
+ let manifest;
20
+ try {
21
+ manifest = loadFromYaml(manifestPath) ?? {};
22
+ } catch {
23
+ throw new Error(`Cannot auto-migrate templated manifest: ${manifestPath}`);
24
+ }
25
+
26
+ const split = splitManifestAndPackageInfo(manifest);
27
+ if (Object.keys(split.packageInfo).length === 0) {
28
+ throw new Error(`No static package fields found in ${manifestPath}`);
29
+ }
30
+
31
+ dumpToYaml(split.packageInfo, packageFilePath);
32
+ dumpToYaml(split.manifest, manifestPath);
33
+
34
+ logger.info(`wrote ${PACKAGE_FILE_NAME}: ${packageFilePath}`);
35
+ logger.info(`updated manifest: ${manifestPath}`);
36
+ }
37
+
38
+ export function migrateCommand(program) {
39
+ program.command({
40
+ command: 'migrate [context]',
41
+ desc: 'Migrate manifest package metadata to package.yml',
42
+ builder: (args) => {
43
+ args.option('f', {
44
+ alias: 'file',
45
+ describe: 'Build config file',
46
+ type: 'string',
47
+ default: 'lzc-build.yml',
48
+ });
49
+ },
50
+ handler: migrateHandler,
51
+ });
52
+ }
@@ -0,0 +1,135 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import yaml from 'js-yaml';
4
+ import { fakeLoadManifestText, fakeLoadManifestYml, loadFromYaml } from './utils.js';
5
+
6
+ export const PACKAGE_FILE_NAME = 'package.yml';
7
+ export const STATIC_PACKAGE_FIELDS = [
8
+ 'package',
9
+ 'version',
10
+ 'name',
11
+ 'description',
12
+ 'author',
13
+ 'license',
14
+ 'homepage',
15
+ 'min_os_version',
16
+ 'unsupported_platforms',
17
+ 'locales',
18
+ ];
19
+
20
+ function hasOwn(obj, key) {
21
+ return Object.prototype.hasOwnProperty.call(obj ?? {}, key);
22
+ }
23
+
24
+ function readYamlIfExists(filePath) {
25
+ if (!filePath || !fs.existsSync(filePath)) {
26
+ return null;
27
+ }
28
+ return yaml.load(fs.readFileSync(filePath, 'utf-8')) ?? {};
29
+ }
30
+
31
+ function tryLoadManifestText(manifestText) {
32
+ const text = String(manifestText ?? '');
33
+ const hasGoTemplate = text.includes('{{') && text.includes('}}');
34
+ try {
35
+ return {
36
+ data: yaml.load(text) ?? {},
37
+ excp: hasGoTemplate,
38
+ };
39
+ } catch {
40
+ return {
41
+ data: fakeLoadManifestText(text) ?? {},
42
+ excp: true,
43
+ };
44
+ }
45
+ }
46
+
47
+ export function loadManifestFile(manifestPath) {
48
+ try {
49
+ return loadFromYaml(manifestPath) ?? {};
50
+ } catch {
51
+ return fakeLoadManifestYml(manifestPath) ?? {};
52
+ }
53
+ }
54
+
55
+ export function loadManifestText(manifestText) {
56
+ return tryLoadManifestText(manifestText).data;
57
+ }
58
+
59
+ export function loadPackageFile(packageFilePath) {
60
+ return readYamlIfExists(packageFilePath);
61
+ }
62
+
63
+ export function defaultPackageFilePath(manifestPath) {
64
+ return path.join(path.dirname(manifestPath), PACKAGE_FILE_NAME);
65
+ }
66
+
67
+ export function findManifestStaticFields(manifest) {
68
+ return STATIC_PACKAGE_FIELDS.filter((field) => hasOwn(manifest, field));
69
+ }
70
+
71
+ export function ensureManifestStaticFieldsAbsent(manifest, manifestPath) {
72
+ const invalidFields = findManifestStaticFields(manifest);
73
+ if (invalidFields.length === 0) {
74
+ return;
75
+ }
76
+ throw new Error(`Static package fields must be moved from ${manifestPath} to ${PACKAGE_FILE_NAME}: ${invalidFields.join(', ')}`);
77
+ }
78
+
79
+ export function applyPackageFileToManifest(manifest, packageInfo) {
80
+ const nextManifest = { ...(manifest ?? {}) };
81
+ for (const field of STATIC_PACKAGE_FIELDS) {
82
+ delete nextManifest[field];
83
+ }
84
+ if (!packageInfo) {
85
+ return nextManifest;
86
+ }
87
+ for (const field of STATIC_PACKAGE_FIELDS) {
88
+ if (hasOwn(packageInfo, field)) {
89
+ nextManifest[field] = packageInfo[field];
90
+ }
91
+ }
92
+ return nextManifest;
93
+ }
94
+
95
+ export function splitManifestAndPackageInfo(manifest, basePackageInfo = null) {
96
+ const manifestOnly = { ...(manifest ?? {}) };
97
+ const packageInfo = { ...(basePackageInfo ?? {}) };
98
+ for (const field of STATIC_PACKAGE_FIELDS) {
99
+ if (hasOwn(manifestOnly, field)) {
100
+ packageInfo[field] = manifestOnly[field];
101
+ delete manifestOnly[field];
102
+ }
103
+ }
104
+ return {
105
+ manifest: manifestOnly,
106
+ packageInfo,
107
+ };
108
+ }
109
+
110
+ export function loadEffectiveManifest(manifestPath, options = {}) {
111
+ const hasInlineManifestText = Object.prototype.hasOwnProperty.call(options, 'manifestText');
112
+ const loadedManifest = hasInlineManifestText
113
+ ? tryLoadManifestText(options.manifestText)
114
+ : { data: loadManifestFile(manifestPath), excp: false };
115
+ const sourceManifest = loadedManifest.data;
116
+ const packageFilePath = options.packageFilePath || defaultPackageFilePath(manifestPath);
117
+ const hasPackageFile = fs.existsSync(packageFilePath);
118
+ const packageInfo = hasPackageFile ? loadPackageFile(packageFilePath) ?? {} : null;
119
+ if (hasPackageFile && options.strictStaticFields) {
120
+ ensureManifestStaticFieldsAbsent(sourceManifest, manifestPath);
121
+ }
122
+ const manifest = hasPackageFile ? applyPackageFileToManifest(sourceManifest, packageInfo) : sourceManifest;
123
+ return {
124
+ manifest,
125
+ sourceManifest,
126
+ packageInfo,
127
+ hasPackageFile,
128
+ packageFilePath,
129
+ excpManifest: loadedManifest.excp,
130
+ };
131
+ }
132
+
133
+ export function loadEffectiveManifestFromFiles(manifestPath, options = {}) {
134
+ return loadEffectiveManifest(manifestPath, options);
135
+ }
package/lib/shellapi.js CHANGED
@@ -23,7 +23,9 @@ function getShellAPIConfigDir() {
23
23
  }
24
24
 
25
25
  class ShellApi {
26
- constructor() { }
26
+ constructor() {
27
+ this.clientId = '';
28
+ }
27
29
 
28
30
  async init() {
29
31
  // 检查当前 shell 环境上下文是否配置 HTTP_PROXY
@@ -109,6 +111,38 @@ NOTE:在指定环境变量的模式下,有些接口依旧不能访问,为
109
111
  });
110
112
  }
111
113
 
114
+ async queryShellCoreInfo() {
115
+ if (!this.client) {
116
+ return {};
117
+ }
118
+ return new Promise((resolve, reject) => {
119
+ this.client.queryShellCoreInfo({}, this.metadata, function (err, response) {
120
+ if (err) {
121
+ reject(err);
122
+ return;
123
+ }
124
+ resolve(response);
125
+ });
126
+ });
127
+ }
128
+
129
+ async resolveClientId() {
130
+ const cached = String(this.clientId ?? '').trim();
131
+ if (cached) {
132
+ return cached;
133
+ }
134
+ if (!this.client) {
135
+ return '';
136
+ }
137
+ const info = await this.queryShellCoreInfo();
138
+ const clientId = String(info?.id ?? '').trim();
139
+ if (!clientId) {
140
+ throw new Error('resolve client id failed: empty shell core id');
141
+ }
142
+ this.clientId = clientId;
143
+ return clientId;
144
+ }
145
+
112
146
  async initBoxInfo() {
113
147
  try {
114
148
  const boxes = await this.boxList();
package/lib/sig/core.js CHANGED
@@ -5,7 +5,7 @@ import crypto from 'node:crypto';
5
5
  import archiver from 'archiver';
6
6
  import AdmZip from 'adm-zip';
7
7
  import * as tar from 'tar';
8
- import yaml from 'js-yaml';
8
+ import { loadEffectiveManifestFromFiles } from '../package_info.js';
9
9
  import { t } from '../i18n/index.js';
10
10
 
11
11
  function toPosixPath(filePath) {
@@ -118,7 +118,7 @@ function loadManifestInfo(workDir) {
118
118
  return { appid: '', version: '' };
119
119
  }
120
120
  try {
121
- const manifest = yaml.load(fs.readFileSync(manifestPath, 'utf-8'));
121
+ const manifest = loadEffectiveManifestFromFiles(manifestPath).manifest;
122
122
  return {
123
123
  appid: manifest?.package ?? '',
124
124
  version: manifest?.version ? String(manifest.version) : '',
package/lib/utils.js CHANGED
@@ -182,28 +182,38 @@ export function loadFromYaml(file) {
182
182
  }
183
183
 
184
184
  // lzc-manifest.yml 要支持模板,目前无法直接用yaml库解释,手动读出必要字段
185
- export function fakeLoadManifestYml(file) {
186
- const res = fs.readFileSync(file, 'utf8');
185
+ function fakeLoadManifestCore(text) {
187
186
  let obj = {
188
187
  application: {
189
188
  subdomain: undefined,
190
189
  },
191
190
  };
192
191
 
193
- res.split('\n').forEach((v) => {
192
+ const normalizeValue = (value) => {
193
+ const commentIndex = value.indexOf(' #');
194
+ if (commentIndex >= 0) {
195
+ value = value.slice(0, commentIndex);
196
+ }
197
+ return value.trim();
198
+ };
199
+
200
+ String(text ?? '').split('\n').forEach((v) => {
194
201
  let line = v.trim();
195
202
  const arr = line.split(':');
196
203
  if (arr.length != 2) {
197
204
  return;
198
205
  }
199
206
  let [key, value] = arr;
200
- value = value.trim();
207
+ value = normalizeValue(value);
201
208
  if (!obj.package && key == 'package') {
202
209
  obj.package = value;
203
210
  }
204
211
  if (!obj.application.subdomain && key == 'subdomain') {
205
212
  obj.application.subdomain = value;
206
213
  }
214
+ if (!obj.name && key == 'name') {
215
+ obj.name = value;
216
+ }
207
217
  if (!obj.version && key == 'version') {
208
218
  obj.version = value;
209
219
  }
@@ -211,6 +221,14 @@ export function fakeLoadManifestYml(file) {
211
221
  return obj;
212
222
  }
213
223
 
224
+ export function fakeLoadManifestText(text) {
225
+ return fakeLoadManifestCore(text);
226
+ }
227
+
228
+ export function fakeLoadManifestYml(file) {
229
+ return fakeLoadManifestCore(fs.readFileSync(file, 'utf8'));
230
+ }
231
+
214
232
  export function dumpToYaml(template, target) {
215
233
  fs.writeFileSync(
216
234
  target,
@@ -526,16 +544,29 @@ export async function resolveDomain(domain, quiet = false) {
526
544
  }
527
545
  }
528
546
 
529
- export function unzipSync(zipPath, destPath, entries = []) {
530
- if (!isFileExist(zipPath)) {
531
- throw t('lzc_cli.lib.utils.unzip_sync_not_exist_fail', `{{ zipPath }} 找不到该文件`, { zipPath, interpolation: { escapeValue: false } });
547
+ function detectLpkArchiveFormatSync(filePath) {
548
+ const fd = fs.openSync(filePath, 'r');
549
+ try {
550
+ const header = Buffer.alloc(512);
551
+ const bytesRead = fs.readSync(fd, header, 0, header.length, 0);
552
+ if (bytesRead >= 4 && header[0] === 0x50 && header[1] === 0x4b && header[2] === 0x03 && header[3] === 0x04) {
553
+ return 'zip';
554
+ }
555
+ if (bytesRead >= 265 && header.subarray(257, 262).toString() === 'ustar') {
556
+ return 'tar';
557
+ }
558
+ throw new Error(`Unsupported LPK archive format: ${filePath}`);
559
+ } finally {
560
+ fs.closeSync(fd);
532
561
  }
562
+ }
533
563
 
534
- // 确保目标目录存在
535
- fs.mkdirSync(destPath, { recursive: true });
536
- // 创建 zip 实例
537
- const zip = new AdmZip(zipPath);
564
+ function normalizeArchiveEntryPath(entryPath) {
565
+ return String(entryPath ?? '').replace(/^\.\//, '').replace(/\\/g, '/');
566
+ }
538
567
 
568
+ function extractZipEntriesSync(zipPath, destPath, entries = []) {
569
+ const zip = new AdmZip(zipPath);
539
570
  if (entries.length > 0) {
540
571
  entries.forEach((entry) => {
541
572
  try {
@@ -544,10 +575,56 @@ export function unzipSync(zipPath, destPath, entries = []) {
544
575
  logger.debug(t('lzc_cli.lib.utils.unzip_sync_not_exist_file_log', `压缩包中没有找到 {{ entry }} 文件`, { entry, interpolation: { escapeValue: false } }));
545
576
  }
546
577
  });
547
- } else {
548
- // 同步解压所有文件
549
- zip.extractAllTo(destPath, true);
578
+ return;
579
+ }
580
+ zip.extractAllTo(destPath, true);
581
+ }
582
+
583
+ function extractTarEntriesSync(tarPath, destPath, entries = []) {
584
+ const wanted = new Set((entries ?? []).map((entry) => normalizeArchiveEntryPath(entry)).filter(Boolean));
585
+ tar.x({
586
+ file: tarPath,
587
+ cwd: destPath,
588
+ sync: true,
589
+ filter: (entryPath) => {
590
+ if (wanted.size === 0) {
591
+ return true;
592
+ }
593
+ const normalized = normalizeArchiveEntryPath(entryPath);
594
+ return wanted.has(normalized);
595
+ },
596
+ });
597
+
598
+ if (wanted.size === 0) {
599
+ return;
600
+ }
601
+ for (const entry of wanted) {
602
+ if (!isFileExist(path.join(destPath, entry))) {
603
+ logger.debug(t('lzc_cli.lib.utils.unzip_sync_not_exist_file_log', `压缩包中没有找到 {{ entry }} 文件`, { entry, interpolation: { escapeValue: false } }));
604
+ }
605
+ }
606
+ }
607
+
608
+ export function extractLpkSync(lpkPath, destPath, entries = []) {
609
+ if (!isFileExist(lpkPath)) {
610
+ throw t('lzc_cli.lib.utils.unzip_sync_not_exist_fail', `{{ zipPath }} 找不到该文件`, { zipPath: lpkPath, interpolation: { escapeValue: false } });
611
+ }
612
+
613
+ fs.mkdirSync(destPath, { recursive: true });
614
+ const format = detectLpkArchiveFormatSync(lpkPath);
615
+ if (format === 'zip') {
616
+ extractZipEntriesSync(lpkPath, destPath, entries);
617
+ return;
550
618
  }
619
+ if (format === 'tar') {
620
+ extractTarEntriesSync(lpkPath, destPath, entries);
621
+ return;
622
+ }
623
+ throw new Error(`Unsupported LPK archive format: ${lpkPath}`);
624
+ }
625
+
626
+ export function unzipSync(zipPath, destPath, entries = []) {
627
+ extractLpkSync(zipPath, destPath, entries);
551
628
  }
552
629
 
553
630
  export async function selectSshPublicKey(avaiableKeys) {
@@ -643,7 +720,7 @@ export function checkRsync() {
643
720
  }
644
721
 
645
722
  const check = spawn.sync('rsync', ['--version'], {
646
- shell: true,
723
+ shell: false,
647
724
  encoding: 'utf-8',
648
725
  stdio: ['pipe', 'pipe', 'pipe'],
649
726
  });
package/package.json CHANGED
@@ -1,91 +1,91 @@
1
1
  {
2
- "name": "@lazycatcloud/lzc-cli",
3
- "version": "2.0.0-pre.0",
4
- "description": "lazycat cloud developer kit",
5
- "scripts": {
6
- "release": "release-it patch",
7
- "prepublishOnly": "node check-changelog.js",
8
- "i18n:parser": "i18next-cli extract -c i18next.config.js --sync-all && prettier -w ./lib/i18n/locales"
9
- },
10
- "files": [
11
- "template",
12
- "scripts",
13
- "lib",
14
- "changelog.md"
15
- ],
16
- "engines": {
17
- "node": ">=18"
18
- },
19
- "bin": {
20
- "lzc-cli": "scripts/cli.js",
21
- "lzc-docker": "scripts/lzc-docker.js",
22
- "lzc-docker-compose": "scripts/lzc-docker-compose.js"
23
- },
24
- "type": "module",
25
- "keywords": [
26
- "lazycat cloud sdk"
27
- ],
28
- "author": "zac zeng",
29
- "license": "ISC",
30
- "dependencies": {
31
- "@balena/dockerignore": "^1.0.2",
32
- "@grpc/grpc-js": "^1.11.1",
33
- "@grpc/proto-loader": "^0.7.13",
34
- "@lazycatcloud/sdk": "^0.1.423",
35
- "adm-zip": "^0.5.16",
36
- "archiver": "^7.0.1",
37
- "axios": "^1.7.7",
38
- "chalk": "^5.3.0",
39
- "chokidar": "^3.6.0",
40
- "command-exists": "^1.2.9",
41
- "cross-spawn": "^7.0.3",
42
- "dockerfile-ast": "^0.6.1",
43
- "envsub": "^4.1.0",
44
- "fast-glob": "^3.3.2",
45
- "form-data": "^4.0.0",
46
- "i18next": "^25.7.1",
47
- "i18next-fs-backend": "^2.6.1",
48
- "ignore": "^5.3.2",
49
- "inquirer": "^10.1.8",
50
- "isbinaryfile": "^5.0.2",
51
- "js-yaml": "^4.1.0",
52
- "lodash": "^4.17.23",
53
- "lodash.debounce": "^4.0.8",
54
- "lodash.merge": "^4.6.2",
55
- "lodash.mergewith": "^4.6.2",
56
- "loglevel": "^1.9.1",
57
- "node-fetch": "^3.3.2",
58
- "semver": "^7.6.3",
59
- "tar": "^7.4.3",
60
- "yargs": "^17.7.2"
61
- },
62
- "devDependencies": {
63
- "@release-it/conventional-changelog": "^10.0.1",
64
- "@types/command-exists": "^1.2.3",
65
- "i18next-cli": "^1.32.0",
66
- "prettier": "^3.3.3",
67
- "release-it": "^19.0.4"
68
- },
69
- "release-it": {
70
- "git": {
71
- "requireCleanWorkingDir": false,
72
- "commitMessage": "chore: release v${version}",
73
- "commit": true,
74
- "tag": true,
75
- "push": false
76
- },
77
- "npm": {
78
- "publish": false
79
- },
80
- "plugins": {
81
- "@release-it/conventional-changelog": {
82
- "preset": "angular",
83
- "infile": "changelog.md"
84
- }
85
- }
86
- },
87
- "publishConfig": {
88
- "registry": "https://registry.npmjs.org",
89
- "access": "public"
90
- }
2
+ "name": "@lazycatcloud/lzc-cli",
3
+ "version": "2.0.0-pre.2",
4
+ "description": "lazycat cloud developer kit",
5
+ "scripts": {
6
+ "release": "release-it patch",
7
+ "prepublishOnly": "node check-changelog.js",
8
+ "i18n:parser": "i18next-cli extract -c i18next.config.js --sync-all && prettier -w ./lib/i18n/locales"
9
+ },
10
+ "files": [
11
+ "template",
12
+ "scripts",
13
+ "lib",
14
+ "changelog.md"
15
+ ],
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "bin": {
20
+ "lzc-cli": "scripts/cli.js",
21
+ "lzc-docker": "scripts/lzc-docker.js",
22
+ "lzc-docker-compose": "scripts/lzc-docker-compose.js"
23
+ },
24
+ "type": "module",
25
+ "keywords": [
26
+ "lazycat cloud sdk"
27
+ ],
28
+ "author": "zac zeng",
29
+ "license": "ISC",
30
+ "dependencies": {
31
+ "@balena/dockerignore": "^1.0.2",
32
+ "@grpc/grpc-js": "^1.11.1",
33
+ "@grpc/proto-loader": "^0.7.13",
34
+ "@lazycatcloud/sdk": "^0.1.423",
35
+ "adm-zip": "^0.5.16",
36
+ "archiver": "^7.0.1",
37
+ "chalk": "^5.3.0",
38
+ "chokidar": "^3.6.0",
39
+ "command-exists": "^1.2.9",
40
+ "cross-spawn": "^7.0.3",
41
+ "dockerfile-ast": "^0.6.1",
42
+ "envsub": "^4.1.0",
43
+ "fast-glob": "^3.3.2",
44
+ "form-data": "^4.0.0",
45
+ "i18next": "^25.7.1",
46
+ "i18next-fs-backend": "^2.6.1",
47
+ "ignore": "^5.3.2",
48
+ "inquirer": "^10.1.8",
49
+ "isbinaryfile": "^5.0.2",
50
+ "js-yaml": "^4.1.0",
51
+ "lodash": "^4.17.23",
52
+ "lodash.debounce": "^4.0.8",
53
+ "lodash.merge": "^4.6.2",
54
+ "lodash.mergewith": "^4.6.2",
55
+ "loglevel": "^1.9.1",
56
+ "node-fetch": "^3.3.2",
57
+ "semver": "^7.6.3",
58
+ "tar": "^7.4.3",
59
+ "yargs": "^17.7.2"
60
+ },
61
+ "devDependencies": {
62
+ "@release-it/conventional-changelog": "^10.0.1",
63
+ "@types/command-exists": "^1.2.3",
64
+ "i18next-cli": "^1.32.0",
65
+ "prettier": "^3.3.3",
66
+ "release-it": "^19.0.4"
67
+ },
68
+ "release-it": {
69
+ "git": {
70
+ "requireCleanWorkingDir": false,
71
+ "commitMessage": "chore: release v${version}",
72
+ "commit": true,
73
+ "tag": true,
74
+ "push": false
75
+ },
76
+ "npm": {
77
+ "publish": false
78
+ },
79
+ "plugins": {
80
+ "@release-it/conventional-changelog": {
81
+ "preset": "angular",
82
+ "infile": "changelog.md"
83
+ }
84
+ }
85
+ },
86
+ "publishConfig": {
87
+ "registry": "https://registry.npmjs.org",
88
+ "access": "public",
89
+ "tag": "lpkv2"
90
+ }
91
91
  }
package/scripts/cli.js CHANGED
@@ -15,6 +15,7 @@ import { lpkAppCommand, lpkProjectCommand } from '../lib/app/index.js';
15
15
  import { configCommand } from '../lib/config/index.js';
16
16
  import { lzcDockerCommand } from '../lib/docker/index.js';
17
17
  import { lpkCommand } from '../lib/lpk/index.js';
18
+ import { migrateCommand } from '../lib/migrate/index.js';
18
19
 
19
20
  function setLoggerLevel({ log }) {
20
21
  logger.setLevel(log, false);
@@ -66,6 +67,7 @@ lpkProjectCommand(program);
66
67
  appstoreCommand(program);
67
68
  lzcDockerCommand(program);
68
69
  lpkCommand(program);
70
+ migrateCommand(program);
69
71
 
70
72
  // 当没有参数的时候,默认显示帮助。
71
73
  (async () => {