@cloudbase/cli 2.12.3-beta.4 → 2.12.4-beta.0

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 (2) hide show
  1. package/dist/standalone/cli.js +1510 -186
  2. package/package.json +1 -1
@@ -326169,7 +326169,7 @@ module.exports = function generate_pattern(it, $keyword, $ruleType) {
326169
326169
  /***/ ((module) => {
326170
326170
 
326171
326171
  "use strict";
326172
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"2.12.3-beta.4","description":"cli tool for cloudbase","main":"lib/index.js","scripts":{"build":"rimraf lib types && tsc --resolveJsonModule && cpx \\"src/**/*.html\\" lib","watch":"rimraf lib types && tsc -w","dev":"rimraf lib types && cpx \\"src/**/*.html\\" lib && tsc -w","eslint":"eslint \\"./**/*.ts\\"","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --forceExit --detectOpenHandles --coverage --verbose --testTimeout=10000","tsc":"tsc","pkg":"pkg ./bin/cloudbase.js --out-path ./pkg","postinstall":"node ./post-install.js || exit 0 && patch-package","prepublishOnly":"node ./scripts/check-publish-source.js","debug":"bin/tcb.js lowcode watch","build:bundle":"webpack --config build/webpack/cli.cjs && webpack --config build/webpack/ccr.cjs && node build/scripts/copy-figlet-fonts.js","package:darwin-arm64":"OS=darwin ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:darwin-x64":"OS=darwin ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-arm64":"OS=linux ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-x64":"OS=linux ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:all":"bash build/scripts/build-all.sh","node:fetch:one":"node -e \\"require(\'child_process\').execSync(\'bash build/scripts/fetch-node.sh\',{stdio:\'inherit\'})\\"","node:fetch:all":"NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh --all","node:fetch:win-x64":"OS=windows ARCH=x64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","node:fetch:win-arm64":"OS=windows ARCH=arm64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","package:windows-x64":"OS=windows ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-arm64":"OS=windows ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-all":"npm run -s node:fetch:win-x64 && npm run -s node:fetch:win-arm64 && npm run -s package:windows-x64 && npm run -s package:windows-arm64","package:npm":"npm run build && npm run build:bundle && bash build/scripts/prepare-publish.sh","out:prune":"bash build/scripts/prune-out.sh","i18n:scan":"i18next-scanner --config locales/i18next-scanner.config.js && node locales/scripts/generate.js","i18n:sync":"node locales/scripts/sync.js sync","publish":"node ./scripts/publish.js"},"repository":{"type":"git","url":"https://github.com/TencentCloudBase/cloud-base-cli.git"},"bin":{"cloudbase":"bin/cloudbase.js","cloudbase-mcp":"bin/cloudbase-mcp.cjs","tcb":"bin/tcb.js"},"husky":{"hooks":{"pre-commit":"npm run build"}},"author":"cwuyiqing@gmail.com","license":"ISC","dependencies":{"@cloudbase/cloud-api":"^0.5.5","@cloudbase/cloudbase-mcp":"^2.7.3","@cloudbase/framework-core":"^1.9.7","@cloudbase/functions-framework":"1.16.0","@cloudbase/iac-core":"0.0.3-alpha.14","@cloudbase/lowcode-cli":"^0.23.0","@cloudbase/manager-node":"4.7.4","@cloudbase/toolbox":"^0.7.16-beta.2","@dotenvx/dotenvx":"^1.48.3","@musistudio/claude-code-router":"1.0.36","address":"^1.1.2","camelcase-keys":"^7.0.2","chalk":"^2.4.2","cli-table3":"^0.5.1","commander":"7","del":"^5.1.0","didyoumean":"^1.2.2","enquirer":"^2.3.6","execa":"^4.0.3","figlet":"^1.7.0","fs-extra":"^8.1.0","gradient-string":"^2.0.2","https-proxy-agent":"^5.0.1","i":"^0.3.7","inquirer":"^6.5.0","json-schema-to-typescript":"^14.0.5","lodash":"^4.17.21","log-symbols":"^3.0.0","lowdb":"^1.0.0","make-dir":"^3.0.0","node-fetch":"^2.6.0","nodemon":"^3.1.4","npm":"^11.5.2","open":"^7.0.0","ora":"^4.0.2","os-locale":"5.0.0","patch-package":"^8.0.0","portfinder":"^1.0.28","progress":"^2.0.3","query-string":"^6.8.1","reflect-metadata":"^0.1.13","semver":"^7.3.7","simple-git":"^3.28.0","tar-fs":"^2.0.1","terminal-link":"^2.1.1","toml":"^3.0.0","unzipper":"^0.10.10","update-notifier":"^4.0.0","xdg-basedir":"^4.0.0","yargs":"^16.2.0","yargs-parser":"^21.0.1","zod":"^4.0.13"},"devDependencies":{"@babel/parser":"^7.28.4","@babel/traverse":"^7.28.4","@babel/types":"^7.28.4","@types/fs-extra":"^11.0.4","@types/jest":"^27","@types/koa__router":"^8.0.11","@types/lodash":"^4.14.182","@types/node":"^12.12.38","@types/node-fetch":"^2.5.4","@types/react":"^17.0.37","@types/semver":"^7.3.9","@types/unzipper":"^0.10.11","@types/webpack-dev-server":"^3.11.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","cpx":"^1.5.0","eslint":"^7.14.0","eslint-config-alloy":"^3.8.2","husky":"^3.0.9","i18next-scanner":"^4.6.0","jest":"^27","rimraf":"^3.0.2","ts-jest":"^27","typescript":"^4.7.2","webpack":"^5.92.0","webpack-cli":"^5.1.4"},"packageManager":"yarn@3.6.2+sha512.2c2f8b9615e6659773f65cdec7cf92ef773a98a99e611579601f61c7a91ec94c89c929aac86f1cee819421a9b0db7acfd53ec3ebb95af44f77f77634b08b9557"}');
326172
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"2.12.4-beta.0","description":"cli tool for cloudbase","main":"lib/index.js","scripts":{"build":"rimraf lib types && tsc --resolveJsonModule && cpx \\"src/**/*.html\\" lib","watch":"rimraf lib types && tsc -w","dev":"rimraf lib types && cpx \\"src/**/*.html\\" lib && tsc -w","eslint":"eslint \\"./**/*.ts\\"","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --forceExit --detectOpenHandles --coverage --verbose --testTimeout=10000","tsc":"tsc","pkg":"pkg ./bin/cloudbase.js --out-path ./pkg","postinstall":"node ./post-install.js || exit 0 && patch-package","prepublishOnly":"node ./scripts/check-publish-source.js","debug":"bin/tcb.js lowcode watch","build:bundle":"webpack --config build/webpack/cli.cjs && webpack --config build/webpack/ccr.cjs && node build/scripts/copy-figlet-fonts.js","package:darwin-arm64":"OS=darwin ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:darwin-x64":"OS=darwin ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-arm64":"OS=linux ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:linux-x64":"OS=linux ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:all":"bash build/scripts/build-all.sh","node:fetch:one":"node -e \\"require(\'child_process\').execSync(\'bash build/scripts/fetch-node.sh\',{stdio:\'inherit\'})\\"","node:fetch:all":"NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh --all","node:fetch:win-x64":"OS=windows ARCH=x64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","node:fetch:win-arm64":"OS=windows ARCH=arm64 NODE_VERSION=22.18.0 bash build/scripts/fetch-node.sh","package:windows-x64":"OS=windows ARCH=x64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-arm64":"OS=windows ARCH=arm64 VERSION= node -e \\"require(\'child_process\').execSync(\'bash build/scripts/package.sh\',{stdio:\'inherit\'})\\"","package:windows-all":"npm run -s node:fetch:win-x64 && npm run -s node:fetch:win-arm64 && npm run -s package:windows-x64 && npm run -s package:windows-arm64","package:npm":"npm run build && npm run build:bundle && bash build/scripts/prepare-publish.sh","out:prune":"bash build/scripts/prune-out.sh","i18n:scan":"i18next-scanner --config locales/i18next-scanner.config.js && node locales/scripts/generate.js","i18n:sync":"node locales/scripts/sync.js sync","publish":"node ./scripts/publish.js"},"repository":{"type":"git","url":"https://github.com/TencentCloudBase/cloud-base-cli.git"},"bin":{"cloudbase":"bin/cloudbase.js","cloudbase-mcp":"bin/cloudbase-mcp.cjs","tcb":"bin/tcb.js"},"husky":{"hooks":{"pre-commit":"npm run build"}},"author":"cwuyiqing@gmail.com","license":"ISC","dependencies":{"@cloudbase/cloud-api":"^0.5.5","@cloudbase/cloudbase-mcp":"^2.7.3","@cloudbase/framework-core":"^1.9.7","@cloudbase/functions-framework":"1.16.0","@cloudbase/iac-core":"0.0.3-alpha.14","@cloudbase/lowcode-cli":"^0.23.0","@cloudbase/manager-node":"4.7.4","@cloudbase/toolbox":"0.7.16","@dotenvx/dotenvx":"^1.48.3","@musistudio/claude-code-router":"1.0.36","address":"^1.1.2","camelcase-keys":"^7.0.2","chalk":"^2.4.2","cli-table3":"^0.5.1","commander":"7","del":"^5.1.0","didyoumean":"^1.2.2","enquirer":"^2.3.6","execa":"^4.0.3","figlet":"^1.7.0","fs-extra":"^8.1.0","gradient-string":"^2.0.2","https-proxy-agent":"^5.0.1","i":"^0.3.7","inquirer":"^6.5.0","json-schema-to-typescript":"^14.0.5","lodash":"^4.17.21","log-symbols":"^3.0.0","lowdb":"^1.0.0","make-dir":"^3.0.0","node-fetch":"^2.6.0","nodemon":"^3.1.4","npm":"^11.5.2","open":"^7.0.0","ora":"^4.0.2","os-locale":"5.0.0","patch-package":"^8.0.0","portfinder":"^1.0.28","progress":"^2.0.3","query-string":"^6.8.1","reflect-metadata":"^0.1.13","semver":"^7.3.7","simple-git":"^3.28.0","tar-fs":"^2.0.1","terminal-link":"^2.1.1","toml":"^3.0.0","unzipper":"^0.10.10","update-notifier":"^4.0.0","xdg-basedir":"^4.0.0","yargs":"^16.2.0","yargs-parser":"^21.0.1","zod":"^4.0.13"},"devDependencies":{"@babel/parser":"^7.28.4","@babel/traverse":"^7.28.4","@babel/types":"^7.28.4","@types/fs-extra":"^11.0.4","@types/jest":"^27","@types/koa__router":"^8.0.11","@types/lodash":"^4.14.182","@types/node":"^12.12.38","@types/node-fetch":"^2.5.4","@types/react":"^17.0.37","@types/semver":"^7.3.9","@types/unzipper":"^0.10.11","@types/webpack-dev-server":"^3.11.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","cpx":"^1.5.0","eslint":"^7.14.0","eslint-config-alloy":"^3.8.2","husky":"^3.0.9","i18next-scanner":"^4.6.0","jest":"^27","rimraf":"^3.0.2","ts-jest":"^27","typescript":"^4.7.2","webpack":"^5.92.0","webpack-cli":"^5.1.4"},"packageManager":"yarn@3.6.2+sha512.2c2f8b9615e6659773f65cdec7cf92ef773a98a99e611579601f61c7a91ec94c89c929aac86f1cee819421a9b0db7acfd53ec3ebb95af44f77f77634b08b9557","ai":{"skills":"./skills","skillsIndex":"./skills/index.json","compatible":["codebuddy","cursor","copilot","claude","windsurf"],"description":"CloudBase CLI - 腾讯云云开发命令行工具,支持云函数、云数据库、静态托管等全栈云开发能力"}}');
326173
326173
 
326174
326174
  /***/ }),
326175
326175
 
@@ -410366,8 +410366,6 @@ function openUrl(url) {
410366
410366
  const child = yield (0, open_1.default)(url, { url: true });
410367
410367
  if (child === null || child === void 0 ? void 0 : child.once) {
410368
410368
  child.once('error', (error) => __awaiter(this, void 0, void 0, function* () {
410369
- const code = (error === null || error === void 0 ? void 0 : error.code) || 'UNKNOWN';
410370
- console.warn(`自动打开浏览器失败(${code})。`);
410371
410369
  if (shouldUseBrowserEnvFallback()) {
410372
410370
  yield openUrlByBrowserEnv(url);
410373
410371
  }
@@ -410394,8 +410392,8 @@ function getDataFromWeb(getUrl, type, options = {}) {
410394
410392
  throw new error_1.CloudBaseError('callbackTimeout must be a positive number');
410395
410393
  }
410396
410394
  const url = getUrl(port);
410397
- console.log('\n\n若链接未自动打开,请手动复制此链接至浏览器,或尝试使用其他登录方式:');
410398
- console.log(`\n${url}`);
410395
+ console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
410396
+ console.log(`\n${url}\n`);
410399
410397
  if (!noBrowser) {
410400
410398
  // 对 url 转码, 避免 wsl 无法正常打开地址
410401
410399
  // https://www.npmjs.com/package/open#url
@@ -459817,7 +459815,7 @@ let FunctionDetail = class FunctionDetail extends common_1.Command {
459817
459815
  this.logDetail(data, name);
459818
459816
  }
459819
459817
  catch (e) {
459820
- if (e.code === 'ResourceNotFound.FunctionName') {
459818
+ if (e.code === 'ResourceNotFound.FunctionName' || e.code === 'ResourceNotFound.Function') {
459821
459819
  throw new error_1.CloudBaseError((0, i18n_1.t)('[{{name}}] 函数不存在', { name }));
459822
459820
  }
459823
459821
  throw e;
@@ -467696,12 +467694,15 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
467696
467694
  functionDetail = yield functionService.getFunctionDetail(name, codeSecret);
467697
467695
  }
467698
467696
  catch (e) {
467699
- if (e.code === 'ResourceNotFound.FunctionName') {
467697
+ if (e.code === 'ResourceNotFound.FunctionName' || e.code === 'ResourceNotFound.Function') {
467700
467698
  throw new error_1.CloudBaseError((0, i18n_1.t)('云函数 [{{name}}] 不存在,请先使用 tcb fn deploy {{name}} 部署函数', { name }));
467701
467699
  }
467702
467700
  throw e;
467703
467701
  }
467704
467702
  const cloudFunctionType = (functionDetail === null || functionDetail === void 0 ? void 0 : functionDetail.Type) || 'Event';
467703
+ const cloudInstallDependency = (functionDetail === null || functionDetail === void 0 ? void 0 : functionDetail.InstallDependency) === 'TRUE';
467704
+ const cloudHandler = (functionDetail === null || functionDetail === void 0 ? void 0 : functionDetail.Handler) || 'index.main';
467705
+ const cloudRuntime = (functionDetail === null || functionDetail === void 0 ? void 0 : functionDetail.Runtime) || func.runtime;
467705
467706
  if (!func.type) {
467706
467707
  func.type = cloudFunctionType;
467707
467708
  }
@@ -467712,6 +467713,16 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
467712
467713
  localType: func.type
467713
467714
  }));
467714
467715
  }
467716
+ if (func.installDependency === undefined) {
467717
+ func.installDependency = cloudInstallDependency;
467718
+ log.verbose((0, i18n_1.t)('使用云端配置 installDependency: {{value}}', { value: cloudInstallDependency }));
467719
+ }
467720
+ if (!func.handler || func.handler === 'index.main') {
467721
+ func.handler = cloudHandler;
467722
+ }
467723
+ if (!func.runtime) {
467724
+ func.runtime = cloudRuntime;
467725
+ }
467715
467726
  if (cloudFunctionType === 'HTTP') {
467716
467727
  const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(funcPath, Object.assign(Object.assign({}, func), { type: 'HTTP', runtime: functionDetail.Runtime }), {
467717
467728
  cancelMessage: (0, i18n_1.t)('已取消更新,请手动创建 scf_bootstrap 文件后重试'),
@@ -467753,7 +467764,7 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
467753
467764
  const mainFile = path_1.default.basename(packageJson.main).replace(/\.[^.]+$/, '');
467754
467765
  handler = `${mainFile}.main`;
467755
467766
  }
467756
- return Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), { handler });
467767
+ return Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), { handler, installDependency: true });
467757
467768
  }
467758
467769
  catch (e) {
467759
467770
  return null;
@@ -467893,11 +467904,11 @@ let CodeDownload = class CodeDownload extends common_1.Command {
467893
467904
  yield functionService.getFunctionDetail(name, codeSecret);
467894
467905
  }
467895
467906
  catch (e) {
467896
- if (e.code === 'ResourceNotFound.FunctionName') {
467907
+ if (e.code === 'ResourceNotFound.FunctionName' || e.code === 'ResourceNotFound.Function') {
467897
467908
  throw new error_1.CloudBaseError((0, i18n_1.t)('云函数 [{{name}}] 不存在!\n\n使用 {{command}} 命令查看已部署云函数', {
467898
467909
  name,
467899
- command: (0, utils_1.highlightCommand)('cloudbase functions:list')
467900
- }));
467910
+ command: (0, utils_1.highlightCommand)('tcb fn list')
467911
+ }), e);
467901
467912
  }
467902
467913
  return;
467903
467914
  }
@@ -493884,7 +493895,7 @@ function validateFunctionTypeChange(envId, func, log) {
493884
493895
  existingFunction = yield functionService.getFunctionDetail(func.name);
493885
493896
  }
493886
493897
  catch (e) {
493887
- if (e.code === 'ResourceNotFound.FunctionName') {
493898
+ if (e.code === 'ResourceNotFound.FunctionName' || e.code === 'ResourceNotFound.Function') {
493888
493899
  log.error((0, i18n_1.t)('云函数 [{{name}}] 不存在,请先部署函数', { name: func.name }));
493889
493900
  return false;
493890
493901
  }
@@ -493927,6 +493938,10 @@ let ConfigUpdate = class ConfigUpdate extends common_1.Command {
493927
493938
  {
493928
493939
  flags: '-e, --envId <envId>',
493929
493940
  desc: (0, i18n_1.t)('环境 Id')
493941
+ },
493942
+ {
493943
+ flags: '--yes',
493944
+ desc: (0, i18n_1.t)('跳过交互确认,使用默认选项自动执行')
493930
493945
  }
493931
493946
  ],
493932
493947
  desc: (0, i18n_1.t)('更新云函数配置'),
@@ -493936,26 +493951,35 @@ let ConfigUpdate = class ConfigUpdate extends common_1.Command {
493936
493951
  }
493937
493952
  execute(ctx, params, log) {
493938
493953
  return __awaiter(this, void 0, void 0, function* () {
493939
- let { envId, config: { functions } } = ctx;
493954
+ let { envId, config: { functions }, options } = ctx;
493940
493955
  const name = params === null || params === void 0 ? void 0 : params[0];
493956
+ const { yes } = options;
493941
493957
  let isBathUpdate = false;
493942
493958
  if (!envId) {
493943
493959
  envId = yield (0, utils_1.selectEnv)({ envTypes: [constant_1.EnvType.BAAS, constant_1.EnvType.WEDA] });
493944
493960
  }
493945
493961
  if (!name) {
493946
- const { isBatch } = yield inquirer_1.default.prompt({
493947
- type: 'confirm',
493948
- name: 'isBatch',
493949
- message: (0, i18n_1.t)('无云函数名称,是否需要更新配置文件中的【全部云函数】的配置?'),
493950
- default: false
493951
- });
493952
- isBathUpdate = isBatch;
493962
+ if (yes) {
493963
+ log.info((0, i18n_1.t)('🚀 --yes 模式:自动更新配置文件中的全部云函数配置'));
493964
+ isBathUpdate = true;
493965
+ }
493966
+ else {
493967
+ const { isBatch } = yield inquirer_1.default.prompt({
493968
+ type: 'confirm',
493969
+ name: 'isBatch',
493970
+ message: (0, i18n_1.t)('无云函数名称,是否需要更新配置文件中的【全部云函数】的配置?'),
493971
+ default: false
493972
+ });
493973
+ isBathUpdate = isBatch;
493974
+ }
493953
493975
  if (!isBathUpdate) {
493954
493976
  throw new error_1.CloudBaseError((0, i18n_1.t)('请指定云函数名称!'));
493955
493977
  }
493956
493978
  }
493957
493979
  if (isBathUpdate) {
493958
- const envVarUpdateMode = hasEnvVariablesConfig(functions) ? yield askEnvVarUpdateMode() : undefined;
493980
+ const envVarUpdateMode = hasEnvVariablesConfig(functions)
493981
+ ? (yes ? 'overwrite' : yield askEnvVarUpdateMode())
493982
+ : undefined;
493959
493983
  for (const func of functions) {
493960
493984
  const isValid = yield validateFunctionTypeChange(envId, func, log);
493961
493985
  if (!isValid) {
@@ -493979,7 +494003,9 @@ let ConfigUpdate = class ConfigUpdate extends common_1.Command {
493979
494003
  if (!isValid) {
493980
494004
  return;
493981
494005
  }
493982
- const envVarUpdateMode = hasEnvVariablesConfig([functionItem]) ? yield askEnvVarUpdateMode() : undefined;
494006
+ const envVarUpdateMode = hasEnvVariablesConfig([functionItem])
494007
+ ? (yes ? 'overwrite' : yield askEnvVarUpdateMode())
494008
+ : undefined;
493983
494009
  yield (0, function_1.updateFunctionConfig)({
493984
494010
  envId,
493985
494011
  functionName: name,
@@ -672190,6 +672216,547 @@ module.exports = function (value) {
672190
672216
  };
672191
672217
 
672192
672218
 
672219
+ /***/ }),
672220
+
672221
+ /***/ 62600:
672222
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
672223
+
672224
+ "use strict";
672225
+
672226
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
672227
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
672228
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
672229
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
672230
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
672231
+ };
672232
+ var __metadata = (this && this.__metadata) || function (k, v) {
672233
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
672234
+ };
672235
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
672236
+ return function (target, key) { decorator(target, key, paramIndex); }
672237
+ };
672238
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
672239
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
672240
+ return new (P || (P = Promise))(function (resolve, reject) {
672241
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
672242
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
672243
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
672244
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
672245
+ });
672246
+ };
672247
+ var __rest = (this && this.__rest) || function (s, e) {
672248
+ var t = {};
672249
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
672250
+ t[p] = s[p];
672251
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
672252
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
672253
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
672254
+ t[p[i]] = s[p[i]];
672255
+ }
672256
+ return t;
672257
+ };
672258
+ var __importDefault = (this && this.__importDefault) || function (mod) {
672259
+ return (mod && mod.__esModule) ? mod : { "default": mod };
672260
+ };
672261
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
672262
+ exports.ConfigPullCommand = void 0;
672263
+ const fs_1 = __importDefault(__webpack_require__(79896));
672264
+ const path_1 = __importDefault(__webpack_require__(16928));
672265
+ const inquirer_1 = __importDefault(__webpack_require__(6403));
672266
+ const common_1 = __webpack_require__(48431);
672267
+ const error_1 = __webpack_require__(66759);
672268
+ const function_1 = __webpack_require__(11686);
672269
+ const utils_1 = __webpack_require__(82079);
672270
+ const utils_2 = __webpack_require__(75213);
672271
+ const decorators_1 = __webpack_require__(93480);
672272
+ const i18n_1 = __webpack_require__(69258);
672273
+ const constant_1 = __webpack_require__(62977);
672274
+ function convertToFunctionConfig(detail, funcDir) {
672275
+ var _a, _b, _c, _d, _e, _f, _g;
672276
+ const config = {
672277
+ name: detail.FunctionName
672278
+ };
672279
+ if (funcDir) {
672280
+ config.dir = funcDir;
672281
+ }
672282
+ if (detail.Type) {
672283
+ config.type = detail.Type;
672284
+ }
672285
+ if (detail.Handler) {
672286
+ config.handler = detail.Handler;
672287
+ }
672288
+ if (detail.Timeout) {
672289
+ config.timeout = detail.Timeout;
672290
+ }
672291
+ if (detail.Runtime) {
672292
+ config.runtime = detail.Runtime;
672293
+ }
672294
+ if (detail.MemorySize) {
672295
+ config.memorySize = detail.MemorySize;
672296
+ }
672297
+ if (detail.InstallDependency !== undefined) {
672298
+ config.installDependency = detail.InstallDependency === 'TRUE';
672299
+ }
672300
+ if (((_b = (_a = detail.Environment) === null || _a === void 0 ? void 0 : _a.Variables) === null || _b === void 0 ? void 0 : _b.length) > 0) {
672301
+ const envVariables = {};
672302
+ for (const item of detail.Environment.Variables) {
672303
+ envVariables[item.Key] = item.Value;
672304
+ }
672305
+ config.envVariables = envVariables;
672306
+ }
672307
+ if (((_c = detail.VpcConfig) === null || _c === void 0 ? void 0 : _c.VpcId) && ((_d = detail.VpcConfig) === null || _d === void 0 ? void 0 : _d.SubnetId)) {
672308
+ config.vpc = {
672309
+ vpcId: detail.VpcConfig.VpcId,
672310
+ subnetId: detail.VpcConfig.SubnetId
672311
+ };
672312
+ }
672313
+ if (((_e = detail.Triggers) === null || _e === void 0 ? void 0 : _e.length) > 0) {
672314
+ config.triggers = detail.Triggers.map((trigger) => ({
672315
+ name: trigger.TriggerName,
672316
+ type: trigger.Type.toLowerCase(),
672317
+ config: trigger.TriggerDesc
672318
+ }));
672319
+ }
672320
+ if (detail.ProtocolType === 'WS') {
672321
+ config.protocolType = 'WS';
672322
+ if ((_g = (_f = detail.ProtocolParams) === null || _f === void 0 ? void 0 : _f.WsParams) === null || _g === void 0 ? void 0 : _g.IdleTimeOut) {
672323
+ config.protocolParams = {
672324
+ wsParams: {
672325
+ idleTimeOut: detail.ProtocolParams.WsParams.IdleTimeOut
672326
+ }
672327
+ };
672328
+ }
672329
+ }
672330
+ if (detail.Type === 'HTTP' && detail.InstanceConcurrencyConfig) {
672331
+ const concurrencyConfig = {};
672332
+ if (detail.InstanceConcurrencyConfig.MaxConcurrency) {
672333
+ concurrencyConfig.maxConcurrency = detail.InstanceConcurrencyConfig.MaxConcurrency;
672334
+ }
672335
+ if (detail.InstanceConcurrencyConfig.DynamicEnabled !== undefined) {
672336
+ concurrencyConfig.dynamicEnabled = detail.InstanceConcurrencyConfig.DynamicEnabled;
672337
+ }
672338
+ if (Object.keys(concurrencyConfig).length > 0) {
672339
+ config.instanceConcurrencyConfig = concurrencyConfig;
672340
+ }
672341
+ }
672342
+ return config;
672343
+ }
672344
+ class FunctionModuleHandler {
672345
+ constructor() {
672346
+ this.moduleName = (0, i18n_1.t)('云函数');
672347
+ this.configKey = 'functions';
672348
+ }
672349
+ createDefaultConfig(funcName, funcDir) {
672350
+ const { installDependency } = constant_1.DefaultFunctionDeployConfig, defaultConfigWithoutInstall = __rest(constant_1.DefaultFunctionDeployConfig, ["installDependency"]);
672351
+ const config = Object.assign({ name: funcName }, defaultConfigWithoutInstall);
672352
+ if (funcDir) {
672353
+ config.dir = funcDir;
672354
+ }
672355
+ return config;
672356
+ }
672357
+ inferFromLocal(name, dir, log) {
672358
+ if (dir) {
672359
+ const targetDir = path_1.default.resolve(process.cwd(), dir);
672360
+ const inferResult = (0, function_1.inferFunctionConfig)({ name, targetDir });
672361
+ if (inferResult) {
672362
+ const config = inferResult.config;
672363
+ config.dir = dir;
672364
+ log.info((0, i18n_1.t)('✓ 已从本地推测出函数 [{{name}}] 配置(来源:{{source}},位置:{{location}})', {
672365
+ name,
672366
+ source: inferResult.source,
672367
+ location: dir
672368
+ }));
672369
+ return { name, config, success: true, inferred: true };
672370
+ }
672371
+ else {
672372
+ const config = this.createDefaultConfig(name, dir);
672373
+ log.info((0, i18n_1.t)('⚠ 无法推测函数 [{{name}}] 配置,使用默认配置', { name }));
672374
+ return { name, config, success: true, inferred: false };
672375
+ }
672376
+ }
672377
+ let inferResult = (0, function_1.inferFunctionConfig)({ name, targetDir: process.cwd() });
672378
+ let finalDir;
672379
+ let sourceLocation = '';
672380
+ if (inferResult) {
672381
+ finalDir = '.';
672382
+ sourceLocation = (0, i18n_1.t)('当前目录');
672383
+ }
672384
+ else {
672385
+ const standardDir = path_1.default.join(process.cwd(), 'functions', name);
672386
+ if (fs_1.default.existsSync(standardDir)) {
672387
+ inferResult = (0, function_1.inferFunctionConfig)({ name, targetDir: standardDir });
672388
+ if (inferResult) {
672389
+ finalDir = undefined;
672390
+ sourceLocation = (0, i18n_1.t)('标准目录 (functions/{{name}})', { name });
672391
+ }
672392
+ }
672393
+ }
672394
+ if (inferResult) {
672395
+ const config = inferResult.config;
672396
+ if (finalDir !== undefined) {
672397
+ config.dir = finalDir;
672398
+ }
672399
+ log.info((0, i18n_1.t)('✓ 已从本地推测出函数 [{{name}}] 配置(来源:{{source}},位置:{{location}})', {
672400
+ name,
672401
+ source: inferResult.source,
672402
+ location: sourceLocation
672403
+ }));
672404
+ return { name, config, success: true, inferred: true };
672405
+ }
672406
+ const config = this.createDefaultConfig(name);
672407
+ log.info((0, i18n_1.t)('⚠ 无法推测函数 [{{name}}] 配置,使用默认配置', { name }));
672408
+ return { name, config, success: true, inferred: false };
672409
+ }
672410
+ batchProcess(options) {
672411
+ return __awaiter(this, void 0, void 0, function* () {
672412
+ const { names, envId, codeSecret, dir, yes, log, loading } = options;
672413
+ const functionService = yield (0, function_1.getFunctionService)(envId);
672414
+ let inferMode = null;
672415
+ const results = [];
672416
+ for (const name of names) {
672417
+ try {
672418
+ loading.start((0, i18n_1.t)('获取函数 [{{name}}] 配置中...', { name }));
672419
+ const detail = yield functionService.getFunctionDetail(name, codeSecret);
672420
+ loading.stop();
672421
+ const config = convertToFunctionConfig(detail, dir || undefined);
672422
+ log.info((0, i18n_1.t)('✓ 已从云端拉取函数 [{{name}}] 的配置', { name }));
672423
+ results.push({ name, config, success: true, inferred: false });
672424
+ }
672425
+ catch (e) {
672426
+ loading.stop();
672427
+ if (e.code === 'ResourceNotFound.Function' || e.code === 'ResourceNotFound.FunctionName') {
672428
+ log.warn((0, i18n_1.t)('云函数 [{{name}}] 不存在', { name }));
672429
+ let shouldCreate = yes || inferMode === 'all';
672430
+ if (!shouldCreate && inferMode === null && names.length > 1) {
672431
+ const { mode } = yield inquirer_1.default.prompt({
672432
+ type: 'list',
672433
+ name: 'mode',
672434
+ message: (0, i18n_1.t)('发现不存在的函数,请选择处理方式:'),
672435
+ choices: [
672436
+ { name: (0, i18n_1.t)('全部推测'), value: 'all' },
672437
+ { name: (0, i18n_1.t)('逐个询问'), value: 'individual' },
672438
+ { name: (0, i18n_1.t)('跳过所有'), value: 'skip' }
672439
+ ]
672440
+ });
672441
+ inferMode = mode;
672442
+ if (inferMode === 'all') {
672443
+ shouldCreate = true;
672444
+ }
672445
+ else if (inferMode === 'skip') {
672446
+ results.push({ name, success: false, error: new Error((0, i18n_1.t)('用户跳过')) });
672447
+ continue;
672448
+ }
672449
+ }
672450
+ if (inferMode === 'skip') {
672451
+ results.push({ name, success: false, error: new Error((0, i18n_1.t)('用户跳过')) });
672452
+ continue;
672453
+ }
672454
+ if (!shouldCreate && inferMode !== 'all') {
672455
+ const { confirm } = yield inquirer_1.default.prompt({
672456
+ type: 'confirm',
672457
+ name: 'confirm',
672458
+ message: (0, i18n_1.t)('是否从本地项目推测函数 [{{name}}] 的配置?', { name }),
672459
+ default: true
672460
+ });
672461
+ shouldCreate = confirm;
672462
+ }
672463
+ if (!shouldCreate) {
672464
+ results.push({ name, success: false, error: new Error((0, i18n_1.t)('用户取消')) });
672465
+ continue;
672466
+ }
672467
+ results.push(this.inferFromLocal(name, dir, log));
672468
+ }
672469
+ else {
672470
+ results.push({ name, success: false, error: e });
672471
+ }
672472
+ }
672473
+ }
672474
+ return results;
672475
+ });
672476
+ }
672477
+ getAllNamesFromConfig(config) {
672478
+ if (!(config === null || config === void 0 ? void 0 : config.functions) || config.functions.length === 0) {
672479
+ throw new error_1.CloudBaseError((0, i18n_1.t)('配置文件中未找到函数定义,请先配置函数或手动指定函数名'));
672480
+ }
672481
+ return config.functions.map((fn) => fn.name).filter(Boolean);
672482
+ }
672483
+ generateCloudbaserc(envId, configs) {
672484
+ return {
672485
+ envId,
672486
+ functionRoot: './functions',
672487
+ functions: configs
672488
+ };
672489
+ }
672490
+ }
672491
+ let ConfigPullCommand = class ConfigPullCommand extends common_1.Command {
672492
+ get options() {
672493
+ return {
672494
+ cmd: 'config',
672495
+ childCmd: 'pull <module> [name...]',
672496
+ options: [
672497
+ {
672498
+ flags: '-e, --envId <envId>',
672499
+ desc: (0, i18n_1.t)('环境 Id')
672500
+ },
672501
+ {
672502
+ flags: '-o, --output <output>',
672503
+ desc: (0, i18n_1.t)('输出文件路径(默认为当前目录下的 cloudbaserc.json)')
672504
+ },
672505
+ {
672506
+ flags: '--stdout',
672507
+ desc: (0, i18n_1.t)('输出到控制台而非文件')
672508
+ },
672509
+ {
672510
+ flags: '--code-secret <codeSecret>',
672511
+ desc: (0, i18n_1.t)('代码加密的函数的 CodeSecret')
672512
+ },
672513
+ {
672514
+ flags: '--dir <dir>',
672515
+ desc: (0, i18n_1.t)('指定目录用于推测配置(当云函数不存在时)')
672516
+ },
672517
+ {
672518
+ flags: '--all',
672519
+ desc: (0, i18n_1.t)('拉取配置文件中的所有云函数配置')
672520
+ },
672521
+ {
672522
+ flags: '--yes',
672523
+ desc: (0, i18n_1.t)('跳过交互确认,自动覆盖已存在的文件')
672524
+ }
672525
+ ],
672526
+ desc: (0, i18n_1.t)('拉取模块配置(当前支持: fn 云函数)'),
672527
+ requiredEnvId: false,
672528
+ autoRunLogin: true
672529
+ };
672530
+ }
672531
+ execute(ctx, params, log) {
672532
+ return __awaiter(this, void 0, void 0, function* () {
672533
+ const module = params === null || params === void 0 ? void 0 : params[0];
672534
+ const names = (params === null || params === void 0 ? void 0 : params[1]) || [];
672535
+ if (!module) {
672536
+ throw new error_1.CloudBaseError((0, i18n_1.t)('请指定模块类型,当前支持: fn (云函数)'));
672537
+ }
672538
+ const handler = this.getModuleHandler(module);
672539
+ yield this.pullModuleConfig(ctx, handler, names, log);
672540
+ });
672541
+ }
672542
+ getModuleHandler(module) {
672543
+ const supportedModules = ['fn'];
672544
+ switch (module) {
672545
+ case 'fn':
672546
+ return new FunctionModuleHandler();
672547
+ default:
672548
+ throw new error_1.CloudBaseError((0, i18n_1.t)('不支持的模块类型: {{module}},当前支持: {{supported}}', {
672549
+ module,
672550
+ supported: supportedModules.join(', ')
672551
+ }));
672552
+ }
672553
+ }
672554
+ pullModuleConfig(ctx, handler, inputNames, log) {
672555
+ return __awaiter(this, void 0, void 0, function* () {
672556
+ let { envId, options, config } = ctx;
672557
+ const { output, codeSecret, dir, yes, stdout, all } = options;
672558
+ let names = [];
672559
+ if (all) {
672560
+ names = handler.getAllNamesFromConfig(config);
672561
+ log.info((0, i18n_1.t)('从配置文件读取到 {{count}} 个{{moduleName}}:{{names}}', {
672562
+ count: names.length,
672563
+ moduleName: handler.moduleName,
672564
+ names: names.join(', ')
672565
+ }));
672566
+ }
672567
+ else {
672568
+ names = [];
672569
+ for (const param of inputNames) {
672570
+ if (typeof param === 'string' && param.trim()) {
672571
+ const splitNames = param.split(',').map(n => n.trim()).filter(n => n);
672572
+ names.push(...splitNames);
672573
+ }
672574
+ }
672575
+ }
672576
+ if (names.length === 0) {
672577
+ throw new error_1.CloudBaseError((0, i18n_1.t)('请指定至少一个名称,或使用 --all 选项拉取配置文件中的所有项目'));
672578
+ }
672579
+ let selectedEnvId = envId;
672580
+ if (!selectedEnvId) {
672581
+ selectedEnvId = yield (0, utils_2.selectEnv)({
672582
+ envTypes: [constant_1.EnvType.BAAS, constant_1.EnvType.WEDA]
672583
+ });
672584
+ }
672585
+ const loading = (0, utils_1.loadingFactory)();
672586
+ try {
672587
+ const results = yield handler.batchProcess({
672588
+ names,
672589
+ envId: selectedEnvId,
672590
+ codeSecret,
672591
+ dir,
672592
+ yes,
672593
+ log,
672594
+ loading
672595
+ });
672596
+ const successConfigs = results.filter((r) => r.success).map((r) => r.config);
672597
+ const failedResults = results.filter((r) => !r.success);
672598
+ const inferredCount = results.filter((r) => r.success && r.inferred).length;
672599
+ log.info((0, i18n_1.t)('处理完成:成功 {{success}} 个,失败 {{failed}} 个,推测 {{inferred}} 个', {
672600
+ success: successConfigs.length,
672601
+ failed: failedResults.length,
672602
+ inferred: inferredCount
672603
+ }));
672604
+ if (failedResults.length > 0) {
672605
+ log.warn((0, i18n_1.t)('失败的项目:'));
672606
+ failedResults.forEach((result) => {
672607
+ var _a;
672608
+ log.error((0, i18n_1.t)(' - {{name}}: {{error}}', {
672609
+ name: result.name,
672610
+ error: ((_a = result.error) === null || _a === void 0 ? void 0 : _a.message) || (0, i18n_1.t)('未知错误')
672611
+ }));
672612
+ });
672613
+ }
672614
+ if (successConfigs.length === 0) {
672615
+ log.warn((0, i18n_1.t)('没有成功获取任何配置'));
672616
+ return;
672617
+ }
672618
+ yield this.handleOutput({
672619
+ handler,
672620
+ configs: successConfigs,
672621
+ envId: selectedEnvId,
672622
+ output,
672623
+ stdout,
672624
+ yes,
672625
+ log
672626
+ });
672627
+ }
672628
+ catch (e) {
672629
+ loading.stop();
672630
+ throw e;
672631
+ }
672632
+ });
672633
+ }
672634
+ handleOutput(options) {
672635
+ return __awaiter(this, void 0, void 0, function* () {
672636
+ const { handler, configs, envId, output, stdout, yes, log } = options;
672637
+ if (stdout) {
672638
+ const cloudbaserc = handler.generateCloudbaserc(envId, configs);
672639
+ const stdoutOutput = JSON.stringify(cloudbaserc, null, 2);
672640
+ if (configs.length === 1) {
672641
+ log.info((0, i18n_1.t)('{{moduleName}} [{{name}}] 配置:', {
672642
+ moduleName: handler.moduleName,
672643
+ name: configs[0].name
672644
+ }));
672645
+ }
672646
+ else {
672647
+ log.info((0, i18n_1.t)('{{count}} 个{{moduleName}}配置:', {
672648
+ count: configs.length,
672649
+ moduleName: handler.moduleName
672650
+ }));
672651
+ }
672652
+ console.log(stdoutOutput);
672653
+ log.info('');
672654
+ log.info((0, i18n_1.t)('提示:可将上述配置添加到 cloudbaserc.json 的 {{configKey}} 数组中', {
672655
+ configKey: handler.configKey
672656
+ }));
672657
+ return;
672658
+ }
672659
+ const outputPath = output
672660
+ ? path_1.default.resolve(process.cwd(), output)
672661
+ : path_1.default.resolve(process.cwd(), 'cloudbaserc.json');
672662
+ let finalOutput;
672663
+ const updatedItems = [];
672664
+ const addedItems = [];
672665
+ if (fs_1.default.existsSync(outputPath)) {
672666
+ try {
672667
+ const existingContent = fs_1.default.readFileSync(outputPath, 'utf-8');
672668
+ const existingConfig = JSON.parse(existingContent);
672669
+ if (!existingConfig[handler.configKey]) {
672670
+ existingConfig[handler.configKey] = [];
672671
+ }
672672
+ for (const config of configs) {
672673
+ const existingIndex = existingConfig[handler.configKey].findIndex((item) => item.name === config.name);
672674
+ if (existingIndex >= 0) {
672675
+ let shouldUpdate = yes;
672676
+ if (!shouldUpdate) {
672677
+ const { update } = yield inquirer_1.default.prompt({
672678
+ type: 'confirm',
672679
+ name: 'update',
672680
+ message: (0, i18n_1.t)('{{moduleName}} [{{name}}] 配置已存在,是否更新?', {
672681
+ moduleName: handler.moduleName,
672682
+ name: config.name
672683
+ }),
672684
+ default: true
672685
+ });
672686
+ shouldUpdate = update;
672687
+ }
672688
+ if (shouldUpdate) {
672689
+ existingConfig[handler.configKey][existingIndex] = config;
672690
+ updatedItems.push(config.name);
672691
+ }
672692
+ }
672693
+ else {
672694
+ existingConfig[handler.configKey].push(config);
672695
+ addedItems.push(config.name);
672696
+ }
672697
+ }
672698
+ if (!existingConfig.envId) {
672699
+ existingConfig.envId = envId;
672700
+ }
672701
+ finalOutput = existingConfig;
672702
+ }
672703
+ catch (parseError) {
672704
+ log.warn((0, i18n_1.t)('现有配置文件解析失败'));
672705
+ let shouldOverwrite = yes;
672706
+ if (!shouldOverwrite) {
672707
+ const { overwrite } = yield inquirer_1.default.prompt({
672708
+ type: 'confirm',
672709
+ name: 'overwrite',
672710
+ message: (0, i18n_1.t)('是否覆盖现有文件?'),
672711
+ default: false
672712
+ });
672713
+ shouldOverwrite = overwrite;
672714
+ }
672715
+ if (!shouldOverwrite) {
672716
+ log.info((0, i18n_1.t)('已取消'));
672717
+ return;
672718
+ }
672719
+ finalOutput = handler.generateCloudbaserc(envId, configs);
672720
+ addedItems.push(...configs.map(c => c.name));
672721
+ }
672722
+ }
672723
+ else {
672724
+ finalOutput = handler.generateCloudbaserc(envId, configs);
672725
+ addedItems.push(...configs.map(c => c.name));
672726
+ }
672727
+ const jsonOutput = JSON.stringify(finalOutput, null, 2);
672728
+ fs_1.default.writeFileSync(outputPath, jsonOutput, 'utf-8');
672729
+ if (updatedItems.length > 0) {
672730
+ log.success((0, i18n_1.t)('已更新{{moduleName}}配置:{{names}}', {
672731
+ moduleName: handler.moduleName,
672732
+ names: updatedItems.join(', ')
672733
+ }));
672734
+ }
672735
+ if (addedItems.length > 0) {
672736
+ log.success((0, i18n_1.t)('已添加{{moduleName}}配置:{{names}}', {
672737
+ moduleName: handler.moduleName,
672738
+ names: addedItems.join(', ')
672739
+ }));
672740
+ }
672741
+ log.success((0, i18n_1.t)('配置已保存到 {{path}}', { path: outputPath }));
672742
+ });
672743
+ }
672744
+ };
672745
+ __decorate([
672746
+ (0, decorators_1.InjectParams)(),
672747
+ __param(0, (0, decorators_1.CmdContext)()),
672748
+ __param(1, (0, decorators_1.ArgsParams)()),
672749
+ __param(2, (0, decorators_1.Log)()),
672750
+ __metadata("design:type", Function),
672751
+ __metadata("design:paramtypes", [Object, Array, decorators_1.Logger]),
672752
+ __metadata("design:returntype", Promise)
672753
+ ], ConfigPullCommand.prototype, "execute", null);
672754
+ ConfigPullCommand = __decorate([
672755
+ (0, common_1.ICommand)()
672756
+ ], ConfigPullCommand);
672757
+ exports.ConfigPullCommand = ConfigPullCommand;
672758
+
672759
+
672193
672760
  /***/ }),
672194
672761
 
672195
672762
  /***/ 62629:
@@ -674065,15 +674632,20 @@ exports.DefaultFunctionDeployConfig = {
674065
674632
  ignore: ['node_modules', 'node_modules/**/*', '.git']
674066
674633
  };
674067
674634
  exports.RuntimeOptions = [
674635
+ { name: 'Node.js 24.11 (公测中)', value: 'Nodejs24.11', handler: 'index.main' },
674636
+ { name: 'Node.js 22.21 (公测中)', value: 'Nodejs22.21', handler: 'index.main' },
674068
674637
  { name: 'Node.js 20.19', value: 'Nodejs20.19', handler: 'index.main' },
674069
674638
  { name: 'Node.js 18.15', value: 'Nodejs18.15', handler: 'index.main' },
674070
674639
  { name: 'Node.js 16.13', value: 'Nodejs16.13', handler: 'index.main' },
674640
+ { name: 'Python 3.11', value: 'Python3.11', handler: 'index.main' },
674641
+ { name: 'Python 3.10', value: 'Python3.10', handler: 'index.main' },
674071
674642
  { name: 'Python 3.9', value: 'Python3.9', handler: 'index.main' },
674072
674643
  { name: 'Python 3.7', value: 'Python3.7', handler: 'index.main' },
674073
674644
  { name: 'PHP 8.0', value: 'Php8.0', handler: 'index.main' },
674074
674645
  { name: 'PHP 7.4', value: 'Php7.4', handler: 'index.main' },
674075
674646
  { name: 'Java 11', value: 'Java11', handler: 'example.Hello::mainHandler' },
674076
- { name: 'Java 8', value: 'Java8', handler: 'example.Hello::mainHandler' }
674647
+ { name: 'Java 8', value: 'Java8', handler: 'example.Hello::mainHandler' },
674648
+ { name: 'Golang 1', value: 'Go1', handler: 'main' }
674077
674649
  ];
674078
674650
  exports.DefaultCloudBaseConfig = {
674079
674651
  functionRoot: './functions',
@@ -731198,6 +731770,7 @@ __exportStar(__webpack_require__(83531), exports);
731198
731770
  __exportStar(__webpack_require__(12591), exports);
731199
731771
  __exportStar(__webpack_require__(78908), exports);
731200
731772
  __exportStar(__webpack_require__(5827), exports);
731773
+ __exportStar(__webpack_require__(62600), exports);
731201
731774
  __exportStar(__webpack_require__(5892), exports);
731202
731775
 
731203
731776
 
@@ -800747,7 +801320,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
800747
801320
  return (mod && mod.__esModule) ? mod : { "default": mod };
800748
801321
  };
800749
801322
  Object.defineProperty(exports, "__esModule", ({ value: true }));
800750
- exports.checkAndCreateBootstrap = exports.generateBootstrapContent = void 0;
801323
+ exports.getConfigSourceDescription = exports.inferFunctionConfig = exports.checkAndCreateBootstrap = exports.generateBootstrapContent = void 0;
800751
801324
  const fs_1 = __importDefault(__webpack_require__(79896));
800752
801325
  const path_1 = __importDefault(__webpack_require__(16928));
800753
801326
  const inquirer_1 = __importDefault(__webpack_require__(6403));
@@ -800839,6 +801412,206 @@ function checkAndCreateBootstrap(functionPath, func, options = {}) {
800839
801412
  });
800840
801413
  }
800841
801414
  exports.checkAndCreateBootstrap = checkAndCreateBootstrap;
801415
+ function inferFunctionConfig(options = {}) {
801416
+ const { name, targetDir = process.cwd(), httpFn } = options;
801417
+ const nodeResult = inferNodejsConfig(targetDir, name, httpFn);
801418
+ if (nodeResult)
801419
+ return nodeResult;
801420
+ const pythonResult = inferPythonConfig(targetDir, name, httpFn);
801421
+ if (pythonResult)
801422
+ return pythonResult;
801423
+ const phpResult = inferPhpConfig(targetDir, name, httpFn);
801424
+ if (phpResult)
801425
+ return phpResult;
801426
+ const javaResult = inferJavaConfig(targetDir, name, httpFn);
801427
+ if (javaResult)
801428
+ return javaResult;
801429
+ const goResult = inferGoConfig(targetDir, name, httpFn);
801430
+ if (goResult)
801431
+ return goResult;
801432
+ const fileBasedResult = inferByFileExtension(targetDir, name, httpFn);
801433
+ if (fileBasedResult)
801434
+ return fileBasedResult;
801435
+ return null;
801436
+ }
801437
+ exports.inferFunctionConfig = inferFunctionConfig;
801438
+ function inferNodejsConfig(targetDir, name, httpFn) {
801439
+ var _a;
801440
+ const packageJsonPath = path_1.default.join(targetDir, 'package.json');
801441
+ if (!fs_1.default.existsSync(packageJsonPath)) {
801442
+ return null;
801443
+ }
801444
+ try {
801445
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
801446
+ const funcName = name || packageJson.name || path_1.default.basename(targetDir);
801447
+ let handler = constant_1.DefaultFunctionDeployConfig.handler;
801448
+ if (packageJson.main) {
801449
+ const mainFile = path_1.default.basename(packageJson.main).replace(/\.[^.]+$/, '');
801450
+ handler = `${mainFile}.main`;
801451
+ }
801452
+ let runtime = constant_1.DefaultFunctionDeployConfig.runtime;
801453
+ if ((_a = packageJson.engines) === null || _a === void 0 ? void 0 : _a.node) {
801454
+ const nodeVersion = packageJson.engines.node;
801455
+ if (nodeVersion.includes('20')) {
801456
+ runtime = 'Nodejs20.19';
801457
+ }
801458
+ else if (nodeVersion.includes('16')) {
801459
+ runtime = 'Nodejs16.13';
801460
+ }
801461
+ }
801462
+ return {
801463
+ config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime,
801464
+ handler, installDependency: true }), (httpFn ? { type: 'HTTP' } : {})),
801465
+ source: (0, i18n_1.t)('Node.js 项目(package.json)')
801466
+ };
801467
+ }
801468
+ catch (e) {
801469
+ return null;
801470
+ }
801471
+ }
801472
+ function inferPythonConfig(targetDir, name, httpFn) {
801473
+ const pythonFiles = ['requirements.txt', 'setup.py', 'pyproject.toml'];
801474
+ const foundFile = pythonFiles.find(file => fs_1.default.existsSync(path_1.default.join(targetDir, file)));
801475
+ if (!foundFile) {
801476
+ return null;
801477
+ }
801478
+ const funcName = name || path_1.default.basename(targetDir);
801479
+ const entryFiles = ['main.py', 'app.py', 'index.py'];
801480
+ let handler = 'index.main';
801481
+ for (const file of entryFiles) {
801482
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, file))) {
801483
+ const filename = path_1.default.basename(file, '.py');
801484
+ handler = `${filename}.main`;
801485
+ break;
801486
+ }
801487
+ }
801488
+ return {
801489
+ config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Python3.9', handler, installDependency: true }), (httpFn ? { type: 'HTTP' } : {})),
801490
+ source: (0, i18n_1.t)('Python 项目({{file}})', { file: foundFile })
801491
+ };
801492
+ }
801493
+ function inferPhpConfig(targetDir, name, httpFn) {
801494
+ const composerJsonPath = path_1.default.join(targetDir, 'composer.json');
801495
+ let hasPhpFiles = false;
801496
+ try {
801497
+ hasPhpFiles = fs_1.default.readdirSync(targetDir).some(file => file.endsWith('.php'));
801498
+ }
801499
+ catch (e) {
801500
+ }
801501
+ if (!fs_1.default.existsSync(composerJsonPath) && !hasPhpFiles) {
801502
+ return null;
801503
+ }
801504
+ let funcName = name || path_1.default.basename(targetDir);
801505
+ let source = (0, i18n_1.t)('PHP 项目(PHP 文件)');
801506
+ if (fs_1.default.existsSync(composerJsonPath)) {
801507
+ try {
801508
+ const composerJson = JSON.parse(fs_1.default.readFileSync(composerJsonPath, 'utf-8'));
801509
+ if (!name && composerJson.name) {
801510
+ funcName = composerJson.name.split('/').pop() || funcName;
801511
+ }
801512
+ source = (0, i18n_1.t)('PHP 项目(composer.json)');
801513
+ }
801514
+ catch (e) {
801515
+ }
801516
+ }
801517
+ let handler = 'index.main';
801518
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'index.php'))) {
801519
+ handler = 'index.main';
801520
+ }
801521
+ return {
801522
+ config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Php8.0', handler, installDependency: fs_1.default.existsSync(composerJsonPath) }), (httpFn ? { type: 'HTTP' } : {})),
801523
+ source
801524
+ };
801525
+ }
801526
+ function inferJavaConfig(targetDir, name, httpFn) {
801527
+ const javaFiles = ['pom.xml', 'build.gradle', 'build.gradle.kts'];
801528
+ const foundFile = javaFiles.find(file => fs_1.default.existsSync(path_1.default.join(targetDir, file)));
801529
+ if (!foundFile) {
801530
+ return null;
801531
+ }
801532
+ let funcName = name || path_1.default.basename(targetDir);
801533
+ if (!name && foundFile === 'pom.xml') {
801534
+ const pomPath = path_1.default.join(targetDir, 'pom.xml');
801535
+ try {
801536
+ const pomContent = fs_1.default.readFileSync(pomPath, 'utf-8');
801537
+ const artifactIdMatch = pomContent.match(/<artifactId>([^<]+)<\/artifactId>/);
801538
+ if (artifactIdMatch) {
801539
+ funcName = artifactIdMatch[1];
801540
+ }
801541
+ }
801542
+ catch (e) {
801543
+ }
801544
+ }
801545
+ return {
801546
+ config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Java11', handler: 'example.Hello::mainHandler', installDependency: true }), (httpFn ? { type: 'HTTP' } : {})),
801547
+ source: (0, i18n_1.t)('Java 项目({{file}})', { file: foundFile })
801548
+ };
801549
+ }
801550
+ function inferGoConfig(targetDir, name, httpFn) {
801551
+ const goFiles = ['go.mod', 'go.sum'];
801552
+ const foundFile = goFiles.find(file => fs_1.default.existsSync(path_1.default.join(targetDir, file)));
801553
+ if (!foundFile) {
801554
+ return null;
801555
+ }
801556
+ let funcName = name || path_1.default.basename(targetDir);
801557
+ if (!name && fs_1.default.existsSync(path_1.default.join(targetDir, 'go.mod'))) {
801558
+ try {
801559
+ const goModContent = fs_1.default.readFileSync(path_1.default.join(targetDir, 'go.mod'), 'utf-8');
801560
+ const moduleMatch = goModContent.match(/^module\s+(.+)$/m);
801561
+ if (moduleMatch) {
801562
+ funcName = moduleMatch[1].split('/').pop() || funcName;
801563
+ }
801564
+ }
801565
+ catch (e) {
801566
+ }
801567
+ }
801568
+ return {
801569
+ config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Go1', handler: 'main', installDependency: true }), (httpFn ? { type: 'HTTP' } : {})),
801570
+ source: (0, i18n_1.t)('Go 项目({{file}})', { file: foundFile })
801571
+ };
801572
+ }
801573
+ function inferByFileExtension(targetDir, name, httpFn) {
801574
+ try {
801575
+ const files = fs_1.default.readdirSync(targetDir);
801576
+ const fileTypes = {
801577
+ js: files.filter(f => f.endsWith('.js')).length,
801578
+ ts: files.filter(f => f.endsWith('.ts')).length,
801579
+ py: files.filter(f => f.endsWith('.py')).length,
801580
+ php: files.filter(f => f.endsWith('.php')).length,
801581
+ java: files.filter(f => f.endsWith('.java')).length,
801582
+ go: files.filter(f => f.endsWith('.go')).length
801583
+ };
801584
+ const maxType = Object.entries(fileTypes).reduce((a, b) => (fileTypes[a[0]] || 0) > (fileTypes[b[0]] || 0) ? a : b);
801585
+ if (maxType[1] === 0) {
801586
+ return null;
801587
+ }
801588
+ const funcName = name || path_1.default.basename(targetDir);
801589
+ const typeConfigMap = {
801590
+ js: { runtime: 'Nodejs18.15', handler: 'index.main', source: (0, i18n_1.t)('JavaScript 文件推测') },
801591
+ ts: { runtime: 'Nodejs18.15', handler: 'index.main', source: (0, i18n_1.t)('TypeScript 文件推测') },
801592
+ py: { runtime: 'Python3.9', handler: 'index.main', source: (0, i18n_1.t)('Python 文件推测') },
801593
+ php: { runtime: 'Php8.0', handler: 'index.main', source: (0, i18n_1.t)('PHP 文件推测') },
801594
+ java: { runtime: 'Java11', handler: 'example.Hello::mainHandler', source: (0, i18n_1.t)('Java 文件推测') },
801595
+ go: { runtime: 'Go1', handler: 'main', source: (0, i18n_1.t)('Go 文件推测') }
801596
+ };
801597
+ const typeConfig = typeConfigMap[maxType[0]];
801598
+ if (!typeConfig) {
801599
+ return null;
801600
+ }
801601
+ return {
801602
+ config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: typeConfig.runtime, handler: typeConfig.handler }), (httpFn ? { type: 'HTTP' } : {})),
801603
+ source: typeConfig.source
801604
+ };
801605
+ }
801606
+ catch (e) {
801607
+ return null;
801608
+ }
801609
+ }
801610
+ function getConfigSourceDescription(targetDir) {
801611
+ const result = inferFunctionConfig({ targetDir, name: 'temp' });
801612
+ return (result === null || result === void 0 ? void 0 : result.source) || (0, i18n_1.t)('默认配置');
801613
+ }
801614
+ exports.getConfigSourceDescription = getConfigSourceDescription;
800842
801615
 
