@openfeature/server-sdk 1.20.0 → 1.20.2
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/LICENSE +1 -1
- package/README.md +63 -48
- package/dist/cjs/index.js +56 -269
- package/dist/cjs/index.js.map +4 -4
- package/dist/esm/index.js +46 -249
- package/dist/esm/index.js.map +4 -4
- package/dist/types.d.ts +44 -117
- package/package.json +3 -3
package/dist/esm/index.js
CHANGED
|
@@ -39,9 +39,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
39
39
|
};
|
|
40
40
|
|
|
41
41
|
// src/provider/provider.ts
|
|
42
|
-
import {
|
|
43
|
-
ServerProviderStatus
|
|
44
|
-
} from "@openfeature/core";
|
|
42
|
+
import { ServerProviderStatus } from "@openfeature/core";
|
|
45
43
|
|
|
46
44
|
// src/provider/no-op-provider.ts
|
|
47
45
|
var REASON_NO_OP = "No-op";
|
|
@@ -171,7 +169,37 @@ var InMemoryProvider = class {
|
|
|
171
169
|
};
|
|
172
170
|
|
|
173
171
|
// src/provider/multi-provider/multi-provider.ts
|
|
174
|
-
import {
|
|
172
|
+
import {
|
|
173
|
+
DefaultLogger,
|
|
174
|
+
ErrorCode as ErrorCode2,
|
|
175
|
+
GeneralError as GeneralError2,
|
|
176
|
+
StandardResolutionReasons as StandardResolutionReasons2,
|
|
177
|
+
constructAggregateError,
|
|
178
|
+
throwAggregateErrorFromPromiseResults,
|
|
179
|
+
StatusTracker
|
|
180
|
+
} from "@openfeature/core";
|
|
181
|
+
|
|
182
|
+
// src/provider/multi-provider/strategies.ts
|
|
183
|
+
import {
|
|
184
|
+
BaseFirstMatchStrategy,
|
|
185
|
+
BaseFirstSuccessfulStrategy,
|
|
186
|
+
BaseComparisonStrategy
|
|
187
|
+
} from "@openfeature/core";
|
|
188
|
+
var FirstMatchStrategy = class extends BaseFirstMatchStrategy {
|
|
189
|
+
constructor() {
|
|
190
|
+
super(ServerProviderStatus);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
var FirstSuccessfulStrategy = class extends BaseFirstSuccessfulStrategy {
|
|
194
|
+
constructor() {
|
|
195
|
+
super(ServerProviderStatus);
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
var ComparisonStrategy = class extends BaseComparisonStrategy {
|
|
199
|
+
constructor(fallbackProvider, onMismatch) {
|
|
200
|
+
super(ServerProviderStatus, fallbackProvider, onMismatch);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
175
203
|
|
|
176
204
|
// src/events/open-feature-event-emitter.ts
|
|
177
205
|
import { GenericEventEmitter } from "@openfeature/core";
|
|
@@ -187,40 +215,8 @@ var OpenFeatureEventEmitter = class extends GenericEventEmitter {
|
|
|
187
215
|
}
|
|
188
216
|
};
|
|
189
217
|
|
|
190
|
-
// src/
|
|
191
|
-
import {
|
|
192
|
-
var ErrorWithCode = class extends OpenFeatureError3 {
|
|
193
|
-
constructor(code, message) {
|
|
194
|
-
super(message);
|
|
195
|
-
this.code = code;
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
var AggregateError = class extends GeneralError2 {
|
|
199
|
-
constructor(message, originalErrors) {
|
|
200
|
-
super(message);
|
|
201
|
-
this.originalErrors = originalErrors;
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
var constructAggregateError = (providerErrors) => {
|
|
205
|
-
const errorsWithSource = providerErrors.map(({ providerName, error }) => {
|
|
206
|
-
return { source: providerName, error };
|
|
207
|
-
}).flat();
|
|
208
|
-
return new AggregateError(
|
|
209
|
-
`Provider errors occurred: ${errorsWithSource[0].source}: ${errorsWithSource[0].error}`,
|
|
210
|
-
errorsWithSource
|
|
211
|
-
);
|
|
212
|
-
};
|
|
213
|
-
var throwAggregateErrorFromPromiseResults = (result, providerEntries) => {
|
|
214
|
-
const errors = result.map((r, i) => {
|
|
215
|
-
if (r.status === "rejected") {
|
|
216
|
-
return { error: r.reason, providerName: providerEntries[i].name };
|
|
217
|
-
}
|
|
218
|
-
return null;
|
|
219
|
-
}).filter((val) => Boolean(val));
|
|
220
|
-
if (errors.length) {
|
|
221
|
-
throw constructAggregateError(errors);
|
|
222
|
-
}
|
|
223
|
-
};
|
|
218
|
+
// src/events/events.ts
|
|
219
|
+
import { ServerProviderEvents } from "@openfeature/core";
|
|
224
220
|
|
|
225
221
|
// src/provider/multi-provider/hook-executor.ts
|
|
226
222
|
var HookExecutor = class {
|
|
@@ -279,193 +275,6 @@ var HookExecutor = class {
|
|
|
279
275
|
}
|
|
280
276
|
};
|
|
281
277
|
|
|
282
|
-
// src/events/events.ts
|
|
283
|
-
import { ServerProviderEvents } from "@openfeature/core";
|
|
284
|
-
|
|
285
|
-
// src/provider/multi-provider/status-tracker.ts
|
|
286
|
-
var StatusTracker = class {
|
|
287
|
-
constructor(events) {
|
|
288
|
-
this.events = events;
|
|
289
|
-
this.providerStatuses = {};
|
|
290
|
-
}
|
|
291
|
-
wrapEventHandler(providerEntry) {
|
|
292
|
-
var _a, _b, _c, _d;
|
|
293
|
-
const provider = providerEntry.provider;
|
|
294
|
-
(_a = provider.events) == null ? void 0 : _a.addHandler(ServerProviderEvents.Error, (details) => {
|
|
295
|
-
this.changeProviderStatus(providerEntry.name, ServerProviderStatus.ERROR, details);
|
|
296
|
-
});
|
|
297
|
-
(_b = provider.events) == null ? void 0 : _b.addHandler(ServerProviderEvents.Stale, (details) => {
|
|
298
|
-
this.changeProviderStatus(providerEntry.name, ServerProviderStatus.STALE, details);
|
|
299
|
-
});
|
|
300
|
-
(_c = provider.events) == null ? void 0 : _c.addHandler(ServerProviderEvents.ConfigurationChanged, (details) => {
|
|
301
|
-
this.events.emit(ServerProviderEvents.ConfigurationChanged, details);
|
|
302
|
-
});
|
|
303
|
-
(_d = provider.events) == null ? void 0 : _d.addHandler(ServerProviderEvents.Ready, (details) => {
|
|
304
|
-
this.changeProviderStatus(providerEntry.name, ServerProviderStatus.READY, details);
|
|
305
|
-
});
|
|
306
|
-
}
|
|
307
|
-
providerStatus(name) {
|
|
308
|
-
return this.providerStatuses[name];
|
|
309
|
-
}
|
|
310
|
-
getStatusFromProviderStatuses() {
|
|
311
|
-
const statuses = Object.values(this.providerStatuses);
|
|
312
|
-
if (statuses.includes(ServerProviderStatus.FATAL)) {
|
|
313
|
-
return ServerProviderStatus.FATAL;
|
|
314
|
-
} else if (statuses.includes(ServerProviderStatus.NOT_READY)) {
|
|
315
|
-
return ServerProviderStatus.NOT_READY;
|
|
316
|
-
} else if (statuses.includes(ServerProviderStatus.ERROR)) {
|
|
317
|
-
return ServerProviderStatus.ERROR;
|
|
318
|
-
} else if (statuses.includes(ServerProviderStatus.STALE)) {
|
|
319
|
-
return ServerProviderStatus.STALE;
|
|
320
|
-
}
|
|
321
|
-
return ServerProviderStatus.READY;
|
|
322
|
-
}
|
|
323
|
-
changeProviderStatus(name, status, details) {
|
|
324
|
-
const currentStatus = this.getStatusFromProviderStatuses();
|
|
325
|
-
this.providerStatuses[name] = status;
|
|
326
|
-
const newStatus = this.getStatusFromProviderStatuses();
|
|
327
|
-
if (currentStatus !== newStatus) {
|
|
328
|
-
if (newStatus === ServerProviderStatus.FATAL || newStatus === ServerProviderStatus.ERROR) {
|
|
329
|
-
this.events.emit(ServerProviderEvents.Error, details);
|
|
330
|
-
} else if (newStatus === ServerProviderStatus.STALE) {
|
|
331
|
-
this.events.emit(ServerProviderEvents.Stale, details);
|
|
332
|
-
} else if (newStatus === ServerProviderStatus.READY) {
|
|
333
|
-
this.events.emit(ServerProviderEvents.Ready, details);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
// src/provider/multi-provider/strategies/base-evaluation-strategy.ts
|
|
340
|
-
var BaseEvaluationStrategy = class {
|
|
341
|
-
constructor() {
|
|
342
|
-
this.runMode = "sequential";
|
|
343
|
-
}
|
|
344
|
-
shouldEvaluateThisProvider(strategyContext, _evalContext) {
|
|
345
|
-
if (strategyContext.providerStatus === ServerProviderStatus.NOT_READY || strategyContext.providerStatus === ServerProviderStatus.FATAL) {
|
|
346
|
-
return false;
|
|
347
|
-
}
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
shouldEvaluateNextProvider(_strategyContext, _context, _result) {
|
|
351
|
-
return true;
|
|
352
|
-
}
|
|
353
|
-
shouldTrackWithThisProvider(strategyContext, _context, _trackingEventName, _trackingEventDetails) {
|
|
354
|
-
if (strategyContext.providerStatus === ServerProviderStatus.NOT_READY || strategyContext.providerStatus === ServerProviderStatus.FATAL) {
|
|
355
|
-
return false;
|
|
356
|
-
}
|
|
357
|
-
return true;
|
|
358
|
-
}
|
|
359
|
-
hasError(resolution) {
|
|
360
|
-
return "thrownError" in resolution || !!resolution.details.errorCode;
|
|
361
|
-
}
|
|
362
|
-
hasErrorWithCode(resolution, code) {
|
|
363
|
-
var _a;
|
|
364
|
-
return "thrownError" in resolution ? ((_a = resolution.thrownError) == null ? void 0 : _a.code) === code : resolution.details.errorCode === code;
|
|
365
|
-
}
|
|
366
|
-
collectProviderErrors(resolutions) {
|
|
367
|
-
var _a;
|
|
368
|
-
const errors = [];
|
|
369
|
-
for (const resolution of resolutions) {
|
|
370
|
-
if ("thrownError" in resolution) {
|
|
371
|
-
errors.push({ providerName: resolution.providerName, error: resolution.thrownError });
|
|
372
|
-
} else if (resolution.details.errorCode) {
|
|
373
|
-
errors.push({
|
|
374
|
-
providerName: resolution.providerName,
|
|
375
|
-
error: new ErrorWithCode(resolution.details.errorCode, (_a = resolution.details.errorMessage) != null ? _a : "unknown error")
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
return { errors };
|
|
380
|
-
}
|
|
381
|
-
resolutionToFinalResult(resolution) {
|
|
382
|
-
return { details: resolution.details, provider: resolution.provider, providerName: resolution.providerName };
|
|
383
|
-
}
|
|
384
|
-
};
|
|
385
|
-
|
|
386
|
-
// src/provider/multi-provider/strategies/first-match-strategy.ts
|
|
387
|
-
import { ErrorCode as ErrorCode2 } from "@openfeature/core";
|
|
388
|
-
var FirstMatchStrategy = class extends BaseEvaluationStrategy {
|
|
389
|
-
shouldEvaluateNextProvider(strategyContext, context, result) {
|
|
390
|
-
if (this.hasErrorWithCode(result, ErrorCode2.FLAG_NOT_FOUND)) {
|
|
391
|
-
return true;
|
|
392
|
-
}
|
|
393
|
-
if (this.hasError(result)) {
|
|
394
|
-
return false;
|
|
395
|
-
}
|
|
396
|
-
return false;
|
|
397
|
-
}
|
|
398
|
-
determineFinalResult(strategyContext, context, resolutions) {
|
|
399
|
-
const finalResolution = resolutions[resolutions.length - 1];
|
|
400
|
-
if (this.hasError(finalResolution)) {
|
|
401
|
-
return this.collectProviderErrors(resolutions);
|
|
402
|
-
}
|
|
403
|
-
return this.resolutionToFinalResult(finalResolution);
|
|
404
|
-
}
|
|
405
|
-
};
|
|
406
|
-
|
|
407
|
-
// src/provider/multi-provider/strategies/first-successful-strategy.ts
|
|
408
|
-
var FirstSuccessfulStrategy = class extends BaseEvaluationStrategy {
|
|
409
|
-
shouldEvaluateNextProvider(strategyContext, context, result) {
|
|
410
|
-
return this.hasError(result);
|
|
411
|
-
}
|
|
412
|
-
determineFinalResult(strategyContext, context, resolutions) {
|
|
413
|
-
const finalResolution = resolutions[resolutions.length - 1];
|
|
414
|
-
if (this.hasError(finalResolution)) {
|
|
415
|
-
return this.collectProviderErrors(resolutions);
|
|
416
|
-
}
|
|
417
|
-
return this.resolutionToFinalResult(finalResolution);
|
|
418
|
-
}
|
|
419
|
-
};
|
|
420
|
-
|
|
421
|
-
// src/provider/multi-provider/strategies/comparison-strategy.ts
|
|
422
|
-
import { GeneralError as GeneralError3 } from "@openfeature/core";
|
|
423
|
-
var ComparisonStrategy = class extends BaseEvaluationStrategy {
|
|
424
|
-
constructor(fallbackProvider, onMismatch) {
|
|
425
|
-
super();
|
|
426
|
-
this.fallbackProvider = fallbackProvider;
|
|
427
|
-
this.onMismatch = onMismatch;
|
|
428
|
-
this.runMode = "parallel";
|
|
429
|
-
}
|
|
430
|
-
determineFinalResult(strategyContext, context, resolutions) {
|
|
431
|
-
var _a;
|
|
432
|
-
let value;
|
|
433
|
-
let fallbackResolution;
|
|
434
|
-
let finalResolution;
|
|
435
|
-
let mismatch = false;
|
|
436
|
-
for (const [i, resolution] of resolutions.entries()) {
|
|
437
|
-
if (this.hasError(resolution)) {
|
|
438
|
-
return this.collectProviderErrors(resolutions);
|
|
439
|
-
}
|
|
440
|
-
if (resolution.provider === this.fallbackProvider) {
|
|
441
|
-
fallbackResolution = resolution;
|
|
442
|
-
}
|
|
443
|
-
if (i === 0) {
|
|
444
|
-
finalResolution = resolution;
|
|
445
|
-
}
|
|
446
|
-
if (typeof value !== "undefined" && value !== resolution.details.value) {
|
|
447
|
-
mismatch = true;
|
|
448
|
-
} else {
|
|
449
|
-
value = resolution.details.value;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
if (!fallbackResolution) {
|
|
453
|
-
throw new GeneralError3("Fallback provider not found in resolution results");
|
|
454
|
-
}
|
|
455
|
-
if (!finalResolution) {
|
|
456
|
-
throw new GeneralError3("Final resolution not found in resolution results");
|
|
457
|
-
}
|
|
458
|
-
if (mismatch) {
|
|
459
|
-
(_a = this.onMismatch) == null ? void 0 : _a.call(this, resolutions);
|
|
460
|
-
return {
|
|
461
|
-
details: fallbackResolution.details,
|
|
462
|
-
provider: fallbackResolution.provider
|
|
463
|
-
};
|
|
464
|
-
}
|
|
465
|
-
return this.resolutionToFinalResult(finalResolution);
|
|
466
|
-
}
|
|
467
|
-
};
|
|
468
|
-
|
|
469
278
|
// src/provider/multi-provider/multi-provider.ts
|
|
470
279
|
var MultiProvider = class _MultiProvider {
|
|
471
280
|
constructor(constructorProviders, evaluationStrategy = new FirstMatchStrategy(), logger = new DefaultLogger()) {
|
|
@@ -478,7 +287,7 @@ var MultiProvider = class _MultiProvider {
|
|
|
478
287
|
this.hookHints = /* @__PURE__ */ new WeakMap();
|
|
479
288
|
this.providerEntries = [];
|
|
480
289
|
this.providerEntriesByName = {};
|
|
481
|
-
this.statusTracker = new StatusTracker(this.events);
|
|
290
|
+
this.statusTracker = new StatusTracker(this.events, ServerProviderStatus, ServerProviderEvents);
|
|
482
291
|
this.hookExecutor = new HookExecutor(this.logger);
|
|
483
292
|
this.registerProviders(constructorProviders);
|
|
484
293
|
const aggregateMetadata = Object.keys(this.providerEntriesByName).reduce((acc, name) => {
|
|
@@ -550,7 +359,7 @@ var MultiProvider = class _MultiProvider {
|
|
|
550
359
|
const hookContext = this.hookContexts.get(context);
|
|
551
360
|
const hookHints = this.hookHints.get(context);
|
|
552
361
|
if (!hookContext || !hookHints) {
|
|
553
|
-
throw new
|
|
362
|
+
throw new GeneralError2("Hook context not available for evaluation");
|
|
554
363
|
}
|
|
555
364
|
const tasks = [];
|
|
556
365
|
for (const providerEntry of this.providerEntries) {
|
|
@@ -578,7 +387,7 @@ var MultiProvider = class _MultiProvider {
|
|
|
578
387
|
throw constructAggregateError(finalResult.errors);
|
|
579
388
|
}
|
|
580
389
|
if (!finalResult.details) {
|
|
581
|
-
throw new
|
|
390
|
+
throw new GeneralError2("No result was returned from any provider");
|
|
582
391
|
}
|
|
583
392
|
return finalResult.details;
|
|
584
393
|
});
|
|
@@ -657,7 +466,7 @@ var MultiProvider = class _MultiProvider {
|
|
|
657
466
|
case "boolean":
|
|
658
467
|
return yield provider.resolveBooleanEvaluation(flagKey, defaultValue, context, this.logger);
|
|
659
468
|
default:
|
|
660
|
-
throw new
|
|
469
|
+
throw new GeneralError2("Invalid flag evaluation type");
|
|
661
470
|
}
|
|
662
471
|
});
|
|
663
472
|
}
|
|
@@ -702,7 +511,7 @@ var MultiProvider = class _MultiProvider {
|
|
|
702
511
|
}
|
|
703
512
|
getErrorEvaluationDetails(flagKey, defaultValue, err, flagMetadata = {}) {
|
|
704
513
|
const errorMessage = err == null ? void 0 : err.message;
|
|
705
|
-
const errorCode = (err == null ? void 0 : err.code) ||
|
|
514
|
+
const errorCode = (err == null ? void 0 : err.code) || ErrorCode2.GENERAL;
|
|
706
515
|
return {
|
|
707
516
|
errorCode,
|
|
708
517
|
errorMessage,
|
|
@@ -715,16 +524,11 @@ var MultiProvider = class _MultiProvider {
|
|
|
715
524
|
};
|
|
716
525
|
|
|
717
526
|
// src/open-feature.ts
|
|
718
|
-
import {
|
|
719
|
-
OpenFeatureCommonAPI,
|
|
720
|
-
ProviderWrapper,
|
|
721
|
-
objectOrUndefined,
|
|
722
|
-
stringOrUndefined
|
|
723
|
-
} from "@openfeature/core";
|
|
527
|
+
import { OpenFeatureCommonAPI, ProviderWrapper, objectOrUndefined, stringOrUndefined } from "@openfeature/core";
|
|
724
528
|
|
|
725
529
|
// src/client/internal/open-feature-client.ts
|
|
726
530
|
import {
|
|
727
|
-
ErrorCode as
|
|
531
|
+
ErrorCode as ErrorCode3,
|
|
728
532
|
ProviderFatalError,
|
|
729
533
|
ProviderNotReadyError,
|
|
730
534
|
SafeLogger,
|
|
@@ -928,17 +732,15 @@ var OpenFeatureClient = class {
|
|
|
928
732
|
beforeHooks(hooks, hookContexts, mergedContext, options) {
|
|
929
733
|
return __async(this, null, function* () {
|
|
930
734
|
var _a;
|
|
931
|
-
|
|
735
|
+
const accumulatedContext = mergedContext;
|
|
932
736
|
for (const [index, hook] of hooks.entries()) {
|
|
933
737
|
const hookContextIndex = hooks.length - 1 - index;
|
|
934
738
|
const hookContext = hookContexts[hookContextIndex];
|
|
935
739
|
Object.assign(hookContext.context, accumulatedContext);
|
|
936
740
|
const hookResult = yield (_a = hook == null ? void 0 : hook.before) == null ? void 0 : _a.call(hook, hookContext, Object.freeze(options.hookHints));
|
|
937
741
|
if (hookResult) {
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
Object.assign(hookContexts[hookContextIndex].context, accumulatedContext);
|
|
941
|
-
}
|
|
742
|
+
Object.assign(accumulatedContext, hookResult);
|
|
743
|
+
Object.assign(hookContext.context, accumulatedContext);
|
|
942
744
|
}
|
|
943
745
|
}
|
|
944
746
|
return Object.freeze(accumulatedContext);
|
|
@@ -1008,7 +810,7 @@ var OpenFeatureClient = class {
|
|
|
1008
810
|
}
|
|
1009
811
|
getErrorEvaluationDetails(flagKey, defaultValue, err, flagMetadata = {}) {
|
|
1010
812
|
const errorMessage = err == null ? void 0 : err.message;
|
|
1011
|
-
const errorCode = (err == null ? void 0 : err.code) ||
|
|
813
|
+
const errorCode = (err == null ? void 0 : err.code) || ErrorCode3.GENERAL;
|
|
1012
814
|
return {
|
|
1013
815
|
errorCode,
|
|
1014
816
|
errorMessage,
|
|
@@ -1164,11 +966,8 @@ var OpenFeature = OpenFeatureAPI.getInstance();
|
|
|
1164
966
|
// src/index.ts
|
|
1165
967
|
export * from "@openfeature/core";
|
|
1166
968
|
export {
|
|
1167
|
-
AggregateError,
|
|
1168
969
|
AsyncLocalStorageTransactionContextPropagator,
|
|
1169
|
-
BaseEvaluationStrategy,
|
|
1170
970
|
ComparisonStrategy,
|
|
1171
|
-
ErrorWithCode,
|
|
1172
971
|
FirstMatchStrategy,
|
|
1173
972
|
FirstSuccessfulStrategy,
|
|
1174
973
|
InMemoryProvider,
|
|
@@ -1179,8 +978,6 @@ export {
|
|
|
1179
978
|
OpenFeatureAPI,
|
|
1180
979
|
OpenFeatureEventEmitter,
|
|
1181
980
|
ServerProviderEvents as ProviderEvents,
|
|
1182
|
-
ServerProviderStatus as ProviderStatus
|
|
1183
|
-
constructAggregateError,
|
|
1184
|
-
throwAggregateErrorFromPromiseResults
|
|
981
|
+
ServerProviderStatus as ProviderStatus
|
|
1185
982
|
};
|
|
1186
983
|
//# sourceMappingURL=index.js.map
|