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

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
@@ -182,12 +182,78 @@ error 级别日志不受 `enableInfoLog` 影响,始终打印:
182
182
  |------|------|
183
183
  | `setup()` | 初始化并启动定时刷新,幂等操作 |
184
184
  | `getConfig<T>()` | 获取类型化的配置对象 |
185
+ | `getValue<T>(key, defaultValue?)` | 根据 key 获取配置值,支持默认值 |
186
+ | `isSwitchEnabled(key, defaultValue?)` | 获取布尔开关状态 |
187
+ | `isHitGrey(configKey, identifier, defaultValue?)` | 判断是否命中灰度流量 |
185
188
  | `refresh()` | 手动触发一次配置刷新 |
186
189
  | `stop()` | 停止定时刷新,清理资源 |
187
190
  | `waitForSetup()` | 等待初始化完成 |
188
191
  | `isSetup` | 是否已完成初始化(只读属性) |
189
192
  | `config` | 当前缓存的配置(原始 Record,只读属性) |
190
193
 
194
+ ### 获取配置值
195
+
196
+ ```typescript
197
+ // 获取配置(带默认值)
198
+ const port = manager.getValue('API_PORT', 8090)
199
+
200
+ // 获取配置并指定类型
201
+ const isEnabled = manager.getValue<boolean>('FEATURE.ENABLED', false)
202
+ ```
203
+
204
+ ### 开关状态检查
205
+
206
+ ```typescript
207
+ // 检查功能是否开启(支持 true/false, 1/0, yes/no, on/off 等多种格式)
208
+ const isEnabled = manager.isSwitchEnabled('FEATURE.ENABLED')
209
+
210
+ // 指定默认值为 true
211
+ const isDebug = manager.isSwitchEnabled('DEBUG_MODE', true)
212
+ ```
213
+
214
+ ### 灰度流量控制
215
+
216
+ ```typescript
217
+ // 流量控制配置结构
218
+ interface TrafficControlConfig {
219
+ enabled: boolean // 总开关
220
+ totalBuckets: number // 总桶数
221
+ effectiveBuckets: number // 生效桶数(0 到 effectiveBuckets-1 生效)
222
+ whitelist?: string[] // 白名单(命中后视为生效)
223
+ blacklist?: string[] // 黑名单(命中后视为不生效)
224
+ }
225
+
226
+ // 判断用户是否命中灰度流量
227
+ const isHit = manager.isHitGrey('TRAFFIC_SPLIT', userId, false)
228
+ if (isHit) {
229
+ // 灰度流量逻辑
230
+ }
231
+ ```
232
+
233
+ ### 批量获取配置
234
+
235
+ ```typescript
236
+ // 原始格式
237
+ const configs = await backendConfigServiceV2.fetchConfigs({
238
+ service: 'TestService',
239
+ keys: ['TestServiceKey1', 'TestServiceKey2'],
240
+ env: 'local'
241
+ })
242
+ // 返回: { 'TestServiceKey1': { value: 'xxx', value_type: 'string' }, ... }
243
+
244
+ // 自动解析类型(推荐)
245
+ const values = await backendConfigServiceV2.getConfigValues(
246
+ 'TestService',
247
+ ['TestServiceKey1', 'TestServiceKey2', 'TestServiceKey3'],
248
+ 'local'
249
+ )
250
+ // 返回: {
251
+ // 'TestServiceKey1': 'xxx',
252
+ // 'TestServiceKey2': 123,
253
+ // 'TestServiceKey3': true
254
+ // }
255
+ ```
256
+
191
257
  ## 发布流程
192
258
 
193
259
  ### 自动发布(推荐)
@@ -112,10 +112,10 @@ class ShieldConfigManager {
112
112
  }
113
113
  __classPrivateFieldSet(this, _ShieldConfigManager_serviceName, options.serviceName, "f");
114
114
  __classPrivateFieldSet(this, _ShieldConfigManager_env, options.env || process.env.NODE_ENV, "f");
115
- __classPrivateFieldSet(this, _ShieldConfigManager_refreshIntervalMs, options.refreshIntervalMs ?? DEFAULT_REFRESH_INTERVAL_MS, "f");
116
- __classPrivateFieldSet(this, _ShieldConfigManager_fetchTimeoutMs, options.fetchTimeoutMs ?? DEFAULT_FETCH_TIMEOUT_MS, "f");
117
- __classPrivateFieldSet(this, _ShieldConfigManager_enableInfoLog, options.enableInfoLog ?? false, "f");
118
- const baseLogger = options.logger ?? defaultLogger;
115
+ __classPrivateFieldSet(this, _ShieldConfigManager_refreshIntervalMs, options.refreshIntervalMs || DEFAULT_REFRESH_INTERVAL_MS, "f");
116
+ __classPrivateFieldSet(this, _ShieldConfigManager_fetchTimeoutMs, options.fetchTimeoutMs || DEFAULT_FETCH_TIMEOUT_MS, "f");
117
+ __classPrivateFieldSet(this, _ShieldConfigManager_enableInfoLog, options.enableInfoLog || false, "f");
118
+ const baseLogger = options.logger || defaultLogger;
119
119
  __classPrivateFieldSet(this, _ShieldConfigManager_logger, __classPrivateFieldGet(this, _ShieldConfigManager_enableInfoLog, "f") ? baseLogger : { ...baseLogger, info: () => { } }, "f");
120
120
  }
121
121
  /** 当前缓存的配置副本(原始 Record) */
@@ -181,7 +181,7 @@ class ShieldConfigManager {
181
181
  * @returns 泛型 T 类型的配置对象
182
182
  */
183
183
  getConfig() {
184
- return __classPrivateFieldGet(this, _ShieldConfigManager_config, "f") ?? null;
184
+ return __classPrivateFieldGet(this, _ShieldConfigManager_config, "f") || null;
185
185
  }
186
186
  /**
187
187
  * 根据 config_key 获取对应的配置值
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@be-link/shield-for-tcb-node-sdk",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "ShieldForTCB Node.js SDK",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "access": "public"
16
16
  },
17
17
  "dependencies": {
18
- "axios": "1.13.2",
18
+ "axios": "0.27.2",
19
19
  "axios-retry": "^4.0.0",
20
20
  "uuid": "^9.0.1"
21
21
  },
package/utils/http.js CHANGED
@@ -44,7 +44,7 @@ const axios_retry_1 = __importDefault(require("axios-retry"));
44
44
  (0, axios_retry_1.default)(axios_1.default, {
45
45
  retries: 1,
46
46
  retryCondition(error) {
47
- return error.response?.status === 502;
47
+ return !!(error.response && error.response.status === 502);
48
48
  },
49
49
  retryDelay: (retryCount) => {
50
50
  console.info(`retryCount: ${retryCount}, retryDelay: ${retryCount * 500}`);
@@ -65,7 +65,7 @@ async function callApi(url, request, options) {
65
65
  return responseData.data;
66
66
  }
67
67
  catch (error) {
68
- if (options?.skipErrorHandling) {
68
+ if (options && options.skipErrorHandling) {
69
69
  throw error;
70
70
  }
71
71
  const axiosError = error;
@@ -114,7 +114,7 @@ async function getApi(url, options) {
114
114
  return responseData.data;
115
115
  }
116
116
  catch (error) {
117
- if (options?.skipErrorHandling) {
117
+ if (options && options.skipErrorHandling) {
118
118
  throw error;
119
119
  }
120
120
  const axiosError = error;