800843
801616
 
800844
801617
  /***/ }),
@@ -834840,6 +835613,10 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834840
835613
  {
834841
835614
  flags: '--deployMode <deployMode>',
834842
835615
  desc: (0, i18n_1.t)('代码上传方式:cos(通过 COS 上传)或 zip(直接 ZIP 上传),默认自动选择')
835616
+ },
835617
+ {
835618
+ flags: '--yes',
835619
+ desc: (0, i18n_1.t)('跳过交互确认,使用推测或默认配置自动部署')
834843
835620
  }
834844
835621
  ],
834845
835622
  desc: (0, i18n_1.t)('部署云函数'),
@@ -834851,7 +835628,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834851
835628
  return __awaiter(this, void 0, void 0, function* () {
834852
835629
  let { envId, config, options } = ctx;
834853
835630
  const { functions } = config;
834854
- const { force, codeSecret, path: access, all, dir, httpFn, ws, deployMode } = options;
835631
+ const { force, codeSecret, path: access, all, dir, httpFn, ws, deployMode, yes } = options;
834855
835632
  const name = params === null || params === void 0 ? void 0 : params[0];
834856
835633
  this.validateOptions({ deployMode, access }, log);
834857
835634
  const isUnresolvedEnvId = !envId || envId.startsWith('{{');
@@ -834871,12 +835648,12 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834871
835648
  if (hasConfig) {
834872
835649
  return this.deployWithConfig({
834873
835650
  name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode,
834874
- all, functions, functionRootPath, log
835651
+ all, functions, functionRootPath, yes, log
834875
835652
  });
834876
835653
  }
834877
835654
  else {
834878
835655
  return this.deployWithoutConfig({
834879
- name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, log
835656
+ name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, yes, log
834880
835657
  });
834881
835658
  }
834882
835659
  });
