@cloudbase/cli 2.12.7 → 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 +385 -205
- package/package.json +1 -1
package/dist/standalone/cli.js
CHANGED
|
@@ -326328,7 +326328,7 @@ module.exports = function generate_pattern(it, $keyword, $ruleType) {
|
|
|
326328
326328
|
/***/ ((module) => {
|
|
326329
326329
|
|
|
326330
326330
|
"use strict";
|
|
326331
|
-
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 - 腾讯云云开发命令行工具,支持云函数、云数据库、静态托管等全栈云开发能力"}}');
|
|
326332
326332
|
|
|
326333
326333
|
/***/ }),
|
|
326334
326334
|
|
|
@@ -724364,21 +724364,27 @@ class StorageService {
|
|
|
724364
724364
|
Error
|
|
724365
724365
|
};
|
|
724366
724366
|
}
|
|
724367
|
-
|
|
724368
|
-
* 获取文件存储权限
|
|
724369
|
-
* READONLY:所有用户可读,仅创建者和管理员可写
|
|
724370
|
-
* PRIVATE:仅创建者及管理员可读写
|
|
724371
|
-
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
724372
|
-
* ADMINONLY:仅管理员可读写
|
|
724373
|
-
* @returns
|
|
724374
|
-
*/
|
|
724375
|
-
async getStorageAcl() {
|
|
724367
|
+
async getStorageAcl(options) {
|
|
724376
724368
|
const { bucket, env } = this.getStorageConfig();
|
|
724377
|
-
const res = await this.tcbService.request('
|
|
724369
|
+
const res = await this.tcbService.request('DescribeStorageSafeRule', {
|
|
724378
724370
|
EnvId: env,
|
|
724379
724371
|
Bucket: bucket
|
|
724380
724372
|
});
|
|
724381
|
-
|
|
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;
|
|
724382
724388
|
}
|
|
724383
724389
|
/**
|
|
724384
724390
|
* 设置文件存储权限
|
|
@@ -724386,20 +724392,38 @@ class StorageService {
|
|
|
724386
724392
|
* PRIVATE:仅创建者及管理员可读写
|
|
724387
724393
|
* ADMINWRITE:所有用户可读,仅管理员可写
|
|
724388
724394
|
* ADMINONLY:仅管理员可读写
|
|
724389
|
-
*
|
|
724395
|
+
* CUSTOM:自定义安全规则(需要传入 rule 参数)
|
|
724396
|
+
* @param {AclType} acl 权限类型
|
|
724397
|
+
* @param {IStorageAclRule} [rule] 自定义安全规则,当 acl 为 CUSTOM 时必填
|
|
724390
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
|
+
* })
|
|
724391
724408
|
*/
|
|
724392
|
-
async setStorageAcl(acl) {
|
|
724393
|
-
const validAcl = ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY'];
|
|
724409
|
+
async setStorageAcl(acl, rule) {
|
|
724410
|
+
const validAcl = ['READONLY', 'PRIVATE', 'ADMINWRITE', 'ADMINONLY', 'CUSTOM'];
|
|
724394
724411
|
if (!validAcl.includes(acl)) {
|
|
724395
|
-
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 参数');
|
|
724396
724416
|
}
|
|
724397
724417
|
const { bucket, env } = this.getStorageConfig();
|
|
724398
|
-
|
|
724418
|
+
const params = {
|
|
724399
724419
|
EnvId: env,
|
|
724400
724420
|
Bucket: bucket,
|
|
724401
724421
|
AclTag: acl
|
|
724402
|
-
}
|
|
724422
|
+
};
|
|
724423
|
+
if (acl === 'CUSTOM' && rule) {
|
|
724424
|
+
params.Rule = JSON.stringify(rule);
|
|
724425
|
+
}
|
|
724426
|
+
return this.tcbService.request('ModifyStorageSafeRule', params);
|
|
724403
724427
|
}
|
|
724404
724428
|
/**
|
|
724405
724429
|
* 遍历云端文件夹
|
|
@@ -730403,8 +730427,8 @@ let GetAclCommand = class GetAclCommand extends common_1.Command {
|
|
|
730403
730427
|
execute(envId) {
|
|
730404
730428
|
return __awaiter(this, void 0, void 0, function* () {
|
|
730405
730429
|
const storageService = yield getStorageService(envId);
|
|
730406
|
-
const acl = yield storageService.getStorageAcl();
|
|
730407
|
-
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] }));
|
|
730408
730432
|
});
|
|
730409
730433
|
}
|
|
730410
730434
|
};
|
|
@@ -902011,117 +902035,213 @@ function isNodeFunction(runtime) {
|
|
|
902011
902035
|
/**
|
|
902012
902036
|
* 构建镜像配置对象
|
|
902013
902037
|
* @param imageConfig 镜像配置
|
|
902014
|
-
* @param options 可选配置
|
|
902015
|
-
* @param options.includeCommandList 是否包含 CommandList/ArgsList(仅 CreateFunction 支持)
|
|
902016
902038
|
* @returns 构建好的镜像配置对象
|
|
902017
902039
|
*/
|
|
902018
|
-
function buildImageConfig(imageConfig
|
|
902019
|
-
|
|
902020
|
-
const
|
|
902021
|
-
|
|
902022
|
-
|
|
902023
|
-
|
|
902024
|
-
|
|
902025
|
-
|
|
902026
|
-
|
|
902027
|
-
|
|
902028
|
-
|
|
902029
|
-
|
|
902030
|
-
|
|
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];
|
|
902031
902110
|
}
|
|
902032
902111
|
}
|
|
902033
|
-
return
|
|
902112
|
+
return undefined;
|
|
902034
902113
|
}
|
|
902035
|
-
//
|
|
902114
|
+
// 解析函数配置,换成请求参数(用于 CreateFunction)
|
|
902036
902115
|
function configToParams(options) {
|
|
902037
|
-
var _a, _b, _c
|
|
902038
|
-
const { func, codeSecret, baseParams } = options;
|
|
902039
|
-
|
|
902040
|
-
//
|
|
902041
|
-
|
|
902042
|
-
|
|
902043
|
-
|
|
902044
|
-
|
|
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]);
|
|
902045
902151
|
}
|
|
902046
|
-
//
|
|
902047
|
-
|
|
902048
|
-
|
|
902049
|
-
|
|
902050
|
-
}
|
|
902051
|
-
//
|
|
902052
|
-
|
|
902053
|
-
|
|
902054
|
-
|
|
902055
|
-
|
|
902056
|
-
|
|
902057
|
-
|
|
902058
|
-
//
|
|
902059
|
-
//
|
|
902060
|
-
|
|
902061
|
-
|
|
902062
|
-
|
|
902063
|
-
|
|
902064
|
-
|
|
902065
|
-
|
|
902066
|
-
|
|
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 配置
|
|
902067
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) {
|
|
902068
|
-
// VPC 网络
|
|
902069
902195
|
params.VpcConfig = {
|
|
902070
|
-
SubnetId:
|
|
902071
|
-
VpcId:
|
|
902196
|
+
SubnetId: func.vpc.subnetId,
|
|
902197
|
+
VpcId: func.vpc.vpcId
|
|
902072
902198
|
};
|
|
902073
902199
|
}
|
|
902074
|
-
//
|
|
902075
|
-
|
|
902076
|
-
|
|
902077
|
-
params.InstallDependency = installDependency;
|
|
902078
|
-
// 代码保护
|
|
902079
|
-
if (codeSecret || func.codeSecret) {
|
|
902080
|
-
params.CodeSecret = codeSecret || func.codeSecret;
|
|
902081
|
-
}
|
|
902082
|
-
// 函数层
|
|
902083
|
-
if ((_e = func === null || func === void 0 ? void 0 : func.layers) === null || _e === void 0 ? void 0 : _e.length) {
|
|
902084
|
-
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 => ({
|
|
902085
902203
|
LayerName: item.name,
|
|
902086
902204
|
LayerVersion: item.version
|
|
902087
902205
|
}));
|
|
902088
|
-
params.Layers = transformLayers;
|
|
902089
902206
|
}
|
|
902090
|
-
//
|
|
902091
|
-
if (
|
|
902092
|
-
params.
|
|
902093
|
-
|
|
902094
|
-
|
|
902095
|
-
|
|
902096
|
-
|
|
902097
|
-
|
|
902098
|
-
|
|
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) {
|
|
902099
902216
|
params.ProtocolParams = {
|
|
902100
|
-
WSParams:
|
|
902101
|
-
IdleTimeOut: typeof idleTimeOut === 'number' ? idleTimeOut : 15
|
|
902102
|
-
}
|
|
902103
|
-
};
|
|
902104
|
-
}
|
|
902105
|
-
// 多并发配置
|
|
902106
|
-
// 参考文档:https://cloud.tencent.com/document/api/583/17244#InstanceConcurrencyConfig
|
|
902107
|
-
if (func === null || func === void 0 ? void 0 : func.instanceConcurrencyConfig) {
|
|
902108
|
-
params.InstanceConcurrencyConfig = {
|
|
902109
|
-
DynamicEnabled: func.instanceConcurrencyConfig.dynamicEnabled || 'FALSE',
|
|
902110
|
-
MaxConcurrency: func.instanceConcurrencyConfig.maxConcurrency || 10
|
|
902217
|
+
WSParams: toPascalCaseKeys(wsParams)
|
|
902111
902218
|
};
|
|
902112
902219
|
}
|
|
902113
902220
|
}
|
|
902114
|
-
//
|
|
902115
|
-
|
|
902116
|
-
|
|
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
|
+
}
|
|
902117
902235
|
}
|
|
902118
|
-
//
|
|
902119
|
-
|
|
902120
|
-
|
|
902121
|
-
|
|
902122
|
-
|
|
902236
|
+
// 10. 镜像配置(用于镜像部署,大小写不敏感)
|
|
902237
|
+
const imageConfig = getFieldIgnoreCase(func, 'imageConfig');
|
|
902238
|
+
if (imageConfig) {
|
|
902239
|
+
params.Code = params.Code || {};
|
|
902240
|
+
params.Code.ImageConfig = buildImageConfig(imageConfig);
|
|
902123
902241
|
}
|
|
902124
|
-
|
|
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);
|
|
902125
902245
|
}
|
|
902126
902246
|
class FunctionService {
|
|
902127
902247
|
constructor(environment) {
|
|
@@ -902138,12 +902258,11 @@ class FunctionService {
|
|
|
902138
902258
|
* @memberof FunctionService
|
|
902139
902259
|
*/
|
|
902140
902260
|
async updateFunctionIncrementalCode(funcParam) {
|
|
902141
|
-
const {
|
|
902261
|
+
const { namespace } = this.getFunctionConfig();
|
|
902142
902262
|
const { functionRootPath, func, deleteFiles, addFiles } = funcParam;
|
|
902143
902263
|
const { name, runtime } = func;
|
|
902144
902264
|
const params = {
|
|
902145
902265
|
FunctionName: name,
|
|
902146
|
-
EnvId: env,
|
|
902147
902266
|
Namespace: namespace
|
|
902148
902267
|
};
|
|
902149
902268
|
let packer;
|
|
@@ -902168,7 +902287,7 @@ class FunctionService {
|
|
|
902168
902287
|
}
|
|
902169
902288
|
params.AddFiles = base64;
|
|
902170
902289
|
}
|
|
902171
|
-
return this.
|
|
902290
|
+
return this.scfService.request('UpdateFunctionIncrementalCode', params);
|
|
902172
902291
|
}
|
|
902173
902292
|
/**
|
|
902174
902293
|
* 创建云函数
|
|
@@ -902176,25 +902295,28 @@ class FunctionService {
|
|
|
902176
902295
|
* @returns {(Promise<IResponseInfo | ICreateFunctionRes>)}
|
|
902177
902296
|
*/
|
|
902178
902297
|
async createFunction(funcParam) {
|
|
902179
|
-
var _a;
|
|
902180
|
-
const {
|
|
902298
|
+
var _a, _b, _c;
|
|
902299
|
+
const { namespace } = this.getFunctionConfig();
|
|
902181
902300
|
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
902182
902301
|
const funcName = func.name;
|
|
902302
|
+
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
902183
902303
|
const params = configToParams({
|
|
902184
902304
|
func,
|
|
902185
902305
|
codeSecret,
|
|
902186
902306
|
baseParams: {
|
|
902187
|
-
|
|
902307
|
+
Namespace: namespace,
|
|
902188
902308
|
Role: 'TCB_QcsRole',
|
|
902189
|
-
Stamp: 'MINI_QCBASE'
|
|
902309
|
+
Stamp: 'MINI_QCBASE',
|
|
902310
|
+
ClsTopicId: TopicId,
|
|
902311
|
+
ClsLogsetId: LogsetId
|
|
902190
902312
|
}
|
|
902191
902313
|
});
|
|
902192
902314
|
// 根据部署方式处理 Code 参数
|
|
902193
902315
|
// 优先使用显式指定的 deployMode,如果未指定但存在 imageConfig 则认为是镜像部署
|
|
902194
|
-
const isImageDeploy = deployMode === 'image' || (!deployMode &&
|
|
902316
|
+
const isImageDeploy = deployMode === 'image' || (!deployMode && ((_a = params.Code) === null || _a === void 0 ? void 0 : _a.ImageConfig));
|
|
902195
902317
|
if (isImageDeploy) {
|
|
902196
902318
|
// 镜像部署:Code 参数已在 configToParams 中通过 imageConfig 设置
|
|
902197
|
-
if (!((
|
|
902319
|
+
if (!((_c = (_b = params.Code) === null || _b === void 0 ? void 0 : _b.ImageConfig) === null || _c === void 0 ? void 0 : _c.ImageUri)) {
|
|
902198
902320
|
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
902199
902321
|
}
|
|
902200
902322
|
// 镜像部署的特殊配置
|
|
@@ -902213,12 +902335,9 @@ class FunctionService {
|
|
|
902213
902335
|
deployMode
|
|
902214
902336
|
}, params.InstallDependency);
|
|
902215
902337
|
}
|
|
902216
|
-
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
902217
|
-
params.ClsTopicId = TopicId;
|
|
902218
|
-
params.ClsLogsetId = LogsetId;
|
|
902219
902338
|
try {
|
|
902220
902339
|
// 创建云函数
|
|
902221
|
-
const res = await this.
|
|
902340
|
+
const res = await this.scfService.request('CreateFunction', params);
|
|
902222
902341
|
// 等待函数状态正常
|
|
902223
902342
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902224
902343
|
// 创建函数触发器、失败自动重试
|
|
@@ -902288,9 +902407,9 @@ class FunctionService {
|
|
|
902288
902407
|
*/
|
|
902289
902408
|
async getFunctionList(limit = 20, offset = 0) {
|
|
902290
902409
|
// 获取Function 环境配置
|
|
902291
|
-
const {
|
|
902292
|
-
const res = await this.
|
|
902293
|
-
|
|
902410
|
+
const { namespace } = this.getFunctionConfig();
|
|
902411
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
902412
|
+
Namespace: namespace,
|
|
902294
902413
|
Limit: limit,
|
|
902295
902414
|
Offset: offset
|
|
902296
902415
|
});
|
|
@@ -902304,9 +902423,9 @@ class FunctionService {
|
|
|
902304
902423
|
*/
|
|
902305
902424
|
async listFunctions(limit = 20, offset = 0) {
|
|
902306
902425
|
// 获取Function 环境配置
|
|
902307
|
-
const {
|
|
902308
|
-
const res = await this.
|
|
902309
|
-
|
|
902426
|
+
const { namespace } = this.getFunctionConfig();
|
|
902427
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
902428
|
+
Namespace: namespace,
|
|
902310
902429
|
Limit: limit,
|
|
902311
902430
|
Offset: offset
|
|
902312
902431
|
});
|
|
@@ -902337,8 +902456,8 @@ class FunctionService {
|
|
|
902337
902456
|
const { envId } = options;
|
|
902338
902457
|
while (true) {
|
|
902339
902458
|
try {
|
|
902340
|
-
const res = await this.
|
|
902341
|
-
|
|
902459
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
902460
|
+
Namespace: envId,
|
|
902342
902461
|
Limit: pageSize,
|
|
902343
902462
|
Offset: currentOffset
|
|
902344
902463
|
});
|
|
@@ -902378,22 +902497,25 @@ class FunctionService {
|
|
|
902378
902497
|
* @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
|
|
902379
902498
|
* @returns {Promise<IResponseInfo>}
|
|
902380
902499
|
*/
|
|
902381
|
-
async deleteFunction(
|
|
902500
|
+
async deleteFunction(name) {
|
|
902382
902501
|
var _a;
|
|
902502
|
+
const funcName = typeof name === 'string'
|
|
902503
|
+
? name
|
|
902504
|
+
: name === null || name === void 0 ? void 0 : name.name;
|
|
902383
902505
|
const { namespace } = this.getFunctionConfig();
|
|
902384
902506
|
// 检测是否绑定了 API 网关
|
|
902385
902507
|
const accessService = this.environment.getAccessService();
|
|
902386
902508
|
const res = await accessService.getAccessList({
|
|
902387
|
-
name
|
|
902509
|
+
name: funcName
|
|
902388
902510
|
});
|
|
902389
902511
|
// 删除绑定的 API 网关
|
|
902390
902512
|
if (((_a = res === null || res === void 0 ? void 0 : res.APISet) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
902391
902513
|
await accessService.deleteAccess({
|
|
902392
|
-
name
|
|
902514
|
+
name: funcName
|
|
902393
902515
|
});
|
|
902394
902516
|
}
|
|
902395
|
-
await this.scfService.request('DeleteFunction', {
|
|
902396
|
-
FunctionName:
|
|
902517
|
+
return await this.scfService.request('DeleteFunction', {
|
|
902518
|
+
FunctionName: funcName,
|
|
902397
902519
|
Namespace: namespace
|
|
902398
902520
|
});
|
|
902399
902521
|
}
|
|
@@ -902421,17 +902543,16 @@ class FunctionService {
|
|
|
902421
902543
|
* @returns {Promise<Record<string, string>>}
|
|
902422
902544
|
*/
|
|
902423
902545
|
async getFunctionDetail(name, codeSecret) {
|
|
902424
|
-
const {
|
|
902546
|
+
const { namespace } = this.getFunctionConfig();
|
|
902425
902547
|
const params = {
|
|
902426
902548
|
FunctionName: name,
|
|
902427
|
-
EnvId: env,
|
|
902428
902549
|
ShowCode: 'TRUE',
|
|
902429
|
-
Namespace:
|
|
902550
|
+
Namespace: namespace
|
|
902430
902551
|
};
|
|
902431
902552
|
if (codeSecret) {
|
|
902432
902553
|
params.CodeSecret = codeSecret;
|
|
902433
902554
|
}
|
|
902434
|
-
const data = await this.
|
|
902555
|
+
const data = await this.scfService.request('GetFunction', params);
|
|
902435
902556
|
// 解析 VPC 配置
|
|
902436
902557
|
const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
|
|
902437
902558
|
if (VpcId && SubnetId) {
|
|
@@ -902608,67 +902729,113 @@ class FunctionService {
|
|
|
902608
902729
|
* @returns {Promise<IResponseInfo>}
|
|
902609
902730
|
*/
|
|
902610
902731
|
async updateFunctionConfig(func) {
|
|
902611
|
-
var _a, _b, _c
|
|
902732
|
+
var _a, _b, _c;
|
|
902612
902733
|
const { namespace } = this.getFunctionConfig();
|
|
902613
|
-
|
|
902614
|
-
|
|
902615
|
-
|
|
902616
|
-
|
|
902617
|
-
|
|
902618
|
-
|
|
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
|
+
// 构建参数
|
|
902619
902758
|
const params = {
|
|
902620
|
-
FunctionName: func.name,
|
|
902621
902759
|
Namespace: namespace,
|
|
902622
|
-
|
|
902623
|
-
|
|
902624
|
-
|
|
902625
|
-
|
|
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]);
|
|
902626
902771
|
}
|
|
902627
|
-
//
|
|
902628
|
-
|
|
902629
|
-
|
|
902630
|
-
|
|
902631
|
-
|
|
902632
|
-
|
|
902633
|
-
|
|
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 配置
|
|
902634
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) {
|
|
902635
|
-
// VPC 网络
|
|
902636
902803
|
params.VpcConfig = {
|
|
902637
|
-
SubnetId:
|
|
902638
|
-
VpcId:
|
|
902804
|
+
SubnetId: func.vpc.subnetId,
|
|
902805
|
+
VpcId: func.vpc.vpcId
|
|
902639
902806
|
};
|
|
902640
902807
|
}
|
|
902641
|
-
//
|
|
902642
|
-
|
|
902643
|
-
|
|
902644
|
-
isNodeFunction(func.runtime) && (params.InstallDependency = 'TRUE');
|
|
902645
|
-
// 是否安装依赖,选项可以覆盖
|
|
902646
|
-
if (typeof func.installDependency !== 'undefined') {
|
|
902647
|
-
params.InstallDependency = func.installDependency ? 'TRUE' : 'FALSE';
|
|
902648
|
-
}
|
|
902649
|
-
// 函数层
|
|
902650
|
-
if ((_e = func === null || func === void 0 ? void 0 : func.layers) === null || _e === void 0 ? void 0 : _e.length) {
|
|
902651
|
-
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 => ({
|
|
902652
902811
|
LayerName: item.name,
|
|
902653
902812
|
LayerVersion: item.version
|
|
902654
902813
|
}));
|
|
902655
|
-
params.Layers = transformLayers;
|
|
902656
902814
|
}
|
|
902657
|
-
//
|
|
902658
|
-
|
|
902659
|
-
|
|
902660
|
-
|
|
902661
|
-
|
|
902662
|
-
|
|
902663
|
-
|
|
902664
|
-
}
|
|
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
|
+
}
|
|
902665
902834
|
}
|
|
902666
|
-
//
|
|
902667
|
-
|
|
902668
|
-
|
|
902669
|
-
|
|
902670
|
-
MaxConcurrency: func.instanceConcurrencyConfig.maxConcurrency || 10
|
|
902671
|
-
};
|
|
902835
|
+
// 特殊处理:忽略系统日志上报(Boolean 类型,直接传递,大小写不敏感)
|
|
902836
|
+
const ignoreSysLogValue = getFieldIgnoreCase(func, 'ignoreSysLog');
|
|
902837
|
+
if (ignoreSysLogValue !== undefined) {
|
|
902838
|
+
params.IgnoreSysLog = ignoreSysLogValue;
|
|
902672
902839
|
}
|
|
902673
902840
|
try {
|
|
902674
902841
|
// 如果函数配置中包含触发器,则更新触发器
|
|
@@ -902697,26 +902864,25 @@ class FunctionService {
|
|
|
902697
902864
|
* @memberof FunctionService
|
|
902698
902865
|
*/
|
|
902699
902866
|
async updateFunctionCode(funcParam) {
|
|
902700
|
-
var _a;
|
|
902701
902867
|
const { func, functionRootPath, base64Code, codeSecret, functionPath, deployMode } = funcParam;
|
|
902702
902868
|
const funcName = func.name;
|
|
902703
|
-
const {
|
|
902869
|
+
const { namespace } = this.getFunctionConfig();
|
|
902704
902870
|
// 镜像部署:使用镜像配置更新函数代码
|
|
902705
902871
|
if (deployMode === 'image') {
|
|
902706
|
-
if (!((_a = func.imageConfig) === null || _a === void 0 ? void 0 : _a.imageUri)) {
|
|
902707
|
-
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
902708
|
-
}
|
|
902709
902872
|
const params = {
|
|
902710
902873
|
FunctionName: funcName,
|
|
902711
|
-
|
|
902874
|
+
Namespace: namespace,
|
|
902712
902875
|
Code: {
|
|
902713
902876
|
ImageConfig: buildImageConfig(func.imageConfig)
|
|
902714
902877
|
}
|
|
902715
902878
|
};
|
|
902879
|
+
if (!params.Code.ImageConfig.ImageUri) {
|
|
902880
|
+
throw new error_1.CloudBaseError('镜像部署需要配置 imageConfig.imageUri');
|
|
902881
|
+
}
|
|
902716
902882
|
try {
|
|
902717
902883
|
// 等待函数状态正常
|
|
902718
902884
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902719
|
-
return await this.
|
|
902885
|
+
return await this.scfService.request('UpdateFunctionCode', params);
|
|
902720
902886
|
}
|
|
902721
902887
|
catch (e) {
|
|
902722
902888
|
throw new error_1.CloudBaseError(`[${funcName}] 函数代码更新失败:${e.message}`, {
|
|
@@ -902729,9 +902895,9 @@ class FunctionService {
|
|
|
902729
902895
|
let installDependency;
|
|
902730
902896
|
// Node 函数默认安装依赖
|
|
902731
902897
|
installDependency = isNodeFunction(func.runtime) ? 'TRUE' : 'FALSE';
|
|
902732
|
-
//
|
|
902733
|
-
if (
|
|
902734
|
-
installDependency = func.installDependency
|
|
902898
|
+
// 是否安装依赖,选项可以覆盖(支持 boolean | string)
|
|
902899
|
+
if (func.installDependency !== undefined) {
|
|
902900
|
+
installDependency = toBooleanString(func.installDependency);
|
|
902735
902901
|
}
|
|
902736
902902
|
const codeParams = await this.getCodeParams({
|
|
902737
902903
|
func,
|
|
@@ -902742,7 +902908,7 @@ class FunctionService {
|
|
|
902742
902908
|
}, installDependency);
|
|
902743
902909
|
const params = {
|
|
902744
902910
|
FunctionName: funcName,
|
|
902745
|
-
|
|
902911
|
+
Namespace: namespace,
|
|
902746
902912
|
Handler: func.handler || 'index.main',
|
|
902747
902913
|
InstallDependency: installDependency,
|
|
902748
902914
|
Code: codeParams
|
|
@@ -902754,7 +902920,7 @@ class FunctionService {
|
|
|
902754
902920
|
// 等待函数状态正常
|
|
902755
902921
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902756
902922
|
// 更新云函数代码
|
|
902757
|
-
const res = await this.
|
|
902923
|
+
const res = await this.scfService.request('UpdateFunctionCode', params);
|
|
902758
902924
|
if (installDependency && func.isWaitInstall === true) {
|
|
902759
902925
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
902760
902926
|
}
|
|
@@ -902896,13 +903062,12 @@ class FunctionService {
|
|
|
902896
903062
|
async deleteFunctionTrigger(name, triggerName) {
|
|
902897
903063
|
const { namespace } = this.getFunctionConfig();
|
|
902898
903064
|
try {
|
|
902899
|
-
await this.scfService.request('DeleteTrigger', {
|
|
903065
|
+
return await this.scfService.request('DeleteTrigger', {
|
|
902900
903066
|
FunctionName: name,
|
|
902901
903067
|
Namespace: namespace,
|
|
902902
903068
|
TriggerName: triggerName,
|
|
902903
903069
|
Type: 'timer'
|
|
902904
903070
|
});
|
|
902905
|
-
(0, utils_1.successLog)(`[${name}] 删除云函数触发器 ${triggerName} 成功!`);
|
|
902906
903071
|
}
|
|
902907
903072
|
catch (e) {
|
|
902908
903073
|
throw new error_1.CloudBaseError(`[${name}] 删除触发器失败:${e.message}`);
|
|
@@ -903138,7 +903303,8 @@ class FunctionService {
|
|
|
903138
903303
|
if (Status === constant_1.SCF_STATUS.CREATE_FAILED) {
|
|
903139
903304
|
const errorDetails = (StatusReasons === null || StatusReasons === void 0 ? void 0 : StatusReasons.map(item => `[${item.ErrorCode}] ${item.ErrorMessage}`).join('\n')) || '';
|
|
903140
903305
|
const errorMsg = `云函数创建失败${StatusDesc ? `\n状态描述: ${StatusDesc}` : ''}${errorDetails ? `\n失败信息: ${errorDetails}` : ''}`;
|
|
903141
|
-
|
|
903306
|
+
// 注意:这里不传递 RequestId,因为这是 GetFunction 的 RequestId,不是导致失败的 CreateFunction/UpdateFunctionCode 的 RequestId
|
|
903307
|
+
throw new error_1.CloudBaseError(errorMsg);
|
|
903142
903308
|
}
|
|
903143
903309
|
// 函数状态正常
|
|
903144
903310
|
clearInterval(ticker);
|
|
@@ -903318,7 +903484,12 @@ class FunctionService {
|
|
|
903318
903484
|
// 清理临时文件
|
|
903319
903485
|
await packer.clean();
|
|
903320
903486
|
if (err) {
|
|
903321
|
-
|
|
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
|
+
}));
|
|
903322
903493
|
}
|
|
903323
903494
|
else {
|
|
903324
903495
|
resolve(data);
|
|
@@ -903371,7 +903542,16 @@ class FunctionService {
|
|
|
903371
903542
|
headers
|
|
903372
903543
|
});
|
|
903373
903544
|
if (!response.ok) {
|
|
903374
|
-
|
|
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}`);
|
|
903375
903555
|
}
|
|
903376
903556
|
// 清理临时文件
|
|
903377
903557
|
await packer.clean();
|