@cloudbase/manager-node 5.8.5 → 5.8.7-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/lib/deploy/StaticDeployer.js +12 -18
- package/lib/deploy/framework.js +34 -0
- package/lib/env/index.js +19 -0
- package/lib/function/index.js +43 -53
- package/lib/index.js +12 -0
- package/package.json +1 -1
- package/types/deploy/StaticDeployer.d.ts +7 -3
- package/types/deploy/framework.d.ts +13 -0
- package/types/env/index.d.ts +16 -1
- package/types/env/type.d.ts +56 -0
- package/types/function/index.d.ts +0 -3
- package/types/function/types.d.ts +1 -0
- package/types/index.d.ts +8 -0
- package/types/interfaces/tcb.interface.d.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
## @cloudbase/manager-node v5.8.6 版本发布 🚀(2026-09-09)
|
|
2
|
+
|
|
3
|
+
- 新增 hosting 本地构建拆分 npm install 并导出构建能力供 CLI 复用
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## @cloudbase/manager-node v5.8.5 版本发布 🚀(2026-09-07)
|
|
8
|
+
|
|
9
|
+
- 新增 deploy 支持自定义 OpenAccessTypes 访问类型(默认值兜底,兼容存量调用)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
1
13
|
## @cloudbase/manager-node v5.8.4 版本发布 🚀(2026-09-02)
|
|
2
14
|
|
|
3
15
|
- 新增 move declarative image config preparation to manager
|
|
@@ -52,7 +52,8 @@ class StaticDeployer {
|
|
|
52
52
|
/**
|
|
53
53
|
* hosting 部署(固定静态流程,不写版本记录)
|
|
54
54
|
*
|
|
55
|
-
*
|
|
55
|
+
* 支持本地构建:buildCommand 非空时自动执行 build 后上传产物(依赖由用户自行安装,
|
|
56
|
+
* 不代为执行 npm install);
|
|
56
57
|
* 纯静态(buildCommand 空/未配置且无法检测框架)时直接上传 outputDir(默认 root,保持现状)。
|
|
57
58
|
* 访问地址 = https://{CdnDomain}{deployPath}(与 tcb hosting deploy 一致)
|
|
58
59
|
*/
|
|
@@ -63,7 +64,7 @@ class StaticDeployer {
|
|
|
63
64
|
const cloudPath = config.deployPath || '/';
|
|
64
65
|
// 1. 解析构建命令:显式 buildCommand > framework 映射 > package.json 自动探测 > null(纯静态)
|
|
65
66
|
const buildCommand = (0, framework_1.resolveBuildCommand)(config, root);
|
|
66
|
-
// 2. 有构建命令 →
|
|
67
|
+
// 2. 有构建命令 → 本地构建(仅 build,依赖由用户自行安装);纯静态 → 跳过构建直接上传
|
|
67
68
|
if (buildCommand) {
|
|
68
69
|
this.runLocalBuild(root, Object.assign(Object.assign({}, config), { buildCommand }), config.envVariables);
|
|
69
70
|
}
|
|
@@ -188,34 +189,27 @@ class StaticDeployer {
|
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
/**
|
|
191
|
-
*
|
|
192
|
+
* 本地构建(仅执行 buildCommand,不安装依赖)
|
|
193
|
+
*
|
|
194
|
+
* 只跑用户的构建命令,依赖由用户自行安装(对齐业界:Vercel/Netlify/Cloudflare
|
|
195
|
+
* 均不在本地构建时代装依赖)。installCommand 不再被本地执行 —— CLI 侧通过
|
|
196
|
+
* installCommand: '' 已可跳过云端安装;本地一律不装。
|
|
192
197
|
*
|
|
193
|
-
* - installCommand:默认 npm install,显式空字符串跳过安装
|
|
194
198
|
* - buildCommand:由调用方保证非空(hosting 经 resolveBuildCommand 判定;app local 由 if 判定)
|
|
195
199
|
* - envVariables:注入构建进程环境变量(值统一转字符串)
|
|
196
200
|
*/
|
|
197
201
|
runLocalBuild(projectPath, config, envVariables) {
|
|
198
|
-
var _a;
|
|
199
|
-
const installCommand = (_a = config.installCommand) !== null && _a !== void 0 ? _a : 'npm install';
|
|
200
202
|
const buildCommand = config.buildCommand || '';
|
|
201
203
|
const env = Object.assign(Object.assign({}, process.env), stringifyEnvValues(envVariables));
|
|
202
|
-
const commands = [];
|
|
203
|
-
if (installCommand) {
|
|
204
|
-
commands.push({ cmd: installCommand, label: '安装依赖' });
|
|
205
|
-
}
|
|
206
|
-
if (buildCommand) {
|
|
207
|
-
commands.push({ cmd: buildCommand, label: '构建' });
|
|
208
|
-
}
|
|
209
204
|
try {
|
|
210
|
-
|
|
211
|
-
(0, child_process_1.execSync)(
|
|
205
|
+
if (buildCommand) {
|
|
206
|
+
(0, child_process_1.execSync)(buildCommand, { cwd: projectPath, stdio: 'inherit', env });
|
|
212
207
|
}
|
|
213
208
|
}
|
|
214
209
|
catch (e) {
|
|
215
210
|
const detail = ((e === null || e === void 0 ? void 0 : e.stderr) || (e === null || e === void 0 ? void 0 : e.stdout) || (e === null || e === void 0 ? void 0 : e.message) || String(e)).toString().trim();
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
`请先在项目目录手动执行该命令排查原因(常见原因:npm registry 网络不可达、依赖安装权限、lockfile 不一致)。\n` +
|
|
211
|
+
throw new error_1.CloudBaseError(`本地构建失败:在 ${projectPath} 执行「${buildCommand}」失败。\n` +
|
|
212
|
+
`请先在项目目录手动执行该命令排查原因(常见原因:构建脚本报错、依赖未安装、lockfile 不一致)。\n` +
|
|
219
213
|
(detail ? `原始错误:${detail.slice(0, 500)}` : ''));
|
|
220
214
|
}
|
|
221
215
|
}
|
package/lib/deploy/framework.js
CHANGED
|
@@ -38,8 +38,10 @@ exports.detectFramework = detectFramework;
|
|
|
38
38
|
exports.resolveBuildCommand = resolveBuildCommand;
|
|
39
39
|
exports.resolveOutputDir = resolveOutputDir;
|
|
40
40
|
exports.resolveHostingOutputDir = resolveHostingOutputDir;
|
|
41
|
+
exports.buildHostingItem = buildHostingItem;
|
|
41
42
|
const fs = __importStar(require("fs"));
|
|
42
43
|
const path = __importStar(require("path"));
|
|
44
|
+
const child_process_1 = require("child_process");
|
|
43
45
|
/**
|
|
44
46
|
* 框架 → 默认构建命令映射(hosting 本地构建 / app 云端构建复用)
|
|
45
47
|
*/
|
|
@@ -228,3 +230,35 @@ function resolveHostingOutputDir(config, root, readPkgFile = defaultReadPkgFile)
|
|
|
228
230
|
}
|
|
229
231
|
return config.outputDir ? path.resolve(root, config.outputDir) : root;
|
|
230
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* 本地构建单个 hosting 项(仅执行 buildCommand,不安装依赖,不上传)
|
|
235
|
+
*
|
|
236
|
+
* 从 StaticDeployer.runLocalBuild 提炼的纯函数版:不依赖 Environment,
|
|
237
|
+
* 供 CLI 的 tcb app build 与任何需要「只构建不上传」的调用方复用,
|
|
238
|
+
* 避免各端各自复制推断/执行逻辑。buildCommand 为空 → 直接返回 null。
|
|
239
|
+
*
|
|
240
|
+
* @param config hosting 项配置(framework/buildCommand/outputDir,root 单独传参)
|
|
241
|
+
* @param root 项目目录(绝对路径)
|
|
242
|
+
* @returns 构建产物目录(resolveHostingOutputDir 结果);无可构建命令返回 null
|
|
243
|
+
* @throws 构建失败时(含 stderr 摘要)
|
|
244
|
+
*/
|
|
245
|
+
function buildHostingItem(config, root, envVariables) {
|
|
246
|
+
const buildCommand = resolveBuildCommand(config, root);
|
|
247
|
+
if (!buildCommand) {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
const env = Object.assign({}, process.env);
|
|
251
|
+
if (envVariables) {
|
|
252
|
+
for (const [key, value] of Object.entries(envVariables)) {
|
|
253
|
+
env[key] = String(value);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
(0, child_process_1.execSync)(buildCommand, { cwd: root, stdio: 'inherit', env });
|
|
258
|
+
}
|
|
259
|
+
catch (e) {
|
|
260
|
+
const detail = ((e === null || e === void 0 ? void 0 : e.stderr) || (e === null || e === void 0 ? void 0 : e.stdout) || (e === null || e === void 0 ? void 0 : e.message) || String(e)).toString().trim();
|
|
261
|
+
throw new Error(`本地构建失败:在 ${root} 执行「${buildCommand}」失败。\n${detail.slice(0, 500)}`);
|
|
262
|
+
}
|
|
263
|
+
return resolveHostingOutputDir(config, root);
|
|
264
|
+
}
|
package/lib/env/index.js
CHANGED
|
@@ -828,6 +828,25 @@ class EnvService {
|
|
|
828
828
|
async deleteHttpServiceRoute(params) {
|
|
829
829
|
return this.cloudService.request('DeleteHTTPServiceRoute', Object.assign({}, params));
|
|
830
830
|
}
|
|
831
|
+
/**
|
|
832
|
+
* 清除HTTP访问服务域名缓存
|
|
833
|
+
* 支持 CDN 和 EO 两种缓存类型。CDN 仅支持 PURGE_URL 刷新方式;PURGE_PREFIX / PURGE_HOST 仅 EO 支持
|
|
834
|
+
* 清除缓存后会生成任务ID,可通过 DescribeHTTPServiceCachePurgeTask 查询任务进度和详细信息
|
|
835
|
+
* @param {PurgeHttpServiceCacheParams} params 清除缓存参数
|
|
836
|
+
* @returns {Promise<PurgeHttpServiceCacheRes>}
|
|
837
|
+
*/
|
|
838
|
+
async purgeHttpServiceCache(params) {
|
|
839
|
+
return this.cloudService.request('PurgeHTTPServiceCache', Object.assign({}, params));
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* 查询HTTP访问服务域名缓存清除任务详情
|
|
843
|
+
* 通过 purgeHttpServiceCache 清除域名缓存后,可传入任务ID查询清除任务状态、时间、缓存类型等信息;也可不传任务ID查询历史任务记录
|
|
844
|
+
* @param {DescribeHttpServiceCachePurgeTaskParams} params 查询参数
|
|
845
|
+
* @returns {Promise<DescribeHttpServiceCachePurgeTaskRes>}
|
|
846
|
+
*/
|
|
847
|
+
async describeHttpServiceCachePurgeTask(params) {
|
|
848
|
+
return this.cloudService.request('DescribeHTTPServiceCachePurgeTask', Object.assign({}, params));
|
|
849
|
+
}
|
|
831
850
|
/**
|
|
832
851
|
* 绑定自定义域名到HTTP访问服务
|
|
833
852
|
* 底层调用 CreateHTTPServiceRoute API,专用于域名绑定场景
|
package/lib/function/index.js
CHANGED
|
@@ -275,18 +275,6 @@ class FunctionService {
|
|
|
275
275
|
this.tcbService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
|
|
276
276
|
this.userService = environment.getUserService();
|
|
277
277
|
}
|
|
278
|
-
// 是否启用 TCB 函数接口(ENABLE_TCBF 为真时开启:true/1/yes/on,大小写不敏感)
|
|
279
|
-
get useTcbFunctionApi() {
|
|
280
|
-
return parseEnvBoolean(process.env.ENABLE_TCBF);
|
|
281
|
-
}
|
|
282
|
-
// 函数操作使用的 CloudService 实例:开关开启走 tcb,否则走 scf
|
|
283
|
-
get functionCloudService() {
|
|
284
|
-
return this.useTcbFunctionApi ? this.tcbService : this.scfService;
|
|
285
|
-
}
|
|
286
|
-
// namespace 参数名:tcb 用 EnvId,scf 用 Namespace
|
|
287
|
-
get namespaceParamKey() {
|
|
288
|
-
return this.useTcbFunctionApi ? 'EnvId' : 'Namespace';
|
|
289
|
-
}
|
|
290
278
|
/**
|
|
291
279
|
* 增量更新函数代码
|
|
292
280
|
* @param {IUpdateFunctionIncrementalCodeParam} funcParam
|
|
@@ -332,12 +320,12 @@ class FunctionService {
|
|
|
332
320
|
*/
|
|
333
321
|
async createFunction(funcParam) {
|
|
334
322
|
var _a, _b, _c;
|
|
335
|
-
const { namespace } = this.getFunctionConfig();
|
|
323
|
+
const { namespace, backend } = this.getFunctionConfig();
|
|
336
324
|
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode, code } = funcParam;
|
|
337
325
|
const funcName = func.name;
|
|
338
326
|
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
339
327
|
const baseParams = {
|
|
340
|
-
|
|
328
|
+
EnvId: namespace,
|
|
341
329
|
Stamp: 'MINI_QCBASE',
|
|
342
330
|
ClsTopicId: TopicId,
|
|
343
331
|
ClsLogsetId: LogsetId
|
|
@@ -351,11 +339,9 @@ class FunctionService {
|
|
|
351
339
|
codeSecret,
|
|
352
340
|
baseParams
|
|
353
341
|
});
|
|
354
|
-
//
|
|
355
|
-
if (
|
|
356
|
-
|
|
357
|
-
params.Runtime = 'Nodejs24.14';
|
|
358
|
-
}
|
|
342
|
+
// 统一走 tcb;默认 runtime 按环境函数后端类型设置
|
|
343
|
+
if (!func.runtime) {
|
|
344
|
+
params.Runtime = backend === 'tcb' ? 'Nodejs24.14' : 'Nodejs20.19';
|
|
359
345
|
}
|
|
360
346
|
const customCode = code;
|
|
361
347
|
const customImageCode = customCode === null || customCode === void 0 ? void 0 : customCode.ImageConfig;
|
|
@@ -395,7 +381,7 @@ class FunctionService {
|
|
|
395
381
|
}
|
|
396
382
|
try {
|
|
397
383
|
// 创建云函数
|
|
398
|
-
const res = await this.
|
|
384
|
+
const res = await this.tcbService.request('CreateFunction', params);
|
|
399
385
|
// 等待函数状态正常
|
|
400
386
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
401
387
|
// 创建函数触发器、失败自动重试
|
|
@@ -597,9 +583,9 @@ class FunctionService {
|
|
|
597
583
|
name: funcName
|
|
598
584
|
});
|
|
599
585
|
}
|
|
600
|
-
return await this.
|
|
586
|
+
return await this.tcbService.request('DeleteFunction', {
|
|
601
587
|
FunctionName: funcName,
|
|
602
|
-
|
|
588
|
+
EnvId: namespace
|
|
603
589
|
});
|
|
604
590
|
}
|
|
605
591
|
/**
|
|
@@ -630,12 +616,13 @@ class FunctionService {
|
|
|
630
616
|
const params = {
|
|
631
617
|
FunctionName: name,
|
|
632
618
|
ShowCode: 'TRUE',
|
|
633
|
-
|
|
619
|
+
EnvId: namespace,
|
|
620
|
+
Namespace: namespace
|
|
634
621
|
};
|
|
635
622
|
if (codeSecret) {
|
|
636
623
|
params.CodeSecret = codeSecret;
|
|
637
624
|
}
|
|
638
|
-
const data = await this.
|
|
625
|
+
const data = await this.tcbService.request('GetFunction', params);
|
|
639
626
|
// 解析 VPC 配置
|
|
640
627
|
const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
|
|
641
628
|
if (VpcId && SubnetId) {
|
|
@@ -774,7 +761,7 @@ class FunctionService {
|
|
|
774
761
|
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
775
762
|
// 构建参数
|
|
776
763
|
const params = {
|
|
777
|
-
|
|
764
|
+
EnvId: namespace,
|
|
778
765
|
FunctionName: func.name,
|
|
779
766
|
ClsTopicId: TopicId,
|
|
780
767
|
ClsLogsetId: LogsetId
|
|
@@ -787,10 +774,8 @@ class FunctionService {
|
|
|
787
774
|
continue;
|
|
788
775
|
params[pascalKey] = toPascalCaseKeys(func[key]);
|
|
789
776
|
}
|
|
790
|
-
//
|
|
791
|
-
|
|
792
|
-
// tcb 的 UpdateFunctionConfiguration 不认,故跳过
|
|
793
|
-
if (func.installDependency !== undefined && !this.useTcbFunctionApi) {
|
|
777
|
+
// 特殊处理:安装依赖标志(仅透传用户显式指定的值)
|
|
778
|
+
if (func.installDependency !== undefined) {
|
|
794
779
|
params.InstallDependency = toBooleanString(func.installDependency);
|
|
795
780
|
}
|
|
796
781
|
// 特殊处理:L5 配置(支持 boolean | string)
|
|
@@ -870,7 +855,7 @@ class FunctionService {
|
|
|
870
855
|
console.warn(`[${func.name}] 触发器更新失败:${triggerError.message}`);
|
|
871
856
|
}
|
|
872
857
|
}
|
|
873
|
-
return this.
|
|
858
|
+
return this.tcbService.request('UpdateFunctionConfiguration', params);
|
|
874
859
|
}
|
|
875
860
|
catch (e) {
|
|
876
861
|
throw new error_1.CloudBaseError(`[${func.name}] 更新函数配置失败:${e.message}`, {
|
|
@@ -893,7 +878,8 @@ class FunctionService {
|
|
|
893
878
|
if (deployMode === 'image') {
|
|
894
879
|
const params = {
|
|
895
880
|
FunctionName: funcName,
|
|
896
|
-
|
|
881
|
+
EnvId: namespace,
|
|
882
|
+
Namespace: namespace,
|
|
897
883
|
Code: {
|
|
898
884
|
ImageConfig: buildImageConfig(func.imageConfig)
|
|
899
885
|
}
|
|
@@ -904,7 +890,7 @@ class FunctionService {
|
|
|
904
890
|
try {
|
|
905
891
|
// 等待函数状态正常
|
|
906
892
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
907
|
-
return await this.
|
|
893
|
+
return await this.tcbService.request('UpdateFunctionCode', params);
|
|
908
894
|
}
|
|
909
895
|
catch (e) {
|
|
910
896
|
throw new error_1.CloudBaseError(`[${funcName}] 函数代码更新失败:${formatImageDeploymentErrorMessage(e, func.imageConfig)}`, {
|
|
@@ -921,6 +907,11 @@ class FunctionService {
|
|
|
921
907
|
let installDependency;
|
|
922
908
|
// Node 函数默认安装依赖
|
|
923
909
|
installDependency = isNodeFunction(func.runtime) ? 'TRUE' : 'FALSE';
|
|
910
|
+
// Nodejs22 及以上默认不支持云端自动安装依赖,默认 FALSE(installDependency 可覆盖)
|
|
911
|
+
const nodejsVer = /^Nodejs(\d+)/i.exec(func.runtime || '');
|
|
912
|
+
if (nodejsVer && Number(nodejsVer[1]) >= 22) {
|
|
913
|
+
installDependency = 'FALSE';
|
|
914
|
+
}
|
|
924
915
|
// 是否安装依赖,选项可以覆盖(支持 boolean | string)
|
|
925
916
|
if (func.installDependency !== undefined) {
|
|
926
917
|
installDependency = toBooleanString(func.installDependency);
|
|
@@ -935,7 +926,8 @@ class FunctionService {
|
|
|
935
926
|
}, installDependency));
|
|
936
927
|
const params = {
|
|
937
928
|
FunctionName: funcName,
|
|
938
|
-
|
|
929
|
+
EnvId: namespace,
|
|
930
|
+
Namespace: namespace,
|
|
939
931
|
Handler: func.handler || 'index.main',
|
|
940
932
|
InstallDependency: installDependency,
|
|
941
933
|
Code: codeParams
|
|
@@ -947,7 +939,7 @@ class FunctionService {
|
|
|
947
939
|
// 等待函数状态正常
|
|
948
940
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
949
941
|
// 更新云函数代码
|
|
950
|
-
const res = await this.
|
|
942
|
+
const res = await this.tcbService.request('UpdateFunctionCode', params);
|
|
951
943
|
if (installDependency && func.isWaitInstall === true) {
|
|
952
944
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
953
945
|
}
|
|
@@ -1154,9 +1146,8 @@ class FunctionService {
|
|
|
1154
1146
|
const { functions, envId } = options;
|
|
1155
1147
|
const promises = functions.map(func => (async () => {
|
|
1156
1148
|
try {
|
|
1157
|
-
func.triggers.
|
|
1158
|
-
|
|
1159
|
-
});
|
|
1149
|
+
await Promise.all(func.triggers.map(trigger => this.deleteFunctionTrigger(func.name, trigger.name)));
|
|
1150
|
+
(0, utils_1.successLog)(`[${func.name}] 删除云函数触发器成功!`);
|
|
1160
1151
|
}
|
|
1161
1152
|
catch (e) {
|
|
1162
1153
|
throw new error_1.CloudBaseError(e.message);
|
|
@@ -1173,11 +1164,10 @@ class FunctionService {
|
|
|
1173
1164
|
const { destPath, envId, functionName, codeSecret, qualifier } = options;
|
|
1174
1165
|
// 检验路径是否存在
|
|
1175
1166
|
(0, utils_1.checkFullAccess)(destPath, true);
|
|
1176
|
-
// 获取下载链接:ENABLE_TCBF 开启走 tcb 的 DownloadFunction,否则走 scf 的 GetFunctionAddress
|
|
1177
|
-
const action = this.useTcbFunctionApi ? 'DownloadFunction' : 'GetFunctionAddress';
|
|
1178
1167
|
const params = {
|
|
1179
1168
|
FunctionName: functionName,
|
|
1180
|
-
|
|
1169
|
+
EnvId: envId,
|
|
1170
|
+
Qualifier: '$LATEST'
|
|
1181
1171
|
};
|
|
1182
1172
|
// 指定版本时透传 Qualifier;默认 $LATEST 与现状一致
|
|
1183
1173
|
if (qualifier) {
|
|
@@ -1186,7 +1176,7 @@ class FunctionService {
|
|
|
1186
1176
|
if (codeSecret) {
|
|
1187
1177
|
params.CodeSecret = codeSecret;
|
|
1188
1178
|
}
|
|
1189
|
-
const { Url } = await this.
|
|
1179
|
+
const { Url } = await this.tcbService.request('DownloadFunction', params);
|
|
1190
1180
|
// 下载文件
|
|
1191
1181
|
return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
|
|
1192
1182
|
}
|
|
@@ -1201,15 +1191,14 @@ class FunctionService {
|
|
|
1201
1191
|
const { namespace } = this.getFunctionConfig();
|
|
1202
1192
|
const params = {
|
|
1203
1193
|
FunctionName: functionName,
|
|
1204
|
-
|
|
1194
|
+
EnvId: namespace,
|
|
1195
|
+
Qualifier: '$LATEST'
|
|
1205
1196
|
};
|
|
1206
1197
|
if (codeSecret) {
|
|
1207
1198
|
params.CodeSecret = codeSecret;
|
|
1208
1199
|
}
|
|
1209
1200
|
try {
|
|
1210
|
-
|
|
1211
|
-
const action = this.useTcbFunctionApi ? 'DownloadFunction' : 'GetFunctionAddress';
|
|
1212
|
-
const { Url, CodeSha256, RequestId } = await this.functionCloudService.request(action, params);
|
|
1201
|
+
const { Url, CodeSha256, RequestId } = await this.tcbService.request('DownloadFunction', params);
|
|
1213
1202
|
return { Url, RequestId, CodeSha256 };
|
|
1214
1203
|
}
|
|
1215
1204
|
catch (e) {
|
|
@@ -1228,9 +1217,9 @@ class FunctionService {
|
|
|
1228
1217
|
LayerName: layerName,
|
|
1229
1218
|
LayerVersion: layerVersion
|
|
1230
1219
|
});
|
|
1231
|
-
const res = await this.
|
|
1220
|
+
const res = await this.tcbService.request('UpdateFunctionConfiguration', {
|
|
1232
1221
|
Layers,
|
|
1233
|
-
|
|
1222
|
+
EnvId: envId,
|
|
1234
1223
|
FunctionName: functionName
|
|
1235
1224
|
});
|
|
1236
1225
|
return res;
|
|
@@ -1247,7 +1236,7 @@ class FunctionService {
|
|
|
1247
1236
|
// 删除指定的层
|
|
1248
1237
|
Layers.splice(index, 1);
|
|
1249
1238
|
const apiParams = {
|
|
1250
|
-
|
|
1239
|
+
EnvId: envId,
|
|
1251
1240
|
FunctionName: functionName,
|
|
1252
1241
|
Layers: Layers.length > 0
|
|
1253
1242
|
? Layers
|
|
@@ -1258,14 +1247,14 @@ class FunctionService {
|
|
|
1258
1247
|
}
|
|
1259
1248
|
]
|
|
1260
1249
|
};
|
|
1261
|
-
return this.
|
|
1250
|
+
return this.tcbService.request('UpdateFunctionConfiguration', apiParams);
|
|
1262
1251
|
}
|
|
1263
1252
|
// 更新云函数层
|
|
1264
1253
|
async updateFunctionLayer(options) {
|
|
1265
1254
|
const { envId, functionName, layers } = options;
|
|
1266
|
-
return this.
|
|
1255
|
+
return this.tcbService.request('UpdateFunctionConfiguration', {
|
|
1267
1256
|
Layers: layers,
|
|
1268
|
-
|
|
1257
|
+
EnvId: envId,
|
|
1269
1258
|
FunctionName: functionName
|
|
1270
1259
|
});
|
|
1271
1260
|
}
|
|
@@ -1770,7 +1759,7 @@ class FunctionService {
|
|
|
1770
1759
|
* @memberof FunctionService
|
|
1771
1760
|
*/
|
|
1772
1761
|
getFunctionConfig() {
|
|
1773
|
-
var _a, _b, _c, _d, _e, _f;
|
|
1762
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
1774
1763
|
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
1775
1764
|
// Functions 可能为空
|
|
1776
1765
|
const namespace = ((_b = (_a = envConfig.Functions) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.Namespace) || '';
|
|
@@ -1787,7 +1776,8 @@ class FunctionService {
|
|
|
1787
1776
|
proxy,
|
|
1788
1777
|
appId,
|
|
1789
1778
|
namespace,
|
|
1790
|
-
env: envConfig.EnvId
|
|
1779
|
+
env: envConfig.EnvId,
|
|
1780
|
+
backend: ((_h = (_g = envConfig.Functions) === null || _g === void 0 ? void 0 : _g[0]) === null || _h === void 0 ? void 0 : _h.Backend) || 'scf'
|
|
1791
1781
|
};
|
|
1792
1782
|
}
|
|
1793
1783
|
/**
|
package/lib/index.js
CHANGED
|
@@ -4,6 +4,7 @@ const environmentManager_1 = require("./environmentManager");
|
|
|
4
4
|
const docs_1 = require("./docs");
|
|
5
5
|
const projectValidator_1 = require("./projectValidator");
|
|
6
6
|
const DeployOrchestrator_1 = require("./deploy/DeployOrchestrator");
|
|
7
|
+
const framework_1 = require("./deploy/framework");
|
|
7
8
|
class CloudBase {
|
|
8
9
|
/**
|
|
9
10
|
* init 初始化 为单例
|
|
@@ -188,4 +189,15 @@ class CloudBase {
|
|
|
188
189
|
return this.context.isInternalEndpoint();
|
|
189
190
|
}
|
|
190
191
|
}
|
|
192
|
+
// export = 模块只能通过 namespace 合并附加类型(TS 惯用法,规则见下)
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
194
|
+
(function (CloudBase) {
|
|
195
|
+
/**
|
|
196
|
+
* 声明式 hosting 构建推断与执行(CLI 侧 tcb app build / hosting 中立化复用,
|
|
197
|
+
* 避免各端复制同一套 framework 推断逻辑)。均为纯函数,不依赖环境上下文。
|
|
198
|
+
*/
|
|
199
|
+
CloudBase.resolveHostingBuildCommand = framework_1.resolveBuildCommand;
|
|
200
|
+
CloudBase.resolveHostingOutputDir = framework_1.resolveHostingOutputDir;
|
|
201
|
+
CloudBase.buildHosting = framework_1.buildHostingItem;
|
|
202
|
+
})(CloudBase || (CloudBase = {}));
|
|
191
203
|
module.exports = CloudBase;
|
package/package.json
CHANGED
|
@@ -69,7 +69,8 @@ export declare class StaticDeployer {
|
|
|
69
69
|
/**
|
|
70
70
|
* hosting 部署(固定静态流程,不写版本记录)
|
|
71
71
|
*
|
|
72
|
-
*
|
|
72
|
+
* 支持本地构建:buildCommand 非空时自动执行 build 后上传产物(依赖由用户自行安装,
|
|
73
|
+
* 不代为执行 npm install);
|
|
73
74
|
* 纯静态(buildCommand 空/未配置且无法检测框架)时直接上传 outputDir(默认 root,保持现状)。
|
|
74
75
|
* 访问地址 = https://{CdnDomain}{deployPath}(与 tcb hosting deploy 一致)
|
|
75
76
|
*/
|
|
@@ -94,9 +95,12 @@ export declare class StaticDeployer {
|
|
|
94
95
|
*/
|
|
95
96
|
private resolveHostingUrl;
|
|
96
97
|
/**
|
|
97
|
-
*
|
|
98
|
+
* 本地构建(仅执行 buildCommand,不安装依赖)
|
|
99
|
+
*
|
|
100
|
+
* 只跑用户的构建命令,依赖由用户自行安装(对齐业界:Vercel/Netlify/Cloudflare
|
|
101
|
+
* 均不在本地构建时代装依赖)。installCommand 不再被本地执行 —— CLI 侧通过
|
|
102
|
+
* installCommand: '' 已可跳过云端安装;本地一律不装。
|
|
98
103
|
*
|
|
99
|
-
* - installCommand:默认 npm install,显式空字符串跳过安装
|
|
100
104
|
* - buildCommand:由调用方保证非空(hosting 经 resolveBuildCommand 判定;app local 由 if 判定)
|
|
101
105
|
* - envVariables:注入构建进程环境变量(值统一转字符串)
|
|
102
106
|
*/
|
|
@@ -61,3 +61,16 @@ export declare function resolveOutputDir(config: IHostingOutputConfig, root: str
|
|
|
61
61
|
* - outputDir 未配置回退 root(纯静态直传)
|
|
62
62
|
*/
|
|
63
63
|
export declare function resolveHostingOutputDir(config: IHostingOutputConfig, root: string, readPkgFile?: ReadPkgFile): string;
|
|
64
|
+
/**
|
|
65
|
+
* 本地构建单个 hosting 项(仅执行 buildCommand,不安装依赖,不上传)
|
|
66
|
+
*
|
|
67
|
+
* 从 StaticDeployer.runLocalBuild 提炼的纯函数版:不依赖 Environment,
|
|
68
|
+
* 供 CLI 的 tcb app build 与任何需要「只构建不上传」的调用方复用,
|
|
69
|
+
* 避免各端各自复制推断/执行逻辑。buildCommand 为空 → 直接返回 null。
|
|
70
|
+
*
|
|
71
|
+
* @param config hosting 项配置(framework/buildCommand/outputDir,root 单独传参)
|
|
72
|
+
* @param root 项目目录(绝对路径)
|
|
73
|
+
* @returns 构建产物目录(resolveHostingOutputDir 结果);无可构建命令返回 null
|
|
74
|
+
* @throws 构建失败时(含 stderr 摘要)
|
|
75
|
+
*/
|
|
76
|
+
export declare function buildHostingItem(config: IHostingOutputConfig, root: string, envVariables?: Record<string, string | number | boolean>): string | null;
|
package/types/env/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Environment } from '../environment';
|
|
2
2
|
import { IResponseInfo, AuthDomain, EnvInfo, LoginConfigItem, ICheckTcbServiceRes, ICreatePostpayRes, EnvBillingInfoItem, PriceResult } from '../interfaces';
|
|
3
|
-
import { CalculatePackageCreatePriceParams, CalculatePackageRenewPriceParams, CalculatePackageModifyPriceParams, DescribeHttpServiceRouteParams, DescribeHttpServiceRouteRes, VerifyHttpServiceRouteParams, VerifyHttpServiceRouteRes, CreateHttpServiceRouteParams, CreateHttpServiceRouteRes, ModifyHttpServiceRouteParams, ModifyHttpServiceRouteRes, DeleteHttpServiceRouteParams, DeleteHttpServiceRouteRes, BindCustomDomainParams, BindCustomDomainRes, DeleteCustomDomainParams, DeleteCustomDomainRes, DescribeCertificatesParams, DescribeCertificatesRes } from './type';
|
|
3
|
+
import { CalculatePackageCreatePriceParams, CalculatePackageRenewPriceParams, CalculatePackageModifyPriceParams, DescribeHttpServiceRouteParams, DescribeHttpServiceRouteRes, VerifyHttpServiceRouteParams, VerifyHttpServiceRouteRes, CreateHttpServiceRouteParams, CreateHttpServiceRouteRes, ModifyHttpServiceRouteParams, ModifyHttpServiceRouteRes, DeleteHttpServiceRouteParams, DeleteHttpServiceRouteRes, PurgeHttpServiceCacheParams, PurgeHttpServiceCacheRes, DescribeHttpServiceCachePurgeTaskParams, DescribeHttpServiceCachePurgeTaskRes, BindCustomDomainParams, BindCustomDomainRes, DeleteCustomDomainParams, DeleteCustomDomainRes, DescribeCertificatesParams, DescribeCertificatesRes } from './type';
|
|
4
4
|
import { CreateBillingDealParams, CreateEnvParams, BaasPackageInfo, DescribeBaasPackageListParams, ModifyEnvPlanParams, RenewEnvParams, DestroyEnvParams, DescribeEnvsParams, DescribeEnvInfoParams, DescribeEnvInfoResponse, DescribeEnvAccountCircleParams, DescribeEnvAccountCircleRes, DescribeCreditsUsageDetailParams, EnvPkgCreditsUsage } from '../interfaces/tcb.interface';
|
|
5
5
|
type SOURCE = 'miniapp' | 'qcloud';
|
|
6
6
|
interface IDeleteDomainRes {
|
|
@@ -922,6 +922,21 @@ export declare class EnvService {
|
|
|
922
922
|
* @returns {Promise<DeleteHttpServiceRouteRes>}
|
|
923
923
|
*/
|
|
924
924
|
deleteHttpServiceRoute(params: DeleteHttpServiceRouteParams): Promise<DeleteHttpServiceRouteRes>;
|
|
925
|
+
/**
|
|
926
|
+
* 清除HTTP访问服务域名缓存
|
|
927
|
+
* 支持 CDN 和 EO 两种缓存类型。CDN 仅支持 PURGE_URL 刷新方式;PURGE_PREFIX / PURGE_HOST 仅 EO 支持
|
|
928
|
+
* 清除缓存后会生成任务ID,可通过 DescribeHTTPServiceCachePurgeTask 查询任务进度和详细信息
|
|
929
|
+
* @param {PurgeHttpServiceCacheParams} params 清除缓存参数
|
|
930
|
+
* @returns {Promise<PurgeHttpServiceCacheRes>}
|
|
931
|
+
*/
|
|
932
|
+
purgeHttpServiceCache(params: PurgeHttpServiceCacheParams): Promise<PurgeHttpServiceCacheRes>;
|
|
933
|
+
/**
|
|
934
|
+
* 查询HTTP访问服务域名缓存清除任务详情
|
|
935
|
+
* 通过 purgeHttpServiceCache 清除域名缓存后,可传入任务ID查询清除任务状态、时间、缓存类型等信息;也可不传任务ID查询历史任务记录
|
|
936
|
+
* @param {DescribeHttpServiceCachePurgeTaskParams} params 查询参数
|
|
937
|
+
* @returns {Promise<DescribeHttpServiceCachePurgeTaskRes>}
|
|
938
|
+
*/
|
|
939
|
+
describeHttpServiceCachePurgeTask(params: DescribeHttpServiceCachePurgeTaskParams): Promise<DescribeHttpServiceCachePurgeTaskRes>;
|
|
925
940
|
/**
|
|
926
941
|
* 绑定自定义域名到HTTP访问服务
|
|
927
942
|
* 底层调用 CreateHTTPServiceRoute API,专用于域名绑定场景
|
package/types/env/type.d.ts
CHANGED
|
@@ -414,6 +414,62 @@ export interface DeleteHttpServiceRouteParams {
|
|
|
414
414
|
export interface DeleteHttpServiceRouteRes {
|
|
415
415
|
RequestId: string;
|
|
416
416
|
}
|
|
417
|
+
/**
|
|
418
|
+
* PurgeHTTPServiceCache 请求参数
|
|
419
|
+
* 用于清除HTTP访问服务域名缓存,支持 CDN 和 EO 两种缓存类型
|
|
420
|
+
*/
|
|
421
|
+
export interface PurgeHttpServiceCacheParams {
|
|
422
|
+
EnvId: string;
|
|
423
|
+
Domain: string;
|
|
424
|
+
CacheType: 'CDN' | 'EO';
|
|
425
|
+
PurgeType: 'PURGE_URL' | 'PURGE_PREFIX' | 'PURGE_HOST';
|
|
426
|
+
Targets: string[];
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* PurgeHTTPServiceCache 返回结果
|
|
430
|
+
*/
|
|
431
|
+
export interface PurgeHttpServiceCacheRes {
|
|
432
|
+
CacheType: 'CDN' | 'EO';
|
|
433
|
+
TaskId: string;
|
|
434
|
+
RequestId: string;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* 缓存清除任务详情
|
|
438
|
+
*/
|
|
439
|
+
export interface HTTPServiceCachePurgeTask {
|
|
440
|
+
TaskId: string;
|
|
441
|
+
CacheType: 'CDN' | 'EO';
|
|
442
|
+
Status: 'PROCESSING' | 'SUCCESS' | 'FAILED' | 'TIMEOUT' | 'CANCELED';
|
|
443
|
+
PurgeType: 'PURGE_URL' | 'PURGE_PREFIX' | 'PURGE_HOST';
|
|
444
|
+
Method: 'INVALIDATE' | 'DELETE';
|
|
445
|
+
Targets: string[];
|
|
446
|
+
FailReason?: string;
|
|
447
|
+
CreateTime: string;
|
|
448
|
+
UpdateTime: string;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* DescribeHTTPServiceCachePurgeTask 请求参数
|
|
452
|
+
* 用于查询HTTPService域名缓存清除任务详情
|
|
453
|
+
*/
|
|
454
|
+
export interface DescribeHttpServiceCachePurgeTaskParams {
|
|
455
|
+
EnvId: string;
|
|
456
|
+
Domain: string;
|
|
457
|
+
CacheType: 'CDN' | 'EO';
|
|
458
|
+
TaskId?: string;
|
|
459
|
+
PurgeType?: 'PURGE_URL' | 'PURGE_PREFIX' | 'PURGE_HOST';
|
|
460
|
+
StartTime?: string;
|
|
461
|
+
EndTime?: string;
|
|
462
|
+
Offset?: number;
|
|
463
|
+
Limit?: number;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* DescribeHTTPServiceCachePurgeTask 返回结果
|
|
467
|
+
*/
|
|
468
|
+
export interface DescribeHttpServiceCachePurgeTaskRes {
|
|
469
|
+
Tasks: HTTPServiceCachePurgeTask[];
|
|
470
|
+
TotalCount: number;
|
|
471
|
+
RequestId: string;
|
|
472
|
+
}
|
|
417
473
|
/**
|
|
418
474
|
* 绑定自定义域名的域名参数
|
|
419
475
|
* 与 HTTPServiceDomainParam 类似,但不包含 Routes(绑定域名场景)
|
|
@@ -235,9 +235,6 @@ export declare class FunctionService {
|
|
|
235
235
|
private tcbService;
|
|
236
236
|
private userService;
|
|
237
237
|
constructor(environment: Environment);
|
|
238
|
-
private get useTcbFunctionApi();
|
|
239
|
-
private get functionCloudService();
|
|
240
|
-
private get namespaceParamKey();
|
|
241
238
|
/**
|
|
242
239
|
* 增量更新函数代码
|
|
243
240
|
* @param {IUpdateFunctionIncrementalCodeParam} funcParam
|
package/types/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ import { IntegrationService } from './integration';
|
|
|
25
25
|
import { MonitorService } from './monitor';
|
|
26
26
|
import { ProjectValidator } from './projectValidator';
|
|
27
27
|
import { DeployOrchestrator } from './deploy/DeployOrchestrator';
|
|
28
|
+
import { resolveBuildCommand as frameworkResolveBuildCommand, resolveHostingOutputDir as frameworkResolveHostingOutputDir, buildHostingItem as frameworkBuildHostingItem } from './deploy/framework';
|
|
28
29
|
interface CloudBaseConfig {
|
|
29
30
|
secretId?: string;
|
|
30
31
|
secretKey?: string;
|
|
@@ -127,5 +128,12 @@ declare class CloudBase {
|
|
|
127
128
|
}
|
|
128
129
|
declare namespace CloudBase {
|
|
129
130
|
type RequestFn = CloudApiRequestFn;
|
|
131
|
+
/**
|
|
132
|
+
* 声明式 hosting 构建推断与执行(CLI 侧 tcb app build / hosting 中立化复用,
|
|
133
|
+
* 避免各端复制同一套 framework 推断逻辑)。均为纯函数,不依赖环境上下文。
|
|
134
|
+
*/
|
|
135
|
+
const resolveHostingBuildCommand: typeof frameworkResolveBuildCommand;
|
|
136
|
+
const resolveHostingOutputDir: typeof frameworkResolveHostingOutputDir;
|
|
137
|
+
const buildHosting: typeof frameworkBuildHostingItem;
|
|
130
138
|
}
|
|
131
139
|
export = CloudBase;
|