@@ -834895,11 +835672,11 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834895
835672
  }
834896
835673
  deployWithConfig(options) {
834897
835674
  return __awaiter(this, void 0, void 0, function* () {
834898
- const { name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, all, functions, functionRootPath, log } = options;
835675
+ const { name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, all, functions, functionRootPath, yes, log } = options;
834899
835676
  if (name) {
834900
835677
  return this.deploySingleWithConfig({
834901
835678
  name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode,
834902
- functions, functionRootPath, log
835679
+ functions, functionRootPath, yes, log
834903
835680
  });
834904
835681
  }
834905
835682
  if (dir) {
@@ -834907,13 +835684,13 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834907
835684
  }
834908
835685
  return this.deployAllFunction({
834909
835686
  all, envId, force, access, functions, codeSecret,
834910
- functionRootPath, httpFn, ws, deployMode, log
835687
+ functionRootPath, httpFn, ws, deployMode, yes, log
834911
835688
  });
834912
835689
  });
834913
835690
  }
834914
835691
  deploySingleWithConfig(options) {
834915
835692
  return __awaiter(this, void 0, void 0, function* () {
834916
- const { name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, functions, functionRootPath, log } = options;
835693
+ const { name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, functions, functionRootPath, yes, log } = options;
834917
835694
  let func = functions === null || functions === void 0 ? void 0 : functions.find((item) => item.name === name);
834918
835695
  let funcPath;
834919
835696
  if (dir) {
@@ -834936,21 +835713,32 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834936
835713
  }
834937
835714
  if (!func) {
834938
835715
  log.warn((0, i18n_1.t)('配置文件中未找到函数 [{{name}}] 的配置', { name }));
834939
- const runtime = yield this.selectRuntime();
834940
- const defaultFunc = Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), { runtime });
834941
- log.info((0, i18n_1.t)('将使用以下默认配置:'));
834942
- this.printFunctionConfig(defaultFunc, log);
834943
- const { confirm } = yield inquirer_1.default.prompt({
834944
- type: 'confirm',
834945
- name: 'confirm',
834946
- message: (0, i18n_1.t)('是否使用默认配置继续部署?'),
834947
- default: false
834948
- });
834949
- if (!confirm) {
834950
- log.info((0, i18n_1.t)('已取消部署,请在配置文件中添加函数 [{{name}}] 的配置后重试', { name }));
834951
- return;
835716
+ if (yes) {
835717
+ const inferredConfig = this.inferFunctionConfig(httpFn, funcPath);
835718
+ const runtime = (inferredConfig === null || inferredConfig === void 0 ? void 0 : inferredConfig.runtime) || (yield this.getDefaultRuntime(funcPath));
835719
+ const defaultFunc = Object.assign(Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), { runtime }), inferredConfig);
835720
+ log.info((0, i18n_1.t)('🚀 --yes 模式:自动使用以下配置部署:'));
835721
+ const sourceDesc = inferredConfig ? this.getConfigSourceDescription(funcPath) : (0, i18n_1.t)('默认配置');
835722
+ this.printFunctionConfig(defaultFunc, log, sourceDesc);
835723
+ func = defaultFunc;
835724
+ }
835725
+ else {
835726
+ const runtime = yield this.selectRuntime();
835727
+ const defaultFunc = Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), { runtime });
835728
+ log.info((0, i18n_1.t)('将使用以下默认配置:'));
835729
+ this.printFunctionConfig(defaultFunc, log, (0, i18n_1.t)('默认配置'));
835730
+ const { confirm } = yield inquirer_1.default.prompt({
835731
+ type: 'confirm',
835732
+ name: 'confirm',
835733
+ message: (0, i18n_1.t)('是否使用默认配置继续部署?'),
835734
+ default: false
835735
+ });
835736
+ if (!confirm) {
835737
+ log.info((0, i18n_1.t)('已取消部署,请在配置文件中添加函数 [{{name}}] 的配置后重试', { name }));
835738
+ return;
835739
+ }
835740
+ func = defaultFunc;
834952
835741
  }
