@cloudbase/manager-node 5.8.5 → 5.8.7-beta.0

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