@cloudbase/manager-node 5.7.1-beta.1 → 5.8.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cloudApp/index.js +12 -3
- package/lib/deploy/DatabaseDeployer.js +238 -0
- package/lib/deploy/DeployOrchestrator.js +645 -0
- package/lib/deploy/FunctionDeployer.js +611 -0
- package/lib/deploy/GatewayDeployer.js +612 -0
- package/lib/deploy/StateStore.js +327 -0
- package/lib/deploy/StaticDeployer.js +236 -0
- package/lib/deploy/domain.js +41 -0
- package/lib/deploy/framework.js +230 -0
- package/lib/deploy/function/artifact.js +207 -0
- package/lib/deploy/function/builders/cloud.js +654 -0
- package/lib/deploy/function/cam-preflight.js +157 -0
- package/lib/deploy/function/cloud-build-service.js +191 -0
- package/lib/deploy/function/config-guard.js +595 -0
- package/lib/deploy/function/docker-preflight.js +87 -0
- package/lib/deploy/function/image-preflight.js +164 -0
- package/lib/deploy/function/local-builder.js +129 -0
- package/lib/deploy/function/planner.js +278 -0
- package/lib/deploy/function/preflight.js +329 -0
- package/lib/deploy/types.js +103 -0
- package/lib/env/index.js +0 -27
- package/lib/environment.js +11 -0
- package/lib/function/index.js +1 -1
- package/lib/hosting/index.js +4 -1
- package/lib/index.js +31 -0
- package/lib/projectValidator/index.js +452 -0
- package/lib/projectValidator/types.js +2 -0
- package/lib/storage/index.js +6 -7
- package/lib/utils/index.js +62 -5
- package/package.json +2 -1
- package/types/cloudApp/index.d.ts +4 -0
- package/types/cloudApp/types.d.ts +87 -6
- package/types/deploy/DatabaseDeployer.d.ts +70 -0
- package/types/deploy/DeployOrchestrator.d.ts +170 -0
- package/types/deploy/FunctionDeployer.d.ts +159 -0
- package/types/deploy/GatewayDeployer.d.ts +194 -0
- package/types/deploy/StateStore.d.ts +170 -0
- package/types/deploy/StaticDeployer.d.ts +97 -0
- package/types/deploy/domain.d.ts +17 -0
- package/types/deploy/framework.d.ts +63 -0
- package/types/deploy/function/artifact.d.ts +40 -0
- package/types/deploy/function/builders/cloud.d.ts +110 -0
- package/types/deploy/function/cam-preflight.d.ts +51 -0
- package/types/deploy/function/cloud-build-service.d.ts +10 -0
- package/types/deploy/function/config-guard.d.ts +41 -0
- package/types/deploy/function/docker-preflight.d.ts +17 -0
- package/types/deploy/function/image-preflight.d.ts +21 -0
- package/types/deploy/function/local-builder.d.ts +26 -0
- package/types/deploy/function/planner.d.ts +15 -0
- package/types/deploy/function/preflight.d.ts +9 -0
- package/types/deploy/types.d.ts +429 -0
- package/types/env/index.d.ts +1 -17
- package/types/env/type.d.ts +6 -260
- package/types/environment.d.ts +7 -0
- package/types/function/types.d.ts +15 -0
- package/types/hosting/index.d.ts +6 -0
- package/types/index.d.ts +18 -0
- package/types/interfaces/function.interface.d.ts +1 -1
- package/types/projectValidator/index.d.ts +38 -0
- package/types/projectValidator/types.d.ts +26 -0
- package/types/storage/index.d.ts +6 -0
- package/types/utils/index.d.ts +13 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { Environment } from '../environment';
|
|
2
|
+
import { HTTPServiceRouteParam } from '../env/type';
|
|
3
|
+
/** 网关路由配置(cloudbaserc.json gateway.routes[]) */
|
|
4
|
+
export interface IGatewayRoute {
|
|
5
|
+
/** 绑定的自定义域名。配置时自动绑定(需 certId);不填则使用环境 HTTP 访问服务的默认域名(如 {envId}-{uin}.{region}.app.tcloudbase.com) */
|
|
6
|
+
domain?: string;
|
|
7
|
+
/** SSL 证书 ID(绑定自定义域名时需要,可先通过 SSL 控制台/API 获取) */
|
|
8
|
+
certId?: string;
|
|
9
|
+
/** 域名接入方式(默认 DIRECT 直接接入):DIRECT/CDN(接入云开发 CDN)/CUSTOM(自定义接入,需 customCname)/EO(接入云开发 EdgeOne) */
|
|
10
|
+
accessType?: 'DIRECT' | 'CDN' | 'CUSTOM' | 'EO';
|
|
11
|
+
/** 自定义接入时配置的 CNAME 记录(accessType=CUSTOM 时必填) */
|
|
12
|
+
customCname?: string;
|
|
13
|
+
/** 域名协议(默认 HTTP_AND_HTTPS):HTTP/HTTPS/HTTP_AND_HTTPS/HTTP_TO_HTTPS/HTTPS_TO_HTTP */
|
|
14
|
+
protocol?: 'HTTP' | 'HTTPS' | 'HTTP_AND_HTTPS' | 'HTTP_TO_HTTPS' | 'HTTPS_TO_HTTP';
|
|
15
|
+
/** 域名启用状态(默认 true) */
|
|
16
|
+
enable?: boolean;
|
|
17
|
+
/** 路径,如 /api 或 /web */
|
|
18
|
+
path: string;
|
|
19
|
+
/** 目标:function:<name> 或 hosting:<name> */
|
|
20
|
+
target: string;
|
|
21
|
+
/** 是否开启路径透传(默认 false) */
|
|
22
|
+
enablePathTransmission?: boolean;
|
|
23
|
+
/** 是否开启身份认证(默认 false) */
|
|
24
|
+
enableAuth?: boolean;
|
|
25
|
+
/** 路径重写配置(prefix/staticStorePrefix 只能填一个)。hosting 路由未配置时自动生成 { Prefix: deployPath };显式配置时透传且不校验 hosting 名称(可引用已部署实例) */
|
|
26
|
+
pathRewrite?: {
|
|
27
|
+
prefix?: string;
|
|
28
|
+
staticStorePrefix?: string;
|
|
29
|
+
};
|
|
30
|
+
/** QPS 限频策略 */
|
|
31
|
+
qpsPolicy?: {
|
|
32
|
+
/** QPS 限额总量(每秒请求次数),100-100000 */
|
|
33
|
+
qpsTotal?: number;
|
|
34
|
+
/** 客户端限频配置 */
|
|
35
|
+
qpsPerClient?: {
|
|
36
|
+
limitBy?: 'UserID' | 'ClientIP';
|
|
37
|
+
limitValue?: number;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** 网关部署结果 */
|
|
42
|
+
export interface IGatewayDeployResult {
|
|
43
|
+
domain: string;
|
|
44
|
+
routes: Array<{
|
|
45
|
+
path: string;
|
|
46
|
+
target: string;
|
|
47
|
+
url: string;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* 网关声明式部署器
|
|
52
|
+
* 支持 function:<name>(SCF 云函数)与 hosting:<name>(STATIC_STORE 静态托管)两种目标
|
|
53
|
+
*/
|
|
54
|
+
export declare class GatewayDeployer {
|
|
55
|
+
private environment;
|
|
56
|
+
constructor(environment: Environment);
|
|
57
|
+
/**
|
|
58
|
+
* 部署网关路由
|
|
59
|
+
*
|
|
60
|
+
* 域名规则:
|
|
61
|
+
* - 未配置 domain → 使用环境 HTTP 访问服务的**默认域名**(Domains 中 IsDefault=true,如 {envId}-{uin}.{region}.app.tcloudbase.com),直接创建路由
|
|
62
|
+
* - 配置了 domain(自定义域名)→ **先自动绑定自定义域名**(bindCustomDomain,需 certId),再创建路由
|
|
63
|
+
* 不同域名的路由分组创建。
|
|
64
|
+
*/
|
|
65
|
+
deploy(options: {
|
|
66
|
+
routes: IGatewayRoute[];
|
|
67
|
+
envId: string;
|
|
68
|
+
/** hosting 配置列表(用于为 hosting:<name> 路由生成 PathRewrite.Prefix 部署路径) */
|
|
69
|
+
hostings?: Array<{
|
|
70
|
+
name?: string;
|
|
71
|
+
deployPath?: string;
|
|
72
|
+
}>;
|
|
73
|
+
}): Promise<IGatewayDeployResult>;
|
|
74
|
+
/**
|
|
75
|
+
* 解析路由配置:校验 target 格式并映射为 HTTPServiceRouteParam
|
|
76
|
+
*
|
|
77
|
+
* 对齐 tcb routes add 的底层校验(src/commands/routes/add.ts):
|
|
78
|
+
* - path 必须以 / 开头,每段只含字母/数字/./_/-,50 字符内,不支持通配符 *
|
|
79
|
+
* - 静态托管(STATIC_STORE)上游名固定为 staticstore,且只支持一级路径
|
|
80
|
+
*/
|
|
81
|
+
parseRoute(route: IGatewayRoute): HTTPServiceRouteParam;
|
|
82
|
+
/**
|
|
83
|
+
* 计算网关路由部署计划(dry-run):每个路由 create/update/skip + 变更字段明细
|
|
84
|
+
*
|
|
85
|
+
* 判定逻辑与 deploy() 完全一致:云端不存在的 path → create;
|
|
86
|
+
* 已存在但显式配置不一致 → update(带 changes);一致 → skip。
|
|
87
|
+
*/
|
|
88
|
+
planRoutes(options: {
|
|
89
|
+
routes: IGatewayRoute[];
|
|
90
|
+
envId: string;
|
|
91
|
+
hostings?: Array<{
|
|
92
|
+
name?: string;
|
|
93
|
+
deployPath?: string;
|
|
94
|
+
}>;
|
|
95
|
+
}): Promise<Array<{
|
|
96
|
+
path: string;
|
|
97
|
+
target: string;
|
|
98
|
+
status: 'create' | 'update' | 'skip';
|
|
99
|
+
changes?: Array<{
|
|
100
|
+
field: string;
|
|
101
|
+
from?: string;
|
|
102
|
+
to?: string;
|
|
103
|
+
}>;
|
|
104
|
+
}>>;
|
|
105
|
+
/**
|
|
106
|
+
* 查询指定域名下已存在的路由(幂等收敛用),返回 Map<path, 云端路由详情>
|
|
107
|
+
*
|
|
108
|
+
* 匹配策略(优先级从高到低):
|
|
109
|
+
* 1. 用 Filters 精确查询目标域名:DescribeHTTPServiceRoute 不带 Filters 时返回的 Domains
|
|
110
|
+
* 列表可能不完整(如 lowcode 环境 TotalCount=67 但 Domains 只返回部分,HTTPSERVICE 的
|
|
111
|
+
* .app.tcloudbase.com 域名缺失),导致云端已有路由查不到被误判为 create
|
|
112
|
+
* 2. 降级:不带 Filters 全量查询,按域名归一化匹配(去协议/尾斜杠/转小写)
|
|
113
|
+
* 若目标域名找不到则返回空(保留 domain 维度,避免把其他域名同 path 误判为已存在)
|
|
114
|
+
*/
|
|
115
|
+
private getExistingRoutes;
|
|
116
|
+
/**
|
|
117
|
+
* 域名归一化:去协议、去尾斜杠、转小写(用于幂等收敛的域名匹配)
|
|
118
|
+
*/
|
|
119
|
+
private normalizeDomain;
|
|
120
|
+
/**
|
|
121
|
+
* 判断错误是否属于「路由已存在/已占用」类(幂等降级专用)
|
|
122
|
+
*
|
|
123
|
+
* 只匹配明确的重复/占用语义(code 含 AlreadyExists/Duplicate/ResourceInUse/Conflict,
|
|
124
|
+
* 或 message 含 already exists),并显式排除否定语义(not exists/not found 等),
|
|
125
|
+
* 避免把「环境/资源不存在」等真实失败误判为「已存在」而被静默跳过
|
|
126
|
+
*/
|
|
127
|
+
private isAlreadyExistsError;
|
|
128
|
+
/**
|
|
129
|
+
* 判断期望路由与云端已存在路由是否一致
|
|
130
|
+
*
|
|
131
|
+
* 只比较**用户显式声明的字段**(enableAuth/enablePathTransmission 显式配置才比较;
|
|
132
|
+
* QPSPolicy/PathRewrite 本地有值才比较),避免覆盖控制台单独配置的字段。
|
|
133
|
+
*/
|
|
134
|
+
private routesEqual;
|
|
135
|
+
/**
|
|
136
|
+
* 构建 modifyHttpServiceRoute 的路由参数:只包含基础字段 + 用户显式声明的配置字段
|
|
137
|
+
*/
|
|
138
|
+
private buildModifyParam;
|
|
139
|
+
private deepEqual;
|
|
140
|
+
/**
|
|
141
|
+
* 自动绑定自定义域名(幂等,支持证书更新)
|
|
142
|
+
*
|
|
143
|
+
* certId 解析优先级:
|
|
144
|
+
* 1. 显式配置的 certId 优先(未配置时按域名自动匹配已签发证书)
|
|
145
|
+
* 2. 域名已绑定 + 未显式 certId 或与云端一致 → 跳过绑定(幂等)
|
|
146
|
+
* 3. 域名已绑定 + 显式 certId 与云端不一致 → 重新绑定(更新证书)
|
|
147
|
+
* 4. 未绑定且无法确定 certId → 明确报错并给出操作指引
|
|
148
|
+
*/
|
|
149
|
+
private ensureDomainBound;
|
|
150
|
+
/**
|
|
151
|
+
* 查询当前环境已绑定的自定义域名列表(含证书 ID,用于幂等跳过与证书更新判断)
|
|
152
|
+
*/
|
|
153
|
+
private getBoundDomains;
|
|
154
|
+
/**
|
|
155
|
+
* 按域名自动匹配 SSL 证书 ID(腾讯云 ssl.DescribeCertificates)
|
|
156
|
+
*
|
|
157
|
+
* 匹配规则(按返回顺序取第一个):
|
|
158
|
+
* - 证书状态为已签发(Status === 1)
|
|
159
|
+
* - 证书主域名(Domain)或关联域名(SubjectAltName)包含目标域名
|
|
160
|
+
* - 证书未过期(CertEndTime 晚于当前时间)
|
|
161
|
+
* 查询失败或无匹配返回 null(由调用方给出明确报错)
|
|
162
|
+
*/
|
|
163
|
+
private resolveCertIdByDomain;
|
|
164
|
+
/**
|
|
165
|
+
* 解析路由(含异步函数类型判断 + hosting 路径重写)
|
|
166
|
+
*
|
|
167
|
+
* - function 目标:查询函数详情,HTTP 类型函数 → WEB_SCF(Web 云函数),普通函数 → SCF。
|
|
168
|
+
* 与 tcb fn deploy 部署 HTTP 函数后控制台创建路由的行为一致(控制台请求中 UpstreamResourceType=WEB_SCF)。
|
|
169
|
+
* - hosting 目标:自动生成 PathRewrite.Prefix = 对应 hosting 配置的 deployPath(控制台行为:静态托管路由必带
|
|
170
|
+
* PathRewrite.Prefix,将 /路由 前缀重写到静态托管的实际部署路径,否则请求会打到存储根路径导致 404)。
|
|
171
|
+
*/
|
|
172
|
+
private parseRouteWithType;
|
|
173
|
+
/**
|
|
174
|
+
* 映射用户 pathRewrite(camelCase)为 API 格式 HTTPServicePathRewrite(PascalCase)
|
|
175
|
+
*/
|
|
176
|
+
private mapPathRewrite;
|
|
177
|
+
/**
|
|
178
|
+
* 生成路由变更字段明细(与 routesEqual 的判定字段一致)
|
|
179
|
+
*/
|
|
180
|
+
private routeChanges;
|
|
181
|
+
/**
|
|
182
|
+
* 解析环境 HTTP 访问服务的默认域名
|
|
183
|
+
*
|
|
184
|
+
* 域名优先级:
|
|
185
|
+
* 1. Domains 列表中 DomainType=HTTPSERVICE 且 IsDefault=true 的域名(HTTP 网关默认域名)
|
|
186
|
+
* —— 注意:AI_AGENT/CBR 等类型的域名(如 agt-xxx.agent.tcloudbase.com)也可能 IsDefault=true,
|
|
187
|
+
* 但它们不是 HTTP 网关默认域名,必须结合 DomainType 过滤
|
|
188
|
+
* 2. 通过 DescribeEnvInfo 构造的默认域名 `{envId}-{uin}.{region}.app.tcloudbase.com`(兜底,覆盖 Domains 列表为空的场景——实测部分环境下 Domains 列表为空但默认域名仍存在)
|
|
189
|
+
* 3. 首个 DomainType=HTTPSERVICE 的域名
|
|
190
|
+
* 4. OriginDomain —— 回源域名(供自定义 CDN/WAF 回源使用,非对外访问地址),仅作最后兜底
|
|
191
|
+
* 查询失败或域名缺失时**明确报错**,不使用猜测的兜底域名(避免 INVALID_HOST)。
|
|
192
|
+
*/
|
|
193
|
+
private resolveDomain;
|
|
194
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/** hosting 文件指纹(hash + size;size 用于懒加载 diff 预判,避免为未变文件重复读内容) */
|
|
2
|
+
export interface IHostingFileFingerprint {
|
|
3
|
+
hash: string;
|
|
4
|
+
size: number;
|
|
5
|
+
}
|
|
6
|
+
/** 快照中指纹值:兼容旧格式(纯 string = 仅 hash,size 未知) */
|
|
7
|
+
export type HostingFileValue = string | IHostingFileFingerprint;
|
|
8
|
+
/** hosting 状态快照条目(产物指纹,不存文件内容) */
|
|
9
|
+
export interface IHostingStateEntry {
|
|
10
|
+
name: string;
|
|
11
|
+
deployPath?: string;
|
|
12
|
+
/** 相对路径 → 文件指纹(兼容旧格式:纯字符串 = 仅 hash,size 未知) */
|
|
13
|
+
files: Record<string, HostingFileValue>;
|
|
14
|
+
}
|
|
15
|
+
/** hosting 文件级 diff 结果(懒加载:size 预判 + 按需 hash) */
|
|
16
|
+
export interface IHostingFileDiff {
|
|
17
|
+
added: string[];
|
|
18
|
+
modified: string[];
|
|
19
|
+
deleted: string[];
|
|
20
|
+
totalChanged: number;
|
|
21
|
+
/** 本地与快照完全一致(可跳过部署) */
|
|
22
|
+
unchanged: boolean;
|
|
23
|
+
/** true = 文件数超过指纹上限,diff 被放弃,需降级为全量部署 */
|
|
24
|
+
overLimit?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** hosting 指纹扫描选项 */
|
|
27
|
+
export interface IHostingScanOptions {
|
|
28
|
+
/** 指纹文件数上限:超过则抛 HostingFilesOverLimitError(默认 50000;0 = 不限) */
|
|
29
|
+
maxFiles?: number;
|
|
30
|
+
/** hash 截断长度(hex 位数,默认 16;64 = 完整 sha256) */
|
|
31
|
+
hashLength?: number;
|
|
32
|
+
}
|
|
33
|
+
/** diffHostingFiles 选项(继承扫描选项,追加忽略规则) */
|
|
34
|
+
export interface IHostingDiffOptions extends IHostingScanOptions {
|
|
35
|
+
/** 自定义忽略规则(追加到默认 node_modules / .DS_Store 之后) */
|
|
36
|
+
ignore?: string[];
|
|
37
|
+
}
|
|
38
|
+
/** hosting 指纹文件数超过上限时抛出(触发降级为全量部署) */
|
|
39
|
+
export declare class HostingFilesOverLimitError extends Error {
|
|
40
|
+
fileCount: number;
|
|
41
|
+
limit: number;
|
|
42
|
+
constructor(fileCount: number, limit: number);
|
|
43
|
+
}
|
|
44
|
+
/** 默认指纹文件数上限(防快照膨胀与 I/O 失控) */
|
|
45
|
+
export declare const DEFAULT_MAX_HOSTING_FILES = 50000;
|
|
46
|
+
/** 默认 hash 截断长度(16 位 hex = 64bit,碰撞概率可忽略;快照体积减半) */
|
|
47
|
+
export declare const DEFAULT_HASH_LENGTH = 16;
|
|
48
|
+
/** app 状态快照条目(仅 diff 相关字段,不写 envVariables 等敏感信息) */
|
|
49
|
+
export interface IAppStateEntry {
|
|
50
|
+
serviceName?: string;
|
|
51
|
+
installCommand?: string;
|
|
52
|
+
buildCommand?: string;
|
|
53
|
+
outputDir?: string;
|
|
54
|
+
deployPath?: string;
|
|
55
|
+
}
|
|
56
|
+
/** 部署状态快照(.cloudbase/state.json) */
|
|
57
|
+
export interface IDeployState {
|
|
58
|
+
version: number;
|
|
59
|
+
updatedAt: string;
|
|
60
|
+
gitCommit?: string;
|
|
61
|
+
resources: {
|
|
62
|
+
hosting?: IHostingStateEntry[];
|
|
63
|
+
gateway?: unknown;
|
|
64
|
+
app?: IAppStateEntry;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
interface IStateStoreOptions {
|
|
68
|
+
/** 项目根目录(默认 process.cwd()) */
|
|
69
|
+
cwd?: string;
|
|
70
|
+
/** 环境名(--env production 等):按环境分文件 state.{env}.json */
|
|
71
|
+
env?: string;
|
|
72
|
+
/** 自定义 state 路径(优先于 cwd+env 推导) */
|
|
73
|
+
stateFile?: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 部署状态快照(StateStore)
|
|
77
|
+
*
|
|
78
|
+
* 职责:读写 `.cloudbase/state.json`(默认),为 dry-run 的 hosting/app diff 提供本地基准,
|
|
79
|
+
* 避免每次 diff 都拉取云端。
|
|
80
|
+
*
|
|
81
|
+
* 指纹算法:hosting = 产物目录逐文件内容 sha256(相对路径为 key)。
|
|
82
|
+
* 只存 hash 不存内容,体积 = O(文件数);app 快照不写入 envVariables(敏感过滤)。
|
|
83
|
+
*/
|
|
84
|
+
export declare class StateStore {
|
|
85
|
+
private cwd;
|
|
86
|
+
private env?;
|
|
87
|
+
private stateFile?;
|
|
88
|
+
constructor(options?: IStateStoreOptions);
|
|
89
|
+
/**
|
|
90
|
+
* 计算 state 文件路径:
|
|
91
|
+
* - 自定义 stateFile 优先
|
|
92
|
+
* - 否则 {cwd}/.cloudbase/state.json(无 env)或 state.{env}.json(多环境隔离)
|
|
93
|
+
*/
|
|
94
|
+
getFilePath(): string;
|
|
95
|
+
/**
|
|
96
|
+
* 读取状态快照;文件不存在或 JSON 损坏返回 null(缺失降级,由调用方走云端兜底)
|
|
97
|
+
*/
|
|
98
|
+
read(): IDeployState | null;
|
|
99
|
+
/**
|
|
100
|
+
* 写入状态快照(自动补 version/updatedAt/gitCommit,自动创建 .cloudbase 目录)
|
|
101
|
+
*/
|
|
102
|
+
write(state: {
|
|
103
|
+
resources: IDeployState['resources'];
|
|
104
|
+
gitCommit?: string;
|
|
105
|
+
}): void;
|
|
106
|
+
/**
|
|
107
|
+
* 计算产物目录逐文件 sha256 指纹(仅 hash,兼容旧调用)
|
|
108
|
+
*
|
|
109
|
+
* @param projectPath 产物目录(hosting 的 outputDir / root)
|
|
110
|
+
* @param ignore 自定义忽略规则(追加到默认 node_modules / .DS_Store 之后)
|
|
111
|
+
* @param options 扫描选项(maxFiles / hashLength)
|
|
112
|
+
* @returns 相对路径(/ 分隔)→ 文件内容 sha256(默认截断 16 位)
|
|
113
|
+
*/
|
|
114
|
+
computeHostingFiles(projectPath: string, ignore?: string[], options?: IHostingScanOptions): Promise<Record<string, string>>;
|
|
115
|
+
/**
|
|
116
|
+
* 计算产物目录逐文件指纹(hash + size)
|
|
117
|
+
*
|
|
118
|
+
* - 强制忽略 node_modules / .DS_Store(与传入 ignore 合并,不可关闭)
|
|
119
|
+
* - hash 默认截断为 16 位 hex(hashLength 可调,64 = 完整 sha256)
|
|
120
|
+
* - 文件数超过 maxFiles 抛 HostingFilesOverLimitError(防快照膨胀与 I/O 失控)
|
|
121
|
+
*
|
|
122
|
+
* @param projectPath 产物目录(hosting 的 outputDir / root)
|
|
123
|
+
* @param ignore 自定义忽略规则
|
|
124
|
+
* @param options 扫描选项(maxFiles / hashLength)
|
|
125
|
+
* @returns 相对路径(/ 分隔)→ { hash, size }
|
|
126
|
+
*/
|
|
127
|
+
computeHostingFingerprints(projectPath: string, ignore?: string[], options?: IHostingScanOptions): Promise<Record<string, IHostingFileFingerprint>>;
|
|
128
|
+
/**
|
|
129
|
+
* 计算产物目录与快照的变更集(懒加载)
|
|
130
|
+
*
|
|
131
|
+
* 优化:先 stat 拿 size,size 与快照不同的文件直接判定变更(不读文件内容),
|
|
132
|
+
* 只有 size 相同(或旧快照 size 未知)的文件才读内容 hash 对比,
|
|
133
|
+
* 避免为未变文件做无谓的 I/O 与 hash。
|
|
134
|
+
* 文件数超过 maxFiles 时放弃 diff,返回 overLimit=true(调用方应降级为全量部署)。
|
|
135
|
+
*
|
|
136
|
+
* @param projectPath 产物目录(hosting 的 outputDir / root)
|
|
137
|
+
* @param previous 上次快照指纹(undefined = 首次部署,全部视为新增)
|
|
138
|
+
* @param options 选项(ignore / maxFiles / hashLength)
|
|
139
|
+
*/
|
|
140
|
+
diffHostingFiles(projectPath: string, previous: Record<string, HostingFileValue> | undefined, options?: IHostingDiffOptions): Promise<IHostingFileDiff>;
|
|
141
|
+
/**
|
|
142
|
+
* 提取 app 配置快照(仅 diff 白名单字段)
|
|
143
|
+
* envVariables / ignore 等非 diff 字段与敏感信息不进入快照
|
|
144
|
+
*/
|
|
145
|
+
buildAppConfig(config: {
|
|
146
|
+
serviceName?: string;
|
|
147
|
+
installCommand?: string;
|
|
148
|
+
buildCommand?: string;
|
|
149
|
+
outputDir?: string;
|
|
150
|
+
deployPath?: string;
|
|
151
|
+
[key: string]: unknown;
|
|
152
|
+
}): IAppStateEntry | undefined;
|
|
153
|
+
private hashFile;
|
|
154
|
+
/** 合并默认忽略规则(node_modules / .DS_Store 不可被调用方关闭) */
|
|
155
|
+
private mergeIgnore;
|
|
156
|
+
/** 归一化快照指纹值:旧格式(纯 string = 仅 hash,size 未知用 -1 表示) */
|
|
157
|
+
private normalizeFileValue;
|
|
158
|
+
/**
|
|
159
|
+
* 是否命中忽略规则:
|
|
160
|
+
* - 目录模式(结尾 /):匹配该目录及其下所有
|
|
161
|
+
* - glob(含 **):转换为正则匹配相对路径
|
|
162
|
+
* - 其余:精确/前缀匹配
|
|
163
|
+
*/
|
|
164
|
+
private isIgnored;
|
|
165
|
+
private matchPattern;
|
|
166
|
+
private escapeRegExp;
|
|
167
|
+
/** 解析当前 git commit(非 git 仓库或失败返回 undefined,不阻断) */
|
|
168
|
+
private resolveGitCommit;
|
|
169
|
+
}
|
|
170
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Environment } from '../environment';
|
|
2
|
+
/** app 声明式配置(cloudbaserc.json app 对象) */
|
|
3
|
+
export interface IAppDeployConfig {
|
|
4
|
+
serviceName?: string;
|
|
5
|
+
root?: string;
|
|
6
|
+
framework?: string;
|
|
7
|
+
installCommand?: string;
|
|
8
|
+
buildCommand?: string;
|
|
9
|
+
outputDir?: string;
|
|
10
|
+
deployPath?: string;
|
|
11
|
+
ignore?: string[];
|
|
12
|
+
envVariables?: Record<string, string | number | boolean>;
|
|
13
|
+
}
|
|
14
|
+
/** hosting 声明式配置(cloudbaserc.json hosting[]) */
|
|
15
|
+
export interface IHostingDeployConfig {
|
|
16
|
+
name?: string;
|
|
17
|
+
root?: string;
|
|
18
|
+
/** 框架类型:显式指定或未配置时读 root/package.json 自动检测;static/custom 表示纯静态(不构建) */
|
|
19
|
+
framework?: string;
|
|
20
|
+
/** 安装命令,默认 npm install;空字符串跳过安装 */
|
|
21
|
+
installCommand?: string;
|
|
22
|
+
/** 构建命令:非空则本地构建后上传;空字符串/未配置且无法检测 → 纯静态直接上传 outputDir */
|
|
23
|
+
buildCommand?: string;
|
|
24
|
+
/** 构建产物目录:有构建时默认 dist,纯静态时默认 root */
|
|
25
|
+
outputDir?: string;
|
|
26
|
+
/** 云端部署路径(决定访问 URL 与网关 PathRewrite.Prefix) */
|
|
27
|
+
deployPath?: string;
|
|
28
|
+
ignore?: string[];
|
|
29
|
+
/** 构建时环境变量(注入本地构建进程,非敏感) */
|
|
30
|
+
envVariables?: Record<string, string | number | boolean>;
|
|
31
|
+
}
|
|
32
|
+
export interface IStaticDeployResult {
|
|
33
|
+
name: string;
|
|
34
|
+
url?: string;
|
|
35
|
+
/** 是否写入了版本记录(app 写、hosting 不写) */
|
|
36
|
+
wroteRecord: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* app/hosting 声明式部署器
|
|
40
|
+
*
|
|
41
|
+
* app:framework=static → 直传产物 + SkipBuild 写记录(对齐 tcb app deploy 纯静态分支);
|
|
42
|
+
* 其余 framework → 云端构建(上传源码 → 云端构建 → 写版本记录),与现有 tcb app deploy 一致
|
|
43
|
+
* hosting:固定静态流程(buildCommand 非空则本地构建后直传),不写版本记录(现有 tcb hosting deploy 行为)
|
|
44
|
+
*/
|
|
45
|
+
export declare class StaticDeployer {
|
|
46
|
+
private environment;
|
|
47
|
+
constructor(environment: Environment);
|
|
48
|
+
/**
|
|
49
|
+
* app 部署(与现有 tcb app deploy 一致)
|
|
50
|
+
*
|
|
51
|
+
* framework=static:直传产物(hosting uploadFiles)+ createApp(SkipBuild) 后台写部署记录,跳过云端构建。
|
|
52
|
+
* 其余 framework:上传源码 ZIP → createApp 云端构建 → 写版本记录。
|
|
53
|
+
*/
|
|
54
|
+
deployApp(options: {
|
|
55
|
+
config: IAppDeployConfig;
|
|
56
|
+
cwd?: string;
|
|
57
|
+
}): Promise<IStaticDeployResult>;
|
|
58
|
+
/**
|
|
59
|
+
* hosting 部署(固定静态流程,不写版本记录)
|
|
60
|
+
*
|
|
61
|
+
* 支持本地构建(对齐 Netlify):buildCommand 非空时自动执行 install + build 后上传产物;
|
|
62
|
+
* 纯静态(buildCommand 空/未配置且无法检测框架)时直接上传 outputDir(默认 root,保持现状)。
|
|
63
|
+
* 访问地址 = https://{CdnDomain}{deployPath}(与 tcb hosting deploy 一致)
|
|
64
|
+
*/
|
|
65
|
+
deployHosting(options: {
|
|
66
|
+
config: IHostingDeployConfig;
|
|
67
|
+
cwd?: string;
|
|
68
|
+
}): Promise<IStaticDeployResult>;
|
|
69
|
+
/**
|
|
70
|
+
* app 纯静态直传(对齐 tcb app deploy 的 deployStaticApp 分支)
|
|
71
|
+
*
|
|
72
|
+
* 1. hosting uploadFiles 直传产物(文件级上传,立即可访问,无需打 ZIP)
|
|
73
|
+
* 2. 后台异步 createApp(SkipBuild) 写部署记录(失败不影响文件访问)
|
|
74
|
+
* 3. 跳过云端构建轮询,返回访问地址
|
|
75
|
+
*/
|
|
76
|
+
private deployAppStatic;
|
|
77
|
+
/**
|
|
78
|
+
* app 云端构建:上传源码 ZIP → createApp 云端构建 → 写版本记录
|
|
79
|
+
*/
|
|
80
|
+
private deployAppCloud;
|
|
81
|
+
/**
|
|
82
|
+
* 解析 hosting 访问地址:https://{CdnDomain}{deployPath}
|
|
83
|
+
*/
|
|
84
|
+
private resolveHostingUrl;
|
|
85
|
+
/**
|
|
86
|
+
* 本地构建(install + build)
|
|
87
|
+
*
|
|
88
|
+
* - installCommand:默认 npm install,显式空字符串跳过安装
|
|
89
|
+
* - buildCommand:由调用方保证非空(hosting 经 resolveBuildCommand 判定;app local 由 if 判定)
|
|
90
|
+
* - envVariables:注入构建进程环境变量(值统一转字符串)
|
|
91
|
+
*/
|
|
92
|
+
private runLocalBuild;
|
|
93
|
+
/**
|
|
94
|
+
* 解析 app 访问地址(describeAppInfo.Domain + appPath)
|
|
95
|
+
*/
|
|
96
|
+
private resolveAppUrl;
|
|
97
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Environment } from '../environment';
|
|
2
|
+
/**
|
|
3
|
+
* 构造环境 HTTP 访问服务默认域名 `${envId}-${AppId}.${region}.${ACCESS_DOMAIN_SUFFIX}`
|
|
4
|
+
*
|
|
5
|
+
* 关键:用 `UserInfo.AppId`(腾讯云 appid)而非 `UserInfo.Uin`(账号 uin)。
|
|
6
|
+
* 控制台默认域名格式是 `${envId}-${AppId}.${region}.${ACCESS_DOMAIN_SUFFIX}`
|
|
7
|
+
* (如 `xxx-1326375956.ap-shanghai.app.tcloudbase.com`),与 cookie 中的 `appid` 字段对应。
|
|
8
|
+
* AppId/Region 缺失或查询失败时返回 undefined
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveAccessServiceDomain(environment: Environment, envId: string): Promise<string | undefined>;
|
|
11
|
+
/**
|
|
12
|
+
* 构造网关基础地址 `https://{envId}.api.tcloudbasegateway.com`
|
|
13
|
+
*
|
|
14
|
+
* 对齐 CLI 的 `EDomain.Gateway`:`isInternalEndpoint` 决定是否国际站域名
|
|
15
|
+
* (`api.intl.tcloudbasegateway.com`)。
|
|
16
|
+
*/
|
|
17
|
+
export declare function getGatewayBaseUrl(environment: Environment, envId: string): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 框架 → 默认构建命令映射(hosting 本地构建 / app 云端构建复用)
|
|
3
|
+
*/
|
|
4
|
+
export declare const FRAMEWORK_BUILD_COMMANDS: Record<string, string>;
|
|
5
|
+
/**
|
|
6
|
+
* 框架 → 默认构建产物目录映射(与 FRAMEWORK_BUILD_COMMANDS 一一对应)
|
|
7
|
+
*
|
|
8
|
+
* 注意不能全部默认 dist:
|
|
9
|
+
* - CRA(react-scripts build)实际输出 build/
|
|
10
|
+
* - next/nuxt 输出 .next/.nuxt
|
|
11
|
+
* - vite/vue 输出 dist
|
|
12
|
+
* - angular 默认 outputPath 为 dist/<项目名>,产物在子目录而非 dist/ 根目录(见 resolveAngularOutputDir),
|
|
13
|
+
* 此处 'dist' 仅作 angular.json 推导失败时的回退值
|
|
14
|
+
* 构建场景 outputDir 未显式配置时必须按此映射取产物目录,否则上传路径与构建产物不一致导致部署失败
|
|
15
|
+
* (或上传到陈旧的 dist 目录)。
|
|
16
|
+
*/
|
|
17
|
+
export declare const FRAMEWORK_OUTPUT_DIRS: Record<string, string>;
|
|
18
|
+
export interface IFrameworkConfig {
|
|
19
|
+
framework?: string;
|
|
20
|
+
buildCommand?: string;
|
|
21
|
+
}
|
|
22
|
+
/** hosting 构建产物目录解析配置 */
|
|
23
|
+
export interface IHostingOutputConfig extends IFrameworkConfig {
|
|
24
|
+
outputDir?: string;
|
|
25
|
+
}
|
|
26
|
+
/** 读取 package.json 的函数签名(测试可注入 mock,Node 20+ 下 fs 属性为只读 getter 不便 spy) */
|
|
27
|
+
export type ReadPkgFile = (filePath: string, encoding: 'utf8') => string;
|
|
28
|
+
/**
|
|
29
|
+
* 探测项目根目录下的框架类型(读 package.json 依赖)
|
|
30
|
+
* 读取失败或无匹配返回 null(按纯静态处理)
|
|
31
|
+
*/
|
|
32
|
+
export declare function detectFramework(root: string, readPkgFile?: ReadPkgFile): string | null;
|
|
33
|
+
/**
|
|
34
|
+
* 解析构建命令,优先级:
|
|
35
|
+
* 1. 显式配置 buildCommand(含空字符串,'' = 不构建)
|
|
36
|
+
* 2. 显式配置 framework → 映射推导(static/custom → null 不构建)
|
|
37
|
+
* 3. 未配置 framework → 读 package.json 自动探测框架并推导
|
|
38
|
+
* 均无法确定 → null(纯静态直接上传)
|
|
39
|
+
*/
|
|
40
|
+
export declare function resolveBuildCommand(config: IFrameworkConfig, root: string, readPkgFile?: ReadPkgFile): string | null;
|
|
41
|
+
/**
|
|
42
|
+
* 解析默认产物目录(有构建场景),优先级:
|
|
43
|
+
* 1. 显式配置 outputDir → 直接返回(调用方负责 path.resolve)
|
|
44
|
+
* 2. 显式 framework → FRAMEWORK_OUTPUT_DIRS 映射(react → build,vite/vue → dist,next → .next;
|
|
45
|
+
* angular 默认 outputPath 为 dist/<项目名>,从 angular.json 推导真实产物目录)
|
|
46
|
+
* 3. package.json 自动探测框架 → 映射推导
|
|
47
|
+
* 均无法确定(纯静态)→ null,由调用方回退到 root
|
|
48
|
+
*
|
|
49
|
+
* 与 resolveBuildCommand 共用同一份「框架探测/推导」逻辑,保证「构建产物目录」与「构建命令」来自同一次探测,
|
|
50
|
+
* 避免 CRA 场景探测到 react-scripts build(产物在 build/)却默认上传 dist 导致路径不存在。
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolveOutputDir(config: IHostingOutputConfig, root: string, readPkgFile?: ReadPkgFile): string | null;
|
|
53
|
+
/**
|
|
54
|
+
* 统一解析 hosting 上传目录(绝对路径),与 StaticDeployer.deployHosting 保持严格一致。
|
|
55
|
+
*
|
|
56
|
+
* 规则:
|
|
57
|
+
* 1) 有构建命令时:
|
|
58
|
+
* - 显式 buildCommand(自定义构建):outputDir 未配置回退 root/dist
|
|
59
|
+
* - 推导 buildCommand(framework / package.json):按 resolveOutputDir 框架映射,未命中回退 dist
|
|
60
|
+
* 2) 无构建命令时:
|
|
61
|
+
* - outputDir 未配置回退 root(纯静态直传)
|
|
62
|
+
*/
|
|
63
|
+
export declare function resolveHostingOutputDir(config: IHostingOutputConfig, root: string, readPkgFile?: ReadPkgFile): string;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ICloudFunction } from '../../interfaces';
|
|
2
|
+
import { ICodeArtifact, IFunctionArtifact, IImageArtifact, INormalizedDeployConfig, INormalizedHttpCloudConfig, INormalizedHttpImageConfig, INormalizedHttpLocalConfig } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* 部署物构造与 SCF 参数映射
|
|
5
|
+
*
|
|
6
|
+
* 四种构建策略最终都产出统一的部署物,之后走同一条 SCF 创建或更新流程
|
|
7
|
+
*/
|
|
8
|
+
/** 由本地代码来源构造代码类部署物 */
|
|
9
|
+
export declare function createCodeArtifact(config: INormalizedDeployConfig): ICodeArtifact;
|
|
10
|
+
/** 由已有镜像配置构造镜像类部署物 */
|
|
11
|
+
export declare function createImageArtifactFromConfig(config: INormalizedHttpImageConfig): IImageArtifact;
|
|
12
|
+
/**
|
|
13
|
+
* 由本地构建结果构造镜像类部署物
|
|
14
|
+
*
|
|
15
|
+
* local 策略(个人版先行)产出:镜像已由 local-builder 构建并推送,
|
|
16
|
+
* 此处仅承载最终 imageUri/digest 与容器启动配置,之后复用镜像部署链。
|
|
17
|
+
*/
|
|
18
|
+
export declare function createImageArtifactFromBuild(config: INormalizedHttpLocalConfig, build: {
|
|
19
|
+
imageUri: string;
|
|
20
|
+
imageDigest?: string;
|
|
21
|
+
}): IImageArtifact;
|
|
22
|
+
/**
|
|
23
|
+
* 由云端构建结果构造镜像类部署物
|
|
24
|
+
*
|
|
25
|
+
* cloud 策略(CloudApp custom)产出:镜像已在构建容器内 docker build + push到 TCR,
|
|
26
|
+
* 此处仅承载最终 imageUri/digest 与构建元信息(buildId/logsUrl),之后复用镜像部署链。
|
|
27
|
+
* effectiveStrategy 标记为 cloud,便于结果层如实回传实际生效的策略。
|
|
28
|
+
*/
|
|
29
|
+
export declare function createImageArtifactFromCloudBuild(config: INormalizedHttpCloudConfig, build: {
|
|
30
|
+
imageUri: string;
|
|
31
|
+
imageDigest?: string;
|
|
32
|
+
buildId?: string;
|
|
33
|
+
logsUrl?: string;
|
|
34
|
+
}): IImageArtifact;
|
|
35
|
+
/**
|
|
36
|
+
* 将部署配置与部署物映射为 FunctionService 所需的云函数配置
|
|
37
|
+
*
|
|
38
|
+
* 只映射与 SCF 相关的字段,public、gatewayPath 等访问配置由后处理阶段负责
|
|
39
|
+
*/
|
|
40
|
+
export declare function toCloudFunction(config: INormalizedDeployConfig, artifact: IFunctionArtifact): ICloudFunction;
|