@openfeature/server-sdk 1.6.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.
@@ -0,0 +1,1055 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
+ var __getOwnPropNames = Object.getOwnPropertyNames;
8
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
10
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
11
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __spreadValues = (a, b) => {
14
+ for (var prop in b || (b = {}))
15
+ if (__hasOwnProp.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ if (__getOwnPropSymbols)
18
+ for (var prop of __getOwnPropSymbols(b)) {
19
+ if (__propIsEnum.call(b, prop))
20
+ __defNormalProp(a, prop, b[prop]);
21
+ }
22
+ return a;
23
+ };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __copyProps = (to, from, except, desc) => {
30
+ if (from && typeof from === "object" || typeof from === "function") {
31
+ for (let key of __getOwnPropNames(from))
32
+ if (!__hasOwnProp.call(to, key) && key !== except)
33
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
+ }
35
+ return to;
36
+ };
37
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
42
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
+ mod
44
+ ));
45
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
46
+ var __async = (__this, __arguments, generator) => {
47
+ return new Promise((resolve, reject) => {
48
+ var fulfilled = (value) => {
49
+ try {
50
+ step(generator.next(value));
51
+ } catch (e) {
52
+ reject(e);
53
+ }
54
+ };
55
+ var rejected = (value) => {
56
+ try {
57
+ step(generator.throw(value));
58
+ } catch (e) {
59
+ reject(e);
60
+ }
61
+ };
62
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
63
+ step((generator = generator.apply(__this, __arguments)).next());
64
+ });
65
+ };
66
+
67
+ // src/index.ts
68
+ var src_exports = {};
69
+ __export(src_exports, {
70
+ DefaultLogger: () => DefaultLogger,
71
+ ErrorCode: () => ErrorCode,
72
+ FlagNotFoundError: () => FlagNotFoundError,
73
+ GeneralError: () => GeneralError,
74
+ InMemoryProvider: () => InMemoryProvider,
75
+ InternalEventEmitter: () => InternalEventEmitter,
76
+ InvalidContextError: () => InvalidContextError,
77
+ LOG_LEVELS: () => LOG_LEVELS,
78
+ NOOP_PROVIDER: () => NOOP_PROVIDER,
79
+ NOOP_TRANSACTION_CONTEXT_PROPAGATOR: () => NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
80
+ OpenFeature: () => OpenFeature,
81
+ OpenFeatureAPI: () => OpenFeatureAPI,
82
+ OpenFeatureClient: () => OpenFeatureClient,
83
+ OpenFeatureCommonAPI: () => OpenFeatureCommonAPI,
84
+ OpenFeatureError: () => OpenFeatureError,
85
+ OpenFeatureEventEmitter: () => OpenFeatureEventEmitter,
86
+ ParseError: () => ParseError,
87
+ ProviderEvents: () => ProviderEvents,
88
+ ProviderStatus: () => ProviderStatus,
89
+ SafeLogger: () => SafeLogger,
90
+ StandardResolutionReasons: () => StandardResolutionReasons,
91
+ TargetingKeyMissingError: () => TargetingKeyMissingError,
92
+ TypeMismatchError: () => TypeMismatchError,
93
+ isObject: () => isObject,
94
+ isString: () => isString,
95
+ objectOrUndefined: () => objectOrUndefined,
96
+ statusMatchesEvent: () => statusMatchesEvent,
97
+ stringOrUndefined: () => stringOrUndefined
98
+ });
99
+ module.exports = __toCommonJS(src_exports);
100
+
101
+ // ../shared/src/errors/open-feature-error-abstract.ts
102
+ var OpenFeatureError = class extends Error {
103
+ constructor(message) {
104
+ super(message);
105
+ Object.setPrototypeOf(this, OpenFeatureError.prototype);
106
+ this.name = "OpenFeatureError";
107
+ }
108
+ };
109
+
110
+ // ../shared/src/evaluation/evaluation.ts
111
+ var StandardResolutionReasons = {
112
+ /**
113
+ * The resolved value was the result of a dynamic evaluation, such as a rule or specific user-targeting.
114
+ */
115
+ TARGETING_MATCH: "TARGETING_MATCH",
116
+ /**
117
+ * The resolved value was the result of pseudorandom assignment.
118
+ */
119
+ SPLIT: "SPLIT",
120
+ /**
121
+ * The resolved value was the result of the flag being disabled in the management system.
122
+ */
123
+ DISABLED: "DISABLED",
124
+ /**
125
+ * The resolved value was configured statically, or otherwise fell back to a pre-configured value.
126
+ */
127
+ DEFAULT: "DEFAULT",
128
+ /**
129
+ * The reason for the resolved value could not be determined.
130
+ */
131
+ UNKNOWN: "UNKNOWN",
132
+ /**
133
+ * The resolved value is static (no dynamic evaluation).
134
+ */
135
+ STATIC: "STATIC",
136
+ /**
137
+ * The resolved value was retrieved from cache.
138
+ */
139
+ CACHED: "CACHED",
140
+ /**
141
+ * The resolved value was the result of an error.
142
+ *
143
+ * Note: The `errorCode` and `errorMessage` fields may contain additional details of this error.
144
+ */
145
+ ERROR: "ERROR"
146
+ };
147
+ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
148
+ ErrorCode2["PROVIDER_NOT_READY"] = "PROVIDER_NOT_READY";
149
+ ErrorCode2["FLAG_NOT_FOUND"] = "FLAG_NOT_FOUND";
150
+ ErrorCode2["PARSE_ERROR"] = "PARSE_ERROR";
151
+ ErrorCode2["TYPE_MISMATCH"] = "TYPE_MISMATCH";
152
+ ErrorCode2["TARGETING_KEY_MISSING"] = "TARGETING_KEY_MISSING";
153
+ ErrorCode2["INVALID_CONTEXT"] = "INVALID_CONTEXT";
154
+ ErrorCode2["GENERAL"] = "GENERAL";
155
+ return ErrorCode2;
156
+ })(ErrorCode || {});
157
+
158
+ // ../shared/src/errors/general-error.ts
159
+ var GeneralError = class extends OpenFeatureError {
160
+ constructor(message) {
161
+ super(message);
162
+ Object.setPrototypeOf(this, GeneralError.prototype);
163
+ this.name = "GeneralError";
164
+ this.code = "GENERAL" /* GENERAL */;
165
+ }
166
+ };
167
+
168
+ // ../shared/src/errors/flag-not-found-error.ts
169
+ var FlagNotFoundError = class extends OpenFeatureError {
170
+ constructor(message) {
171
+ super(message);
172
+ Object.setPrototypeOf(this, FlagNotFoundError.prototype);
173
+ this.name = "FlagNotFoundError";
174
+ this.code = "FLAG_NOT_FOUND" /* FLAG_NOT_FOUND */;
175
+ }
176
+ };
177
+
178
+ // ../shared/src/errors/parse-error.ts
179
+ var ParseError = class extends OpenFeatureError {
180
+ constructor(message) {
181
+ super(message);
182
+ Object.setPrototypeOf(this, ParseError.prototype);
183
+ this.name = "ParseError";
184
+ this.code = "PARSE_ERROR" /* PARSE_ERROR */;
185
+ }
186
+ };
187
+
188
+ // ../shared/src/errors/type-mismatch-error.ts
189
+ var TypeMismatchError = class extends OpenFeatureError {
190
+ constructor(message) {
191
+ super(message);
192
+ Object.setPrototypeOf(this, TypeMismatchError.prototype);
193
+ this.name = "TypeMismatchError";
194
+ this.code = "TYPE_MISMATCH" /* TYPE_MISMATCH */;
195
+ }
196
+ };
197
+
198
+ // ../shared/src/errors/targeting-key-missing-error.ts
199
+ var TargetingKeyMissingError = class extends OpenFeatureError {
200
+ constructor(message) {
201
+ super(message);
202
+ Object.setPrototypeOf(this, TargetingKeyMissingError.prototype);
203
+ this.name = "TargetingKeyMissingError";
204
+ this.code = "TARGETING_KEY_MISSING" /* TARGETING_KEY_MISSING */;
205
+ }
206
+ };
207
+
208
+ // ../shared/src/errors/invalid-context-error.ts
209
+ var InvalidContextError = class extends OpenFeatureError {
210
+ constructor(message) {
211
+ super(message);
212
+ Object.setPrototypeOf(this, InvalidContextError.prototype);
213
+ this.name = "InvalidContextError";
214
+ this.code = "INVALID_CONTEXT" /* INVALID_CONTEXT */;
215
+ }
216
+ };
217
+
218
+ // ../shared/src/provider/provider.ts
219
+ var ProviderStatus = /* @__PURE__ */ ((ProviderStatus2) => {
220
+ ProviderStatus2["NOT_READY"] = "NOT_READY";
221
+ ProviderStatus2["READY"] = "READY";
222
+ ProviderStatus2["ERROR"] = "ERROR";
223
+ ProviderStatus2["STALE"] = "STALE";
224
+ return ProviderStatus2;
225
+ })(ProviderStatus || {});
226
+
227
+ // ../shared/src/events/events.ts
228
+ var ProviderEvents = /* @__PURE__ */ ((ProviderEvents3) => {
229
+ ProviderEvents3["Ready"] = "PROVIDER_READY";
230
+ ProviderEvents3["Error"] = "PROVIDER_ERROR";
231
+ ProviderEvents3["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
232
+ ProviderEvents3["Stale"] = "PROVIDER_STALE";
233
+ return ProviderEvents3;
234
+ })(ProviderEvents || {});
235
+
236
+ // ../shared/src/events/event-utils.ts
237
+ var eventStatusMap = {
238
+ ["READY" /* READY */]: "PROVIDER_READY" /* Ready */,
239
+ ["ERROR" /* ERROR */]: "PROVIDER_ERROR" /* Error */,
240
+ ["STALE" /* STALE */]: "PROVIDER_STALE" /* Stale */,
241
+ ["NOT_READY" /* NOT_READY */]: void 0
242
+ };
243
+ var statusMatchesEvent = (event, status) => {
244
+ return !status && event === "PROVIDER_READY" /* Ready */ || eventStatusMap[status] === event;
245
+ };
246
+
247
+ // ../shared/src/events/open-feature-event-emitter.ts
248
+ var import_events2 = __toESM(require("events"));
249
+
250
+ // ../shared/src/logger/default-logger.ts
251
+ var DefaultLogger = class {
252
+ error(...args) {
253
+ console.error(...args);
254
+ }
255
+ warn(...args) {
256
+ console.warn(...args);
257
+ }
258
+ info() {
259
+ }
260
+ debug() {
261
+ }
262
+ };
263
+
264
+ // ../shared/src/logger/safe-logger.ts
265
+ var LOG_LEVELS = ["error", "warn", "info", "debug"];
266
+ var SafeLogger = class {
267
+ constructor(logger) {
268
+ this.fallbackLogger = new DefaultLogger();
269
+ try {
270
+ for (const level of LOG_LEVELS) {
271
+ if (!logger[level] || typeof logger[level] !== "function") {
272
+ throw new Error(`The provided logger is missing the ${level} method.`);
273
+ }
274
+ }
275
+ this.logger = logger;
276
+ } catch (err) {
277
+ console.error(err);
278
+ console.error("Falling back to the default logger.");
279
+ this.logger = this.fallbackLogger;
280
+ }
281
+ }
282
+ error(...args) {
283
+ this.log("error", ...args);
284
+ }
285
+ warn(...args) {
286
+ this.log("warn", ...args);
287
+ }
288
+ info(...args) {
289
+ this.log("info", ...args);
290
+ }
291
+ debug(...args) {
292
+ this.log("debug", ...args);
293
+ }
294
+ log(level, ...args) {
295
+ try {
296
+ this.logger[level](...args);
297
+ } catch (error) {
298
+ this.fallbackLogger[level](...args);
299
+ }
300
+ }
301
+ };
302
+
303
+ // ../shared/src/events/open-feature-event-emitter.ts
304
+ var GenericEventEmitter = class {
305
+ constructor(globalLogger) {
306
+ this.globalLogger = globalLogger;
307
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
308
+ this._handlers = /* @__PURE__ */ new WeakMap();
309
+ this.eventEmitter = new import_events2.default({ captureRejections: true });
310
+ this.eventEmitter.on("error", (err) => {
311
+ var _a;
312
+ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
313
+ });
314
+ }
315
+ emit(eventType, context) {
316
+ this.eventEmitter.emit(eventType, context);
317
+ }
318
+ addHandler(eventType, handler) {
319
+ const asyncHandler = (details) => __async(this, null, function* () {
320
+ yield handler(details);
321
+ });
322
+ this._handlers.set(handler, asyncHandler);
323
+ this.eventEmitter.on(eventType, asyncHandler);
324
+ }
325
+ removeHandler(eventType, handler) {
326
+ const asyncHandler = this._handlers.get(handler);
327
+ if (!asyncHandler) {
328
+ return;
329
+ }
330
+ this.eventEmitter.removeListener(eventType, asyncHandler);
331
+ }
332
+ removeAllHandlers(eventType) {
333
+ if (eventType) {
334
+ this.eventEmitter.removeAllListeners(eventType);
335
+ } else {
336
+ this.eventEmitter.removeAllListeners();
337
+ }
338
+ }
339
+ getHandlers(eventType) {
340
+ return this.eventEmitter.listeners(eventType);
341
+ }
342
+ setLogger(logger) {
343
+ this._eventLogger = new SafeLogger(logger);
344
+ return this;
345
+ }
346
+ get _logger() {
347
+ var _a, _b;
348
+ return (_b = this._eventLogger) != null ? _b : (_a = this.globalLogger) == null ? void 0 : _a.call(this);
349
+ }
350
+ };
351
+ var OpenFeatureEventEmitter = class extends GenericEventEmitter {
352
+ };
353
+ var InternalEventEmitter = class extends GenericEventEmitter {
354
+ };
355
+
356
+ // ../shared/src/transaction-context/no-op-transaction-context-propagator.ts
357
+ var NoopTransactionContextPropagator = class {
358
+ getTransactionContext() {
359
+ return {};
360
+ }
361
+ setTransactionContext(_, callback) {
362
+ callback();
363
+ }
364
+ };
365
+ var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
366
+
367
+ // ../shared/src/type-guards.ts
368
+ function isString(value) {
369
+ return typeof value === "string";
370
+ }
371
+ function stringOrUndefined(value) {
372
+ return isString(value) ? value : void 0;
373
+ }
374
+ function isObject(value) {
375
+ return typeof value === "object";
376
+ }
377
+ function objectOrUndefined(value) {
378
+ return isObject(value) ? value : void 0;
379
+ }
380
+
381
+ // ../shared/src/filter.ts
382
+ function isDefined(input) {
383
+ return typeof input !== "undefined" && input !== null;
384
+ }
385
+
386
+ // ../shared/src/open-feature.ts
387
+ var OpenFeatureCommonAPI = class {
388
+ constructor(category) {
389
+ this._hooks = [];
390
+ this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
391
+ this._context = {};
392
+ this._logger = new DefaultLogger();
393
+ this._events = new InternalEventEmitter(() => this._logger);
394
+ this._clientEventHandlers = /* @__PURE__ */ new Map();
395
+ this._clientProviders = /* @__PURE__ */ new Map();
396
+ this._clientEvents = /* @__PURE__ */ new Map();
397
+ this._runsOn = category;
398
+ }
399
+ addHooks(...hooks) {
400
+ this._hooks = [...this._hooks, ...hooks];
401
+ return this;
402
+ }
403
+ getHooks() {
404
+ return this._hooks;
405
+ }
406
+ clearHooks() {
407
+ this._hooks = [];
408
+ return this;
409
+ }
410
+ setLogger(logger) {
411
+ this._logger = new SafeLogger(logger);
412
+ return this;
413
+ }
414
+ /**
415
+ * Get metadata about registered provider.
416
+ * @returns {ProviderMetadata} Provider Metadata
417
+ */
418
+ get providerMetadata() {
419
+ return this._defaultProvider.metadata;
420
+ }
421
+ /**
422
+ * Adds a handler for the given provider event type.
423
+ * The handlers are called in the order they have been added.
424
+ * API (global) events run for all providers.
425
+ * @param {ProviderEvents} eventType The provider event type to listen to
426
+ * @param {EventHandler} handler The handler to run on occurrence of the event type
427
+ */
428
+ addHandler(eventType, handler) {
429
+ [.../* @__PURE__ */ new Map([[void 0, this._defaultProvider]]), ...this._clientProviders].forEach((keyProviderTuple) => {
430
+ var _a;
431
+ const clientName = keyProviderTuple[0];
432
+ const provider = keyProviderTuple[1];
433
+ const shouldRunNow = statusMatchesEvent(eventType, keyProviderTuple[1].status);
434
+ if (shouldRunNow) {
435
+ try {
436
+ handler({ clientName, providerName: provider.metadata.name });
437
+ } catch (err) {
438
+ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
439
+ }
440
+ }
441
+ });
442
+ this._events.addHandler(eventType, handler);
443
+ }
444
+ /**
445
+ * Removes a handler for the given provider event type.
446
+ * @param {ProviderEvents} eventType The provider event type to remove the listener for
447
+ * @param {EventHandler} handler The handler to remove for the provider event type
448
+ */
449
+ removeHandler(eventType, handler) {
450
+ this._events.removeHandler(eventType, handler);
451
+ }
452
+ /**
453
+ * Gets the current handlers for the given provider event type.
454
+ * @param {ProviderEvents} eventType The provider event type to get the current handlers for
455
+ * @returns {EventHandler[]} The handlers currently attached to the given provider event type
456
+ */
457
+ getHandlers(eventType) {
458
+ return this._events.getHandlers(eventType);
459
+ }
460
+ setProviderAndWait(clientOrProvider, providerOrUndefined) {
461
+ return __async(this, null, function* () {
462
+ yield this.setAwaitableProvider(clientOrProvider, providerOrUndefined);
463
+ });
464
+ }
465
+ setProvider(clientOrProvider, providerOrUndefined) {
466
+ const maybePromise = this.setAwaitableProvider(clientOrProvider, providerOrUndefined);
467
+ if (maybePromise) {
468
+ maybePromise.catch(() => {
469
+ });
470
+ }
471
+ return this;
472
+ }
473
+ setAwaitableProvider(clientOrProvider, providerOrUndefined) {
474
+ var _a, _b, _c, _d, _e, _f;
475
+ const clientName = stringOrUndefined(clientOrProvider);
476
+ const provider = (_a = objectOrUndefined(clientOrProvider)) != null ? _a : objectOrUndefined(providerOrUndefined);
477
+ if (!provider) {
478
+ this._logger.debug("No provider defined, ignoring setProvider call");
479
+ return;
480
+ }
481
+ const oldProvider = this.getProviderForClient(clientName);
482
+ const providerName = provider.metadata.name;
483
+ if (oldProvider === provider) {
484
+ this._logger.debug("Provider is already set, ignoring setProvider call");
485
+ return;
486
+ }
487
+ if (!provider.runsOn) {
488
+ this._logger.debug(`Provider '${provider.metadata.name}' has not defined its intended use.`);
489
+ } else if (provider.runsOn !== this._runsOn) {
490
+ throw new GeneralError(`Provider '${provider.metadata.name}' is intended for use on the ${provider.runsOn}.`);
491
+ }
492
+ const emitters = this.getAssociatedEventEmitters(clientName);
493
+ if (typeof provider.initialize === "function" && provider.status === void 0) {
494
+ const activeLogger = this._logger || console;
495
+ activeLogger.warn(
496
+ `Provider ${providerName} implements 'initialize' but not 'status'. Please implement 'status'.`
497
+ );
498
+ }
499
+ let initializationPromise = void 0;
500
+ if ((provider == null ? void 0 : provider.status) === "NOT_READY" /* NOT_READY */ && typeof provider.initialize === "function") {
501
+ initializationPromise = (_d = (_c = (_b = provider.initialize) == null ? void 0 : _b.call(provider, this._context)) == null ? void 0 : _c.then(() => {
502
+ var _a2;
503
+ this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
504
+ emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
505
+ });
506
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
507
+ })) == null ? void 0 : _d.catch((error) => {
508
+ var _a2;
509
+ this.getAssociatedEventEmitters(clientName).forEach((emitter) => {
510
+ emitter == null ? void 0 : emitter.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message });
511
+ });
512
+ (_a2 = this._events) == null ? void 0 : _a2.emit("PROVIDER_ERROR" /* Error */, { clientName, providerName, message: error.message });
513
+ throw error;
514
+ });
515
+ } else {
516
+ emitters.forEach((emitter) => {
517
+ emitter == null ? void 0 : emitter.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
518
+ });
519
+ (_e = this._events) == null ? void 0 : _e.emit("PROVIDER_READY" /* Ready */, { clientName, providerName });
520
+ }
521
+ if (clientName) {
522
+ this._clientProviders.set(clientName, provider);
523
+ } else {
524
+ this._defaultProvider = provider;
525
+ }
526
+ this.transferListeners(oldProvider, provider, clientName, emitters);
527
+ if (![...this._clientProviders.values(), this._defaultProvider].includes(oldProvider)) {
528
+ (_f = oldProvider == null ? void 0 : oldProvider.onClose) == null ? void 0 : _f.call(oldProvider);
529
+ }
530
+ return initializationPromise;
531
+ }
532
+ getProviderForClient(name) {
533
+ var _a;
534
+ if (!name) {
535
+ return this._defaultProvider;
536
+ }
537
+ return (_a = this._clientProviders.get(name)) != null ? _a : this._defaultProvider;
538
+ }
539
+ buildAndCacheEventEmitterForClient(name) {
540
+ const emitter = this._clientEvents.get(name);
541
+ if (emitter) {
542
+ return emitter;
543
+ }
544
+ const newEmitter = new InternalEventEmitter(() => this._logger);
545
+ this._clientEvents.set(name, newEmitter);
546
+ const clientProvider = this.getProviderForClient(name);
547
+ Object.values(ProviderEvents).forEach(
548
+ (eventType) => {
549
+ var _a;
550
+ return (_a = clientProvider.events) == null ? void 0 : _a.addHandler(eventType, (details) => __async(this, null, function* () {
551
+ newEmitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName: name, providerName: clientProvider.metadata.name }));
552
+ }));
553
+ }
554
+ );
555
+ return newEmitter;
556
+ }
557
+ getUnboundEmitters() {
558
+ const namedProviders = [...this._clientProviders.keys()];
559
+ const eventEmitterNames = [...this._clientEvents.keys()].filter(isDefined);
560
+ const unboundEmitterNames = eventEmitterNames.filter((name) => !namedProviders.includes(name));
561
+ return [
562
+ // all unbound, named emitters
563
+ ...unboundEmitterNames.map((name) => this._clientEvents.get(name)),
564
+ // the default emitter
565
+ this._clientEvents.get(void 0)
566
+ ].filter(isDefined);
567
+ }
568
+ getAssociatedEventEmitters(clientName) {
569
+ return clientName ? [this.buildAndCacheEventEmitterForClient(clientName)] : this.getUnboundEmitters();
570
+ }
571
+ transferListeners(oldProvider, newProvider, clientName, emitters) {
572
+ var _a;
573
+ (_a = this._clientEventHandlers.get(clientName)) == null ? void 0 : _a.forEach((eventHandler) => {
574
+ var _a2;
575
+ return (_a2 = oldProvider.events) == null ? void 0 : _a2.removeHandler(...eventHandler);
576
+ });
577
+ const newClientHandlers = Object.values(ProviderEvents).map((eventType) => {
578
+ const handler = (details) => __async(this, null, function* () {
579
+ emitters.forEach((emitter) => {
580
+ emitter == null ? void 0 : emitter.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name }));
581
+ });
582
+ this._events.emit(eventType, __spreadProps(__spreadValues({}, details), { clientName, providerName: newProvider.metadata.name }));
583
+ });
584
+ return [eventType, handler];
585
+ });
586
+ this._clientEventHandlers.set(clientName, newClientHandlers);
587
+ newClientHandlers.forEach((eventHandler) => {
588
+ var _a2;
589
+ return (_a2 = newProvider.events) == null ? void 0 : _a2.addHandler(...eventHandler);
590
+ });
591
+ }
592
+ close() {
593
+ return __async(this, null, function* () {
594
+ var _a, _b;
595
+ try {
596
+ yield (_b = (_a = this == null ? void 0 : this._defaultProvider) == null ? void 0 : _a.onClose) == null ? void 0 : _b.call(_a);
597
+ } catch (err) {
598
+ this.handleShutdownError(this._defaultProvider, err);
599
+ }
600
+ const providers = Array.from(this._clientProviders);
601
+ yield Promise.all(
602
+ providers.map((_0) => __async(this, [_0], function* ([, provider]) {
603
+ var _a2;
604
+ try {
605
+ yield (_a2 = provider.onClose) == null ? void 0 : _a2.call(provider);
606
+ } catch (err) {
607
+ this.handleShutdownError(this._defaultProvider, err);
608
+ }
609
+ }))
610
+ );
611
+ });
612
+ }
613
+ handleShutdownError(provider, err) {
614
+ this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`);
615
+ this._logger.error(err == null ? void 0 : err.stack);
616
+ }
617
+ setTransactionContextPropagator(transactionContextPropagator) {
618
+ const baseMessage = "Invalid TransactionContextPropagator, will not be set: ";
619
+ if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.getTransactionContext) !== "function") {
620
+ this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);
621
+ } else if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.setTransactionContext) !== "function") {
622
+ this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);
623
+ } else {
624
+ this._transactionContextPropagator = transactionContextPropagator;
625
+ }
626
+ return this;
627
+ }
628
+ setTransactionContext(transactionContext, callback, ...args) {
629
+ this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);
630
+ }
631
+ getTransactionContext() {
632
+ try {
633
+ return this._transactionContextPropagator.getTransactionContext();
634
+ } catch (err) {
635
+ const error = err;
636
+ this._logger.error(`Error getting transaction context: ${error == null ? void 0 : error.message}, returning empty context.`);
637
+ this._logger.error(error == null ? void 0 : error.stack);
638
+ return {};
639
+ }
640
+ }
641
+ };
642
+
643
+ // src/provider/no-op-provider.ts
644
+ var REASON_NO_OP = "No-op";
645
+ var NoopFeatureProvider = class {
646
+ constructor() {
647
+ this.metadata = {
648
+ name: "No-op Provider"
649
+ };
650
+ }
651
+ get status() {
652
+ return "NOT_READY" /* NOT_READY */;
653
+ }
654
+ resolveBooleanEvaluation(_, defaultValue) {
655
+ return this.noOp(defaultValue);
656
+ }
657
+ resolveStringEvaluation(_, defaultValue) {
658
+ return this.noOp(defaultValue);
659
+ }
660
+ resolveNumberEvaluation(_, defaultValue) {
661
+ return this.noOp(defaultValue);
662
+ }
663
+ resolveObjectEvaluation(_, defaultValue) {
664
+ return this.noOp(defaultValue);
665
+ }
666
+ noOp(defaultValue) {
667
+ return Promise.resolve({
668
+ value: defaultValue,
669
+ reason: REASON_NO_OP
670
+ });
671
+ }
672
+ };
673
+ var NOOP_PROVIDER = new NoopFeatureProvider();
674
+
675
+ // src/provider/in-memory-provider/variant-not-found-error.ts
676
+ var VariantFoundError = class extends OpenFeatureError {
677
+ constructor(message) {
678
+ super(message);
679
+ Object.setPrototypeOf(this, VariantFoundError.prototype);
680
+ this.name = "VariantFoundError";
681
+ this.code = "GENERAL" /* GENERAL */;
682
+ }
683
+ };
684
+
685
+ // src/provider/in-memory-provider/in-memory-provider.ts
686
+ var InMemoryProvider = class {
687
+ constructor(flagConfiguration = {}) {
688
+ this.events = new OpenFeatureEventEmitter();
689
+ this.runsOn = "server";
690
+ this.metadata = {
691
+ name: "in-memory"
692
+ };
693
+ this._flagConfiguration = __spreadValues({}, flagConfiguration);
694
+ }
695
+ /**
696
+ * Overwrites the configured flags.
697
+ * @param { FlagConfiguration } flagConfiguration new flag configuration
698
+ */
699
+ putConfiguration(flagConfiguration) {
700
+ const flagsChanged = Object.entries(flagConfiguration).filter(([key, value]) => this._flagConfiguration[key] !== value).map(([key]) => key);
701
+ this._flagConfiguration = __spreadValues({}, flagConfiguration);
702
+ this.events.emit("PROVIDER_CONFIGURATION_CHANGED" /* ConfigurationChanged */, { flagsChanged });
703
+ }
704
+ resolveBooleanEvaluation(flagKey, defaultValue, context, logger) {
705
+ return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
706
+ }
707
+ resolveNumberEvaluation(flagKey, defaultValue, context, logger) {
708
+ return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
709
+ }
710
+ resolveStringEvaluation(flagKey, defaultValue, context, logger) {
711
+ return __async(this, null, function* () {
712
+ return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
713
+ });
714
+ }
715
+ resolveObjectEvaluation(flagKey, defaultValue, context, logger) {
716
+ return __async(this, null, function* () {
717
+ return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
718
+ });
719
+ }
720
+ resolveFlagWithReason(flagKey, defaultValue, ctx, logger) {
721
+ return __async(this, null, function* () {
722
+ try {
723
+ const resolutionResult = this.lookupFlagValue(flagKey, defaultValue, ctx, logger);
724
+ if (typeof (resolutionResult == null ? void 0 : resolutionResult.value) != typeof defaultValue) {
725
+ throw new TypeMismatchError();
726
+ }
727
+ return resolutionResult;
728
+ } catch (error) {
729
+ if (!(error instanceof OpenFeatureError)) {
730
+ throw new GeneralError((error == null ? void 0 : error.message) || "unknown error");
731
+ }
732
+ throw error;
733
+ }
734
+ });
735
+ }
736
+ lookupFlagValue(flagKey, defaultValue, ctx, logger) {
737
+ var _a;
738
+ if (!(flagKey in this._flagConfiguration)) {
739
+ const message = `no flag found with key ${flagKey}`;
740
+ logger == null ? void 0 : logger.debug(message);
741
+ throw new FlagNotFoundError(message);
742
+ }
743
+ const flagSpec = this._flagConfiguration[flagKey];
744
+ if (flagSpec.disabled) {
745
+ return { value: defaultValue, reason: StandardResolutionReasons.DISABLED };
746
+ }
747
+ const isContextEval = ctx && (flagSpec == null ? void 0 : flagSpec.contextEvaluator);
748
+ const variant = isContextEval ? (_a = flagSpec.contextEvaluator) == null ? void 0 : _a.call(flagSpec, ctx) : flagSpec.defaultVariant;
749
+ const value = variant && (flagSpec == null ? void 0 : flagSpec.variants[variant]);
750
+ if (value === void 0) {
751
+ const message = `no value associated with variant ${variant}`;
752
+ logger == null ? void 0 : logger.error(message);
753
+ throw new VariantFoundError(message);
754
+ }
755
+ return __spreadProps(__spreadValues({
756
+ value
757
+ }, variant && { variant }), {
758
+ reason: isContextEval ? StandardResolutionReasons.TARGETING_MATCH : StandardResolutionReasons.STATIC
759
+ });
760
+ }
761
+ };
762
+
763
+ // src/open-feature.ts
764
+ var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js-sdk/api");
765
+ var _globalThis = globalThis;
766
+ var OpenFeatureAPI = class extends OpenFeatureCommonAPI {
767
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
768
+ constructor() {
769
+ super("server");
770
+ this._defaultProvider = NOOP_PROVIDER;
771
+ }
772
+ /**
773
+ * Gets a singleton instance of the OpenFeature API.
774
+ * @ignore
775
+ * @returns {OpenFeatureAPI} OpenFeature API
776
+ */
777
+ static getInstance() {
778
+ const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];
779
+ if (globalApi) {
780
+ return globalApi;
781
+ }
782
+ const instance = new OpenFeatureAPI();
783
+ _globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
784
+ return instance;
785
+ }
786
+ setContext(context) {
787
+ this._context = context;
788
+ return this;
789
+ }
790
+ getContext() {
791
+ return this._context;
792
+ }
793
+ getClient(nameOrContext, versionOrContext, contextOrUndefined) {
794
+ var _a, _b;
795
+ const name = stringOrUndefined(nameOrContext);
796
+ const version = stringOrUndefined(versionOrContext);
797
+ const context = (_b = (_a = objectOrUndefined(nameOrContext)) != null ? _a : objectOrUndefined(versionOrContext)) != null ? _b : objectOrUndefined(contextOrUndefined);
798
+ return new OpenFeatureClient(
799
+ () => this.getProviderForClient(name),
800
+ () => this.buildAndCacheEventEmitterForClient(name),
801
+ () => this._logger,
802
+ { name, version },
803
+ context
804
+ );
805
+ }
806
+ };
807
+ var OpenFeature = OpenFeatureAPI.getInstance();
808
+
809
+ // src/client/open-feature-client.ts
810
+ var OpenFeatureClient = class {
811
+ constructor(providerAccessor, emitterAccessor, globalLogger, options, context = {}) {
812
+ this.providerAccessor = providerAccessor;
813
+ this.emitterAccessor = emitterAccessor;
814
+ this.globalLogger = globalLogger;
815
+ this.options = options;
816
+ this._hooks = [];
817
+ this._context = context;
818
+ }
819
+ get metadata() {
820
+ return {
821
+ name: this.options.name,
822
+ version: this.options.version,
823
+ providerMetadata: this.providerAccessor().metadata
824
+ };
825
+ }
826
+ addHandler(eventType, handler) {
827
+ var _a;
828
+ this.emitterAccessor().addHandler(eventType, handler);
829
+ const shouldRunNow = statusMatchesEvent(eventType, this._provider.status);
830
+ if (shouldRunNow) {
831
+ try {
832
+ handler({ clientName: this.metadata.name, providerName: this._provider.metadata.name });
833
+ } catch (err) {
834
+ (_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
835
+ }
836
+ }
837
+ }
838
+ removeHandler(eventType, handler) {
839
+ this.emitterAccessor().removeHandler(eventType, handler);
840
+ }
841
+ getHandlers(eventType) {
842
+ return this.emitterAccessor().getHandlers(eventType);
843
+ }
844
+ setLogger(logger) {
845
+ this._clientLogger = new SafeLogger(logger);
846
+ return this;
847
+ }
848
+ setContext(context) {
849
+ this._context = context;
850
+ return this;
851
+ }
852
+ getContext() {
853
+ return this._context;
854
+ }
855
+ addHooks(...hooks) {
856
+ this._hooks = [...this._hooks, ...hooks];
857
+ return this;
858
+ }
859
+ getHooks() {
860
+ return this._hooks;
861
+ }
862
+ clearHooks() {
863
+ this._hooks = [];
864
+ return this;
865
+ }
866
+ getBooleanValue(flagKey, defaultValue, context, options) {
867
+ return __async(this, null, function* () {
868
+ return (yield this.getBooleanDetails(flagKey, defaultValue, context, options)).value;
869
+ });
870
+ }
871
+ getBooleanDetails(flagKey, defaultValue, context, options) {
872
+ return this.evaluate(
873
+ flagKey,
874
+ this._provider.resolveBooleanEvaluation,
875
+ defaultValue,
876
+ "boolean",
877
+ context,
878
+ options
879
+ );
880
+ }
881
+ getStringValue(flagKey, defaultValue, context, options) {
882
+ return __async(this, null, function* () {
883
+ return (yield this.getStringDetails(flagKey, defaultValue, context, options)).value;
884
+ });
885
+ }
886
+ getStringDetails(flagKey, defaultValue, context, options) {
887
+ return this.evaluate(
888
+ flagKey,
889
+ // this isolates providers from our restricted string generic argument.
890
+ this._provider.resolveStringEvaluation,
891
+ defaultValue,
892
+ "string",
893
+ context,
894
+ options
895
+ );
896
+ }
897
+ getNumberValue(flagKey, defaultValue, context, options) {
898
+ return __async(this, null, function* () {
899
+ return (yield this.getNumberDetails(flagKey, defaultValue, context, options)).value;
900
+ });
901
+ }
902
+ getNumberDetails(flagKey, defaultValue, context, options) {
903
+ return this.evaluate(
904
+ flagKey,
905
+ // this isolates providers from our restricted number generic argument.
906
+ this._provider.resolveNumberEvaluation,
907
+ defaultValue,
908
+ "number",
909
+ context,
910
+ options
911
+ );
912
+ }
913
+ getObjectValue(flagKey, defaultValue, context, options) {
914
+ return __async(this, null, function* () {
915
+ return (yield this.getObjectDetails(flagKey, defaultValue, context, options)).value;
916
+ });
917
+ }
918
+ getObjectDetails(flagKey, defaultValue, context, options) {
919
+ return this.evaluate(flagKey, this._provider.resolveObjectEvaluation, defaultValue, "object", context, options);
920
+ }
921
+ evaluate(_0, _1, _2, _3) {
922
+ return __async(this, arguments, function* (flagKey, resolver, defaultValue, flagType, invocationContext = {}, options = {}) {
923
+ var _a;
924
+ const allHooks = [
925
+ ...OpenFeature.getHooks(),
926
+ ...this.getHooks(),
927
+ ...options.hooks || [],
928
+ ...this._provider.hooks || []
929
+ ];
930
+ const allHooksReversed = [...allHooks].reverse();
931
+ const mergedContext = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, OpenFeature.getContext()), OpenFeature.getTransactionContext()), this._context), invocationContext);
932
+ const hookContext = {
933
+ flagKey,
934
+ defaultValue,
935
+ flagValueType: flagType,
936
+ clientMetadata: this.metadata,
937
+ providerMetadata: OpenFeature.providerMetadata,
938
+ context: mergedContext,
939
+ logger: this._logger
940
+ };
941
+ try {
942
+ const frozenContext = yield this.beforeHooks(allHooks, hookContext, options);
943
+ const resolution = yield resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);
944
+ const evaluationDetails = __spreadProps(__spreadValues({}, resolution), {
945
+ flagMetadata: Object.freeze((_a = resolution.flagMetadata) != null ? _a : {}),
946
+ flagKey
947
+ });
948
+ yield this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
949
+ return evaluationDetails;
950
+ } catch (err) {
951
+ const errorMessage = err == null ? void 0 : err.message;
952
+ const errorCode = (err == null ? void 0 : err.code) || "GENERAL" /* GENERAL */;
953
+ yield this.errorHooks(allHooksReversed, hookContext, err, options);
954
+ return {
955
+ errorCode,
956
+ errorMessage,
957
+ value: defaultValue,
958
+ reason: StandardResolutionReasons.ERROR,
959
+ flagMetadata: Object.freeze({}),
960
+ flagKey
961
+ };
962
+ } finally {
963
+ yield this.finallyHooks(allHooksReversed, hookContext, options);
964
+ }
965
+ });
966
+ }
967
+ beforeHooks(hooks, hookContext, options) {
968
+ return __async(this, null, function* () {
969
+ var _a;
970
+ for (const hook of hooks) {
971
+ Object.freeze(hookContext);
972
+ Object.assign(hookContext.context, __spreadValues(__spreadValues({}, hookContext.context), yield (_a = hook == null ? void 0 : hook.before) == null ? void 0 : _a.call(hook, hookContext, Object.freeze(options.hookHints))));
973
+ }
974
+ return Object.freeze(hookContext.context);
975
+ });
976
+ }
977
+ afterHooks(hooks, hookContext, evaluationDetails, options) {
978
+ return __async(this, null, function* () {
979
+ var _a;
980
+ for (const hook of hooks) {
981
+ yield (_a = hook == null ? void 0 : hook.after) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, options.hookHints);
982
+ }
983
+ });
984
+ }
985
+ errorHooks(hooks, hookContext, err, options) {
986
+ return __async(this, null, function* () {
987
+ var _a;
988
+ for (const hook of hooks) {
989
+ try {
990
+ yield (_a = hook == null ? void 0 : hook.error) == null ? void 0 : _a.call(hook, hookContext, err, options.hookHints);
991
+ } catch (err2) {
992
+ this._logger.error(`Unhandled error during 'error' hook: ${err2}`);
993
+ if (err2 instanceof Error) {
994
+ this._logger.error(err2.stack);
995
+ }
996
+ this._logger.error(err2 == null ? void 0 : err2.stack);
997
+ }
998
+ }
999
+ });
1000
+ }
1001
+ finallyHooks(hooks, hookContext, options) {
1002
+ return __async(this, null, function* () {
1003
+ var _a;
1004
+ for (const hook of hooks) {
1005
+ try {
1006
+ yield (_a = hook == null ? void 0 : hook.finally) == null ? void 0 : _a.call(hook, hookContext, options.hookHints);
1007
+ } catch (err) {
1008
+ this._logger.error(`Unhandled error during 'finally' hook: ${err}`);
1009
+ if (err instanceof Error) {
1010
+ this._logger.error(err.stack);
1011
+ }
1012
+ this._logger.error(err == null ? void 0 : err.stack);
1013
+ }
1014
+ }
1015
+ });
1016
+ }
1017
+ get _provider() {
1018
+ return this.providerAccessor();
1019
+ }
1020
+ get _logger() {
1021
+ return this._clientLogger || this.globalLogger();
1022
+ }
1023
+ };
1024
+ // Annotate the CommonJS export names for ESM import in node:
1025
+ 0 && (module.exports = {
1026
+ DefaultLogger,
1027
+ ErrorCode,
1028
+ FlagNotFoundError,
1029
+ GeneralError,
1030
+ InMemoryProvider,
1031
+ InternalEventEmitter,
1032
+ InvalidContextError,
1033
+ LOG_LEVELS,
1034
+ NOOP_PROVIDER,
1035
+ NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
1036
+ OpenFeature,
1037
+ OpenFeatureAPI,
1038
+ OpenFeatureClient,
1039
+ OpenFeatureCommonAPI,
1040
+ OpenFeatureError,
1041
+ OpenFeatureEventEmitter,
1042
+ ParseError,
1043
+ ProviderEvents,
1044
+ ProviderStatus,
1045
+ SafeLogger,
1046
+ StandardResolutionReasons,
1047
+ TargetingKeyMissingError,
1048
+ TypeMismatchError,
1049
+ isObject,
1050
+ isString,
1051
+ objectOrUndefined,
1052
+ statusMatchesEvent,
1053
+ stringOrUndefined
1054
+ });
1055
+ //# sourceMappingURL=index.js.map