@be-link/shield-for-tcb-node-sdk 1.0.16 → 1.0.17

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/README.md CHANGED
@@ -254,6 +254,46 @@ const values = await backendConfigServiceV2.getConfigValues(
254
254
  // }
255
255
  ```
256
256
 
257
+ ## 云函数场景:按单 Key 读取配置
258
+
259
+ 云函数等短生命周期场景不适合在每次请求中初始化 `ShieldConfigManager` 并拉取全量配置。可以使用 `ShieldCloudFunctionConfig` 按需读取单个 key:构造不发请求、不 `setup()`、不启动定时器、SDK 侧不维护本地缓存,每次 `fetchKey()` 只发一次单 key HTTP 请求,缓存集中在 Shield 服务端(本地内存 + Redis + MySQL)。
260
+
261
+ ```ts
262
+ import { ShieldCloudFunctionConfig } from '@be-link/shield-for-tcb-node-sdk'
263
+
264
+ const configClient = new ShieldCloudFunctionConfig({
265
+ serviceName: 'TheVitality',
266
+ env: 'prod',
267
+ fetchTimeoutMs: 2000,
268
+ })
269
+
270
+ export async function handler() {
271
+ const redisConfig = await configClient.fetchKey<{
272
+ HOST: string
273
+ PORT: number
274
+ }>('REDIS')
275
+
276
+ const timeout = await configClient.fetchKey<number>('API_TIMEOUT', 3000)
277
+ const enabled = await configClient.isSwitchEnabled('FEATURE_ENABLED', false)
278
+ const isHit = await configClient.isHitGrey('TRAFFIC_SPLIT', 'user_001', false)
279
+
280
+ return { redisConfig, timeout, enabled, isHit }
281
+ }
282
+ ```
283
+
284
+ ### 行为说明
285
+
286
+ - 构造 `ShieldCloudFunctionConfig` 不会发起 HTTP 请求。
287
+ - 不需要调用 `setup()`。
288
+ - 不会启动定时器。
289
+ - SDK 侧不维护本地缓存。
290
+ - 每次 `fetchKey()` 都会请求 Shield 服务端单 key 接口 `POST /shield/v2/config/cloud-function/fetch-key`。
291
+ - 默认超时时间为 2 秒,可以通过 `fetchTimeoutMs` 覆盖。
292
+ - 配置不存在、HTTP 超时、网络异常、Shield 5xx 时,`fetchKey()` 返回 `defaultValue` 或 `undefined`。
293
+ - `defaultValue` 同时适用于「配置不存在」和「远程读取失败」,安全敏感开关应选择 fail-safe 默认值。
294
+ - 多个 key 会产生多次 HTTP 请求;如果同一次云函数调用需要多个 key,调用方应评估延迟预算。
295
+ - `isSwitchEnabled()` / `isHitGrey()` 与 `ShieldConfigManager` 保持一致的解析与灰度规则,灰度判断复用同一套逻辑,结果不会漂移。
296
+
257
297
  ## 发布流程
258
298
 
259
299
  ### 自动发布(推荐)
package/index.d.ts CHANGED
@@ -4,3 +4,5 @@ export { backendConfigServiceV2, ConfigServiceV2 } from './modules/config/servic
4
4
  export type { ServiceV2 as ConfigControllerTypesV2 } from './modules/config/typesV2';
5
5
  export { ShieldConfigManager } from './modules/config/ShieldConfigManager';
6
6
  export type { ShieldConfigManagerOptions, Logger } from './modules/config/ShieldConfigManager';
7
+ export { ShieldCloudFunctionConfig } from './modules/config/ShieldCloudFunctionConfig';
8
+ export type { ShieldCloudFunctionConfigOptions } from './modules/config/ShieldCloudFunctionConfig';
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ShieldConfigManager = exports.ConfigServiceV2 = exports.backendConfigServiceV2 = exports.backendConfigService = void 0;
3
+ exports.ShieldCloudFunctionConfig = exports.ShieldConfigManager = exports.ConfigServiceV2 = exports.backendConfigServiceV2 = exports.backendConfigService = void 0;
4
4
  // V1 SDK (YAML 数据源)
5
5
  var service_1 = require("./modules/config/service");
6
6
  Object.defineProperty(exports, "backendConfigService", { enumerable: true, get: function () { return service_1.backendConfigService; } });
@@ -11,3 +11,6 @@ Object.defineProperty(exports, "ConfigServiceV2", { enumerable: true, get: funct
11
11
  // ShieldConfigManager
12
12
  var ShieldConfigManager_1 = require("./modules/config/ShieldConfigManager");
13
13
  Object.defineProperty(exports, "ShieldConfigManager", { enumerable: true, get: function () { return ShieldConfigManager_1.ShieldConfigManager; } });
14
+ // Cloud Function SDK
15
+ var ShieldCloudFunctionConfig_1 = require("./modules/config/ShieldCloudFunctionConfig");
16
+ Object.defineProperty(exports, "ShieldCloudFunctionConfig", { enumerable: true, get: function () { return ShieldCloudFunctionConfig_1.ShieldCloudFunctionConfig; } });
@@ -0,0 +1,32 @@
1
+ import type { Logger } from './ShieldConfigManager';
2
+ export interface ShieldCloudFunctionConfigOptions {
3
+ serviceName: string;
4
+ env?: string;
5
+ fetchTimeoutMs?: number;
6
+ logger?: Logger;
7
+ }
8
+ /**
9
+ * 云函数专用单 Key 配置客户端
10
+ *
11
+ * 面向云函数等短生命周期场景:构造函数不发 HTTP、不 setup、不启动定时器、不维护 SDK 本地缓存。
12
+ * 每次 fetchKey 只按指定 key 发一次 HTTP 请求到 Shield 服务,缓存集中在服务端。
13
+ */
14
+ export declare class ShieldCloudFunctionConfig {
15
+ #private;
16
+ constructor(options: ShieldCloudFunctionConfigOptions);
17
+ /**
18
+ * 按单 Key 读取配置
19
+ * @param key 配置键
20
+ * @param defaultValue 配置不存在或读取异常时的默认值
21
+ * @returns 解析后的配置值,配置不存在或异常时返回 defaultValue / undefined
22
+ */
23
+ fetchKey<T = any>(key: string, defaultValue?: T): Promise<T | undefined>;
24
+ /**
25
+ * 开关判断:按 ShieldConfigManager.isSwitchEnabled 兼容规则解析布尔值
26
+ */
27
+ isSwitchEnabled(key: string, defaultValue?: boolean): Promise<boolean>;
28
+ /**
29
+ * 灰度判断:复用共享 greyMatcher,保证与 ShieldConfigManager.isHitGrey 结果一致
30
+ */
31
+ isHitGrey(configKey: string, identifier: string, defaultValue?: boolean): Promise<boolean>;
32
+ }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _ShieldCloudFunctionConfig_serviceName, _ShieldCloudFunctionConfig_env, _ShieldCloudFunctionConfig_fetchTimeoutMs, _ShieldCloudFunctionConfig_logger;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ShieldCloudFunctionConfig = void 0;
16
+ const serviceV2_1 = require("./serviceV2");
17
+ const greyMatcher_1 = require("./greyMatcher");
18
+ const defaultLogger = {
19
+ info: (msg, ...args) => console.log(`[ShieldCloudFunctionConfig] ${msg}`, ...args),
20
+ warn: (msg, ...args) => console.warn(`[ShieldCloudFunctionConfig] ${msg}`, ...args),
21
+ error: (msg, ...args) => console.error(`[ShieldCloudFunctionConfig] ${msg}`, ...args),
22
+ };
23
+ const DEFAULT_FETCH_TIMEOUT_MS = 2 * 1000;
24
+ /**
25
+ * 云函数专用单 Key 配置客户端
26
+ *
27
+ * 面向云函数等短生命周期场景:构造函数不发 HTTP、不 setup、不启动定时器、不维护 SDK 本地缓存。
28
+ * 每次 fetchKey 只按指定 key 发一次 HTTP 请求到 Shield 服务,缓存集中在服务端。
29
+ */
30
+ class ShieldCloudFunctionConfig {
31
+ constructor(options) {
32
+ _ShieldCloudFunctionConfig_serviceName.set(this, void 0);
33
+ _ShieldCloudFunctionConfig_env.set(this, void 0);
34
+ _ShieldCloudFunctionConfig_fetchTimeoutMs.set(this, void 0);
35
+ _ShieldCloudFunctionConfig_logger.set(this, void 0);
36
+ if (!options.serviceName) {
37
+ throw new Error('[ShieldCloudFunctionConfig] serviceName is required');
38
+ }
39
+ __classPrivateFieldSet(this, _ShieldCloudFunctionConfig_serviceName, options.serviceName, "f");
40
+ __classPrivateFieldSet(this, _ShieldCloudFunctionConfig_env, options.env || process.env.NODE_ENV, "f");
41
+ __classPrivateFieldSet(this, _ShieldCloudFunctionConfig_fetchTimeoutMs, options.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS, "f");
42
+ __classPrivateFieldSet(this, _ShieldCloudFunctionConfig_logger, options.logger || defaultLogger, "f");
43
+ }
44
+ /**
45
+ * 按单 Key 读取配置
46
+ * @param key 配置键
47
+ * @param defaultValue 配置不存在或读取异常时的默认值
48
+ * @returns 解析后的配置值,配置不存在或异常时返回 defaultValue / undefined
49
+ */
50
+ async fetchKey(key, defaultValue) {
51
+ if (!key) {
52
+ throw new Error('[ShieldCloudFunctionConfig] key is required');
53
+ }
54
+ const startTime = Date.now();
55
+ try {
56
+ const result = await serviceV2_1.backendConfigServiceV2.fetchCloudFunctionConfigKey({ service: __classPrivateFieldGet(this, _ShieldCloudFunctionConfig_serviceName, "f"), key, env: __classPrivateFieldGet(this, _ShieldCloudFunctionConfig_env, "f") }, { timeoutMs: __classPrivateFieldGet(this, _ShieldCloudFunctionConfig_fetchTimeoutMs, "f") });
57
+ if (!result) {
58
+ return defaultValue;
59
+ }
60
+ return result.value;
61
+ }
62
+ catch (error) {
63
+ const durationMs = Date.now() - startTime;
64
+ const message = error instanceof Error ? error.message : JSON.stringify(error);
65
+ __classPrivateFieldGet(this, _ShieldCloudFunctionConfig_logger, "f").error(`[ShieldCloudFunctionConfig] fetch key error service=${__classPrivateFieldGet(this, _ShieldCloudFunctionConfig_serviceName, "f")} env=${__classPrivateFieldGet(this, _ShieldCloudFunctionConfig_env, "f") || ''} key=${key} durationMs=${durationMs} error=${message}`);
66
+ return defaultValue;
67
+ }
68
+ }
69
+ /**
70
+ * 开关判断:按 ShieldConfigManager.isSwitchEnabled 兼容规则解析布尔值
71
+ */
72
+ async isSwitchEnabled(key, defaultValue = false) {
73
+ const value = await this.fetchKey(key);
74
+ if (value === undefined || value === null) {
75
+ return defaultValue;
76
+ }
77
+ if (typeof value === 'boolean') {
78
+ return value;
79
+ }
80
+ if (typeof value === 'number') {
81
+ return value !== 0;
82
+ }
83
+ if (typeof value === 'string') {
84
+ const lower = value.trim().toLowerCase();
85
+ if (lower === 'true' || lower === '1' || lower === 'yes' || lower === 'on') {
86
+ return true;
87
+ }
88
+ if (lower === 'false' || lower === '0' || lower === 'no' || lower === 'off') {
89
+ return false;
90
+ }
91
+ }
92
+ return defaultValue;
93
+ }
94
+ /**
95
+ * 灰度判断:复用共享 greyMatcher,保证与 ShieldConfigManager.isHitGrey 结果一致
96
+ */
97
+ async isHitGrey(configKey, identifier, defaultValue = false) {
98
+ const config = await this.fetchKey(configKey);
99
+ return (0, greyMatcher_1.isHitGreyConfig)(config, identifier, defaultValue);
100
+ }
101
+ }
102
+ exports.ShieldCloudFunctionConfig = ShieldCloudFunctionConfig;
103
+ _ShieldCloudFunctionConfig_serviceName = new WeakMap(), _ShieldCloudFunctionConfig_env = new WeakMap(), _ShieldCloudFunctionConfig_fetchTimeoutMs = new WeakMap(), _ShieldCloudFunctionConfig_logger = new WeakMap();
@@ -46,7 +46,7 @@ export interface Logger {
46
46
  error: (message: string, ...args: any[]) => void;
47
47
  }
48
48
  /**
49
- * 流量控制配置
49
+ * 流量控制配置(类型从 greyMatcher 复用,保证灰度判断逻辑统一)
50
50
  *
51
51
  * @example
52
52
  * ```json
@@ -59,18 +59,7 @@ export interface Logger {
59
59
  * }
60
60
  * ```
61
61
  */
62
- export interface TrafficControlConfig {
63
- /** 总开关 */
64
- enabled: boolean;
65
- /** 总桶数 */
66
- totalBuckets: number;
67
- /** 生效桶数(bucket 0 到 effectiveBuckets-1 生效) */
68
- effectiveBuckets: number;
69
- /** 白名单(命中后视为生效) */
70
- whitelist?: string[];
71
- /** 黑名单(命中后视为不生效) */
72
- blacklist?: string[];
73
- }
62
+ export type { TrafficControlConfig } from './greyMatcher';
74
63
  /**
75
64
  * 配置管理器
76
65
  *
@@ -71,11 +71,12 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
71
71
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
72
72
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
73
73
  };
74
- var _ShieldConfigManager_instances, _ShieldConfigManager_serviceName, _ShieldConfigManager_env, _ShieldConfigManager_refreshIntervalMs, _ShieldConfigManager_fetchTimeoutMs, _ShieldConfigManager_enableInfoLog, _ShieldConfigManager_logger, _ShieldConfigManager_config, _ShieldConfigManager_refreshTimer, _ShieldConfigManager_isSetup, _ShieldConfigManager_setupPromise, _ShieldConfigManager_doSetup, _ShieldConfigManager_hashString, _ShieldConfigManager_startRefreshTimer;
74
+ var _ShieldConfigManager_instances, _ShieldConfigManager_serviceName, _ShieldConfigManager_env, _ShieldConfigManager_refreshIntervalMs, _ShieldConfigManager_fetchTimeoutMs, _ShieldConfigManager_enableInfoLog, _ShieldConfigManager_logger, _ShieldConfigManager_config, _ShieldConfigManager_refreshTimer, _ShieldConfigManager_isSetup, _ShieldConfigManager_setupPromise, _ShieldConfigManager_doSetup, _ShieldConfigManager_startRefreshTimer;
75
75
  Object.defineProperty(exports, "__esModule", { value: true });
76
76
  exports.ShieldConfigManager = void 0;
77
77
  const serviceV2_1 = require("./serviceV2");
78
78
  const shieldClient = __importStar(require("./service"));
79
+ const greyMatcher_1 = require("./greyMatcher");
79
80
  const defaultLogger = {
80
81
  info: (msg, ...args) => console.log(`[ShieldConfigManager] ${msg}`, ...args),
81
82
  warn: (msg, ...args) => console.warn(`[ShieldConfigManager] ${msg}`, ...args),
@@ -264,26 +265,7 @@ class ShieldConfigManager {
264
265
  */
265
266
  isHitGrey(configKey, identifier, defaultValue = false) {
266
267
  const config = this.getValue(configKey);
267
- if (!config) {
268
- return defaultValue;
269
- }
270
- // 总开关关闭,返回 false
271
- if (!config.enabled) {
272
- return false;
273
- }
274
- // 黑名单检查(精确匹配)- 命中后返回 false
275
- if (config.blacklist && config.blacklist.includes(identifier)) {
276
- return false;
277
- }
278
- // 白名单检查(精确匹配)- 命中后返回 true
279
- if (config.whitelist && config.whitelist.includes(identifier)) {
280
- return true;
281
- }
282
- // 桶路由
283
- const totalBuckets = config.totalBuckets || 100;
284
- const effectiveBuckets = config.effectiveBuckets || 0;
285
- const hash = __classPrivateFieldGet(this, _ShieldConfigManager_instances, "m", _ShieldConfigManager_hashString).call(this, identifier);
286
- return hash % totalBuckets < effectiveBuckets;
268
+ return (0, greyMatcher_1.isHitGreyConfig)(config, identifier, defaultValue);
287
269
  }
288
270
  /**
289
271
  * 停止定时刷新,清理资源
@@ -312,14 +294,6 @@ _ShieldConfigManager_serviceName = new WeakMap(), _ShieldConfigManager_env = new
312
294
  __classPrivateFieldGet(this, _ShieldConfigManager_instances, "m", _ShieldConfigManager_startRefreshTimer).call(this);
313
295
  __classPrivateFieldSet(this, _ShieldConfigManager_isSetup, true, "f");
314
296
  __classPrivateFieldGet(this, _ShieldConfigManager_logger, "f").info('ShieldConfigManager initialized successfully');
315
- }, _ShieldConfigManager_hashString = function _ShieldConfigManager_hashString(str) {
316
- let hash = 0;
317
- for (let i = 0; i < str.length; i++) {
318
- const char = str.charCodeAt(i);
319
- hash = (hash << 5) - hash + char;
320
- hash = hash & hash; // Convert to 32bit integer
321
- }
322
- return Math.abs(hash);
323
297
  }, _ShieldConfigManager_startRefreshTimer = function _ShieldConfigManager_startRefreshTimer() {
324
298
  __classPrivateFieldSet(this, _ShieldConfigManager_refreshTimer, setInterval(() => {
325
299
  this.refresh().catch((error) => {
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 流量控制配置
3
+ * Shared by ShieldConfigManager and ShieldCloudFunctionConfig.
4
+ */
5
+ export interface TrafficControlConfig {
6
+ /** 总开关 */
7
+ enabled: boolean;
8
+ /** 总桶数 */
9
+ totalBuckets: number;
10
+ /** 生效桶数(bucket 0 到 effectiveBuckets-1 生效) */
11
+ effectiveBuckets: number;
12
+ /** 白名单(命中后视为生效) */
13
+ whitelist?: string[];
14
+ /** 黑名单(命中后视为不生效) */
15
+ blacklist?: string[];
16
+ }
17
+ export declare function hashString(str: string): number;
18
+ export declare function isHitGreyConfig(config: TrafficControlConfig | null | undefined, identifier: string, defaultValue?: boolean): boolean;
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hashString = hashString;
4
+ exports.isHitGreyConfig = isHitGreyConfig;
5
+ function hashString(str) {
6
+ let hash = 0;
7
+ for (let i = 0; i < str.length; i++) {
8
+ const char = str.charCodeAt(i);
9
+ hash = (hash << 5) - hash + char;
10
+ hash = hash & hash; // Convert to 32bit integer
11
+ }
12
+ return Math.abs(hash);
13
+ }
14
+ function isHitGreyConfig(config, identifier, defaultValue = false) {
15
+ if (!config) {
16
+ return defaultValue;
17
+ }
18
+ if (!config.enabled) {
19
+ return false;
20
+ }
21
+ if (config.blacklist && config.blacklist.includes(identifier)) {
22
+ return false;
23
+ }
24
+ if (config.whitelist && config.whitelist.includes(identifier)) {
25
+ return true;
26
+ }
27
+ const totalBuckets = config.totalBuckets || 100;
28
+ const effectiveBuckets = config.effectiveBuckets || 0;
29
+ const hash = hashString(identifier);
30
+ return hash % totalBuckets < effectiveBuckets;
31
+ }
@@ -18,6 +18,15 @@ export declare class ConfigServiceV2 extends BaseService implements ServiceV2.Co
18
18
  * @returns 配置数据映射
19
19
  */
20
20
  fetchConfigs(req: ServiceV2.Request.FetchConfigs): Promise<ServiceV2.Response.FetchConfigsResponse>;
21
+ /**
22
+ * 云函数单 Key 配置读取
23
+ * @param req 请求参数
24
+ * @param options 请求选项
25
+ * @returns 解析后的配置数据,如果配置不存在返回 null
26
+ */
27
+ fetchCloudFunctionConfigKey(req: ServiceV2.Request.FetchCloudFunctionConfigKey, options?: {
28
+ timeoutMs?: number;
29
+ }): Promise<ServiceV2.Response.FetchCloudFunctionConfigKeyResponse | null>;
21
30
  /**
22
31
  * 获取所有服务列表
23
32
  * @param env 环境名称(可选,默认使用当前环境)
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.backendConfigServiceV2 = exports.ConfigServiceV2 = void 0;
7
7
  const http_1 = require("../../utils/http");
8
+ const cloudFunctionHttp_1 = require("../../utils/cloudFunctionHttp");
8
9
  const BaseService_1 = __importDefault(require("../BaseService"));
9
10
  /**
10
11
  * V2 配置服务
@@ -33,6 +34,15 @@ class ConfigServiceV2 extends BaseService_1.default {
33
34
  fetchConfigs(req) {
34
35
  return (0, http_1.callApi)(this.getApiUrlV2('/fetch-batch'), req).catch(() => ({}));
35
36
  }
37
+ /**
38
+ * 云函数单 Key 配置读取
39
+ * @param req 请求参数
40
+ * @param options 请求选项
41
+ * @returns 解析后的配置数据,如果配置不存在返回 null
42
+ */
43
+ fetchCloudFunctionConfigKey(req, options) {
44
+ return (0, cloudFunctionHttp_1.quietPost)(this.getApiUrlV2('/cloud-function/fetch-key'), req, { timeoutMs: options?.timeoutMs ?? 2000 });
45
+ }
36
46
  /**
37
47
  * 获取所有服务列表
38
48
  * @param env 环境名称(可选,默认使用当前环境)
@@ -47,6 +47,14 @@ export declare namespace ServiceV2 {
47
47
  serviceName: string;
48
48
  env?: string;
49
49
  }
50
+ /**
51
+ * 云函数单 Key 配置请求参数
52
+ */
53
+ interface FetchCloudFunctionConfigKey {
54
+ service: string;
55
+ key: string;
56
+ env?: string;
57
+ }
50
58
  }
51
59
  namespace Response {
52
60
  /**
@@ -72,6 +80,20 @@ export declare namespace ServiceV2 {
72
80
  * 获取服务配置键列表响应
73
81
  */
74
82
  type GetServiceKeysResponse = string[];
83
+ /**
84
+ * 云函数单 Key 配置缓存命中来源
85
+ */
86
+ type CloudFunctionConfigKeySource = 'local' | 'redis' | 'mysql';
87
+ /**
88
+ * 云函数单 Key 配置响应
89
+ */
90
+ interface FetchCloudFunctionConfigKeyResponse {
91
+ key: string;
92
+ value: any;
93
+ value_type: 'string' | 'number' | 'boolean' | 'object' | 'array' | string;
94
+ updated_at?: string;
95
+ source: CloudFunctionConfigKeySource;
96
+ }
75
97
  }
76
98
  /**
77
99
  * V2 配置控制器接口
@@ -102,5 +124,13 @@ export declare namespace ServiceV2 {
102
124
  * @returns 配置键列表
103
125
  */
104
126
  getServiceKeys(serviceName: string, env?: string): Promise<Response.GetServiceKeysResponse>;
127
+ /**
128
+ * 云函数单 Key 配置读取
129
+ * @param req 请求参数
130
+ * @returns 解析后的配置数据,配置不存在时返回 null
131
+ */
132
+ fetchCloudFunctionConfigKey(req: Request.FetchCloudFunctionConfigKey, options?: {
133
+ timeoutMs?: number;
134
+ }): Promise<Response.FetchCloudFunctionConfigKeyResponse | null>;
105
135
  }
106
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@be-link/shield-for-tcb-node-sdk",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "ShieldForTCB Node.js SDK",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -0,0 +1,5 @@
1
+ type QuietPostOptions = {
2
+ timeoutMs: number;
3
+ };
4
+ export declare function quietPost<T>(url: string, request: Record<string, any>, options: QuietPostOptions): Promise<T>;
5
+ export {};
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.quietPost = quietPost;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const uuid_1 = require("uuid");
9
+ // 云函数单 Key 接口专用 axios 实例:不挂载 axios-retry,避免对每次单 key 读取做重试放大请求。
10
+ const cloudFunctionAxios = axios_1.default.create();
11
+ async function quietPost(url, request, options) {
12
+ const requestId = (0, uuid_1.v4)();
13
+ const response = await cloudFunctionAxios.post(url, request || {}, {
14
+ timeout: options.timeoutMs,
15
+ headers: { 'x-request-id': requestId, 'content-type': 'application/json' },
16
+ });
17
+ const responseData = response.data;
18
+ return responseData.data;
19
+ }