@cloudbase/cli 2.11.10 → 2.12.0-beta.1

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 +721 -126
  2. package/package.json +1 -1
@@ -307180,6 +307180,7 @@ class FunctionPacker {
307180
307180
  zipOption.pattern = this.incrementalPath;
307181
307181
  }
307182
307182
  await (0, utils_1.compressToZip)(zipOption);
307183
+ return this.zipFilePath;
307183
307184
  }
307184
307185
  // 获取 Java 代码
307185
307186
  getJavaFile() {
@@ -326019,7 +326020,7 @@ module.exports = function generate_pattern(it, $keyword, $ruleType) {
326019
326020
  /***/ ((module) => {
326020
326021
 
326021
326022
  "use strict";
326022
- module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"2.11.10","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.6.6","@cloudbase/toolbox":"^0.7.9","@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"}');
326023
+ module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"2.12.0-beta.1","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.2","@cloudbase/toolbox":"^0.7.9","@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"}');
326023
326024
 
326024
326025
  /***/ }),
326025
326026
 
@@ -352188,6 +352189,7 @@ __exportStar(__webpack_require__(97841), exports);
352188
352189
  __exportStar(__webpack_require__(13234), exports);
352189
352190
  __exportStar(__webpack_require__(713), exports);
352190
352191
  __exportStar(__webpack_require__(1026), exports);
352192
+ __exportStar(__webpack_require__(85319), exports);
352191
352193
 
352192
352194
 
352193
352195
  /***/ }),
@@ -447879,19 +447881,20 @@ class EnvService {
447879
447881
  });
447880
447882
  }