834953
- func = defaultFunc;
834954
835742
  }
834955
835743
  if (httpFn) {
834956
835744
  func = Object.assign(Object.assign({}, func), { type: 'HTTP' });
@@ -834960,95 +835748,177 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
834960
835748
  }
834961
835749
  return this.doDeploySingleFunction({
834962
835750
  func, envId, force, codeSecret, access, deployMode,
834963
- functionRootPath, functionPath: funcPath, log
835751
+ functionRootPath, functionPath: funcPath, yes, log
834964
835752
  });
834965
835753
  });
834966
835754
  }
834967
835755
  deployWithoutConfig(options) {
834968
835756
  return __awaiter(this, void 0, void 0, function* () {
834969
- const { name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, log } = options;
834970
- let deployDir = process.cwd();
834971
- if (dir) {
834972
- (0, utils_1.checkFullAccess)(dir, true);
834973
- if (!(0, utils_1.isDirectory)(dir)) {
834974
- throw new error_1.CloudBaseError((0, i18n_1.t)('--dir 参数必须指定为云函数的文件夹路径'));
834975
- }
834976
- deployDir = path_1.default.resolve(process.cwd(), dir);
834977
- log.info((0, i18n_1.t)('将从目录 {{dir}} 部署云函数', { dir: deployDir }));
835757
+ const { envId, codeSecret, httpFn, ws, log } = options;
835758
+ const { deployDir, functionName } = this.resolveFunctionInfo(options);
835759
+ log.verbose((0, i18n_1.t)('正在检测云端函数状态...'));
835760
+ let checkResult;
835761
+ try {
835762
+ checkResult = yield this.checkCloudFunction(functionName, envId, codeSecret);
834978
835763
  }
834979
- else {
834980
- log.info((0, i18n_1.t)('未找到配置文件,将从当前目录部署云函数'));
835764
+ catch (error) {
835765
+ this.displayFriendlyError(error, {
835766
+ functionName,
835767
+ operation: '前置检测'
835768
+ }, log);
835769
+ checkResult = { uncertain: true, exists: false };
834981
835770
  }
834982
835771
  let inferredConfig = this.inferFunctionConfig(httpFn, deployDir);
834983
835772
  const isInferred = !!inferredConfig;
834984
835773
  if (!inferredConfig) {
834985
- inferredConfig = Object.assign(Object.assign(Object.assign({ name: name || path_1.default.basename(deployDir) }, constant_1.DefaultFunctionDeployConfig), (httpFn ? { type: 'HTTP' } : {})), (ws ? { type: 'HTTP', protocolType: 'WS' } : {}));
835774
+ inferredConfig = Object.assign(Object.assign(Object.assign({ name: functionName }, constant_1.DefaultFunctionDeployConfig), (httpFn ? { type: 'HTTP' } : {})), (ws ? { type: 'HTTP', protocolType: 'WS' } : {}));
834986
835775
  }
834987
- else if (name) {
834988
- inferredConfig.name = name;
835776
+ else {
835777
+ inferredConfig.name = functionName;
834989
835778
  }
834990
835779
  if (ws && isInferred) {
834991
835780
  inferredConfig = Object.assign(Object.assign({}, inferredConfig), { type: 'HTTP', protocolType: 'WS' });
834992
835781
  }
834993
- if (isInferred) {
834994
- log.info((0, i18n_1.t)('从 package.json 推测出以下配置:'));
835782
+ if (checkResult.uncertain) {
835783
+ return yield this.handleNewFunction(inferredConfig, isInferred, options, deployDir);
835784
+ }
835785
+ else if (checkResult.exists) {
835786
+ return yield this.handleExistingFunction(checkResult, inferredConfig, isInferred, options, deployDir);
834995
835787
  }
834996
835788
  else {
834997
- log.info((0, i18n_1.t)('未推测出配置,将使用默认配置:'));
835789
+ return yield this.handleNewFunction(inferredConfig, isInferred, options, deployDir);
834998
835790
  }
834999
- this.printFunctionConfig(inferredConfig, log);
835000
- const { action } = yield inquirer_1.default.prompt({
835001
- type: 'list',
835002
- name: 'action',
835003
- message: (0, i18n_1.t)('请选择操作'),
835004
- choices: [
835005
- { name: (0, i18n_1.t)('使用当前配置部署'), value: 'deploy' },
835006
- { name: (0, i18n_1.t)('手动输入配置'), value: 'manual' },
835007
- { name: (0, i18n_1.t)('退出'), value: 'exit' }
835008
- ]
835791
+ });
835792
+ }
835793
+ resolveFunctionInfo(options) {
835794
+ const { name, dir, log } = options;
835795
+ let deployDir = process.cwd();
835796
+ if (dir) {
835797
+ (0, utils_1.checkFullAccess)(dir, true);
835798
+ if (!(0, utils_1.isDirectory)(dir)) {
835799
+ throw new error_1.CloudBaseError((0, i18n_1.t)('--dir 参数必须指定为云函数的文件夹路径'));
835800
+ }
835801
+ deployDir = path_1.default.resolve(process.cwd(), dir);
835802
+ log.info((0, i18n_1.t)('将从目录 {{dir}} 部署云函数', { dir: deployDir }));
835803
+ }
835804
+ else {
835805
+ log.info((0, i18n_1.t)('未找到配置文件,将从当前目录部署云函数'));
835806
+ }
835807
+ const functionName = name || path_1.default.basename(deployDir);
835808
+ return { deployDir, functionName };
835809
+ }
835810
+ handleExistingFunction(checkResult, inferredConfig, isInferred, options, deployDir) {
835811
+ return __awaiter(this, void 0, void 0, function* () {
835812
+ const { envId, force, codeSecret, access, deployMode, yes, log } = options;
835813
+ const conflicts = this.detectConfigConflicts(inferredConfig, checkResult.functionDetail);
835814
+ if (conflicts.length > 0) {
835815
+ this.displayConfigConflicts(inferredConfig.name, conflicts);
835816
+ throw new error_1.CloudBaseError((0, i18n_1.t)('配置冲突,无法部署'));
835817
+ }
835818
+ let shouldUpdate = force || yes;
835819
+ if (!shouldUpdate) {
835820
+ shouldUpdate = yield this.confirmUpdate(inferredConfig.name);
835821
+ if (!shouldUpdate) {
835822
+ log.info((0, i18n_1.t)('已取消部署'));
835823
+ return;
835824
+ }
835825
+ }
835826
+ const mergedConfig = this.mergeCloudAndLocalConfig(checkResult.functionDetail, inferredConfig);
835827
+ log.info((0, i18n_1.t)('✓ 函数已存在,将使用以下合并配置更新:'));
835828
+ this.displayMergedConfig(inferredConfig.name, mergedConfig, isInferred ? 'inferred' : 'default');
835829
+ let finalConfig = mergedConfig;
835830
+ if (!yes) {
835831
+ const { action } = yield inquirer_1.default.prompt({
835832
+ type: 'list',
835833
+ name: 'action',
835834
+ message: (0, i18n_1.t)('请选择操作'),
835835
+ choices: [
835836
+ { name: (0, i18n_1.t)('使用合并配置更新'), value: 'update' },
835837
+ { name: (0, i18n_1.t)('手动输入配置'), value: 'manual' },
835838
+ { name: (0, i18n_1.t)('退出'), value: 'exit' }
835839
+ ]
835840
+ });
835841
+ if (action === 'exit') {
835842
+ log.info((0, i18n_1.t)('已取消部署'));
835843
+ return;
835844
+ }
835845
+ if (action === 'manual') {
835846
+ finalConfig = yield this.promptFunctionConfig(mergedConfig, options.httpFn, options.ws);
835847
+ }
835848
+ }
835849
+ return yield this.doDeploySingleFunction({
835850
+ func: finalConfig,
835851
+ envId,
835852
+ force: true,
835853
+ codeSecret,
835854
+ access,
835855
+ deployMode,
835856
+ functionRootPath: deployDir,
835857
+ functionPath: '.',
835858
+ yes,
835859
+ log,
835860
+ preCheckResult: checkResult
835009
835861
  });
835010
- if (action === 'exit') {
835011
- log.info((0, i18n_1.t)('已取消部署'));
835012
- return;
835862
+ });
835863
+ }
835864
+ handleNewFunction(inferredConfig, isInferred, options, deployDir) {
835865
+ return __awaiter(this, void 0, void 0, function* () {
835866
+ const { envId, force, codeSecret, access, deployMode, yes, log } = options;
835867
+ const sourceDesc = isInferred ? this.getConfigSourceDescription(deployDir) : (0, i18n_1.t)('默认配置');
835868
+ if (isInferred) {
835869
+ log.info((0, i18n_1.t)('✓ 从项目文件推测出以下配置:'));
835870
+ }
835871
+ else {
835872
+ log.info((0, i18n_1.t)('⚠ 未推测出配置,将使用默认配置:'));
835013
835873
  }
835014
- let func;
835015
- if (action === 'manual') {
835016
- func = yield this.promptFunctionConfig(inferredConfig, httpFn);
835874
+ this.printFunctionConfig(inferredConfig, log, sourceDesc);
835875
+ let finalConfig = inferredConfig;
835876
+ if (yes) {
835877
+ log.info((0, i18n_1.t)('🚀 --yes 模式:跳过交互,自动部署'));
835017
835878
  }
835018
835879
  else {
835019
- func = inferredConfig;
835880
+ const { action } = yield inquirer_1.default.prompt({
835881
+ type: 'list',
835882
+ name: 'action',
835883
+ message: (0, i18n_1.t)('请选择操作'),
835884
+ choices: [
835885
+ { name: (0, i18n_1.t)('使用当前配置部署'), value: 'deploy' },
835886
+ { name: (0, i18n_1.t)('手动输入配置'), value: 'manual' },
835887
+ { name: (0, i18n_1.t)('退出'), value: 'exit' }
835888
+ ]
835889
+ });
835890
+ if (action === 'exit') {
835891
+ log.info((0, i18n_1.t)('已取消部署'));
835892
+ return;
835893
+ }
835894
+ if (action === 'manual') {
835895
+ finalConfig = yield this.promptFunctionConfig(inferredConfig, options.httpFn, options.ws);
835896
+ }
835020
835897
  }
835021
- return this.doDeploySingleFunction({
835022
- func, envId, force, codeSecret, access, deployMode,
835023
- functionRootPath: deployDir, functionPath: '.', log
835898
+ return yield this.doDeploySingleFunction({
835899
+ func: finalConfig,
835900
+ envId,
835901
+ force,
835902
+ codeSecret,
835903
+ access,
835904
+ deployMode,
835905
+ functionRootPath: deployDir,
835906
+ functionPath: '.',
835907
+ yes,
835908
+ log
835024
835909
  });
835025
835910
  });
835026
835911
  }
835027
835912
  inferFunctionConfig(httpFn, deployDir) {
835028
835913
  const targetDir = deployDir || process.cwd();
835029
- const packageJsonPath = path_1.default.join(targetDir, 'package.json');
835030
- if (!fs_1.default.existsSync(packageJsonPath)) {
835031
- return null;
835032
- }
835033
- try {
835034
- const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
835035
- if (!packageJson.name) {
835036
- return null;
835037
- }
835038
- let handler = constant_1.DefaultFunctionDeployConfig.handler;
835039
- if (packageJson.main) {
835040
- const mainFile = path_1.default.basename(packageJson.main).replace(/\.[^.]+$/, '');
835041
- handler = `${mainFile}.main`;
835042
- }
835043
- return Object.assign(Object.assign(Object.assign({ name: packageJson.name }, constant_1.DefaultFunctionDeployConfig), { handler }), (httpFn ? { type: 'HTTP' } : {}));
835044
- }
835045
- catch (e) {
835046
- return null;
835047
- }
835914
+ const result = (0, function_1.inferFunctionConfig)({ targetDir, httpFn });
835915
+ return (result === null || result === void 0 ? void 0 : result.config) || null;
835048
835916
  }
835049
- promptFunctionConfig(defaultConfig, httpFn) {
835917
+ promptFunctionConfig(defaultConfig, httpFn, ws) {
835050
835918
  var _a, _b, _c;
835051
835919
  return __awaiter(this, void 0, void 0, function* () {
835920
+ const isHttpFnFromCli = httpFn || ws;
835921
+ const isWsFromCli = ws;
835052
835922
  const answers = yield inquirer_1.default.prompt([
835053
835923
  {
835054
835924
  type: 'input',
@@ -835077,62 +835947,49 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835077
835947
  name: 'handler',
835078
835948
  message: (0, i18n_1.t)('入口函数(格式:文件名.函数名)'),
835079
835949
  default: (answers) => {
835950
+ if (defaultConfig.handler) {
835951
+ return defaultConfig.handler;
835952
+ }
835080
835953
  const selectedRuntime = constant_1.RuntimeOptions.find(r => r.value === answers.runtime);
835081
- return (selectedRuntime === null || selectedRuntime === void 0 ? void 0 : selectedRuntime.handler) || defaultConfig.handler;
835954
+ return (selectedRuntime === null || selectedRuntime === void 0 ? void 0 : selectedRuntime.handler) || constant_1.DefaultFunctionDeployConfig.handler;
835082
835955
  }
835083
835956
  },
835084
835957
  {
835085
835958
  type: 'confirm',
835086
835959
  name: 'isHttpFn',
835087
835960
  message: (0, i18n_1.t)('是否为 HTTP 函数'),
835088
- default: httpFn || defaultConfig.type === 'HTTP',
835089
- when: !httpFn
835961
+ default: isHttpFnFromCli || defaultConfig.type === 'HTTP',
835962
+ when: !isHttpFnFromCli
835090
835963
  },
835091
835964
  {
835092
835965
  type: 'confirm',
835093
835966
  name: 'enableWebSocket',
835094
835967
  message: (0, i18n_1.t)('是否支持 WebSocket 协议'),
835095
- default: defaultConfig.protocolType === 'WS',
835096
- when: (answers) => httpFn || answers.isHttpFn
835968
+ default: isWsFromCli || defaultConfig.protocolType === 'WS',
835969
+ when: (answers) => !isWsFromCli && (isHttpFnFromCli || answers.isHttpFn)
835097
835970
  },
835098
835971
  {
835099
835972
  type: 'number',
835100
835973
  name: 'timeout',
835101
835974
  message: (answers) => {
835102
- const isWs = answers.enableWebSocket;
835975
+ const isWs = isWsFromCli || answers.enableWebSocket;
835103
835976
  return isWs ? (0, i18n_1.t)('超时时间(秒,1-7200)') : (0, i18n_1.t)('超时时间(秒,1-900)');
835104
835977
  },
835105
835978
  default: defaultConfig.timeout,
835106
- validate: (input, answers) => {
835107
- const num = Number(input);
835108
- const isWs = answers.enableWebSocket;
835109
- const maxTimeout = isWs ? 7200 : 900;
835110
- if (isNaN(num) || num < 1 || num > maxTimeout) {
835111
- return isWs ? (0, i18n_1.t)('超时时间必须在 1-7200 秒之间') : (0, i18n_1.t)('超时时间必须在 1-900 秒之间');
835112
- }
835113
- return true;
835114
- }
835115
835979
  },
835116
835980
  {
835117
835981
  type: 'number',
835118
835982
  name: 'idleTimeOut',
835119
835983
  message: (0, i18n_1.t)('空闲超时时间(秒,10-7200,默认15)'),
835120
835984
  default: ((_b = (_a = defaultConfig.protocolParams) === null || _a === void 0 ? void 0 : _a.wsParams) === null || _b === void 0 ? void 0 : _b.idleTimeOut) || 15,
835121
- when: (answers) => answers.enableWebSocket,
835122
- validate: (input) => {
835123
- const num = Number(input);
835124
- if (isNaN(num) || num < 10 || num > 7200) {
835125
- return (0, i18n_1.t)('空闲超时时间必须在 10-7200 秒之间');
835126
- }
835127
- return true;
835128
- }
835985
+ when: (answers) => isWsFromCli || answers.enableWebSocket,
835129
835986
  },
835130
835987
  {
835131
835988
  type: 'confirm',
835132
835989
  name: 'enableInstanceConcurrency',
835133
835990
  message: (0, i18n_1.t)('是否启用多并发'),
835134
835991
  default: !!defaultConfig.instanceConcurrencyConfig,
835135
- when: (answers) => httpFn || answers.isHttpFn
835992
+ when: (answers) => isHttpFnFromCli || answers.isHttpFn
835136
835993
  },
835137
835994
  {
835138
835995
  type: 'number',
@@ -835168,15 +836025,16 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835168
836025
  default: defaultConfig.installDependency
835169
836026
  }
835170
836027
  ]);
835171
- const protocolType = answers.enableWebSocket ? 'WS' : undefined;
835172
- const protocolParams = answers.idleTimeOut ? {
836028
+ const enableWs = isWsFromCli || answers.enableWebSocket;
836029
+ const protocolType = enableWs ? 'WS' : undefined;
836030
+ const protocolParams = (enableWs && answers.idleTimeOut) ? {
835173
836031
  wsParams: { idleTimeOut: answers.idleTimeOut }
835174
836032
  } : undefined;
835175
836033
  const instanceConcurrencyConfig = answers.enableInstanceConcurrency ? {
835176
836034
  dynamicEnabled: 'FALSE',
835177
836035
  maxConcurrency: answers.maxConcurrency
835178
836036
  } : undefined;
835179
- return Object.assign(Object.assign(Object.assign(Object.assign({ name: answers.name.trim(), runtime: answers.runtime, handler: answers.handler, timeout: answers.timeout, memorySize: answers.memorySize, installDependency: answers.installDependency, ignore: defaultConfig.ignore || constant_1.DefaultFunctionDeployConfig.ignore }, (httpFn || answers.isHttpFn ? { type: 'HTTP' } : {})), (protocolType ? { protocolType } : {})), (protocolParams ? { protocolParams } : {})), (instanceConcurrencyConfig ? { instanceConcurrencyConfig } : {}));
836037
+ return Object.assign(Object.assign(Object.assign(Object.assign({ name: answers.name.trim(), runtime: answers.runtime, handler: answers.handler, timeout: answers.timeout, memorySize: answers.memorySize, installDependency: answers.installDependency, ignore: defaultConfig.ignore || constant_1.DefaultFunctionDeployConfig.ignore }, (isHttpFnFromCli || answers.isHttpFn ? { type: 'HTTP' } : {})), (protocolType ? { protocolType } : {})), (protocolParams ? { protocolParams } : {})), (instanceConcurrencyConfig ? { instanceConcurrencyConfig } : {}));
835180
836038
  });
835181
836039
  }
835182
836040
  promptFunctionName() {
@@ -835195,8 +836053,11 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835195
836053
  return funcName.trim();
835196
836054
  });
835197
836055
  }
835198
- printFunctionConfig(func, log) {
836056
+ printFunctionConfig(func, log, source) {
835199
836057
  var _a, _b;
836058
+ if (source) {
836059
+ log.info((0, i18n_1.t)('配置来源:{{source}}', { source }));
836060
+ }
835200
836061
  log.info((0, i18n_1.t)(' - 函数名称:{{name}}', { name: func.name }));
835201
836062
  log.info((0, i18n_1.t)(' - 运行时:{{runtime}}', { runtime: func.runtime }));
835202
836063
  log.info((0, i18n_1.t)(' - 入口函数:{{handler}}', { handler: func.handler }));
@@ -835219,10 +836080,65 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835219
836080
  log.info((0, i18n_1.t)(' - 单实例最大并发数:{{num}}', { num: func.instanceConcurrencyConfig.maxConcurrency }));
835220
836081
  }
835221
836082
  }
836083
+ else {
836084
+ log.info((0, i18n_1.t)(' - 函数类型:Event(事件触发)'));
836085
+ }
836086
+ if (func.envVariables && Object.keys(func.envVariables).length > 0) {
836087
+ log.info((0, i18n_1.t)(' - 环境变量:{{count}} 个', { count: Object.keys(func.envVariables).length }));
836088
+ }
836089
+ if (func.vpc) {
836090
+ log.info((0, i18n_1.t)(' - VPC 配置:已配置'));
836091
+ }
836092
+ }
836093
+ getConfigSourceDescription(targetDir) {
836094
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'package.json'))) {
836095
+ return (0, i18n_1.t)('Node.js 项目(package.json)');
836096
+ }
836097
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'requirements.txt'))) {
836098
+ return (0, i18n_1.t)('Python 项目(requirements.txt)');
836099
+ }
836100
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'setup.py'))) {
836101
+ return (0, i18n_1.t)('Python 项目(setup.py)');
836102
+ }
836103
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'pyproject.toml'))) {
836104
+ return (0, i18n_1.t)('Python 项目(pyproject.toml)');
836105
+ }
836106
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'composer.json'))) {
836107
+ return (0, i18n_1.t)('PHP 项目(composer.json)');
836108
+ }
836109
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'pom.xml'))) {
836110
+ return (0, i18n_1.t)('Java 项目(pom.xml)');
836111
+ }
836112
+ if (fs_1.default.existsSync(path_1.default.join(targetDir, 'build.gradle'))) {
836113
+ return (0, i18n_1.t)('Java 项目(build.gradle)');
836114
+ }
836115
+ try {
836116
+ const files = fs_1.default.readdirSync(targetDir);
836117
+ const fileTypes = {
836118
+ js: files.filter(f => f.endsWith('.js')).length,
836119
+ ts: files.filter(f => f.endsWith('.ts')).length,
836120
+ py: files.filter(f => f.endsWith('.py')).length,
836121
+ php: files.filter(f => f.endsWith('.php')).length,
836122
+ java: files.filter(f => f.endsWith('.java')).length
836123
+ };
836124
+ const maxType = Object.entries(fileTypes).reduce((a, b) => fileTypes[a[0]] > fileTypes[b[0]] ? a : b);
836125
+ if (maxType[1] > 0) {
836126
+ switch (maxType[0]) {
836127
+ case 'js': return (0, i18n_1.t)('JavaScript 文件推测');
836128
+ case 'ts': return (0, i18n_1.t)('TypeScript 文件推测');
836129
+ case 'py': return (0, i18n_1.t)('Python 文件推测');
836130
+ case 'php': return (0, i18n_1.t)('PHP 文件推测');
836131
+ case 'java': return (0, i18n_1.t)('Java 文件推测');
836132
+ }
836133
+ }
836134
+ }
836135
+ catch (e) {
836136
+ }
836137
+ return (0, i18n_1.t)('默认配置');
835222
836138
  }
