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