@cloudbase/cli 2.12.6 → 2.12.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/standalone/cli.js +622 -329
- package/package.json +1 -1
package/dist/standalone/cli.js
CHANGED
|
@@ -2447,6 +2447,80 @@ function* pattern(...rest) {
|
|
|
2447
2447
|
}
|
|
2448
2448
|
//# sourceMappingURL=exec.js.map
|
|
2449
2449
|
|
|
2450
|
+
/***/ }),
|
|
2451
|
+
|
|
2452
|
+
/***/ 325:
|
|
2453
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
2454
|
+
|
|
2455
|
+
"use strict";
|
|
2456
|
+
|
|
2457
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
2458
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
2459
|
+
};
|
|
2460
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
2461
|
+
exports.validateImageDeploy = exports.resolveFuncPathWithConfig = exports.resolveFunctionName = exports.resolveAndValidateFunctionDir = void 0;
|
|
2462
|
+
const path_1 = __importDefault(__webpack_require__(16928));
|
|
2463
|
+
const error_1 = __webpack_require__(66759);
|
|
2464
|
+
const i18n_1 = __webpack_require__(69258);
|
|
2465
|
+
const utils_1 = __webpack_require__(82079);
|
|
2466
|
+
function resolveAndValidateFunctionDir(options) {
|
|
2467
|
+
const { dir, defaultDir, action, log } = options;
|
|
2468
|
+
let targetDir = defaultDir;
|
|
2469
|
+
if (dir) {
|
|
2470
|
+
(0, utils_1.checkFullAccess)(dir, true);
|
|
2471
|
+
if (!(0, utils_1.isDirectory)(dir)) {
|
|
2472
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('--dir 参数必须指定为云函数的文件夹路径'));
|
|
2473
|
+
}
|
|
2474
|
+
targetDir = path_1.default.resolve(defaultDir, dir);
|
|
2475
|
+
log === null || log === void 0 ? void 0 : log.info((0, i18n_1.t)(`将从目录 {{dir}} ${action}云函数`, { dir: targetDir }));
|
|
2476
|
+
}
|
|
2477
|
+
else {
|
|
2478
|
+
log === null || log === void 0 ? void 0 : log.info((0, i18n_1.t)(`未找到配置文件,将从当前目录${action}云函数`));
|
|
2479
|
+
}
|
|
2480
|
+
return targetDir;
|
|
2481
|
+
}
|
|
2482
|
+
exports.resolveAndValidateFunctionDir = resolveAndValidateFunctionDir;
|
|
2483
|
+
function resolveFunctionName(name, deployDir) {
|
|
2484
|
+
return name || path_1.default.basename(deployDir);
|
|
2485
|
+
}
|
|
2486
|
+
exports.resolveFunctionName = resolveFunctionName;
|
|
2487
|
+
function resolveFuncPathWithConfig(options) {
|
|
2488
|
+
const { dir, funcDir, functionRootPath, name, deployMode, log } = options;
|
|
2489
|
+
if (deployMode === 'image') {
|
|
2490
|
+
return '';
|
|
2491
|
+
}
|
|
2492
|
+
let funcPath = '';
|
|
2493
|
+
if (dir) {
|
|
2494
|
+
(0, utils_1.checkFullAccess)(dir, true);
|
|
2495
|
+
if (!(0, utils_1.isDirectory)(dir)) {
|
|
2496
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('--dir 参数必须指定为云函数的文件夹路径'));
|
|
2497
|
+
}
|
|
2498
|
+
funcPath = path_1.default.resolve(process.cwd(), dir);
|
|
2499
|
+
log.info((0, i18n_1.t)('使用命令行指定的目录:{{path}}', { path: funcPath }));
|
|
2500
|
+
}
|
|
2501
|
+
else if (funcDir) {
|
|
2502
|
+
funcPath = path_1.default.resolve(process.cwd(), funcDir);
|
|
2503
|
+
log.info((0, i18n_1.t)('使用配置文件中的目录:{{path}}', { path: funcPath }));
|
|
2504
|
+
}
|
|
2505
|
+
else {
|
|
2506
|
+
funcPath = path_1.default.join(functionRootPath, name);
|
|
2507
|
+
}
|
|
2508
|
+
return funcPath;
|
|
2509
|
+
}
|
|
2510
|
+
exports.resolveFuncPathWithConfig = resolveFuncPathWithConfig;
|
|
2511
|
+
function validateImageDeploy(deployMode, hasConfig) {
|
|
2512
|
+
if (deployMode === 'image') {
|
|
2513
|
+
if (hasConfig === false) {
|
|
2514
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('镜像部署时需要在配置文件中指定 imageConfig'));
|
|
2515
|
+
}
|
|
2516
|
+
if (hasConfig === undefined) {
|
|
2517
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('镜像部署时需要在配置文件中指定函数配置和 imageConfig'));
|
|
2518
|
+
}
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
exports.validateImageDeploy = validateImageDeploy;
|
|
2522
|
+
|
|
2523
|
+
|
|
2450
2524
|
/***/ }),
|
|
2451
2525
|
|
|
2452
2526
|
/***/ 340:
|
|
@@ -326254,7 +326328,7 @@ module.exports = function generate_pattern(it, $keyword, $ruleType) {
|
|
|
326254
326328
|
/***/ ((module) => {
|
|
326255
326329
|
|
|
326256
326330
|
"use strict";
|
|
326257
|
-
module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"2.12.
|
|
326331
|
+
module.exports = /*#__PURE__*/JSON.parse('{"name":"@cloudbase/cli","version":"2.12.8","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.10.6","@cloudbase/toolbox":"0.7.17","@dotenvx/dotenvx":"^1.48.3","@musistudio/claude-code-router":"1.0.36","address":"^1.1.2","camelcase-keys":"^7.0.2","chalk":"^2.4.2","cli-table3":"^0.5.1","commander":"7","del":"^5.1.0","didyoumean":"^1.2.2","enquirer":"^2.3.6","execa":"^4.0.3","figlet":"^1.7.0","fs-extra":"^8.1.0","gradient-string":"^2.0.2","https-proxy-agent":"^5.0.1","i":"^0.3.7","inquirer":"^6.5.0","json-schema-to-typescript":"^14.0.5","lodash":"^4.17.21","log-symbols":"^3.0.0","lowdb":"^1.0.0","make-dir":"^3.0.0","node-fetch":"^2.6.0","nodemon":"^3.1.4","npm":"^11.5.2","open":"^7.0.0","ora":"^4.0.2","os-locale":"5.0.0","patch-package":"^8.0.0","portfinder":"^1.0.28","progress":"^2.0.3","query-string":"^6.8.1","reflect-metadata":"^0.1.13","semver":"^7.3.7","simple-git":"^3.28.0","tar-fs":"^2.0.1","terminal-link":"^2.1.1","toml":"^3.0.0","unzipper":"^0.10.10","update-notifier":"^4.0.0","xdg-basedir":"^4.0.0","yargs":"^16.2.0","yargs-parser":"^21.0.1","zod":"^4.0.13"},"devDependencies":{"@babel/parser":"^7.28.4","@babel/traverse":"^7.28.4","@babel/types":"^7.28.4","@types/fs-extra":"^11.0.4","@types/jest":"^27","@types/koa__router":"^8.0.11","@types/lodash":"^4.14.182","@types/node":"^12.12.38","@types/node-fetch":"^2.5.4","@types/react":"^17.0.37","@types/semver":"^7.3.9","@types/unzipper":"^0.10.11","@types/webpack-dev-server":"^3.11.1","@typescript-eslint/eslint-plugin":"^4.8.1","@typescript-eslint/parser":"^4.8.1","cpx":"^1.5.0","eslint":"^7.14.0","eslint-config-alloy":"^3.8.2","husky":"^3.0.9","i18next-scanner":"^4.6.0","jest":"^27","rimraf":"^3.0.2","ts-jest":"^27","typescript":"^4.7.2","webpack":"^5.92.0","webpack-cli":"^5.1.4"},"packageManager":"yarn@3.6.2+sha512.2c2f8b9615e6659773f65cdec7cf92ef773a98a99e611579601f61c7a91ec94c89c929aac86f1cee819421a9b0db7acfd53ec3ebb95af44f77f77634b08b9557","ai":{"skills":"./skills","skillsIndex":"./skills/index.json","compatible":["codebuddy","cursor","copilot","claude","windsurf"],"description":"CloudBase CLI - 腾讯云云开发命令行工具,支持云函数、云数据库、静态托管等全栈云开发能力"}}');
|
|
326258
326332
|
|
|
326259
326333
|
/***/ }),
|
|
326260
326334
|
|
|
@@ -467668,6 +467742,7 @@ const decorators_1 = __webpack_require__(93480);
|
|
|
467668
467742
|
const i18n_1 = __webpack_require__(69258);
|
|
467669
467743
|
const utils_2 = __webpack_require__(75213);
|
|
467670
467744
|
const constant_1 = __webpack_require__(62977);
|
|
467745
|
+
const common_utils_1 = __webpack_require__(325);
|
|
467671
467746
|
let CodeUpdate = class CodeUpdate extends common_1.Command {
|
|
467672
467747
|
get options() {
|
|
467673
467748
|
return {
|
|
@@ -467723,9 +467798,7 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
|
|
|
467723
467798
|
}
|
|
467724
467799
|
const configFiles = ['cloudbaserc.json', 'cloudbaserc.js', 'cloudbaserc.yaml', 'cloudbaserc.yml', 'cloudbaserc', 'cloudbase.config.js'];
|
|
467725
467800
|
const hasConfigFile = configFiles.some(file => fs_1.default.existsSync(path_1.default.join(process.cwd(), file)));
|
|
467726
|
-
|
|
467727
|
-
throw new error_1.CloudBaseError((0, i18n_1.t)('镜像部署时需要在配置文件中指定 imageConfig,请创建 cloudbaserc.json 并配置镜像参数'));
|
|
467728
|
-
}
|
|
467801
|
+
(0, common_utils_1.validateImageDeploy)(deployMode, hasConfigFile ? undefined : false);
|
|
467729
467802
|
const hasConfig = hasConfigFile || functions.length > 0;
|
|
467730
467803
|
if (hasConfig) {
|
|
467731
467804
|
return this.updateWithConfig({ name, dir, envId, codeSecret, deployMode, config, functions, log });
|
|
@@ -467743,26 +467816,19 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
|
|
|
467743
467816
|
log.info((0, i18n_1.t)('从配置文件读取函数 [{{name}}] 的配置', { name }));
|
|
467744
467817
|
}
|
|
467745
467818
|
else {
|
|
467819
|
+
(0, common_utils_1.validateImageDeploy)(deployMode, undefined);
|
|
467746
467820
|
func = Object.assign({ name }, constant_1.DefaultFunctionDeployConfig);
|
|
467747
467821
|
log.info((0, i18n_1.t)('未找到函数 [{{name}}] 的配置,使用默认配置', { name }));
|
|
467748
467822
|
}
|
|
467749
467823
|
const functionRootPath = path_1.default.join(process.cwd(), config.functionRoot || 'functions');
|
|
467750
|
-
|
|
467751
|
-
|
|
467752
|
-
|
|
467753
|
-
|
|
467754
|
-
|
|
467755
|
-
|
|
467756
|
-
|
|
467757
|
-
|
|
467758
|
-
}
|
|
467759
|
-
else if (func === null || func === void 0 ? void 0 : func.dir) {
|
|
467760
|
-
funcPath = path_1.default.resolve(process.cwd(), func.dir);
|
|
467761
|
-
log.info((0, i18n_1.t)('使用配置文件中的目录:{{path}}', { path: funcPath }));
|
|
467762
|
-
}
|
|
467763
|
-
else {
|
|
467764
|
-
funcPath = path_1.default.join(functionRootPath, name);
|
|
467765
|
-
}
|
|
467824
|
+
const funcPath = (0, common_utils_1.resolveFuncPathWithConfig)({
|
|
467825
|
+
dir,
|
|
467826
|
+
funcDir: func === null || func === void 0 ? void 0 : func.dir,
|
|
467827
|
+
functionRootPath,
|
|
467828
|
+
name,
|
|
467829
|
+
deployMode,
|
|
467830
|
+
log
|
|
467831
|
+
});
|
|
467766
467832
|
return this.doUpdateCode({
|
|
467767
467833
|
func, funcPath, functionRootPath, envId, codeSecret, deployMode,
|
|
467768
467834
|
functionPath: dir ? funcPath : undefined, log
|
|
@@ -467772,18 +467838,13 @@ let CodeUpdate = class CodeUpdate extends common_1.Command {
|
|
|
467772
467838
|
updateWithoutConfig(options) {
|
|
467773
467839
|
return __awaiter(this, void 0, void 0, function* () {
|
|
467774
467840
|
const { name, dir, envId, codeSecret, deployMode, log } = options;
|
|
467775
|
-
|
|
467776
|
-
|
|
467777
|
-
|
|
467778
|
-
|
|
467779
|
-
|
|
467780
|
-
|
|
467781
|
-
|
|
467782
|
-
log.info((0, i18n_1.t)('将从目录 {{dir}} 更新云函数代码', { dir: updateDir }));
|
|
467783
|
-
}
|
|
467784
|
-
else {
|
|
467785
|
-
log.info((0, i18n_1.t)('未找到配置文件,将从当前目录更新云函数代码'));
|
|
467786
|
-
}
|
|
467841
|
+
(0, common_utils_1.validateImageDeploy)(deployMode, false);
|
|
467842
|
+
const updateDir = (0, common_utils_1.resolveAndValidateFunctionDir)({
|
|
467843
|
+
dir,
|
|
467844
|
+
defaultDir: process.cwd(),
|
|
467845
|
+
action: '更新',
|
|
467846
|
+
log
|
|
467847
|
+
});
|
|
467787
467848
|
let inferredConfig = this.inferFunctionConfig(name, updateDir);
|
|
467788
467849
|
const isInferred = !!inferredConfig;
|
|
467789
467850
|
if (!inferredConfig) {
|
|
@@ -694008,9 +694069,10 @@ function updateFunctionCode(options) {
|
|
|
694008
694069
|
});
|
|
694009
694070
|
}
|
|
694010
694071
|
catch (e) {
|
|
694011
|
-
throw new error_1.CloudBaseError((0, i18n_1.t)('[{{name}}] 函数代码更新失败: {{error}}', { name: funcName, error: e.message }), {
|
|
694072
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('[{{name}}] 函数代码更新失败: {{error}}', { name: funcName, error: e.message || String(e) }), {
|
|
694012
694073
|
code: e.code,
|
|
694013
|
-
requestId: e.requestId
|
|
694074
|
+
requestId: e.requestId,
|
|
694075
|
+
original: e
|
|
694014
694076
|
});
|
|
694015
694077
|
}
|
|
694016
694078
|
});
|
|
@@ -724302,21 +724364,27 @@ class StorageService {
|
|
|
724302
724364
|
Error
|
|
724303
724365
|
};
|
|
724304
724366
|
}
|
|
724305
|
-
|
|
724306
|
-
* 获取文件存储权限
|
|
724307
|
-
* READONLY:所有用户可读,仅创建者和管理员可写
|
|
724308
|
-
* PRIVATE:仅创建者及管理员可读写
|
|
724309
|
-
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
724310
|
-
* ADMINONLY:仅管理员可读写
|
|
724311
|
-
* @returns
|
|
724312
|
-
*/
|
|
724313
|
-
async getStorageAcl() {
|
|
724367
|
+
async getStorageAcl(options) {
|
|
724314
724368
|
const { bucket, env } = this.getStorageConfig();
|
|
724315
|
-
const res = await this.tcbService.request('
|
|
724369
|
+
const res = await this.tcbService.request('DescribeStorageSafeRule', {
|
|
724316
724370
|
EnvId: env,
|
|
724317
724371
|
Bucket: bucket
|
|
724318
724372
|
});
|
|
724319
|
-
|
|
724373
|
+
// 默认行为:返回简单的 AclType(向后兼容)
|
|
724374
|
+
if (!(options === null || options === void 0 ? void 0 : options.withRule)) {
|
|
724375
|
+
return res.AclTag;
|
|
724376
|
+
}
|
|
724377
|
+
// 带规则模式:返回对象
|
|
724378
|
+
const result = { acl: res.AclTag };
|
|
724379
|
+
if (res.AclTag === 'CUSTOM' && res.Rule) {
|
|
724380
|
+
try {
|
|
724381
|
+
result.rule = JSON.parse(res.Rule);
|
|
724382
|
+
}
|
|
724383
|
+
catch (_a) {
|
|
724384
|
+
// Rule 可能不是 JSON 格式,忽略解析错误
|
|
724385
|
+
}
|
|
724386
|
+
}
|
|
724387
|
+
return result;
|
|
724320
724388
|
}
|
|
724321
724389
|
/**
|
|
724322
724390
|
* 设置文件存储权限
|
|
@@ -724324,20 +724392,38 @@ class StorageService {
|
|
|
724324
724392
|
* PRIVATE:仅创建者及管理员可读写
|
|
724325
724393
|
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
724326
724394
|
* ADMINONLY:仅管理员可读写
|
|
724327
|
-
*
|
|
724395
|
+
* CUSTOM:自定义安全规则(需要传入 rule 参数)
|
|
724396
|
+
* @param {AclType} acl 权限类型
|
|
724397
|
+
* @param {IStorageAclRule} [rule] 自定义安全规则,当 acl 为 CUSTOM 时必填
|
|
724328
724398
|
* @returns
|
|
724399
|
+
* @example
|
|
724400
|
+
* // 设置简易权限
|
|
724401
|
+
* await storage.setStorageAcl('READONLY')
|
|
724402
|
+
*
|
|
724403
|
+
* // 设置自定义安全规则
|
|
724404
|
+
* await storage.setStorageAcl('CUSTOM', {
|
|
724405
|
+
* read: true,
|
|
724406
|
+
* write: 'resource.openid == auth.uid'
|
|
724407
|
+
* })
|
|
724329
724408
|
*/
|
|
724330
|
-
async setStorageAcl(acl) {
|
|
724331
|
-
const validAcl = ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY'];
|
|
724409
|
+
async setStorageAcl(acl, rule) {
|
|
724410
|
+
const validAcl = ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY', 'CUSTOM'];
|
|
724332
724411
|
if (!validAcl.includes(acl)) {
|
|
724333
|
-
throw new error_1.CloudBaseError('
|
|
724412
|
+
throw new error_1.CloudBaseError(`非法的权限类型: "${acl}", 有效值: ${validAcl.join(', ')}`);
|
|
724413
|
+
}
|
|
724414
|
+
if (acl === 'CUSTOM' && !rule) {
|
|
724415
|
+
throw new error_1.CloudBaseError('使用 CUSTOM 权限类型时,必须提供 rule 参数');
|
|
724334
724416
|
}
|
|
724335
724417
|
const { bucket, env } = this.getStorageConfig();
|
|
724336
|
-
|
|
724418
|
+
const params = {
|
|
724337
724419
|
EnvId: env,
|
|
724338
724420
|
Bucket: bucket,
|
|
724339
724421
|
AclTag: acl
|
|
724340
|
-
}
|
|
724422
|
+
};
|
|
724423
|
+
if (acl === 'CUSTOM' && rule) {
|
|
724424
|
+
params.Rule = JSON.stringify(rule);
|
|
724425
|
+
}
|
|
724426
|
+
return this.tcbService.request('ModifyStorageSafeRule', params);
|
|
724341
724427
|
}
|
|
724342
724428
|
/**
|
|
724343
724429
|
* 遍历云端文件夹
|
|
@@ -726148,7 +726234,9 @@ const outputHelpInfo = () => {
|
|
|
726148
726234
|
hosting [cmd] ${(0, i18n_1.t)('静态托管资源管理操作')}
|
|
726149
726235
|
storage [cmd] ${(0, i18n_1.t)('云存储资源管理操作')}
|
|
726150
726236
|
service [cmd] ${(0, i18n_1.t)('HTTP 访问服务管理操作')}
|
|
726151
|
-
cloudrun [cmd] ${(0, i18n_1.t)('
|
|
726237
|
+
cloudrun [cmd] ${(0, i18n_1.t)('云托管服务管理操作')}
|
|
726238
|
+
config [cmd] ${(0, i18n_1.t)('配置文件管理操作')}
|
|
726239
|
+
gateway [cmd] ${(0, i18n_1.t)('网关管理操作')}
|
|
726152
726240
|
`;
|
|
726153
726241
|
const options = `
|
|
726154
726242
|
${(0, i18n_1.t)('选项')}
|
|
@@ -730339,8 +730427,8 @@ let GetAclCommand = class GetAclCommand extends common_1.Command {
|
|
|
730339
730427
|
execute(envId) {
|
|
730340
730428
|
return __awaiter(this, void 0, void 0, function* () {
|
|
730341
730429
|
const storageService = yield getStorageService(envId);
|
|
730342
|
-
const acl = yield storageService.getStorageAcl();
|
|
730343
|
-
console.log((0, i18n_1.t)('当前权限【{{acl}}】', { acl: AclMap[acl] }));
|
|
730430
|
+
const acl = yield storageService.getStorageAcl({ withRule: true });
|
|
730431
|
+
console.log((0, i18n_1.t)('当前权限【{{acl}}】', { acl: AclMap[acl.acl] }));
|
|
730344
730432
|
});
|
|
730345
730433
|
}
|
|
730346
730434
|
};
|
|
@@ -801619,9 +801707,12 @@ function inferNodejsConfig(targetDir, name, httpFn) {
|
|
|
801619
801707
|
runtime = 'Nodejs16.13';
|
|
801620
801708
|
}
|
|
801621
801709
|
}
|
|
801710
|
+
const hasDependencies = Boolean(packageJson.dependencies && Object.keys(packageJson.dependencies).length > 0);
|
|
801711
|
+
const hasDevDependencies = Boolean(packageJson.devDependencies && Object.keys(packageJson.devDependencies).length > 0);
|
|
801712
|
+
const shouldInstallDeps = hasDependencies || hasDevDependencies;
|
|
801622
801713
|
return {
|
|
801623
|
-
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime,
|
|
801624
|
-
handler, installDependency: true }), (httpFn ? { type: 'HTTP' } : {})),
|
|
801714
|
+
config: Object.assign(Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime,
|
|
801715
|
+
handler }), (shouldInstallDeps ? { installDependency: true } : {})), (httpFn ? { type: 'HTTP' } : {})),
|
|
801625
801716
|
source: (0, i18n_1.t)('Node.js 项目(package.json)')
|
|
801626
801717
|
};
|
|
801627
801718
|
}
|
|
@@ -801646,7 +801737,7 @@ function inferPythonConfig(targetDir, name, httpFn) {
|
|
|
801646
801737
|
}
|
|
801647
801738
|
}
|
|
801648
801739
|
return {
|
|
801649
|
-
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Python3.9', handler
|
|
801740
|
+
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Python3.9', handler }), (httpFn ? { type: 'HTTP' } : {})),
|
|
801650
801741
|
source: (0, i18n_1.t)('Python 项目({{file}})', { file: foundFile })
|
|
801651
801742
|
};
|
|
801652
801743
|
}
|
|
@@ -801679,7 +801770,7 @@ function inferPhpConfig(targetDir, name, httpFn) {
|
|
|
801679
801770
|
handler = 'index.main';
|
|
801680
801771
|
}
|
|
801681
801772
|
return {
|
|
801682
|
-
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Php8.0', handler
|
|
801773
|
+
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Php8.0', handler }), (httpFn ? { type: 'HTTP' } : {})),
|
|
801683
801774
|
source
|
|
801684
801775
|
};
|
|
801685
801776
|
}
|
|
@@ -801703,7 +801794,7 @@ function inferJavaConfig(targetDir, name, httpFn) {
|
|
|
801703
801794
|
}
|
|
801704
801795
|
}
|
|
801705
801796
|
return {
|
|
801706
|
-
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Java11', handler: 'example.Hello::mainHandler'
|
|
801797
|
+
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Java11', handler: 'example.Hello::mainHandler' }), (httpFn ? { type: 'HTTP' } : {})),
|
|
801707
801798
|
source: (0, i18n_1.t)('Java 项目({{file}})', { file: foundFile })
|
|
801708
801799
|
};
|
|
801709
801800
|
}
|
|
@@ -801726,7 +801817,7 @@ function inferGoConfig(targetDir, name, httpFn) {
|
|
|
801726
801817
|
}
|
|
801727
801818
|
}
|
|
801728
801819
|
return {
|
|
801729
|
-
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Go1', handler: 'main'
|
|
801820
|
+
config: Object.assign(Object.assign(Object.assign({ name: funcName }, constant_1.DefaultFunctionDeployConfig), { runtime: 'Go1', handler: 'main' }), (httpFn ? { type: 'HTTP' } : {})),
|
|
801730
801821
|
source: (0, i18n_1.t)('Go 项目({{file}})', { file: foundFile })
|
|
801731
801822
|
};
|
|
801732
801823
|
}
|
|
@@ -801759,7 +801850,7 @@ function inferByFileExtension(targetDir, name, httpFn) {
|
|
|
801759
801850
|
return null;
|
|
801760
801851
|
}
|
|
801761
801852
|
return {
|
|
801762
|
-
config: Object.assign(
|
|
801853
|
+
config: Object.assign({ name: funcName, timeout: constant_1.DefaultFunctionDeployConfig.timeout, runtime: typeConfig.runtime, handler: typeConfig.handler, ignore: constant_1.DefaultFunctionDeployConfig.ignore }, (httpFn ? { type: 'HTTP' } : {})),
|
|
801763
801854
|
source: typeConfig.source
|
|
801764
801855
|
};
|
|
801765
801856
|
}
|
|
@@ -835731,6 +835822,27 @@ const decorators_1 = __webpack_require__(93480);
|
|
|
835731
835822
|
const function_2 = __webpack_require__(11686);
|
|
835732
835823
|
const i18n_1 = __webpack_require__(69258);
|
|
835733
835824
|
const utils_2 = __webpack_require__(75213);
|
|
835825
|
+
const common_utils_1 = __webpack_require__(325);
|
|
835826
|
+
const MAX_PARALLEL_DEPLOY = 5;
|
|
835827
|
+
function buildImageConfig(functionConf) {
|
|
835828
|
+
const fileImageConfig = (0, function_2.buildImageConfigFromConfig)(functionConf);
|
|
835829
|
+
if (!fileImageConfig) {
|
|
835830
|
+
return null;
|
|
835831
|
+
}
|
|
835832
|
+
return fileImageConfig;
|
|
835833
|
+
}
|
|
835834
|
+
function checkWebFunctionBootstrap(functionPath, functionConf) {
|
|
835835
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
835836
|
+
return yield (0, function_1.checkAndCreateBootstrap)(functionPath, functionConf);
|
|
835837
|
+
});
|
|
835838
|
+
}
|
|
835839
|
+
function resolveFunctionPath(options) {
|
|
835840
|
+
const { functionRootPath, functionName, functionDirFromConfig } = options;
|
|
835841
|
+
if (functionDirFromConfig) {
|
|
835842
|
+
return path_1.default.resolve(process.cwd(), functionDirFromConfig);
|
|
835843
|
+
}
|
|
835844
|
+
return path_1.default.join(functionRootPath, functionName);
|
|
835845
|
+
}
|
|
835734
835846
|
let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
835735
835847
|
get options() {
|
|
835736
835848
|
return {
|
|
@@ -835852,26 +835964,29 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
835852
835964
|
return __awaiter(this, void 0, void 0, function* () {
|
|
835853
835965
|
const { name, dir, envId, force, codeSecret, access, httpFn, ws, deployMode, functions, functionRootPath, yes, log } = options;
|
|
835854
835966
|
let func = functions === null || functions === void 0 ? void 0 : functions.find((item) => item.name === name);
|
|
835855
|
-
let funcPath;
|
|
835856
|
-
if (
|
|
835857
|
-
|
|
835858
|
-
|
|
835859
|
-
|
|
835967
|
+
let funcPath = '';
|
|
835968
|
+
if (deployMode !== 'image') {
|
|
835969
|
+
if (dir) {
|
|
835970
|
+
(0, utils_1.checkFullAccess)(dir, true);
|
|
835971
|
+
if (!(0, utils_1.isDirectory)(dir)) {
|
|
835972
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('--dir 参数必须指定为云函数的文件夹路径'));
|
|
835973
|
+
}
|
|
835974
|
+
funcPath = path_1.default.resolve(process.cwd(), dir);
|
|
835975
|
+
log.info((0, i18n_1.t)('使用命令行指定的目录:{{path}}', { path: funcPath }));
|
|
835976
|
+
}
|
|
835977
|
+
else if (func === null || func === void 0 ? void 0 : func.dir) {
|
|
835978
|
+
funcPath = path_1.default.resolve(process.cwd(), func.dir);
|
|
835979
|
+
log.info((0, i18n_1.t)('使用配置文件中的目录:{{path}}', { path: funcPath }));
|
|
835980
|
+
}
|
|
835981
|
+
else {
|
|
835982
|
+
funcPath = path_1.default.join(functionRootPath, name);
|
|
835983
|
+
}
|
|
835984
|
+
if (!fs_1.default.existsSync(funcPath)) {
|
|
835985
|
+
throw new error_1.CloudBaseError((0, i18n_1.t)('未找到函数 [{{name}}] 的目录:{{path}},请检查函数名称或使用 --dir 指定函数目录', { name, path: funcPath }));
|
|
835860
835986
|
}
|
|
835861
|
-
funcPath = path_1.default.resolve(process.cwd(), dir);
|
|
835862
|
-
log.info((0, i18n_1.t)('使用命令行指定的目录:{{path}}', { path: funcPath }));
|
|
835863
|
-
}
|
|
835864
|
-
else if (func === null || func === void 0 ? void 0 : func.dir) {
|
|
835865
|
-
funcPath = path_1.default.resolve(process.cwd(), func.dir);
|
|
835866
|
-
log.info((0, i18n_1.t)('使用配置文件中的目录:{{path}}', { path: funcPath }));
|
|
835867
|
-
}
|
|
835868
|
-
else {
|
|
835869
|
-
funcPath = path_1.default.join(functionRootPath, name);
|
|
835870
|
-
}
|
|
835871
|
-
if (!fs_1.default.existsSync(funcPath)) {
|
|
835872
|
-
throw new error_1.CloudBaseError((0, i18n_1.t)('未找到函数 [{{name}}] 的目录:{{path}},请检查函数名称或使用 --dir 指定函数目录', { name, path: funcPath }));
|
|
835873
835987
|
}
|
|
835874
835988
|
if (!func) {
|
|
835989
|
+
(0, common_utils_1.validateImageDeploy)(deployMode, undefined);
|
|
835875
835990
|
log.warn((0, i18n_1.t)('配置文件中未找到函数 [{{name}}] 的配置', { name }));
|
|
835876
835991
|
if (yes) {
|
|
835877
835992
|
const inferredConfig = this.inferFunctionConfig(httpFn, funcPath);
|
|
@@ -835914,7 +836029,8 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
835914
836029
|
}
|
|
835915
836030
|
deployWithoutConfig(options) {
|
|
835916
836031
|
return __awaiter(this, void 0, void 0, function* () {
|
|
835917
|
-
const { envId, codeSecret, httpFn, ws, log } = options;
|
|
836032
|
+
const { envId, codeSecret, httpFn, ws, deployMode, log } = options;
|
|
836033
|
+
(0, common_utils_1.validateImageDeploy)(deployMode, false);
|
|
835918
836034
|
const { deployDir, functionName } = this.resolveFunctionInfo(options);
|
|
835919
836035
|
log.verbose((0, i18n_1.t)('正在检测云端函数状态...'));
|
|
835920
836036
|
let checkResult;
|
|
@@ -835952,19 +836068,13 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
835952
836068
|
}
|
|
835953
836069
|
resolveFunctionInfo(options) {
|
|
835954
836070
|
const { name, dir, log } = options;
|
|
835955
|
-
|
|
835956
|
-
|
|
835957
|
-
|
|
835958
|
-
|
|
835959
|
-
|
|
835960
|
-
|
|
835961
|
-
|
|
835962
|
-
log.info((0, i18n_1.t)('将从目录 {{dir}} 部署云函数', { dir: deployDir }));
|
|
835963
|
-
}
|
|
835964
|
-
else {
|
|
835965
|
-
log.info((0, i18n_1.t)('未找到配置文件,将从当前目录部署云函数'));
|
|
835966
|
-
}
|
|
835967
|
-
const functionName = name || path_1.default.basename(deployDir);
|
|
836071
|
+
const deployDir = (0, common_utils_1.resolveAndValidateFunctionDir)({
|
|
836072
|
+
dir,
|
|
836073
|
+
defaultDir: process.cwd(),
|
|
836074
|
+
action: '部署',
|
|
836075
|
+
log
|
|
836076
|
+
});
|
|
836077
|
+
const functionName = (0, common_utils_1.resolveFunctionName)(name, deployDir);
|
|
835968
836078
|
return { deployDir, functionName };
|
|
835969
836079
|
}
|
|
835970
836080
|
handleExistingFunction(checkResult, inferredConfig, isInferred, options, deployDir) {
|
|
@@ -835972,7 +836082,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
835972
836082
|
const { envId, force, codeSecret, access, deployMode, yes, log } = options;
|
|
835973
836083
|
const conflicts = this.detectConfigConflicts(inferredConfig, checkResult.functionDetail);
|
|
835974
836084
|
if (conflicts.length > 0) {
|
|
835975
|
-
this.displayConfigConflicts(inferredConfig.name, conflicts);
|
|
836085
|
+
this.displayConfigConflicts(inferredConfig.name, conflicts, log);
|
|
835976
836086
|
throw new error_1.CloudBaseError((0, i18n_1.t)('配置冲突,无法部署'));
|
|
835977
836087
|
}
|
|
835978
836088
|
let shouldUpdate = force || yes;
|
|
@@ -835985,7 +836095,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
835985
836095
|
}
|
|
835986
836096
|
const mergedConfig = this.mergeCloudAndLocalConfig(checkResult.functionDetail, inferredConfig);
|
|
835987
836097
|
log.info((0, i18n_1.t)('✓ 函数已存在,将使用以下合并配置更新:'));
|
|
835988
|
-
this.displayMergedConfig(inferredConfig.name, mergedConfig, isInferred ? 'inferred' : 'default');
|
|
836098
|
+
this.displayMergedConfig(inferredConfig.name, mergedConfig, isInferred ? 'inferred' : 'default', log);
|
|
835989
836099
|
let finalConfig = mergedConfig;
|
|
835990
836100
|
if (!yes) {
|
|
835991
836101
|
const { action } = yield inquirer_1.default.prompt({
|
|
@@ -836182,7 +836292,11 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836182
836292
|
type: 'confirm',
|
|
836183
836293
|
name: 'installDependency',
|
|
836184
836294
|
message: (0, i18n_1.t)('是否在线安装依赖'),
|
|
836185
|
-
default: defaultConfig.installDependency
|
|
836295
|
+
default: defaultConfig.installDependency,
|
|
836296
|
+
when: (answers) => {
|
|
836297
|
+
const runtime = answers.runtime || defaultConfig.runtime;
|
|
836298
|
+
return runtime === null || runtime === void 0 ? void 0 : runtime.startsWith('Nodejs');
|
|
836299
|
+
}
|
|
836186
836300
|
}
|
|
836187
836301
|
]);
|
|
836188
836302
|
const enableWs = isWsFromCli || answers.enableWebSocket;
|
|
@@ -836194,7 +836308,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836194
836308
|
dynamicEnabled: 'FALSE',
|
|
836195
836309
|
maxConcurrency: answers.maxConcurrency
|
|
836196
836310
|
} : undefined;
|
|
836197
|
-
return Object.assign(Object.assign(Object.assign(Object.assign({ name: answers.name.trim(), runtime: answers.runtime, handler: answers.handler, timeout: answers.timeout, memorySize: answers.memorySize, installDependency: answers.installDependency, ignore: defaultConfig.ignore || constant_1.DefaultFunctionDeployConfig.ignore }, (isHttpFnFromCli || answers.isHttpFn ? { type: 'HTTP' } : {})), (protocolType ? { protocolType } : {})), (protocolParams ? { protocolParams } : {})), (instanceConcurrencyConfig ? { instanceConcurrencyConfig } : {}));
|
|
836311
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ name: answers.name.trim(), runtime: answers.runtime, handler: answers.handler, timeout: answers.timeout, memorySize: answers.memorySize }, (answers.installDependency !== undefined ? { installDependency: answers.installDependency } : {})), { ignore: defaultConfig.ignore || constant_1.DefaultFunctionDeployConfig.ignore }), (isHttpFnFromCli || answers.isHttpFn ? { type: 'HTTP' } : {})), (protocolType ? { protocolType } : {})), (protocolParams ? { protocolParams } : {})), (instanceConcurrencyConfig ? { instanceConcurrencyConfig } : {}));
|
|
836198
836312
|
});
|
|
836199
836313
|
}
|
|
836200
836314
|
promptFunctionName() {
|
|
@@ -836214,7 +836328,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836214
836328
|
});
|
|
836215
836329
|
}
|
|
836216
836330
|
printFunctionConfig(func, log, source) {
|
|
836217
|
-
var _a, _b;
|
|
836331
|
+
var _a, _b, _c;
|
|
836218
836332
|
if (source) {
|
|
836219
836333
|
log.info((0, i18n_1.t)('配置来源:{{source}}', { source }));
|
|
836220
836334
|
}
|
|
@@ -836225,12 +836339,14 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836225
836339
|
if (func.memorySize) {
|
|
836226
836340
|
log.info((0, i18n_1.t)(' - 内存大小:{{memorySize}} MB', { memorySize: func.memorySize }));
|
|
836227
836341
|
}
|
|
836228
|
-
|
|
836342
|
+
if (((_a = func.runtime) === null || _a === void 0 ? void 0 : _a.startsWith('Nodejs')) && func.installDependency !== undefined) {
|
|
836343
|
+
log.info((0, i18n_1.t)(' - 在线安装依赖:{{installDependency}}', { installDependency: func.installDependency ? (0, i18n_1.t)('是') : (0, i18n_1.t)('否') }));
|
|
836344
|
+
}
|
|
836229
836345
|
if (func.type === 'HTTP') {
|
|
836230
836346
|
log.info((0, i18n_1.t)(' - 函数类型:HTTP'));
|
|
836231
836347
|
if (func.protocolType === 'WS') {
|
|
836232
836348
|
log.info((0, i18n_1.t)(' - WebSocket 协议:已启用'));
|
|
836233
|
-
const idleTimeOut = (
|
|
836349
|
+
const idleTimeOut = (_c = (_b = func.protocolParams) === null || _b === void 0 ? void 0 : _b.wsParams) === null || _c === void 0 ? void 0 : _c.idleTimeOut;
|
|
836234
836350
|
if (idleTimeOut) {
|
|
836235
836351
|
log.info((0, i18n_1.t)(' - 空闲超时时间:{{seconds}} 秒', { seconds: idleTimeOut }));
|
|
836236
836352
|
}
|
|
@@ -836301,7 +836417,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836301
836417
|
const { func, envId, force, codeSecret, access, deployMode, functionRootPath, functionPath, yes, log, preCheckResult } = options;
|
|
836302
836418
|
let finalFunc = Object.assign({}, func);
|
|
836303
836419
|
if (deployMode === 'image') {
|
|
836304
|
-
const fileImageConfig = (
|
|
836420
|
+
const fileImageConfig = buildImageConfig(func);
|
|
836305
836421
|
if (fileImageConfig) {
|
|
836306
836422
|
finalFunc.imageConfig = fileImageConfig;
|
|
836307
836423
|
}
|
|
@@ -836311,7 +836427,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836311
836427
|
}
|
|
836312
836428
|
if (finalFunc.type === 'HTTP' && deployMode !== 'image') {
|
|
836313
836429
|
const funcPath = functionPath === '.' ? process.cwd() : (functionPath || path_1.default.join(functionRootPath, finalFunc.name));
|
|
836314
|
-
const shouldContinue = yield (
|
|
836430
|
+
const shouldContinue = yield checkWebFunctionBootstrap(funcPath, finalFunc);
|
|
836315
836431
|
if (!shouldContinue) {
|
|
836316
836432
|
return;
|
|
836317
836433
|
}
|
|
@@ -836466,7 +836582,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836466
836582
|
funcWithType = Object.assign(Object.assign({}, funcWithType), { type: 'HTTP', protocolType: 'WS' });
|
|
836467
836583
|
}
|
|
836468
836584
|
if (deployMode === 'image') {
|
|
836469
|
-
const fileImageConfig = (
|
|
836585
|
+
const fileImageConfig = buildImageConfig(funcWithType);
|
|
836470
836586
|
if (fileImageConfig) {
|
|
836471
836587
|
funcWithType = Object.assign(Object.assign({}, funcWithType), { imageConfig: fileImageConfig });
|
|
836472
836588
|
}
|
|
@@ -836475,21 +836591,24 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836475
836591
|
return { status: 'skipped', name: func.name };
|
|
836476
836592
|
}
|
|
836477
836593
|
}
|
|
836478
|
-
const funcPath =
|
|
836479
|
-
|
|
836480
|
-
:
|
|
836594
|
+
const funcPath = resolveFunctionPath({
|
|
836595
|
+
functionRootPath,
|
|
836596
|
+
functionName: func.name,
|
|
836597
|
+
functionDirFromConfig: func.dir
|
|
836598
|
+
});
|
|
836481
836599
|
if (deployMode !== 'image' && !fs_1.default.existsSync(funcPath)) {
|
|
836482
836600
|
log.error((0, i18n_1.t)('未找到函数 [{{name}}] 的目录:{{path}},已跳过', { name: func.name, path: funcPath }));
|
|
836483
836601
|
return { status: 'skipped', name: func.name };
|
|
836484
836602
|
}
|
|
836485
836603
|
if (funcWithType.type === 'HTTP' && deployMode !== 'image') {
|
|
836486
|
-
const shouldContinue = yield (
|
|
836604
|
+
const shouldContinue = yield checkWebFunctionBootstrap(funcPath, funcWithType);
|
|
836487
836605
|
if (!shouldContinue) {
|
|
836488
836606
|
log.warn((0, i18n_1.t)('[{{name}}] 已跳过部署', { name: func.name }));
|
|
836489
836607
|
return { status: 'skipped', name: func.name };
|
|
836490
836608
|
}
|
|
836491
836609
|
}
|
|
836492
836610
|
loading.start((0, i18n_1.t)('云函数部署中'));
|
|
836611
|
+
let deployError = null;
|
|
836493
836612
|
try {
|
|
836494
836613
|
yield (0, function_1.createFunction)({
|
|
836495
836614
|
func: funcWithType,
|
|
@@ -836505,32 +836624,33 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836505
836624
|
return { status: 'success', name: func.name };
|
|
836506
836625
|
}
|
|
836507
836626
|
catch (e) {
|
|
836627
|
+
deployError = e;
|
|
836508
836628
|
loading.stop();
|
|
836509
|
-
|
|
836510
|
-
|
|
836511
|
-
|
|
836512
|
-
|
|
836513
|
-
|
|
836514
|
-
|
|
836515
|
-
|
|
836516
|
-
|
|
836517
|
-
|
|
836518
|
-
|
|
836519
|
-
|
|
836520
|
-
|
|
836521
|
-
|
|
836522
|
-
|
|
836523
|
-
|
|
836524
|
-
}
|
|
836525
|
-
|
|
836526
|
-
|
|
836527
|
-
}
|
|
836629
|
+
}
|
|
836630
|
+
try {
|
|
836631
|
+
const result = yield this.handleDeployFail(deployError, {
|
|
836632
|
+
func: funcWithType,
|
|
836633
|
+
envId,
|
|
836634
|
+
force,
|
|
836635
|
+
codeSecret,
|
|
836636
|
+
functionRootPath,
|
|
836637
|
+
functionPath: func.dir ? funcPath : undefined,
|
|
836638
|
+
accessPath: access,
|
|
836639
|
+
yes: yes || force || functionsToOverwrite.has(func.name),
|
|
836640
|
+
batchMode: true,
|
|
836641
|
+
logger: log,
|
|
836642
|
+
deployMode
|
|
836643
|
+
});
|
|
836644
|
+
return { status: result || 'error', name: func.name };
|
|
836645
|
+
}
|
|
836646
|
+
catch (handleError) {
|
|
836647
|
+
return { status: 'error', name: func.name, error: handleError };
|
|
836528
836648
|
}
|
|
836529
836649
|
}));
|
|
836530
836650
|
if (tasks.length > 5) {
|
|
836531
836651
|
log.info((0, i18n_1.t)('函数数量较多,将使用队列部署'));
|
|
836532
836652
|
}
|
|
836533
|
-
const asyncTaskController = new utils_1.AsyncTaskParallelController(
|
|
836653
|
+
const asyncTaskController = new utils_1.AsyncTaskParallelController(MAX_PARALLEL_DEPLOY, 50);
|
|
836534
836654
|
asyncTaskController.loadTasks(tasks);
|
|
836535
836655
|
const rawResults = yield asyncTaskController.run();
|
|
836536
836656
|
const results = rawResults.map((r, index) => {
|
|
@@ -836621,7 +836741,7 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836621
836741
|
}
|
|
836622
836742
|
const conflicts = this.detectConfigConflicts(func, existingFunction);
|
|
836623
836743
|
if (conflicts.length > 0) {
|
|
836624
|
-
this.displayConfigConflicts(func.name, conflicts);
|
|
836744
|
+
this.displayConfigConflicts(func.name, conflicts, log);
|
|
836625
836745
|
return 'error';
|
|
836626
836746
|
}
|
|
836627
836747
|
func = this.mergeCloudAndLocalConfig(existingFunction, func);
|
|
@@ -836966,7 +837086,22 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
836966
837086
|
}
|
|
836967
837087
|
}
|
|
836968
837088
|
getSpecificSuggestions(error, context = {}) {
|
|
837089
|
+
var _a, _b;
|
|
836969
837090
|
const { functionName } = context;
|
|
837091
|
+
if (((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('COS 上传失败')) || ((_b = error.message) === null || _b === void 0 ? void 0 : _b.includes('上传失败'))) {
|
|
837092
|
+
const suggestions = [(0, i18n_1.t)('检查网络连接是否正常')];
|
|
837093
|
+
if (error.code === 'AccessDenied') {
|
|
837094
|
+
suggestions.push((0, i18n_1.t)('签名或权限不正确,拒绝访问'));
|
|
837095
|
+
suggestions.push((0, i18n_1.t)('运行 {{command}} 重新登录', { command: (0, utils_1.highlightCommand)('tcb login') }));
|
|
837096
|
+
}
|
|
837097
|
+
else if (error.code === 'NoSuchBucket') {
|
|
837098
|
+
suggestions.push((0, i18n_1.t)('指定的存储桶不存在,请检查环境配置'));
|
|
837099
|
+
}
|
|
837100
|
+
else if (error.code === 'RequestTimeout') {
|
|
837101
|
+
suggestions.push((0, i18n_1.t)('请求超时,可能是文件过大或网络不稳定'));
|
|
837102
|
+
}
|
|
837103
|
+
return suggestions;
|
|
837104
|
+
}
|
|
836970
837105
|
if (error.code === 'Forbidden' || error.code === 'Unauthorized' ||
|
|
836971
837106
|
error.code === 'AuthFailure' || error.code === 'UnauthorizedOperation') {
|
|
836972
837107
|
return [
|
|
@@ -837029,33 +837164,35 @@ let FunctionDeploy = class FunctionDeploy extends common_1.Command {
|
|
|
837029
837164
|
}
|
|
837030
837165
|
});
|
|
837031
837166
|
}
|
|
837032
|
-
displayConfigConflicts(functionName, conflicts) {
|
|
837033
|
-
|
|
837167
|
+
displayConfigConflicts(functionName, conflicts, log) {
|
|
837168
|
+
const activeLogger = log || utils_1.logger;
|
|
837169
|
+
activeLogger.error((0, i18n_1.t)('函数 [{{name}}] 存在配置冲突:', { name: functionName }));
|
|
837034
837170
|
conflicts.forEach((conflict) => {
|
|
837035
|
-
|
|
837036
|
-
|
|
837171
|
+
activeLogger.error(` ✗ ${conflict.field}: 云端 ${conflict.cloudValue} ≠ 本地 ${conflict.localValue}`);
|
|
837172
|
+
activeLogger.error(` ${conflict.message}`);
|
|
837037
837173
|
});
|
|
837038
|
-
|
|
837039
|
-
|
|
837040
|
-
|
|
837041
|
-
|
|
837174
|
+
activeLogger.info((0, i18n_1.t)('解决建议:'));
|
|
837175
|
+
activeLogger.info((0, i18n_1.t)(' 1. 修改本地配置使其与云端一致'));
|
|
837176
|
+
activeLogger.info((0, i18n_1.t)(' 2. 删除云端函数后重新创建'));
|
|
837177
|
+
activeLogger.info((0, i18n_1.t)(' 3. 使用 {{command}} 查看云端配置', {
|
|
837042
837178
|
command: (0, utils_1.highlightCommand)(`tcb fn detail ${functionName}`)
|
|
837043
837179
|
}));
|
|
837044
837180
|
}
|
|
837045
|
-
displayMergedConfig(functionName, config, source) {
|
|
837046
|
-
|
|
837047
|
-
|
|
837048
|
-
|
|
837049
|
-
|
|
837181
|
+
displayMergedConfig(functionName, config, source, log) {
|
|
837182
|
+
const activeLogger = log || utils_1.logger;
|
|
837183
|
+
activeLogger.info((0, i18n_1.t)('函数 [{{name}}] 最终配置:', { name: functionName }));
|
|
837184
|
+
activeLogger.info(` ${(0, i18n_1.t)('类型')}: ${config.type || 'Event'}`);
|
|
837185
|
+
activeLogger.info(` ${(0, i18n_1.t)('运行时')}: ${config.runtime}`);
|
|
837186
|
+
activeLogger.info(` ${(0, i18n_1.t)('入口')}: ${config.handler}`);
|
|
837050
837187
|
if (config.memorySize) {
|
|
837051
|
-
|
|
837188
|
+
activeLogger.info(` ${(0, i18n_1.t)('内存')}: ${config.memorySize}MB`);
|
|
837052
837189
|
}
|
|
837053
|
-
|
|
837190
|
+
activeLogger.info(` ${(0, i18n_1.t)('超时')}: ${config.timeout}s`);
|
|
837054
837191
|
if (source === 'inferred') {
|
|
837055
|
-
|
|
837192
|
+
activeLogger.info((0, i18n_1.t)(' (配置来源: 智能推测)'));
|
|
837056
837193
|
}
|
|
837057
837194
|
else if (source === 'default') {
|
|
837058
|
-
|
|
837195
|
+
activeLogger.info((0, i18n_1.t)(' (配置来源: 默认配置)'));
|
|
837059
837196
|
}
|
|
837060
837197
|
}
|
|
837061
837198
|
confirmUpdate(functionName) {
|
|
@@ -901898,117 +902035,213 @@ function isNodeFunction(runtime) {
|
|
|
901898
902035
|
/**
|
|
901899
902036
|
* 构建镜像配置对象
|
|
901900
902037
|
* @param imageConfig 镜像配置
|
|
901901
|
-
* @param options 可选配置
|
|
901902
|
-
* @param options.includeCommandList 是否包含 CommandList/ArgsList(仅 CreateFunction 支持)
|
|
901903
902038
|
* @returns 构建好的镜像配置对象
|
|
901904
902039
|
*/
|
|
901905
|
-
function buildImageConfig(imageConfig
|
|
901906
|
-
|
|
901907
|
-
const
|
|
901908
|
-
|
|
901909
|
-
|
|
901910
|
-
|
|
901911
|
-
|
|
901912
|
-
|
|
901913
|
-
|
|
901914
|
-
|
|
901915
|
-
|
|
901916
|
-
|
|
901917
|
-
|
|
902040
|
+
function buildImageConfig(imageConfig) {
|
|
902041
|
+
// 先转换大小写
|
|
902042
|
+
const config = toPascalCaseKeys(imageConfig);
|
|
902043
|
+
// 再补充默认值
|
|
902044
|
+
return Object.assign({ ImageType: 'enterprise', ImagePort: 9000 }, config);
|
|
902045
|
+
}
|
|
902046
|
+
/**
|
|
902047
|
+
* 递归转换对象的 key 从 camelCase 到 PascalCase
|
|
902048
|
+
*/
|
|
902049
|
+
function toPascalCaseKeys(obj) {
|
|
902050
|
+
if (obj === null || obj === undefined)
|
|
902051
|
+
return obj;
|
|
902052
|
+
if (Array.isArray(obj))
|
|
902053
|
+
return obj.map(item => toPascalCaseKeys(item));
|
|
902054
|
+
if (typeof obj !== 'object')
|
|
902055
|
+
return obj;
|
|
902056
|
+
const result = {};
|
|
902057
|
+
for (const key of Object.keys(obj)) {
|
|
902058
|
+
// 通用规则:首字母大写
|
|
902059
|
+
const pascalKey = key.charAt(0).toUpperCase() + key.slice(1);
|
|
902060
|
+
result[pascalKey] = toPascalCaseKeys(obj[key]);
|
|
902061
|
+
}
|
|
902062
|
+
return result;
|
|
902063
|
+
}
|
|
902064
|
+
/**
|
|
902065
|
+
* 将布尔值转换为 API 需要的 'TRUE'/'FALSE' 字符串
|
|
902066
|
+
* 支持 boolean | string | undefined 输入
|
|
902067
|
+
* @param value 输入值
|
|
902068
|
+
* @returns 'TRUE' | 'FALSE' | undefined
|
|
902069
|
+
*/
|
|
902070
|
+
function toBooleanString(value) {
|
|
902071
|
+
if (value === undefined)
|
|
902072
|
+
return undefined;
|
|
902073
|
+
// 已经是字符串格式
|
|
902074
|
+
if (value === 'TRUE' || value === 'FALSE')
|
|
902075
|
+
return value;
|
|
902076
|
+
// 字符串 'true'/'false' 兼容
|
|
902077
|
+
if (typeof value === 'string') {
|
|
902078
|
+
return value.toUpperCase() === 'TRUE' ? 'TRUE' : 'FALSE';
|
|
902079
|
+
}
|
|
902080
|
+
// 布尔值转换
|
|
902081
|
+
return value ? 'TRUE' : 'FALSE';
|
|
902082
|
+
}
|
|
902083
|
+
/**
|
|
902084
|
+
* 大小写不敏感获取对象字段值(优先 camelCase)
|
|
902085
|
+
* @param obj 目标对象
|
|
902086
|
+
* @param fieldName 字段名(任意大小写)
|
|
902087
|
+
* @returns 字段值,找不到返回 undefined
|
|
902088
|
+
* @example
|
|
902089
|
+
* getFieldIgnoreCase({ type: 'A', Type: 'B' }, 'type') // → 'A' (camelCase 优先)
|
|
902090
|
+
* getFieldIgnoreCase({ Type: 'B' }, 'type') // → 'B'
|
|
902091
|
+
*/
|
|
902092
|
+
function getFieldIgnoreCase(obj, fieldName) {
|
|
902093
|
+
if (!obj || typeof obj !== 'object')
|
|
902094
|
+
return undefined;
|
|
902095
|
+
const lowerFieldName = fieldName.toLowerCase();
|
|
902096
|
+
// 优先查找 camelCase(首字母小写)
|
|
902097
|
+
const camelCaseKey = lowerFieldName.charAt(0).toLowerCase() + fieldName.slice(1);
|
|
902098
|
+
if (obj[camelCaseKey] !== undefined) {
|
|
902099
|
+
return obj[camelCaseKey];
|
|
902100
|
+
}
|
|
902101
|
+
// 其次查找 PascalCase(首字母大写)
|
|
902102
|
+
const pascalCaseKey = lowerFieldName.charAt(0).toUpperCase() + fieldName.slice(1);
|
|
902103
|
+
if (obj[pascalCaseKey] !== undefined) {
|
|
902104
|
+
return obj[pascalCaseKey];
|
|
902105
|
+
}
|
|
902106
|
+
// 最后遍历查找任意大小写匹配
|
|
902107
|
+
for (const key of Object.keys(obj)) {
|
|
902108
|
+
if (key.toLowerCase() === lowerFieldName) {
|
|
902109
|
+
return obj[key];
|
|
901918
902110
|
}
|
|
901919
902111
|
}
|
|
901920
|
-
return
|
|
902112
|
+
return undefined;
|
|
901921
902113
|
}
|
|
901922
|
-
//
|
|
902114
|
+
// 解析函数配置,换成请求参数(用于 CreateFunction)
|
|
901923
902115
|
function configToParams(options) {
|
|
901924
|
-
var _a, _b, _c
|
|
901925
|
-
const { func, codeSecret, baseParams } = options;
|
|
901926
|
-
|
|
901927
|
-
//
|
|
901928
|
-
|
|
901929
|
-
|
|
901930
|
-
|
|
901931
|
-
|
|
902116
|
+
var _a, _b, _c;
|
|
902117
|
+
const { func, codeSecret, baseParams = {} } = options;
|
|
902118
|
+
// 白名单:只有这些字段会被透传到 API(大小写不敏感)
|
|
902119
|
+
// 参考 SCF API 文档:https://cloud.tencent.com/document/product/583/18586
|
|
902120
|
+
// key: 小写用于匹配,value: PascalCase 用于输出
|
|
902121
|
+
const AUTO_CONVERT_FIELDS = {
|
|
902122
|
+
// 基础配置
|
|
902123
|
+
'description': 'Description',
|
|
902124
|
+
'memorysize': 'MemorySize',
|
|
902125
|
+
'timeout': 'Timeout',
|
|
902126
|
+
'runtime': 'Runtime',
|
|
902127
|
+
'type': 'Type', // Event/HTTP
|
|
902128
|
+
'role': 'Role',
|
|
902129
|
+
// 日志配置
|
|
902130
|
+
'clslogsetid': 'ClsLogsetId',
|
|
902131
|
+
'clstopicid': 'ClsTopicId',
|
|
902132
|
+
// 高级配置
|
|
902133
|
+
'deadletterconfig': 'DeadLetterConfig',
|
|
902134
|
+
'publicnetconfig': 'PublicNetConfig',
|
|
902135
|
+
'cfsconfig': 'CfsConfig',
|
|
902136
|
+
'inittimeout': 'InitTimeout',
|
|
902137
|
+
'tags': 'Tags',
|
|
902138
|
+
// 注意:asyncRunEnable/traceEnable/autoDeployClsTopicIndex/autoCreateClsTopic/dnsCache
|
|
902139
|
+
// 需要 'TRUE'/'FALSE' 字符串,在特殊处理阶段处理
|
|
902140
|
+
'protocoltype': 'ProtocolType', // WS
|
|
902141
|
+
'intranetconfig': 'IntranetConfig',
|
|
902142
|
+
};
|
|
902143
|
+
let params = Object.assign(Object.assign({}, baseParams), { FunctionName: func.name });
|
|
902144
|
+
// 第一阶段:白名单字段自动转换(大小写不敏感,统一输出 PascalCase)
|
|
902145
|
+
for (const key of Object.keys(func)) {
|
|
902146
|
+
const lowerKey = key.toLowerCase();
|
|
902147
|
+
const pascalKey = AUTO_CONVERT_FIELDS[lowerKey];
|
|
902148
|
+
if (!pascalKey || func[key] === undefined)
|
|
902149
|
+
continue;
|
|
902150
|
+
params[pascalKey] = toPascalCaseKeys(func[key]);
|
|
901932
902151
|
}
|
|
901933
|
-
//
|
|
901934
|
-
|
|
901935
|
-
|
|
901936
|
-
|
|
901937
|
-
}
|
|
901938
|
-
//
|
|
901939
|
-
|
|
901940
|
-
|
|
901941
|
-
|
|
901942
|
-
|
|
901943
|
-
|
|
901944
|
-
|
|
901945
|
-
//
|
|
901946
|
-
//
|
|
901947
|
-
|
|
901948
|
-
|
|
901949
|
-
|
|
901950
|
-
|
|
901951
|
-
|
|
901952
|
-
|
|
901953
|
-
|
|
902152
|
+
// 第二阶段:特殊处理字段
|
|
902153
|
+
// 1. 安装依赖标志(支持 boolean | string)
|
|
902154
|
+
if (func.installDependency !== undefined) {
|
|
902155
|
+
params.InstallDependency = toBooleanString(func.installDependency);
|
|
902156
|
+
}
|
|
902157
|
+
// 2. L5 配置 - 当不存在时不修改,否则根据 true/false 进行修改
|
|
902158
|
+
if (func.l5 !== undefined) {
|
|
902159
|
+
params.L5Enable = toBooleanString(func.l5);
|
|
902160
|
+
}
|
|
902161
|
+
else {
|
|
902162
|
+
params.L5Enable = null;
|
|
902163
|
+
}
|
|
902164
|
+
// 3. 需要 'TRUE'/'FALSE' 字符串的布尔字段统一处理(大小写不敏感)
|
|
902165
|
+
// key: 小写用于匹配,value: PascalCase 用于输出
|
|
902166
|
+
const BOOLEAN_STRING_FIELDS = {
|
|
902167
|
+
'asyncrunenable': 'AsyncRunEnable', // 异步属性
|
|
902168
|
+
'traceenable': 'TraceEnable', // 事件追踪
|
|
902169
|
+
'autodeployclstopicindex': 'AutoDeployClsTopicIndex', // 自动创建 CLS 索引
|
|
902170
|
+
'autocreateclstopic': 'AutoCreateClsTopic', // 自动创建 CLS 主题
|
|
902171
|
+
'dnscache': 'DnsCache', // Dns 缓存
|
|
902172
|
+
};
|
|
902173
|
+
for (const key of Object.keys(func)) {
|
|
902174
|
+
const lowerKey = key.toLowerCase();
|
|
902175
|
+
const pascalKey = BOOLEAN_STRING_FIELDS[lowerKey];
|
|
902176
|
+
if (pascalKey && func[key] !== undefined) {
|
|
902177
|
+
params[pascalKey] = toBooleanString(func[key]);
|
|
902178
|
+
}
|
|
902179
|
+
}
|
|
902180
|
+
// 5. 环境变量 - 为覆盖式修改,不保留已有字段
|
|
902181
|
+
if (func.envVariables && Object.keys(func.envVariables).length > 0) {
|
|
902182
|
+
params.Environment = {
|
|
902183
|
+
Variables: Object.keys(func.envVariables).map(key => ({
|
|
902184
|
+
Key: key,
|
|
902185
|
+
Value: func.envVariables[key]
|
|
902186
|
+
}))
|
|
902187
|
+
};
|
|
902188
|
+
}
|
|
902189
|
+
// 4. 函数角色(如果白名单已处理则跳过)
|
|
902190
|
+
if (!params.Role && func.role) {
|
|
902191
|
+
params.Role = func.role;
|
|
902192
|
+
}
|
|
902193
|
+
// 5. VPC 配置
|
|
901954
902194
|
if (((_a = func === null || func === void 0 ? void 0 : func.vpc) === null || _a === void 0 ? void 0 : _a.subnetId) !== undefined && ((_b = func === null || func === void 0 ? void 0 : func.vpc) === null || _b === void 0 ? void 0 : _b.vpcId) !== undefined) {
|
|
901955
|
-
// VPC 网络
|
|
901956
902195
|
params.VpcConfig = {
|
|
901957
|
-
SubnetId:
|
|
901958
|
-
VpcId:
|
|
902196
|
+
SubnetId: func.vpc.subnetId,
|
|
902197
|
+
VpcId: func.vpc.vpcId
|
|
901959
902198
|
};
|
|
901960
902199
|
}
|
|
901961
|
-
//
|
|
901962
|
-
|
|
901963
|
-
|
|
901964
|
-
params.InstallDependency = installDependency;
|
|
901965
|
-
// 代码保护
|
|
901966
|
-
if (codeSecret || func.codeSecret) {
|
|
901967
|
-
params.CodeSecret = codeSecret || func.codeSecret;
|
|
901968
|
-
}
|
|
901969
|
-
// 函数层
|
|
901970
|
-
if ((_e = func === null || func === void 0 ? void 0 : func.layers) === null || _e === void 0 ? void 0 : _e.length) {
|
|
901971
|
-
const transformLayers = func.layers.map(item => ({
|
|
902200
|
+
// 6. 函数层
|
|
902201
|
+
if ((_c = func === null || func === void 0 ? void 0 : func.layers) === null || _c === void 0 ? void 0 : _c.length) {
|
|
902202
|
+
params.Layers = func.layers.map(item => ({
|
|
901972
902203
|
LayerName: item.name,
|
|
901973
902204
|
LayerVersion: item.version
|
|
901974
902205
|
}));
|
|
901975
|
-
params.Layers = transformLayers;
|
|
901976
902206
|
}
|
|
901977
|
-
//
|
|
901978
|
-
if (
|
|
901979
|
-
params.
|
|
901980
|
-
|
|
901981
|
-
|
|
901982
|
-
|
|
901983
|
-
|
|
901984
|
-
|
|
901985
|
-
|
|
902207
|
+
// 7. 代码保护
|
|
902208
|
+
if (codeSecret || func.codeSecret) {
|
|
902209
|
+
params.CodeSecret = codeSecret || func.codeSecret;
|
|
902210
|
+
}
|
|
902211
|
+
// 8. 协议参数(WebSocket,大小写不敏感)
|
|
902212
|
+
const protocolParams = getFieldIgnoreCase(func, 'protocolParams');
|
|
902213
|
+
if (protocolParams) {
|
|
902214
|
+
const wsParams = getFieldIgnoreCase(protocolParams, 'wsParams');
|
|
902215
|
+
if (wsParams) {
|
|
901986
902216
|
params.ProtocolParams = {
|
|
901987
|
-
WSParams:
|
|
901988
|
-
IdleTimeOut: typeof idleTimeOut === 'number' ? idleTimeOut : 15
|
|
901989
|
-
}
|
|
901990
|
-
};
|
|
901991
|
-
}
|
|
901992
|
-
// 多并发配置
|
|
901993
|
-
// 参考文档:https://cloud.tencent.com/document/api/583/17244#InstanceConcurrencyConfig
|
|
901994
|
-
if (func === null || func === void 0 ? void 0 : func.instanceConcurrencyConfig) {
|
|
901995
|
-
params.InstanceConcurrencyConfig = {
|
|
901996
|
-
DynamicEnabled: func.instanceConcurrencyConfig.dynamicEnabled || 'FALSE',
|
|
901997
|
-
MaxConcurrency: func.instanceConcurrencyConfig.maxConcurrency || 10
|
|
902217
|
+
WSParams: toPascalCaseKeys(wsParams)
|
|
901998
902218
|
};
|
|
901999
902219
|
}
|
|
902000
902220
|
}
|
|
902001
|
-
//
|
|
902002
|
-
|
|
902003
|
-
|
|
902221
|
+
// 9. HTTP 云函数特殊处理(type 字段大小写不敏感)
|
|
902222
|
+
const funcType = getFieldIgnoreCase(func, 'type');
|
|
902223
|
+
if ((funcType === null || funcType === void 0 ? void 0 : funcType.toUpperCase()) === 'HTTP') {
|
|
902224
|
+
params.Type = 'HTTP';
|
|
902225
|
+
// 多并发配置 - 仅 HTTP 函数支持(大小写不敏感)
|
|
902226
|
+
const instanceConcurrencyConfig = getFieldIgnoreCase(func, 'instanceConcurrencyConfig');
|
|
902227
|
+
if (instanceConcurrencyConfig) {
|
|
902228
|
+
const config = toPascalCaseKeys(instanceConcurrencyConfig);
|
|
902229
|
+
// DynamicEnabled 需要特殊处理为 'TRUE'/'FALSE'
|
|
902230
|
+
if (config.DynamicEnabled !== undefined) {
|
|
902231
|
+
config.DynamicEnabled = toBooleanString(config.DynamicEnabled);
|
|
902232
|
+
}
|
|
902233
|
+
params.InstanceConcurrencyConfig = config;
|
|
902234
|
+
}
|
|
902004
902235
|
}
|
|
902005
|
-
//
|
|
902006
|
-
|
|
902007
|
-
|
|
902008
|
-
|
|
902009
|
-
|
|
902236
|
+
// 10. 镜像配置(用于镜像部署,大小写不敏感)
|
|
902237
|
+
const imageConfig = getFieldIgnoreCase(func, 'imageConfig');
|
|
902238
|
+
if (imageConfig) {
|
|
902239
|
+
params.Code = params.Code || {};
|
|
902240
|
+
params.Code.ImageConfig = buildImageConfig(imageConfig);
|
|
902010
902241
|
}
|
|
902011
|
-
|
|
902242
|
+
// 第三阶段:统一应用默认值
|
|
902243
|
+
const runtime = params.Runtime || 'Nodejs18.15';
|
|
902244
|
+
return Object.assign({ Handler: func.handler || 'index.main', Timeout: 10, Runtime: 'Nodejs18.15', MemorySize: 256, InstallDependency: isNodeFunction(runtime) ? 'TRUE' : 'FALSE' }, params);
|
|
902012
902245
|
}
|
|
902013
902246
|
class FunctionService {
|
|
902014
902247
|
constructor(environment) {
|
|
@@ -902025,12 +902258,11 @@ class FunctionService {
|
|
|
902025
902258
|
* @memberof FunctionService
|
|
902026
902259
|
*/
|
|
902027
902260
|
async updateFunctionIncrementalCode(funcParam) {
|
|
902028
|
-
const {
|
|
902261
|
+
const { namespace } = this.getFunctionConfig();
|
|
902029
902262
|
const { functionRootPath, func, deleteFiles, addFiles } = funcParam;
|
|
902030
902263
|
const { name, runtime } = func;
|
|
902031
902264
|
const params = {
|
|
902032
902265
|
FunctionName: name,
|
|
902033
|
-
EnvId: env,
|
|
902034
902266
|
Namespace: namespace
|
|
902035
902267
|
};
|
|
902036
902268
|
let packer;
|
|
@@ -902055,7 +902287,7 @@ class FunctionService {
|
|
|
902055
902287
|
}
|
|
902056
902288
|
params.AddFiles = base64;
|
|
902057
902289
|
}
|
|
902058
|
-
return this.
|
|
902290
|
+
return this.scfService.request('UpdateFunctionIncrementalCode', params);
|
|
902059
902291
|
}
|
|
902060
902292
|
/**
|
|
902061
902293
|
* 创建云函数
|
|
@@ -902063,25 +902295,28 @@ class FunctionService {
|
|
|
902063
902295
|
* @returns {(Promise<IResponseInfo | ICreateFunctionRes>)}
|
|
902064
902296
|
*/
|
|
902065
902297
|
async createFunction(funcParam) {
|
|
902066
|
-
var _a;
|
|
902067
|
-
const {
|
|
902298
|
+
var _a, _b, _c;
|
|
902299
|
+
const { namespace } = this.getFunctionConfig();
|
|
902068
902300
|
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
902069
902301
|
const funcName = func.name;
|
|
902302
|
+
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
902070
902303
|
const params = configToParams({
|
|
902071
902304
|
func,
|
|
902072
902305
|
codeSecret,
|
|
902073
902306
|
baseParams: {
|
|
902074
|
-
|
|
902307
|
+
Namespace: namespace,
|
|
902075
902308
|
Role: 'TCB_QcsRole',
|
|
902076
|
-
Stamp: 'MINI_QCBASE'
|
|
902309
|
+
Stamp: 'MINI_QCBASE',
|
|
902310
|
+
ClsTopicId: TopicId,
|
|
902311
|
+
ClsLogsetId: LogsetId
|
|
902077
902312
|
}
|
|
902078
902313
|
});
|
|
902079
902314
|
// 根据部署方式处理 Code 参数
|
|
902080
902315
|
// 优先使用显式指定的 deployMode,如果未指定但存在 imageConfig 则认为是镜像部署
|
|
902081
|
-
const isImageDeploy = deployMode === 'image' || (!deployMode &&
|
|
902316
|
+
const isImageDeploy = deployMode === 'image' || (!deployMode && ((_a = params.Code) === null || _a === void 0 ? void 0 : _a.ImageConfig));
|
|
902082
902317
|
if (isImageDeploy) {
|
|
902083
902318
|
// 镜像部署:Code 参数已在 configToParams 中通过 imageConfig 设置
|
|
902084
|
-
if (!((
|
|
902319
|
+
if (!((_c = (_b = params.Code) === null || _b === void 0 ? void 0 : _b.ImageConfig) === null || _c === void 0 ? void 0 : _c.ImageUri)) {
|
|
902085
902320
|
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
902086
902321
|
}
|
|
902087
902322
|
// 镜像部署的特殊配置
|
|
@@ -902100,12 +902335,9 @@ class FunctionService {
|
|
|
902100
902335
|
deployMode
|
|
902101
902336
|
}, params.InstallDependency);
|
|
902102
902337
|
}
|
|
902103
|
-
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
902104
|
-
params.ClsTopicId = TopicId;
|
|
902105
|
-
params.ClsLogsetId = LogsetId;
|
|
902106
902338
|
try {
|
|
902107
902339
|
// 创建云函数
|
|
902108
|
-
const res = await this.
|
|
902340
|
+
const res = await this.scfService.request('CreateFunction', params);
|
|
902109
902341
|
// 等待函数状态正常
|
|
902110
902342
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902111
902343
|
// 创建函数触发器、失败自动重试
|
|
@@ -902175,9 +902407,9 @@ class FunctionService {
|
|
|
902175
902407
|
*/
|
|
902176
902408
|
async getFunctionList(limit = 20, offset = 0) {
|
|
902177
902409
|
// 获取Function 环境配置
|
|
902178
|
-
const {
|
|
902179
|
-
const res = await this.
|
|
902180
|
-
|
|
902410
|
+
const { namespace } = this.getFunctionConfig();
|
|
902411
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
902412
|
+
Namespace: namespace,
|
|
902181
902413
|
Limit: limit,
|
|
902182
902414
|
Offset: offset
|
|
902183
902415
|
});
|
|
@@ -902191,9 +902423,9 @@ class FunctionService {
|
|
|
902191
902423
|
*/
|
|
902192
902424
|
async listFunctions(limit = 20, offset = 0) {
|
|
902193
902425
|
// 获取Function 环境配置
|
|
902194
|
-
const {
|
|
902195
|
-
const res = await this.
|
|
902196
|
-
|
|
902426
|
+
const { namespace } = this.getFunctionConfig();
|
|
902427
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
902428
|
+
Namespace: namespace,
|
|
902197
902429
|
Limit: limit,
|
|
902198
902430
|
Offset: offset
|
|
902199
902431
|
});
|
|
@@ -902224,8 +902456,8 @@ class FunctionService {
|
|
|
902224
902456
|
const { envId } = options;
|
|
902225
902457
|
while (true) {
|
|
902226
902458
|
try {
|
|
902227
|
-
const res = await this.
|
|
902228
|
-
|
|
902459
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
902460
|
+
Namespace: envId,
|
|
902229
902461
|
Limit: pageSize,
|
|
902230
902462
|
Offset: currentOffset
|
|
902231
902463
|
});
|
|
@@ -902265,22 +902497,25 @@ class FunctionService {
|
|
|
902265
902497
|
* @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
|
|
902266
902498
|
* @returns {Promise<IResponseInfo>}
|
|
902267
902499
|
*/
|
|
902268
|
-
async deleteFunction(
|
|
902500
|
+
async deleteFunction(name) {
|
|
902269
902501
|
var _a;
|
|
902502
|
+
const funcName = typeof name === 'string'
|
|
902503
|
+
? name
|
|
902504
|
+
: name === null || name === void 0 ? void 0 : name.name;
|
|
902270
902505
|
const { namespace } = this.getFunctionConfig();
|
|
902271
902506
|
// 检测是否绑定了 API 网关
|
|
902272
902507
|
const accessService = this.environment.getAccessService();
|
|
902273
902508
|
const res = await accessService.getAccessList({
|
|
902274
|
-
name
|
|
902509
|
+
name: funcName
|
|
902275
902510
|
});
|
|
902276
902511
|
// 删除绑定的 API 网关
|
|
902277
902512
|
if (((_a = res === null || res === void 0 ? void 0 : res.APISet) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
902278
902513
|
await accessService.deleteAccess({
|
|
902279
|
-
name
|
|
902514
|
+
name: funcName
|
|
902280
902515
|
});
|
|
902281
902516
|
}
|
|
902282
|
-
await this.scfService.request('DeleteFunction', {
|
|
902283
|
-
FunctionName:
|
|
902517
|
+
return await this.scfService.request('DeleteFunction', {
|
|
902518
|
+
FunctionName: funcName,
|
|
902284
902519
|
Namespace: namespace
|
|
902285
902520
|
});
|
|
902286
902521
|
}
|
|
@@ -902308,17 +902543,16 @@ class FunctionService {
|
|
|
902308
902543
|
* @returns {Promise<Record<string, string>>}
|
|
902309
902544
|
*/
|
|
902310
902545
|
async getFunctionDetail(name, codeSecret) {
|
|
902311
|
-
const {
|
|
902546
|
+
const { namespace } = this.getFunctionConfig();
|
|
902312
902547
|
const params = {
|
|
902313
902548
|
FunctionName: name,
|
|
902314
|
-
EnvId: env,
|
|
902315
902549
|
ShowCode: 'TRUE',
|
|
902316
|
-
Namespace:
|
|
902550
|
+
Namespace: namespace
|
|
902317
902551
|
};
|
|
902318
902552
|
if (codeSecret) {
|
|
902319
902553
|
params.CodeSecret = codeSecret;
|
|
902320
902554
|
}
|
|
902321
|
-
const data = await this.
|
|
902555
|
+
const data = await this.scfService.request('GetFunction', params);
|
|
902322
902556
|
// 解析 VPC 配置
|
|
902323
902557
|
const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
|
|
902324
902558
|
if (VpcId && SubnetId) {
|
|
@@ -902495,67 +902729,113 @@ class FunctionService {
|
|
|
902495
902729
|
* @returns {Promise<IResponseInfo>}
|
|
902496
902730
|
*/
|
|
902497
902731
|
async updateFunctionConfig(func) {
|
|
902498
|
-
var _a, _b, _c
|
|
902732
|
+
var _a, _b, _c;
|
|
902499
902733
|
const { namespace } = this.getFunctionConfig();
|
|
902500
|
-
|
|
902501
|
-
|
|
902502
|
-
|
|
902503
|
-
|
|
902504
|
-
|
|
902505
|
-
|
|
902734
|
+
// UpdateFunctionConfiguration API 白名单(大小写不敏感)
|
|
902735
|
+
// 参考:https://cloud.tencent.com/document/product/583/18580
|
|
902736
|
+
// 注意:Runtime, Handler, Code, Type, ProtocolType 只能在 CreateFunction 时指定
|
|
902737
|
+
// key: 小写用于匹配,value: PascalCase 用于输出
|
|
902738
|
+
const UPDATE_CONFIG_FIELDS = {
|
|
902739
|
+
'description': 'Description',
|
|
902740
|
+
'memorysize': 'MemorySize',
|
|
902741
|
+
'timeout': 'Timeout',
|
|
902742
|
+
'role': 'Role',
|
|
902743
|
+
// 日志配置
|
|
902744
|
+
'clslogsetid': 'ClsLogsetId',
|
|
902745
|
+
'clstopicid': 'ClsTopicId',
|
|
902746
|
+
// 高级配置
|
|
902747
|
+
'deadletterconfig': 'DeadLetterConfig',
|
|
902748
|
+
'publicnetconfig': 'PublicNetConfig',
|
|
902749
|
+
'cfsconfig': 'CfsConfig',
|
|
902750
|
+
'inittimeout': 'InitTimeout',
|
|
902751
|
+
// 注意:asyncRunEnable/traceEnable/autoDeployClsTopicIndex/autoCreateClsTopic
|
|
902752
|
+
// 只能在 CreateFunction 时设置,UpdateFunctionConfiguration 不支持
|
|
902753
|
+
// 注意:dnsCache 需要 'TRUE'/'FALSE' 字符串,在特殊处理阶段处理
|
|
902754
|
+
'intranetconfig': 'IntranetConfig',
|
|
902755
|
+
};
|
|
902756
|
+
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
902757
|
+
// 构建参数
|
|
902506
902758
|
const params = {
|
|
902507
|
-
FunctionName: func.name,
|
|
902508
902759
|
Namespace: namespace,
|
|
902509
|
-
|
|
902510
|
-
|
|
902511
|
-
|
|
902512
|
-
|
|
902760
|
+
FunctionName: func.name,
|
|
902761
|
+
ClsTopicId: TopicId,
|
|
902762
|
+
ClsLogsetId: LogsetId
|
|
902763
|
+
};
|
|
902764
|
+
// 白名单字段自动转换(大小写不敏感,统一输出 PascalCase)
|
|
902765
|
+
for (const key of Object.keys(func)) {
|
|
902766
|
+
const lowerKey = key.toLowerCase();
|
|
902767
|
+
const pascalKey = UPDATE_CONFIG_FIELDS[lowerKey];
|
|
902768
|
+
if (!pascalKey || func[key] === undefined)
|
|
902769
|
+
continue;
|
|
902770
|
+
params[pascalKey] = toPascalCaseKeys(func[key]);
|
|
902513
902771
|
}
|
|
902514
|
-
//
|
|
902515
|
-
|
|
902516
|
-
|
|
902517
|
-
|
|
902518
|
-
|
|
902519
|
-
|
|
902520
|
-
|
|
902772
|
+
// 特殊处理:安装依赖标志(支持 boolean | string)
|
|
902773
|
+
if (func.installDependency !== undefined) {
|
|
902774
|
+
params.InstallDependency = toBooleanString(func.installDependency);
|
|
902775
|
+
}
|
|
902776
|
+
// 特殊处理:L5 配置(支持 boolean | string)
|
|
902777
|
+
if (func.l5 !== undefined) {
|
|
902778
|
+
params.L5Enable = toBooleanString(func.l5);
|
|
902779
|
+
}
|
|
902780
|
+
// 特殊处理:DnsCache(支持 boolean | string,大小写不敏感)
|
|
902781
|
+
// 注意:asyncRunEnable/traceEnable/autoDeployClsTopicIndex/autoCreateClsTopic
|
|
902782
|
+
// 只能在 CreateFunction 时设置,UpdateFunctionConfiguration 不支持这些参数
|
|
902783
|
+
const dnsCacheValue = getFieldIgnoreCase(func, 'dnsCache');
|
|
902784
|
+
if (dnsCacheValue !== undefined) {
|
|
902785
|
+
params.DnsCache = toBooleanString(dnsCacheValue);
|
|
902786
|
+
}
|
|
902787
|
+
// 特殊处理:Publish - 是否同时发布新版本(支持 boolean | string,大小写不敏感)
|
|
902788
|
+
const publishValue = getFieldIgnoreCase(func, 'publish');
|
|
902789
|
+
if (publishValue !== undefined) {
|
|
902790
|
+
params.Publish = toBooleanString(publishValue);
|
|
902791
|
+
}
|
|
902792
|
+
// 特殊处理:环境变量
|
|
902793
|
+
if (func.envVariables && Object.keys(func.envVariables).length > 0) {
|
|
902794
|
+
params.Environment = {
|
|
902795
|
+
Variables: Object.keys(func.envVariables).map(key => ({
|
|
902796
|
+
Key: key,
|
|
902797
|
+
Value: func.envVariables[key]
|
|
902798
|
+
}))
|
|
902799
|
+
};
|
|
902800
|
+
}
|
|
902801
|
+
// 特殊处理:VPC 配置
|
|
902521
902802
|
if (((_a = func === null || func === void 0 ? void 0 : func.vpc) === null || _a === void 0 ? void 0 : _a.subnetId) !== undefined && ((_b = func === null || func === void 0 ? void 0 : func.vpc) === null || _b === void 0 ? void 0 : _b.vpcId) !== undefined) {
|
|
902522
|
-
// VPC 网络
|
|
902523
902803
|
params.VpcConfig = {
|
|
902524
|
-
SubnetId:
|
|
902525
|
-
VpcId:
|
|
902804
|
+
SubnetId: func.vpc.subnetId,
|
|
902805
|
+
VpcId: func.vpc.vpcId
|
|
902526
902806
|
};
|
|
902527
902807
|
}
|
|
902528
|
-
//
|
|
902529
|
-
|
|
902530
|
-
|
|
902531
|
-
isNodeFunction(func.runtime) && (params.InstallDependency = 'TRUE');
|
|
902532
|
-
// 是否安装依赖,选项可以覆盖
|
|
902533
|
-
if (typeof func.installDependency !== 'undefined') {
|
|
902534
|
-
params.InstallDependency = func.installDependency ? 'TRUE' : 'FALSE';
|
|
902535
|
-
}
|
|
902536
|
-
// 函数层
|
|
902537
|
-
if ((_e = func === null || func === void 0 ? void 0 : func.layers) === null || _e === void 0 ? void 0 : _e.length) {
|
|
902538
|
-
const transformLayers = func.layers.map(item => ({
|
|
902808
|
+
// 特殊处理:函数层
|
|
902809
|
+
if ((_c = func === null || func === void 0 ? void 0 : func.layers) === null || _c === void 0 ? void 0 : _c.length) {
|
|
902810
|
+
params.Layers = func.layers.map(item => ({
|
|
902539
902811
|
LayerName: item.name,
|
|
902540
902812
|
LayerVersion: item.version
|
|
902541
902813
|
}));
|
|
902542
|
-
params.Layers = transformLayers;
|
|
902543
902814
|
}
|
|
902544
|
-
//
|
|
902545
|
-
|
|
902546
|
-
|
|
902547
|
-
|
|
902548
|
-
|
|
902549
|
-
|
|
902550
|
-
|
|
902551
|
-
}
|
|
902815
|
+
// 特殊处理:HTTP 函数多并发配置(大小写不敏感)
|
|
902816
|
+
const instanceConcurrencyConfig = getFieldIgnoreCase(func, 'instanceConcurrencyConfig');
|
|
902817
|
+
if (instanceConcurrencyConfig) {
|
|
902818
|
+
const config = toPascalCaseKeys(instanceConcurrencyConfig);
|
|
902819
|
+
// DynamicEnabled 需要特殊处理为 'TRUE'/'FALSE'
|
|
902820
|
+
if (config.DynamicEnabled !== undefined) {
|
|
902821
|
+
config.DynamicEnabled = toBooleanString(config.DynamicEnabled);
|
|
902822
|
+
}
|
|
902823
|
+
params.InstanceConcurrencyConfig = config;
|
|
902824
|
+
}
|
|
902825
|
+
// 特殊处理:HTTP 函数协议参数(WebSocket,大小写不敏感)
|
|
902826
|
+
const protocolParams = getFieldIgnoreCase(func, 'protocolParams');
|
|
902827
|
+
if (protocolParams) {
|
|
902828
|
+
const wsParams = getFieldIgnoreCase(protocolParams, 'wsParams');
|
|
902829
|
+
if (wsParams) {
|
|
902830
|
+
params.ProtocolParams = {
|
|
902831
|
+
WSParams: toPascalCaseKeys(wsParams)
|
|
902832
|
+
};
|
|
902833
|
+
}
|
|
902552
902834
|
}
|
|
902553
|
-
//
|
|
902554
|
-
|
|
902555
|
-
|
|
902556
|
-
|
|
902557
|
-
MaxConcurrency: func.instanceConcurrencyConfig.maxConcurrency || 10
|
|
902558
|
-
};
|
|
902835
|
+
// 特殊处理:忽略系统日志上报(Boolean 类型,直接传递,大小写不敏感)
|
|
902836
|
+
const ignoreSysLogValue = getFieldIgnoreCase(func, 'ignoreSysLog');
|
|
902837
|
+
if (ignoreSysLogValue !== undefined) {
|
|
902838
|
+
params.IgnoreSysLog = ignoreSysLogValue;
|
|
902559
902839
|
}
|
|
902560
902840
|
try {
|
|
902561
902841
|
// 如果函数配置中包含触发器,则更新触发器
|
|
@@ -902584,26 +902864,25 @@ class FunctionService {
|
|
|
902584
902864
|
* @memberof FunctionService
|
|
902585
902865
|
*/
|
|
902586
902866
|
async updateFunctionCode(funcParam) {
|
|
902587
|
-
var _a;
|
|
902588
902867
|
const { func, functionRootPath, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
902589
902868
|
const funcName = func.name;
|
|
902590
|
-
const {
|
|
902869
|
+
const { namespace } = this.getFunctionConfig();
|
|
902591
902870
|
// 镜像部署:使用镜像配置更新函数代码
|
|
902592
902871
|
if (deployMode === 'image') {
|
|
902593
|
-
if (!((_a = func.imageConfig) === null || _a === void 0 ? void 0 : _a.imageUri)) {
|
|
902594
|
-
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
902595
|
-
}
|
|
902596
902872
|
const params = {
|
|
902597
902873
|
FunctionName: funcName,
|
|
902598
|
-
|
|
902874
|
+
Namespace: namespace,
|
|
902599
902875
|
Code: {
|
|
902600
902876
|
ImageConfig: buildImageConfig(func.imageConfig)
|
|
902601
902877
|
}
|
|
902602
902878
|
};
|
|
902879
|
+
if (!params.Code.ImageConfig.ImageUri) {
|
|
902880
|
+
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
902881
|
+
}
|
|
902603
902882
|
try {
|
|
902604
902883
|
// 等待函数状态正常
|
|
902605
902884
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902606
|
-
return await this.
|
|
902885
|
+
return await this.scfService.request('UpdateFunctionCode', params);
|
|
902607
902886
|
}
|
|
902608
902887
|
catch (e) {
|
|
902609
902888
|
throw new error_1.CloudBaseError(`[${funcName}] 函数代码更新失败:${e.message}`, {
|
|
@@ -902616,9 +902895,9 @@ class FunctionService {
|
|
|
902616
902895
|
let installDependency;
|
|
902617
902896
|
// Node 函数默认安装依赖
|
|
902618
902897
|
installDependency = isNodeFunction(func.runtime) ? 'TRUE' : 'FALSE';
|
|
902619
|
-
//
|
|
902620
|
-
if (
|
|
902621
|
-
installDependency = func.installDependency
|
|
902898
|
+
// 是否安装依赖,选项可以覆盖(支持 boolean | string)
|
|
902899
|
+
if (func.installDependency !== undefined) {
|
|
902900
|
+
installDependency = toBooleanString(func.installDependency);
|
|
902622
902901
|
}
|
|
902623
902902
|
const codeParams = await this.getCodeParams({
|
|
902624
902903
|
func,
|
|
@@ -902629,7 +902908,7 @@ class FunctionService {
|
|
|
902629
902908
|
}, installDependency);
|
|
902630
902909
|
const params = {
|
|
902631
902910
|
FunctionName: funcName,
|
|
902632
|
-
|
|
902911
|
+
Namespace: namespace,
|
|
902633
902912
|
Handler: func.handler || 'index.main',
|
|
902634
902913
|
InstallDependency: installDependency,
|
|
902635
902914
|
Code: codeParams
|
|
@@ -902641,7 +902920,7 @@ class FunctionService {
|
|
|
902641
902920
|
// 等待函数状态正常
|
|
902642
902921
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902643
902922
|
// 更新云函数代码
|
|
902644
|
-
const res = await this.
|
|
902923
|
+
const res = await this.scfService.request('UpdateFunctionCode', params);
|
|
902645
902924
|
if (installDependency && func.isWaitInstall === true) {
|
|
902646
902925
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902647
902926
|
}
|
|
@@ -902783,13 +903062,12 @@ class FunctionService {
|
|
|
902783
903062
|
async deleteFunctionTrigger(name, triggerName) {
|
|
902784
903063
|
const { namespace } = this.getFunctionConfig();
|
|
902785
903064
|
try {
|
|
902786
|
-
await this.scfService.request('DeleteTrigger', {
|
|
903065
|
+
return await this.scfService.request('DeleteTrigger', {
|
|
902787
903066
|
FunctionName: name,
|
|
902788
903067
|
Namespace: namespace,
|
|
902789
903068
|
TriggerName: triggerName,
|
|
902790
903069
|
Type: 'timer'
|
|
902791
903070
|
});
|
|
902792
|
-
(0, utils_1.successLog)(`[${name}] 删除云函数触发器 ${triggerName} 成功!`);
|
|
902793
903071
|
}
|
|
902794
903072
|
catch (e) {
|
|
902795
903073
|
throw new error_1.CloudBaseError(`[${name}] 删除触发器失败:${e.message}`);
|
|
@@ -903025,7 +903303,8 @@ class FunctionService {
|
|
|
903025
903303
|
if (Status === constant_1.SCF_STATUS.CREATE_FAILED) {
|
|
903026
903304
|
const errorDetails = (StatusReasons === null || StatusReasons === void 0 ? void 0 : StatusReasons.map(item => `[${item.ErrorCode}] ${item.ErrorMessage}`).join('\n')) || '';
|
|
903027
903305
|
const errorMsg = `云函数创建失败${StatusDesc ? `\n状态描述: ${StatusDesc}` : ''}${errorDetails ? `\n失败信息: ${errorDetails}` : ''}`;
|
|
903028
|
-
|
|
903306
|
+
// 注意:这里不传递 RequestId,因为这是 GetFunction 的 RequestId,不是导致失败的 CreateFunction/UpdateFunctionCode 的 RequestId
|
|
903307
|
+
throw new error_1.CloudBaseError(errorMsg);
|
|
903029
903308
|
}
|
|
903030
903309
|
// 函数状态正常
|
|
903031
903310
|
clearInterval(ticker);
|
|
@@ -903205,7 +903484,12 @@ class FunctionService {
|
|
|
903205
903484
|
// 清理临时文件
|
|
903206
903485
|
await packer.clean();
|
|
903207
903486
|
if (err) {
|
|
903208
|
-
|
|
903487
|
+
// 保留完整的错误信息(避免原始错误丢失)
|
|
903488
|
+
const errorMessage = err.message || err.error || String(err);
|
|
903489
|
+
const errorCode = err.code || err.statusCode || '';
|
|
903490
|
+
reject(new error_1.CloudBaseError(`COS 上传失败: ${errorMessage}${errorCode ? ` (${errorCode})` : ''}`, {
|
|
903491
|
+
code: errorCode
|
|
903492
|
+
}));
|
|
903209
903493
|
}
|
|
903210
903494
|
else {
|
|
903211
903495
|
resolve(data);
|
|
@@ -903258,7 +903542,16 @@ class FunctionService {
|
|
|
903258
903542
|
headers
|
|
903259
903543
|
});
|
|
903260
903544
|
if (!response.ok) {
|
|
903261
|
-
|
|
903545
|
+
// 尝试获取响应体中的错误信息
|
|
903546
|
+
let errorDetail = '';
|
|
903547
|
+
try {
|
|
903548
|
+
const responseText = await response.text();
|
|
903549
|
+
errorDetail = responseText ? ` - ${responseText}` : '';
|
|
903550
|
+
}
|
|
903551
|
+
catch (e) {
|
|
903552
|
+
// 忽略响应体解析错误
|
|
903553
|
+
}
|
|
903554
|
+
throw new error_1.CloudBaseError(`上传失败: ${response.status} ${response.statusText}${errorDetail}`);
|
|
903262
903555
|
}
|
|
903263
903556
|
// 清理临时文件
|
|
903264
903557
|
await packer.clean();
|