@lazycatcloud/lzc-cli 2.0.0-pre.3 → 2.0.0-pre.5

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/changelog.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.0.0-pre.5](https://gitee.com/linakesi/lzc-cli/compare/v2.0.0-pre.4...v2.0.0-pre.5) (2026-03-19)
4
+
5
+ ### Features
6
+
7
+ - remove dozzle and use LPK v2
8
+ - read debug bridge version from package metadata
9
+
10
+ ### Bug Fixes
11
+
12
+ - keep `.lzcdevignore` semantics consistent during `project sync --watch`
13
+
14
+ ## [2.0.0-pre.4](https://gitee.com/linakesi/lzc-cli/compare/v2.0.0-pre.3...v2.0.0-pre.4) (2026-03-14)
15
+
16
+ ### Features
17
+
18
+ - support build package metadata overrides
19
+
3
20
  ## [2.0.0-pre.3](https://gitee.com/linakesi/lzc-cli/compare/v2.0.0-pre.2...v2.0.0-pre.3) (2026-03-12)
4
21
 
5
22
  ### Features
@@ -303,16 +303,39 @@ function mergeBuildOptions(baseOptions, topOptions) {
303
303
  };
304
304
  }
305
305
 
306
- function applyPkgIdSuffix(packageId, suffix) {
307
- const normalizedPackageId = String(packageId ?? '').trim();
308
- const normalizedSuffix = String(suffix ?? '').trim();
309
- if (!normalizedSuffix) {
310
- return normalizedPackageId;
306
+ function normalizePackageMetadataOverride(options, fieldName) {
307
+ if (!Object.prototype.hasOwnProperty.call(options ?? {}, fieldName)) {
308
+ return '';
311
309
  }
312
- if (!normalizedPackageId) {
313
- throw new Error('package is empty, cannot apply pkg_id_suffix');
310
+ const normalizedValue = String(options[fieldName] ?? '').trim();
311
+ if (!normalizedValue) {
312
+ throw new Error(`${fieldName} cannot be empty when specified`);
314
313
  }
315
- return `${normalizedPackageId}.${normalizedSuffix}`;
314
+ return normalizedValue;
315
+ }
316
+
317
+ function applyPackageMetadataOverrides(manifest, packageInfo, options) {
318
+ const pkgId = normalizePackageMetadataOverride(options, 'pkg_id');
319
+ const pkgName = normalizePackageMetadataOverride(options, 'pkg_name');
320
+ const hasPackageMetadataOverrides = !!pkgId || !!pkgName;
321
+ let nextManifest = { ...(manifest ?? {}) };
322
+ let nextPackageInfo = packageInfo;
323
+
324
+ if (pkgId) {
325
+ nextManifest = { ...nextManifest, package: pkgId };
326
+ nextPackageInfo = { ...(nextPackageInfo ?? {}), package: pkgId };
327
+ }
328
+
329
+ if (pkgName) {
330
+ nextManifest = { ...nextManifest, name: pkgName };
331
+ nextPackageInfo = { ...(nextPackageInfo ?? {}), name: pkgName };
332
+ }
333
+
334
+ return {
335
+ manifest: nextManifest,
336
+ packageInfo: nextPackageInfo,
337
+ hasPackageMetadataOverrides,
338
+ };
316
339
  }
317
340
 
318
341
  export function validatePackageFileForArchiveFormat(hasPackageFile, archiveFormat) {
@@ -328,8 +351,8 @@ function hasBuildEnvEntries(envEntries) {
328
351
  return Array.isArray(envEntries) && envEntries.length > 0;
329
352
  }
330
353
 
331
- export function shouldUseV2PackageLayout({ forceV2 = false, hasPackageFile = false, hasImagesConfig = false, buildEnvEntries = [] } = {}) {
332
- return !!forceV2 || !!hasPackageFile || !!hasImagesConfig || hasBuildEnvEntries(buildEnvEntries);
354
+ export function shouldUseV2PackageLayout({ forceV2 = false, hasPackageFile = false, hasImagesConfig = false, buildEnvEntries = [], hasPackageMetadataOverrides = false } = {}) {
355
+ return !!forceV2 || !!hasPackageFile || !!hasImagesConfig || hasBuildEnvEntries(buildEnvEntries) || !!hasPackageMetadataOverrides;
333
356
  }
334
357
 
335
358
  function logDeprecatedStaticFieldWarning(manifestPath, fields) {
@@ -347,6 +370,16 @@ function normalizeBuildOptions(options) {
347
370
  return normalized;
348
371
  }
349
372
 
373
+ function normalizeContentDir(contentdir) {
374
+ if (contentdir === undefined || contentdir === null) {
375
+ return '';
376
+ }
377
+ if (typeof contentdir === 'string') {
378
+ return contentdir.trim();
379
+ }
380
+ return contentdir;
381
+ }
382
+
350
383
  function loadYamlIfExists(filePath) {
351
384
  if (!filePath || !isFileExist(filePath)) {
352
385
  return {};
@@ -396,6 +429,7 @@ export class LpkBuild {
396
429
  this.sourceManifest = null;
397
430
  this.packageInfo = null;
398
431
  this.hasPackageFile = false;
432
+ this.hasPackageMetadataOverrides = false;
399
433
  this.buildVars = null;
400
434
  this.preprocessedManifestText = '';
401
435
 
@@ -424,6 +458,7 @@ export class LpkBuild {
424
458
  this.sourceManifest = null;
425
459
  this.packageInfo = null;
426
460
  this.hasPackageFile = false;
461
+ this.hasPackageMetadataOverrides = false;
427
462
  this.buildVars = buildVarsFromEnvEntries(this.options['envs']);
428
463
  this.preprocessedManifestText = '';
429
464
  return this;
@@ -476,15 +511,10 @@ export class LpkBuild {
476
511
  this.sourceManifest = loaded.sourceManifest;
477
512
  this.packageInfo = loaded.packageInfo;
478
513
  this.hasPackageFile = loaded.hasPackageFile;
479
- this.manifest = loaded.manifest;
480
-
481
- const packageWithSuffix = applyPkgIdSuffix(this.manifest['package'], this.options['pkg_id_suffix']);
482
- if (packageWithSuffix !== this.manifest['package']) {
483
- this.manifest = { ...this.manifest, package: packageWithSuffix };
484
- if (this.hasPackageFile) {
485
- this.packageInfo = { ...(this.packageInfo ?? {}), package: packageWithSuffix };
486
- }
487
- }
514
+ const packageMetadata = applyPackageMetadataOverrides(loaded.manifest, loaded.packageInfo, this.options);
515
+ this.manifest = packageMetadata.manifest;
516
+ this.packageInfo = packageMetadata.packageInfo;
517
+ this.hasPackageMetadataOverrides = packageMetadata.hasPackageMetadataOverrides;
488
518
 
489
519
  if (!isValidPackageName(this.manifest['package'])) {
490
520
  throw t('lzc_cli.lib.app.lpk_build.get_manifest_package_name_fail', `{{ package }} 含有非法字符,请使用正确的包名格式(java的包名格式),如:cloud.lazycat.apps.video`, {
@@ -538,7 +568,7 @@ export class LpkBuild {
538
568
  }
539
569
 
540
570
  const tempDir = fs.mkdtempSync('.lzc-cli-build');
541
- let contentdir = this.options['contentdir'];
571
+ let contentdir = normalizeContentDir(this.options['contentdir']);
542
572
  let browserExtension = this.options['browser-extension'];
543
573
  let aiPodService = this.options['ai-pod-service'];
544
574
  try {
@@ -649,6 +679,7 @@ export class LpkBuild {
649
679
  hasPackageFile: this.hasPackageFile,
650
680
  hasImagesConfig,
651
681
  buildEnvEntries: this.options['envs'],
682
+ hasPackageMetadataOverrides: this.hasPackageMetadataOverrides,
652
683
  });
653
684
  if (useV2PackageLayout) {
654
685
  logDeprecatedStaticFieldWarning(this.manifestFilePath, findManifestStaticFields(this.sourceManifest));
@@ -212,17 +212,18 @@ export class TemplateInit {
212
212
  this.type = normalizeTemplateType(type);
213
213
  this.lpkManifest = new LpkManifest(name);
214
214
  this.lpkPackageFile = new LpkPackageFile(name);
215
+ this.templateVars = null;
215
216
  }
216
217
 
217
218
  async init() {
218
219
  this.type = await chooseTemplate(this.type);
219
220
 
220
- const templateRoot = path.join(contextDirname(import.meta.url), '..', '..', 'template', '_lpk');
221
- const typeTemplatePath = path.join(templateRoot, `${this.type}.manifest.yml.in`);
222
- const manifestTemplatePath = isFileExist(typeTemplatePath) ? typeTemplatePath : path.join(templateRoot, 'manifest.yml.in');
223
- const packageTemplatePath = path.join(templateRoot, 'package.yml.in');
224
- const templateVars = await this.lpkManifest.init(manifestTemplatePath, true);
225
- await this.lpkPackageFile.init(packageTemplatePath, true, templateVars);
221
+ const templateRoot = path.join(contextDirname(import.meta.url), '..', '..', 'template', '_lpk');
222
+ const typeTemplatePath = path.join(templateRoot, `${this.type}.manifest.yml.in`);
223
+ const manifestTemplatePath = isFileExist(typeTemplatePath) ? typeTemplatePath : path.join(templateRoot, 'manifest.yml.in');
224
+ const packageTemplatePath = path.join(templateRoot, 'package.yml.in');
225
+ this.templateVars = await this.lpkManifest.init(manifestTemplatePath, true);
226
+ await this.lpkPackageFile.init(packageTemplatePath, true, this.templateVars);
226
227
  }
227
228
 
228
229
  async create() {
@@ -286,7 +287,7 @@ class LpkCreate {
286
287
  ),
287
288
  );
288
289
  }
289
- await TemplateConfig[type].build(path.resolve(this.cwd, this.name));
290
+ await TemplateConfig[type].build(path.resolve(this.cwd, this.name), { templateVars: template.templateVars });
290
291
 
291
292
  console.log(chalk.green(t('lzc_cli.lib.app.lpk_create.exec_init_project_success_tips', `✨ 初始化懒猫云应用`)));
292
293
  await TemplateConfig[type].after(this.name, this.cwd);
@@ -8,8 +8,23 @@ import logger from 'loglevel';
8
8
  import { t } from '../i18n/index.js';
9
9
 
10
10
  const __dirname = contextDirname(import.meta.url);
11
+ const PROJECT_CREATE_PACKAGE_DEV_PLACEHOLDER = '__PROJECT_CREATE_PACKAGE_DEV__';
11
12
 
12
- async function loadFiles(dirPath, prefix = '') {
13
+ function renderProjectCreateFileContent(filePath, content, opts = {}) {
14
+ if (typeof content !== 'string' || path.basename(filePath) !== 'lzc-build.dev.yml') {
15
+ return content;
16
+ }
17
+ if (!content.includes(PROJECT_CREATE_PACKAGE_DEV_PLACEHOLDER)) {
18
+ return content;
19
+ }
20
+ const packageId = String(opts.templateVars?.package ?? '').trim();
21
+ if (!packageId) {
22
+ throw new Error(`templateVars.package is required for ${filePath}`);
23
+ }
24
+ return content.replaceAll(PROJECT_CREATE_PACKAGE_DEV_PLACEHOLDER, `${packageId}.dev`);
25
+ }
26
+
27
+ async function loadFiles(dirPath, prefix = '', opts = {}) {
13
28
  const templateRoot = path.join(__dirname, '..', '..', 'template');
14
29
  const templateDir = path.join(templateRoot, dirPath);
15
30
 
@@ -26,15 +41,16 @@ async function loadFiles(dirPath, prefix = '') {
26
41
  } else {
27
42
  content = fs.readFileSync(sourcePath, 'utf8');
28
43
  }
29
- if (p.startsWith('_')) {
30
- p = p.replace('_', '.');
31
- }
44
+ if (p.startsWith('_')) {
45
+ p = p.replace('_', '.');
46
+ }
32
47
 
33
- files[path.join(prefix, p)] = {
34
- content,
35
- mode,
36
- };
37
- }
48
+ const outputPath = path.join(prefix, p);
49
+ files[outputPath] = {
50
+ content: renderProjectCreateFileContent(outputPath, content, opts),
51
+ mode,
52
+ };
53
+ }
38
54
  return files;
39
55
  }
40
56
 
@@ -50,7 +66,7 @@ function writeFileTree(target, files) {
50
66
  }
51
67
 
52
68
  export async function generate(type, to, opts = {}) {
53
- const files = await loadFiles(type, opts.prefix);
69
+ const files = await loadFiles(type, opts.prefix, opts);
54
70
  writeFileTree(to, files);
55
71
  }
56
72
 
@@ -64,7 +64,7 @@ function createIgnoreMatcher(rootDir) {
64
64
  return ig;
65
65
  }
66
66
 
67
- function createWatchIgnored(rootDir) {
67
+ export function createWatchIgnored(rootDir) {
68
68
  const ig = createIgnoreMatcher(rootDir);
69
69
  return (candidatePath) => {
70
70
  const relPath = normalizePosixPath(path.relative(rootDir, candidatePath));
@@ -162,9 +162,6 @@ export function buildRsyncArgs(runtime, uid, host, rootDir, targetDir, sourceDir
162
162
  const ignoreFile = path.join(rootDir, LZCDEVIGNORE_FILE);
163
163
  if (fs.existsSync(ignoreFile)) {
164
164
  args.push(`--exclude-from=${ignoreFile}`);
165
- if (deleteMode) {
166
- args.push('--delete-excluded');
167
- }
168
165
  }
169
166
  if (sourceDir) {
170
167
  args.push('--relative');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazycatcloud/lzc-cli",
3
- "version": "2.0.0-pre.3",
3
+ "version": "2.0.0-pre.5",
4
4
  "description": "lazycat cloud developer kit",
5
5
  "scripts": {
6
6
  "release": "release-it patch",
@@ -1,4 +1,7 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: cloud.lazycat.app.helloworld.dev
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
@@ -1,7 +1,10 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
5
8
 
6
9
  envs:
7
10
  - DEV_MODE=1
@@ -1,4 +1,7 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
@@ -1,7 +1,10 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
5
8
 
6
9
  envs:
7
10
  - DEV_MODE=1
@@ -1,7 +1,10 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
5
8
 
6
9
  envs:
7
10
  - DEV_MODE=1
@@ -1,7 +1,10 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
5
8
 
6
9
  envs:
7
10
  - DEV_MODE=1
@@ -1,7 +1,10 @@
1
1
  # 开发态覆盖配置
2
2
 
3
- # pkg_id_suffix: append an extra package id segment for dev deploys
4
- pkg_id_suffix: dev
3
+ # 覆盖开发态包名,避免覆盖 release 安装包
4
+ pkg_id: __PROJECT_CREATE_PACKAGE_DEV__
5
+
6
+ # 覆盖 release 配置中的 contentdir;留空表示开发态不打包内容目录
7
+ contentdir:
5
8
 
6
9
  envs:
7
10
  - DEV_MODE=1