@cloudbase/manager-node 5.7.0-beta.2 → 5.7.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.
Files changed (62) hide show
  1. package/jest.config.unit.js +14 -0
  2. package/lib/cloudApp/index.js +3 -12
  3. package/lib/environment.js +0 -11
  4. package/lib/function/index.js +67 -26
  5. package/lib/hosting/index.js +1 -4
  6. package/lib/index.js +0 -31
  7. package/lib/storage/index.js +7 -6
  8. package/lib/utils/index.js +1 -41
  9. package/package.json +1 -2
  10. package/types/cloudApp/index.d.ts +0 -4
  11. package/types/cloudApp/types.d.ts +6 -87
  12. package/types/env/type.d.ts +4 -4
  13. package/types/environment.d.ts +0 -7
  14. package/types/function/index.d.ts +3 -0
  15. package/types/function/types.d.ts +0 -15
  16. package/types/hosting/index.d.ts +0 -6
  17. package/types/index.d.ts +0 -18
  18. package/types/interfaces/function.interface.d.ts +1 -1
  19. package/types/storage/index.d.ts +0 -6
  20. package/types/utils/index.d.ts +0 -13
  21. package/lib/deploy/DatabaseDeployer.js +0 -238
  22. package/lib/deploy/DeployOrchestrator.js +0 -564
  23. package/lib/deploy/FunctionDeployer.js +0 -611
  24. package/lib/deploy/GatewayDeployer.js +0 -612
  25. package/lib/deploy/StateStore.js +0 -327
  26. package/lib/deploy/StaticDeployer.js +0 -335
  27. package/lib/deploy/domain.js +0 -39
  28. package/lib/deploy/framework.js +0 -105
  29. package/lib/deploy/function/artifact.js +0 -207
  30. package/lib/deploy/function/builders/cloud.js +0 -454
  31. package/lib/deploy/function/cam-preflight.js +0 -157
  32. package/lib/deploy/function/cloud-build-service.js +0 -170
  33. package/lib/deploy/function/config-guard.js +0 -588
  34. package/lib/deploy/function/docker-preflight.js +0 -87
  35. package/lib/deploy/function/image-preflight.js +0 -164
  36. package/lib/deploy/function/local-builder.js +0 -110
  37. package/lib/deploy/function/planner.js +0 -282
  38. package/lib/deploy/function/preflight.js +0 -264
  39. package/lib/deploy/types.js +0 -99
  40. package/lib/projectValidator/index.js +0 -479
  41. package/lib/projectValidator/types.js +0 -2
  42. package/types/deploy/DatabaseDeployer.d.ts +0 -70
  43. package/types/deploy/DeployOrchestrator.d.ts +0 -150
  44. package/types/deploy/FunctionDeployer.d.ts +0 -158
  45. package/types/deploy/GatewayDeployer.d.ts +0 -194
  46. package/types/deploy/StateStore.d.ts +0 -170
  47. package/types/deploy/StaticDeployer.d.ts +0 -104
  48. package/types/deploy/domain.d.ts +0 -17
  49. package/types/deploy/framework.d.ts +0 -23
  50. package/types/deploy/function/artifact.d.ts +0 -40
  51. package/types/deploy/function/builders/cloud.d.ts +0 -110
  52. package/types/deploy/function/cam-preflight.d.ts +0 -51
  53. package/types/deploy/function/cloud-build-service.d.ts +0 -10
  54. package/types/deploy/function/config-guard.d.ts +0 -41
  55. package/types/deploy/function/docker-preflight.d.ts +0 -17
  56. package/types/deploy/function/image-preflight.d.ts +0 -21
  57. package/types/deploy/function/local-builder.d.ts +0 -26
  58. package/types/deploy/function/planner.d.ts +0 -15
  59. package/types/deploy/function/preflight.d.ts +0 -9
  60. package/types/deploy/types.d.ts +0 -429
  61. package/types/projectValidator/index.d.ts +0 -43
  62. package/types/projectValidator/types.d.ts +0 -26
