@openfeature/server-sdk 1.13.5 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/dist/cjs/index.js +365 -282
- package/dist/cjs/index.js.map +4 -4
- package/dist/esm/index.js +366 -278
- package/dist/esm/index.js.map +4 -4
- package/dist/types.d.ts +38 -59
- package/package.json +6 -6
package/dist/cjs/index.js
CHANGED
|
@@ -1,8 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
6
23
|
var __export = (target, all) => {
|
|
7
24
|
for (var name in all)
|
|
8
25
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,6 +34,26 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
34
|
};
|
|
18
35
|
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
19
36
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
37
|
+
var __async = (__this, __arguments, generator) => {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
var fulfilled = (value) => {
|
|
40
|
+
try {
|
|
41
|
+
step(generator.next(value));
|
|
42
|
+
} catch (e) {
|
|
43
|
+
reject(e);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var rejected = (value) => {
|
|
47
|
+
try {
|
|
48
|
+
step(generator.throw(value));
|
|
49
|
+
} catch (e) {
|
|
50
|
+
reject(e);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
54
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
55
|
+
});
|
|
56
|
+
};
|
|
20
57
|
|
|
21
58
|
// src/index.ts
|
|
22
59
|
var src_exports = {};
|
|
@@ -27,44 +64,23 @@ __export(src_exports, {
|
|
|
27
64
|
NOOP_TRANSACTION_CONTEXT_PROPAGATOR: () => NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
|
|
28
65
|
OpenFeature: () => OpenFeature,
|
|
29
66
|
OpenFeatureAPI: () => OpenFeatureAPI,
|
|
30
|
-
OpenFeatureClient: () => OpenFeatureClient,
|
|
31
67
|
OpenFeatureEventEmitter: () => OpenFeatureEventEmitter,
|
|
32
|
-
ProviderEvents: () =>
|
|
33
|
-
ProviderStatus: () =>
|
|
68
|
+
ProviderEvents: () => import_core6.ServerProviderEvents,
|
|
69
|
+
ProviderStatus: () => import_core.ServerProviderStatus
|
|
34
70
|
});
|
|
35
71
|
module.exports = __toCommonJS(src_exports);
|
|
36
72
|
|
|
37
|
-
// src/client/open-feature-client.ts
|
|
38
|
-
var import_core7 = require("@openfeature/core");
|
|
39
|
-
|
|
40
|
-
// src/open-feature.ts
|
|
41
|
-
var import_core6 = require("@openfeature/core");
|
|
42
|
-
|
|
43
|
-
// src/events/open-feature-event-emitter.ts
|
|
44
|
-
var import_core = require("@openfeature/core");
|
|
45
|
-
var import_node_events = require("events");
|
|
46
|
-
var OpenFeatureEventEmitter = class extends import_core.GenericEventEmitter {
|
|
47
|
-
eventEmitter = new import_node_events.EventEmitter({ captureRejections: true });
|
|
48
|
-
constructor() {
|
|
49
|
-
super();
|
|
50
|
-
this.eventEmitter.on("error", (err) => {
|
|
51
|
-
this._logger?.error("Error running event handler:", err);
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
// src/events/events.ts
|
|
57
|
-
var import_core2 = require("@openfeature/core");
|
|
58
|
-
|
|
59
73
|
// src/provider/provider.ts
|
|
60
|
-
var
|
|
74
|
+
var import_core = require("@openfeature/core");
|
|
61
75
|
|
|
62
76
|
// src/provider/no-op-provider.ts
|
|
63
77
|
var REASON_NO_OP = "No-op";
|
|
64
78
|
var NoopFeatureProvider = class {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
constructor() {
|
|
80
|
+
this.metadata = {
|
|
81
|
+
name: "No-op Provider"
|
|
82
|
+
};
|
|
83
|
+
}
|
|
68
84
|
resolveBooleanEvaluation(_, defaultValue) {
|
|
69
85
|
return this.noOp(defaultValue);
|
|
70
86
|
}
|
|
@@ -87,30 +103,28 @@ var NoopFeatureProvider = class {
|
|
|
87
103
|
var NOOP_PROVIDER = new NoopFeatureProvider();
|
|
88
104
|
|
|
89
105
|
// src/provider/in-memory-provider/in-memory-provider.ts
|
|
90
|
-
var
|
|
106
|
+
var import_core3 = require("@openfeature/core");
|
|
91
107
|
|
|
92
108
|
// src/provider/in-memory-provider/variant-not-found-error.ts
|
|
93
|
-
var
|
|
94
|
-
var VariantFoundError = class _VariantFoundError extends
|
|
95
|
-
code;
|
|
109
|
+
var import_core2 = require("@openfeature/core");
|
|
110
|
+
var VariantFoundError = class _VariantFoundError extends import_core2.OpenFeatureError {
|
|
96
111
|
constructor(message) {
|
|
97
112
|
super(message);
|
|
98
113
|
Object.setPrototypeOf(this, _VariantFoundError.prototype);
|
|
99
114
|
this.name = "VariantFoundError";
|
|
100
|
-
this.code =
|
|
115
|
+
this.code = import_core2.ErrorCode.GENERAL;
|
|
101
116
|
}
|
|
102
117
|
};
|
|
103
118
|
|
|
104
119
|
// src/provider/in-memory-provider/in-memory-provider.ts
|
|
105
120
|
var InMemoryProvider = class {
|
|
106
|
-
events = new OpenFeatureEventEmitter();
|
|
107
|
-
runsOn = "server";
|
|
108
|
-
metadata = {
|
|
109
|
-
name: "in-memory"
|
|
110
|
-
};
|
|
111
|
-
_flagConfiguration;
|
|
112
121
|
constructor(flagConfiguration = {}) {
|
|
113
|
-
this.
|
|
122
|
+
this.events = new OpenFeatureEventEmitter();
|
|
123
|
+
this.runsOn = "server";
|
|
124
|
+
this.metadata = {
|
|
125
|
+
name: "in-memory"
|
|
126
|
+
};
|
|
127
|
+
this._flagConfiguration = __spreadValues({}, flagConfiguration);
|
|
114
128
|
}
|
|
115
129
|
/**
|
|
116
130
|
* Overwrites the configured flags.
|
|
@@ -118,8 +132,8 @@ var InMemoryProvider = class {
|
|
|
118
132
|
*/
|
|
119
133
|
putConfiguration(flagConfiguration) {
|
|
120
134
|
const flagsChanged = Object.entries(flagConfiguration).filter(([key, value]) => this._flagConfiguration[key] !== value).map(([key]) => key);
|
|
121
|
-
this._flagConfiguration = {
|
|
122
|
-
this.events.emit(
|
|
135
|
+
this._flagConfiguration = __spreadValues({}, flagConfiguration);
|
|
136
|
+
this.events.emit(import_core6.ServerProviderEvents.ConfigurationChanged, { flagsChanged });
|
|
123
137
|
}
|
|
124
138
|
resolveBooleanEvaluation(flagKey, defaultValue, context, logger) {
|
|
125
139
|
return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
|
|
@@ -127,163 +141,64 @@ var InMemoryProvider = class {
|
|
|
127
141
|
resolveNumberEvaluation(flagKey, defaultValue, context, logger) {
|
|
128
142
|
return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
|
|
129
143
|
}
|
|
130
|
-
|
|
131
|
-
return this
|
|
144
|
+
resolveStringEvaluation(flagKey, defaultValue, context, logger) {
|
|
145
|
+
return __async(this, null, function* () {
|
|
146
|
+
return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
|
|
147
|
+
});
|
|
132
148
|
}
|
|
133
|
-
|
|
134
|
-
return this
|
|
149
|
+
resolveObjectEvaluation(flagKey, defaultValue, context, logger) {
|
|
150
|
+
return __async(this, null, function* () {
|
|
151
|
+
return this.resolveFlagWithReason(flagKey, defaultValue, context, logger);
|
|
152
|
+
});
|
|
135
153
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
154
|
+
resolveFlagWithReason(flagKey, defaultValue, ctx, logger) {
|
|
155
|
+
return __async(this, null, function* () {
|
|
156
|
+
try {
|
|
157
|
+
const resolutionResult = this.lookupFlagValue(flagKey, defaultValue, ctx, logger);
|
|
158
|
+
if (typeof (resolutionResult == null ? void 0 : resolutionResult.value) != typeof defaultValue) {
|
|
159
|
+
throw new import_core3.TypeMismatchError();
|
|
160
|
+
}
|
|
161
|
+
return resolutionResult;
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (!(error instanceof import_core3.OpenFeatureError)) {
|
|
164
|
+
throw new import_core3.GeneralError((error == null ? void 0 : error.message) || "unknown error");
|
|
165
|
+
}
|
|
166
|
+
throw error;
|
|
146
167
|
}
|
|
147
|
-
|
|
148
|
-
}
|
|
168
|
+
});
|
|
149
169
|
}
|
|
150
170
|
lookupFlagValue(flagKey, defaultValue, ctx, logger) {
|
|
171
|
+
var _a;
|
|
151
172
|
if (!(flagKey in this._flagConfiguration)) {
|
|
152
173
|
const message = `no flag found with key ${flagKey}`;
|
|
153
|
-
logger
|
|
154
|
-
throw new
|
|
174
|
+
logger == null ? void 0 : logger.debug(message);
|
|
175
|
+
throw new import_core3.FlagNotFoundError(message);
|
|
155
176
|
}
|
|
156
177
|
const flagSpec = this._flagConfiguration[flagKey];
|
|
157
178
|
if (flagSpec.disabled) {
|
|
158
|
-
return { value: defaultValue, reason:
|
|
179
|
+
return { value: defaultValue, reason: import_core3.StandardResolutionReasons.DISABLED };
|
|
159
180
|
}
|
|
160
|
-
const isContextEval = ctx && flagSpec
|
|
161
|
-
const variant = isContextEval ? flagSpec.contextEvaluator
|
|
162
|
-
const value = variant && flagSpec
|
|
181
|
+
const isContextEval = ctx && (flagSpec == null ? void 0 : flagSpec.contextEvaluator);
|
|
182
|
+
const variant = isContextEval ? (_a = flagSpec.contextEvaluator) == null ? void 0 : _a.call(flagSpec, ctx) : flagSpec.defaultVariant;
|
|
183
|
+
const value = variant && (flagSpec == null ? void 0 : flagSpec.variants[variant]);
|
|
163
184
|
if (value === void 0) {
|
|
164
185
|
const message = `no value associated with variant ${variant}`;
|
|
165
|
-
logger
|
|
186
|
+
logger == null ? void 0 : logger.error(message);
|
|
166
187
|
throw new VariantFoundError(message);
|
|
167
188
|
}
|
|
168
|
-
return {
|
|
169
|
-
value
|
|
170
|
-
|
|
171
|
-
reason: isContextEval ?
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
// src/transaction-context/no-op-transaction-context-propagator.ts
|
|
177
|
-
var NoopTransactionContextPropagator = class {
|
|
178
|
-
getTransactionContext() {
|
|
179
|
-
return {};
|
|
180
|
-
}
|
|
181
|
-
setTransactionContext(_, callback, ...args) {
|
|
182
|
-
callback(...args);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
|
|
186
|
-
|
|
187
|
-
// src/transaction-context/async-local-storage-transaction-context-propagator.ts
|
|
188
|
-
var import_async_hooks = require("async_hooks");
|
|
189
|
-
var AsyncLocalStorageTransactionContextPropagator = class {
|
|
190
|
-
asyncLocalStorage = new import_async_hooks.AsyncLocalStorage();
|
|
191
|
-
getTransactionContext() {
|
|
192
|
-
return this.asyncLocalStorage.getStore() ?? {};
|
|
193
|
-
}
|
|
194
|
-
setTransactionContext(transactionContext, callback, ...args) {
|
|
195
|
-
this.asyncLocalStorage.run(transactionContext, callback, ...args);
|
|
189
|
+
return __spreadProps(__spreadValues({
|
|
190
|
+
value
|
|
191
|
+
}, variant && { variant }), {
|
|
192
|
+
reason: isContextEval ? import_core3.StandardResolutionReasons.TARGETING_MATCH : import_core3.StandardResolutionReasons.STATIC
|
|
193
|
+
});
|
|
196
194
|
}
|
|
197
195
|
};
|
|
198
196
|
|
|
199
197
|
// src/open-feature.ts
|
|
200
|
-
var
|
|
201
|
-
var _globalThis = globalThis;
|
|
202
|
-
var OpenFeatureAPI = class _OpenFeatureAPI extends import_core6.OpenFeatureCommonAPI {
|
|
203
|
-
_statusEnumType = import_core3.ServerProviderStatus;
|
|
204
|
-
_apiEmitter = new OpenFeatureEventEmitter();
|
|
205
|
-
_defaultProvider = new import_core6.ProviderWrapper(NOOP_PROVIDER, import_core3.ServerProviderStatus.NOT_READY, this._statusEnumType);
|
|
206
|
-
_domainScopedProviders = /* @__PURE__ */ new Map();
|
|
207
|
-
_createEventEmitter = () => new OpenFeatureEventEmitter();
|
|
208
|
-
_transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
|
|
209
|
-
constructor() {
|
|
210
|
-
super("server");
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Gets a singleton instance of the OpenFeature API.
|
|
214
|
-
* @ignore
|
|
215
|
-
* @returns {OpenFeatureAPI} OpenFeature API
|
|
216
|
-
*/
|
|
217
|
-
static getInstance() {
|
|
218
|
-
const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];
|
|
219
|
-
if (globalApi) {
|
|
220
|
-
return globalApi;
|
|
221
|
-
}
|
|
222
|
-
const instance = new _OpenFeatureAPI();
|
|
223
|
-
_globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
|
|
224
|
-
return instance;
|
|
225
|
-
}
|
|
226
|
-
getProviderStatus(domain) {
|
|
227
|
-
if (!domain) {
|
|
228
|
-
return this._defaultProvider.status;
|
|
229
|
-
}
|
|
230
|
-
return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;
|
|
231
|
-
}
|
|
232
|
-
setContext(context) {
|
|
233
|
-
this._context = context;
|
|
234
|
-
return this;
|
|
235
|
-
}
|
|
236
|
-
getContext() {
|
|
237
|
-
return this._context;
|
|
238
|
-
}
|
|
239
|
-
getClient(domainOrContext, versionOrContext, contextOrUndefined) {
|
|
240
|
-
const domain = (0, import_core6.stringOrUndefined)(domainOrContext);
|
|
241
|
-
const version = (0, import_core6.stringOrUndefined)(versionOrContext);
|
|
242
|
-
const context = (0, import_core6.objectOrUndefined)(domainOrContext) ?? (0, import_core6.objectOrUndefined)(versionOrContext) ?? (0, import_core6.objectOrUndefined)(contextOrUndefined);
|
|
243
|
-
return new OpenFeatureClient(
|
|
244
|
-
() => this.getProviderForClient(domain),
|
|
245
|
-
() => this.getProviderStatus(domain),
|
|
246
|
-
() => this.buildAndCacheEventEmitterForClient(domain),
|
|
247
|
-
() => this._logger,
|
|
248
|
-
{ domain, version },
|
|
249
|
-
context
|
|
250
|
-
);
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Clears all registered providers and resets the default provider.
|
|
254
|
-
* @returns {Promise<void>}
|
|
255
|
-
*/
|
|
256
|
-
clearProviders() {
|
|
257
|
-
return super.clearProvidersAndSetDefault(NOOP_PROVIDER);
|
|
258
|
-
}
|
|
259
|
-
setTransactionContextPropagator(transactionContextPropagator) {
|
|
260
|
-
const baseMessage = "Invalid TransactionContextPropagator, will not be set: ";
|
|
261
|
-
if (typeof transactionContextPropagator?.getTransactionContext !== "function") {
|
|
262
|
-
this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);
|
|
263
|
-
} else if (typeof transactionContextPropagator?.setTransactionContext !== "function") {
|
|
264
|
-
this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);
|
|
265
|
-
} else {
|
|
266
|
-
this._transactionContextPropagator = transactionContextPropagator;
|
|
267
|
-
}
|
|
268
|
-
return this;
|
|
269
|
-
}
|
|
270
|
-
setTransactionContext(transactionContext, callback, ...args) {
|
|
271
|
-
this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);
|
|
272
|
-
}
|
|
273
|
-
getTransactionContext() {
|
|
274
|
-
try {
|
|
275
|
-
return this._transactionContextPropagator.getTransactionContext();
|
|
276
|
-
} catch (err) {
|
|
277
|
-
const error = err;
|
|
278
|
-
this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);
|
|
279
|
-
this._logger.error(error?.stack);
|
|
280
|
-
return {};
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
var OpenFeature = OpenFeatureAPI.getInstance();
|
|
198
|
+
var import_core7 = require("@openfeature/core");
|
|
285
199
|
|
|
286
|
-
// src/client/open-feature-client.ts
|
|
200
|
+
// src/client/internal/open-feature-client.ts
|
|
201
|
+
var import_core4 = require("@openfeature/core");
|
|
287
202
|
var OpenFeatureClient = class {
|
|
288
203
|
constructor(providerAccessor, providerStatusAccessor, emitterAccessor, globalLogger, options, context = {}) {
|
|
289
204
|
this.providerAccessor = providerAccessor;
|
|
@@ -291,16 +206,15 @@ var OpenFeatureClient = class {
|
|
|
291
206
|
this.emitterAccessor = emitterAccessor;
|
|
292
207
|
this.globalLogger = globalLogger;
|
|
293
208
|
this.options = options;
|
|
209
|
+
this._hooks = [];
|
|
294
210
|
this._context = context;
|
|
295
211
|
}
|
|
296
|
-
_context;
|
|
297
|
-
_hooks = [];
|
|
298
|
-
_clientLogger;
|
|
299
212
|
get metadata() {
|
|
213
|
+
var _a, _b;
|
|
300
214
|
return {
|
|
301
215
|
// Use domain if name is not provided
|
|
302
|
-
name: this.options.domain
|
|
303
|
-
domain: this.options.domain
|
|
216
|
+
name: (_a = this.options.domain) != null ? _a : this.options.name,
|
|
217
|
+
domain: (_b = this.options.domain) != null ? _b : this.options.name,
|
|
304
218
|
version: this.options.version,
|
|
305
219
|
providerMetadata: this.providerAccessor().metadata
|
|
306
220
|
};
|
|
@@ -309,8 +223,9 @@ var OpenFeatureClient = class {
|
|
|
309
223
|
return this.providerStatusAccessor();
|
|
310
224
|
}
|
|
311
225
|
addHandler(eventType, handler) {
|
|
226
|
+
var _a;
|
|
312
227
|
this.emitterAccessor().addHandler(eventType, handler);
|
|
313
|
-
const shouldRunNow = (0,
|
|
228
|
+
const shouldRunNow = (0, import_core4.statusMatchesEvent)(eventType, this._providerStatus);
|
|
314
229
|
if (shouldRunNow) {
|
|
315
230
|
try {
|
|
316
231
|
handler({
|
|
@@ -319,7 +234,7 @@ var OpenFeatureClient = class {
|
|
|
319
234
|
providerName: this._provider.metadata.name
|
|
320
235
|
});
|
|
321
236
|
} catch (err) {
|
|
322
|
-
this._logger
|
|
237
|
+
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
|
|
323
238
|
}
|
|
324
239
|
}
|
|
325
240
|
}
|
|
@@ -330,7 +245,7 @@ var OpenFeatureClient = class {
|
|
|
330
245
|
return this.emitterAccessor().getHandlers(eventType);
|
|
331
246
|
}
|
|
332
247
|
setLogger(logger) {
|
|
333
|
-
this._clientLogger = new
|
|
248
|
+
this._clientLogger = new import_core4.SafeLogger(logger);
|
|
334
249
|
return this;
|
|
335
250
|
}
|
|
336
251
|
setContext(context) {
|
|
@@ -351,8 +266,10 @@ var OpenFeatureClient = class {
|
|
|
351
266
|
this._hooks = [];
|
|
352
267
|
return this;
|
|
353
268
|
}
|
|
354
|
-
|
|
355
|
-
return (
|
|
269
|
+
getBooleanValue(flagKey, defaultValue, context, options) {
|
|
270
|
+
return __async(this, null, function* () {
|
|
271
|
+
return (yield this.getBooleanDetails(flagKey, defaultValue, context, options)).value;
|
|
272
|
+
});
|
|
356
273
|
}
|
|
357
274
|
getBooleanDetails(flagKey, defaultValue, context, options) {
|
|
358
275
|
return this.evaluate(
|
|
@@ -364,8 +281,10 @@ var OpenFeatureClient = class {
|
|
|
364
281
|
options
|
|
365
282
|
);
|
|
366
283
|
}
|
|
367
|
-
|
|
368
|
-
return (
|
|
284
|
+
getStringValue(flagKey, defaultValue, context, options) {
|
|
285
|
+
return __async(this, null, function* () {
|
|
286
|
+
return (yield this.getStringDetails(flagKey, defaultValue, context, options)).value;
|
|
287
|
+
});
|
|
369
288
|
}
|
|
370
289
|
getStringDetails(flagKey, defaultValue, context, options) {
|
|
371
290
|
return this.evaluate(
|
|
@@ -378,8 +297,10 @@ var OpenFeatureClient = class {
|
|
|
378
297
|
options
|
|
379
298
|
);
|
|
380
299
|
}
|
|
381
|
-
|
|
382
|
-
return (
|
|
300
|
+
getNumberValue(flagKey, defaultValue, context, options) {
|
|
301
|
+
return __async(this, null, function* () {
|
|
302
|
+
return (yield this.getNumberDetails(flagKey, defaultValue, context, options)).value;
|
|
303
|
+
});
|
|
383
304
|
}
|
|
384
305
|
getNumberDetails(flagKey, defaultValue, context, options) {
|
|
385
306
|
return this.evaluate(
|
|
@@ -392,106 +313,117 @@ var OpenFeatureClient = class {
|
|
|
392
313
|
options
|
|
393
314
|
);
|
|
394
315
|
}
|
|
395
|
-
|
|
396
|
-
return (
|
|
316
|
+
getObjectValue(flagKey, defaultValue, context, options) {
|
|
317
|
+
return __async(this, null, function* () {
|
|
318
|
+
return (yield this.getObjectDetails(flagKey, defaultValue, context, options)).value;
|
|
319
|
+
});
|
|
397
320
|
}
|
|
398
321
|
getObjectDetails(flagKey, defaultValue, context, options) {
|
|
399
322
|
return this.evaluate(flagKey, this._provider.resolveObjectEvaluation, defaultValue, "object", context, options);
|
|
400
323
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
...
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
providerMetadata: this._provider.metadata,
|
|
421
|
-
context: mergedContext,
|
|
422
|
-
logger: this._logger
|
|
423
|
-
};
|
|
424
|
-
try {
|
|
425
|
-
const frozenContext = await this.beforeHooks(allHooks, hookContext, options);
|
|
426
|
-
if (this.providerStatus === import_core3.ServerProviderStatus.NOT_READY) {
|
|
427
|
-
throw new import_core7.ProviderNotReadyError("provider has not yet initialized");
|
|
428
|
-
} else if (this.providerStatus === import_core3.ServerProviderStatus.FATAL) {
|
|
429
|
-
throw new import_core7.ProviderFatalError("provider is in an irrecoverable error state");
|
|
430
|
-
}
|
|
431
|
-
const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);
|
|
432
|
-
const evaluationDetails = {
|
|
433
|
-
...resolution,
|
|
434
|
-
flagMetadata: Object.freeze(resolution.flagMetadata ?? {}),
|
|
435
|
-
flagKey
|
|
324
|
+
evaluate(_0, _1, _2, _3) {
|
|
325
|
+
return __async(this, arguments, function* (flagKey, resolver, defaultValue, flagType, invocationContext = {}, options = {}) {
|
|
326
|
+
var _a;
|
|
327
|
+
const allHooks = [
|
|
328
|
+
...OpenFeature.getHooks(),
|
|
329
|
+
...this.getHooks(),
|
|
330
|
+
...options.hooks || [],
|
|
331
|
+
...this._provider.hooks || []
|
|
332
|
+
];
|
|
333
|
+
const allHooksReversed = [...allHooks].reverse();
|
|
334
|
+
const mergedContext = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, OpenFeature.getContext()), OpenFeature.getTransactionContext()), this._context), invocationContext);
|
|
335
|
+
const hookContext = {
|
|
336
|
+
flagKey,
|
|
337
|
+
defaultValue,
|
|
338
|
+
flagValueType: flagType,
|
|
339
|
+
clientMetadata: this.metadata,
|
|
340
|
+
providerMetadata: this._provider.metadata,
|
|
341
|
+
context: mergedContext,
|
|
342
|
+
logger: this._logger
|
|
436
343
|
};
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
344
|
+
try {
|
|
345
|
+
const frozenContext = yield this.beforeHooks(allHooks, hookContext, options);
|
|
346
|
+
if (this.providerStatus === import_core.ServerProviderStatus.NOT_READY) {
|
|
347
|
+
throw new import_core4.ProviderNotReadyError("provider has not yet initialized");
|
|
348
|
+
} else if (this.providerStatus === import_core.ServerProviderStatus.FATAL) {
|
|
349
|
+
throw new import_core4.ProviderFatalError("provider is in an irrecoverable error state");
|
|
350
|
+
}
|
|
351
|
+
const resolution = yield resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);
|
|
352
|
+
const evaluationDetails = __spreadProps(__spreadValues({}, resolution), {
|
|
353
|
+
flagMetadata: Object.freeze((_a = resolution.flagMetadata) != null ? _a : {}),
|
|
354
|
+
flagKey
|
|
355
|
+
});
|
|
356
|
+
if (evaluationDetails.errorCode) {
|
|
357
|
+
throw (0, import_core4.instantiateErrorByErrorCode)(evaluationDetails.errorCode);
|
|
358
|
+
}
|
|
359
|
+
yield this.afterHooks(allHooksReversed, hookContext, evaluationDetails, options);
|
|
360
|
+
return evaluationDetails;
|
|
361
|
+
} catch (err) {
|
|
362
|
+
const errorMessage = err == null ? void 0 : err.message;
|
|
363
|
+
const errorCode = (err == null ? void 0 : err.code) || import_core4.ErrorCode.GENERAL;
|
|
364
|
+
yield this.errorHooks(allHooksReversed, hookContext, err, options);
|
|
365
|
+
return {
|
|
366
|
+
errorCode,
|
|
367
|
+
errorMessage,
|
|
368
|
+
value: defaultValue,
|
|
369
|
+
reason: import_core4.StandardResolutionReasons.ERROR,
|
|
370
|
+
flagMetadata: Object.freeze({}),
|
|
371
|
+
flagKey
|
|
372
|
+
};
|
|
373
|
+
} finally {
|
|
374
|
+
yield this.finallyHooks(allHooksReversed, hookContext, options);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
454
377
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
|
|
378
|
+
beforeHooks(hooks, hookContext, options) {
|
|
379
|
+
return __async(this, null, function* () {
|
|
380
|
+
var _a;
|
|
381
|
+
for (const hook of hooks) {
|
|
382
|
+
Object.freeze(hookContext);
|
|
383
|
+
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))));
|
|
384
|
+
}
|
|
385
|
+
return Object.freeze(hookContext.context);
|
|
386
|
+
});
|
|
464
387
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
388
|
+
afterHooks(hooks, hookContext, evaluationDetails, options) {
|
|
389
|
+
return __async(this, null, function* () {
|
|
390
|
+
var _a;
|
|
391
|
+
for (const hook of hooks) {
|
|
392
|
+
yield (_a = hook == null ? void 0 : hook.after) == null ? void 0 : _a.call(hook, hookContext, evaluationDetails, options.hookHints);
|
|
393
|
+
}
|
|
394
|
+
});
|
|
469
395
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
this._logger.error(err2
|
|
396
|
+
errorHooks(hooks, hookContext, err, options) {
|
|
397
|
+
return __async(this, null, function* () {
|
|
398
|
+
var _a;
|
|
399
|
+
for (const hook of hooks) {
|
|
400
|
+
try {
|
|
401
|
+
yield (_a = hook == null ? void 0 : hook.error) == null ? void 0 : _a.call(hook, hookContext, err, options.hookHints);
|
|
402
|
+
} catch (err2) {
|
|
403
|
+
this._logger.error(`Unhandled error during 'error' hook: ${err2}`);
|
|
404
|
+
if (err2 instanceof Error) {
|
|
405
|
+
this._logger.error(err2.stack);
|
|
406
|
+
}
|
|
407
|
+
this._logger.error(err2 == null ? void 0 : err2.stack);
|
|
478
408
|
}
|
|
479
|
-
this._logger.error(err2?.stack);
|
|
480
409
|
}
|
|
481
|
-
}
|
|
410
|
+
});
|
|
482
411
|
}
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
this._logger.error(err
|
|
412
|
+
finallyHooks(hooks, hookContext, options) {
|
|
413
|
+
return __async(this, null, function* () {
|
|
414
|
+
var _a;
|
|
415
|
+
for (const hook of hooks) {
|
|
416
|
+
try {
|
|
417
|
+
yield (_a = hook == null ? void 0 : hook.finally) == null ? void 0 : _a.call(hook, hookContext, options.hookHints);
|
|
418
|
+
} catch (err) {
|
|
419
|
+
this._logger.error(`Unhandled error during 'finally' hook: ${err}`);
|
|
420
|
+
if (err instanceof Error) {
|
|
421
|
+
this._logger.error(err.stack);
|
|
422
|
+
}
|
|
423
|
+
this._logger.error(err == null ? void 0 : err.stack);
|
|
491
424
|
}
|
|
492
|
-
this._logger.error(err?.stack);
|
|
493
425
|
}
|
|
494
|
-
}
|
|
426
|
+
});
|
|
495
427
|
}
|
|
496
428
|
get _provider() {
|
|
497
429
|
return this.providerAccessor();
|
|
@@ -504,6 +436,158 @@ var OpenFeatureClient = class {
|
|
|
504
436
|
}
|
|
505
437
|
};
|
|
506
438
|
|
|
439
|
+
// src/events/open-feature-event-emitter.ts
|
|
440
|
+
var import_core5 = require("@openfeature/core");
|
|
441
|
+
var import_node_events = require("events");
|
|
442
|
+
var OpenFeatureEventEmitter = class extends import_core5.GenericEventEmitter {
|
|
443
|
+
constructor() {
|
|
444
|
+
super();
|
|
445
|
+
this.eventEmitter = new import_node_events.EventEmitter({ captureRejections: true });
|
|
446
|
+
this.eventEmitter.on("error", (err) => {
|
|
447
|
+
var _a;
|
|
448
|
+
(_a = this._logger) == null ? void 0 : _a.error("Error running event handler:", err);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
453
|
+
// src/events/events.ts
|
|
454
|
+
var import_core6 = require("@openfeature/core");
|
|
455
|
+
|
|
456
|
+
// src/transaction-context/no-op-transaction-context-propagator.ts
|
|
457
|
+
var NoopTransactionContextPropagator = class {
|
|
458
|
+
getTransactionContext() {
|
|
459
|
+
return {};
|
|
460
|
+
}
|
|
461
|
+
setTransactionContext(_, callback, ...args) {
|
|
462
|
+
callback(...args);
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
var NOOP_TRANSACTION_CONTEXT_PROPAGATOR = new NoopTransactionContextPropagator();
|
|
466
|
+
|
|
467
|
+
// src/transaction-context/async-local-storage-transaction-context-propagator.ts
|
|
468
|
+
var import_async_hooks = require("async_hooks");
|
|
469
|
+
var AsyncLocalStorageTransactionContextPropagator = class {
|
|
470
|
+
constructor() {
|
|
471
|
+
this.asyncLocalStorage = new import_async_hooks.AsyncLocalStorage();
|
|
472
|
+
}
|
|
473
|
+
getTransactionContext() {
|
|
474
|
+
var _a;
|
|
475
|
+
return (_a = this.asyncLocalStorage.getStore()) != null ? _a : {};
|
|
476
|
+
}
|
|
477
|
+
setTransactionContext(transactionContext, callback, ...args) {
|
|
478
|
+
this.asyncLocalStorage.run(transactionContext, callback, ...args);
|
|
479
|
+
}
|
|
480
|
+
};
|
|
481
|
+
|
|
482
|
+
// src/open-feature.ts
|
|
483
|
+
var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js-sdk/api");
|
|
484
|
+
var _globalThis = globalThis;
|
|
485
|
+
var OpenFeatureAPI = class _OpenFeatureAPI extends import_core7.OpenFeatureCommonAPI {
|
|
486
|
+
constructor() {
|
|
487
|
+
super("server");
|
|
488
|
+
this._statusEnumType = import_core.ServerProviderStatus;
|
|
489
|
+
this._apiEmitter = new OpenFeatureEventEmitter();
|
|
490
|
+
this._defaultProvider = new import_core7.ProviderWrapper(
|
|
491
|
+
NOOP_PROVIDER,
|
|
492
|
+
import_core.ServerProviderStatus.NOT_READY,
|
|
493
|
+
this._statusEnumType
|
|
494
|
+
);
|
|
495
|
+
this._domainScopedProviders = /* @__PURE__ */ new Map();
|
|
496
|
+
this._createEventEmitter = () => new OpenFeatureEventEmitter();
|
|
497
|
+
this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Gets a singleton instance of the OpenFeature API.
|
|
501
|
+
* @ignore
|
|
502
|
+
* @returns {OpenFeatureAPI} OpenFeature API
|
|
503
|
+
*/
|
|
504
|
+
static getInstance() {
|
|
505
|
+
const globalApi = _globalThis[GLOBAL_OPENFEATURE_API_KEY];
|
|
506
|
+
if (globalApi) {
|
|
507
|
+
return globalApi;
|
|
508
|
+
}
|
|
509
|
+
const instance = new _OpenFeatureAPI();
|
|
510
|
+
_globalThis[GLOBAL_OPENFEATURE_API_KEY] = instance;
|
|
511
|
+
return instance;
|
|
512
|
+
}
|
|
513
|
+
getProviderStatus(domain) {
|
|
514
|
+
var _a, _b;
|
|
515
|
+
if (!domain) {
|
|
516
|
+
return this._defaultProvider.status;
|
|
517
|
+
}
|
|
518
|
+
return (_b = (_a = this._domainScopedProviders.get(domain)) == null ? void 0 : _a.status) != null ? _b : this._defaultProvider.status;
|
|
519
|
+
}
|
|
520
|
+
setProviderAndWait(domainOrProvider, providerOrUndefined) {
|
|
521
|
+
return __async(this, null, function* () {
|
|
522
|
+
const domain = (0, import_core7.stringOrUndefined)(domainOrProvider);
|
|
523
|
+
const provider = domain ? (0, import_core7.objectOrUndefined)(providerOrUndefined) : (0, import_core7.objectOrUndefined)(domainOrProvider);
|
|
524
|
+
yield this.setAwaitableProvider(domain, provider);
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
setProvider(clientOrProvider, providerOrUndefined) {
|
|
528
|
+
const domain = (0, import_core7.stringOrUndefined)(clientOrProvider);
|
|
529
|
+
const provider = domain ? (0, import_core7.objectOrUndefined)(providerOrUndefined) : (0, import_core7.objectOrUndefined)(clientOrProvider);
|
|
530
|
+
const maybePromise = this.setAwaitableProvider(domain, provider);
|
|
531
|
+
Promise.resolve(maybePromise).catch((err) => {
|
|
532
|
+
this._logger.error("Error during provider initialization:", err);
|
|
533
|
+
});
|
|
534
|
+
return this;
|
|
535
|
+
}
|
|
536
|
+
setContext(context) {
|
|
537
|
+
this._context = context;
|
|
538
|
+
return this;
|
|
539
|
+
}
|
|
540
|
+
getContext() {
|
|
541
|
+
return this._context;
|
|
542
|
+
}
|
|
543
|
+
getClient(domainOrContext, versionOrContext, contextOrUndefined) {
|
|
544
|
+
var _a, _b;
|
|
545
|
+
const domain = (0, import_core7.stringOrUndefined)(domainOrContext);
|
|
546
|
+
const version = (0, import_core7.stringOrUndefined)(versionOrContext);
|
|
547
|
+
const context = (_b = (_a = (0, import_core7.objectOrUndefined)(domainOrContext)) != null ? _a : (0, import_core7.objectOrUndefined)(versionOrContext)) != null ? _b : (0, import_core7.objectOrUndefined)(contextOrUndefined);
|
|
548
|
+
return new OpenFeatureClient(
|
|
549
|
+
() => this.getProviderForClient(domain),
|
|
550
|
+
() => this.getProviderStatus(domain),
|
|
551
|
+
() => this.buildAndCacheEventEmitterForClient(domain),
|
|
552
|
+
() => this._logger,
|
|
553
|
+
{ domain, version },
|
|
554
|
+
context
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Clears all registered providers and resets the default provider.
|
|
559
|
+
* @returns {Promise<void>}
|
|
560
|
+
*/
|
|
561
|
+
clearProviders() {
|
|
562
|
+
return super.clearProvidersAndSetDefault(NOOP_PROVIDER);
|
|
563
|
+
}
|
|
564
|
+
setTransactionContextPropagator(transactionContextPropagator) {
|
|
565
|
+
const baseMessage = "Invalid TransactionContextPropagator, will not be set: ";
|
|
566
|
+
if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.getTransactionContext) !== "function") {
|
|
567
|
+
this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);
|
|
568
|
+
} else if (typeof (transactionContextPropagator == null ? void 0 : transactionContextPropagator.setTransactionContext) !== "function") {
|
|
569
|
+
this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);
|
|
570
|
+
} else {
|
|
571
|
+
this._transactionContextPropagator = transactionContextPropagator;
|
|
572
|
+
}
|
|
573
|
+
return this;
|
|
574
|
+
}
|
|
575
|
+
setTransactionContext(transactionContext, callback, ...args) {
|
|
576
|
+
this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);
|
|
577
|
+
}
|
|
578
|
+
getTransactionContext() {
|
|
579
|
+
try {
|
|
580
|
+
return this._transactionContextPropagator.getTransactionContext();
|
|
581
|
+
} catch (err) {
|
|
582
|
+
const error = err;
|
|
583
|
+
this._logger.error(`Error getting transaction context: ${error == null ? void 0 : error.message}, returning empty context.`);
|
|
584
|
+
this._logger.error(error == null ? void 0 : error.stack);
|
|
585
|
+
return {};
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
var OpenFeature = OpenFeatureAPI.getInstance();
|
|
590
|
+
|
|
507
591
|
// src/index.ts
|
|
508
592
|
__reExport(src_exports, require("@openfeature/core"), module.exports);
|
|
509
593
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -514,7 +598,6 @@ __reExport(src_exports, require("@openfeature/core"), module.exports);
|
|
|
514
598
|
NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
|
|
515
599
|
OpenFeature,
|
|
516
600
|
OpenFeatureAPI,
|
|
517
|
-
OpenFeatureClient,
|
|
518
601
|
OpenFeatureEventEmitter,
|
|
519
602
|
ProviderEvents,
|
|
520
603
|
ProviderStatus,
|