@cloudbase/cli 2.9.4 → 2.9.6

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.
Binary file
@@ -79,6 +79,10 @@ const AccessType = {
79
79
  MINIAPP: 'MINIAPP',
80
80
  VPC: 'VPC'
81
81
  };
82
+ const ResourceTitle = {
83
+ container: '容器型云托管',
84
+ function: '函数型云托管'
85
+ };
82
86
  function getCloudrunService(envId) {
83
87
  return __awaiter(this, void 0, void 0, function* () {
84
88
  const region = yield (0, toolbox_1.getRegion)();
@@ -598,12 +602,17 @@ let CloudRunDeployCommand = class CloudRunDeployCommand extends common_1.Command
598
602
  }
599
603
  serviceName = yield _inputServiceName(defaultName);
600
604
  }
605
+ const containerConfigFile = 'container.config.json';
606
+ const containerConfigPath = path_1.default.join(targetDir, containerConfigFile);
607
+ if (yield fs_extra_1.default.pathExists(containerConfigPath)) {
608
+ log.warn(`CLI 中 ${containerConfigFile} 文件将不会生效,请通过命令行参数进行配置!`);
609
+ }
601
610
  if (!force) {
602
611
  const answers = yield inquirer_1.default.prompt([
603
612
  {
604
613
  type: 'confirm',
605
614
  name: 'confirm',
606
- message: `即将开始部署,是否确认继续?`,
615
+ message: '即将开始部署,是否确认继续?',
607
616
  default: true
608
617
  }
609
618
  ]);
@@ -643,29 +652,25 @@ let CloudRunDeployCommand = class CloudRunDeployCommand extends common_1.Command
643
652
  function _runDeploy() {
644
653
  return __awaiter(this, void 0, void 0, function* () {
645
654
  try {
646
- const res = serverType === 'function'
647
- ? yield iac_core_1.IAC.FunctionV2.apply({
648
- cwd: targetDir,
649
- envId: envId,
650
- name: serviceName
651
- }, function (message) {
652
- (0, utils_2.trackCallback)(message, log);
653
- })
654
- : yield iac_core_1.IAC.Cloudrun.apply({
655
- cwd: targetDir,
656
- envId: envId,
657
- name: serviceName,
658
- port: port ? Number(port) : undefined
659
- }, function (message) {
660
- (0, utils_2.trackCallback)(message, log);
661
- });
655
+ utils_2.trackCallback === null || utils_2.trackCallback === void 0 ? void 0 : (0, utils_2.trackCallback)({
656
+ details: `正在提交${ResourceTitle[serverType]} ${serviceName} 中,请稍候...`,
657
+ status: 'progress'
658
+ }, log);
659
+ yield cloudrunService.deploy({
660
+ serverName: serviceName,
661
+ targetPath: targetDir,
662
+ serverConfig: Object.assign({}, (port ? { Port: Number(port) } : {}))
663
+ });
664
+ utils_2.trackCallback === null || utils_2.trackCallback === void 0 ? void 0 : (0, utils_2.trackCallback)({
665
+ details: `提交${ResourceTitle[serverType]} ${serviceName} 已完成!`,
666
+ status: 'done'
667
+ }, log);
662
668
  yield (0, utils_2.upsertCloudbaserc)(targetDir, {
663
669
  envId,
664
670
  cloudrun: { name: serviceName }
665
671
  });
666
- const { envId: _envId, name, resourceType: _resourceType } = res === null || res === void 0 ? void 0 : res.data;
667
672
  (0, utils_2.trackCallback)({
668
- details: `请打开链接查看部署状态: https://tcb.cloud.tencent.com/dev?envId=${_envId}#/platform-run/service/detail?serverName=${name}&tabId=deploy&envId=${_envId}`
673
+ details: `请打开链接查看部署状态: https://tcb.cloud.tencent.com/dev?envId=${envId}#/platform-run/service/detail?serverName=${serviceName}&tabId=deploy&envId=${envId}`
669
674
  }, log);
670
675
  }
671
676
  catch (e) {
@@ -675,7 +680,7 @@ let CloudRunDeployCommand = class CloudRunDeployCommand extends common_1.Command
675
680
  {
676
681
  type: 'confirm',
677
682
  name: 'confirm',
678
- message: `平台当前有部署发布任务正在运行中。确认继续部署,正在执行的部署任务将被取消,并立即部署最新的代码`,
683
+ message: '平台当前有部署发布任务正在运行中。确认继续部署,正在执行的部署任务将被取消,并立即部署最新的代码',
679
684
  default: true
680
685
  }
681
686
  ])
@@ -743,11 +748,11 @@ let CloudRunRunCommand = class CloudRunRunCommand extends common_1.Command {
743
748
  options: [
744
749
  {
745
750
  flags: '--runMode <runMode>',
746
- desc: `运行模式,可选值: normal(普通函数) | agent(函数式 Agent),默认值: normal`
751
+ desc: '运行模式,可选值: normal(普通函数) | agent(函数式 Agent),默认值: normal'
747
752
  },
748
753
  {
749
754
  flags: '--agentId <agentId>',
750
- desc: `在 agent 模式下需要提供 Agent ID 进行调试`
755
+ desc: '在 agent 模式下需要提供 Agent ID 进行调试'
751
756
  },
752
757
  {
753
758
  flags: '-e, --envId <envId>',
@@ -793,7 +798,7 @@ let CloudRunRunCommand = class CloudRunRunCommand extends common_1.Command {
793
798
  },
794
799
  {
795
800
  flags: '--open-debug-panel <openDebugPanel>',
796
- desc: `是否打开调试面板,默认为 'true'`
801
+ desc: '是否打开调试面板,默认为 \'true\''
797
802
  }
798
803
  ],
799
804
  requiredEnvId: false,
@@ -828,7 +833,7 @@ let CloudRunRunCommand = class CloudRunRunCommand extends common_1.Command {
828
833
  {
829
834
  type: 'input',
830
835
  name: 'agentId',
831
- message: `请输入 Agent ID(如没有请填写任意值):`,
836
+ message: '请输入 Agent ID(如没有请填写任意值):',
832
837
  validate: (val) => {
833
838
  return val.trim() ? true : 'Agent ID 不能为空';
834
839
  }
@@ -895,7 +900,7 @@ let CloudRunRunCommand = class CloudRunRunCommand extends common_1.Command {
895
900
  logger.info(`[nodemon ${e.type}] ${e.message}`);
896
901
  })
897
902
  .on('crash', () => {
898
- logger.error(`Server crashed.`);
903
+ logger.error('Server crashed.');
899
904
  process.exit(1);
900
905
  })
901
906
  .on('exit', (e) => {
@@ -124,6 +124,19 @@ class TemplateManager {
124
124
  subpath: giteeMatch[4]
125
125
  };
126
126
  }
127
+ const cnbMatchWithDash = url.match(/https?:\/\/cnb\.cool\/(.+?)\/-\/tree\/([^\/]+)\/(.+)$/);
128
+ if (cnbMatchWithDash) {
129
+ const pathParts = cnbMatchWithDash[1].split('/').filter(p => p.length > 0);
130
+ if (pathParts.length >= 2) {
131
+ return {
132
+ platform: 'cnb',
133
+ owner: pathParts[0],
134
+ repo: pathParts.slice(1).join('/'),
135
+ branch: cnbMatchWithDash[2] || 'main',
136
+ subpath: cnbMatchWithDash[3]
137
+ };
138
+ }
139
+ }
127
140
  const cnbMatch = url.match(/https?:\/\/cnb\.cool\/(.+?)(?:\/tree\/([^\/]+)\/(.+))?$/);
128
141
  if (cnbMatch) {
129
142
  const pathParts = cnbMatch[1].split('/').filter(p => p.length > 0);
@@ -160,6 +173,38 @@ class TemplateManager {
160
173
  }
161
174
  throw new error_1.CloudBaseError(`不支持的 Git 平台: ${gitInfo.platform}`);
162
175
  }
176
+ cloneWithSubpathOptimized(gitUrl, tempDir, gitInfo, log) {
177
+ return __awaiter(this, void 0, void 0, function* () {
178
+ try {
179
+ yield this.git.clone(gitUrl, tempDir, [
180
+ '--depth', '1',
181
+ '--single-branch',
182
+ '--branch', gitInfo.branch,
183
+ '--filter=blob:none'
184
+ ]);
185
+ const subpathFull = path_1.default.join(tempDir, gitInfo.subpath);
186
+ if (!(yield fs_extra_1.default.pathExists(subpathFull))) {
187
+ throw new error_1.CloudBaseError(`子目录不存在: ${gitInfo.subpath}`);
188
+ }
189
+ const tempContentDir = path_1.default.join(tempDir, '.temp-content-' + Date.now());
190
+ yield fs_extra_1.default.move(subpathFull, tempContentDir);
191
+ const tempFiles = yield fs_extra_1.default.readdir(tempDir);
192
+ for (const file of tempFiles) {
193
+ if (file !== path_1.default.basename(tempContentDir)) {
194
+ yield fs_extra_1.default.remove(path_1.default.join(tempDir, file));
195
+ }
196
+ }
197
+ const contentFiles = yield fs_extra_1.default.readdir(tempContentDir);
198
+ for (const file of contentFiles) {
199
+ yield fs_extra_1.default.move(path_1.default.join(tempContentDir, file), path_1.default.join(tempDir, file));
200
+ }
201
+ yield fs_extra_1.default.remove(tempContentDir);
202
+ }
203
+ catch (error) {
204
+ throw new error_1.CloudBaseError(`克隆子目录失败: ${error.message}`, { original: error });
205
+ }
206
+ });
207
+ }
163
208
  cloneWithSubpath(gitUrl, tempDir, gitInfo, log) {
164
209
  return __awaiter(this, void 0, void 0, function* () {
165
210
  try {
@@ -212,10 +257,10 @@ class TemplateManager {
212
257
  log.info(`📦 正在从 ${gitInfo.platform} 下载模板到临时目录...`);
213
258
  try {
214
259
  if (gitInfo.subpath) {
215
- yield this.cloneWithSubpath(gitUrl, tempDir, gitInfo, log);
260
+ yield this.cloneWithSubpathOptimized(gitUrl, tempDir, gitInfo, log);
216
261
  }
217
262
  else {
218
- yield this.git.clone(gitUrl, tempDir);
263
+ yield this.git.clone(gitUrl, tempDir, ['--depth', '1', '--single-branch', '--branch', gitInfo.branch]);
219
264
  }
220
265
  log.info(`✅ Git 模板下载完成到临时目录`);
221
266
  }
@@ -271,10 +316,14 @@ class TemplateManager {
271
316
  if (stat.isDirectory()) {
272
317
  yield fs_extra_1.default.ensureDir(destPath);
273
318
  const entries = yield fs_extra_1.default.readdir(srcPath, { withFileTypes: true });
274
- for (const entry of entries) {
319
+ const copyPromises = entries.map(entry => {
275
320
  const entrySrcPath = path_1.default.join(srcPath, entry.name);
276
321
  const entryDestPath = path_1.default.join(destPath, entry.name);
277
- yield copyFile(entrySrcPath, entryDestPath);
322
+ return copyFile(entrySrcPath, entryDestPath);
323
+ });
324
+ const chunks = this.chunkArray(copyPromises, 10);
325
+ for (const chunk of chunks) {
326
+ yield Promise.all(chunk);
278
327
  }
279
328
  }
280
329
  else {
@@ -295,10 +344,14 @@ class TemplateManager {
295
344
  }
296
345
  });
297
346
  const entries = yield fs_extra_1.default.readdir(sourceDir, { withFileTypes: true });
298
- for (const entry of entries) {
347
+ const copyPromises = entries.map(entry => {
299
348
  const srcPath = path_1.default.join(sourceDir, entry.name);
300
349
  const destPath = path_1.default.join(targetDir, entry.name);
301
- yield copyFile(srcPath, destPath);
350
+ return copyFile(srcPath, destPath);
351
+ });
352
+ const chunks = this.chunkArray(copyPromises, 5);
353
+ for (const chunk of chunks) {
354
+ yield Promise.all(chunk);
302
355
  }
303
356
  log.info(`📊 复制统计: ${copiedCount} 个新文件复制, ${overwrittenCount} 个文件覆盖`);
304
357
  });
@@ -313,10 +366,14 @@ class TemplateManager {
313
366
  if (stat.isDirectory()) {
314
367
  yield fs_extra_1.default.ensureDir(destPath);
315
368
  const entries = yield fs_extra_1.default.readdir(srcPath, { withFileTypes: true });
316
- for (const entry of entries) {
369
+ const copyPromises = entries.map(entry => {
317
370
  const entrySrcPath = path_1.default.join(srcPath, entry.name);
318
371
  const entryDestPath = path_1.default.join(destPath, entry.name);
319
- yield copyFile(entrySrcPath, entryDestPath);
372
+ return copyFile(entrySrcPath, entryDestPath);
373
+ });
374
+ const chunks = this.chunkArray(copyPromises, 10);
375
+ for (const chunk of chunks) {
376
+ yield Promise.all(chunk);
320
377
  }
321
378
  }
322
379
  else {
@@ -337,14 +394,25 @@ class TemplateManager {
337
394
  }
338
395
  });
339
396
  const entries = yield fs_extra_1.default.readdir(sourceDir, { withFileTypes: true });
340
- for (const entry of entries) {
397
+ const copyPromises = entries.map(entry => {
341
398
  const srcPath = path_1.default.join(sourceDir, entry.name);
342
399
  const destPath = path_1.default.join(targetDir, entry.name);
343
- yield copyFile(srcPath, destPath);
400
+ return copyFile(srcPath, destPath);
401
+ });
402
+ const chunks = this.chunkArray(copyPromises, 5);
403
+ for (const chunk of chunks) {
404
+ yield Promise.all(chunk);
344
405
  }
345
406
  log.info(`📊 复制统计: ${copiedCount} 个文件复制完成, ${skippedCount} 个文件跳过`);
346
407
  });
347
408
  }
409
+ chunkArray(array, chunkSize) {
410
+ const chunks = [];
411
+ for (let i = 0; i < array.length; i += chunkSize) {
412
+ chunks.push(array.slice(i, i + chunkSize));
413
+ }
414
+ return chunks;
415
+ }
348
416
  getBuiltinTemplates() {
349
417
  const templates = {};
350
418
  for (const [key, template] of Object.entries(BUILTIN_TEMPLATES)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/cli",
3
- "version": "2.9.4",
3
+ "version": "2.9.6",
4
4
  "description": "cli tool for cloudbase",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -53,7 +53,7 @@
53
53
  "@cloudbase/functions-framework": "1.16.0",
54
54
  "@cloudbase/iac-core": "0.0.3-alpha.11",
55
55
  "@cloudbase/lowcode-cli": "^0.22.2",
56
- "@cloudbase/manager-node": "4.6.1",
56
+ "@cloudbase/manager-node": "4.6.3",
57
57
  "@cloudbase/toolbox": "^0.7.9",
58
58
  "@dotenvx/dotenvx": "^1.48.3",
59
59
  "@musistudio/claude-code-router": "1.0.36",
@@ -12,12 +12,14 @@ export declare class TemplateManager {
12
12
  private isGitUrl;
13
13
  private parseGitUrl;
14
14
  private buildGitUrl;
15
+ private cloneWithSubpathOptimized;
15
16
  private cloneWithSubpath;
16
17
  private downloadBuiltinTemplateToTemp;
17
18
  private downloadGitTemplateToTemp;
18
19
  private copyFromTempToTarget;
19
20
  private copyFilesWithOverwrite;
20
21
  private copyFilesSkipExisting;
22
+ private chunkArray;
21
23
  getBuiltinTemplates(): Record<string, string>;
22
24
  }
23
25
  export {};