447881
447883
  getCos() {
447884
+ const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
447882
447885
  const { secretId, secretKey, token } = this.environment.getAuthConfig();
447883
447886
  const cosConfig = {
447884
447887
  SecretId: secretId,
447885
447888
  SecretKey: secretKey,
447886
447889
  SecurityToken: token,
447887
- Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
447890
+ Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
447888
447891
  };
447889
447892
  if (constant_1.COS_SDK_PROTOCOL) {
447890
447893
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
447891
447894
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
447892
447895
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
447893
447896
  }
447894
- if (constant_1.USE_INTERNAL_ENDPOINT) {
447897
+ if (internalEndpoint) {
447895
447898
  cosConfig.Protocol = 'http:';
447896
447899
  }
447897
447900
  return new cos_nodejs_sdk_v5_1.default(cosConfig);
@@ -467134,6 +467137,10 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
467134
467137
  {
467135
467138
  flags: '--code-secret <codeSecret>',
467136
467139
  desc: (0, i18n_1.t)('传入此参数将保护代码,格式为 36 位大小写字母和数字')
467140
+ },
467141
+ {
467142
+ flags: '--deployMode <deployMode>',
467143
+ desc: (0, i18n_1.t)('代码上传方式:cos(通过 COS 上传)或 zip(直接 ZIP 上传),默认自动选择')
467137
467144
  }
467138
467145
  ],
467139
467146
  desc: (0, i18n_1.t)('更新云函数代码')
@@ -467142,12 +467149,32 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
467142
467149
  execute(ctx, params) {
467143
467150
  return __awaiter(this, void 0, void 0, function* () {
467144
467151
  const { envId, config, options } = ctx;
467145
- const { codeSecret } = options;
467152
+ const { codeSecret, deployMode } = options;
467146
467153
  const name = params === null || params === void 0 ? void 0 : params[0];
467147
467154
  if (!name) {
467148
467155
  throw new error_1.CloudBaseError((0, i18n_1.t)('请指定云函数名称!'));
467149
467156
  }
467157
+ if (deployMode && !['cos', 'zip'].includes(deployMode)) {
467158
+ throw new error_1.CloudBaseError((0, i18n_1.t)('--deployMode 参数只能是 cos 或 zip'));
467159
+ }
467150
467160
  const func = config.functions.find((item) => item.name === name) || { name };
467161
+ const functionRootPath = path_1.default.join(process.cwd(), config.functionRoot);
467162
+ const funcPath = path_1.default.join(functionRootPath, name);
467163
+ try {
467164
+ const functionService = yield (0, function_1.getFunctionService)(envId);
467165
+ const functionDetail = yield functionService.getFunctionDetail(name, codeSecret);
467166
+ if ((functionDetail === null || functionDetail === void 0 ? void 0 : functionDetail.Type) === 'HTTP') {
467167
+ const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(funcPath, Object.assign(Object.assign({}, func), { type: 'HTTP', runtime: functionDetail.Runtime }), {
467168
+ cancelMessage: (0, i18n_1.t)('已取消更新,请手动创建 scf_bootstrap 文件后重试'),
467169
+ continueMessage: (0, i18n_1.t)('是否继续更新?')
467170
+ });
467171
+ if (!shouldContinue) {
467172
+ return;
467173
+ }
467174
+ }
467175
+ }
467176
+ catch (e) {
467177
+ }
467151
467178
  const loading = (0, utils_1.loadingFactory)();
467152
467179
  loading.start((0, i18n_1.t)('[{{name}}] 函数代码更新中...', { name: func.name }));
467153
467180
  try {
@@ -467155,7 +467182,8 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
467155
467182
  func,
467156
467183
  envId,
467157
467184
  codeSecret,
467158
- functionRootPath: path_1.default.join(process.cwd(), config.functionRoot)
467185
+ functionRootPath,
467186
+ deployMode
467159
467187
  });
467160
467188
  loading.succeed((0, i18n_1.t)('[{{name}}] 函数代码更新成功!', { name: func.name }));
467161
467189
  }
@@ -493217,6 +493245,24 @@ const error_1 = __webpack_require__(66759);
493217
493245
  const decorators_1 = __webpack_require__(93480);
493218
493246
  const function_1 = __webpack_require__(11686);
493219
493247
  const i18n_1 = __webpack_require__(69258);
493248
+ function hasEnvVariablesConfig(functions) {
493249
+ return functions.some((func) => func.envVariables && Object.keys(func.envVariables).length > 0);
493250
+ }
493251
+ function askEnvVarUpdateMode() {
493252
+ return __awaiter(this, void 0, void 0, function* () {
493253
+ const { envVarUpdateMode } = yield inquirer_1.default.prompt({
493254
+ type: 'list',
493255
+ name: 'envVarUpdateMode',
493256
+ message: (0, i18n_1.t)('检测到配置中包含环境变量,请选择环境变量更新方式'),
493257
+ choices: [
493258
+ { name: (0, i18n_1.t)('覆盖更新'), value: 'overwrite' },
493259
+ { name: (0, i18n_1.t)('合并更新'), value: 'merge' }
493260
+ ],
493261
+ default: 'overwrite'
493262
+ });
493263
+ return envVarUpdateMode;
493264
+ });
493265
+ }
493220
493266
  let ConfigUpdate = class ConfigUpdate extends common_1.Command {
493221
493267
  get options() {
493222
493268
  return {
@@ -493254,10 +493300,12 @@ let ConfigUpdate = class ConfigUpdate extends common_1.Command {
493254
493300
  }
493255
493301
  }
493256
493302
  if (isBathUpdate) {
493303
+ const envVarUpdateMode = hasEnvVariablesConfig(functions) ? yield askEnvVarUpdateMode() : undefined;
493257
493304
  yield (0, function_1.batchUpdateFunctionConfig)({
493258
493305
  envId,
493259
493306
  functions,
493260
- log: true
493307
+ log: true,
493308
+ envVarUpdateMode
493261
493309
  });
493262
493310
  return;
493263
493311
  }
@@ -493265,10 +493313,12 @@ let ConfigUpdate = class ConfigUpdate extends common_1.Command {
493265
493313
  if (!functionItem) {
493266
493314
  throw new error_1.CloudBaseError((0, i18n_1.t)('未找到相关函数配置,请检查函数名是否正确'));
493267
493315
  }
493316
+ const envVarUpdateMode = hasEnvVariablesConfig([functionItem]) ? yield askEnvVarUpdateMode() : undefined;
493268
493317
  yield (0, function_1.updateFunctionConfig)({
493269
493318
  envId,
493270
493319
  functionName: name,
493271
- config: functionItem
493320
+ config: functionItem,
493321
+ envVarUpdateMode
493272
493322
  });
493273
493323
  log.success((0, i18n_1.t)('[{{name}}] 更新云函数配置成功!', { name }));
493274
493324
  });
@@ -655704,6 +655754,7 @@ class Environment {
655704
655754
  this.cloudBaseContext = context;
655705
655755
  this.envType = context.envType;
655706
655756
  // 拉取当前环境 的环境信息 todo
655757
+ this.userService = new user_1.UserService(this);
655707
655758
  this.functionService = new function_1.FunctionService(this);
655708
655759
  this.cloudRunService = new cloudrun_1.CloudRunService(this);
655709
655760
  this.agentService = new agent_1.AgentService(this);
@@ -673184,7 +673235,7 @@ module.exports = function (inputRows /*, options*/) {
673184
673235
  "use strict";
673185
673236
 
673186
673237
  Object.defineProperty(exports, "__esModule", ({ value: true }));
673187
- exports.EnvType = exports.DEFAULT_CPU_MEM_SET = exports.CPU_MEM_OPTS = exports.ConcurrencyTaskStatus = exports.StatusMap = exports.ALL_COMMANDS = exports.STATUS_TEXT = exports.REQUEST_TIMEOUT = exports.DefaultCloudBaseConfig = exports.DefaultFunctionDeployConfig = exports.ConfigItems = void 0;
673238
+ exports.EnvType = exports.DEFAULT_CPU_MEM_SET = exports.CPU_MEM_OPTS = exports.ConcurrencyTaskStatus = exports.StatusMap = exports.ALL_COMMANDS = exports.STATUS_TEXT = exports.REQUEST_TIMEOUT = exports.DefaultCloudBaseConfig = exports.RuntimeOptions = exports.DefaultFunctionDeployConfig = exports.ConfigItems = void 0;
673188
673239
  const i18n_1 = __webpack_require__(69258);
673189
673240
  class ConfigItems {
673190
673241
  }
@@ -673194,10 +673245,21 @@ ConfigItems.ssh = 'ssh';
673194
673245
  exports.DefaultFunctionDeployConfig = {
673195
673246
  timeout: 3,
673196
673247
  handler: 'index.main',
673197
- runtime: 'Nodejs10.15',
673248
+ runtime: 'Nodejs18.15',
673198
673249
  installDependency: true,
673199
673250
  ignore: ['node_modules', 'node_modules/**/*', '.git']
673200
673251
  };
673252
+ exports.RuntimeOptions = [
673253
+ { name: 'Node.js 20.19', value: 'Nodejs20.19', handler: 'index.main' },
673254
+ { name: 'Node.js 18.15', value: 'Nodejs18.15', handler: 'index.main' },
673255
+ { name: 'Node.js 16.13', value: 'Nodejs16.13', handler: 'index.main' },
673256
+ { name: 'Python 3.9', value: 'Python3.9', handler: 'index.main' },
673257
+ { name: 'Python 3.7', value: 'Python3.7', handler: 'index.main' },
673258
+ { name: 'PHP 8.0', value: 'Php8.0', handler: 'index.main' },
673259
+ { name: 'PHP 7.4', value: 'Php7.4', handler: 'index.main' },
673260
+ { name: 'Java 11', value: 'Java11', handler: 'index.main' },
673261
+ { name: 'Java 8', value: 'Java8', handler: 'index.main' }
673262
+ ];
673201
673263
  exports.DefaultCloudBaseConfig = {
673202
673264
  functionRoot: './functions',
673203
673265
  functions: []
@@ -691126,20 +691188,25 @@ module.exports = (chalk, temporary) => {
691126
691188
  /***/ }),
691127
691189
 
691128
691190
  /***/ 65607:
691129
- /***/ ((__unused_webpack_module, exports) => {
691191
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
691130
691192
 
691131
691193
  "use strict";
691132
691194
 
691133
691195
  Object.defineProperty(exports, "__esModule", ({ value: true }));
691134
691196
  exports.CloudBaseContext = void 0;
691197
+ const constant_1 = __webpack_require__(40762);
691135
691198
  class CloudBaseContext {
691136
- constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
691199
+ constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
691137
691200
  this.secretId = secretId;
691138
691201
  this.secretKey = secretKey;
691139
691202
  this.token = token;
691140
691203
  this.proxy = proxy;
691141
691204
  this.region = region;
691142
691205
  this.envType = envType;
691206
+ this.useInternalEndpoint = useInternalEndpoint;
691207
+ }
691208
+ isInternalEndpoint() {
691209
+ return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
691143
691210
  }
691144
691211
  }
691145
691212
  exports.CloudBaseContext = CloudBaseContext;
@@ -692373,7 +692440,7 @@ const i18n_1 = __webpack_require__(69258);
692373
692440
  function updateFunctionCode(options) {
692374
692441
  var _a;
692375
692442
  return __awaiter(this, void 0, void 0, function* () {
692376
- const { functionRootPath = '', envId, base64Code = '', codeSecret } = options;
692443
+ const { functionRootPath = '', functionPath, envId, base64Code = '', codeSecret, deployMode } = options;
692377
692444
  const func = Object.assign(Object.assign({}, (_a = options === null || options === void 0 ? void 0 : options.func) === null || _a === void 0 ? void 0 : _a.config), options.func);
692378
692445
  const funcName = func.name;
692379
692446
  if (codeSecret && !/^[A-Za-z0-9+=/]{1,160}$/.test(codeSecret)) {
@@ -692384,8 +692451,10 @@ function updateFunctionCode(options) {
692384
692451
  yield scfService.updateFunctionCode({
692385
692452
  func,
692386
692453
  functionRootPath,
692454
+ functionPath,
692387
692455
  base64Code,
692388
- codeSecret
692456
+ codeSecret,
692457
+ deployMode
692389
692458
  });
692390
692459
  }
692391
692460
  catch (e) {
@@ -719624,6 +719693,9 @@ class UserService {
719624
719693
  }]
719625
719694
  });
719626
719695
  }
719696
+ async getTcbAccountInfo() {
719697
+ return this.tcbService.request('DescribeTcbAccountInfo');
719698
+ }
719627
719699
  isValidStr(obj) {
719628
719700
  return typeof obj === 'string' && obj.trim().length > 0;
719629
719701
  }
@@ -722885,6 +722957,7 @@ class StorageService {
722885
722957
  * 获取 COS 配置
722886
722958
  */
722887
722959
  getCos(parallel = 20) {
722960
+ const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
722888
722961
  const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
722889
722962
  const cosProxy = process.env.TCB_COS_PROXY;
722890
722963
  const cosConfig = {
@@ -722893,14 +722966,14 @@ class StorageService {
722893
722966
  SecretKey: secretKey,
722894
722967
  Proxy: cosProxy || proxy,
722895
722968
  SecurityToken: token,
722896
- Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
722969
+ Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
722897
722970
  };
722898
722971
  if (constant_1.COS_SDK_PROTOCOL) {
722899
722972
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
722900
722973
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
722901
722974
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
722902
722975
  }
722903
- if (constant_1.USE_INTERNAL_ENDPOINT) {
722976
+ if (internalEndpoint) {
722904
722977
  cosConfig.Protocol = 'http:';
722905
722978
  }
722906
722979
  // COSSDK 默认开启 KeepAlive,这里提供关闭的方式
@@ -726339,7 +726412,7 @@ const i18n_1 = __webpack_require__(69258);
726339
726412
  function createFunction(options) {
726340
726413
  var _a;
726341
726414
  return __awaiter(this, void 0, void 0, function* () {
726342
- const { envId, accessPath, codeSecret, force = false, functionPath, base64Code = '', functionRootPath = '' } = options;
726415
+ const { envId, accessPath, codeSecret, force = false, functionPath, base64Code = '', functionRootPath = '', deployMode } = options;
726343
726416
  const func = Object.assign(Object.assign({}, (_a = options === null || options === void 0 ? void 0 : options.func) === null || _a === void 0 ? void 0 : _a.config), options.func);
726344
726417
  accessPath && (func.path = accessPath);
726345
726418
  const funcName = func.name;
@@ -726352,7 +726425,8 @@ function createFunction(options) {
726352
726425
  base64Code,
726353
726426
  codeSecret,
726354
726427
  functionPath,
726355
- functionRootPath
726428
+ functionRootPath,
726429
+ deployMode
726356
726430
  });
726357
726431
  }
726358
726432
  catch (e) {
@@ -730590,22 +730664,39 @@ function getFunctionLog(options) {
730590
730664
  }
730591
730665
  exports.getFunctionLog = getFunctionLog;
730592
730666
  function updateFunctionConfig(options) {
730667
+ var _a;
730593
730668
  return __awaiter(this, void 0, void 0, function* () {
730594
- const { functionName, config, envId } = options;
730669
+ const { functionName, config, envId, envVarUpdateMode = 'overwrite' } = options;
730670
+ let finalConfig = Object.assign({}, config);
730671
+ if (envVarUpdateMode === 'merge' && config.envVariables) {
730672
+ try {
730673
+ const cloudFunctionDetail = yield getFunctionDetail({ functionName, envId });
730674
+ const cloudEnvVariables = {};
730675
+ if ((_a = cloudFunctionDetail.Environment) === null || _a === void 0 ? void 0 : _a.Variables) {
730676
+ for (const item of cloudFunctionDetail.Environment.Variables) {
730677
+ cloudEnvVariables[item.Key] = item.Value;
730678
+ }
730679
+ }
730680
+ finalConfig.envVariables = Object.assign(Object.assign({}, cloudEnvVariables), config.envVariables);
730681
+ }
730682
+ catch (e) {
730683
+ }
730684
+ }
730595
730685
  const functionService = yield getFunctionService(envId);
730596
- yield functionService.updateFunctionConfig(Object.assign({ name: functionName }, config));
730686
+ yield functionService.updateFunctionConfig(Object.assign({ name: functionName }, finalConfig));
730597
730687
  });
730598
730688
  }
730599
730689
  exports.updateFunctionConfig = updateFunctionConfig;
730600
730690
  function batchUpdateFunctionConfig(options) {
730601
730691
  return __awaiter(this, void 0, void 0, function* () {
730602
- const { functions, envId, log } = options;
730692
+ const { functions, envId, log, envVarUpdateMode } = options;
730603
730693
  const promises = functions.map(func => (() => __awaiter(this, void 0, void 0, function* () {
730604
730694
  try {
730605
730695
  yield updateFunctionConfig({
730606
730696
  functionName: func.name,
730607
730697
  config: func,
730608
- envId
730698
+ envId,
730699
+ envVarUpdateMode
730609
730700
  });
730610
730701
  log && (0, logger_1.successLog)((0, i18n_1.t)('[{{name}}] 更新云函数配置成功!', { name: func.name }));
730611
730702
  }
@@ -736686,6 +736777,9 @@ function selectEnv(options = {}) {
736686
736777
  let data = yield (0, env_1.listEnvs)({ source }).finally(() => {
736687
736778
  loading.stop();
736688
736779
  });
736780
+ if (!data || data.length === 0) {
736781
+ throw new Error((0, i18n_1.t)('没有可用的环境,请先在控制台创建环境'));
736782
+ }
736689
736783
  const choices = (0, lodash_1.sortBy)(data, ['Alias']).map((item) => {
736690
736784
  return {
736691
736785
  name: `${item.Alias || item.EnvId} (${item.EnvId}) ${item.Status === constants_1.EnvStatus.NORMAL ? (0, i18n_1.t)('正常') : (0, i18n_1.t)('不可用')}`,
@@ -776498,6 +776592,7 @@ class CloudService {
776498
776592
  this.cloudBaseContext = context;
776499
776593
  }
776500
776594
  get baseUrl() {
776595
+ const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
776501
776596
  const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
776502
776597
  const urlMap = {
776503
776598
  tcb,
@@ -776511,8 +776606,8 @@ class CloudService {
776511
776606
  const intranetUrlMap = Object.keys(urlMap).map((service) => ({
776512
776607
  [service]: `https://${service}.internal.tencentcloudapi.com`,
776513
776608
  })).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
776514
- if (constant_1.USE_INTERNAL_ENDPOINT) {
776515
- return intranetUrlMap[this.service];
776609
+ if (internalEndpoint) {
776610
+ return intranetUrlMap[this.service] || `https://${this.service}.internal.tencentcloudapi.com`;
776516
776611
  }
776517
776612
  if (urlMap[this.service]) {
776518
776613
  return urlMap[this.service];
@@ -799584,6 +799679,120 @@ class XMLParser{
799584
799679
 
799585
799680
  module.exports = XMLParser;
799586
799681
 
799682
+ /***/ }),
799683
+
799684
+ /***/ 85319:
799685
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
799686
+
799687
+ "use strict";
799688
+
799689
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
799690
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
799691
+ return new (P || (P = Promise))(function (resolve, reject) {
799692
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
799693
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
799694
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
799695
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
799696
+ });
799697
+ };
799698
+ var __importDefault = (this && this.__importDefault) || function (mod) {
799699
+ return (mod && mod.__esModule) ? mod : { "default": mod };
799700
+ };
799701
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
799702
+ exports.checkAndCreateBootstrap = exports.generateBootstrapContent = void 0;
799703
+ const fs_1 = __importDefault(__webpack_require__(79896));
799704
+ const path_1 = __importDefault(__webpack_require__(16928));
799705
+ const inquirer_1 = __importDefault(__webpack_require__(6403));
799706
+ const utils_1 = __webpack_require__(82079);
799707
+ const i18n_1 = __webpack_require__(69258);
799708
+ const constant_1 = __webpack_require__(62977);
799709
+ function generateBootstrapContent(func) {
799710
+ const runtime = func.runtime || constant_1.DefaultFunctionDeployConfig.runtime;
799711
+ const handler = func.handler || constant_1.DefaultFunctionDeployConfig.handler;
799712
+ const lastDotIndex = handler.lastIndexOf('.');
799713
+ const entryFileBase = lastDotIndex > 0 ? handler.substring(0, lastDotIndex) : handler;
799714
+ if (runtime.startsWith('Nodejs')) {
799715
+ const nodeVersion = runtime.replace('Nodejs', '');
799716
+ return `#!/bin/bash
799717
+ export PORT=9000
799718
+ /var/lang/node${nodeVersion}/bin/node ${entryFileBase}.js
799719
+ `;
799720
+ }
799721
+ else if (runtime.startsWith('Python')) {
799722
+ const pyVersion = runtime.replace('Python', '');
799723
+ return `#!/bin/bash
799724
+ export PORT=9000
799725
+ /var/lang/python${pyVersion}/bin/python3 ${entryFileBase}.py
799726
+ `;
799727
+ }
799728
+ else if (runtime.startsWith('Php')) {
799729
+ const phpVersion = runtime.replace('Php', '');
799730
+ return `#!/bin/bash
799731
+ export PORT=9000
799732
+ /var/lang/php${phpVersion}/bin/php -S 0.0.0.0:9000
799733
+ `;
799734
+ }
799735
+ else if (runtime.startsWith('Java')) {
799736
+ const javaVersion = runtime.replace('Java', '');
799737
+ return `#!/bin/bash
799738
+ export PORT=9000
799739
+ /var/lang/java${javaVersion}/bin/java -jar app.jar
799740
+ `;
799741
+ }
799742
+ else if (runtime.startsWith('Go')) {
799743
+ return `#!/bin/bash
799744
+ export PORT=9000
799745
+ ./main
799746
+ `;
799747
+ }
799748
+ const defaultVersion = constant_1.DefaultFunctionDeployConfig.runtime.replace('Nodejs', '');
799749
+ return `#!/bin/bash
799750
+ export PORT=9000
799751
+ /var/lang/node${defaultVersion}/bin/node ${entryFileBase}.js
799752
+ `;
799753
+ }
799754
+ exports.generateBootstrapContent = generateBootstrapContent;
799755
+ function checkAndCreateBootstrap(functionPath, func, options = {}) {
799756
+ return __awaiter(this, void 0, void 0, function* () {
799757
+ const { cancelMessage = (0, i18n_1.t)('已取消部署,请手动创建 scf_bootstrap 文件后重试'), continueMessage = (0, i18n_1.t)('是否继续部署?') } = options;
799758
+ if (func.type !== 'HTTP') {
799759
+ return true;
799760
+ }
799761
+ const bootstrapPath = path_1.default.join(functionPath, 'scf_bootstrap');
799762
+ if (fs_1.default.existsSync(bootstrapPath)) {
799763
+ return true;
799764
+ }
799765
+ utils_1.logger.warn((0, i18n_1.t)('Web 函数需要 scf_bootstrap 启动文件,当前目录未找到'));
799766
+ const { createBootstrap } = yield inquirer_1.default.prompt({
799767
+ type: 'confirm',
799768
+ name: 'createBootstrap',
799769
+ message: (0, i18n_1.t)('是否自动创建 scf_bootstrap 启动文件示例?'),
799770
+ default: true
799771
+ });
799772
+ if (!createBootstrap) {
799773
+ utils_1.logger.info(cancelMessage);
799774
+ utils_1.logger.info((0, i18n_1.t)('参考文档:https://docs.cloudbase.net/cli-v1/functions/web-deploy#%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC'));
799775
+ return false;
799776
+ }
799777
+ const bootstrapContent = generateBootstrapContent(func);
799778
+ fs_1.default.writeFileSync(bootstrapPath, bootstrapContent, { mode: 0o755 });
799779
+ utils_1.logger.success((0, i18n_1.t)('已创建 scf_bootstrap 文件:{{path}}', { path: bootstrapPath }));
799780
+ utils_1.logger.info('');
799781
+ utils_1.logger.warn((0, i18n_1.t)('可以根据您的实际项目修改启动命令,参考文档:'));
799782
+ utils_1.logger.info((0, i18n_1.t)(' https://docs.cloudbase.net/cli-v1/functions/web-deploy#%E5%90%AF%E5%8A%A8%E8%84%9A%E6%9C%AC'));
799783
+ utils_1.logger.info('');
799784
+ const { continueDeploy } = yield inquirer_1.default.prompt({
799785
+ type: 'confirm',
799786
+ name: 'continueDeploy',
799787
+ message: continueMessage,
799788
+ default: true
799789
+ });
799790
+ return continueDeploy;
799791
+ });
799792
+ }
799793
+ exports.checkAndCreateBootstrap = checkAndCreateBootstrap;
799794
+
799795
+
799587
799796
  /***/ }),
799588
799797
 
799589
799798
  /***/ 85328:
@@ -833536,10 +833745,12 @@ const error_1 = __webpack_require__(66759);
833536
833745
  const function_1 = __webpack_require__(11686);
833537
833746
  const gateway_1 = __webpack_require__(71608);
833538
833747
  const utils_1 = __webpack_require__(82079);
833748
+ const fs_1 = __importDefault(__webpack_require__(79896));
833539
833749
  const constant_1 = __webpack_require__(62977);
833540
833750
  const decorators_1 = __webpack_require__(93480);
833541
833751
  const function_2 = __webpack_require__(11686);
833542
833752
  const i18n_1 = __webpack_require__(69258);
833753
+ const utils_2 = __webpack_require__(75213);
833543
833754
  const regionIdMap = {
833544
833755
  'ap-guangzhou': 1,
833545
833756
  'ap-shanghai': 4,
@@ -833575,18 +833786,42 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833575
833786
  {
833576
833787
  flags: '--dir <dir>',
833577
833788
  desc: (0, i18n_1.t)('指定云函数的文件夹路径')
833789
+ },
833790
+ {
833791
+ flags: '--httpFn',
833792
+ desc: (0, i18n_1.t)('部署为 HTTP 云函数(HTTP 触发)')
833793
+ },
833794
+ {
833795
+ flags: '--deployMode <deployMode>',
833796
+ desc: (0, i18n_1.t)('代码上传方式:cos(通过 COS 上传)或 zip(直接 ZIP 上传),默认自动选择')
833578
833797
  }
833579
833798
  ],
833580
- desc: (0, i18n_1.t)('部署云函数')
833799
+ desc: (0, i18n_1.t)('部署云函数'),
833800
+ requiredEnvId: false,
833801
+ autoRunLogin: true
833581
833802
  };
833582
833803
  }
833583
833804
  execute(ctx, params, log) {
833584
833805
  return __awaiter(this, void 0, void 0, function* () {
833585
- const { envId, config, options } = ctx;
833806
+ let { envId, config, options } = ctx;
833586
833807
  const { functions } = config;
833587
- const { force, codeSecret, path: access, all, dir } = options;
833588
- const functionRootPath = path_1.default.join(process.cwd(), config.functionRoot);
833808
+ const { force, codeSecret, path: access, all, dir, httpFn, deployMode } = options;
833809
+ if (!envId) {
833810
+ envId = yield (0, utils_2.selectEnv)();
833811
+ log.info((0, i18n_1.t)('当前环境 Id:{{envId}}', { envId }));
833812
+ }
833813
+ const hasConfig = !!(config.envId || (functions && functions.length > 0));
833589
833814
  const name = params === null || params === void 0 ? void 0 : params[0];
833815
+ let functionRootPath;
833816
+ if (hasConfig) {
833817
+ functionRootPath = path_1.default.join(process.cwd(), config.functionRoot || 'functions');
833818
+ }
833819
+ else {
833820
+ functionRootPath = process.cwd();
833821
+ }
833822
+ if (deployMode && !['cos', 'zip'].includes(deployMode)) {
833823
+ throw new error_1.CloudBaseError((0, i18n_1.t)('--deployMode 参数只能是 cos 或 zip'));
833824
+ }
833590
833825
  if (access && (0, utils_1.checkFullAccess)(access)) {
833591
833826
  log.warn((0, i18n_1.t)('--path 参数已更换为HTTP 访问服务路径,请使用 --dir 指定部署函数的文件夹路径'));
833592
833827
  }
@@ -833594,6 +833829,75 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833594
833829
  throw new error_1.CloudBaseError((0, i18n_1.t)('HTTP 访问服务路径必须以 / 开头'));
833595
833830
  }
833596
833831
  if ((!name && !dir) || all) {
833832
+ if (!functions || functions.length === 0) {
833833
+ let currentDirFunc = this.getFunctionFromCurrentDir(httpFn);
833834
+ if (!currentDirFunc && !all) {
833835
+ const { funcName } = yield inquirer_1.default.prompt({
833836
+ type: 'input',
833837
+ name: 'funcName',
833838
+ message: (0, i18n_1.t)('请输入函数名称'),
833839
+ validate: (input) => {
833840
+ if (!input || !input.trim()) {
833841
+ return (0, i18n_1.t)('函数名称不能为空');
833842
+ }
833843
+ return true;
833844
+ }
833845
+ });
833846
+ const runtime = yield this.selectRuntime();
833847
+ currentDirFunc = Object.assign(Object.assign(Object.assign({ name: funcName.trim() }, constant_1.DefaultFunctionDeployConfig), { runtime }), (httpFn ? { type: 'HTTP' } : {}));
833848
+ }
833849
+ if (currentDirFunc) {
833850
+ log.info((0, i18n_1.t)('未找到配置文件,将从当前目录部署云函数'));
833851
+ log.info((0, i18n_1.t)('函数名称:{{name}}', { name: currentDirFunc.name }));
833852
+ log.info((0, i18n_1.t)('默认配置:'));
833853
+ log.info((0, i18n_1.t)(' - 运行时:{{runtime}}', { runtime: currentDirFunc.runtime }));
833854
+ log.info((0, i18n_1.t)(' - 超时时间:{{timeout}} 秒', { timeout: currentDirFunc.timeout }));
833855
+ log.info((0, i18n_1.t)(' - 入口函数:{{handler}}', { handler: currentDirFunc.handler }));
833856
+ log.info((0, i18n_1.t)(' - 在线安装依赖:{{installDependency}}', { installDependency: currentDirFunc.installDependency ? (0, i18n_1.t)('是') : (0, i18n_1.t)('否') }));
833857
+ if (currentDirFunc.type === 'HTTP') {
833858
+ log.info((0, i18n_1.t)(' - 函数类型:HTTP'));
833859
+ }
833860
+ if (currentDirFunc.type === 'HTTP') {
833861
+ const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(process.cwd(), currentDirFunc);
833862
+ if (!shouldContinue) {
833863
+ return;
833864
+ }
833865
+ }
833866
+ const loading = (0, utils_1.loadingFactory)();
833867
+ loading.start((0, i18n_1.t)('云函数部署中...'));
833868
+ try {
833869
+ yield (0, function_1.createFunction)({
833870
+ force,
833871
+ envId,
833872
+ codeSecret,
833873
+ functionRootPath: process.cwd(),
833874
+ func: currentDirFunc,
833875
+ accessPath: access,
833876
+ functionPath: '.',
833877
+ deployMode
833878
+ });
833879
+ loading.succeed((0, i18n_1.t)('[{{name}}] 云函数部署成功!', { name: currentDirFunc.name }));
833880
+ this.printSuccessTips(envId);
833881
+ }
833882
+ catch (e) {
833883
+ loading.stop();
833884
+ yield this.handleDeployFail(e, {
833885
+ envId,
833886
+ force,
833887
+ codeSecret,
833888
+ functionRootPath: process.cwd(),
833889
+ func: currentDirFunc,
833890
+ accessPath: access,
833891
+ functionPath: '.'
833892
+ });
833893
+ }
833894
+ if (access || currentDirFunc.path) {
833895
+ const link = (0, utils_1.genClickableLink)(`https://${envId}.service.tcloudbase.com${access || currentDirFunc.path}`);
833896
+ console.log((0, i18n_1.t)('\n云函数HTTP 访问服务访问链接:{{link}}', { link }));
833897
+ }
833898
+ return;
833899
+ }
833900
+ }
833597
833901
  return this.deployAllFunction({
833598
833902
  all,
833599
833903
  envId,
@@ -833601,7 +833905,9 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833601
833905
  access,
833602
833906
  functions,
833603
833907
  codeSecret,
833604
- functionRootPath
833908
+ functionRootPath,
833909
+ httpFn,
833910
+ deployMode
833605
833911
  });
833606
833912
  }
833607
833913
  if (dir) {
@@ -833614,9 +833920,22 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833614
833920
  if (functions && functions.length > 0) {
833615
833921
  newFunction = functions.find((item) => item.name === name);
833616
833922
  }
833923
+ const deployFromCurrentDir = !hasConfig && name && !dir;
833617
833924
  if (!newFunction || !newFunction.name) {
833618
- log.info((0, i18n_1.t)('未找到函数发布配置,使用默认配置 => 运行时:Nodejs10.15/在线安装依赖'));
833619
- newFunction = Object.assign({ name }, constant_1.DefaultFunctionDeployConfig);
833925
+ const runtime = yield this.selectRuntime();
833926
+ log.info((0, i18n_1.t)('未找到函数发布配置,使用默认配置 => 运行时:{{runtime}}/在线安装依赖', { runtime }));
833927
+ newFunction = Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), { runtime });
833928
+ }
833929
+ if (httpFn) {
833930
+ newFunction.type = 'HTTP';
833931
+ }
833932
+ const functionPath = deployFromCurrentDir ? '.' : dir;
833933
+ if (newFunction.type === 'HTTP') {
833934
+ const funcPath = functionPath === '.' ? process.cwd() : (dir || path_1.default.join(functionRootPath, name));
833935
+ const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(funcPath, newFunction);
833936
+ if (!shouldContinue) {
833937
+ return;
833938
+ }
833620
833939
  }
833621
833940
  const loading = (0, utils_1.loadingFactory)();
833622
833941
  loading.start((0, i18n_1.t)('云函数部署中...'));
@@ -833628,7 +833947,8 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833628
833947
  functionRootPath,
833629
833948
  func: newFunction,
833630
833949
  accessPath: access,
833631
- functionPath: dir
833950
+ functionPath,
833951
+ deployMode
833632
833952
  });
833633
833953
  loading.succeed((0, i18n_1.t)('[{{name}}] 云函数部署成功!', { name: newFunction.name }));
833634
833954
  this.printSuccessTips(envId);
@@ -833637,11 +833957,12 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833637
833957
  loading.stop();
833638
833958
  yield this.handleDeployFail(e, {
833639
833959
  envId,
833960
+ force,
833640
833961
  codeSecret,
833641
833962
  functionRootPath,
833642
833963
  func: newFunction,
833643
833964
  accessPath: access,
833644
- functionPath: dir
833965
+ functionPath
833645
833966
  });
833646
833967
  }
833647
833968
  if (access || newFunction.path) {
@@ -833652,37 +833973,86 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833652
833973
  }
833653
833974
  deployAllFunction(options) {
833654
833975
  return __awaiter(this, void 0, void 0, function* () {
833655
- const { functions = [], envId, force, codeSecret, functionRootPath, all, access } = options;
833976
+ let { functions = [], envId, force, codeSecret, functionRootPath, all, access, httpFn, deployMode } = options;
833977
+ if (!functions || functions.length === 0) {
833978
+ functions = this.scanFunctionDirectory(functionRootPath, httpFn);
833979
+ if (functions.length > 0) {
833980
+ utils_1.logger.info((0, i18n_1.t)('未找到配置文件,已扫描 {{path}} 目录,发现 {{count}} 个函数,将使用默认配置部署:', {
833981
+ path: functionRootPath,
833982
+ count: functions.length
833983
+ }));
833984
+ functions.forEach((func) => {
833985
+ utils_1.logger.info(` - ${func.name}`);
833986
+ });
833987
+ }
833988
+ }
833989
+ if (!functions || functions.length === 0) {
833990
+ throw new error_1.CloudBaseError((0, i18n_1.t)('未找到云函数配置,请在 cloudbaserc.json 中配置 functions 字段,或使用 tcb fn deploy <函数名> 指定要部署的函数'));
833991
+ }
833992
+ let selectedFunctions = functions;
833656
833993
  if (!all) {
833657
- const { isBatch } = yield inquirer_1.default.prompt({
833658
- type: 'confirm',
833659
- name: 'isBatch',
833660
- message: (0, i18n_1.t)('没有指定需要部署的云函数,是否部署配置文件中的全部云函数?'),
833661
- default: false
833994
+ const choices = functions.map((func) => ({
833995
+ name: `${func.name}${func.type === 'HTTP' ? ' (HTTP)' : ''}`,
833996
+ value: func.name,
833997
+ short: func.name
833998
+ }));
833999
+ choices.unshift({
834000
+ name: (0, i18n_1.t)('全部函数'),
834001
+ value: '__ALL__',
834002
+ short: (0, i18n_1.t)('全部')
833662
834003
  });
833663
- if (!isBatch) {
833664
- throw new error_1.CloudBaseError((0, i18n_1.t)('请指定需要部署的云函数的名称或通过 --path 参数指定需要部署的函数的路径!'));
834004
+ const { selected } = yield inquirer_1.default.prompt({
834005
+ type: 'checkbox',
834006
+ name: 'selected',
834007
+ message: (0, i18n_1.t)('请选择要部署的云函数(空格选择,回车确认)'),
834008
+ choices,
834009
+ validate: (answer) => {
834010
+ if (answer.length === 0) {
834011
+ return (0, i18n_1.t)('请至少选择一个云函数');
834012
+ }
834013
+ return true;
834014
+ }
834015
+ });
834016
+ if (selected.includes('__ALL__')) {
834017
+ selectedFunctions = functions;
834018
+ }
834019
+ else {
834020
+ selectedFunctions = functions.filter((func) => selected.includes(func.name));
834021
+ }
834022
+ if (selectedFunctions.length === 0) {
834023
+ throw new error_1.CloudBaseError((0, i18n_1.t)('没有选择任何云函数'));
833665
834024
  }
833666
834025
  }
833667
834026
  const loading = (0, utils_1.loadingFactory)();
833668
- const tasks = functions.map((func) => () => __awaiter(this, void 0, void 0, function* () {
834027
+ const tasks = selectedFunctions.map((func) => () => __awaiter(this, void 0, void 0, function* () {
834028
+ const funcWithType = httpFn ? Object.assign(Object.assign({}, func), { type: 'HTTP' }) : func;
834029
+ if (funcWithType.type === 'HTTP') {
834030
+ const funcPath = path_1.default.join(functionRootPath, func.name);
834031
+ const shouldContinue = yield (0, function_1.checkAndCreateBootstrap)(funcPath, funcWithType);
834032
+ if (!shouldContinue) {
834033
+ utils_1.logger.warn((0, i18n_1.t)('[{{name}}] 已跳过部署', { name: func.name }));
834034
+ return;
834035
+ }
834036
+ }
833669
834037
  loading.start((0, i18n_1.t)('云函数部署中'));
833670
834038
  try {
833671
834039
  yield (0, function_1.createFunction)({
833672
- func,
834040
+ func: funcWithType,
833673
834041
  envId,
833674
834042
  force,
833675
834043
  codeSecret,
833676
834044
  functionRootPath,
833677
- accessPath: access
834045
+ accessPath: access,
834046
+ deployMode
833678
834047
  });
833679
834048
  loading.succeed((0, i18n_1.t)('[{{name}}] 云函数部署成功', { name: func.name }));
833680
834049
  }
833681
834050
  catch (e) {
833682
834051
  loading.stop();
833683
834052
  yield this.handleDeployFail(e, {
833684
- func,
834053
+ func: funcWithType,
833685
834054
  envId,
834055
+ force,
833686
834056
  codeSecret,
833687
834057
  functionRootPath,
833688
834058
  accessPath: access
@@ -833697,30 +834067,53 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833697
834067
  const results = yield asyncTaskController.run();
833698
834068
  const success = results.filter((_) => !_);
833699
834069
  utils_1.logger.success((0, i18n_1.t)('成功部署 {{count}} 个函数', { count: success === null || success === void 0 ? void 0 : success.length }));
833700
- const err = results.filter((_) => _);
833701
- (err === null || err === void 0 ? void 0 : err.length) && utils_1.logger.error((0, i18n_1.t)('{{count}} 个云函数部署失败', { count: err === null || err === void 0 ? void 0 : err.length }));
834070
+ const errors = results.filter((_) => _);
834071
+ if (errors === null || errors === void 0 ? void 0 : errors.length) {
834072
+ utils_1.logger.error((0, i18n_1.t)('{{count}} 个云函数部署失败', { count: errors === null || errors === void 0 ? void 0 : errors.length }));
834073
+ errors.forEach((err) => {
834074
+ if (err === null || err === void 0 ? void 0 : err.message) {
834075
+ utils_1.logger.error(` - ${err.message}`);
834076
+ }
834077
+ });
834078
+ }
833702
834079
  });
833703
834080
  }
833704
834081
  handleDeployFail(e, options) {
833705
834082
  return __awaiter(this, void 0, void 0, function* () {
833706
- const { envId, codeSecret, functionRootPath, func, functionPath, accessPath } = options;
834083
+ const { envId, codeSecret, functionRootPath, func, functionPath, accessPath, force: forceOverwrite } = options;
833707
834084
  const loading = (0, utils_1.loadingFactory)();
833708
834085
  if (e.code === 'ResourceInUse.FunctionName' || e.code === 'ResourceInUse.Function') {
833709
- const { force } = yield inquirer_1.default.prompt({
833710
- type: 'confirm',
833711
- name: 'force',
833712
- message: (0, i18n_1.t)('存在同名云函数:[{{name}}],是否覆盖原函数代码与配置', { name: func.name }),
833713
- default: false
833714
- });
834086
+ const functionService = yield (0, function_2.getFunctionService)(envId);
834087
+ const existingFunction = yield functionService.getFunctionDetail(func.name, codeSecret);
834088
+ const existingType = (existingFunction === null || existingFunction === void 0 ? void 0 : existingFunction.Type) || 'Event';
834089
+ const newType = func.type || 'Event';
834090
+ if (existingType !== newType) {
834091
+ throw new error_1.CloudBaseError((0, i18n_1.t)('不支持变更函数类型:云端函数 [{{name}}] 类型为 {{existingType}},无法变更为 {{newType}}', {
834092
+ name: func.name,
834093
+ existingType,
834094
+ newType
834095
+ }));
834096
+ }
834097
+ let shouldForce = forceOverwrite;
834098
+ if (!shouldForce) {
834099
+ const answer = yield inquirer_1.default.prompt({
834100
+ type: 'confirm',
834101
+ name: 'force',
834102
+ message: (0, i18n_1.t)('存在同名云函数:[{{name}}],是否覆盖原函数代码与配置', { name: func.name }),
834103
+ default: false
834104
+ });
834105
+ shouldForce = answer.force;
834106
+ }
833715
834107
  const { triggers } = func;
833716
- if (force) {
834108
+ if (shouldForce) {
833717
834109
  loading.start((0, i18n_1.t)('云函数更新部署中...'));
833718
834110
  try {
833719
834111
  yield (0, function_2.updateFunctionCode)({
833720
834112
  func,
833721
834113
  envId,
833722
834114
  codeSecret,
833723
- functionRootPath
834115
+ functionRootPath,
834116
+ functionPath
833724
834117
  });
833725
834118
  yield this.waitForFunctionReady(envId, func.name, loading);
833726
834119
  loading.succeed((0, i18n_1.t)('[{{name}}] 云函数配置更新中...', { name: func.name }));
@@ -833811,6 +834204,55 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
833811
834204
  console.log((0, i18n_1.t)('\n云函数HTTP 访问服务链接:{{link}}', { link }));
833812
834205
  });
833813
834206
  }
834207
+ getFunctionFromCurrentDir(httpFn) {
834208
+ const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
834209
+ if (!fs_1.default.existsSync(packageJsonPath)) {
834210
+ return null;
834211
+ }
834212
+ try {
834213
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, 'utf-8'));
834214
+ if (!packageJson.name) {
834215
+ return null;
834216
+ }
834217
+ let handler = constant_1.DefaultFunctionDeployConfig.handler;
834218
+ if (packageJson.main) {
834219
+ const mainFile = path_1.default.basename(packageJson.main).replace(/\.[^.]+$/, '');
834220
+ handler = `${mainFile}.main`;
834221
+ }
834222
+ return Object.assign(Object.assign(Object.assign({ name: packageJson.name }, constant_1.DefaultFunctionDeployConfig), { handler }), (httpFn ? { type: 'HTTP' } : {}));
834223
+ }
834224
+ catch (e) {
834225
+ return null;
834226
+ }
834227
+ }
834228
+ scanFunctionDirectory(functionRootPath, httpFn) {
834229
+ if (!fs_1.default.existsSync(functionRootPath)) {
834230
+ return [];
834231
+ }
834232
+ const dirs = fs_1.default.readdirSync(functionRootPath).filter((name) => {
834233
+ const fullPath = path_1.default.join(functionRootPath, name);
834234
+ return fs_1.default.statSync(fullPath).isDirectory() && !name.startsWith('.');
834235
+ });
834236
+ if (dirs.length === 0) {
834237
+ return [];
834238
+ }
834239
+ return dirs.map((name) => (Object.assign(Object.assign({ name }, constant_1.DefaultFunctionDeployConfig), (httpFn ? { type: 'HTTP' } : {}))));
834240
+ }
834241
+ selectRuntime() {
834242
+ return __awaiter(this, void 0, void 0, function* () {
834243
+ const packageJsonPath = path_1.default.join(process.cwd(), 'package.json');
834244
+ if (fs_1.default.existsSync(packageJsonPath)) {
834245
+ return constant_1.DefaultFunctionDeployConfig.runtime;
834246
+ }
834247
+ const { runtime } = yield inquirer_1.default.prompt({
834248
+ type: 'list',
834249
+ name: 'runtime',
834250
+ message: (0, i18n_1.t)('请选择运行时'),
834251
+ choices: constant_1.RuntimeOptions
834252
+ });
834253
+ return runtime;
834254
+ });
834255
+ }
833814
834256
  };
833815
834257
  __decorate([
833816
834258
  (0, decorators_1.InjectParams)(),
@@ -845628,7 +846070,7 @@ function listEnvs(options = {}) {
845628
846070
  Channels: ['dcloud']
845629
846071
  });
845630
846072
  let { EnvList = [] } = res;
845631
- if (source && Array.isArray(source)) {
846073
+ if (source && Array.isArray(source) && source.length > 0) {
845632
846074
  EnvList = EnvList.filter((item) => source.includes(item.Source));
845633
846075
  }
845634
846076
  return EnvList;
@@ -891408,7 +891850,7 @@ class CloudBase {
891408
891850
  }
891409
891851
  constructor(config = {}) {
891410
891852
  this.cloudBaseConfig = {};
891411
- let { secretId, secretKey, token, envId, proxy, region, envType } = config;
891853
+ let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
891412
891854
  // config 中传入的 secretId secretkey 必须同时存在
891413
891855
  if ((secretId && !secretKey) || (!secretId && secretKey)) {
891414
891856
  throw new Error('secretId and secretKey must be a pair');
@@ -891420,7 +891862,8 @@ class CloudBase {
891420
891862
  envId,
891421
891863
  envType,
891422
891864
  proxy,
891423
- region
891865
+ region,
891866
+ useInternalEndpoint
891424
891867
  };
891425
891868
  // 初始化 context
891426
891869
  this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
@@ -891475,6 +891918,9 @@ class CloudBase {
891475
891918
  getManagerConfig() {
891476
891919
  return this.cloudBaseConfig;
891477
891920
  }
891921
+ get isInternalEndpoint() {
891922
+ return this.context.isInternalEndpoint();
891923
+ }
891478
891924
  }
891479
891925
  module.exports = CloudBase;
891480
891926
 
@@ -898412,6 +898858,7 @@ exports.FunctionService = void 0;
898412
898858
  const fs_1 = __importDefault(__webpack_require__(79896));
898413
898859
  const path_1 = __importDefault(__webpack_require__(16928));
898414
898860
  const lodash_1 = __importDefault(__webpack_require__(24924));
898861
+ const cos_nodejs_sdk_v5_1 = __importDefault(__webpack_require__(93625));
898415
898862
  const packer_1 = __webpack_require__(5147);
898416
898863
  const error_1 = __webpack_require__(40430);
898417
898864
  const utils_1 = __webpack_require__(62358);
@@ -898476,6 +898923,14 @@ function configToParams(options) {
898476
898923
  }));
898477
898924
  params.Layers = transformLayers;
898478
898925
  }
898926
+ // HTTP 云函数类型
898927
+ if ((func === null || func === void 0 ? void 0 : func.type) === 'HTTP') {
898928
+ params.Type = 'HTTP';
898929
+ }
898930
+ // 云函数描述
898931
+ if (func === null || func === void 0 ? void 0 : func.description) {
898932
+ params.Description = func.description;
898933
+ }
898479
898934
  return params;
898480
898935
  }
898481
898936
  class FunctionService {
@@ -898484,6 +898939,7 @@ class FunctionService {
898484
898939
  this.scfService = new utils_1.CloudService(environment.cloudBaseContext, 'scf', '2018-04-16');
898485
898940
  this.vpcService = new utils_1.CloudService(environment.cloudBaseContext, 'vpc', '2017-03-12');
898486
898941
  this.tcbService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
898942
+ this.userService = environment.getUserService();
898487
898943
  }
898488
898944
  /**
898489
898945
  * 增量更新函数代码
@@ -898492,12 +898948,12 @@ class FunctionService {
898492
898948
  * @memberof FunctionService
898493
898949
  */
898494
898950
  async updateFunctionIncrementalCode(funcParam) {
898495
- const { namespace } = this.getFunctionConfig();
898951
+ const { env } = this.getFunctionConfig();
898496
898952
  const { functionRootPath, func, deleteFiles, addFiles } = funcParam;
898497
898953
  const { name, runtime } = func;
898498
898954
  const params = {
898499
898955
  FunctionName: name,
898500
- Namespace: namespace
898956
+ EnvId: env
898501
898957
  };
898502
898958
  let packer;
898503
898959
  let base64;
@@ -898521,7 +898977,7 @@ class FunctionService {
898521
898977
  }
898522
898978
  params.AddFiles = base64;
898523
898979
  }
898524
- return this.scfService.request('UpdateFunctionIncrementalCode', params);
898980
+ return this.tcbService.request('UpdateFunctionIncrementalCode', params);
898525
898981
  }
898526
898982
  /**
898527
898983
  * 创建云函数
@@ -898529,14 +898985,14 @@ class FunctionService {
898529
898985
  * @returns {(Promise<IResponseInfo | ICreateFunctionRes>)}
898530
898986
  */
898531
898987
  async createFunction(funcParam) {
898532
- const { namespace } = this.getFunctionConfig();
898533
- const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath } = funcParam;
898988
+ const { env } = this.getFunctionConfig();
898989
+ const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode } = funcParam;
898534
898990
  const funcName = func.name;
898535
898991
  const params = configToParams({
898536
898992
  func,
898537
898993
  codeSecret,
898538
898994
  baseParams: {
898539
- Namespace: namespace,
898995
+ EnvId: env,
898540
898996
  Role: 'TCB_QcsRole',
898541
898997
  Stamp: 'MINI_QCBASE'
898542
898998
  }
@@ -898545,14 +899001,15 @@ class FunctionService {
898545
899001
  func,
898546
899002
  base64Code,
898547
899003
  functionPath,
898548
- functionRootPath
899004
+ functionRootPath,
899005
+ deployMode
898549
899006
  }, params.InstallDependency);
898550
899007
  const { TopicId, LogsetId } = this.getClsServiceConfig();
898551
899008
  params.ClsTopicId = TopicId;
898552
899009
  params.ClsLogsetId = LogsetId;
898553
899010
  try {
898554
899011
  // 创建云函数
898555
- const res = await this.scfService.request('CreateFunction', params);
899012
+ const res = await this.tcbService.request('CreateFunction', params);
898556
899013
  // 等待函数状态正常
898557
899014
  await this.waitFunctionActive(funcName, codeSecret);
898558
899015
  // 创建函数触发器、失败自动重试
@@ -898621,9 +899078,9 @@ class FunctionService {
898621
899078
  */
898622
899079
  async getFunctionList(limit = 20, offset = 0) {
898623
899080
  // 获取Function 环境配置
898624
- const { namespace } = this.getFunctionConfig();
898625
- const res = await this.scfService.request('ListFunctions', {
898626
- Namespace: namespace,
899081
+ const { env } = this.getFunctionConfig();
899082
+ const res = await this.tcbService.request('ListFunctions', {
899083
+ EnvId: env,
898627
899084
  Limit: limit,
898628
899085
  Offset: offset
898629
899086
  });
@@ -898754,16 +899211,17 @@ class FunctionService {
898754
899211
  * @returns {Promise<Record<string, string>>}
898755
899212
  */
898756
899213
  async getFunctionDetail(name, codeSecret) {
898757
- const { namespace } = this.getFunctionConfig();
899214
+ const { env } = this.getFunctionConfig();
898758
899215
  const params = {
898759
899216
  FunctionName: name,
898760
- Namespace: namespace,
898761
- ShowCode: 'TRUE'
899217
+ EnvId: env,
899218
+ ShowCode: 'TRUE',
899219
+ Namespace: env
898762
899220
  };
898763
899221
  if (codeSecret) {
898764
899222
  params.CodeSecret = codeSecret;
898765
899223
  }
898766
- const data = await this.scfService.request('GetFunction', params);
899224
+ const data = await this.tcbService.request('GetFunction', params);
898767
899225
  // 解析 VPC 配置
898768
899226
  const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
898769
899227
  if (VpcId && SubnetId) {
@@ -898953,6 +899411,9 @@ class FunctionService {
898953
899411
  Namespace: namespace,
898954
899412
  L5Enable: l5Enable
898955
899413
  };
899414
+ if (func === null || func === void 0 ? void 0 : func.description) {
899415
+ params.Description = func.description;
899416
+ }
898956
899417
  // 修复参数存在 undefined 字段时,会出现鉴权失败的情况
898957
899418
  // Environment 为覆盖式修改,不保留已有字段
898958
899419
  envVariables.length && (params.Environment = { Variables: envVariables });
@@ -899009,9 +899470,9 @@ class FunctionService {
899009
899470
  * @memberof FunctionService
899010
899471
  */
899011
899472
  async updateFunctionCode(funcParam) {
899012
- const { func, functionRootPath, base64Code, codeSecret, functionPath } = funcParam;
899473
+ const { func, functionRootPath, base64Code, codeSecret, functionPath, deployMode } = funcParam;
899013
899474
  const funcName = func.name;
899014
- const { namespace } = this.getFunctionConfig();
899475
+ const { env } = this.getFunctionConfig();
899015
899476
  let installDependency;
899016
899477
  // Node 函数默认安装依赖
899017
899478
  installDependency = isNodeFunction(func.runtime) ? 'TRUE' : 'FALSE';
@@ -899023,9 +899484,16 @@ class FunctionService {
899023
899484
  func,
899024
899485
  functionPath,
899025
899486
  functionRootPath,
899026
- base64Code
899487
+ base64Code,
899488
+ deployMode
899027
899489
  }, installDependency);
899028
- const params = Object.assign({ FunctionName: funcName, Namespace: namespace, Handler: func.handler || 'index.main', InstallDependency: installDependency }, codeParams);
899490
+ const params = {
899491
+ FunctionName: funcName,
899492
+ EnvId: env,
899493
+ Handler: func.handler || 'index.main',
899494
+ InstallDependency: installDependency,
899495
+ Code: codeParams
899496
+ };
899029
899497
  if (codeSecret) {
899030
899498
  params.CodeSecret = codeSecret;
899031
899499
  }
@@ -899033,7 +899501,7 @@ class FunctionService {
899033
899501
  // 等待函数状态正常
899034
899502
  await this.waitFunctionActive(funcName, codeSecret);
899035
899503
  // 更新云函数代码
899036
- const res = await this.scfService.request('UpdateFunctionCode', params);
899504
+ const res = await this.tcbService.request('UpdateFunctionCode', params);
899037
899505
  if (installDependency && func.isWaitInstall === true) {
899038
899506
  await this.waitFunctionActive(funcName, codeSecret);
899039
899507
  }
@@ -899388,6 +899856,45 @@ class FunctionService {
899388
899856
  LayerVersion: version
899389
899857
  });
899390
899858
  }
899859
+ // 检查函数状态,部分操作在函数更新中时不可进行
899860
+ async waitFunctionActive(funcName, codeSecret) {
899861
+ let ticker;
899862
+ let timer;
899863
+ let resolved;
899864
+ return new Promise((resolve, reject) => {
899865
+ // 超时时间 5 分钟
899866
+ timer = setTimeout(() => {
899867
+ clearInterval(ticker);
899868
+ if (!resolved) {
899869
+ reject(new error_1.CloudBaseError('函数状态异常,检查超时'));
899870
+ }
899871
+ }, 300000);
899872
+ ticker = setInterval(async () => {
899873
+ try {
899874
+ const { Status, StatusDesc, StatusReasons, RequestId } = await this.getFunctionDetail(funcName, codeSecret);
899875
+ // 更新中
899876
+ if (Status === constant_1.SCF_STATUS.CREATING || Status === constant_1.SCF_STATUS.UPDATING)
899877
+ return;
899878
+ // 创建失败
899879
+ if (Status === constant_1.SCF_STATUS.CREATE_FAILED) {
899880
+ StatusDesc && console.log(`函数状态描述: ${StatusDesc}`);
899881
+ const errorDetails = StatusReasons.map(item => `[${item.ErrorCode}] ${item.ErrorMessage}`).join('\n');
899882
+ throw new error_1.CloudBaseError(`云函数创建失败\n失败信息: ${errorDetails}\nRequestId: ${RequestId}`);
899883
+ }
899884
+ // 函数状态正常
899885
+ clearInterval(ticker);
899886
+ clearTimeout(timer);
899887
+ resolve();
899888
+ }
899889
+ catch (e) {
899890
+ clearInterval(ticker);
899891
+ clearTimeout(timer);
899892
+ reject(e);
899893
+ }
899894
+ resolved = true;
899895
+ }, 1000);
899896
+ });
899897
+ }
899391
899898
  /**
899392
899899
  * 设置预置并发
899393
899900
  * @private
@@ -899503,6 +900010,114 @@ class FunctionService {
899503
900010
  Namespace: namespace
899504
900011
  });
899505
900012
  }
900013
+ /**
900014
+ * 通过scf COS 上传方式(通过 GetTempCosInfo + COS SDK 上传)
900015
+ * 返回 TempCosObjectName 用于创建/更新函数
900016
+ */
900017
+ async uploadFunctionZipToCosLegacy(options, installDependency) {
900018
+ const { func, functionPath, functionRootPath } = options;
900019
+ const { env } = this.getFunctionConfig();
900020
+ const { CloudAppId } = await this.userService.getTcbAccountInfo();
900021
+ const objectPath = `${CloudAppId}/${env}/${func.name}.zip`;
900022
+ // 1. 生成存放函数包的临时 Cos 目录
900023
+ const { Date: cosDate, Sign } = await this.scfService.request('GetTempCosInfo', {
900024
+ ObjectPath: `${objectPath}`
900025
+ });
900026
+ // 2. 本地压缩
900027
+ const codeType = packer_1.CodeType.File;
900028
+ // 云端安装依赖,自动忽略 node_modules 目录
900029
+ const ignore = installDependency === 'TRUE'
900030
+ ? ['node_modules/**/*', 'node_modules', ...(func.ignore || [])]
900031
+ : [...(func.ignore || [])];
900032
+ const packer = new packer_1.FunctionPacker({
900033
+ ignore,
900034
+ codeType,
900035
+ functionPath,
900036
+ name: func.name,
900037
+ root: functionRootPath
900038
+ });
900039
+ const zipFilePath = await packer.compressFiles();
900040
+ // 3. 初始化 cos 并上传
900041
+ const tempCosObjectName = `/${cosDate}/${objectPath}`;
900042
+ const TEMP_COS_APPID = '1253665819';
900043
+ const uploadParams = {
900044
+ Bucket: `shtempcos-${TEMP_COS_APPID}`,
900045
+ Key: tempCosObjectName,
900046
+ Region: 'ap-shanghai',
900047
+ FilePath: zipFilePath,
900048
+ };
900049
+ const cos = new cos_nodejs_sdk_v5_1.default({
900050
+ getAuthorization: function (options, callback) {
900051
+ // 注入上一步获取的临时密钥
900052
+ callback(Sign);
900053
+ }
900054
+ });
900055
+ return new Promise((resolve, reject) => {
900056
+ cos.sliceUploadFile(uploadParams, async (err, data) => {
900057
+ // 清理临时文件
900058
+ await packer.clean();
900059
+ if (err) {
900060
+ reject(err);
900061
+ }
900062
+ else {
900063
+ resolve(data);
900064
+ }
900065
+ });
900066
+ });
900067
+ }
900068
+ /**
900069
+ * 新的 COS 上传方式(通过 DescribeBuildServiceCosInfo + PUT 上传)
900070
+ * 返回 CosTimestamp 用于创建/更新函数
900071
+ */
900072
+ async uploadFunctionZipToCos(options, installDependency) {
900073
+ const { func, functionPath, functionRootPath } = options;
900074
+ const { env } = this.getFunctionConfig();
900075
+ // 1. 生成存放函数包的临时 Cos 目录
900076
+ const { UploadUrl, UnixTimestamp, UploadHeaders } = await this.tcbService.request('DescribeBuildServiceCosInfo', {
900077
+ EnvId: env,
900078
+ ServiceName: func.name,
900079
+ Business: 'scf',
900080
+ Suffix: '.zip'
900081
+ });
900082
+ // 2. 本地压缩
900083
+ const codeType = packer_1.CodeType.File;
900084
+ // 云端安装依赖,自动忽略 node_modules 目录
900085
+ const ignore = installDependency === 'TRUE'
900086
+ ? ['node_modules/**/*', 'node_modules', ...(func.ignore || [])]
900087
+ : [...(func.ignore || [])];
900088
+ const packer = new packer_1.FunctionPacker({
900089
+ ignore,
900090
+ codeType,
900091
+ functionPath,
900092
+ name: func.name,
900093
+ root: functionRootPath
900094
+ });
900095
+ const zipFilePath = await packer.compressFiles();
900096
+ // 3. 通过 UploadUrl 直接上传
900097
+ const fileBuffer = fs_1.default.readFileSync(zipFilePath);
900098
+ // 构建请求头
900099
+ const headers = {
900100
+ 'Content-Type': 'application/zip'
900101
+ };
900102
+ if (UploadHeaders && UploadHeaders.length > 0) {
900103
+ UploadHeaders.forEach(item => {
900104
+ headers[item.Key] = item.Value;
900105
+ });
900106
+ }
900107
+ const response = await fetch(UploadUrl, {
900108
+ method: 'PUT',
900109
+ body: fileBuffer,
900110
+ headers
900111
+ });
900112
+ if (!response.ok) {
900113
+ throw new error_1.CloudBaseError(`上传失败: ${response.status} ${response.statusText}`);
900114
+ }
900115
+ // 清理临时文件
900116
+ await packer.clean();
900117
+ return {
900118
+ UnixTimestamp
900119
+ };
900120
+ }
899506
900121
  async createAccessPath(name, path) {
899507
900122
  const access = this.environment.getAccessService();
899508
900123
  try {
@@ -899527,11 +900142,13 @@ class FunctionService {
899527
900142
  }
899528
900143
  }
899529
900144
  async getCodeParams(options, installDependency) {
899530
- const { func, functionPath, functionRootPath, base64Code } = options;
899531
- // 20MB
899532
- const BIG_LENGTH = 167772160;
899533
- if ((base64Code === null || base64Code === void 0 ? void 0 : base64Code.length) > BIG_LENGTH) {
899534
- throw new error_1.CloudBaseError('base64 不能大于 20 MB');
900145
+ const { func, functionPath, functionRootPath, base64Code, deployMode } = options;
900146
+ // 更新的时候直接上传的zip包的情况
900147
+ // ZIP 包大小上限 20MB,base64 编码后长度约为原始大小的 4/3
900148
+ const MAX_ZIP_SIZE = 20 * 1024 * 1024; // 20MB
900149
+ const MAX_BASE64_LENGTH = Math.floor(MAX_ZIP_SIZE * 4 / 3); // ≈ 27962026
900150
+ if ((base64Code === null || base64Code === void 0 ? void 0 : base64Code.length) > MAX_BASE64_LENGTH) {
900151
+ throw new error_1.CloudBaseError('ZIP 包不能大于 20MB');
899535
900152
  }
899536
900153
  if (base64Code === null || base64Code === void 0 ? void 0 : base64Code.length) {
899537
900154
  return {
@@ -899551,11 +900168,22 @@ class FunctionService {
899551
900168
  root: functionRootPath
899552
900169
  });
899553
900170
  await packer.build();
899554
- // 通过云 API 传输的代码大小不能超过 50MB
900171
+ // 如果指定了上传方式,按指定方式上传
900172
+ // 判断是否需要走 COS 上传
899555
900173
  const reachMax = await packer.isReachMaxSize();
899556
- if (reachMax) {
899557
- throw new error_1.CloudBaseError('函数代码不能大于 50MB');
900174
+ const useCos = deployMode === 'cos' || (deployMode !== 'zip' && reachMax);
900175
+ if (useCos) {
900176
+ // 先调用scf的 COS 上传方式
900177
+ const legacyResult = await this.uploadFunctionZipToCosLegacy(options, installDependency);
900178
+ // 再调用tcb COS 上传方式
900179
+ const cosResult = await this.uploadFunctionZipToCos(options, installDependency);
900180
+ return {
900181
+ CosTimestamp: cosResult.UnixTimestamp,
900182
+ CosBucketRegion: 'ap-shanghai',
900183
+ TempCosObjectName: `/${legacyResult.Key}`
900184
+ };
899558
900185
  }
900186
+ // ZIP base64 上传
899559
900187
  const base64 = await packer.getBase64Code();
899560
900188
  if (!(base64 === null || base64 === void 0 ? void 0 : base64.length)) {
899561
900189
  throw new error_1.CloudBaseError('文件不能为空');
@@ -899649,45 +900277,6 @@ class FunctionService {
899649
900277
  });
899650
900278
  return SubnetSet;
899651
900279
  }
899652
- // 检查函数状态,部分操作在函数更新中时不可进行
899653
- async waitFunctionActive(funcName, codeSecret) {
899654
- let ticker;
899655
- let timer;
899656
- let resolved;
899657
- return new Promise((resolve, reject) => {
899658
- // 超时时间 5 分钟
899659
- timer = setTimeout(() => {
899660
- clearInterval(ticker);
899661
- if (!resolved) {
899662
- reject(new error_1.CloudBaseError('函数状态异常,检查超时'));
899663
- }
899664
- }, 300000);
899665
- ticker = setInterval(async () => {
899666
- try {
899667
- const { Status, StatusDesc, StatusReasons, RequestId } = await this.getFunctionDetail(funcName, codeSecret);
899668
- // 更新中
899669
- if (Status === constant_1.SCF_STATUS.CREATING || Status === constant_1.SCF_STATUS.UPDATING)
899670
- return;
899671
- // 创建失败
899672
- if (Status === constant_1.SCF_STATUS.CREATE_FAILED) {
899673
- StatusDesc && console.log(`函数状态描述: ${StatusDesc}`);
899674
- const errorDetails = StatusReasons.map(item => `[${item.ErrorCode}] ${item.ErrorMessage}`).join('\n');
899675
- throw new error_1.CloudBaseError(`云函数创建失败\n失败信息: ${errorDetails}\nRequestId: ${RequestId}`);
899676
- }
899677
- // 函数状态正常
899678
- clearInterval(ticker);
899679
- clearTimeout(timer);
899680
- resolve();
899681
- }
899682
- catch (e) {
899683
- clearInterval(ticker);
899684
- clearTimeout(timer);
899685
- reject(e);
899686
- }
899687
- resolved = true;
899688
- }, 1000);
899689
- });
899690
- }
899691
900280
  }
899692
900281
  exports.FunctionService = FunctionService;
899693
900282
  __decorate([
@@ -899798,6 +900387,12 @@ __decorate([
899798
900387
  __decorate([
899799
900388
  (0, utils_1.preLazy)()
899800
900389
  ], FunctionService.prototype, "getFunctionAlias", null);
900390
+ __decorate([
900391
+ (0, utils_1.preLazy)()
900392
+ ], FunctionService.prototype, "uploadFunctionZipToCosLegacy", null);
900393
+ __decorate([
900394
+ (0, utils_1.preLazy)()
900395
+ ], FunctionService.prototype, "uploadFunctionZipToCos", null);
899801
900396
  __decorate([
899802
900397
  (0, utils_1.preLazy)()
899803
900398
  ], FunctionService.prototype, "createAccessPath", null);
@@ -900639,7 +901234,7 @@ const ActionVersionMap = {
900639
901234
  flexdb: '2018-11-27',
900640
901235
  scf: '2018-04-16',
900641
901236
  sts: '2018-04-16',
900642
- cam: '2018-04-16',
901237
+ cam: '2019-01-16',
900643
901238
  lowcode: '2021-01-08'
900644
901239
  };
900645
901240
  class CommonService {