@cloudbase/manager-node 5.8.3 → 5.8.4
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 +9 -0
- package/lib/deploy/DeployOrchestrator.js +165 -287
- package/lib/deploy/FunctionDeployer.js +61 -33
- package/lib/deploy/function/artifact.js +55 -41
- package/lib/deploy/function/builders/cloud.js +13 -11
- package/lib/deploy/function/cam-preflight.js +2 -1
- package/lib/deploy/function/config-guard.js +181 -36
- package/lib/deploy/function/enterprise-tcr.js +7 -6
- package/lib/deploy/function/local-builder.js +10 -9
- package/lib/deploy/function/preflight.js +3 -2
- package/lib/projectValidator/index.js +0 -3
- package/package.json +1 -1
- package/types/deploy/DeployOrchestrator.d.ts +9 -25
- package/types/deploy/FunctionDeployer.d.ts +15 -1
- package/types/deploy/function/artifact.d.ts +0 -5
- package/types/deploy/function/config-guard.d.ts +18 -0
- package/types/deploy/function/enterprise-tcr.d.ts +2 -2
- package/types/deploy/types.d.ts +76 -20
- package/types/projectValidator/types.d.ts +0 -1
- package/lib/deploy/StateStore.js +0 -328
- package/types/deploy/StateStore.d.ts +0 -174
|
@@ -6,6 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.parseImageReference = parseImageReference;
|
|
7
7
|
exports.normalizeGatewayPath = normalizeGatewayPath;
|
|
8
8
|
exports.isCustomImageRuntime = isCustomImageRuntime;
|
|
9
|
+
exports.applyMinimalDeployConfigDefaults = applyMinimalDeployConfigDefaults;
|
|
10
|
+
exports.getMissingDeployInputs = getMissingDeployInputs;
|
|
11
|
+
exports.prepareMinimalDeployConfig = prepareMinimalDeployConfig;
|
|
9
12
|
exports.normalizeDeployConfig = normalizeDeployConfig;
|
|
10
13
|
exports.checkDeployConfig = checkDeployConfig;
|
|
11
14
|
exports.assertDeployConfig = assertDeployConfig;
|
|
@@ -163,18 +166,151 @@ function inferHttpBuildStrategy(config) {
|
|
|
163
166
|
if (config === null || config === void 0 ? void 0 : config.buildStrategy) {
|
|
164
167
|
return config.buildStrategy;
|
|
165
168
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
if (config === null || config === void 0 ? void 0 : config.build) {
|
|
169
|
+
const imageConfig = config === null || config === void 0 ? void 0 : config.imageConfig;
|
|
170
|
+
if (imageConfig === null || imageConfig === void 0 ? void 0 : imageConfig.build) {
|
|
170
171
|
// 有构建上下文但未声明策略时,默认使用无需本地 Docker 的云端构建
|
|
171
172
|
return 'cloud';
|
|
172
173
|
}
|
|
174
|
+
if (imageConfig === null || imageConfig === void 0 ? void 0 : imageConfig.imageUri) {
|
|
175
|
+
return 'image';
|
|
176
|
+
}
|
|
173
177
|
if (isCustomImageRuntime(config === null || config === void 0 ? void 0 : config.runtime)) {
|
|
174
178
|
return 'image';
|
|
175
179
|
}
|
|
176
180
|
return 'zip';
|
|
177
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* 应用最小化镜像配置的可安全默认值,不执行 IO,不生成凭证。
|
|
184
|
+
* 仅填充构建上下文、仓库名、namespace 和运行时固定值;用户凭证必须显式传入。
|
|
185
|
+
*
|
|
186
|
+
* 直接在 cloudbaserc 的嵌套形状上操作:镜像字段位于 imageConfig,构建目标位于
|
|
187
|
+
* imageConfig.build,不再做字段平铺映射。
|
|
188
|
+
*/
|
|
189
|
+
function applyMinimalDeployConfigDefaults(config, context = {}) {
|
|
190
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
191
|
+
const result = lodash_1.default.cloneDeep(config);
|
|
192
|
+
if ((result === null || result === void 0 ? void 0 : result.type) !== 'HTTP') {
|
|
193
|
+
return result;
|
|
194
|
+
}
|
|
195
|
+
const strategy = inferHttpBuildStrategy(result);
|
|
196
|
+
if (!['image', 'local', 'cloud'].includes(strategy)) {
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
result.buildStrategy = strategy;
|
|
200
|
+
const imageConfig = Object.assign({}, (result.imageConfig || {}));
|
|
201
|
+
result.imageConfig = imageConfig;
|
|
202
|
+
if (strategy === 'image') {
|
|
203
|
+
if (imageConfig.imageUri === undefined && ((_a = context.defaults) === null || _a === void 0 ? void 0 : _a.imageUri) !== undefined) {
|
|
204
|
+
imageConfig.imageUri = context.defaults.imageUri;
|
|
205
|
+
}
|
|
206
|
+
return result;
|
|
207
|
+
}
|
|
208
|
+
if (result.runtime === undefined) {
|
|
209
|
+
result.runtime = types_1.CUSTOM_IMAGE_RUNTIME;
|
|
210
|
+
}
|
|
211
|
+
if (imageConfig.imagePort === undefined) {
|
|
212
|
+
imageConfig.imagePort = types_1.IMAGE_FUNCTION_PORT;
|
|
213
|
+
}
|
|
214
|
+
const build = Object.assign({}, (imageConfig.build || {}));
|
|
215
|
+
imageConfig.build = build;
|
|
216
|
+
const functionPath = context.functionPath ||
|
|
217
|
+
(context.functionRootPath && result.name ? `${context.functionRootPath}/${result.name}` : undefined);
|
|
218
|
+
if (build.cwd === undefined && functionPath) {
|
|
219
|
+
build.cwd = functionPath;
|
|
220
|
+
}
|
|
221
|
+
if (build.dockerfile === undefined) {
|
|
222
|
+
build.dockerfile = types_1.DEFAULT_DOCKERFILE;
|
|
223
|
+
}
|
|
224
|
+
if (build.platform === undefined) {
|
|
225
|
+
build.platform = types_1.DEFAULT_IMAGE_PLATFORM;
|
|
226
|
+
}
|
|
227
|
+
const defaultRepository = (_c = (_b = context.defaults) === null || _b === void 0 ? void 0 : _b.repository) !== null && _c !== void 0 ? _c : result.name;
|
|
228
|
+
const defaultNamespace = (_e = (_d = context.defaults) === null || _d === void 0 ? void 0 : _d.namespace) !== null && _e !== void 0 ? _e : context.envId;
|
|
229
|
+
if (build.repository === undefined && defaultRepository !== undefined) {
|
|
230
|
+
build.repository = defaultRepository;
|
|
231
|
+
}
|
|
232
|
+
if (build.namespace === undefined && defaultNamespace !== undefined) {
|
|
233
|
+
build.namespace = defaultNamespace;
|
|
234
|
+
}
|
|
235
|
+
if (imageConfig.registryId === undefined && ((_f = context.defaults) === null || _f === void 0 ? void 0 : _f.registryId) !== undefined) {
|
|
236
|
+
imageConfig.registryId = context.defaults.registryId;
|
|
237
|
+
}
|
|
238
|
+
if (build.registryCredential === undefined && ((_g = context.defaults) === null || _g === void 0 ? void 0 : _g.registryCredential) !== undefined) {
|
|
239
|
+
build.registryCredential = lodash_1.default.cloneDeep(context.defaults.registryCredential);
|
|
240
|
+
}
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* 返回最小化部署在当前配置下仍缺失的输入字段;不执行网络、文件或凭证操作。
|
|
245
|
+
*/
|
|
246
|
+
function getMissingDeployInputs(config, context = {}) {
|
|
247
|
+
var _a, _b, _c;
|
|
248
|
+
const normalized = lodash_1.default.cloneDeep(config);
|
|
249
|
+
const missing = [];
|
|
250
|
+
if ((normalized === null || normalized === void 0 ? void 0 : normalized.type) !== 'HTTP') {
|
|
251
|
+
return missing;
|
|
252
|
+
}
|
|
253
|
+
const strategy = (_a = normalized.buildStrategy) !== null && _a !== void 0 ? _a : inferHttpBuildStrategy(normalized);
|
|
254
|
+
if (!['image', 'local', 'cloud'].includes(strategy)) {
|
|
255
|
+
return missing;
|
|
256
|
+
}
|
|
257
|
+
const imageConfig = normalized.imageConfig || {};
|
|
258
|
+
if (strategy === 'image') {
|
|
259
|
+
if (!imageConfig.imageUri) {
|
|
260
|
+
missing.push({ name: 'imageUri', path: 'imageConfig.imageUri', required: true, reason: '已有镜像部署需要固定 tag 或 digest 的 imageUri' });
|
|
261
|
+
}
|
|
262
|
+
return missing;
|
|
263
|
+
}
|
|
264
|
+
const build = imageConfig.build || {};
|
|
265
|
+
const imageType = imageConfig.imageType || (imageConfig.registryId || build.registryId ? 'enterprise' : 'personal');
|
|
266
|
+
if (imageType === 'enterprise') {
|
|
267
|
+
if (!imageConfig.registryId && !build.registryId) {
|
|
268
|
+
missing.push({ name: 'registryId', path: 'imageConfig.registryId', required: true, reason: '企业版镜像构建需要指定 TCR 实例 ID' });
|
|
269
|
+
}
|
|
270
|
+
if (!build.repository) {
|
|
271
|
+
missing.push({ name: 'repository', path: 'imageConfig.build.repository', required: true, reason: '企业版镜像构建需要目标仓库' });
|
|
272
|
+
}
|
|
273
|
+
return missing;
|
|
274
|
+
}
|
|
275
|
+
const namespace = build.namespace || context.envId;
|
|
276
|
+
if (!namespace) {
|
|
277
|
+
missing.push({ name: 'namespace', path: 'imageConfig.build.namespace', required: true, reason: '个人版镜像构建需要 namespace,且无法从 envId 推导' });
|
|
278
|
+
}
|
|
279
|
+
if (!((_b = build.registryCredential) === null || _b === void 0 ? void 0 : _b.username)) {
|
|
280
|
+
missing.push({ name: 'registryCredential.username', path: 'imageConfig.build.registryCredential.username', required: true, reason: '个人版 TCR 构建需要推送用户名' });
|
|
281
|
+
}
|
|
282
|
+
if (!((_c = build.registryCredential) === null || _c === void 0 ? void 0 : _c.password)) {
|
|
283
|
+
missing.push({ name: 'registryCredential.password', path: 'imageConfig.build.registryCredential.password', required: true, reason: '个人版 TCR 构建需要推送密码' });
|
|
284
|
+
}
|
|
285
|
+
return missing;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 生成最小化配置准备结果:先应用安全默认值,再返回剩余缺失字段和默认值路径。
|
|
289
|
+
*/
|
|
290
|
+
function prepareMinimalDeployConfig(config, context = {}) {
|
|
291
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
|
|
292
|
+
const prepared = applyMinimalDeployConfigDefaults(config, context);
|
|
293
|
+
const missing = getMissingDeployInputs(prepared, { envId: context.envId });
|
|
294
|
+
const original = lodash_1.default.cloneDeep(config);
|
|
295
|
+
const preparedAny = prepared;
|
|
296
|
+
const appliedDefaults = [];
|
|
297
|
+
const candidates = [
|
|
298
|
+
['imageConfig.imageUri', (_a = original.imageConfig) === null || _a === void 0 ? void 0 : _a.imageUri, (_b = preparedAny.imageConfig) === null || _b === void 0 ? void 0 : _b.imageUri],
|
|
299
|
+
['imageConfig.build.cwd', (_d = (_c = original.imageConfig) === null || _c === void 0 ? void 0 : _c.build) === null || _d === void 0 ? void 0 : _d.cwd, (_f = (_e = preparedAny.imageConfig) === null || _e === void 0 ? void 0 : _e.build) === null || _f === void 0 ? void 0 : _f.cwd],
|
|
300
|
+
['imageConfig.build.dockerfile', (_h = (_g = original.imageConfig) === null || _g === void 0 ? void 0 : _g.build) === null || _h === void 0 ? void 0 : _h.dockerfile, (_k = (_j = preparedAny.imageConfig) === null || _j === void 0 ? void 0 : _j.build) === null || _k === void 0 ? void 0 : _k.dockerfile],
|
|
301
|
+
['imageConfig.build.platform', (_m = (_l = original.imageConfig) === null || _l === void 0 ? void 0 : _l.build) === null || _m === void 0 ? void 0 : _m.platform, (_p = (_o = preparedAny.imageConfig) === null || _o === void 0 ? void 0 : _o.build) === null || _p === void 0 ? void 0 : _p.platform],
|
|
302
|
+
['imageConfig.build.repository', (_r = (_q = original.imageConfig) === null || _q === void 0 ? void 0 : _q.build) === null || _r === void 0 ? void 0 : _r.repository, (_t = (_s = preparedAny.imageConfig) === null || _s === void 0 ? void 0 : _s.build) === null || _t === void 0 ? void 0 : _t.repository],
|
|
303
|
+
['imageConfig.build.namespace', (_v = (_u = original.imageConfig) === null || _u === void 0 ? void 0 : _u.build) === null || _v === void 0 ? void 0 : _v.namespace, (_x = (_w = preparedAny.imageConfig) === null || _w === void 0 ? void 0 : _w.build) === null || _x === void 0 ? void 0 : _x.namespace],
|
|
304
|
+
['imageConfig.registryId', (_y = original.imageConfig) === null || _y === void 0 ? void 0 : _y.registryId, (_z = preparedAny.imageConfig) === null || _z === void 0 ? void 0 : _z.registryId],
|
|
305
|
+
['imageConfig.build.registryCredential', (_1 = (_0 = original.imageConfig) === null || _0 === void 0 ? void 0 : _0.build) === null || _1 === void 0 ? void 0 : _1.registryCredential, (_3 = (_2 = preparedAny.imageConfig) === null || _2 === void 0 ? void 0 : _2.build) === null || _3 === void 0 ? void 0 : _3.registryCredential]
|
|
306
|
+
];
|
|
307
|
+
candidates.forEach(([fieldPath, before, after]) => {
|
|
308
|
+
if (before === undefined && after !== undefined) {
|
|
309
|
+
appliedDefaults.push(fieldPath);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
return { config: prepared, missing, appliedDefaults };
|
|
313
|
+
}
|
|
178
314
|
/**
|
|
179
315
|
* 规范化部署配置
|
|
180
316
|
*
|
|
@@ -182,7 +318,7 @@ function inferHttpBuildStrategy(config) {
|
|
|
182
318
|
* 以便 checkDeployConfig 汇总全部问题
|
|
183
319
|
*/
|
|
184
320
|
function normalizeDeployConfig(config) {
|
|
185
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j
|
|
321
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
186
322
|
if (!config || typeof config !== 'object') {
|
|
187
323
|
throw new error_1.CloudBaseError('部署配置必须是对象', {
|
|
188
324
|
code: types_1.FUNCTION_DEPLOY_ERROR.CONFIG_INVALID
|
|
@@ -210,20 +346,20 @@ function normalizeDeployConfig(config) {
|
|
|
210
346
|
// node_modules 必须随代码包上传,不能被 ignore 排除
|
|
211
347
|
ignore: ignoreList.filter((item) => !/node_modules/.test(item)) });
|
|
212
348
|
}
|
|
213
|
-
const
|
|
214
|
-
normalizedImage.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
349
|
+
const imageConfig = Object.assign({}, (cloned.imageConfig || {}));
|
|
350
|
+
const normalizedImage = Object.assign(Object.assign({}, cloned), { type: 'HTTP', buildStrategy, runtime: types_1.CUSTOM_IMAGE_RUNTIME, imageConfig });
|
|
351
|
+
imageConfig.imagePort = (_a = imageConfig.imagePort) !== null && _a !== void 0 ? _a : types_1.IMAGE_FUNCTION_PORT;
|
|
352
|
+
imageConfig.imageType =
|
|
353
|
+
(_b = imageConfig.imageType) !== null && _b !== void 0 ? _b : (((_c = imageConfig.registryId) !== null && _c !== void 0 ? _c : (_d = imageConfig.build) === null || _d === void 0 ? void 0 : _d.registryId) ? 'enterprise' : 'personal');
|
|
218
354
|
// 镜像函数由容器启动命令决定入口,不使用 handler 与云端装依赖
|
|
219
355
|
delete normalizedImage.handler;
|
|
220
356
|
delete normalizedImage.installDependency;
|
|
221
357
|
if (buildStrategy === 'cloud' || buildStrategy === 'local') {
|
|
222
|
-
|
|
358
|
+
imageConfig.build = Object.assign(Object.assign({}, (imageConfig.build || {})), { dockerfile: (_f = (_e = imageConfig.build) === null || _e === void 0 ? void 0 : _e.dockerfile) !== null && _f !== void 0 ? _f : types_1.DEFAULT_DOCKERFILE, platform: (_h = (_g = imageConfig.build) === null || _g === void 0 ? void 0 : _g.platform) !== null && _h !== void 0 ? _h : types_1.DEFAULT_IMAGE_PLATFORM });
|
|
223
359
|
}
|
|
224
360
|
if (buildStrategy === 'local') {
|
|
225
361
|
// 默认不静默改变构建环境
|
|
226
|
-
|
|
362
|
+
imageConfig.localFallback = (_j = imageConfig.localFallback) !== null && _j !== void 0 ? _j : 'error';
|
|
227
363
|
}
|
|
228
364
|
return normalizedImage;
|
|
229
365
|
}
|
|
@@ -334,10 +470,11 @@ function checkHttpCommon(raw, checks) {
|
|
|
334
470
|
}
|
|
335
471
|
/** 校验镜像函数公共约束 */
|
|
336
472
|
function checkImageRuntimeCommon(raw, checks) {
|
|
473
|
+
var _a;
|
|
337
474
|
if (raw.runtime !== undefined && !isCustomImageRuntime(raw.runtime)) {
|
|
338
475
|
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_RUNTIME_INVALID, `镜像部署要求 runtime 为 ${types_1.CUSTOM_IMAGE_RUNTIME}`, `当前为 ${raw.runtime},请移除 runtime 或设置为 ${types_1.CUSTOM_IMAGE_RUNTIME}`));
|
|
339
476
|
}
|
|
340
|
-
if (raw.imagePort !== undefined && raw.imagePort !== types_1.IMAGE_FUNCTION_PORT) {
|
|
477
|
+
if (((_a = raw.imageConfig) === null || _a === void 0 ? void 0 : _a.imagePort) !== undefined && raw.imageConfig.imagePort !== types_1.IMAGE_FUNCTION_PORT) {
|
|
341
478
|
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_PORT_INVALID, `镜像监听端口必须为 ${types_1.IMAGE_FUNCTION_PORT}`, `请让容器监听 ${types_1.IMAGE_FUNCTION_PORT} 端口`));
|
|
342
479
|
}
|
|
343
480
|
if (raw.handler !== undefined) {
|
|
@@ -369,17 +506,17 @@ function checkImageReference(imageConfig, checks) {
|
|
|
369
506
|
}
|
|
370
507
|
/**
|
|
371
508
|
* 校验镜像类型与仓库 ID
|
|
372
|
-
*
|
|
373
|
-
* local
|
|
509
|
+
* 直接读取 cloudbaserc 嵌套形状:imageType 位于 imageConfig.imageType;
|
|
510
|
+
* registryId 位于 imageConfig.registryId(cloud/local 兼容 imageConfig.build.registryId)。
|
|
374
511
|
*/
|
|
375
512
|
function checkImageIdentity(raw, checks) {
|
|
376
|
-
var _a
|
|
513
|
+
var _a;
|
|
377
514
|
const imageConfig = raw === null || raw === void 0 ? void 0 : raw.imageConfig;
|
|
378
|
-
const
|
|
515
|
+
const build = imageConfig === null || imageConfig === void 0 ? void 0 : imageConfig.build;
|
|
516
|
+
const buildRegistryId = build === null || build === void 0 ? void 0 : build.registryId;
|
|
379
517
|
const buildStrategy = raw === null || raw === void 0 ? void 0 : raw.buildStrategy;
|
|
380
|
-
const registryId = (
|
|
381
|
-
const
|
|
382
|
-
const imageType = resolveBuildImageType(raw, (_e = raw === null || raw === void 0 ? void 0 : raw.build) !== null && _e !== void 0 ? _e : {});
|
|
518
|
+
const registryId = (_a = imageConfig === null || imageConfig === void 0 ? void 0 : imageConfig.registryId) !== null && _a !== void 0 ? _a : buildRegistryId;
|
|
519
|
+
const imageType = resolveBuildImageType(raw, build !== null && build !== void 0 ? build : {});
|
|
383
520
|
if (imageType !== 'enterprise' && imageType !== 'personal') {
|
|
384
521
|
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_TYPE_INVALID, buildStrategy === 'cloud' || buildStrategy === 'local'
|
|
385
522
|
? `${buildStrategy} 策略必须显式声明镜像类型`
|
|
@@ -388,25 +525,25 @@ function checkImageIdentity(raw, checks) {
|
|
|
388
525
|
}
|
|
389
526
|
if (imageType === 'enterprise') {
|
|
390
527
|
if (buildStrategy === 'image' && (registryId === undefined || registryId === null)) {
|
|
391
|
-
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_REGISTRY_ID_MISSING, '企业版镜像未配置仓库实例 ID', '请配置 imageConfig.registryId
|
|
528
|
+
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_REGISTRY_ID_MISSING, '企业版镜像未配置仓库实例 ID', '请配置 imageConfig.registryId'));
|
|
392
529
|
}
|
|
393
530
|
else if (registryId !== undefined && (typeof registryId !== 'string' || !registryId.trim())) {
|
|
394
531
|
const registryField = buildStrategy === 'cloud' || buildStrategy === 'local'
|
|
395
|
-
? 'build.registryId'
|
|
396
|
-
: 'registryId';
|
|
532
|
+
? 'imageConfig.build.registryId'
|
|
533
|
+
: 'imageConfig.registryId';
|
|
397
534
|
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_REGISTRY_ID_INVALID, '企业版镜像仓库实例 ID 无效', `${registryField} 已声明但解析结果为空;若使用 {{env.*}},请检查对应环境变量已赋值为实际企业版 TCR 实例 ID`));
|
|
398
535
|
}
|
|
399
536
|
}
|
|
400
537
|
else if (registryId !== undefined) {
|
|
401
|
-
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_TYPE_INVALID, '个人版镜像不能配置企业版仓库实例 ID', '请移除 build.registryId,或将 imageType 设置为 enterprise'));
|
|
538
|
+
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_TYPE_INVALID, '个人版镜像不能配置企业版仓库实例 ID', '请移除 imageConfig.build.registryId,或将 imageConfig.imageType 设置为 enterprise'));
|
|
402
539
|
}
|
|
403
540
|
}
|
|
404
541
|
/** 解析构建策略使用的镜像类型 */
|
|
405
542
|
function resolveBuildImageType(raw, build) {
|
|
406
|
-
var _a, _b, _c, _d
|
|
407
|
-
return (
|
|
543
|
+
var _a, _b, _c, _d;
|
|
544
|
+
return (_b = (_a = raw.imageConfig) === null || _a === void 0 ? void 0 : _a.imageType) !== null && _b !== void 0 ? _b : (raw.buildStrategy === 'local' || raw.buildStrategy === 'cloud'
|
|
408
545
|
? 'enterprise'
|
|
409
|
-
: ((
|
|
546
|
+
: ((_d = (_c = raw.imageConfig) === null || _c === void 0 ? void 0 : _c.registryId) !== null && _d !== void 0 ? _d : build.registryId)
|
|
410
547
|
? 'enterprise'
|
|
411
548
|
: 'personal');
|
|
412
549
|
}
|
|
@@ -447,9 +584,9 @@ function checkBuildSource(build, checks) {
|
|
|
447
584
|
}
|
|
448
585
|
/** 判断当前构建策略是否要求完整仓库地址 */
|
|
449
586
|
function requiresFullBuildRepository(raw, imageType) {
|
|
450
|
-
var _a;
|
|
587
|
+
var _a, _b;
|
|
451
588
|
return raw.buildStrategy === 'local' && imageType === 'personal' &&
|
|
452
|
-
((_a = raw.
|
|
589
|
+
((_b = (_a = raw.imageConfig) === null || _a === void 0 ? void 0 : _a.build) === null || _b === void 0 ? void 0 : _b.repository) !== undefined;
|
|
453
590
|
}
|
|
454
591
|
/** 添加仓库地址缺失或不完整的错误 */
|
|
455
592
|
function addFullRepositoryError(raw, checks, missing) {
|
|
@@ -546,6 +683,12 @@ function checkBuildRegistry(raw, build, checks) {
|
|
|
546
683
|
const imageType = resolveBuildImageType(raw, build);
|
|
547
684
|
const registryCredential = build.registryCredential;
|
|
548
685
|
if (imageType === 'personal') {
|
|
686
|
+
if (build.namespace !== undefined &&
|
|
687
|
+
(typeof build.namespace !== 'string' ||
|
|
688
|
+
!build.namespace.trim() ||
|
|
689
|
+
!IMAGE_REPOSITORY_PATTERN.test(build.namespace.trim()))) {
|
|
690
|
+
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.BUILD_REPOSITORY_INVALID, '个人版 TCR 命名空间未配置或不合法', 'build.namespace 必须为合法的个人版 TCR 命名空间;未声明时可由 envId 默认补齐'));
|
|
691
|
+
}
|
|
549
692
|
checkPersonalRegistryCredential(registryCredential, checks);
|
|
550
693
|
return;
|
|
551
694
|
}
|
|
@@ -555,9 +698,10 @@ function checkBuildRegistry(raw, build, checks) {
|
|
|
555
698
|
}
|
|
556
699
|
/** 校验镜像构建目标配置 */
|
|
557
700
|
function checkBuildTarget(raw, checks) {
|
|
558
|
-
|
|
701
|
+
var _a, _b;
|
|
702
|
+
const build = (_a = raw.imageConfig) === null || _a === void 0 ? void 0 : _a.build;
|
|
559
703
|
if (!lodash_1.default.isPlainObject(build)) {
|
|
560
|
-
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.BUILD_CONFIG_MISSING, '缺少镜像构建配置', '请配置 build,至少包含构建上下文与 Dockerfile 信息'));
|
|
704
|
+
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.BUILD_CONFIG_MISSING, '缺少镜像构建配置', '请配置 imageConfig.build,至少包含构建上下文与 Dockerfile 信息'));
|
|
561
705
|
return;
|
|
562
706
|
}
|
|
563
707
|
checks.push(...checkBuildTag(raw, build));
|
|
@@ -565,8 +709,8 @@ function checkBuildTarget(raw, checks) {
|
|
|
565
709
|
checkBuildRepository(raw, build, checks);
|
|
566
710
|
checkBuildArgs(raw, build, checks);
|
|
567
711
|
checkBuildRegistry(raw, build, checks);
|
|
568
|
-
if (raw.imageConfig !== undefined) {
|
|
569
|
-
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_CONFIG_NOT_ALLOWED, `buildStrategy 为 ${raw.buildStrategy} 时不能指定 imageConfig`, '镜像地址将由构建结果决定,如需直接部署已有镜像请使用 buildStrategy: image'));
|
|
712
|
+
if (((_b = raw.imageConfig) === null || _b === void 0 ? void 0 : _b.imageUri) !== undefined) {
|
|
713
|
+
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.IMAGE_CONFIG_NOT_ALLOWED, `buildStrategy 为 ${raw.buildStrategy} 时不能指定 imageConfig.imageUri`, '镜像地址将由构建结果决定,如需直接部署已有镜像请使用 buildStrategy: image'));
|
|
570
714
|
}
|
|
571
715
|
}
|
|
572
716
|
/**
|
|
@@ -574,6 +718,7 @@ function checkBuildTarget(raw, checks) {
|
|
|
574
718
|
* @returns 检查报告,包含全部问题而非仅第一个
|
|
575
719
|
*/
|
|
576
720
|
function checkDeployConfig(config) {
|
|
721
|
+
var _a;
|
|
577
722
|
const checks = [];
|
|
578
723
|
if (!config || typeof config !== 'object') {
|
|
579
724
|
return {
|
|
@@ -623,16 +768,16 @@ function checkDeployConfig(config) {
|
|
|
623
768
|
}
|
|
624
769
|
else {
|
|
625
770
|
checkImageReference(raw.imageConfig, checks);
|
|
626
|
-
// imageType
|
|
771
|
+
// imageType 与 registryId 位于 imageConfig,统一传 raw 由 checkImageIdentity 读取
|
|
627
772
|
checkImageIdentity(raw, checks);
|
|
628
|
-
// 注:imagePort
|
|
773
|
+
// 注:imagePort 位于 imageConfig,已由 checkImageRuntimeCommon 校验,此处不重复
|
|
629
774
|
}
|
|
630
775
|
}
|
|
631
776
|
else {
|
|
632
777
|
checkImageIdentity(raw, checks);
|
|
633
778
|
checkBuildTarget(raw, checks);
|
|
634
779
|
if (strategy === 'local') {
|
|
635
|
-
const fallback = raw.localFallback;
|
|
780
|
+
const fallback = (_a = raw.imageConfig) === null || _a === void 0 ? void 0 : _a.localFallback;
|
|
636
781
|
if (fallback !== undefined && fallback !== 'cloud' && fallback !== 'error') {
|
|
637
782
|
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.LOCAL_FALLBACK_INVALID, 'localFallback 取值不合法', "只能是 'cloud' 或 'error'"));
|
|
638
783
|
}
|
|
@@ -142,22 +142,23 @@ async function ensureNamespace(service, registryId, namespace) {
|
|
|
142
142
|
}
|
|
143
143
|
async function prepareEnterpriseTcrTarget(config, options) {
|
|
144
144
|
var _a;
|
|
145
|
-
const
|
|
145
|
+
const build = config.imageConfig.build;
|
|
146
|
+
const configuredRegistryId = (_a = config.imageConfig.registryId) !== null && _a !== void 0 ? _a : build.registryId;
|
|
146
147
|
const explicitRegistryId = typeof configuredRegistryId === 'string' && configuredRegistryId.trim()
|
|
147
148
|
? configuredRegistryId.trim()
|
|
148
149
|
: undefined;
|
|
149
150
|
const resolvedRegistry = await resolveRegistry(options.service, options.region, explicitRegistryId);
|
|
150
|
-
const repositoryTarget = parseRepositoryTarget(
|
|
151
|
-
const namespace = (
|
|
151
|
+
const repositoryTarget = parseRepositoryTarget(build.repository || config.name);
|
|
152
|
+
const namespace = (build.namespace || repositoryTarget.namespace || options.envId).trim();
|
|
152
153
|
assertNamespace(namespace);
|
|
153
|
-
if (
|
|
154
|
-
throwTcrError('build.namespace 与 build.repository 中的命名空间不一致。', types_1.FUNCTION_DEPLOY_ERROR.BUILD_REPOSITORY_INVALID);
|
|
154
|
+
if (build.namespace && repositoryTarget.namespace && build.namespace !== repositoryTarget.namespace) {
|
|
155
|
+
throwTcrError('imageConfig.build.namespace 与 imageConfig.build.repository 中的命名空间不一致。', types_1.FUNCTION_DEPLOY_ERROR.BUILD_REPOSITORY_INVALID);
|
|
155
156
|
}
|
|
156
157
|
await ensureNamespace(options.service, resolvedRegistry.registryId, namespace);
|
|
157
158
|
const registry = repositoryTarget.registry || resolvedRegistry.registry;
|
|
158
159
|
const repository = repositoryTarget.repository || config.name;
|
|
159
160
|
const imageRepository = `${registry}/${namespace}/${repository}`;
|
|
160
|
-
const preparedConfig = Object.assign(Object.assign({}, config), { imageType: 'enterprise', registryId: resolvedRegistry.registryId, build: Object.assign(Object.assign({},
|
|
161
|
+
const preparedConfig = Object.assign(Object.assign({}, config), { imageConfig: Object.assign(Object.assign({}, config.imageConfig), { imageType: 'enterprise', registryId: resolvedRegistry.registryId, build: Object.assign(Object.assign({}, build), { registryId: resolvedRegistry.registryId, namespace, repository: imageRepository }) }) });
|
|
161
162
|
return {
|
|
162
163
|
config: preparedConfig,
|
|
163
164
|
target: {
|
|
@@ -61,18 +61,19 @@ const defaultDeps = {
|
|
|
61
61
|
};
|
|
62
62
|
/** 解析构建上下文目录(绝对路径) */
|
|
63
63
|
function resolveContext(config) {
|
|
64
|
-
const cwd = config.build.cwd || config.functionPath || process.cwd();
|
|
64
|
+
const cwd = config.imageConfig.build.cwd || config.functionPath || process.cwd();
|
|
65
65
|
return path_1.default.resolve(cwd);
|
|
66
66
|
}
|
|
67
67
|
/** 解析目标镜像完整引用 imageUri(repository 需为含域名与命名空间的完整仓库地址,个人版/企业版通用) */
|
|
68
68
|
async function resolveImageUri(config, context) {
|
|
69
|
-
const
|
|
69
|
+
const build = config.imageConfig.build;
|
|
70
|
+
const repository = build.repository;
|
|
70
71
|
if (typeof repository !== 'string' || !repository.trim()) {
|
|
71
|
-
throw new error_1.CloudBaseError('local 策略缺少目标镜像仓库地址 build.repository', {
|
|
72
|
+
throw new error_1.CloudBaseError('local 策略缺少目标镜像仓库地址 imageConfig.build.repository', {
|
|
72
73
|
code: types_1.FUNCTION_DEPLOY_ERROR.LOCAL_BUILD_REPOSITORY_MISSING
|
|
73
74
|
});
|
|
74
75
|
}
|
|
75
|
-
const tag = await (0, image_tag_1.resolveImageTag)({ explicitTag:
|
|
76
|
+
const tag = await (0, image_tag_1.resolveImageTag)({ explicitTag: build.tag, cwd: context });
|
|
76
77
|
return `${repository.trim()}:${tag}`;
|
|
77
78
|
}
|
|
78
79
|
/** 从 buildx imagetools inspect 输出解析 digest */
|
|
@@ -106,7 +107,7 @@ async function buildLocalImage(config, onLog, options = {}) {
|
|
|
106
107
|
code: types_1.FUNCTION_DEPLOY_ERROR.LOCAL_BUILD_CONTEXT_MISSING
|
|
107
108
|
});
|
|
108
109
|
}
|
|
109
|
-
const dockerfile = config.build.dockerfile || types_1.DEFAULT_DOCKERFILE;
|
|
110
|
+
const dockerfile = config.imageConfig.build.dockerfile || types_1.DEFAULT_DOCKERFILE;
|
|
110
111
|
const dockerfilePath = path_1.default.resolve(context, dockerfile);
|
|
111
112
|
if (!deps.existsSync(dockerfilePath) || !deps.isFile(dockerfilePath)) {
|
|
112
113
|
throw new error_1.CloudBaseError(`Dockerfile 不存在:${dockerfilePath}`, {
|
|
@@ -114,7 +115,7 @@ async function buildLocalImage(config, onLog, options = {}) {
|
|
|
114
115
|
});
|
|
115
116
|
}
|
|
116
117
|
const imageUri = await resolveImageUri(config, context);
|
|
117
|
-
const platform = config.build.platform || types_1.DEFAULT_IMAGE_PLATFORM;
|
|
118
|
+
const platform = config.imageConfig.build.platform || types_1.DEFAULT_IMAGE_PLATFORM;
|
|
118
119
|
const args = [
|
|
119
120
|
'buildx',
|
|
120
121
|
'build',
|
|
@@ -126,10 +127,10 @@ async function buildLocalImage(config, onLog, options = {}) {
|
|
|
126
127
|
imageUri,
|
|
127
128
|
'--load'
|
|
128
129
|
];
|
|
129
|
-
if (config.build.forceBuild) {
|
|
130
|
+
if (config.imageConfig.build.forceBuild) {
|
|
130
131
|
args.push('--no-cache');
|
|
131
132
|
}
|
|
132
|
-
const buildArgs = config.build.buildArgs || {};
|
|
133
|
+
const buildArgs = config.imageConfig.build.buildArgs || {};
|
|
133
134
|
for (const key of Object.keys(buildArgs)) {
|
|
134
135
|
args.push('--build-arg', `${key}=${buildArgs[key]}`);
|
|
135
136
|
}
|
|
@@ -244,7 +245,7 @@ function createTemporaryDockerConfig() {
|
|
|
244
245
|
*/
|
|
245
246
|
async function buildAndPushImage(config, onLog, deps = defaultDeps) {
|
|
246
247
|
const startedAt = Date.now();
|
|
247
|
-
const credential = config.build.registryCredential;
|
|
248
|
+
const credential = config.imageConfig.build.registryCredential;
|
|
248
249
|
const dockerConfig = credential ? createTemporaryDockerConfig() : undefined;
|
|
249
250
|
const commandOptions = dockerConfig ? { env: dockerConfig.env } : undefined;
|
|
250
251
|
try {
|
|
@@ -71,7 +71,8 @@ function safeStat(target) {
|
|
|
71
71
|
}
|
|
72
72
|
/** 检查 cloud 构建上下文与 Dockerfile,确保任何云端操作前即可失败 */
|
|
73
73
|
function checkCloudBuildSource(config, checks) {
|
|
74
|
-
const
|
|
74
|
+
const build = config.imageConfig.build;
|
|
75
|
+
const cwd = path_1.default.resolve(build.cwd || config.functionPath || process.cwd());
|
|
75
76
|
const contextStat = safeStat(cwd);
|
|
76
77
|
if (contextStat === null) {
|
|
77
78
|
checks.push(fail(types_1.FUNCTION_DEPLOY_ERROR.BUILD_CONTEXT_INVALID, '云端镜像构建上下文目录不存在', {
|
|
@@ -87,7 +88,7 @@ function checkCloudBuildSource(config, checks) {
|
|
|
87
88
|
}));
|
|
88
89
|
return;
|
|
89
90
|
}
|
|
90
|
-
const dockerfile =
|
|
91
|
+
const dockerfile = build.dockerfile || types_1.DEFAULT_DOCKERFILE;
|
|
91
92
|
const dockerfilePath = path_1.default.resolve(cwd, dockerfile);
|
|
92
93
|
const dockerfileStat = safeStat(dockerfilePath);
|
|
93
94
|
if (dockerfileStat === null || !dockerfileStat.isFile()) {
|
|
@@ -23,7 +23,6 @@ const path_1 = __importDefault(require("path"));
|
|
|
23
23
|
const toolbox_1 = require("@cloudbase/toolbox");
|
|
24
24
|
class ProjectValidator {
|
|
25
25
|
async validate(options = {}) {
|
|
26
|
-
var _a;
|
|
27
26
|
const cwd = path_1.default.resolve(options.cwd || process.cwd());
|
|
28
27
|
const errors = [];
|
|
29
28
|
const warnings = [];
|
|
@@ -32,7 +31,6 @@ class ProjectValidator {
|
|
|
32
31
|
mode: options.mode,
|
|
33
32
|
errors,
|
|
34
33
|
});
|
|
35
|
-
const version = String(((_a = loaded.rawConfig) === null || _a === void 0 ? void 0 : _a.version) || '2.1');
|
|
36
34
|
if (loaded.rawConfig) {
|
|
37
35
|
this.validateSchema(loaded.rawConfig, errors);
|
|
38
36
|
}
|
|
@@ -47,7 +45,6 @@ class ProjectValidator {
|
|
|
47
45
|
const summary = this.getSummary(loaded.config);
|
|
48
46
|
return {
|
|
49
47
|
valid: errors.length === 0,
|
|
50
|
-
version,
|
|
51
48
|
errors,
|
|
52
49
|
warnings,
|
|
53
50
|
summary,
|
package/package.json
CHANGED
|
@@ -19,8 +19,6 @@ export interface IDeployOptions {
|
|
|
19
19
|
yes?: boolean;
|
|
20
20
|
/** 已存在资源(函数)的覆盖更新确认回调:返回 true 部署、false 跳过(CLI 注入 autoConfirm) */
|
|
21
21
|
confirmUpdate?: (item: IDeployPlanItem) => Promise<boolean>;
|
|
22
|
-
/** 强制云端对比(漂移检测):忽略本地 state 快照的 skip 判定,强制重新对比/部署 */
|
|
23
|
-
refresh?: boolean;
|
|
24
22
|
/** 同类型资源最大并行数,默认 1(串行)。仅作用于同类型连续实例之间,跨类型依赖顺序不变 */
|
|
25
23
|
concurrency?: number;
|
|
26
24
|
/** 失败后继续部署其余资源(database 失败仍强制中断) */
|
|
@@ -51,13 +49,6 @@ export interface IDeployPlanItem {
|
|
|
51
49
|
from?: string;
|
|
52
50
|
to?: string;
|
|
53
51
|
}>;
|
|
54
|
-
/** hosting 文件级 diff(新增/修改/删除,前 N 条 + 统计) */
|
|
55
|
-
fileDiff?: {
|
|
56
|
-
added: string[];
|
|
57
|
-
modified: string[];
|
|
58
|
-
deleted: string[];
|
|
59
|
-
totalChanged: number;
|
|
60
|
-
};
|
|
61
52
|
/** 资源级详情子行(dry-run 树状渲染用):如函数 runtime/构建策略、迁移逐条状态等 */
|
|
62
53
|
details?: Array<{
|
|
63
54
|
label: string;
|
|
@@ -109,6 +100,11 @@ export declare class DeployOrchestrator {
|
|
|
109
100
|
* - database 失败始终强制中断(无论是否 continueOnError)
|
|
110
101
|
*/
|
|
111
102
|
deploy(options: IDeployOptions): Promise<IDeployResult>;
|
|
103
|
+
/**
|
|
104
|
+
* 归一化声明式函数配置:直接消费 cloudbaserc 的嵌套形状(imageConfig.build),
|
|
105
|
+
* 不做字段平铺映射;非 HTTP 函数原样返回。
|
|
106
|
+
*/
|
|
107
|
+
private normalizeFunctionConfigs;
|
|
112
108
|
/**
|
|
113
109
|
* 将扁平 plan 按「连续相同资源类型」切成有序 segments
|
|
114
110
|
*
|
|
@@ -117,22 +113,14 @@ export declare class DeployOrchestrator {
|
|
|
117
113
|
* → [[db], [fnA, fnB], [hostingX, hostingY], [gateway]]
|
|
118
114
|
*/
|
|
119
115
|
private segmentPlan;
|
|
120
|
-
/**
|
|
121
|
-
* 部署成功后写回本地 state 快照
|
|
122
|
-
*
|
|
123
|
-
* - hosting:成功部署/未变更(skip)的项重算产物指纹;失败项保留旧快照
|
|
124
|
-
* - app:成功部署写 buildAppConfig 快照;skip 复用旧快照
|
|
125
|
-
* - gateway:保留旧快照(本轮不做路由级实时快照)
|
|
126
|
-
*/
|
|
127
|
-
private persistState;
|
|
128
116
|
/**
|
|
129
117
|
* 构建完整部署计划(按依赖顺序 + only/skip 过滤)
|
|
130
118
|
*
|
|
131
119
|
* 通过查询云端状态判定每个资源的动作:
|
|
132
120
|
* - database:先按迁移文件做 preview,再聚合成单条资源级计划项(pending→create,存在 conflict→conflict,全部 applied→不出现在 plan)
|
|
133
121
|
* - functions:ListFunctions 判断是否已存在 → create / update(不做本地 hash / 字段 diff)
|
|
134
|
-
* - app:describeAppInfo 判断是否已存在 → create / update
|
|
135
|
-
* - hosting
|
|
122
|
+
* - app:describeAppInfo 判断是否已存在 → create / update
|
|
123
|
+
* - hosting:直传覆盖(无存在性概念)
|
|
136
124
|
* - gateway:planRoutes 对比云端路由 → create / update / skip(含变更字段明细)
|
|
137
125
|
* 云端查询失败时降级为保守判定(全 create),不影响 dry-run 展示。
|
|
138
126
|
*/
|
|
@@ -146,11 +134,11 @@ export declare class DeployOrchestrator {
|
|
|
146
134
|
*/
|
|
147
135
|
private buildDatabasePlan;
|
|
148
136
|
/**
|
|
149
|
-
* app
|
|
137
|
+
* app 计划:按云端存在性 → create / update
|
|
150
138
|
*/
|
|
151
139
|
private buildAppPlan;
|
|
152
140
|
/**
|
|
153
|
-
* hosting
|
|
141
|
+
* hosting 计划:每次直传覆盖(无本地指纹 skip)
|
|
154
142
|
*/
|
|
155
143
|
private buildHostingPlans;
|
|
156
144
|
/**
|
|
@@ -169,10 +157,6 @@ export declare class DeployOrchestrator {
|
|
|
169
157
|
* 执行单个计划步骤
|
|
170
158
|
*/
|
|
171
159
|
private executeStep;
|
|
172
|
-
/** 深比较(JSON 快照语义):仅用于 app 配置快照等简单对象 */
|
|
173
|
-
private deepEqual;
|
|
174
|
-
/** app 配置差异明细(from → to) */
|
|
175
|
-
private appConfigChanges;
|
|
176
160
|
/**
|
|
177
161
|
* 轻量 inline 守卫:配置合法 + 目录存在(validateProject 接线点)
|
|
178
162
|
*/
|
|
@@ -80,6 +80,20 @@ export declare class FunctionDeployer {
|
|
|
80
80
|
* 只做纯函数、无 IO 的配置契约校验,一次返回全部问题
|
|
81
81
|
*/
|
|
82
82
|
checkConfig(config: IFunctionDeployConfig): ICheckReport;
|
|
83
|
+
/**
|
|
84
|
+
* 计算最小化部署配置的默认值,不执行网络或云端变更。
|
|
85
|
+
*/
|
|
86
|
+
applyMinimalConfigDefaults(config: IFunctionDeployConfig, context?: import('./types').IMinimalDeployConfigContext): IFunctionDeployConfig;
|
|
87
|
+
/**
|
|
88
|
+
* 返回最小化配置仍缺失的字段,不执行网络或云端变更。
|
|
89
|
+
*/
|
|
90
|
+
getMissingConfigInputs(config: IFunctionDeployConfig, context?: {
|
|
91
|
+
envId?: string;
|
|
92
|
+
}): import('./types').IDeployInputField[];
|
|
93
|
+
/**
|
|
94
|
+
* 应用安全默认值并返回缺失字段,供 CLI/MCP 逐步收集用户输入。
|
|
95
|
+
*/
|
|
96
|
+
prepareMinimalConfig(config: IFunctionDeployConfig, context?: import('./types').IMinimalDeployConfigContext): import('./types').IMinimalDeployConfigResult;
|
|
83
97
|
/**
|
|
84
98
|
* 生成部署计划
|
|
85
99
|
*
|
|
@@ -166,7 +180,7 @@ export declare class FunctionDeployer {
|
|
|
166
180
|
private emitProgressDone;
|
|
167
181
|
}
|
|
168
182
|
export * from './types';
|
|
169
|
-
export { assertDeployConfig, checkDeployConfig, isCustomImageRuntime, normalizeDeployConfig, normalizeGatewayPath, parseImageReference } from './function/config-guard';
|
|
183
|
+
export { assertDeployConfig, checkDeployConfig, applyMinimalDeployConfigDefaults, getMissingDeployInputs, prepareMinimalDeployConfig, isCustomImageRuntime, normalizeDeployConfig, normalizeGatewayPath, parseImageReference } from './function/config-guard';
|
|
170
184
|
export { createDeployPlan, toCurrentState } from './function/planner';
|
|
171
185
|
export { createCodeArtifact, createImageArtifactFromConfig, toCloudFunction } from './function/artifact';
|
|
172
186
|
export { buildImageOnCloud } from './function/builders/cloud';
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { ICloudFunction } from '../../interfaces';
|
|
2
2
|
import { ICodeArtifact, IFunctionArtifact, IImageArtifact, INormalizedDeployConfig, INormalizedHttpCloudConfig, INormalizedHttpImageConfig, INormalizedHttpLocalConfig } from '../types';
|
|
3
|
-
/**
|
|
4
|
-
* 部署物构造与 SCF 参数映射
|
|
5
|
-
*
|
|
6
|
-
* 四种构建策略最终都产出统一的部署物,之后走同一条 SCF 创建或更新流程
|
|
7
|
-
*/
|
|
8
3
|
/** 由本地代码来源构造代码类部署物 */
|
|
9
4
|
export declare function createCodeArtifact(config: INormalizedDeployConfig): ICodeArtifact;
|
|
10
5
|
/** 由已有镜像配置构造镜像类部署物 */
|