@cloudbase/manager-node 5.7.0-beta.3 → 5.7.1-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/jest.config.unit.js +14 -0
- package/lib/cloudApp/index.js +3 -12
- package/lib/env/index.js +9 -0
- package/lib/environment.js +0 -11
- package/lib/function/index.js +67 -26
- package/lib/hosting/index.js +1 -4
- package/lib/index.js +0 -31
- package/lib/storage/index.js +7 -6
- package/lib/utils/index.js +5 -62
- package/package.json +1 -2
- package/types/cloudApp/index.d.ts +0 -4
- package/types/cloudApp/types.d.ts +6 -87
- package/types/env/index.d.ts +8 -1
- package/types/env/type.d.ts +97 -6
- package/types/environment.d.ts +0 -7
- package/types/function/index.d.ts +3 -0
- package/types/function/types.d.ts +0 -15
- package/types/hosting/index.d.ts +0 -6
- package/types/index.d.ts +0 -18
- package/types/interfaces/function.interface.d.ts +1 -1
- package/types/storage/index.d.ts +0 -6
- package/types/utils/index.d.ts +0 -13
- package/lib/deploy/DatabaseDeployer.js +0 -238
- package/lib/deploy/DeployOrchestrator.js +0 -632
- package/lib/deploy/FunctionDeployer.js +0 -611
- package/lib/deploy/GatewayDeployer.js +0 -612
- package/lib/deploy/StateStore.js +0 -327
- package/lib/deploy/StaticDeployer.js +0 -239
- package/lib/deploy/domain.js +0 -41
- package/lib/deploy/framework.js +0 -105
- package/lib/deploy/function/artifact.js +0 -207
- package/lib/deploy/function/builders/cloud.js +0 -536
- package/lib/deploy/function/cam-preflight.js +0 -157
- package/lib/deploy/function/cloud-build-service.js +0 -170
- package/lib/deploy/function/config-guard.js +0 -592
- package/lib/deploy/function/docker-preflight.js +0 -87
- package/lib/deploy/function/image-preflight.js +0 -164
- package/lib/deploy/function/local-builder.js +0 -129
- package/lib/deploy/function/planner.js +0 -282
- package/lib/deploy/function/preflight.js +0 -264
- package/lib/deploy/types.js +0 -99
- package/lib/projectValidator/index.js +0 -440
- package/lib/projectValidator/types.js +0 -2
- package/types/deploy/DatabaseDeployer.d.ts +0 -70
- package/types/deploy/DeployOrchestrator.d.ts +0 -168
- package/types/deploy/FunctionDeployer.d.ts +0 -158
- package/types/deploy/GatewayDeployer.d.ts +0 -194
- package/types/deploy/StateStore.d.ts +0 -170
- package/types/deploy/StaticDeployer.d.ts +0 -97
- package/types/deploy/domain.d.ts +0 -17
- package/types/deploy/framework.d.ts +0 -23
- package/types/deploy/function/artifact.d.ts +0 -40
- package/types/deploy/function/builders/cloud.d.ts +0 -110
- package/types/deploy/function/cam-preflight.d.ts +0 -51
- package/types/deploy/function/cloud-build-service.d.ts +0 -10
- package/types/deploy/function/config-guard.d.ts +0 -41
- package/types/deploy/function/docker-preflight.d.ts +0 -17
- package/types/deploy/function/image-preflight.d.ts +0 -21
- package/types/deploy/function/local-builder.d.ts +0 -26
- package/types/deploy/function/planner.d.ts +0 -15
- package/types/deploy/function/preflight.d.ts +0 -9
- package/types/deploy/types.d.ts +0 -429
- package/types/projectValidator/index.d.ts +0 -38
- package/types/projectValidator/types.d.ts +0 -26
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// 仅供不依赖真实云凭证的单元测试使用:跳过 globalSetup
|
|
2
|
+
module.exports = {
|
|
3
|
+
roots: ['<rootDir>/test'],
|
|
4
|
+
globals: {
|
|
5
|
+
'ts-jest': {
|
|
6
|
+
tsConfig: 'tsconfig.test.json'
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
transform: {
|
|
10
|
+
'^.+\\.ts?$': 'ts-jest'
|
|
11
|
+
},
|
|
12
|
+
transformIgnorePatterns: ['node_modules'],
|
|
13
|
+
testEnvironment: 'node'
|
|
14
|
+
}
|
package/lib/cloudApp/index.js
CHANGED
|
@@ -123,14 +123,10 @@ class CloudAppService {
|
|
|
123
123
|
* 注意:此方法不依赖应用是否已创建,可在创建应用前调用
|
|
124
124
|
* 返回的 cosTimestamp 用于 createApp 时传入 staticConfig.cosTimestamp
|
|
125
125
|
*
|
|
126
|
-
* 内置默认忽略:.git 目录、.DS_Store(含任意层级);node_modules 仅在
|
|
127
|
-
* excludeNodeModules 为 true(默认)时排除——云端构建(需云端 install)场景应传
|
|
128
|
-
* excludeNodeModules: false 允许私有/离线依赖随源码包上传。
|
|
129
|
-
*
|
|
130
126
|
* @param params 上传参数
|
|
131
127
|
*/
|
|
132
128
|
async uploadCode(params) {
|
|
133
|
-
const { serviceName, localPath, ignore = [],
|
|
129
|
+
const { serviceName, localPath, ignore = [], onPhase } = params;
|
|
134
130
|
// 1. 验证本地路径
|
|
135
131
|
if (!fs_1.default.existsSync(localPath)) {
|
|
136
132
|
throw new error_1.CloudBaseError(`本地路径不存在: ${localPath}`);
|
|
@@ -139,14 +135,9 @@ class CloudAppService {
|
|
|
139
135
|
if (!stat.isDirectory()) {
|
|
140
136
|
throw new error_1.CloudBaseError(`localPath 必须是目录: ${localPath}`);
|
|
141
137
|
}
|
|
142
|
-
// 2. 打包本地文件为 ZIP
|
|
138
|
+
// 2. 打包本地文件为 ZIP
|
|
143
139
|
const tmpZipPath = path_1.default.join(os_1.default.tmpdir(), `cloudapp-${Date.now()}-${Math.random().toString(36).slice(2)}.zip`);
|
|
144
|
-
const defaultIgnore = [
|
|
145
|
-
...(excludeNodeModules ? ['node_modules/**'] : []),
|
|
146
|
-
'.git/**',
|
|
147
|
-
'.DS_Store',
|
|
148
|
-
'**/.DS_Store'
|
|
149
|
-
];
|
|
140
|
+
const defaultIgnore = ['node_modules/**', '.git/**', '.DS_Store', '**/.DS_Store'];
|
|
150
141
|
const packStart = Date.now();
|
|
151
142
|
await (0, utils_1.compressToZip)({
|
|
152
143
|
dirPath: localPath,
|
package/lib/env/index.js
CHANGED
|
@@ -777,6 +777,15 @@ class EnvService {
|
|
|
777
777
|
async describeHttpServiceRoute(params) {
|
|
778
778
|
return this.cloudService.request('DescribeHTTPServiceRoute', Object.assign({}, params));
|
|
779
779
|
}
|
|
780
|
+
/**
|
|
781
|
+
* 校验HTTP访问服务域名路由
|
|
782
|
+
* 此操作为只读预检,不会创建任何资源。
|
|
783
|
+
* @param {VerifyHttpServiceRouteParams} params 校验参数
|
|
784
|
+
* @returns {Promise<VerifyHttpServiceRouteRes>}
|
|
785
|
+
*/
|
|
786
|
+
async verifyHttpServiceRoute(params) {
|
|
787
|
+
return this.cloudService.request('VerifyHTTPServiceRoute', Object.assign({}, params));
|
|
788
|
+
}
|
|
780
789
|
/**
|
|
781
790
|
* 创建HTTP访问服务域名路由
|
|
782
791
|
* @param {CreateHttpServiceRouteParams} params 创建参数
|
package/lib/environment.js
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Environment = void 0;
|
|
4
4
|
const database_1 = require("./database");
|
|
5
5
|
const function_1 = require("./function");
|
|
6
|
-
const FunctionDeployer_1 = require("./deploy/FunctionDeployer");
|
|
7
6
|
const cloudrun_1 = require("./cloudrun");
|
|
8
7
|
const agent_1 = require("./agent");
|
|
9
8
|
const storage_1 = require("./storage");
|
|
@@ -84,16 +83,6 @@ class Environment {
|
|
|
84
83
|
getFunctionService() {
|
|
85
84
|
return this.functionService;
|
|
86
85
|
}
|
|
87
|
-
/**
|
|
88
|
-
* 获取函数部署编排器
|
|
89
|
-
* 采用懒初始化,避免模块循环引用导致的初始化顺序问题
|
|
90
|
-
*/
|
|
91
|
-
getFunctionDeployer() {
|
|
92
|
-
if (!this.functionDeployer) {
|
|
93
|
-
this.functionDeployer = new FunctionDeployer_1.FunctionDeployer(this);
|
|
94
|
-
}
|
|
95
|
-
return this.functionDeployer;
|
|
96
|
-
}
|
|
97
86
|
getCloudRunService() {
|
|
98
87
|
return this.cloudRunService;
|
|
99
88
|
}
|
package/lib/function/index.js
CHANGED
|
@@ -18,6 +18,17 @@ const packer_1 = require("./packer");
|
|
|
18
18
|
const error_1 = require("../error");
|
|
19
19
|
const utils_1 = require("../utils");
|
|
20
20
|
const constant_1 = require("../constant");
|
|
21
|
+
/**
|
|
22
|
+
* 解析环境变量为布尔值
|
|
23
|
+
* 视 'true'/'1'/'yes'/'on'(大小写不敏感)为 true,
|
|
24
|
+
* 其余(含 'false'/'0'/'no'/'off'/空串/undefined)为 false
|
|
25
|
+
* 避免 `!!process.env.X` 把 'FALSE'/'0' 等非空字符串误判为 true
|
|
26
|
+
*/
|
|
27
|
+
function parseEnvBoolean(value) {
|
|
28
|
+
if (!value)
|
|
29
|
+
return false;
|
|
30
|
+
return ['true', '1', 'yes', 'on'].includes(value.toLowerCase());
|
|
31
|
+
}
|
|
21
32
|
// 是否为 Node 函数
|
|
22
33
|
function isNodeFunction(runtime) {
|
|
23
34
|
// 不严格限制
|
|
@@ -244,6 +255,18 @@ class FunctionService {
|
|
|
244
255
|
this.tcbService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
|
|
245
256
|
this.userService = environment.getUserService();
|
|
246
257
|
}
|
|
258
|
+
// 是否启用 TCB 函数接口(ENABLE_TCBF 为真时开启:true/1/yes/on,大小写不敏感)
|
|
259
|
+
get useTcbFunctionApi() {
|
|
260
|
+
return parseEnvBoolean(process.env.ENABLE_TCBF);
|
|
261
|
+
}
|
|
262
|
+
// 函数操作使用的 CloudService 实例:开关开启走 tcb,否则走 scf
|
|
263
|
+
get functionCloudService() {
|
|
264
|
+
return this.useTcbFunctionApi ? this.tcbService : this.scfService;
|
|
265
|
+
}
|
|
266
|
+
// namespace 参数名:tcb 用 EnvId,scf 用 Namespace
|
|
267
|
+
get namespaceParamKey() {
|
|
268
|
+
return this.useTcbFunctionApi ? 'EnvId' : 'Namespace';
|
|
269
|
+
}
|
|
247
270
|
/**
|
|
248
271
|
* 增量更新函数代码
|
|
249
272
|
* @param {IUpdateFunctionIncrementalCodeParam} funcParam
|
|
@@ -293,17 +316,27 @@ class FunctionService {
|
|
|
293
316
|
const { func, functionRootPath, force = false, base64Code, codeSecret, functionPath, deployMode, code } = funcParam;
|
|
294
317
|
const funcName = func.name;
|
|
295
318
|
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
319
|
+
const baseParams = {
|
|
320
|
+
[this.namespaceParamKey]: namespace,
|
|
321
|
+
Stamp: 'MINI_QCBASE',
|
|
322
|
+
ClsTopicId: TopicId,
|
|
323
|
+
ClsLogsetId: LogsetId
|
|
324
|
+
};
|
|
325
|
+
// 默认注入 TCB_QcsRole,DISABLE_DEFAULT_TCB_ROLE 为真时跳过(由 func.role 决定或留空)
|
|
326
|
+
if (!parseEnvBoolean(process.env.DISABLE_DEFAULT_TCB_ROLE)) {
|
|
327
|
+
baseParams.Role = 'TCB_QcsRole';
|
|
328
|
+
}
|
|
296
329
|
const params = configToParams({
|
|
297
330
|
func,
|
|
298
331
|
codeSecret,
|
|
299
|
-
baseParams
|
|
300
|
-
Namespace: namespace,
|
|
301
|
-
Role: 'TCB_QcsRole',
|
|
302
|
-
Stamp: 'MINI_QCBASE',
|
|
303
|
-
ClsTopicId: TopicId,
|
|
304
|
-
ClsLogsetId: LogsetId
|
|
305
|
-
}
|
|
332
|
+
baseParams
|
|
306
333
|
});
|
|
334
|
+
// ENABLE_TCBF 开启时,runtime 适配 tcb 风格
|
|
335
|
+
if (this.useTcbFunctionApi) {
|
|
336
|
+
if (!func.runtime) {
|
|
337
|
+
params.Runtime = 'Nodejs24.14';
|
|
338
|
+
}
|
|
339
|
+
}
|
|
307
340
|
const customCode = code;
|
|
308
341
|
const customImageCode = customCode === null || customCode === void 0 ? void 0 : customCode.ImageConfig;
|
|
309
342
|
const funcImageCode = (_a = params.Code) === null || _a === void 0 ? void 0 : _a.ImageConfig;
|
|
@@ -340,7 +373,7 @@ class FunctionService {
|
|
|
340
373
|
}
|
|
341
374
|
try {
|
|
342
375
|
// 创建云函数
|
|
343
|
-
const res = await this.
|
|
376
|
+
const res = await this.functionCloudService.request('CreateFunction', params);
|
|
344
377
|
// 等待函数状态正常
|
|
345
378
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
346
379
|
// 创建函数触发器、失败自动重试
|
|
@@ -536,9 +569,9 @@ class FunctionService {
|
|
|
536
569
|
name: funcName
|
|
537
570
|
});
|
|
538
571
|
}
|
|
539
|
-
return await this.
|
|
572
|
+
return await this.functionCloudService.request('DeleteFunction', {
|
|
540
573
|
FunctionName: funcName,
|
|
541
|
-
|
|
574
|
+
[this.namespaceParamKey]: namespace
|
|
542
575
|
});
|
|
543
576
|
}
|
|
544
577
|
/**
|
|
@@ -569,12 +602,12 @@ class FunctionService {
|
|
|
569
602
|
const params = {
|
|
570
603
|
FunctionName: name,
|
|
571
604
|
ShowCode: 'TRUE',
|
|
572
|
-
|
|
605
|
+
[this.namespaceParamKey]: namespace
|
|
573
606
|
};
|
|
574
607
|
if (codeSecret) {
|
|
575
608
|
params.CodeSecret = codeSecret;
|
|
576
609
|
}
|
|
577
|
-
const data = await this.
|
|
610
|
+
const data = await this.functionCloudService.request('GetFunction', params);
|
|
578
611
|
// 解析 VPC 配置
|
|
579
612
|
const { VpcId = '', SubnetId = '' } = data.VpcConfig || {};
|
|
580
613
|
if (VpcId && SubnetId) {
|
|
@@ -713,7 +746,7 @@ class FunctionService {
|
|
|
713
746
|
const { TopicId, LogsetId } = this.getClsServiceConfig();
|
|
714
747
|
// 构建参数
|
|
715
748
|
const params = {
|
|
716
|
-
|
|
749
|
+
[this.namespaceParamKey]: namespace,
|
|
717
750
|
FunctionName: func.name,
|
|
718
751
|
ClsTopicId: TopicId,
|
|
719
752
|
ClsLogsetId: LogsetId
|
|
@@ -727,7 +760,9 @@ class FunctionService {
|
|
|
727
760
|
params[pascalKey] = toPascalCaseKeys(func[key]);
|
|
728
761
|
}
|
|
729
762
|
// 特殊处理:安装依赖标志(支持 boolean | string)
|
|
730
|
-
|
|
763
|
+
// 注意:ENABLE_TCBF 开启时,InstallDependency 属于 UpdateFunctionCode 的参数,
|
|
764
|
+
// tcb 的 UpdateFunctionConfiguration 不认,故跳过
|
|
765
|
+
if (func.installDependency !== undefined && !this.useTcbFunctionApi) {
|
|
731
766
|
params.InstallDependency = toBooleanString(func.installDependency);
|
|
732
767
|
}
|
|
733
768
|
// 特殊处理:L5 配置(支持 boolean | string)
|
|
@@ -807,7 +842,7 @@ class FunctionService {
|
|
|
807
842
|
console.warn(`[${func.name}] 触发器更新失败:${triggerError.message}`);
|
|
808
843
|
}
|
|
809
844
|
}
|
|
810
|
-
return this.
|
|
845
|
+
return this.functionCloudService.request('UpdateFunctionConfiguration', params);
|
|
811
846
|
}
|
|
812
847
|
catch (e) {
|
|
813
848
|
throw new error_1.CloudBaseError(`[${func.name}] 更新函数配置失败:${e.message}`, {
|
|
@@ -830,7 +865,7 @@ class FunctionService {
|
|
|
830
865
|
if (deployMode === 'image') {
|
|
831
866
|
const params = {
|
|
832
867
|
FunctionName: funcName,
|
|
833
|
-
|
|
868
|
+
[this.namespaceParamKey]: namespace,
|
|
834
869
|
Code: {
|
|
835
870
|
ImageConfig: buildImageConfig(func.imageConfig)
|
|
836
871
|
}
|
|
@@ -841,7 +876,7 @@ class FunctionService {
|
|
|
841
876
|
try {
|
|
842
877
|
// 等待函数状态正常
|
|
843
878
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
844
|
-
return await this.
|
|
879
|
+
return await this.functionCloudService.request('UpdateFunctionCode', params);
|
|
845
880
|
}
|
|
846
881
|
catch (e) {
|
|
847
882
|
throw new error_1.CloudBaseError(`[${funcName}] 函数代码更新失败:${e.message}`, {
|
|
@@ -871,7 +906,7 @@ class FunctionService {
|
|
|
871
906
|
}, installDependency);
|
|
872
907
|
const params = {
|
|
873
908
|
FunctionName: funcName,
|
|
874
|
-
|
|
909
|
+
[this.namespaceParamKey]: namespace,
|
|
875
910
|
Handler: func.handler || 'index.main',
|
|
876
911
|
InstallDependency: installDependency,
|
|
877
912
|
Code: codeParams
|
|
@@ -883,7 +918,7 @@ class FunctionService {
|
|
|
883
918
|
// 等待函数状态正常
|
|
884
919
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
885
920
|
// 更新云函数代码
|
|
886
|
-
const res = await this.
|
|
921
|
+
const res = await this.functionCloudService.request('UpdateFunctionCode', params);
|
|
887
922
|
if (installDependency && func.isWaitInstall === true) {
|
|
888
923
|
await this.waitFunctionActive(funcName, codeSecret);
|
|
889
924
|
}
|
|
@@ -1109,12 +1144,16 @@ class FunctionService {
|
|
|
1109
1144
|
const { destPath, envId, functionName, codeSecret } = options;
|
|
1110
1145
|
// 检验路径是否存在
|
|
1111
1146
|
(0, utils_1.checkFullAccess)(destPath, true);
|
|
1112
|
-
//
|
|
1113
|
-
const
|
|
1147
|
+
// 获取下载链接:ENABLE_TCBF 开启走 tcb 的 DownloadFunction,否则走 scf 的 GetFunctionAddress
|
|
1148
|
+
const action = this.useTcbFunctionApi ? 'DownloadFunction' : 'GetFunctionAddress';
|
|
1149
|
+
const params = {
|
|
1114
1150
|
FunctionName: functionName,
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1151
|
+
[this.namespaceParamKey]: envId
|
|
1152
|
+
};
|
|
1153
|
+
if (codeSecret) {
|
|
1154
|
+
params.CodeSecret = codeSecret;
|
|
1155
|
+
}
|
|
1156
|
+
const { Url } = await this.functionCloudService.request(action, params);
|
|
1118
1157
|
// 下载文件
|
|
1119
1158
|
return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
|
|
1120
1159
|
}
|
|
@@ -1129,13 +1168,15 @@ class FunctionService {
|
|
|
1129
1168
|
const { namespace } = this.getFunctionConfig();
|
|
1130
1169
|
const params = {
|
|
1131
1170
|
FunctionName: functionName,
|
|
1132
|
-
|
|
1171
|
+
[this.namespaceParamKey]: namespace
|
|
1133
1172
|
};
|
|
1134
1173
|
if (codeSecret) {
|
|
1135
1174
|
params.CodeSecret = codeSecret;
|
|
1136
1175
|
}
|
|
1137
1176
|
try {
|
|
1138
|
-
|
|
1177
|
+
// ENABLE_TCBF 开启走 tcb 的 DownloadFunction,否则走 scf 的 GetFunctionAddress
|
|
1178
|
+
const action = this.useTcbFunctionApi ? 'DownloadFunction' : 'GetFunctionAddress';
|
|
1179
|
+
const { Url, CodeSha256, RequestId } = await this.functionCloudService.request(action, params);
|
|
1139
1180
|
return { Url, RequestId, CodeSha256 };
|
|
1140
1181
|
}
|
|
1141
1182
|
catch (e) {
|
package/lib/hosting/index.js
CHANGED
|
@@ -364,7 +364,7 @@ class HostingService {
|
|
|
364
364
|
* @param options
|
|
365
365
|
*/
|
|
366
366
|
async setWebsiteDocument(options) {
|
|
367
|
-
const { indexDocument, errorDocument,
|
|
367
|
+
const { indexDocument, errorDocument, routingRules } = options;
|
|
368
368
|
const hosting = await this.checkStatus();
|
|
369
369
|
const { Bucket, Regoin } = hosting;
|
|
370
370
|
const storageService = await this.environment.getStorageService();
|
|
@@ -373,9 +373,6 @@ class HostingService {
|
|
|
373
373
|
region: Regoin,
|
|
374
374
|
indexDocument,
|
|
375
375
|
errorDocument,
|
|
376
|
-
originalHttpStatus,
|
|
377
|
-
charity404,
|
|
378
|
-
autoAddressing,
|
|
379
376
|
routingRules
|
|
380
377
|
});
|
|
381
378
|
return res;
|
package/lib/index.js
CHANGED
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
const context_1 = require("./context");
|
|
3
3
|
const environmentManager_1 = require("./environmentManager");
|
|
4
4
|
const docs_1 = require("./docs");
|
|
5
|
-
const projectValidator_1 = require("./projectValidator");
|
|
6
|
-
const DeployOrchestrator_1 = require("./deploy/DeployOrchestrator");
|
|
7
5
|
class CloudBase {
|
|
8
6
|
/**
|
|
9
7
|
* init 初始化 为单例
|
|
@@ -51,13 +49,6 @@ class CloudBase {
|
|
|
51
49
|
get functions() {
|
|
52
50
|
return this.currentEnvironment().getFunctionService();
|
|
53
51
|
}
|
|
54
|
-
/**
|
|
55
|
-
* 函数部署编排器(FunctionDeployer)
|
|
56
|
-
* 在现有 FunctionService 之上,按 buildStrategy 编排 Event/HTTP 函数的创建、更新与访问收敛
|
|
57
|
-
*/
|
|
58
|
-
get functionDeployer() {
|
|
59
|
-
return this.currentEnvironment().getFunctionDeployer();
|
|
60
|
-
}
|
|
61
52
|
get cloudrun() {
|
|
62
53
|
return this.currentEnvironment().getCloudRunService();
|
|
63
54
|
}
|
|
@@ -155,28 +146,6 @@ class CloudBase {
|
|
|
155
146
|
}
|
|
156
147
|
return this.docsService;
|
|
157
148
|
}
|
|
158
|
-
get projectValidator() {
|
|
159
|
-
if (!this.projectValidatorService) {
|
|
160
|
-
this.projectValidatorService = new projectValidator_1.ProjectValidator();
|
|
161
|
-
}
|
|
162
|
-
return this.projectValidatorService;
|
|
163
|
-
}
|
|
164
|
-
getProjectValidator() {
|
|
165
|
-
return this.projectValidator;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* 声明式部署编排器
|
|
169
|
-
* 顺序:database → functions → app → hosting → gateway;支持 dry-run / only / skip / 幂等重试
|
|
170
|
-
*/
|
|
171
|
-
get deployOrchestrator() {
|
|
172
|
-
if (!this.deployOrchestratorService) {
|
|
173
|
-
this.deployOrchestratorService = new DeployOrchestrator_1.DeployOrchestrator(this.currentEnvironment());
|
|
174
|
-
}
|
|
175
|
-
return this.deployOrchestratorService;
|
|
176
|
-
}
|
|
177
|
-
getDeployOrchestrator() {
|
|
178
|
-
return this.deployOrchestrator;
|
|
179
|
-
}
|
|
180
149
|
getEnvironmentManager() {
|
|
181
150
|
return this.environmentManager;
|
|
182
151
|
}
|
package/lib/storage/index.js
CHANGED
|
@@ -1046,19 +1046,20 @@ class StorageService {
|
|
|
1046
1046
|
* 配置文档
|
|
1047
1047
|
*/
|
|
1048
1048
|
async putBucketWebsite(options) {
|
|
1049
|
-
const { indexDocument, errorDocument,
|
|
1049
|
+
const { indexDocument, errorDocument, bucket, region, routingRules } = options;
|
|
1050
1050
|
const cos = this.getCos();
|
|
1051
1051
|
const putBucketWebsite = util_1.default.promisify(cos.putBucketWebsite).bind(cos);
|
|
1052
1052
|
let params = {
|
|
1053
1053
|
Bucket: bucket,
|
|
1054
1054
|
Region: region,
|
|
1055
|
-
WebsiteConfiguration:
|
|
1055
|
+
WebsiteConfiguration: {
|
|
1056
|
+
IndexDocument: {
|
|
1056
1057
|
Suffix: indexDocument
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1058
|
+
},
|
|
1059
|
+
ErrorDocument: {
|
|
1060
|
+
Key: errorDocument
|
|
1060
1061
|
}
|
|
1061
|
-
|
|
1062
|
+
}
|
|
1062
1063
|
};
|
|
1063
1064
|
if (routingRules) {
|
|
1064
1065
|
params.WebsiteConfiguration.RoutingRules = [];
|
package/lib/utils/index.js
CHANGED
|
@@ -34,7 +34,6 @@ const archiver_1 = __importDefault(require("archiver"));
|
|
|
34
34
|
const crypto_1 = __importDefault(require("crypto"));
|
|
35
35
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
36
36
|
const lodash_1 = __importDefault(require("lodash"));
|
|
37
|
-
const os_1 = __importDefault(require("os"));
|
|
38
37
|
const path_1 = __importDefault(require("path"));
|
|
39
38
|
const unzipper_1 = __importDefault(require("unzipper"));
|
|
40
39
|
const constant_1 = require("../constant");
|
|
@@ -48,53 +47,18 @@ __exportStar(require("./http-request"), exports);
|
|
|
48
47
|
var uuid_1 = require("./uuid");
|
|
49
48
|
Object.defineProperty(exports, "guid6", { enumerable: true, get: function () { return uuid_1.guid6; } });
|
|
50
49
|
async function compressToZip(option) {
|
|
51
|
-
const { dirPath, outputPath, ignore, pattern = '**/*'
|
|
52
|
-
// 额外注入的文件先落地到临时目录,用 archive.file() 追加,
|
|
53
|
-
// 使 archiver 正确计算 CRC/size(archiver 3.x 的 append(buffer/string)
|
|
54
|
-
// 会写出 CRC=0 的流式条目,被严格解压器判为 bad CRC)。
|
|
55
|
-
let extraTmpDir;
|
|
56
|
-
if (extraEntries && extraEntries.length > 0) {
|
|
57
|
-
extraTmpDir = path_1.default.join(os_1.default.tmpdir(), `zip-extra-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
58
|
-
fs_extra_1.default.mkdirpSync(extraTmpDir);
|
|
59
|
-
}
|
|
50
|
+
const { dirPath, outputPath, ignore, pattern = '**/*' } = option;
|
|
60
51
|
return new Promise((resolve, reject) => {
|
|
61
|
-
// 幂等清理:archiver 的 error 事件与 output.close 事件在不同代码路径上,
|
|
62
|
-
// 但 extraEntries 写入异常分支调用 archive.abort() 后的异步收尾流程
|
|
63
|
-
// 仍可能间接触发 archive.error,导致 cleanupExtra 被多次调用。
|
|
64
|
-
// 用 done 标志保证清理和 resolve/reject 仅生效一次。
|
|
65
|
-
let done = false;
|
|
66
|
-
const settle = (fn) => {
|
|
67
|
-
if (done)
|
|
68
|
-
return;
|
|
69
|
-
done = true;
|
|
70
|
-
fn();
|
|
71
|
-
};
|
|
72
|
-
const cleanupExtra = () => {
|
|
73
|
-
if (extraTmpDir) {
|
|
74
|
-
try {
|
|
75
|
-
fs_extra_1.default.removeSync(extraTmpDir);
|
|
76
|
-
}
|
|
77
|
-
catch (_a) {
|
|
78
|
-
// 清理临时目录失败不影响主流程
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
52
|
const output = fs_extra_1.default.createWriteStream(outputPath);
|
|
83
53
|
const archive = (0, archiver_1.default)('zip');
|
|
84
54
|
output.on('close', function () {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
zipPath: outputPath,
|
|
89
|
-
size: Math.ceil(archive.pointer() / 1024)
|
|
90
|
-
});
|
|
55
|
+
resolve({
|
|
56
|
+
zipPath: outputPath,
|
|
57
|
+
size: Math.ceil(archive.pointer() / 1024)
|
|
91
58
|
});
|
|
92
59
|
});
|
|
93
60
|
archive.on('error', function (err) {
|
|
94
|
-
|
|
95
|
-
cleanupExtra();
|
|
96
|
-
reject(err);
|
|
97
|
-
});
|
|
61
|
+
reject(err);
|
|
98
62
|
});
|
|
99
63
|
archive.pipe(output);
|
|
100
64
|
// append files from a glob pattern
|
|
@@ -104,27 +68,6 @@ async function compressToZip(option) {
|
|
|
104
68
|
ignore: ignore,
|
|
105
69
|
dot: true
|
|
106
70
|
});
|
|
107
|
-
// 追加 SDK 注入的额外文件(如构建推送脚本),不污染用户源码目录
|
|
108
|
-
if (extraEntries && extraEntries.length > 0 && extraTmpDir) {
|
|
109
|
-
try {
|
|
110
|
-
extraEntries.forEach((entry, index) => {
|
|
111
|
-
const tmpFile = path_1.default.join(extraTmpDir, `entry-${index}`);
|
|
112
|
-
const buf = Buffer.isBuffer(entry.content)
|
|
113
|
-
? entry.content
|
|
114
|
-
: Buffer.from(entry.content, 'utf8');
|
|
115
|
-
fs_extra_1.default.writeFileSync(tmpFile, buf, { mode: entry.mode });
|
|
116
|
-
archive.file(tmpFile, { name: entry.zipPath, mode: entry.mode });
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
catch (error) {
|
|
120
|
-
settle(() => {
|
|
121
|
-
cleanupExtra();
|
|
122
|
-
archive.abort();
|
|
123
|
-
reject(error);
|
|
124
|
-
});
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
71
|
archive.finalize();
|
|
129
72
|
});
|
|
130
73
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudbase/manager-node",
|
|
3
|
-
"version": "5.7.
|
|
3
|
+
"version": "5.7.1-beta.0",
|
|
4
4
|
"description": "The node manage service api for cloudbase.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -42,7 +42,6 @@
|
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@cloudbase/signature-nodejs": "^1.0.0",
|
|
45
|
-
"@cloudbase/toolbox": "^0.8.3-beta.0",
|
|
46
45
|
"@cloudbase/database": "^0.6.2",
|
|
47
46
|
"archiver": "^3.1.1",
|
|
48
47
|
"cos-nodejs-sdk-v5": "^2.14.0",
|
|
@@ -57,10 +57,6 @@ export declare class CloudAppService {
|
|
|
57
57
|
* 注意:此方法不依赖应用是否已创建,可在创建应用前调用
|
|
58
58
|
* 返回的 cosTimestamp 用于 createApp 时传入 staticConfig.cosTimestamp
|
|
59
59
|
*
|
|
60
|
-
* 内置默认忽略:.git 目录、.DS_Store(含任意层级);node_modules 仅在
|
|
61
|
-
* excludeNodeModules 为 true(默认)时排除——云端构建(需云端 install)场景应传
|
|
62
|
-
* excludeNodeModules: false 允许私有/离线依赖随源码包上传。
|
|
63
|
-
*
|
|
64
60
|
* @param params 上传参数
|
|
65
61
|
*/
|
|
66
62
|
uploadCode(params: IUploadCloudAppCodeParams): Promise<IUploadCloudAppCodeResult>;
|
|
@@ -10,80 +10,19 @@
|
|
|
10
10
|
* 部署类型
|
|
11
11
|
* - static-hosting: 静态托管部署
|
|
12
12
|
* - http-function: HTTP 云函数部署(预留)
|
|
13
|
-
* - custom: 自定义构建(CloudApp custom:源码 ZIP → 容器内执行 CustomSteps → docker build/push TCR),
|
|
14
|
-
* 用于 HTTP 函数镜像的云端构建(buildStrategy: cloud)
|
|
15
13
|
*/
|
|
16
|
-
export type DeployType = 'static-hosting' | 'http-function'
|
|
14
|
+
export type DeployType = 'static-hosting' | 'http-function';
|
|
17
15
|
/**
|
|
18
16
|
* 构建类型
|
|
19
17
|
* - GIT: 从 Git 仓库构建
|
|
20
18
|
* - ZIP: 从 ZIP 包构建
|
|
21
19
|
* - TEMPLATE: 从模板构建
|
|
22
|
-
* - zip: custom 构建的源码 ZIP(与 API 文档 BuildType 大小写保持一致)
|
|
23
20
|
*/
|
|
24
|
-
export type BuildType = 'GIT' | 'ZIP' | 'TEMPLATE'
|
|
25
|
-
/**
|
|
26
|
-
* custom 构建源码来源
|
|
27
|
-
*对应 API 的 Source 字段,zip 模式回填 DescribeCloudAppCosInfo 返回的时间戳
|
|
28
|
-
*/
|
|
29
|
-
export interface ICustomBuildSource {
|
|
30
|
-
/** 源码类型,当前实现为 zip */
|
|
31
|
-
type: 'zip' | 'git';
|
|
32
|
-
/** COS 时间戳,原样使用 DescribeCloudAppCosInfo 返回的 UnixTimestamp */
|
|
33
|
-
cosTimestamp?: string;
|
|
34
|
-
/** COS 文件后缀,默认 .zip */
|
|
35
|
-
cosSuffix?: string;
|
|
36
|
-
}
|
|
37
|
-
/** custom 构建环境变量项(明文,禁止写入敏感值) */
|
|
38
|
-
export interface ICustomBuildEnv {
|
|
39
|
-
key: string;
|
|
40
|
-
value: string;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* custom 构建密钥项
|
|
44
|
-
* CloudApp 在构建容器中按 $SECRET_{NAME} 注入,Value 不应进入日志或普通环境变量。
|
|
45
|
-
*/
|
|
46
|
-
export interface ICustomBuildSecret {
|
|
47
|
-
name: string;
|
|
48
|
-
value: string;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* custom 构建自定义步骤
|
|
52
|
-
* SDK 固定生成模板,用户不可控字段绝不作为任意 shell 片段拼接
|
|
53
|
-
*/
|
|
54
|
-
export interface ICustomBuildStep {
|
|
55
|
-
name: string;
|
|
56
|
-
command: string;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* custom 构建单步状态(API 响应,字段大小写与响应一致)
|
|
60
|
-
* 注意:Duration 为字符串、Status 为小写
|
|
61
|
-
*/
|
|
62
|
-
export interface CloudAppBuildStep {
|
|
63
|
-
Name: string;
|
|
64
|
-
Status: string;
|
|
65
|
-
Duration?: string;
|
|
66
|
-
/** 失败时的退出码,用于定位 */
|
|
67
|
-
ExitCode?: number;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* custom 构建产物(API 响应)
|
|
71
|
-
* 镜像构建成功后Type 通常为 image
|
|
72
|
-
*/
|
|
73
|
-
export interface CloudAppArtifact {
|
|
74
|
-
Type: string;
|
|
75
|
-
Name: string;
|
|
76
|
-
Status?: string;
|
|
77
|
-
/** 部分场景直接回传完整镜像地址 */
|
|
78
|
-
ImageUri?: string;
|
|
79
|
-
/** 部分场景回传 digest */
|
|
80
|
-
Digest?: string;
|
|
81
|
-
}
|
|
21
|
+
export type BuildType = 'GIT' | 'ZIP' | 'TEMPLATE';
|
|
82
22
|
/**
|
|
83
23
|
* 构建状态
|
|
84
|
-
* custom 构建终态为 SUCCESS / FAILED / CANCELED
|
|
85
24
|
*/
|
|
86
|
-
export type BuildStatus = 'BUILDING' | 'SUCCESS' | 'FAILED'
|
|
25
|
+
export type BuildStatus = 'BUILDING' | 'SUCCESS' | 'FAILED';
|
|
87
26
|
/**
|
|
88
27
|
* 构建命令配置(入参)
|
|
89
28
|
*/
|
|
@@ -210,24 +149,14 @@ export interface CloudAppVersion {
|
|
|
210
149
|
export interface ICreateCloudAppParams {
|
|
211
150
|
/** 环境 ID(可选,默认从 Environment 获取) */
|
|
212
151
|
envId?: string;
|
|
213
|
-
/** 部署类型:static-hosting / http-function
|
|
152
|
+
/** 部署类型:static-hosting / http-function */
|
|
214
153
|
deployType: DeployType;
|
|
215
154
|
/** 服务名称 */
|
|
216
155
|
serviceName: string;
|
|
217
|
-
/** 构建类型:GIT / ZIP / TEMPLATE
|
|
156
|
+
/** 构建类型:GIT / ZIP / TEMPLATE */
|
|
218
157
|
buildType?: BuildType;
|
|
219
158
|
/** 静态托管配置(deployType 为 static-hosting 时使用) */
|
|
220
159
|
staticConfig?: IStaticConfig;
|
|
221
|
-
/** custom 构建源码来源(deployType 为 custom 时使用) */
|
|
222
|
-
source?: ICustomBuildSource;
|
|
223
|
-
/** custom 构建环境变量(deployType 为 custom 时使用,禁止敏感值) */
|
|
224
|
-
env?: ICustomBuildEnv[];
|
|
225
|
-
/** custom 构建密钥(deployType 为 custom 时使用) */
|
|
226
|
-
secrets?: ICustomBuildSecret[];
|
|
227
|
-
/** custom 构建自定义步骤(deployType 为 custom 时使用,SDK 固定模板) */
|
|
228
|
-
customSteps?: ICustomBuildStep[];
|
|
229
|
-
/** 跳过云端构建(纯静态直传场景:产物已直传,仅写部署记录,对应 API SkipBuild) */
|
|
230
|
-
skipBuild?: boolean;
|
|
231
160
|
}
|
|
232
161
|
export interface ICreateCloudAppResult {
|
|
233
162
|
ServiceName: string;
|
|
@@ -303,10 +232,6 @@ export interface IDescribeCloudAppVersionResult {
|
|
|
303
232
|
Framework?: string;
|
|
304
233
|
StaticConfig?: CloudAppStaticConfig;
|
|
305
234
|
BuildTime?: string;
|
|
306
|
-
/** custom 构建的分步状态(deployType 为 custom 时返回) */
|
|
307
|
-
Steps?: CloudAppBuildStep[] | null;
|
|
308
|
-
/** custom 构建产物(deployType 为 custom 时返回,镜像信息优先从此获取) */
|
|
309
|
-
Artifacts?: CloudAppArtifact[] | null;
|
|
310
235
|
RequestId: string;
|
|
311
236
|
}
|
|
312
237
|
export interface IDescribeCloudAppVersionListParams {
|
|
@@ -399,14 +324,8 @@ export interface IUploadCloudAppCodeParams {
|
|
|
399
324
|
serviceName: string;
|
|
400
325
|
/** 本地文件夹路径 */
|
|
401
326
|
localPath: string;
|
|
402
|
-
/**
|
|
327
|
+
/** 忽略的文件/目录模式 */
|
|
403
328
|
ignore?: string[];
|
|
404
|
-
/**
|
|
405
|
-
* 是否排除 node_modules:
|
|
406
|
-
* 默认 true(静态产物 / 版本快照场景,避免误传大目录);
|
|
407
|
-
* 云端构建(需云端 install)场景设为 false,允许私有/离线依赖随源码包上传
|
|
408
|
-
*/
|
|
409
|
-
excludeNodeModules?: boolean;
|
|
410
329
|
/** 进度回调 */
|
|
411
330
|
onProgress?: (progress: IProgressData) => void;
|
|
412
331
|
/** 分步计时回调(各阶段完成时触发,用于 verbose 模式输出耗时) */
|