@@ -1,611 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.IMAGE_PULL_GRANT_URL = exports.REQUIRED_IMAGE_PULL_POLICY = exports.SCF_PULL_IMAGE_ROLE = exports.isCamPermissionError = exports.runImagePullAuthPreflight = exports.runImageRemotePreflight = exports.runLocalPreflight = exports.createCloudBuildService = exports.buildImageOnCloud = exports.toCloudFunction = exports.createImageArtifactFromConfig = exports.createCodeArtifact = exports.toCurrentState = exports.createDeployPlan = exports.parseImageReference = exports.normalizeGatewayPath = exports.normalizeDeployConfig = exports.isCustomImageRuntime = exports.checkDeployConfig = exports.assertDeployConfig = exports.FunctionDeployer = void 0;
18
- const error_1 = require("../error");
19
- const artifact_1 = require("./function/artifact");
20
- const config_guard_1 = require("./function/config-guard");
21
- const cam_preflight_1 = require("./function/cam-preflight");
22
- const cloud_1 = require("./function/builders/cloud");
23
- const cloud_build_service_1 = require("./function/cloud-build-service");
24
- const docker_preflight_1 = require("./function/docker-preflight");
25
- const GatewayDeployer_1 = require("./GatewayDeployer");
26
- const domain_1 = require("./domain");
27
- const image_preflight_1 = require("./function/image-preflight");
28
- const local_builder_1 = require("./function/local-builder");
29
- const planner_1 = require("./function/planner");
30
- const preflight_1 = require("./function/preflight");
31
- const types_1 = require("./types");
32
- /** OPA 用户策略 key */
33
- const AUTHZ_USER_REGO_KEY = 'authz.user.rego';
34
- /**
35
- * 函数部署编排器
36
- *
37
- * 统一编排 Event 与 HTTP 函数的部署流程,对上层屏蔽以下差异:
38
- * - Event 与 HTTP 的运行模型
39
- * - zip、cloud、local、image 四种构建策略
40
- * - 创建、更新与需要删除重建的场景
41
- *
42
- * 已支持代码包、已有镜像、云端构建、本地构建、匿名访问与网关路径收敛;
43
- * 未实现能力(replace 删除重建、local 企业版 TCR)会显式报错,不会静默跳过。
44
- */
45
- class FunctionDeployer {
46
- constructor(environment, deps) {
47
- var _a;
48
- this.environment = environment;
49
- this.functionService = environment.getFunctionService();
50
- this.imagePreflightDeps = deps === null || deps === void 0 ? void 0 : deps.imagePreflightDeps;
51
- this.cloudBuildServiceFactory =
52
- (_a = deps === null || deps === void 0 ? void 0 : deps.cloudBuildServiceFactory) !== null && _a !== void 0 ? _a : (() => (0, cloud_build_service_1.createCloudBuildService)(this.environment.getCloudAppService()));
53
- }
54
- /**
55
- * 兼容既有声明式部署入口
56
- *
57
- * 该方法只负责补齐声明式上下文并委托 deployFunction,避免继续维护第二套
58
- * cloud/local/image 分发逻辑。force 在旧入口中表示允许覆盖,计划阶段会自行
59
- * 判断 create/update;涉及删除重建时仍要求显式审批,不将 force 等同 allowReplace。
60
- */
61
- async deploy(options) {
62
- const { func, functionRootPath, functionPath } = options;
63
- const config = this.withLegacyDeployContext(func, functionRootPath, functionPath);
64
- const result = await this.deployFunction(config);
65
- return {
66
- name: result.functionName,
67
- url: await this.resolveUrl(config)
68
- };
69
- }
70
- /** 解析最终部署策略:显式 buildStrategy 优先,未配置默认 zip */
71
- resolveStrategy(config) {
72
- return config.type === 'HTTP' && config.buildStrategy
73
- ? config.buildStrategy
74
- : 'zip';
75
- }
76
- /**
77
- * 配置 HTTP 函数匿名访问(public=true)
78
- * 通过 OPA Rego 策略追加匿名放通规则,不覆盖用户已有策略
79
- */
80
- async ensurePublicAccess(functionName) {
81
- const permissionService = this.environment.getPermissionService();
82
- const { Item } = await permissionService.describeEnvAuthzConfig({
83
- key: AUTHZ_USER_REGO_KEY
84
- });
85
- const currentRego = (Item === null || Item === void 0 ? void 0 : Item.Value) || '';
86
- if (currentRego.includes(`resource_name == "${functionName}"`)) {
87
- return;
88
- }
89
- const rule = this.buildPublicAccessRego(functionName);
90
- const mergedRego = currentRego.trim() ? `${currentRego.trim()}\n\n${rule}` : rule;
91
- await permissionService.modifyEnvAuthzConfig({
92
- key: AUTHZ_USER_REGO_KEY,
93
- value: mergedRego
94
- });
95
- }
96
- /**
97
- * 收敛 HTTP 函数网关路由(gatewayPath 配置)
98
- *
99
- * 幂等:云端不存在该 path → 创建;已存在且一致 → 跳过;不一致 → 更新。
100
- * 复用 GatewayDeployer 的幂等收敛与默认域名解析逻辑,与 gateway.routes 声明式部署行为一致。
101
- * 返回该函数网关访问 URL(与 resolveUrl 解析结果一致),无 envId 时返回 undefined。
102
- */
103
- async ensureGatewayRoute(config) {
104
- var _a;
105
- if (config.type !== 'HTTP' || !config.gatewayPath) {
106
- return undefined;
107
- }
108
- const envId = this.environment.getEnvId();
109
- if (!envId) {
110
- return undefined;
111
- }
112
- const result = await new GatewayDeployer_1.GatewayDeployer(this.environment).deploy({
113
- routes: [
114
- {
115
- path: config.gatewayPath,
116
- target: `function:${config.name}`
117
- }
118
- ],
119
- envId
120
- });
121
- return (_a = result.routes.find(route => route.path === config.gatewayPath)) === null || _a === void 0 ? void 0 : _a.url;
122
- }
123
- /** 生成匿名访问 OPA Rego 规则 */
124
- buildPublicAccessRego(functionName) {
125
- return [
126
- `# 自动生成:放通匿名用户访问云函数 ${functionName}(public: true)`,
127
- 'allow if {',
128
- ' input.cloudbase.resource_type == "functions"',
129
- ` input.cloudbase.resource_name == "${functionName}"`,
130
- ' input.subject.auth_type == "anonymous"',
131
- '}'
132
- ].join('\n');
133
- }
134
- /** 生成 HTTP 函数可访问 URL */
135
- async resolveUrl(config) {
136
- if (config.type !== 'HTTP') {
137
- return undefined;
138
- }
139
- let envId;
140
- try {
141
- envId = this.environment.getEnvId();
142
- }
143
- catch (_a) {
144
- return undefined;
145
- }
146
- if (!envId) {
147
- return undefined;
148
- }
149
- const pathValue = config.path || config.gatewayPath;
150
- // 推荐方式:通过 API 网关调用云函数(无需配置访问服务)
151
- const recommendedUrl = `${(0, domain_1.getGatewayBaseUrl)(this.environment, envId)}/v1/functions/${config.name}`;
152
- if (!pathValue) {
153
- return recommendedUrl;
154
- }
155
- // 配了访问服务(path / gatewayPath)→ 环境 HTTP 访问服务默认域名 + 路径
156
- const domain = await (0, domain_1.resolveAccessServiceDomain)(this.environment, envId);
157
- if (domain) {
158
- return `https://${domain}/${pathValue.replace(/^\//, '')}`;
159
- }
160
- // getEnvInfo 失败时退化为推荐方式,保证地址可访问
161
- return recommendedUrl;
162
- }
163
- /**
164
- * 校验部署配置
165
- *
166
- * 只做纯函数、无 IO 的配置契约校验,一次返回全部问题
167
- */
168
- checkConfig(config) {
169
- return (0, config_guard_1.checkDeployConfig)(config);
170
- }
171
- /**
172
- * 生成部署计划
173
- *
174
- * 会查询线上函数状态,用于判断创建、更新或删除重建
175
- */
176
- async plan(config) {
177
- const normalized = (0, config_guard_1.assertDeployConfig)(config);
178
- const current = await this.getCurrentFunction(normalized.name, normalized.codeSecret);
179
- return (0, planner_1.createDeployPlan)(normalized, current);
180
- }
181
- /**
182
- * 部署前本地环境检查(有 IO)
183
- *
184
- * 与 checkConfig 不同,本方法会读取文件系统,目前覆盖 HTTP 代码包所需的
185
- * scf_bootstrap 等文件条件。先做配置契约校验,再执行本地检查。
186
- */
187
- preflight(config) {
188
- const normalized = (0, config_guard_1.assertDeployConfig)(config);
189
- return (0, preflight_1.runLocalPreflight)(normalized);
190
- }
191
- /**
192
- * 部署函数
193
- * @param config 部署配置
194
- * @param options 部署选项,dryRun 时只生成计划不做任何变更
195
- */
196
- async deployFunction(config, options = {}) {
197
- const startTime = Date.now();
198
- const ctx = { steps: [], options };
199
- const warnings = [];
200
- const report = (0, config_guard_1.checkDeployConfig)(config);
201
- report.checks
202
- .filter(item => item.status === 'warn')
203
- .forEach(item => warnings.push(`[${item.id}] ${item.summary}`));
204
- const normalized = await this.runStep(ctx, 'validate', async () => {
205
- return (0, config_guard_1.assertDeployConfig)(config);
206
- });
207
- const plan = await this.runStep(ctx, 'plan', async () => {
208
- const current = await this.getCurrentFunction(normalized.name, normalized.codeSecret);
209
- return (0, planner_1.createDeployPlan)(normalized, current);
210
- });
211
- if (options.dryRun) {
212
- return await this.buildResult({
213
- config: normalized,
214
- plan,
215
- steps: ctx.steps,
216
- warnings,
217
- startTime,
218
- dryRun: true
219
- });
220
- }
221
- await this.runStep(ctx, 'preflight', async () => {
222
- const report = (0, preflight_1.runLocalPreflight)(normalized);
223
- report.checks
224
- .filter(item => item.status === 'warn')
225
- .forEach(item => warnings.push(`[${item.id}] ${item.summary}`));
226
- this.assertPreflightReady(report);
227
- });
228
- await this.runStep(ctx, 'preflight', async () => {
229
- const report = await (0, cam_preflight_1.runImagePullAuthPreflight)(this.createCamPreflightAdapter(), normalized, options.autoGrant !== false);
230
- report.checks
231
- .filter(item => item.status === 'warn')
232
- .forEach(item => warnings.push(`[${item.id}] ${item.summary}`));
233
- this.assertPreflightReady(report);
234
- });
235
- await this.runStep(ctx, 'preflight', async () => {
236
- const report = await (0, image_preflight_1.runImageRemotePreflight)(normalized, this.resolveDeployRegion(), this.imagePreflightDeps);
237
- report.checks
238
- .filter(item => item.status === 'warn')
239
- .forEach(item => warnings.push(`[${item.id}] ${item.summary}`));
240
- this.assertPreflightReady(report);
241
- });
242
- this.assertPlanExecutable(normalized, plan, options);
243
- // noop:函数本身无变更,但仍可能需要收敛访问配置
244
- if (plan.action === 'noop') {
245
- await this.applyAccessPlan(ctx, normalized, plan);
246
- return await this.buildResult({
247
- config: normalized,
248
- plan,
249
- steps: ctx.steps,
250
- warnings,
251
- startTime,
252
- dryRun: false
253
- });
254
- }
255
- const artifact = await this.prepareArtifact(ctx, normalized, warnings);
256
- await this.applyPlan(ctx, { config: normalized, plan, artifact });
257
- await this.applyAccessPlan(ctx, normalized, plan);
258
- return await this.buildResult({
259
- config: normalized,
260
- plan,
261
- steps: ctx.steps,
262
- warnings,
263
- startTime,
264
- dryRun: false,
265
- artifact
266
- });
267
- }
268
- /**
269
- * 将既有声明式调用补齐为完整部署配置
270
- */
271
- withLegacyDeployContext(func, functionRootPath, functionPath) {
272
- var _a, _b;
273
- const config = Object.assign({}, func);
274
- const strategy = this.resolveStrategy(config);
275
- if (functionPath) {
276
- config.functionPath = functionPath;
277
- delete config.functionRootPath;
278
- }
279
- else if (functionRootPath && !config.functionRootPath && !config.functionPath) {
280
- config.functionRootPath = functionRootPath;
281
- }
282
- if (strategy === 'cloud' || strategy === 'local') {
283
- const effectiveFunctionRootPath = functionRootPath || config.functionRootPath;
284
- const buildCwd = functionPath ||
285
- (functionRootPath ? `${functionRootPath}/${config.name}` : undefined) ||
286
- config.functionPath ||
287
- (effectiveFunctionRootPath
288
- ? `${effectiveFunctionRootPath}/${config.name}`
289
- : undefined);
290
- if (buildCwd || ((_a = config.build) === null || _a === void 0 ? void 0 : _a.cwd)) {
291
- config.build = Object.assign(Object.assign({}, (config.build || {})), { cwd: ((_b = config.build) === null || _b === void 0 ? void 0 : _b.cwd) || buildCwd });
292
- }
293
- }
294
- // 兼容旧声明式 imageUri 字段,统一转换到运行时 imageConfig 契约
295
- if (strategy === 'image' && config.imageUri && !config.imageConfig) {
296
- config.imageType = config.imageType || 'personal';
297
- config.imageConfig = {
298
- imageUri: config.imageUri
299
- };
300
- delete config.imageUri;
301
- }
302
- return config;
303
- }
304
- /**
305
- * 解析函数部署地域,供镜像远端地域校验使用
306
- *
307
- * 地域来源于 environment 的鉴权配置;未显式配置时返回 undefined,
308
- * 由image-preflight 自动跳过地域校验,不误报。
309
- */
310
- resolveDeployRegion() {
311
- try {
312
- return this.environment.getAuthConfig().region;
313
- }
314
- catch (_a) {
315
- return undefined;
316
- }
317
- }
318
- /**
319
- * 构造镜像拉取授权 Preflight 所需的 CAM 适配器
320
- *
321
- * 用 CommonService 走 CAM 通道:ListAttachedRolePolicies 读已绑策略、
322
- * AttachRolePolicies 按策略名绑定。任何权限/网络错误都原样抛出,
323
- * 交由 cam-preflight 判定并降级,本层不吞异常。
324
- */
325
- createCamPreflightAdapter() {
326
- const cam = this.environment.getCommonService('cam', undefined);
327
- return {
328
- getRoleWithPolicies: async (roleName) => {
329
- const res = await cam.call({
330
- Action: 'ListAttachedRolePolicies',
331
- Param: { Page: 1, Rp: 200, RoleName: roleName }
332
- });
333
- const list = (res === null || res === void 0 ? void 0 : res.List) || [];
334
- return {
335
- RoleName: roleName,
336
- attachedPolicyNames: list
337
- .map(item => item === null || item === void 0 ? void 0 : item.PolicyName)
338
- .filter((name) => typeof name === 'string')
339
- };
340
- },
341
- attachPolicyByName: async (roleName, policyName) => {
342
- await cam.call({
343
- Action: 'AttachRolePolicies',
344
- Param: { AttachRoleName: roleName, PolicyName: [policyName] }
345
- });
346
- }
347
- };
348
- }
349
- /** 查询线上函数详情,不存在时返回 null */
350
- async getCurrentFunction(name, codeSecret) {
351
- try {
352
- return await this.functionService.getFunctionDetail(name, codeSecret);
353
- }
354
- catch (error) {
355
- if (this.isFunctionNotFoundError(error)) {
356
- return null;
357
- }
358
- throw error;
359
- }
360
- }
361
- /** 判断是否为函数不存在错误,其他错误必须继续抛出 */
362
- isFunctionNotFoundError(error) {
363
- var _a, _b;
364
- const code = (error === null || error === void 0 ? void 0 : error.code) || ((_b = (_a = error === null || error === void 0 ? void 0 : error.original) === null || _a === void 0 ? void 0 : _a.Error) === null || _b === void 0 ? void 0 : _b.Code) || '';
365
- return typeof code === 'string' && code.startsWith('ResourceNotFound');
366
- }
367
- /**
368
- * 校验 Preflight 报告,存在 fail 项时聚合抛错
369
- */
370
- assertPreflightReady(report) {
371
- if (report.ready) {
372
- return;
373
- }
374
- const failures = report.checks.filter(item => item.status === 'fail');
375
- const message = failures
376
- .map(item => {
377
- const remediation = item.remediation ? `,${item.remediation}` : '';
378
- return `- [${item.id}] ${item.summary}${remediation}`;
379
- })
380
- .join('\n');
381
- throw new error_1.CloudBaseError(`部署前检查未通过:\n${message}`, {
382
- code: failures[0].id
383
- });
384
- }
385
- /**
386
- * 判断计划是否可以在当前实现范围内执行
387
- *
388
- * 未实现的能力必须显式报错,避免用户误认为访问规则或镜像构建已经生效
389
- */
390
- assertPlanExecutable(config, plan, options) {
391
- if (plan.requiresReplaceApproval && !options.allowReplace) {
392
- throw new error_1.CloudBaseError(`函数 ${plan.functionName} 存在无法原地更新的变更,需要删除后重建:\n` +
393
- plan.replaceReasons.map(reason => `- ${reason}`).join('\n') +
394
- '\n如确认可以中断服务并接受触发器等配置需要重新设置,请显式设置 allowReplace', { code: types_1.FUNCTION_DEPLOY_ERROR.REPLACE_NOT_APPROVED });
395
- }
396
- if (plan.action === 'replace') {
397
- throw new error_1.CloudBaseError('删除重建流程尚未实现,需要先完成触发器与访问配置的保存与恢复', { code: types_1.FUNCTION_DEPLOY_ERROR.NOT_IMPLEMENTED });
398
- }
399
- // local 个人版先行已支持;企业版 TCR 增强后置,暂未实现
400
- if (config.buildStrategy === 'local' && config.imageType === 'enterprise') {
401
- throw new error_1.CloudBaseError('local 策略的企业版 TCR 构建推送尚未实现,当前支持个人版镜像仓库(不指定 imageType 或 personal)', { code: types_1.FUNCTION_DEPLOY_ERROR.NOT_IMPLEMENTED });
402
- }
403
- }
404
- /**
405
- * 准备部署物
406
- *
407
- * cloud 策略在云端构建容器内build+push,产出镜像部署物(不依赖本地 Docker);
408
- * local 策略需要先做 Docker 本地能力检查,再本地构建并推送镜像,产出镜像部署物;
409
- * 其余策略走同步的 pack。
410
- */
411
- async prepareArtifact(ctx, config, warnings) {
412
- if (config.buildStrategy === 'cloud') {
413
- const cloudConfig = config;
414
- const buildResult = await this.runStep(ctx, 'build', async () => {
415
- const cloudBuildService = this.cloudBuildServiceFactory();
416
- return (0, cloud_1.buildImageOnCloud)(cloudConfig, cloudBuildService, {
417
- onLog: line => this.emitProgress(ctx.options, {
418
- stage: 'build',
419
- status: 'start',
420
- message: line
421
- }),
422
- region: this.resolveDeployRegion()
423
- });
424
- });
425
- return (0, artifact_1.createImageArtifactFromCloudBuild)(config, buildResult);
426
- }
427
- if (config.buildStrategy === 'local') {
428
- await this.runStep(ctx, 'preflight', async () => {
429
- const report = await (0, docker_preflight_1.runDockerPreflight)();
430
- report.checks
431
- .filter(item => item.status === 'warn')
432
- .forEach(item => warnings.push(`[${item.id}] ${item.summary}`));
433
- this.assertPreflightReady(report);
434
- });
435
- const localConfig = config;
436
- const buildResult = await this.runStep(ctx, 'build', async () => {
437
- return (0, local_builder_1.buildAndPushImage)(localConfig, line => this.emitProgress(ctx.options, { stage: 'build', status: 'start', message: line }));
438
- });
439
- return (0, artifact_1.createImageArtifactFromBuild)(config, buildResult);
440
- }
441
- return this.runStep(ctx, 'pack', async () => {
442
- return this.createArtifact(config);
443
- });
444
- }
445
- /** 生成部署物 */
446
- createArtifact(config) {
447
- if (config.buildStrategy === 'image') {
448
- return (0, artifact_1.createImageArtifactFromConfig)(config);
449
- }
450
- return (0, artifact_1.createCodeArtifact)(config);
451
- }
452
- /** 执行部署计划 */
453
- async applyPlan(ctx, params) {
454
- const { config, plan, artifact } = params;
455
- // noop:线上与目标一致,不调用任何 SCF 变更接口
456
- if (plan.action === 'noop') {
457
- return;
458
- }
459
- const func = (0, artifact_1.toCloudFunction)(config, artifact);
460
- const codeParams = artifact.kind === 'code'
461
- ? {
462
- functionRootPath: artifact.functionRootPath,
463
- functionPath: artifact.functionPath,
464
- base64Code: artifact.base64Code
465
- }
466
- : {};
467
- if (plan.action === 'create') {
468
- await this.runStep(ctx, 'deploy-function', async () => {
469
- await this.functionService.createFunction(Object.assign(Object.assign({ func }, codeParams), { codeSecret: config.codeSecret, deployMode: artifact.deployMode,
470
- // 计划阶段已确认函数不存在,此处不覆盖同名函数,避免并发场景误删
471
- force: false }));
472
- });
473
- await this.runStep(ctx, 'wait-active', async () => {
474
- await this.functionService.waitFunctionActive(config.name, config.codeSecret);
475
- });
476
- return;
477
- }
478
- await this.runStep(ctx, 'deploy-function', async () => {
479
- await this.functionService.updateFunctionCode(Object.assign(Object.assign({ func }, codeParams), { codeSecret: config.codeSecret, deployMode: artifact.deployMode }));
480
- });
481
- await this.runStep(ctx, 'wait-active', async () => {
482
- await this.functionService.waitFunctionActive(config.name, config.codeSecret);
483
- });
484
- await this.runStep(ctx, 'deploy-function', async () => {
485
- await this.functionService.updateFunctionConfig(func);
486
- });
487
- await this.runStep(ctx, 'wait-active', async () => {
488
- await this.functionService.waitFunctionActive(config.name, config.codeSecret);
489
- });
490
- }
491
- /** 收敛 HTTP 函数访问配置(匿名访问 + 网关路由) */
492
- async applyAccessPlan(ctx, config, plan) {
493
- if (config.type !== 'HTTP') {
494
- return;
495
- }
496
- if (config.public === true && plan.operations.includes('configure-access')) {
497
- await this.runStep(ctx, 'configure-access', async () => {
498
- await this.ensurePublicAccess(config.name);
499
- });
500
- }
501
- if (plan.operations.includes('configure-gateway')) {
502
- await this.runStep(ctx, 'configure-gateway', async () => {
503
- await this.ensureGatewayRoute(config);
504
- });
505
- }
506
- }
507
- /** 执行单个步骤并记录耗时与进度 */
508
- async runStep(ctx, stage, handler) {
509
- const startTime = Date.now();
510
- this.emitProgress(ctx.options, { stage, status: 'start' });
511
- try {
512
- const result = await handler();
513
- ctx.steps.push({ stage, status: 'success', elapsedTime: Date.now() - startTime });
514
- this.emitProgress(ctx.options, { stage, status: 'success' });
515
- return result;
516
- }
517
- catch (error) {
518
- ctx.steps.push({
519
- stage,
520
- status: 'failed',
521
- elapsedTime: Date.now() - startTime,
522
- detail: error === null || error === void 0 ? void 0 : error.message
523
- });
524
- this.emitProgress(ctx.options, { stage, status: 'failed', message: error === null || error === void 0 ? void 0 : error.message });
525
- throw error;
526
- }
527
- }
528
- /** 上报进度,回调异常不影响部署流程 */
529
- emitProgress(options, event) {
530
- if (typeof options.onProgress !== 'function') {
531
- return;
532
- }
533
- try {
534
- options.onProgress(event);
535
- }
536
- catch (error) {
537
- // 进度回调由调用方提供,异常不应影响部署结果
538
- }
539
- }
540
- /** 汇总部署结果 */
541
- async buildResult(params) {
542
- const { config, plan, steps, warnings, startTime, dryRun, artifact } = params;
543
- const result = {
544
- functionName: config.name,
545
- functionType: config.type,
546
- requestedStrategy: config.buildStrategy,
547
- effectiveStrategy: (artifact === null || artifact === void 0 ? void 0 : artifact.kind) === 'image' ? artifact.effectiveStrategy : config.buildStrategy,
548
- action: plan.action,
549
- operations: plan.operations,
550
- dryRun,
551
- elapsedTime: Date.now() - startTime,
552
- steps,
553
- warnings,
554
- plan
555
- };
556
- if ((artifact === null || artifact === void 0 ? void 0 : artifact.kind) === 'image') {
557
- result.imageUri = artifact.imageUri;
558
- if (artifact.imageDigest !== undefined) {
559
- result.imageDigest = artifact.imageDigest;
560
- }
561
- if (artifact.buildId !== undefined) {
562
- result.buildId = artifact.buildId;
563
- }
564
- }
565
- if (config.type === 'HTTP') {
566
- result.public = config.public;
567
- result.gatewayUrl = await this.resolveUrl(config);
568
- }
569
- if (!dryRun) {
570
- this.emitProgressDone(params);
571
- }
572
- return result;
573
- }
574
- emitProgressDone(params) {
575
- params.steps.push({
576
- stage: 'done',
577
- status: 'success',
578
- elapsedTime: Date.now() - params.startTime
579
- });
580
- }
581
- }
582
- exports.FunctionDeployer = FunctionDeployer;
583
- __exportStar(require("./types"), exports);
584
- var config_guard_2 = require("./function/config-guard");
585
- Object.defineProperty(exports, "assertDeployConfig", { enumerable: true, get: function () { return config_guard_2.assertDeployConfig; } });
586
- Object.defineProperty(exports, "checkDeployConfig", { enumerable: true, get: function () { return config_guard_2.checkDeployConfig; } });
587
- Object.defineProperty(exports, "isCustomImageRuntime", { enumerable: true, get: function () { return config_guard_2.isCustomImageRuntime; } });
588
- Object.defineProperty(exports, "normalizeDeployConfig", { enumerable: true, get: function () { return config_guard_2.normalizeDeployConfig; } });
589
- Object.defineProperty(exports, "normalizeGatewayPath", { enumerable: true, get: function () { return config_guard_2.normalizeGatewayPath; } });
590
- Object.defineProperty(exports, "parseImageReference", { enumerable: true, get: function () { return config_guard_2.parseImageReference; } });
591
- var planner_2 = require("./function/planner");
592
- Object.defineProperty(exports, "createDeployPlan", { enumerable: true, get: function () { return planner_2.createDeployPlan; } });
593
- Object.defineProperty(exports, "toCurrentState", { enumerable: true, get: function () { return planner_2.toCurrentState; } });
594
- var artifact_2 = require("./function/artifact");
595
- Object.defineProperty(exports, "createCodeArtifact", { enumerable: true, get: function () { return artifact_2.createCodeArtifact; } });
596
- Object.defineProperty(exports, "createImageArtifactFromConfig", { enumerable: true, get: function () { return artifact_2.createImageArtifactFromConfig; } });
597
- Object.defineProperty(exports, "toCloudFunction", { enumerable: true, get: function () { return artifact_2.toCloudFunction; } });
598
- var cloud_2 = require("./function/builders/cloud");
599
- Object.defineProperty(exports, "buildImageOnCloud", { enumerable: true, get: function () { return cloud_2.buildImageOnCloud; } });
600
- var cloud_build_service_2 = require("./function/cloud-build-service");
601
- Object.defineProperty(exports, "createCloudBuildService", { enumerable: true, get: function () { return cloud_build_service_2.createCloudBuildService; } });
602
- var preflight_2 = require("./function/preflight");
603
- Object.defineProperty(exports, "runLocalPreflight", { enumerable: true, get: function () { return preflight_2.runLocalPreflight; } });
604
- var image_preflight_2 = require("./function/image-preflight");
605
- Object.defineProperty(exports, "runImageRemotePreflight", { enumerable: true, get: function () { return image_preflight_2.runImageRemotePreflight; } });
606
- var cam_preflight_2 = require("./function/cam-preflight");
607
- Object.defineProperty(exports, "runImagePullAuthPreflight", { enumerable: true, get: function () { return cam_preflight_2.runImagePullAuthPreflight; } });
608
- Object.defineProperty(exports, "isCamPermissionError", { enumerable: true, get: function () { return cam_preflight_2.isCamPermissionError; } });
609
- Object.defineProperty(exports, "SCF_PULL_IMAGE_ROLE", { enumerable: true, get: function () { return cam_preflight_2.SCF_PULL_IMAGE_ROLE; } });
610
- Object.defineProperty(exports, "REQUIRED_IMAGE_PULL_POLICY", { enumerable: true, get: function () { return cam_preflight_2.REQUIRED_IMAGE_PULL_POLICY; } });
611
- Object.defineProperty(exports, "IMAGE_PULL_GRANT_URL", { enumerable: true, get: function () { return cam_preflight_2.IMAGE_PULL_GRANT_URL; } });