835223
836139
  doDeploySingleFunction(options) {
835224
836140
  return __awaiter(this, void 0, void 0, function* () {
835225
- const { func, envId, force, codeSecret, access, deployMode, functionRootPath, functionPath, log } = options;
836141
+ const { func, envId, force, codeSecret, access, deployMode, functionRootPath, functionPath, yes, log, preCheckResult } = options;
835226
836142
  if (func.type === 'HTTP') {
835227
836143
  const funcPath = functionPath === '.' ? process.cwd() : (functionPath || path_1.default.join(functionRootPath, func.name));
835228
836144
  const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(funcPath, func);
@@ -835256,7 +836172,9 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835256
836172
  func,
835257
836173
  accessPath: access,
835258
836174
  functionPath,
835259
- logger: log
836175
+ yes,
836176
+ logger: log,
836177
+ preCheckResult
835260
836178
  });
835261
836179
  }
835262
836180
  if (access || func.path) {
@@ -835267,7 +836185,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835267
836185
  }
835268
836186
  deployAllFunction(options) {
835269
836187
  return __awaiter(this, void 0, void 0, function* () {
835270
- let { functions = [], envId, force, codeSecret, functionRootPath, all, access, httpFn, ws, deployMode, log } = options;
836188
+ let { functions = [], envId, force, codeSecret, functionRootPath, all, access, httpFn, ws, deployMode, yes, log } = options;
835271
836189
  if (!functions || functions.length === 0) {
835272
836190
  functions = this.scanFunctionDirectory(functionRootPath, httpFn);
835273
836191
  if (functions.length > 0) {
@@ -835284,7 +836202,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835284
836202
  throw new error_1.CloudBaseError((0, i18n_1.t)('未找到云函数配置,请在 cloudbaserc.json 中配置 functions 字段,或使用 tcb fn deploy <函数名> 指定要部署的函数'));
835285
836203
  }
835286
836204
  let selectedFunctions = functions;
835287
- if (!all) {
836205
+ if (!all && !yes) {
835288
836206
  const choices = functions.map((func) => ({
835289
836207
  name: `${func.name}${func.type === 'HTTP' ? ' (HTTP)' : ''}${func.protocolType === 'WS' ? ' (WS)' : ''}`,
835290
836208
  value: func.name,
@@ -835317,7 +836235,60 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835317
836235
  throw new error_1.CloudBaseError((0, i18n_1.t)('没有选择任何云函数'));
835318
836236
  }
835319
836237
  }
836238
+ else if (yes) {
836239
+ log.info((0, i18n_1.t)('🚀 --yes 模式:自动部署全部 {{count}} 个函数', { count: functions.length }));
836240
+ }
835320
836241
  const loading = (0, utils_1.loadingFactory)();
836242
+ let functionsToOverwrite = new Set();
836243
+ if (!force && !yes) {
836244
+ loading.start((0, i18n_1.t)('正在检查云函数状态...'));
836245
+ const functionService = yield (0, function_2.getFunctionService)(envId);
836246
+ const existingFunctions = [];
836247
+ const checkTasks = selectedFunctions.map((func) => __awaiter(this, void 0, void 0, function* () {
836248
+ try {
836249
+ const detail = yield functionService.getFunctionDetail(func.name, codeSecret);
836250
+ if (detail) {
836251
+ return func.name;
836252
+ }
836253
+ }
836254
+ catch (e) {
836255
+ }
836256
+ return null;
836257
+ }));
836258
+ const checkResults = yield Promise.all(checkTasks);
836259
+ checkResults.forEach(name => {
836260
+ if (name)
836261
+ existingFunctions.push(name);
836262
+ });
836263
+ loading.stop();
836264
+ if (existingFunctions.length > 0) {
836265
+ log.info((0, i18n_1.t)('发现 {{count}} 个已存在的云函数:', { count: existingFunctions.length }));
836266
+ existingFunctions.forEach(name => {
836267
+ log.info(` - ${name}`);
836268
+ });
836269
+ const { toOverwrite } = yield inquirer_1.default.prompt({
836270
+ type: 'checkbox',
836271
+ name: 'toOverwrite',
836272
+ message: (0, i18n_1.t)('请选择要覆盖更新的函数(未选中的将跳过部署)'),
836273
+ choices: existingFunctions.map(name => ({
836274
+ name,
836275
+ value: name,
836276
+ checked: true
836277
+ }))
836278
+ });
836279
+ functionsToOverwrite = new Set(toOverwrite);
836280
+ const skippedByUser = existingFunctions.filter(name => !functionsToOverwrite.has(name));
836281
+ if (skippedByUser.length > 0) {
836282
+ log.info((0, i18n_1.t)('以下函数将跳过部署:{{names}}', { names: skippedByUser.join(', ') }));
836283
+ }
836284
+ }
836285
+ }
836286
+ else if (force) {
836287
+ log.verbose((0, i18n_1.t)('--force 模式:将自动覆盖所有已存在的函数'));
836288
+ }
836289
+ else if (yes) {
836290
+ log.verbose((0, i18n_1.t)('--yes 模式:将自动覆盖所有已存在的函数'));
836291
+ }
835321
836292
  const tasks = selectedFunctions.map((func) => () => __awaiter(this, void 0, void 0, function* () {
835322
836293
  let funcWithType = httpFn ? Object.assign(Object.assign({}, func), { type: 'HTTP' }) : func;
835323
836294
  if (ws) {
@@ -835328,13 +836299,13 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835328
836299
  : path_1.default.join(functionRootPath, func.name);
835329
836300
  if (!fs_1.default.existsSync(funcPath)) {
835330
836301
  log.error((0, i18n_1.t)('未找到函数 [{{name}}] 的目录:{{path}},已跳过', { name: func.name, path: funcPath }));
835331
- return;
836302
+ return { status: 'skipped', name: func.name };
835332
836303
  }
835333
836304
  if (funcWithType.type === 'HTTP') {
835334
836305
  const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(funcPath, funcWithType);
835335
836306
  if (!shouldContinue) {
835336
836307
  log.warn((0, i18n_1.t)('[{{name}}] 已跳过部署', { name: func.name }));
835337
- return;
836308
+ return { status: 'skipped', name: func.name };
835338
836309
  }
835339
836310
  }
835340
836311
  loading.start((0, i18n_1.t)('云函数部署中'));
@@ -835350,19 +836321,28 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835350
836321
  deployMode
835351
836322
  });
835352
836323
  loading.succeed((0, i18n_1.t)('[{{name}}] 云函数部署成功', { name: func.name }));
836324
+ return { status: 'success', name: func.name };
835353
836325
  }
835354
836326
  catch (e) {
835355
836327
  loading.stop();
835356
- yield this.handleDeployFail(e, {
835357
- func: funcWithType,
835358
- envId,
835359
- force,
835360
- codeSecret,
835361
- functionRootPath,
835362
- functionPath: func.dir ? funcPath : undefined,
835363
- accessPath: access,
835364
- logger: log
835365
- });
836328
+ try {
836329
+ const result = yield this.handleDeployFail(e, {
836330
+ func: funcWithType,
836331
+ envId,
836332
+ force,
836333
+ codeSecret,
836334
+ functionRootPath,
836335
+ functionPath: func.dir ? funcPath : undefined,
836336
+ accessPath: access,
836337
+ yes: yes || force || functionsToOverwrite.has(func.name),
836338
+ batchMode: true,
836339
+ logger: log
836340
+ });
836341
+ return { status: result || 'error', name: func.name };
836342
+ }
836343
+ catch (handleError) {
836344
+ return { status: 'error', name: func.name, error: handleError };
836345
+ }
835366
836346
  }
835367
836347
  }));
835368
836348
  if (tasks.length > 5) {
@@ -835370,51 +836350,111 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835370
836350
  }
835371
836351
  const asyncTaskController = new utils_1.AsyncTaskParallelController(5, 50);
835372
836352
  asyncTaskController.loadTasks(tasks);
835373
- const results = yield asyncTaskController.run();
835374
- const success = results.filter((_) => !_);
835375
- log.success((0, i18n_1.t)('成功部署 {{count}} 个函数', { count: success === null || success === void 0 ? void 0 : success.length }));
835376
- const errors = results.filter((_) => _);
835377
- if (errors === null || errors === void 0 ? void 0 : errors.length) {
835378
- log.error((0, i18n_1.t)('{{count}} 个云函数部署失败', { count: errors === null || errors === void 0 ? void 0 : errors.length }));
835379
- errors.forEach((err) => {
835380
- if (err === null || err === void 0 ? void 0 : err.message) {
835381
- log.error(` - ${err.message}`);
836353
+ const rawResults = yield asyncTaskController.run();
836354
+ const results = rawResults.map((r, index) => {
836355
+ var _a;
836356
+ if (r instanceof Error) {
836357
+ return { status: 'error', name: ((_a = selectedFunctions[index]) === null || _a === void 0 ? void 0 : _a.name) || 'unknown', error: r };
836358
+ }
836359
+ return r;
836360
+ });
836361
+ const successCount = results.filter(r => (r === null || r === void 0 ? void 0 : r.status) === 'success').length;
836362
+ const skippedCount = results.filter(r => (r === null || r === void 0 ? void 0 : r.status) === 'skipped').length;
836363
+ const cancelledCount = results.filter(r => (r === null || r === void 0 ? void 0 : r.status) === 'cancelled').length;
836364
+ const errorCount = results.filter(r => (r === null || r === void 0 ? void 0 : r.status) === 'error').length;
836365
+ if (successCount > 0) {
836366
+ log.success((0, i18n_1.t)('成功部署 {{count}} 个函数', { count: successCount }));
836367
+ }
836368
+ if (skippedCount > 0) {
836369
+ log.warn((0, i18n_1.t)('跳过 {{count}} 个函数', { count: skippedCount }));
836370
+ }
836371
+ if (cancelledCount > 0) {
836372
+ log.info((0, i18n_1.t)('取消部署 {{count}} 个函数', { count: cancelledCount }));
836373
+ }
836374
+ if (errorCount > 0) {
836375
+ log.error((0, i18n_1.t)('{{count}} 个云函数部署失败', { count: errorCount }));
836376
+ let envNotFoundError = null;
836377
+ const stackIgnoreErrors = ['TencentCloudSDKHttpException', 'CloudBaseError'];
836378
+ results.filter(r => (r === null || r === void 0 ? void 0 : r.status) === 'error').forEach((r) => {
836379
+ var _a, _b;
836380
+ if (r === null || r === void 0 ? void 0 : r.error) {
836381
+ const err = r.error;
836382
+ log.error(` - [${r.name}] ${err.message || err}`);
836383
+ if (err.requestId) {
836384
+ log.error(` requestId: ${err.requestId}`);
836385
+ }
836386
+ if (err.stack && !stackIgnoreErrors.includes(err.name)) {
836387
+ const stackLines = err.stack.split('\n').slice(1, 6);
836388
+ stackLines.forEach(line => log.error(` ${line.trim()}`));
836389
+ }
836390
+ if (((_a = err.message) === null || _a === void 0 ? void 0 : _a.includes('Environment')) && ((_b = err.message) === null || _b === void 0 ? void 0 : _b.includes('not found')) && !envNotFoundError) {
836391
+ envNotFoundError = err;
836392
+ }
835382
836393
  }
835383
836394
  });
836395
+ if (envNotFoundError) {
836396
+ throw envNotFoundError;
836397
+ }
836398
+ }
836399
+ if (successCount === 0 && errorCount === 0 && skippedCount === 0 && cancelledCount === 0) {
836400
+ log.info((0, i18n_1.t)('没有函数被部署'));
835384
836401
  }
835385
836402
  });
835386
836403
  }
835387
836404
  handleDeployFail(e, options) {
836405
+ var _a;
835388
836406
  return __awaiter(this, void 0, void 0, function* () {
835389
- const { envId, codeSecret, functionRootPath, func: originalFunc, functionPath, accessPath, force: forceOverwrite, logger: log } = options;
836407
+ const { envId, codeSecret, functionRootPath, func: originalFunc, functionPath, accessPath, force: forceOverwrite, yes, batchMode, logger: log, preCheckResult } = options;
835390
836408
  let func = originalFunc;
835391
836409
  const loading = (0, utils_1.loadingFactory)();
835392
- if (e.code === 'ResourceInUse.FunctionName' || e.code === 'ResourceInUse.Function') {
835393
- const functionService = yield (0, function_2.getFunctionService)(envId);
835394
- const existingFunction = yield functionService.getFunctionDetail(func.name, codeSecret);
835395
- const existingType = (existingFunction === null || existingFunction === void 0 ? void 0 : existingFunction.Type) || 'Event';
835396
- const newType = func.type || existingType;
835397
- if (func.type && existingType !== newType) {
835398
- (log || utils_1.logger).error((0, i18n_1.t)('不支持变更函数类型:云端函数 [{{name}}] 类型为 {{existingType}},无法变更为 {{newType}}', {
835399
- name: func.name,
835400
- existingType,
835401
- newType
835402
- }));
835403
- return;
836410
+ const isResourceInUseError = e.code === 'ResourceInUse.FunctionName'
836411
+ || e.code === 'ResourceInUse.Function'
836412
+ || (e.message && e.message.includes('ResourceInUse.FunctionName'))
836413
+ || (e.message && e.message.includes('ResourceInUse.Function'));
836414
+ if (!isResourceInUseError) {
836415
+ this.displayFriendlyError(e, {
836416
+ functionName: func.name,
836417
+ operation: '函数部署'
836418
+ }, log);
836419
+ return 'error';
836420
+ }
836421
+ if (isResourceInUseError) {
836422
+ let existingFunction;
836423
+ if (preCheckResult && preCheckResult.exists && preCheckResult.functionDetail) {
836424
+ existingFunction = preCheckResult.functionDetail;
836425
+ (_a = log === null || log === void 0 ? void 0 : log.verbose) === null || _a === void 0 ? void 0 : _a.call(log, (0, i18n_1.t)('复用前置检测结果,避免重复 API 调用'));
835404
836426
  }
836427
+ else {
836428
+ try {
836429
+ const functionService = yield (0, function_2.getFunctionService)(envId);
836430
+ existingFunction = (yield functionService.getFunctionDetail(func.name, codeSecret));
836431
+ }
836432
+ catch (detailError) {
836433
+ this.displayFriendlyError(detailError, {
836434
+ functionName: func.name,
836435
+ operation: '获取函数详情'
836436
+ }, log);
836437
+ return 'error';
836438
+ }
836439
+ }
836440
+ const conflicts = this.detectConfigConflicts(func, existingFunction);
836441
+ if (conflicts.length > 0) {
836442
+ this.displayConfigConflicts(func.name, conflicts);
836443
+ return 'error';
836444
+ }
836445
+ func = this.mergeCloudAndLocalConfig(existingFunction, func);
836446
+ const existingType = (existingFunction === null || existingFunction === void 0 ? void 0 : existingFunction.Type) || 'Event';
835405
836447
  const existingProtocolType = (existingFunction === null || existingFunction === void 0 ? void 0 : existingFunction.ProtocolType) || '';
835406
- const newProtocolType = func.protocolType !== undefined ? func.protocolType : existingProtocolType;
835407
- if (func.protocolType !== undefined && existingProtocolType !== newProtocolType) {
835408
- (log || utils_1.logger).error((0, i18n_1.t)('不支持变更协议类型:云端函数 [{{name}}] 协议类型为 {{existingProtocolType}},本地配置为 {{newProtocolType}},协议类型仅支持在创建函数时设置', {
835409
- name: func.name,
835410
- existingProtocolType: existingProtocolType || '无',
835411
- newProtocolType: newProtocolType || '无'
835412
- }));
835413
- return;
836448
+ const localTypeDisplay = originalFunc.type || (0, i18n_1.t)('未指定');
836449
+ const cloudTypeDisplay = existingType === 'HTTP' ? 'HTTP' : 'Event';
836450
+ if (!originalFunc.type && existingType) {
836451
+ (log || utils_1.logger).info((0, i18n_1.t)('ℹ 本地配置未指定函数类型,将保持云端类型:{{cloudType}}', { cloudType: cloudTypeDisplay }));
836452
+ }
836453
+ if (!originalFunc.protocolType && existingProtocolType) {
836454
+ (log || utils_1.logger).info((0, i18n_1.t)('ℹ 本地配置未指定协议类型,将保持云端协议:{{protocolType}}', { protocolType: existingProtocolType }));
835414
836455
  }
835415
- func = Object.assign(Object.assign({}, func), { type: newType, protocolType: newProtocolType || undefined });
835416
- let shouldForce = forceOverwrite;
835417
- if (!shouldForce) {
836456
+ let shouldForce = forceOverwrite || yes;
836457
+ if (!shouldForce && !batchMode) {
835418
836458
  const answer = yield inquirer_1.default.prompt({
835419
836459
  type: 'confirm',
835420
836460
  name: 'force',
@@ -835423,9 +836463,12 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835423
836463
  });
835424
836464
  shouldForce = answer.force;
835425
836465
  }
835426
- const { triggers } = func;
836466
+ else if (!shouldForce && batchMode) {
836467
+ (log || utils_1.logger).info((0, i18n_1.t)('[{{name}}] 已跳过部署', { name: func.name }));
836468
+ return 'cancelled';
836469
+ }
835427
836470
  if (shouldForce) {
835428
- loading.start((0, i18n_1.t)('云函数更新部署中...'));
836471
+ loading.start(batchMode ? (0, i18n_1.t)('云函数 [{{name}}] 更新部署中...', { name: func.name }) : (0, i18n_1.t)('云函数更新部署中...'));
835429
836472
  try {
835430
836473
  yield (0, function_2.updateFunctionCode)({
835431
836474
  func,
@@ -835436,7 +836479,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835436
836479
  });
835437
836480
  const success = yield this.waitForFunctionReady(envId, func.name, loading);
835438
836481
  if (!success) {
835439
- return;
836482
+ return 'error';
835440
836483
  }
835441
836484
  loading.succeed((0, i18n_1.t)('[{{name}}] 云函数配置更新中...', { name: func.name }));
835442
836485
  yield (0, function_2.updateFunctionConfig)({
@@ -835445,7 +836488,10 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835445
836488
  config: func
835446
836489
  });
835447
836490
  loading.succeed((0, i18n_1.t)('[{{name}}] 云函数更新成功!', { name: func.name }));
835448
- yield this.printSuccessTips(envId);
836491
+ if (!batchMode) {
836492
+ yield this.printSuccessTips(envId);
836493
+ }
836494
+ return 'success';
835449
836495
  }
835450
836496
  catch (e) {
835451
836497
  loading.stop();
@@ -835453,9 +836499,9 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835453
836499
  }
835454
836500
  }
835455
836501
  else {
835456
- (log || utils_1.logger).info((0, i18n_1.t)('已取消部署'));
836502
+ (log || utils_1.logger).info(batchMode ? (0, i18n_1.t)('[{{name}}] 已跳过部署', { name: func.name }) : (0, i18n_1.t)('已取消部署'));
836503
+ return 'cancelled';
835457
836504
  }
835458
- return;
835459
836505
  }
835460
836506
  throw e;
835461
836507
  });
@@ -835573,6 +836619,284 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
835573
836619
  return runtime;
835574
836620
  });
835575
836621
  }
836622
+ getDefaultRuntime(targetDir) {
836623
+ var _a;
836624
+ return __awaiter(this, void 0, void 0, function* () {
836625
+ const dir = targetDir || process.cwd();
836626
+ if (fs_1.default.existsSync(path_1.default.join(dir, 'package.json'))) {
836627
+ try {
836628
+ const packageJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(dir, 'package.json'), 'utf-8'));
836629
+ if ((_a = packageJson.engines) === null || _a === void 0 ? void 0 : _a.node) {
836630
+ const nodeVersion = packageJson.engines.node;
836631
+ if (nodeVersion.includes('20'))
836632
+ return 'Nodejs20.19';
836633
+ if (nodeVersion.includes('16'))
836634
+ return 'Nodejs16.13';
836635
+ }
836636
+ }
836637
+ catch (e) {
836638
+ }
836639
+ return constant_1.DefaultFunctionDeployConfig.runtime;
836640
+ }
836641
+ const pythonFiles = ['requirements.txt', 'setup.py', 'pyproject.toml'];
836642
+ if (pythonFiles.some(file => fs_1.default.existsSync(path_1.default.join(dir, file)))) {
836643
+ return 'Python3.9';
836644
+ }
836645
+ if (fs_1.default.existsSync(path_1.default.join(dir, 'composer.json')) ||
836646
+ fs_1.default.readdirSync(dir).some(file => file.endsWith('.php'))) {
836647
+ return 'Php8.0';
836648
+ }
836649
+ const javaFiles = ['pom.xml', 'build.gradle', 'build.gradle.kts'];
836650
+ if (javaFiles.some(file => fs_1.default.existsSync(path_1.default.join(dir, file)))) {
836651
+ return 'Java11';
836652
+ }
836653
+ try {
836654
+ const files = fs_1.default.readdirSync(dir);
836655
+ const fileTypes = {
836656
+ js: files.filter(f => f.endsWith('.js')).length,
836657
+ ts: files.filter(f => f.endsWith('.ts')).length,
836658
+ py: files.filter(f => f.endsWith('.py')).length,
836659
+ php: files.filter(f => f.endsWith('.php')).length,
836660
+ java: files.filter(f => f.endsWith('.java')).length
836661
+ };
836662
+ const maxType = Object.entries(fileTypes).reduce((a, b) => fileTypes[a[0]] > fileTypes[b[0]] ? a : b);
836663
+ switch (maxType[0]) {
836664
+ case 'py': return 'Python3.9';
836665
+ case 'php': return 'Php8.0';
836666
+ case 'java': return 'Java11';
836667
+ default: return constant_1.DefaultFunctionDeployConfig.runtime;
836668
+ }
836669
+ }
836670
+ catch (e) {
836671
+ return constant_1.DefaultFunctionDeployConfig.runtime;
836672
+ }
836673
+ });
836674
+ }
836675
+ checkCloudFunction(functionName, envId, codeSecret) {
836676
+ var _a, _b;
836677
+ return __awaiter(this, void 0, void 0, function* () {
836678
+ try {
836679
+ const functionService = yield (0, function_2.getFunctionService)(envId);
836680
+ const detail = yield functionService.getFunctionDetail(functionName, codeSecret);
836681
+ return {
836682
+ exists: true,
836683
+ functionDetail: detail,
836684
+ checkTime: Date.now(),
836685
+ uncertain: false
836686
+ };
836687
+ }
836688
+ catch (error) {
836689
+ if (error.code === 'ResourceNotFound.Function' ||
836690
+ error.code === 'ResourceNotFound' ||
836691
+ ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('does not exist')) ||
836692
+ ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('not found'))) {
836693
+ return { exists: false, uncertain: false };
836694
+ }
836695
+ if (error.code === 'ENOTFOUND' || error.code === 'ECONNRESET' ||
836696
+ error.code === 'ETIMEDOUT' || error.code === 'NetworkError' ||
836697
+ error.code === 'Forbidden' || error.code === 'Unauthorized' ||
836698
+ error.code === 'AuthFailure' || error.code === 'UnauthorizedOperation') {
836699
+ return { exists: false, uncertain: true, error };
836700
+ }
836701
+ throw error;
836702
+ }
836703
+ });
836704
+ }
836705
+ checkBatchFunctions(functionNames, envId, codeSecret) {
836706
+ return __awaiter(this, void 0, void 0, function* () {
836707
+ const checkTasks = functionNames.map((name) => __awaiter(this, void 0, void 0, function* () {
836708
+ try {
836709
+ const result = yield this.checkCloudFunction(name, envId, codeSecret);
836710
+ return Object.assign({ name }, result);
836711
+ }
836712
+ catch (error) {
836713
+ return {
836714
+ name,
836715
+ exists: false,
836716
+ uncertain: true,
836717
+ error
836718
+ };
836719
+ }
836720
+ }));
836721
+ const results = yield Promise.all(checkTasks);
836722
+ const existing = results.filter((r) => r.exists).map((r) => ({
836723
+ name: r.name,
836724
+ detail: r.functionDetail
836725
+ }));
836726
+ const missing = results.filter((r) => !r.exists && !r.uncertain).map((r) => ({
836727
+ name: r.name
836728
+ }));
836729
+ const uncertain = results.filter((r) => r.uncertain).map((r) => ({
836730
+ name: r.name,
836731
+ error: r.error
836732
+ }));
836733
+ return { existing, missing, uncertain, totalChecked: results.length };
836734
+ });
836735
+ }
836736
+ detectConfigConflicts(localConfig, cloudConfig) {
836737
+ const conflicts = [];
836738
+ const immutableFields = [
836739
+ { local: 'type', cloud: 'Type', name: '函数类型' },
836740
+ { local: 'protocolType', cloud: 'ProtocolType', name: '协议类型' }
836741
+ ];
836742
+ immutableFields.forEach(field => {
836743
+ const localValue = localConfig[field.local];
836744
+ const cloudValue = cloudConfig[field.cloud];
836745
+ if (localValue && cloudValue && localValue !== cloudValue) {
836746
+ conflicts.push({
836747
+ field: field.name,
836748
+ localValue,
836749
+ cloudValue,
836750
+ severity: 'error',
836751
+ message: `${field.name}不匹配,无法更新`
836752
+ });
836753
+ }
836754
+ });
836755
+ return conflicts;
836756
+ }
836757
+ mergeCloudAndLocalConfig(cloudFunction, localConfig) {
836758
+ return Object.assign(Object.assign({}, localConfig), { type: cloudFunction.Type || localConfig.type, protocolType: cloudFunction.ProtocolType || localConfig.protocolType });
836759
+ }
836760
+ checkDirectoryExists(functionPath) {
836761
+ return fs_1.default.existsSync(functionPath) && fs_1.default.statSync(functionPath).isDirectory();
836762
+ }
836763
+ displayFriendlyError(error, context = {}, log) {
836764
+ const logger = log || (__webpack_require__(82079).logger);
836765
+ const { functionName, operation = '操作' } = context;
836766
+ const errorPrefix = functionName ? `[${functionName}] ` : '';
836767
+ logger.error(`${errorPrefix}${operation}失败`);
836768
+ if (error.message) {
836769
+ logger.error(` 错误信息: ${error.message}`);
836770
+ }
836771
+ if (error.code) {
836772
+ logger.error(` 错误码: ${error.code}`);
836773
+ }
836774
+ if (error.requestId) {
836775
+ logger.error(` RequestId: ${error.requestId}`);
836776
+ }
836777
+ const suggestions = this.getSpecificSuggestions(error, context);
836778
+ if (suggestions.length > 0) {
836779
+ logger.info((0, i18n_1.t)('解决建议:'));
836780
+ suggestions.forEach((suggestion, index) => {
836781
+ logger.info(` ${index + 1}. ${suggestion}`);
836782
+ });
836783
+ }
836784
+ }
836785
+ getSpecificSuggestions(error, context = {}) {
836786
+ const { functionName } = context;
836787
+ if (error.code === 'Forbidden' || error.code === 'Unauthorized' ||
836788
+ error.code === 'AuthFailure' || error.code === 'UnauthorizedOperation') {
836789
+ return [
836790
+ (0, i18n_1.t)('运行 {{command}} 重新登录', { command: (0, utils_1.highlightCommand)('tcb login') }),
836791
+ (0, i18n_1.t)('检查当前账号是否有该环境的操作权限'),
836792
+ ];
836793
+ }
836794
+ if (error.code === 'ResourceNotFound' || error.code === 'ResourceNotFound.FunctionName') {
836795
+ return [
836796
+ (0, i18n_1.t)('检查函数名称是否正确'),
836797
+ (0, i18n_1.t)('检查环境ID是否正确'),
836798
+ ];
836799
+ }
836800
+ if (error.code === 'InvalidParameter' || error.code === 'InvalidParameterValue') {
836801
+ return [
836802
+ (0, i18n_1.t)('检查函数配置参数是否在允许范围内(如内存、超时时间等)'),
836803
+ (0, i18n_1.t)('参考文档: https://cloud.tencent.com/document/product/876/19358'),
836804
+ ];
836805
+ }
836806
+ if (error.code === 'LimitExceeded') {
836807
+ return [
836808
+ (0, i18n_1.t)('当前环境函数数量已达上限'),
836809
+ (0, i18n_1.t)('删除不需要的函数或升级套餐'),
836810
+ ];
836811
+ }
836812
+ if (error.code === 'ResourceInUse.FunctionName' || error.code === 'ResourceInUse.Function') {
836813
+ return [
836814
+ (0, i18n_1.t)('函数已存在,使用 -f 参数强制覆盖'),
836815
+ ];
836816
+ }
836817
+ if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT' ||
836818
+ error.code === 'ENOTFOUND' || error.code === 'NetworkError') {
836819
+ return [
836820
+ (0, i18n_1.t)('检查网络连接是否正常'),
836821
+ (0, i18n_1.t)('检查是否需要配置代理'),
836822
+ ];
836823
+ }
836824
+ return [];
836825
+ }
836826
+ handleBatchErrors(errors, log) {
836827
+ if (errors.length === 0)
836828
+ return;
836829
+ log.error((0, i18n_1.t)('以下函数操作失败:'));
836830
+ errors.forEach(({ functionName, error, operation = '部署' }) => {
836831
+ log.error(` ✗ [${functionName}] ${operation}失败`);
836832
+ if (error.message) {
836833
+ log.error(` 错误信息: ${error.message}`);
836834
+ }
836835
+ if (error.code) {
836836
+ log.error(` 错误码: ${error.code}`);
836837
+ }
836838
+ if (error.requestId) {
836839
+ log.error(` RequestId: ${error.requestId}`);
836840
+ }
836841
+ const suggestions = this.getSpecificSuggestions(error, { functionName, operation });
836842
+ if (suggestions.length > 0) {
836843
+ suggestions.forEach((suggestion) => {
836844
+ log.info(` - ${suggestion}`);
836845
+ });
836846
+ }
836847
+ });
836848
+ }
836849
+ displayConfigConflicts(functionName, conflicts) {
836850
+ utils_1.logger.error((0, i18n_1.t)('函数 [{{name}}] 存在配置冲突:', { name: functionName }));
836851
+ conflicts.forEach((conflict) => {
836852
+ utils_1.logger.error(` ✗ ${conflict.field}: 云端 ${conflict.cloudValue} ≠ 本地 ${conflict.localValue}`);
836853
+ utils_1.logger.error(` ${conflict.message}`);
836854
+ });
836855
+ utils_1.logger.info((0, i18n_1.t)('解决建议:'));
836856
+ utils_1.logger.info((0, i18n_1.t)(' 1. 修改本地配置使其与云端一致'));
836857
+ utils_1.logger.info((0, i18n_1.t)(' 2. 删除云端函数后重新创建'));
836858
+ utils_1.logger.info((0, i18n_1.t)(' 3. 使用 {{command}} 查看云端配置', {
836859
+ command: (0, utils_1.highlightCommand)(`tcb fn detail ${functionName}`)
836860
+ }));
836861
+ }
836862
+ displayMergedConfig(functionName, config, source) {
836863
+ utils_1.logger.info((0, i18n_1.t)('函数 [{{name}}] 最终配置:', { name: functionName }));
836864
+ utils_1.logger.info(` ${(0, i18n_1.t)('类型')}: ${config.type || 'Event'}`);
836865
+ utils_1.logger.info(` ${(0, i18n_1.t)('运行时')}: ${config.runtime}`);
836866
+ utils_1.logger.info(` ${(0, i18n_1.t)('入口')}: ${config.handler}`);
836867
+ if (config.memorySize) {
836868
+ utils_1.logger.info(` ${(0, i18n_1.t)('内存')}: ${config.memorySize}MB`);
836869
+ }
836870
+ utils_1.logger.info(` ${(0, i18n_1.t)('超时')}: ${config.timeout}s`);
836871
+ if (source === 'inferred') {
836872
+ utils_1.logger.info((0, i18n_1.t)(' (配置来源: 智能推测)'));
836873
+ }
836874
+ else if (source === 'default') {
836875
+ utils_1.logger.info((0, i18n_1.t)(' (配置来源: 默认配置)'));
836876
+ }
836877
+ }
836878
+ confirmUpdate(functionName) {
836879
+ return __awaiter(this, void 0, void 0, function* () {
836880
+ const { confirm } = yield inquirer_1.default.prompt({
836881
+ type: 'confirm',
836882
+ name: 'confirm',
836883
+ message: (0, i18n_1.t)('检测到云端已存在函数 [{{name}}],是否覆盖更新?', { name: functionName }),
836884
+ default: false
836885
+ });
836886
+ return confirm;
836887
+ });
836888
+ }
836889
+ confirmDeploy() {
836890
+ return __awaiter(this, void 0, void 0, function* () {
836891
+ const { confirm } = yield inquirer_1.default.prompt({
836892
+ type: 'confirm',
836893
+ name: 'confirm',
836894
+ message: (0, i18n_1.t)('确认部署?'),
836895
+ default: true
836896
+ });
836897
+ return confirm;
836898
+ });
836899
+ }
835576
836900
  };
835577
836901
  __decorate([
835578
836902
  (0, decorators_1.InjectParams)(),