@openfeature/web-sdk 1.6.2 → 1.7.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.
@@ -235,12 +235,18 @@ var OpenFeature = (() => {
235
235
  // src/index.ts
236
236
  var index_exports = {};
237
237
  __export(index_exports, {
238
+ AggregateError: () => AggregateError,
238
239
  AllProviderEvents: () => ClientProviderEvents,
239
240
  AllProviderStatus: () => ClientProviderStatus,
241
+ BaseEvaluationStrategy: () => BaseEvaluationStrategy,
240
242
  ClientProviderEvents: () => ClientProviderEvents,
241
243
  ClientProviderStatus: () => ClientProviderStatus,
244
+ ComparisonStrategy: () => ComparisonStrategy,
242
245
  DefaultLogger: () => DefaultLogger,
243
246
  ErrorCode: () => ErrorCode,
247
+ ErrorWithCode: () => ErrorWithCode,
248
+ FirstMatchStrategy: () => FirstMatchStrategy,
249
+ FirstSuccessfulStrategy: () => FirstSuccessfulStrategy,
244
250
  FlagNotFoundError: () => FlagNotFoundError,
245
251
  GeneralError: () => GeneralError,
246
252
  GenericEventEmitter: () => GenericEventEmitter,
@@ -248,6 +254,7 @@ var OpenFeature = (() => {
248
254
  InvalidContextError: () => InvalidContextError,
249
255
  LOG_LEVELS: () => LOG_LEVELS,
250
256
  MapHookData: () => MapHookData,
257
+ MultiProvider: () => MultiProvider,
251
258
  NOOP_PROVIDER: () => NOOP_PROVIDER,
252
259
  OpenFeature: () => OpenFeature,
253
260
  OpenFeatureAPI: () => OpenFeatureAPI,
@@ -268,13 +275,15 @@ var OpenFeature = (() => {
268
275
  TelemetryAttribute: () => TelemetryAttribute,
269
276
  TelemetryFlagMetadata: () => TelemetryFlagMetadata,
270
277
  TypeMismatchError: () => TypeMismatchError,
278
+ constructAggregateError: () => constructAggregateError,
271
279
  createEvaluationEvent: () => createEvaluationEvent,
272
280
  instantiateErrorByErrorCode: () => instantiateErrorByErrorCode,
273
281
  isObject: () => isObject,
274
282
  isString: () => isString,
275
283
  objectOrUndefined: () => objectOrUndefined,
276
284
  statusMatchesEvent: () => statusMatchesEvent,
277
- stringOrUndefined: () => stringOrUndefined
285
+ stringOrUndefined: () => stringOrUndefined,
286
+ throwAggregateErrorFromPromiseResults: () => throwAggregateErrorFromPromiseResults
278
287
  });
279
288
 
280
289
  // ../shared/src/hooks/hook-data.ts
@@ -1259,6 +1268,509 @@ var OpenFeature = (() => {
1259
1268
  }
1260
1269
  };
1261
1270
 
1271
+ // src/provider/multi-provider/hook-executor.ts
1272
+ var HookExecutor = class {
1273
+ constructor(logger) {
1274
+ this.logger = logger;
1275
+ }
1276
+ beforeHooks(hooks, hookContext, hints) {
1277
+ var _a;
1278
+ for (const hook of hooks != null ? hooks : []) {
1279
+ (_a = hook == null ? void 0 : hook.before) == null ? void 0 : _a.call(hook, hookContext, Object.freeze(hints));
1280
+ }
1281
+ }
1282
+ afterHooks(hooks, hookContext, evaluationDetails, hints) {
1283
+ var _a;
1284
+ for (const hook of hooks != null ? hooks : []) {
1285
+ (_a = hook == null ? void 0 : hook.after) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, hints);
1286
+ }
1287
+ }
1288
+ errorHooks(hooks, hookContext, err, hints) {
1289
+ var _a;
1290
+ for (const hook of hooks != null ? hooks : []) {
1291
+ try {
1292
+ (_a = hook == null ? void 0 : hook.error) == null ? void 0 : _a.call(hook, hookContext, err, hints);
1293
+ } catch (err2) {
1294
+ this.logger.error(`Unhandled error during 'error' hook: ${err2}`);
1295
+ if (err2 instanceof Error) {
1296
+ this.logger.error(err2.stack);
1297
+ }
1298
+ }
1299
+ }
1300
+ }
1301
+ finallyHooks(hooks, hookContext, evaluationDetails, hints) {
1302
+ var _a;
1303
+ for (const hook of hooks != null ? hooks : []) {
1304
+ try {
1305
+ (_a = hook == null ? void 0 : hook.finally) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, hints);
1306
+ } catch (err) {
1307
+ this.logger.error(`Unhandled error during 'finally' hook: ${err}`);
1308
+ if (err instanceof Error) {
1309
+ this.logger.error(err.stack);
1310
+ }
1311
+ }
1312
+ }
1313
+ }
1314
+ };
1315
+
1316
+ // src/provider/multi-provider/errors.ts
1317
+ var ErrorWithCode = class extends OpenFeatureError {
1318
+ constructor(code, message) {
1319
+ super(message);
1320
+ this.code = code;
1321
+ }
1322
+ };
1323
+ var AggregateError = class extends GeneralError {
1324
+ constructor(message, originalErrors) {
1325
+ super(message);
1326
+ this.originalErrors = originalErrors;
1327
+ }
1328
+ };
1329
+ var constructAggregateError = (providerErrors) => {
1330
+ const errorsWithSource = providerErrors.map(({ providerName, error }) => {
1331
+ return { source: providerName, error };
1332
+ }).flat();
1333
+ return new AggregateError(
1334
+ `Provider errors occurred: ${errorsWithSource[0].source}: ${errorsWithSource[0].error}`,
1335
+ errorsWithSource
1336
+ );
1337
+ };
1338
+ var throwAggregateErrorFromPromiseResults = (result, providerEntries) => {
1339
+ const errors = result.map((r, i) => {
1340
+ if (r.status === "rejected") {
1341
+ return { error: r.reason, providerName: providerEntries[i].name };
1342
+ }
1343
+ return null;
1344
+ }).filter((val) => Boolean(val));
1345
+ if (errors.length) {
1346
+ throw constructAggregateError(errors);
1347
+ }
1348
+ };
1349
+
1350
+ // src/provider/multi-provider/strategies/base-evaluation-strategy.ts
1351
+ var BaseEvaluationStrategy = class {
1352
+ shouldEvaluateThisProvider(strategyContext, _evalContext) {
1353
+ if (strategyContext.providerStatus === "NOT_READY" /* NOT_READY */ || strategyContext.providerStatus === "FATAL" /* FATAL */) {
1354
+ return false;
1355
+ }
1356
+ return true;
1357
+ }
1358
+ shouldEvaluateNextProvider(_strategyContext, _context, _result) {
1359
+ return true;
1360
+ }
1361
+ shouldTrackWithThisProvider(strategyContext, _context, _trackingEventName, _trackingEventDetails) {
1362
+ if (strategyContext.providerStatus === "NOT_READY" /* NOT_READY */ || strategyContext.providerStatus === "FATAL" /* FATAL */) {
1363
+ return false;
1364
+ }
1365
+ return true;
1366
+ }
1367
+ hasError(resolution) {
1368
+ return "thrownError" in resolution || !!resolution.details.errorCode;
1369
+ }
1370
+ hasErrorWithCode(resolution, code) {
1371
+ var _a;
1372
+ return "thrownError" in resolution ? ((_a = resolution.thrownError) == null ? void 0 : _a.code) === code : resolution.details.errorCode === code;
1373
+ }
1374
+ collectProviderErrors(resolutions) {
1375
+ var _a;
1376
+ const errors = [];
1377
+ for (const resolution of resolutions) {
1378
+ if ("thrownError" in resolution) {
1379
+ errors.push({ providerName: resolution.providerName, error: resolution.thrownError });
1380
+ } else if (resolution.details.errorCode) {
1381
+ errors.push({
1382
+ providerName: resolution.providerName,
1383
+ error: new ErrorWithCode(resolution.details.errorCode, (_a = resolution.details.errorMessage) != null ? _a : "unknown error")
1384
+ });
1385
+ }
1386
+ }
1387
+ return { errors };
1388
+ }
1389
+ resolutionToFinalResult(resolution) {
1390
+ return { details: resolution.details, provider: resolution.provider, providerName: resolution.providerName };
1391
+ }
1392
+ };
1393
+
1394
+ // src/provider/multi-provider/strategies/first-match-strategy.ts
1395
+ var FirstMatchStrategy = class extends BaseEvaluationStrategy {
1396
+ shouldEvaluateNextProvider(strategyContext, context, result) {
1397
+ if (this.hasErrorWithCode(result, "FLAG_NOT_FOUND" /* FLAG_NOT_FOUND */)) {
1398
+ return true;
1399
+ }
1400
+ if (this.hasError(result)) {
1401
+ return false;
1402
+ }
1403
+ return false;
1404
+ }
1405
+ determineFinalResult(strategyContext, context, resolutions) {
1406
+ const finalResolution = resolutions[resolutions.length - 1];
1407
+ if (this.hasError(finalResolution)) {
1408
+ return this.collectProviderErrors(resolutions);
1409
+ }
1410
+ return this.resolutionToFinalResult(finalResolution);
1411
+ }
1412
+ };
1413
+
1414
+ // src/provider/multi-provider/strategies/first-successful-strategy.ts
1415
+ var FirstSuccessfulStrategy = class extends BaseEvaluationStrategy {
1416
+ shouldEvaluateNextProvider(strategyContext, context, result) {
1417
+ return this.hasError(result);
1418
+ }
1419
+ determineFinalResult(strategyContext, context, resolutions) {
1420
+ const finalResolution = resolutions[resolutions.length - 1];
1421
+ if (this.hasError(finalResolution)) {
1422
+ return this.collectProviderErrors(resolutions);
1423
+ }
1424
+ return this.resolutionToFinalResult(finalResolution);
1425
+ }
1426
+ };
1427
+
1428
+ // src/provider/multi-provider/strategies/comparison-strategy.ts
1429
+ var ComparisonStrategy = class extends BaseEvaluationStrategy {
1430
+ constructor(fallbackProvider, onMismatch) {
1431
+ super();
1432
+ this.fallbackProvider = fallbackProvider;
1433
+ this.onMismatch = onMismatch;
1434
+ }
1435
+ determineFinalResult(strategyContext, context, resolutions) {
1436
+ var _a;
1437
+ let value;
1438
+ let fallbackResolution;
1439
+ let finalResolution;
1440
+ let mismatch = false;
1441
+ for (const [i, resolution] of resolutions.entries()) {
1442
+ if (this.hasError(resolution)) {
1443
+ return this.collectProviderErrors(resolutions);
1444
+ }
1445
+ if (resolution.provider === this.fallbackProvider) {
1446
+ fallbackResolution = resolution;
1447
+ }
1448
+ if (i === 0) {
1449
+ finalResolution = resolution;
1450
+ }
1451
+ if (typeof value !== "undefined" && value !== resolution.details.value) {
1452
+ mismatch = true;
1453
+ } else {
1454
+ value = resolution.details.value;
1455
+ }
1456
+ }
1457
+ if (!fallbackResolution) {
1458
+ throw new GeneralError("Fallback provider not found in resolution results");
1459
+ }
1460
+ if (!finalResolution) {
1461
+ throw new GeneralError("Final resolution not found in resolution results");
1462
+ }
1463
+ if (mismatch) {
1464
+ (_a = this.onMismatch) == null ? void 0 : _a.call(this, resolutions);
1465
+ return {
1466
+ details: fallbackResolution.details,
1467
+ provider: fallbackResolution.provider
1468
+ };
1469
+ }
1470
+ return this.resolutionToFinalResult(finalResolution);
1471
+ }
1472
+ };
1473
+
1474
+ // src/provider/multi-provider/status-tracker.ts
1475
+ var StatusTracker = class {
1476
+ constructor(events) {
1477
+ this.events = events;
1478
+ this.providerStatuses = {};
1479
+ }
1480
+ wrapEventHandler(providerEntry) {
1481
+ var _a, _b, _c, _d, _e;
1482
+ const provider = providerEntry.provider;
1483
+ (_a = provider.events) == null ? void 0 : _a.addHandler("PROVIDER_ERROR" /* Error */, (details) => {
1484
+ this.changeProviderStatus(providerEntry.name, "ERROR" /* ERROR */, details);
1485
+ });
1486
+ (_b = provider.events) == null ? void 0 : _b.addHandler("PROVIDER_STALE" /* Stale */, (details) => {
1487
+ this.changeProviderStatus(providerEntry.name, "STALE" /* STALE */, details);
1488
+ });
1489
+ (_c = provider.events) == null ? void 0 : _c.addHandler("PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */, (details) => {
1490
+ this.events.emit("PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */, details);
1491
+ });
1492
+ (_d = provider.events) == null ? void 0 : _d.addHandler("PROVIDER_READY" /* Ready */, (details) => {
1493
+ this.changeProviderStatus(providerEntry.name, "READY" /* READY */, details);
1494
+ });
1495
+ (_e = provider.events) == null ? void 0 : _e.addHandler("PROVIDER_RECONCILING" /* Reconciling */, (details) => {
1496
+ this.changeProviderStatus(providerEntry.name, "RECONCILING" /* RECONCILING */, details);
1497
+ });
1498
+ }
1499
+ providerStatus(name) {
1500
+ return this.providerStatuses[name];
1501
+ }
1502
+ getStatusFromProviderStatuses() {
1503
+ const statuses = Object.values(this.providerStatuses);
1504
+ if (statuses.includes("FATAL" /* FATAL */)) {
1505
+ return "FATAL" /* FATAL */;
1506
+ } else if (statuses.includes("NOT_READY" /* NOT_READY */)) {
1507
+ return "NOT_READY" /* NOT_READY */;
1508
+ } else if (statuses.includes("ERROR" /* ERROR */)) {
1509
+ return "ERROR" /* ERROR */;
1510
+ } else if (statuses.includes("STALE" /* STALE */)) {
1511
+ return "STALE" /* STALE */;
1512
+ } else if (statuses.includes("RECONCILING" /* RECONCILING */)) {
1513
+ return "RECONCILING" /* RECONCILING */;
1514
+ }
1515
+ return "READY" /* READY */;
1516
+ }
1517
+ changeProviderStatus(name, status, details) {
1518
+ const currentStatus = this.getStatusFromProviderStatuses();
1519
+ this.providerStatuses[name] = status;
1520
+ const newStatus = this.getStatusFromProviderStatuses();
1521
+ if (currentStatus !== newStatus) {
1522
+ if (newStatus === "FATAL" /* FATAL */ || newStatus === "ERROR" /* ERROR */) {
1523
+ this.events.emit("PROVIDER_ERROR" /* Error */, details);
1524
+ } else if (newStatus === "STALE" /* STALE */) {
1525
+ this.events.emit("PROVIDER_STALE" /* Stale */, details);
1526
+ } else if (newStatus === "READY" /* READY */) {
1527
+ this.events.emit("PROVIDER_READY" /* Ready */, details);
1528
+ } else if (newStatus === "RECONCILING" /* RECONCILING */) {
1529
+ this.events.emit("PROVIDER_RECONCILING" /* Reconciling */, details);
1530
+ }
1531
+ }
1532
+ }
1533
+ };
1534
+
1535
+ // src/provider/multi-provider/multi-provider-web.ts
1536
+ var MultiProvider = class _MultiProvider {
1537
+ constructor(constructorProviders, evaluationStrategy = new FirstMatchStrategy(), logger = new DefaultLogger()) {
1538
+ this.constructorProviders = constructorProviders;
1539
+ this.evaluationStrategy = evaluationStrategy;
1540
+ this.logger = logger;
1541
+ this.runsOn = "client";
1542
+ this.events = new OpenFeatureEventEmitter();
1543
+ this.hookContexts = /* @__PURE__ */ new WeakMap();
1544
+ this.hookHints = /* @__PURE__ */ new WeakMap();
1545
+ this.providerEntries = [];
1546
+ this.providerEntriesByName = {};
1547
+ this.statusTracker = new StatusTracker(this.events);
1548
+ this.hookExecutor = new HookExecutor(this.logger);
1549
+ this.registerProviders(constructorProviders);
1550
+ const aggregateMetadata = Object.keys(this.providerEntriesByName).reduce((acc, name) => {
1551
+ return __spreadProps(__spreadValues({}, acc), { [name]: this.providerEntriesByName[name].provider.metadata });
1552
+ }, {});
1553
+ this.metadata = __spreadProps(__spreadValues({}, aggregateMetadata), {
1554
+ name: _MultiProvider.name
1555
+ });
1556
+ }
1557
+ registerProviders(constructorProviders) {
1558
+ var _a, _b;
1559
+ const providersByName = {};
1560
+ for (const constructorProvider of constructorProviders) {
1561
+ const providerName = constructorProvider.provider.metadata.name;
1562
+ const candidateName = (_a = constructorProvider.name) != null ? _a : providerName;
1563
+ if (constructorProvider.name && providersByName[constructorProvider.name]) {
1564
+ throw new Error("Provider names must be unique");
1565
+ }
1566
+ (_b = providersByName[candidateName]) != null ? _b : providersByName[candidateName] = [];
1567
+ providersByName[candidateName].push(constructorProvider.provider);
1568
+ }
1569
+ for (const name of Object.keys(providersByName)) {
1570
+ const useIndexedNames = providersByName[name].length > 1;
1571
+ for (let i = 0; i < providersByName[name].length; i++) {
1572
+ const indexedName = useIndexedNames ? `${name}-${i + 1}` : name;
1573
+ this.providerEntriesByName[indexedName] = { provider: providersByName[name][i], name: indexedName };
1574
+ this.providerEntries.push(this.providerEntriesByName[indexedName]);
1575
+ this.statusTracker.wrapEventHandler(this.providerEntriesByName[indexedName]);
1576
+ }
1577
+ }
1578
+ Object.freeze(this.providerEntries);
1579
+ Object.freeze(this.providerEntriesByName);
1580
+ }
1581
+ initialize(context) {
1582
+ return __async(this, null, function* () {
1583
+ const result = yield Promise.allSettled(
1584
+ this.providerEntries.map((provider) => {
1585
+ var _a, _b;
1586
+ return (_b = (_a = provider.provider).initialize) == null ? void 0 : _b.call(_a, context);
1587
+ })
1588
+ );
1589
+ throwAggregateErrorFromPromiseResults(result, this.providerEntries);
1590
+ });
1591
+ }
1592
+ onClose() {
1593
+ return __async(this, null, function* () {
1594
+ const result = yield Promise.allSettled(this.providerEntries.map((provider) => {
1595
+ var _a, _b;
1596
+ return (_b = (_a = provider.provider).onClose) == null ? void 0 : _b.call(_a);
1597
+ }));
1598
+ throwAggregateErrorFromPromiseResults(result, this.providerEntries);
1599
+ });
1600
+ }
1601
+ onContextChange(oldContext, newContext) {
1602
+ return __async(this, null, function* () {
1603
+ var _a, _b;
1604
+ for (const providerEntry of this.providerEntries) {
1605
+ yield (_b = (_a = providerEntry.provider).onContextChange) == null ? void 0 : _b.call(_a, oldContext, newContext);
1606
+ }
1607
+ });
1608
+ }
1609
+ resolveBooleanEvaluation(flagKey, defaultValue, context) {
1610
+ return this.flagResolutionProxy(flagKey, "boolean", defaultValue, context);
1611
+ }
1612
+ resolveStringEvaluation(flagKey, defaultValue, context) {
1613
+ return this.flagResolutionProxy(flagKey, "string", defaultValue, context);
1614
+ }
1615
+ resolveNumberEvaluation(flagKey, defaultValue, context) {
1616
+ return this.flagResolutionProxy(flagKey, "number", defaultValue, context);
1617
+ }
1618
+ resolveObjectEvaluation(flagKey, defaultValue, context) {
1619
+ return this.flagResolutionProxy(flagKey, "object", defaultValue, context);
1620
+ }
1621
+ track(trackingEventName, context, trackingEventDetails) {
1622
+ var _a, _b;
1623
+ for (const providerEntry of this.providerEntries) {
1624
+ if (!providerEntry.provider.track) {
1625
+ continue;
1626
+ }
1627
+ const strategyContext = {
1628
+ provider: providerEntry.provider,
1629
+ providerName: providerEntry.name,
1630
+ providerStatus: this.statusTracker.providerStatus(providerEntry.name)
1631
+ };
1632
+ if (this.evaluationStrategy.shouldTrackWithThisProvider(
1633
+ strategyContext,
1634
+ context,
1635
+ trackingEventName,
1636
+ trackingEventDetails
1637
+ )) {
1638
+ try {
1639
+ (_b = (_a = providerEntry.provider).track) == null ? void 0 : _b.call(_a, trackingEventName, context, trackingEventDetails);
1640
+ } catch (error) {
1641
+ this.logger.error(
1642
+ `Error tracking event "${trackingEventName}" with provider "${providerEntry.name}":`,
1643
+ error
1644
+ );
1645
+ }
1646
+ }
1647
+ }
1648
+ }
1649
+ flagResolutionProxy(flagKey, flagType, defaultValue, context) {
1650
+ var _a;
1651
+ const hookContext = this.hookContexts.get(context);
1652
+ const hookHints = this.hookHints.get(context);
1653
+ if (!hookContext || !hookHints) {
1654
+ throw new GeneralError("Hook context not available for evaluation");
1655
+ }
1656
+ const results = [];
1657
+ for (const providerEntry of this.providerEntries) {
1658
+ const [shouldEvaluateNext, result] = this.evaluateProviderEntry(
1659
+ flagKey,
1660
+ flagType,
1661
+ defaultValue,
1662
+ providerEntry,
1663
+ hookContext,
1664
+ hookHints,
1665
+ context
1666
+ );
1667
+ results.push(result);
1668
+ if (!shouldEvaluateNext) {
1669
+ break;
1670
+ }
1671
+ }
1672
+ const resolutions = results.filter((r) => Boolean(r));
1673
+ const finalResult = this.evaluationStrategy.determineFinalResult({ flagKey, flagType }, context, resolutions);
1674
+ if ((_a = finalResult.errors) == null ? void 0 : _a.length) {
1675
+ throw constructAggregateError(finalResult.errors);
1676
+ }
1677
+ if (!finalResult.details) {
1678
+ throw new GeneralError("No result was returned from any provider");
1679
+ }
1680
+ return finalResult.details;
1681
+ }
1682
+ evaluateProviderEntry(flagKey, flagType, defaultValue, providerEntry, hookContext, hookHints, context) {
1683
+ let evaluationResult = void 0;
1684
+ const provider = providerEntry.provider;
1685
+ const strategyContext = {
1686
+ flagKey,
1687
+ flagType,
1688
+ provider,
1689
+ providerName: providerEntry.name,
1690
+ providerStatus: this.statusTracker.providerStatus(providerEntry.name)
1691
+ };
1692
+ if (!this.evaluationStrategy.shouldEvaluateThisProvider(strategyContext, context)) {
1693
+ return [true, null];
1694
+ }
1695
+ let resolution;
1696
+ try {
1697
+ evaluationResult = this.evaluateProviderAndHooks(flagKey, defaultValue, provider, hookContext, hookHints);
1698
+ resolution = {
1699
+ details: evaluationResult,
1700
+ provider,
1701
+ providerName: providerEntry.name
1702
+ };
1703
+ } catch (error) {
1704
+ resolution = {
1705
+ thrownError: error,
1706
+ provider,
1707
+ providerName: providerEntry.name
1708
+ };
1709
+ }
1710
+ return [this.evaluationStrategy.shouldEvaluateNextProvider(strategyContext, context, resolution), resolution];
1711
+ }
1712
+ evaluateProviderAndHooks(flagKey, defaultValue, provider, hookContext, hookHints) {
1713
+ var _a;
1714
+ let evaluationDetails;
1715
+ try {
1716
+ this.hookExecutor.beforeHooks(provider.hooks, hookContext, hookHints);
1717
+ const resolutionDetails = this.callProviderResolve(
1718
+ provider,
1719
+ flagKey,
1720
+ defaultValue,
1721
+ hookContext.context
1722
+ );
1723
+ evaluationDetails = __spreadProps(__spreadValues({}, resolutionDetails), {
1724
+ flagMetadata: Object.freeze((_a = resolutionDetails.flagMetadata) != null ? _a : {}),
1725
+ flagKey
1726
+ });
1727
+ this.hookExecutor.afterHooks(provider.hooks, hookContext, evaluationDetails, hookHints);
1728
+ } catch (error) {
1729
+ this.hookExecutor.errorHooks(provider.hooks, hookContext, error, hookHints);
1730
+ evaluationDetails = this.getErrorEvaluationDetails(flagKey, defaultValue, error);
1731
+ }
1732
+ this.hookExecutor.finallyHooks(provider.hooks, hookContext, evaluationDetails, hookHints);
1733
+ return evaluationDetails;
1734
+ }
1735
+ callProviderResolve(provider, flagKey, defaultValue, context) {
1736
+ switch (typeof defaultValue) {
1737
+ case "string":
1738
+ return provider.resolveStringEvaluation(flagKey, defaultValue, context, this.logger);
1739
+ case "number":
1740
+ return provider.resolveNumberEvaluation(flagKey, defaultValue, context, this.logger);
1741
+ case "object":
1742
+ return provider.resolveObjectEvaluation(flagKey, defaultValue, context, this.logger);
1743
+ case "boolean":
1744
+ return provider.resolveBooleanEvaluation(flagKey, defaultValue, context, this.logger);
1745
+ default:
1746
+ throw new GeneralError("Invalid flag evaluation type");
1747
+ }
1748
+ }
1749
+ get hooks() {
1750
+ return [
1751
+ {
1752
+ before: (hookContext, hints) => {
1753
+ this.hookContexts.set(hookContext.context, hookContext);
1754
+ this.hookHints.set(hookContext.context, hints != null ? hints : {});
1755
+ return hookContext.context;
1756
+ }
1757
+ }
1758
+ ];
1759
+ }
1760
+ getErrorEvaluationDetails(flagKey, defaultValue, err, flagMetadata = {}) {
1761
+ const errorMessage = err == null ? void 0 : err.message;
1762
+ const errorCode = (err == null ? void 0 : err.code) || "GENERAL" /* GENERAL */;
1763
+ return {
1764
+ errorCode,
1765
+ errorMessage,
1766
+ value: defaultValue,
1767
+ reason: StandardResolutionReasons.ERROR,
1768
+ flagMetadata: Object.freeze(flagMetadata),
1769
+ flagKey
1770
+ };
1771
+ }
1772
+ };
1773
+
1262
1774
  // src/client/internal/open-feature-client.ts
1263
1775
  var OpenFeatureClient = class {
1264
1776
  constructor(providerAccessor, providerStatusAccessor, emitterAccessor, apiContextAccessor, apiHooksAccessor, globalLogger, options) {