@ik-firewall/core 2.4.0 → 2.4.1

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/dist/index.cjs CHANGED
@@ -90,10 +90,10 @@ var Registry = class _Registry {
90
90
  /**
91
91
  * Loads instance configurations with Hook support
92
92
  */
93
- load() {
93
+ async load() {
94
94
  if (this.hooks?.loadState) {
95
95
  try {
96
- const hookData = this.hooks.loadState("ik_registry");
96
+ const hookData = await this.hooks.loadState("ik_registry");
97
97
  if (hookData) return JSON.parse(hookData);
98
98
  } catch (e) {
99
99
  console.warn("[IK_REGISTRY] Registry load via hook failed, falling back...");
@@ -114,10 +114,10 @@ var Registry = class _Registry {
114
114
  }
115
115
  return {};
116
116
  }
117
- save(data) {
117
+ async save(data) {
118
118
  const jsonStr = JSON.stringify(data, null, 2);
119
119
  if (this.hooks?.persistState) {
120
- this.hooks.persistState("ik_registry", jsonStr);
120
+ await this.hooks.persistState("ik_registry", jsonStr);
121
121
  }
122
122
  if (fs && this.registryPath) {
123
123
  try {
@@ -132,10 +132,10 @@ var Registry = class _Registry {
132
132
  }
133
133
  }
134
134
  }
135
- updateInstance(instanceId, config) {
136
- const all = this.load();
135
+ async updateInstance(instanceId, config) {
136
+ const all = await this.load();
137
137
  all[instanceId] = { ...all[instanceId] || {}, ...config, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
138
- this.save(all);
138
+ await this.save(all);
139
139
  }
140
140
  getUsageFilePath() {
141
141
  return this.usagePath;
@@ -158,13 +158,25 @@ var Registry = class _Registry {
158
158
  } catch (e) {
159
159
  }
160
160
  }
161
- clearUsage() {
161
+ async clearUsage() {
162
162
  if (!fs || !this.usagePath) return;
163
163
  try {
164
164
  if (fs.existsSync(this.usagePath)) fs.unlinkSync(this.usagePath);
165
165
  } catch (e) {
166
166
  }
167
167
  }
168
+ async getLastFlushTime() {
169
+ if (this.hooks?.loadState) {
170
+ const val = await this.hooks.loadState("ik_last_flush");
171
+ if (val) return parseInt(val, 10);
172
+ }
173
+ return null;
174
+ }
175
+ async setLastFlushTime(time) {
176
+ if (this.hooks?.persistState) {
177
+ await this.hooks.persistState("ik_last_flush", time.toString());
178
+ }
179
+ }
168
180
  };
169
181
 
170
182
  // src/lib/hmac.ts
@@ -210,7 +222,6 @@ var ConfigManager = class {
210
222
  if (hooks) {
211
223
  this.registry.setHooks(hooks);
212
224
  }
213
- this.loadFromRegistry();
214
225
  }
215
226
  getRegistry() {
216
227
  return this.registry;
@@ -226,16 +237,16 @@ var ConfigManager = class {
226
237
  if (state) {
227
238
  const parsed = JSON.parse(state);
228
239
  const registry = this.registry;
229
- registry.save(parsed);
230
- this.loadFromRegistry();
240
+ await registry.save(parsed);
241
+ await this.loadFromRegistry();
231
242
  }
232
243
  } catch (e) {
233
244
  console.warn("[IK_CONFIG] Hydration from hooks failed:", e);
234
245
  }
235
246
  }
236
247
  }
237
- loadFromRegistry() {
238
- const instanceConfigs = this.registry.load();
248
+ async loadFromRegistry() {
249
+ const instanceConfigs = await this.registry.load();
239
250
  this.config.instanceConfigs = {
240
251
  ...this.config.instanceConfigs || {},
241
252
  ...instanceConfigs
@@ -277,7 +288,7 @@ var ConfigManager = class {
277
288
  return;
278
289
  }
279
290
  }
280
- this.setInstanceConfig(instanceId, {
291
+ await this.setInstanceConfig(instanceId, {
281
292
  billingStatus: data.billingStatus,
282
293
  isVerified: data.isVerified,
283
294
  pricing: data.pricing,
@@ -289,7 +300,7 @@ var ConfigManager = class {
289
300
  }
290
301
  } catch (error) {
291
302
  console.error(`[IK_CONFIG] Remote sync failed (${error.message}). Falling open (Fail-Open mode).`);
292
- this.setInstanceConfig(instanceId, {
303
+ await this.setInstanceConfig(instanceId, {
293
304
  isVerified: true,
294
305
  lastSyncDate: now.toISOString()
295
306
  });
@@ -321,13 +332,13 @@ var ConfigManager = class {
321
332
  * Updates the live blocked status for an instance (Kill-Switch).
322
333
  * This is used by UsageTracker when it receives a response from the central server.
323
334
  */
324
- setBlockedStatus(instanceId, blocked) {
335
+ async setBlockedStatus(instanceId, blocked) {
325
336
  if (blocked) {
326
337
  this.blockedInstances.add(instanceId);
327
- this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
338
+ await this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
328
339
  } else {
329
340
  this.blockedInstances.delete(instanceId);
330
- this.setInstanceConfig(instanceId, { billingStatus: "active" });
341
+ await this.setInstanceConfig(instanceId, { billingStatus: "active" });
331
342
  }
332
343
  }
333
344
  updateConfig(newConfig) {
@@ -368,7 +379,7 @@ var ConfigManager = class {
368
379
  return false;
369
380
  }
370
381
  }
371
- this.setInstanceConfig(instanceId, {
382
+ await this.setInstanceConfig(instanceId, {
372
383
  licenseKey: data.licenseKey,
373
384
  billingStatus: data.status.toLowerCase(),
374
385
  isVerified: true,
@@ -384,10 +395,10 @@ var ConfigManager = class {
384
395
  return false;
385
396
  }
386
397
  }
387
- ensureInstanceConfig(instanceId) {
388
- const all = this.registry.load();
398
+ async ensureInstanceConfig(instanceId) {
399
+ const all = await this.registry.load();
389
400
  if (!all[instanceId]) {
390
- this.registry.updateInstance(instanceId, {
401
+ await this.registry.updateInstance(instanceId, {
391
402
  balance: this.config.balance || 0.5,
392
403
  aggressiveness: this.config.aggressiveness || 0.5,
393
404
  isEnabled: true,
@@ -395,15 +406,15 @@ var ConfigManager = class {
395
406
  ownerEmail: this.config.ownerEmail
396
407
  // Inherit from global if not specific
397
408
  });
398
- this.loadFromRegistry();
409
+ await this.loadFromRegistry();
399
410
  }
400
411
  }
401
- getInstanceConfigs() {
412
+ async getInstanceConfigs() {
402
413
  return this.registry.load();
403
414
  }
404
- setInstanceConfig(instanceId, config) {
405
- this.registry.updateInstance(instanceId, config);
406
- this.loadFromRegistry();
415
+ async setInstanceConfig(instanceId, config) {
416
+ await this.registry.updateInstance(instanceId, config);
417
+ await this.loadFromRegistry();
407
418
  }
408
419
  };
409
420
 
@@ -1522,11 +1533,14 @@ var UsageTracker = class {
1522
1533
  }
1523
1534
  async checkFlushConditions(instanceId) {
1524
1535
  const now = Date.now();
1536
+ if (this.lastFlushTime === 0) {
1537
+ const persisted = await this.config.getRegistry().getLastFlushTime();
1538
+ if (persisted) this.lastFlushTime = persisted;
1539
+ else this.lastFlushTime = now;
1540
+ }
1525
1541
  const timeSinceFlush = now - this.lastFlushTime;
1526
1542
  if (this.aggregationMap.size >= this.BATCH_SIZE_THRESHOLD || timeSinceFlush >= this.TIME_THRESHOLD_MS) {
1527
- this.performAsyncFlush(instanceId).catch((err) => {
1528
- console.error("[IK_TRACKER] Background flush failed:", err);
1529
- });
1543
+ await this.performAsyncFlush(instanceId);
1530
1544
  }
1531
1545
  }
1532
1546
  async performAsyncFlush(instanceId) {
@@ -1535,7 +1549,8 @@ var UsageTracker = class {
1535
1549
  const reports = Array.from(this.aggregationMap.values());
1536
1550
  this.aggregationMap.clear();
1537
1551
  this.lastFlushTime = Date.now();
1538
- const licenseKey = this.config.getConfig().instanceConfigs?.[instanceId]?.licenseKey || this.config.get("licenseKey");
1552
+ const instanceConfigs = await this.config.getInstanceConfigs();
1553
+ const licenseKey = instanceConfigs[instanceId]?.licenseKey || this.config.get("licenseKey");
1539
1554
  const payload = {
1540
1555
  licenseKey: licenseKey || "TRIAL-KEY",
1541
1556
  instanceId,
@@ -1568,7 +1583,8 @@ var UsageTracker = class {
1568
1583
  try {
1569
1584
  const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
1570
1585
  if (crypto && crypto.createHmac) {
1571
- payload.signature = crypto.createHmac("sha256", hmacSecret).update(JSON.stringify(payload)).digest("hex");
1586
+ const { signature: _sig, ...signablePayload } = payload;
1587
+ payload.signature = crypto.createHmac("sha256", hmacSecret).update(JSON.stringify(signablePayload)).digest("hex");
1572
1588
  }
1573
1589
  } catch (e) {
1574
1590
  }
@@ -1594,6 +1610,7 @@ var UsageTracker = class {
1594
1610
  }
1595
1611
  } catch (e) {
1596
1612
  }
1613
+ await this.config.getRegistry().setLastFlushTime(this.lastFlushTime);
1597
1614
  this.hooks?.onFlushSuccess?.(payload);
1598
1615
  }
1599
1616
  async handleFailure(payload) {
@@ -1807,11 +1824,11 @@ var IKFirewallCore = class _IKFirewallCore {
1807
1824
  getSessionDNA() {
1808
1825
  return this.sessionDNA;
1809
1826
  }
1810
- getInstanceConfigs() {
1827
+ async getInstanceConfigs() {
1811
1828
  return this.configManager.getInstanceConfigs();
1812
1829
  }
1813
- setInstanceConfig(instanceId, config) {
1814
- this.configManager.setInstanceConfig(instanceId, config);
1830
+ async setInstanceConfig(instanceId, config) {
1831
+ await this.configManager.setInstanceConfig(instanceId, config);
1815
1832
  }
1816
1833
  /**
1817
1834
  * Discovers available providers by checking environment variables and local health.
@@ -1895,7 +1912,7 @@ var IKFirewallCore = class _IKFirewallCore {
1895
1912
  this.hydrated = true;
1896
1913
  }
1897
1914
  if (instanceId) {
1898
- this.configManager.ensureInstanceConfig(instanceId);
1915
+ await this.configManager.ensureInstanceConfig(instanceId);
1899
1916
  }
1900
1917
  const mergedConfig = this.configManager.getMergedConfig(instanceId);
1901
1918
  if (instanceId && mergedConfig?.billingStatus === "blocked") {
@@ -2030,7 +2047,7 @@ var IKFirewallCore = class _IKFirewallCore {
2030
2047
  }
2031
2048
  async analyzeAIAssisted(input, provider, personaName = "professional", instanceId, configOverride) {
2032
2049
  if (instanceId) {
2033
- this.configManager.ensureInstanceConfig(instanceId);
2050
+ await this.configManager.ensureInstanceConfig(instanceId);
2034
2051
  }
2035
2052
  const activeConfig = this.configManager.getMergedConfig(instanceId, configOverride);
2036
2053
  const locale = activeConfig?.locale || "en";
package/dist/index.d.cts CHANGED
@@ -340,8 +340,8 @@ declare class IKFirewallCore {
340
340
  getConfig(): IKConfig;
341
341
  getPlugins(): IKPluginInfo[];
342
342
  getSessionDNA(): number;
343
- getInstanceConfigs(): Record<string, Partial<IKConfig>>;
344
- setInstanceConfig(instanceId: string, config: Partial<IKConfig>): void;
343
+ getInstanceConfigs(): Promise<Record<string, Partial<IKConfig>>>;
344
+ setInstanceConfig(instanceId: string, config: Partial<IKConfig>): Promise<void>;
345
345
  /**
346
346
  * Discovers available providers by checking environment variables and local health.
347
347
  */
package/dist/index.d.ts CHANGED
@@ -340,8 +340,8 @@ declare class IKFirewallCore {
340
340
  getConfig(): IKConfig;
341
341
  getPlugins(): IKPluginInfo[];
342
342
  getSessionDNA(): number;
343
- getInstanceConfigs(): Record<string, Partial<IKConfig>>;
344
- setInstanceConfig(instanceId: string, config: Partial<IKConfig>): void;
343
+ getInstanceConfigs(): Promise<Record<string, Partial<IKConfig>>>;
344
+ setInstanceConfig(instanceId: string, config: Partial<IKConfig>): Promise<void>;
345
345
  /**
346
346
  * Discovers available providers by checking environment variables and local health.
347
347
  */
package/dist/index.js CHANGED
@@ -48,10 +48,10 @@ var Registry = class _Registry {
48
48
  /**
49
49
  * Loads instance configurations with Hook support
50
50
  */
51
- load() {
51
+ async load() {
52
52
  if (this.hooks?.loadState) {
53
53
  try {
54
- const hookData = this.hooks.loadState("ik_registry");
54
+ const hookData = await this.hooks.loadState("ik_registry");
55
55
  if (hookData) return JSON.parse(hookData);
56
56
  } catch (e) {
57
57
  console.warn("[IK_REGISTRY] Registry load via hook failed, falling back...");
@@ -72,10 +72,10 @@ var Registry = class _Registry {
72
72
  }
73
73
  return {};
74
74
  }
75
- save(data) {
75
+ async save(data) {
76
76
  const jsonStr = JSON.stringify(data, null, 2);
77
77
  if (this.hooks?.persistState) {
78
- this.hooks.persistState("ik_registry", jsonStr);
78
+ await this.hooks.persistState("ik_registry", jsonStr);
79
79
  }
80
80
  if (fs && this.registryPath) {
81
81
  try {
@@ -90,10 +90,10 @@ var Registry = class _Registry {
90
90
  }
91
91
  }
92
92
  }
93
- updateInstance(instanceId, config) {
94
- const all = this.load();
93
+ async updateInstance(instanceId, config) {
94
+ const all = await this.load();
95
95
  all[instanceId] = { ...all[instanceId] || {}, ...config, updatedAt: (/* @__PURE__ */ new Date()).toISOString() };
96
- this.save(all);
96
+ await this.save(all);
97
97
  }
98
98
  getUsageFilePath() {
99
99
  return this.usagePath;
@@ -116,13 +116,25 @@ var Registry = class _Registry {
116
116
  } catch (e) {
117
117
  }
118
118
  }
119
- clearUsage() {
119
+ async clearUsage() {
120
120
  if (!fs || !this.usagePath) return;
121
121
  try {
122
122
  if (fs.existsSync(this.usagePath)) fs.unlinkSync(this.usagePath);
123
123
  } catch (e) {
124
124
  }
125
125
  }
126
+ async getLastFlushTime() {
127
+ if (this.hooks?.loadState) {
128
+ const val = await this.hooks.loadState("ik_last_flush");
129
+ if (val) return parseInt(val, 10);
130
+ }
131
+ return null;
132
+ }
133
+ async setLastFlushTime(time) {
134
+ if (this.hooks?.persistState) {
135
+ await this.hooks.persistState("ik_last_flush", time.toString());
136
+ }
137
+ }
126
138
  };
127
139
 
128
140
  // src/lib/hmac.ts
@@ -168,7 +180,6 @@ var ConfigManager = class {
168
180
  if (hooks) {
169
181
  this.registry.setHooks(hooks);
170
182
  }
171
- this.loadFromRegistry();
172
183
  }
173
184
  getRegistry() {
174
185
  return this.registry;
@@ -184,16 +195,16 @@ var ConfigManager = class {
184
195
  if (state) {
185
196
  const parsed = JSON.parse(state);
186
197
  const registry = this.registry;
187
- registry.save(parsed);
188
- this.loadFromRegistry();
198
+ await registry.save(parsed);
199
+ await this.loadFromRegistry();
189
200
  }
190
201
  } catch (e) {
191
202
  console.warn("[IK_CONFIG] Hydration from hooks failed:", e);
192
203
  }
193
204
  }
194
205
  }
195
- loadFromRegistry() {
196
- const instanceConfigs = this.registry.load();
206
+ async loadFromRegistry() {
207
+ const instanceConfigs = await this.registry.load();
197
208
  this.config.instanceConfigs = {
198
209
  ...this.config.instanceConfigs || {},
199
210
  ...instanceConfigs
@@ -235,7 +246,7 @@ var ConfigManager = class {
235
246
  return;
236
247
  }
237
248
  }
238
- this.setInstanceConfig(instanceId, {
249
+ await this.setInstanceConfig(instanceId, {
239
250
  billingStatus: data.billingStatus,
240
251
  isVerified: data.isVerified,
241
252
  pricing: data.pricing,
@@ -247,7 +258,7 @@ var ConfigManager = class {
247
258
  }
248
259
  } catch (error) {
249
260
  console.error(`[IK_CONFIG] Remote sync failed (${error.message}). Falling open (Fail-Open mode).`);
250
- this.setInstanceConfig(instanceId, {
261
+ await this.setInstanceConfig(instanceId, {
251
262
  isVerified: true,
252
263
  lastSyncDate: now.toISOString()
253
264
  });
@@ -279,13 +290,13 @@ var ConfigManager = class {
279
290
  * Updates the live blocked status for an instance (Kill-Switch).
280
291
  * This is used by UsageTracker when it receives a response from the central server.
281
292
  */
282
- setBlockedStatus(instanceId, blocked) {
293
+ async setBlockedStatus(instanceId, blocked) {
283
294
  if (blocked) {
284
295
  this.blockedInstances.add(instanceId);
285
- this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
296
+ await this.setInstanceConfig(instanceId, { billingStatus: "blocked" });
286
297
  } else {
287
298
  this.blockedInstances.delete(instanceId);
288
- this.setInstanceConfig(instanceId, { billingStatus: "active" });
299
+ await this.setInstanceConfig(instanceId, { billingStatus: "active" });
289
300
  }
290
301
  }
291
302
  updateConfig(newConfig) {
@@ -326,7 +337,7 @@ var ConfigManager = class {
326
337
  return false;
327
338
  }
328
339
  }
329
- this.setInstanceConfig(instanceId, {
340
+ await this.setInstanceConfig(instanceId, {
330
341
  licenseKey: data.licenseKey,
331
342
  billingStatus: data.status.toLowerCase(),
332
343
  isVerified: true,
@@ -342,10 +353,10 @@ var ConfigManager = class {
342
353
  return false;
343
354
  }
344
355
  }
345
- ensureInstanceConfig(instanceId) {
346
- const all = this.registry.load();
356
+ async ensureInstanceConfig(instanceId) {
357
+ const all = await this.registry.load();
347
358
  if (!all[instanceId]) {
348
- this.registry.updateInstance(instanceId, {
359
+ await this.registry.updateInstance(instanceId, {
349
360
  balance: this.config.balance || 0.5,
350
361
  aggressiveness: this.config.aggressiveness || 0.5,
351
362
  isEnabled: true,
@@ -353,15 +364,15 @@ var ConfigManager = class {
353
364
  ownerEmail: this.config.ownerEmail
354
365
  // Inherit from global if not specific
355
366
  });
356
- this.loadFromRegistry();
367
+ await this.loadFromRegistry();
357
368
  }
358
369
  }
359
- getInstanceConfigs() {
370
+ async getInstanceConfigs() {
360
371
  return this.registry.load();
361
372
  }
362
- setInstanceConfig(instanceId, config) {
363
- this.registry.updateInstance(instanceId, config);
364
- this.loadFromRegistry();
373
+ async setInstanceConfig(instanceId, config) {
374
+ await this.registry.updateInstance(instanceId, config);
375
+ await this.loadFromRegistry();
365
376
  }
366
377
  };
367
378
 
@@ -1480,11 +1491,14 @@ var UsageTracker = class {
1480
1491
  }
1481
1492
  async checkFlushConditions(instanceId) {
1482
1493
  const now = Date.now();
1494
+ if (this.lastFlushTime === 0) {
1495
+ const persisted = await this.config.getRegistry().getLastFlushTime();
1496
+ if (persisted) this.lastFlushTime = persisted;
1497
+ else this.lastFlushTime = now;
1498
+ }
1483
1499
  const timeSinceFlush = now - this.lastFlushTime;
1484
1500
  if (this.aggregationMap.size >= this.BATCH_SIZE_THRESHOLD || timeSinceFlush >= this.TIME_THRESHOLD_MS) {
1485
- this.performAsyncFlush(instanceId).catch((err) => {
1486
- console.error("[IK_TRACKER] Background flush failed:", err);
1487
- });
1501
+ await this.performAsyncFlush(instanceId);
1488
1502
  }
1489
1503
  }
1490
1504
  async performAsyncFlush(instanceId) {
@@ -1493,7 +1507,8 @@ var UsageTracker = class {
1493
1507
  const reports = Array.from(this.aggregationMap.values());
1494
1508
  this.aggregationMap.clear();
1495
1509
  this.lastFlushTime = Date.now();
1496
- const licenseKey = this.config.getConfig().instanceConfigs?.[instanceId]?.licenseKey || this.config.get("licenseKey");
1510
+ const instanceConfigs = await this.config.getInstanceConfigs();
1511
+ const licenseKey = instanceConfigs[instanceId]?.licenseKey || this.config.get("licenseKey");
1497
1512
  const payload = {
1498
1513
  licenseKey: licenseKey || "TRIAL-KEY",
1499
1514
  instanceId,
@@ -1526,7 +1541,8 @@ var UsageTracker = class {
1526
1541
  try {
1527
1542
  const crypto = typeof window === "undefined" ? (await import("crypto")).default : null;
1528
1543
  if (crypto && crypto.createHmac) {
1529
- payload.signature = crypto.createHmac("sha256", hmacSecret).update(JSON.stringify(payload)).digest("hex");
1544
+ const { signature: _sig, ...signablePayload } = payload;
1545
+ payload.signature = crypto.createHmac("sha256", hmacSecret).update(JSON.stringify(signablePayload)).digest("hex");
1530
1546
  }
1531
1547
  } catch (e) {
1532
1548
  }
@@ -1552,6 +1568,7 @@ var UsageTracker = class {
1552
1568
  }
1553
1569
  } catch (e) {
1554
1570
  }
1571
+ await this.config.getRegistry().setLastFlushTime(this.lastFlushTime);
1555
1572
  this.hooks?.onFlushSuccess?.(payload);
1556
1573
  }
1557
1574
  async handleFailure(payload) {
@@ -1765,11 +1782,11 @@ var IKFirewallCore = class _IKFirewallCore {
1765
1782
  getSessionDNA() {
1766
1783
  return this.sessionDNA;
1767
1784
  }
1768
- getInstanceConfigs() {
1785
+ async getInstanceConfigs() {
1769
1786
  return this.configManager.getInstanceConfigs();
1770
1787
  }
1771
- setInstanceConfig(instanceId, config) {
1772
- this.configManager.setInstanceConfig(instanceId, config);
1788
+ async setInstanceConfig(instanceId, config) {
1789
+ await this.configManager.setInstanceConfig(instanceId, config);
1773
1790
  }
1774
1791
  /**
1775
1792
  * Discovers available providers by checking environment variables and local health.
@@ -1853,7 +1870,7 @@ var IKFirewallCore = class _IKFirewallCore {
1853
1870
  this.hydrated = true;
1854
1871
  }
1855
1872
  if (instanceId) {
1856
- this.configManager.ensureInstanceConfig(instanceId);
1873
+ await this.configManager.ensureInstanceConfig(instanceId);
1857
1874
  }
1858
1875
  const mergedConfig = this.configManager.getMergedConfig(instanceId);
1859
1876
  if (instanceId && mergedConfig?.billingStatus === "blocked") {
@@ -1988,7 +2005,7 @@ var IKFirewallCore = class _IKFirewallCore {
1988
2005
  }
1989
2006
  async analyzeAIAssisted(input, provider, personaName = "professional", instanceId, configOverride) {
1990
2007
  if (instanceId) {
1991
- this.configManager.ensureInstanceConfig(instanceId);
2008
+ await this.configManager.ensureInstanceConfig(instanceId);
1992
2009
  }
1993
2010
  const activeConfig = this.configManager.getMergedConfig(instanceId, configOverride);
1994
2011
  const locale = activeConfig?.locale || "en";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ik-firewall/core",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "type": "module",
5
5
  "description": "The core IK Firewall engine for semantic-driven AI optimization.",
6
6
  "main": "./dist/index.js",