Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@openfeature/server-sdk

Package Overview
Dependencies
Maintainers
2
Versions
27
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openfeature/server-sdk - npm Package Compare versions

Comparing version 1.12.0 to 1.13.0

122

dist/cjs/index.js
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;

@@ -21,10 +19,2 @@ var __export = (target, all) => {

var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

@@ -35,2 +25,3 @@

__export(src_exports, {
AsyncLocalStorageTransactionContextPropagator: () => AsyncLocalStorageTransactionContextPropagator,
InMemoryProvider: () => InMemoryProvider,

@@ -43,3 +34,4 @@ NOOP_PROVIDER: () => NOOP_PROVIDER,

OpenFeatureEventEmitter: () => OpenFeatureEventEmitter,
ProviderEvents: () => import_core5.ServerProviderEvents
ProviderEvents: () => import_core2.ServerProviderEvents,
ProviderStatus: () => import_core3.ServerProviderStatus
});

@@ -51,4 +43,25 @@ module.exports = __toCommonJS(src_exports);

// src/open-feature.ts
var import_core6 = require("@openfeature/core");
// src/events/open-feature-event-emitter.ts
var import_core = require("@openfeature/core");
var import_node_events = require("events");
var OpenFeatureEventEmitter = class extends import_core.GenericEventEmitter {
eventEmitter = new import_node_events.EventEmitter({ captureRejections: true });
constructor() {
super();
this.eventEmitter.on("error", (err) => {
this._logger?.error("Error running event handler:", err);
});
}
};
// src/events/events.ts
var import_core2 = require("@openfeature/core");
// src/provider/provider.ts
var import_core3 = require("@openfeature/core");
// src/provider/no-op-provider.ts
var import_core = require("@openfeature/core");
var REASON_NO_OP = "No-op";

@@ -59,5 +72,2 @@ var NoopFeatureProvider = class {

};
get status() {
return import_core.ProviderStatus.NOT_READY;
}
resolveBooleanEvaluation(_, defaultValue) {

@@ -85,7 +95,7 @@ return this.noOp(defaultValue);

// src/provider/in-memory-provider/in-memory-provider.ts
var import_core3 = require("@openfeature/core");
var import_core5 = require("@openfeature/core");
// src/provider/in-memory-provider/variant-not-found-error.ts
var import_core2 = require("@openfeature/core");
var VariantFoundError = class _VariantFoundError extends import_core2.OpenFeatureError {
var import_core4 = require("@openfeature/core");
var VariantFoundError = class _VariantFoundError extends import_core4.OpenFeatureError {
code;

@@ -96,3 +106,3 @@ constructor(message) {

this.name = "VariantFoundError";
this.code = import_core2.ErrorCode.GENERAL;
this.code = import_core4.ErrorCode.GENERAL;
}

@@ -119,3 +129,3 @@ };

this._flagConfiguration = { ...flagConfiguration };
this.events.emit(import_core5.ServerProviderEvents.ConfigurationChanged, { flagsChanged });
this.events.emit(import_core2.ServerProviderEvents.ConfigurationChanged, { flagsChanged });
}

@@ -138,8 +148,8 @@ resolveBooleanEvaluation(flagKey, defaultValue, context, logger) {

if (typeof resolutionResult?.value != typeof defaultValue) {
throw new import_core3.TypeMismatchError();
throw new import_core5.TypeMismatchError();
}
return resolutionResult;
} catch (error) {
if (!(error instanceof import_core3.OpenFeatureError)) {
throw new import_core3.GeneralError(error?.message || "unknown error");
if (!(error instanceof import_core5.OpenFeatureError)) {
throw new import_core5.GeneralError(error?.message || "unknown error");
}

@@ -153,7 +163,7 @@ throw error;

logger?.debug(message);
throw new import_core3.FlagNotFoundError(message);
throw new import_core5.FlagNotFoundError(message);
}
const flagSpec = this._flagConfiguration[flagKey];
if (flagSpec.disabled) {
return { value: defaultValue, reason: import_core3.StandardResolutionReasons.DISABLED };
return { value: defaultValue, reason: import_core5.StandardResolutionReasons.DISABLED };
}

@@ -171,3 +181,3 @@ const isContextEval = ctx && flagSpec?.contextEvaluator;

...variant && { variant },
reason: isContextEval ? import_core3.StandardResolutionReasons.TARGETING_MATCH : import_core3.StandardResolutionReasons.STATIC
reason: isContextEval ? import_core5.StandardResolutionReasons.TARGETING_MATCH : import_core5.StandardResolutionReasons.STATIC
};

@@ -177,5 +187,2 @@ }

// src/open-feature.ts
var import_core6 = require("@openfeature/core");
// src/transaction-context/no-op-transaction-context-propagator.ts

@@ -186,4 +193,4 @@ var NoopTransactionContextPropagator = class {

}
setTransactionContext(_, callback) {
callback();
setTransactionContext(_, callback, ...args) {
callback(...args);
}

@@ -193,18 +200,14 @@ };

// src/events/open-feature-event-emitter.ts
var import_core4 = require("@openfeature/core");
var import_events = __toESM(require("events"));
var OpenFeatureEventEmitter = class extends import_core4.GenericEventEmitter {
eventEmitter = new import_events.default({ captureRejections: true });
constructor() {
super();
this.eventEmitter.on("error", (err) => {
this._logger?.error("Error running event handler:", err);
});
// src/transaction-context/async-local-storage-transaction-context-propagator.ts
var import_async_hooks = require("async_hooks");
var AsyncLocalStorageTransactionContextPropagator = class {
asyncLocalStorage = new import_async_hooks.AsyncLocalStorage();
getTransactionContext() {
return this.asyncLocalStorage.getStore() ?? {};
}
setTransactionContext(transactionContext, callback, ...args) {
this.asyncLocalStorage.run(transactionContext, callback, ...args);
}
};
// src/events/events.ts
var import_core5 = require("@openfeature/core");
// src/open-feature.ts

@@ -214,4 +217,6 @@ var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js-sdk/api");

var OpenFeatureAPI = class _OpenFeatureAPI extends import_core6.OpenFeatureCommonAPI {
_events = new OpenFeatureEventEmitter();
_defaultProvider = NOOP_PROVIDER;
_statusEnumType = import_core3.ServerProviderStatus;
_apiEmitter = new OpenFeatureEventEmitter();
_defaultProvider = new import_core6.ProviderWrapper(NOOP_PROVIDER, import_core3.ServerProviderStatus.NOT_READY, this._statusEnumType);
_domainScopedProviders = /* @__PURE__ */ new Map();
_createEventEmitter = () => new OpenFeatureEventEmitter();

@@ -236,2 +241,8 @@ _transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;

}
getProviderStatus(domain) {
if (!domain) {
return this._defaultProvider.status;
}
return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;
}
setContext(context) {

@@ -250,2 +261,3 @@ this._context = context;

() => this.getProviderForClient(domain),
() => this.getProviderStatus(domain),
() => this.buildAndCacheEventEmitterForClient(domain),

@@ -293,4 +305,5 @@ () => this._logger,

var OpenFeatureClient = class {
constructor(providerAccessor, emitterAccessor, globalLogger, options, context = {}) {
constructor(providerAccessor, providerStatusAccessor, emitterAccessor, globalLogger, options, context = {}) {
this.providerAccessor = providerAccessor;
this.providerStatusAccessor = providerStatusAccessor;
this.emitterAccessor = emitterAccessor;

@@ -313,5 +326,8 @@ this.globalLogger = globalLogger;

}
get providerStatus() {
return this.providerStatusAccessor();
}
addHandler(eventType, handler) {
this.emitterAccessor().addHandler(eventType, handler);
const shouldRunNow = (0, import_core7.statusMatchesEvent)(eventType, this._provider.status);
const shouldRunNow = (0, import_core7.statusMatchesEvent)(eventType, this._providerStatus);
if (shouldRunNow) {

@@ -429,2 +445,7 @@ try {

const frozenContext = await this.beforeHooks(allHooks, hookContext, options);
if (this.providerStatus === import_core3.ServerProviderStatus.NOT_READY) {
throw new import_core7.ProviderNotReadyError("provider has not yet initialized");
} else if (this.providerStatus === import_core3.ServerProviderStatus.FATAL) {
throw new import_core7.ProviderFatalError("provider is in an irrecoverable error state");
}
const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);

@@ -498,2 +519,5 @@ const evaluationDetails = {

}
get _providerStatus() {
return this.providerStatusAccessor();
}
get _logger() {

@@ -508,2 +532,3 @@ return this._clientLogger || this.globalLogger();

0 && (module.exports = {
AsyncLocalStorageTransactionContextPropagator,
InMemoryProvider,

@@ -517,4 +542,5 @@ NOOP_PROVIDER,

ProviderEvents,
ProviderStatus,
...require("@openfeature/core")
});
//# sourceMappingURL=index.js.map
// src/client/open-feature-client.ts
import {
ErrorCode as ErrorCode2,
ProviderFatalError,
ProviderNotReadyError,
SafeLogger,

@@ -9,4 +11,30 @@ StandardResolutionReasons as StandardResolutionReasons2,

// src/open-feature.ts
import {
OpenFeatureCommonAPI,
ProviderWrapper,
objectOrUndefined,
stringOrUndefined
} from "@openfeature/core";
// src/events/open-feature-event-emitter.ts
import { GenericEventEmitter } from "@openfeature/core";
import { EventEmitter } from "events";
var OpenFeatureEventEmitter = class extends GenericEventEmitter {
eventEmitter = new EventEmitter({ captureRejections: true });
constructor() {
super();
this.eventEmitter.on("error", (err) => {
this._logger?.error("Error running event handler:", err);
});
}
};
// src/events/events.ts
import { ServerProviderEvents } from "@openfeature/core";
// src/provider/provider.ts
import { ServerProviderStatus } from "@openfeature/core";
// src/provider/no-op-provider.ts
import { ProviderStatus } from "@openfeature/core";
var REASON_NO_OP = "No-op";

@@ -17,5 +45,2 @@ var NoopFeatureProvider = class {

};
get status() {
return ProviderStatus.NOT_READY;
}
resolveBooleanEvaluation(_, defaultValue) {

@@ -135,9 +160,2 @@ return this.noOp(defaultValue);

// src/open-feature.ts
import {
OpenFeatureCommonAPI,
objectOrUndefined,
stringOrUndefined
} from "@openfeature/core";
// src/transaction-context/no-op-transaction-context-propagator.ts

@@ -148,4 +166,4 @@ var NoopTransactionContextPropagator = class {

}
setTransactionContext(_, callback) {
callback();
setTransactionContext(_, callback, ...args) {
callback(...args);
}

@@ -155,18 +173,14 @@ };

// src/events/open-feature-event-emitter.ts
import { GenericEventEmitter } from "@openfeature/core";
import EventEmitter from "events";
var OpenFeatureEventEmitter = class extends GenericEventEmitter {
eventEmitter = new EventEmitter({ captureRejections: true });
constructor() {
super();
this.eventEmitter.on("error", (err) => {
this._logger?.error("Error running event handler:", err);
});
// src/transaction-context/async-local-storage-transaction-context-propagator.ts
import { AsyncLocalStorage } from "async_hooks";
var AsyncLocalStorageTransactionContextPropagator = class {
asyncLocalStorage = new AsyncLocalStorage();
getTransactionContext() {
return this.asyncLocalStorage.getStore() ?? {};
}
setTransactionContext(transactionContext, callback, ...args) {
this.asyncLocalStorage.run(transactionContext, callback, ...args);
}
};
// src/events/events.ts
import { ServerProviderEvents } from "@openfeature/core";
// src/open-feature.ts

@@ -176,4 +190,6 @@ var GLOBAL_OPENFEATURE_API_KEY = Symbol.for("@openfeature/js-sdk/api");

var OpenFeatureAPI = class _OpenFeatureAPI extends OpenFeatureCommonAPI {
_events = new OpenFeatureEventEmitter();
_defaultProvider = NOOP_PROVIDER;
_statusEnumType = ServerProviderStatus;
_apiEmitter = new OpenFeatureEventEmitter();
_defaultProvider = new ProviderWrapper(NOOP_PROVIDER, ServerProviderStatus.NOT_READY, this._statusEnumType);
_domainScopedProviders = /* @__PURE__ */ new Map();
_createEventEmitter = () => new OpenFeatureEventEmitter();

@@ -198,2 +214,8 @@ _transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;

}
getProviderStatus(domain) {
if (!domain) {
return this._defaultProvider.status;
}
return this._domainScopedProviders.get(domain)?.status ?? this._defaultProvider.status;
}
setContext(context) {

@@ -212,2 +234,3 @@ this._context = context;

() => this.getProviderForClient(domain),
() => this.getProviderStatus(domain),
() => this.buildAndCacheEventEmitterForClient(domain),

@@ -255,4 +278,5 @@ () => this._logger,

var OpenFeatureClient = class {
constructor(providerAccessor, emitterAccessor, globalLogger, options, context = {}) {
constructor(providerAccessor, providerStatusAccessor, emitterAccessor, globalLogger, options, context = {}) {
this.providerAccessor = providerAccessor;
this.providerStatusAccessor = providerStatusAccessor;
this.emitterAccessor = emitterAccessor;

@@ -275,5 +299,8 @@ this.globalLogger = globalLogger;

}
get providerStatus() {
return this.providerStatusAccessor();
}
addHandler(eventType, handler) {
this.emitterAccessor().addHandler(eventType, handler);
const shouldRunNow = statusMatchesEvent(eventType, this._provider.status);
const shouldRunNow = statusMatchesEvent(eventType, this._providerStatus);
if (shouldRunNow) {

@@ -391,2 +418,7 @@ try {

const frozenContext = await this.beforeHooks(allHooks, hookContext, options);
if (this.providerStatus === ServerProviderStatus.NOT_READY) {
throw new ProviderNotReadyError("provider has not yet initialized");
} else if (this.providerStatus === ServerProviderStatus.FATAL) {
throw new ProviderFatalError("provider is in an irrecoverable error state");
}
const resolution = await resolver.call(this._provider, flagKey, defaultValue, frozenContext, this._logger);

@@ -460,2 +492,5 @@ const evaluationDetails = {

}
get _providerStatus() {
return this.providerStatusAccessor();
}
get _logger() {

@@ -469,2 +504,3 @@ return this._clientLogger || this.globalLogger();

export {
AsyncLocalStorageTransactionContextPropagator,
InMemoryProvider,

@@ -477,4 +513,5 @@ NOOP_PROVIDER,

OpenFeatureEventEmitter,
ServerProviderEvents as ProviderEvents
ServerProviderEvents as ProviderEvents,
ServerProviderStatus as ProviderStatus
};
//# sourceMappingURL=index.js.map

@@ -1,5 +0,6 @@

import { BaseHook, FlagValue, EvaluationContext, HookHints, EvaluationDetails, JsonValue, EvaluationLifeCycle, ManageContext, ManageLogger, Eventing, ClientMetadata, GenericEventEmitter, ServerProviderEvents, CommonProvider, Logger, ResolutionDetails, ProviderStatus, EventHandler, OpenFeatureCommonAPI } from '@openfeature/core';
import * as _openfeature_core from '@openfeature/core';
import { BaseHook, FlagValue, EvaluationContext, HookHints, EvaluationDetails, JsonValue, CommonProvider, ServerProviderStatus, Logger, ResolutionDetails, GenericEventEmitter, ServerProviderEvents, EvaluationLifeCycle, ManageContext, ManageLogger, Eventing, ClientMetadata, EventHandler, OpenFeatureCommonAPI, ProviderWrapper } from '@openfeature/core';
export * from '@openfeature/core';
export { ServerProviderEvents as ProviderEvents } from '@openfeature/core';
import EventEmitter from 'events';
export { ServerProviderEvents as ProviderEvents, ServerProviderStatus as ProviderStatus } from '@openfeature/core';
import { EventEmitter } from 'node:events';

@@ -99,27 +100,3 @@ type Hook = BaseHook<FlagValue, Promise<EvaluationContext | void> | EvaluationContext | void, Promise<void> | void>;

interface Client extends EvaluationLifeCycle<Client>, Features, ManageContext<Client>, ManageLogger<Client>, Eventing {
readonly metadata: ClientMetadata;
}
/**
* The OpenFeatureEventEmitter can be used by provider developers to emit
* events at various parts of the provider lifecycle.
*
* NOTE: Ready and error events are automatically emitted by the SDK based on
* the result of the initialize method.
*/
declare class OpenFeatureEventEmitter extends GenericEventEmitter<ServerProviderEvents> {
protected readonly eventEmitter: EventEmitter;
constructor();
}
/**
* The InternalEventEmitter is not exported publicly and should only be used within the SDK. It extends the
* OpenFeatureEventEmitter to include additional properties that can be included
* in the event details.
*/
declare abstract class InternalEventEmitter extends GenericEventEmitter<ServerProviderEvents> {
}
/**
* Interface that providers must implement to resolve flag values for their particular

@@ -130,3 +107,3 @@ * backend or vendor.

*/
interface Provider extends CommonProvider {
interface Provider extends CommonProvider<ServerProviderStatus> {
/**

@@ -164,3 +141,2 @@ * A provider hook exposes a mechanism for provider authors to register hooks

};
get status(): ProviderStatus;
resolveBooleanEvaluation(_: string, defaultValue: boolean): Promise<ResolutionDetails<boolean>>;

@@ -232,2 +208,30 @@ resolveStringEvaluation(_: string, defaultValue: string): Promise<ResolutionDetails<string>>;

/**
* The OpenFeatureEventEmitter can be used by provider developers to emit
* events at various parts of the provider lifecycle.
*
* NOTE: Ready and error events are automatically emitted by the SDK based on
* the result of the initialize method.
*/
declare class OpenFeatureEventEmitter extends GenericEventEmitter<ServerProviderEvents> {
protected readonly eventEmitter: EventEmitter;
constructor();
}
interface Client extends EvaluationLifeCycle<Client>, Features, ManageContext<Client>, ManageLogger<Client>, Eventing<ServerProviderEvents> {
readonly metadata: ClientMetadata;
/**
* Returns the status of the associated provider.
*/
readonly providerStatus: ServerProviderStatus;
}
/**
* The InternalEventEmitter is not exported publicly and should only be used within the SDK. It extends the
* OpenFeatureEventEmitter to include additional properties that can be included
* in the event details.
*/
declare abstract class InternalEventEmitter extends GenericEventEmitter<ServerProviderEvents> {
}
type OpenFeatureClientOptions = {

@@ -243,2 +247,3 @@ /**

private readonly providerAccessor;
private readonly providerStatusAccessor;
private readonly emitterAccessor;

@@ -250,7 +255,8 @@ private readonly globalLogger;

private _clientLogger?;
constructor(providerAccessor: () => Provider, emitterAccessor: () => InternalEventEmitter, globalLogger: () => Logger, options: OpenFeatureClientOptions, context?: EvaluationContext);
constructor(providerAccessor: () => Provider, providerStatusAccessor: () => ServerProviderStatus, emitterAccessor: () => InternalEventEmitter, globalLogger: () => Logger, options: OpenFeatureClientOptions, context?: EvaluationContext);
get metadata(): ClientMetadata;
get providerStatus(): ServerProviderStatus;
addHandler(eventType: ServerProviderEvents, handler: EventHandler): void;
removeHandler(eventType: ServerProviderEvents, handler: EventHandler): void;
getHandlers(eventType: ServerProviderEvents): EventHandler[];
getHandlers(eventType: ServerProviderEvents): EventHandler<ServerProviderEvents | _openfeature_core.AllProviderEvents>[];
setLogger(logger: Logger): OpenFeatureClient;

@@ -276,2 +282,3 @@ setContext(context: EvaluationContext): OpenFeatureClient;

private get _provider();
private get _providerStatus();
private get _logger();

@@ -288,9 +295,5 @@ }

/**
* EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
* The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
*
* Sets a transaction context propagator on this receiver. The transaction context
* propagator is responsible for persisting context for the duration of a single
* transaction.
* @experimental
* @template T The type of the receiver

@@ -304,8 +307,4 @@ * @param {TransactionContextPropagator} transactionContextPropagator The context propagator to be used

/**
* EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
* The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
*
* Returns the currently defined transaction context using the registered transaction
* context propagator.
* @experimental
* @returns {TransactionContext} The current transaction context

@@ -315,13 +314,30 @@ */

/**
* EXPERIMENTAL: Transaction context propagation is experimental and subject to change.
* The OpenFeature Enhancement Proposal regarding transaction context can be found [here](https://github.com/open-feature/ofep/pull/32).
* Sets the transaction context using the registered transaction context propagator.
* Runs the {@link callback} function, in which the {@link transactionContext} will be available by calling
* {@link this#getTransactionContext}.
*
* Sets the transaction context using the registered transaction context propagator.
* @experimental
* The {@link TransactionContextPropagator} must persist the {@link transactionContext} and make it available
* to {@link callback} via {@link this#getTransactionContext}.
*
* The precedence of merging context can be seen in {@link https://openfeature.dev/specification/sections/evaluation-context#requirement-323 the specification}.
*
* Example:
*
* ```js
* app.use((req: Request, res: Response, next: NextFunction) => {
* const ip = res.headers.get("X-Forwarded-For")
* OpenFeature.setTransactionContext({ targetingKey: req.user.id, ipAddress: ip }, () => {
* // The transaction context is used in any flag evaluation throughout the whole call chain of next
* next();
* });
* })
*
* ```
* @template TArgs The optional args passed to the callback function
* @template R The return value of the callback
* @param {TransactionContext} transactionContext The transaction specific context
* @param {(...args: unknown[]) => R} callback Callback function used to set the transaction context on the stack
* @param {(...args: unknown[]) => R} callback Callback function to run
* @param {...unknown[]} args Optional arguments that are passed to the callback function
*/
setTransactionContext<R>(transactionContext: TransactionContext, callback: (...args: unknown[]) => R, ...args: unknown[]): void;
setTransactionContext<TArgs extends unknown[], R>(transactionContext: TransactionContext, callback: (...args: TArgs) => R, ...args: TArgs): void;
}

@@ -331,9 +347,17 @@

getTransactionContext(): EvaluationContext;
setTransactionContext(_: EvaluationContext, callback: () => void): void;
setTransactionContext<TArgs extends unknown[], R>(_: TransactionContext, callback: (...args: TArgs) => R, ...args: TArgs): void;
}
declare const NOOP_TRANSACTION_CONTEXT_PROPAGATOR: NoopTransactionContextPropagator;
declare class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider, Hook> implements ManageContext<OpenFeatureAPI>, ManageTransactionContextPropagator<OpenFeatureCommonAPI<Provider>> {
protected _events: OpenFeatureEventEmitter;
protected _defaultProvider: Provider;
declare class AsyncLocalStorageTransactionContextPropagator implements TransactionContextPropagator {
private asyncLocalStorage;
getTransactionContext(): EvaluationContext;
setTransactionContext<TArgs extends unknown[], R>(transactionContext: TransactionContext, callback: (...args: TArgs) => R, ...args: TArgs): void;
}
declare class OpenFeatureAPI extends OpenFeatureCommonAPI<ServerProviderStatus, Provider, Hook> implements ManageContext<OpenFeatureAPI>, ManageTransactionContextPropagator<OpenFeatureCommonAPI<ServerProviderStatus, Provider>> {
protected _statusEnumType: typeof ServerProviderStatus;
protected _apiEmitter: OpenFeatureEventEmitter;
protected _defaultProvider: ProviderWrapper<Provider, ServerProviderStatus>;
protected _domainScopedProviders: Map<string, ProviderWrapper<Provider, ServerProviderStatus>>;
protected _createEventEmitter: () => OpenFeatureEventEmitter;

@@ -348,2 +372,3 @@ private _transactionContextPropagator;

static getInstance(): OpenFeatureAPI;
private getProviderStatus;
setContext(context: EvaluationContext): this;

@@ -391,4 +416,4 @@ getContext(): EvaluationContext;

clearProviders(): Promise<void>;
setTransactionContextPropagator(transactionContextPropagator: TransactionContextPropagator): OpenFeatureCommonAPI<Provider>;
setTransactionContext<R>(transactionContext: TransactionContext, callback: (...args: unknown[]) => R, ...args: unknown[]): void;
setTransactionContextPropagator(transactionContextPropagator: TransactionContextPropagator): OpenFeatureCommonAPI<ServerProviderStatus, Provider>;
setTransactionContext<TArgs extends unknown[], R>(transactionContext: TransactionContext, callback: (...args: TArgs) => R, ...args: TArgs): void;
getTransactionContext(): TransactionContext;

@@ -402,2 +427,2 @@ }

export { Client, Features, FlagEvaluationOptions, Hook, InMemoryProvider, ManageTransactionContextPropagator, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureEventEmitter, Provider, TransactionContext, TransactionContextPropagator };
export { AsyncLocalStorageTransactionContextPropagator, Client, Features, FlagEvaluationOptions, Hook, InMemoryProvider, ManageTransactionContextPropagator, NOOP_PROVIDER, NOOP_TRANSACTION_CONTEXT_PROPAGATOR, OpenFeature, OpenFeatureAPI, OpenFeatureClient, OpenFeatureEventEmitter, Provider, TransactionContext, TransactionContextPropagator };
{
"name": "@openfeature/server-sdk",
"version": "1.12.0",
"version": "1.13.0",
"description": "OpenFeature SDK for JavaScript",

@@ -51,7 +51,7 @@ "main": "./dist/cjs/index.js",

"peerDependencies": {
"@openfeature/core": "0.0.26"
"@openfeature/core": "0.0.27"
},
"devDependencies": {
"@openfeature/core": "0.0.26"
"@openfeature/core": "0.0.27"
}
}

@@ -19,4 +19,4 @@ <!-- markdownlint-disable MD033 -->

<!-- x-release-please-start-version -->
<a href="https://github.com/open-feature/js-sdk/releases/tag/server-sdk-v1.12.0">
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.12.0&color=blue&style=for-the-badge" />
<a href="https://github.com/open-feature/js-sdk/releases/tag/server-sdk-v1.13.0">
<img alt="Release" src="https://img.shields.io/static/v1?label=release&message=v1.13.0&color=blue&style=for-the-badge" />
</a>

@@ -90,12 +90,13 @@ <!-- x-release-please-end -->

| Status | Features | Description |
| ------ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
| ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
| ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
| ✅ | [Logging](#logging) | Integrate with popular logging packages. |
| ✅ | [Domains](#domains) | Logically bind clients with providers. |
| ✅ | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
| ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
| ✅ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |
| Status | Features | Description |
|--------|---------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| ✅ | [Providers](#providers) | Integrate with a commercial, open source, or in-house feature management tool. |
| ✅ | [Targeting](#targeting) | Contextually-aware flag evaluation using [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context). |
| ✅ | [Hooks](#hooks) | Add functionality to various stages of the flag evaluation life-cycle. |
| ✅ | [Logging](#logging) | Integrate with popular logging packages. |
| ✅ | [Domains](#domains) | Logically bind clients with providers. |
| ✅ | [Eventing](#eventing) | React to state changes in the provider or flag management system. |
| ✅ | [Shutdown](#shutdown) | Gracefully clean up a provider during application shutdown. |
| ✅ | [Transaction Context Propagation](#transaction-context-propagation) | Set a specific [evaluation context](https://openfeature.dev/docs/reference/concepts/evaluation-context) for a transaction (e.g. an HTTP request or a thread) | |
| ✅ | [Extending](#extending) | Extend OpenFeature with custom providers and hooks. |

@@ -118,3 +119,3 @@ <sub>Implemented: ✅ | In-progress: ⚠️ | Not implemented yet: ❌</sub>

await OpenFeature.setProviderAndWait(new MyProvider());
```
```

@@ -192,3 +193,3 @@ #### Synchronous

// Sets a global logger
// Sets a global logger
OpenFeature.setLogger(logger);

@@ -258,2 +259,28 @@

### Transaction Context Propagation
Transaction context is a container for transaction-specific evaluation context (e.g. user id, user agent, IP).
Transaction context can be set where specific data is available (e.g. an auth service or request handler) and by using the transaction context propagator it will automatically be applied to all flag evaluations within a transaction (e.g. a request or thread).
The following example shows an Express middleware using transaction context propagation to propagate the request ip and user id into request scoped transaction context.
```ts
import express, { Request, Response, NextFunction } from "express";
import { OpenFeature, AsyncLocalStorageTransactionContextPropagator } from '@openfeature/server-sdk';
OpenFeature.setTransactionContextPropagator(new AsyncLocalStorageTransactionContextPropagator())
/**
* This example is based on an express middleware.
*/
const app = express();
app.use((req: Request, res: Response, next: NextFunction) => {
const ip = res.headers.get("X-Forwarded-For")
OpenFeature.setTransactionContext({ targetingKey: req.user.id, ipAddress: ip }, () => {
// The transaction context is used in any flag evaluation throughout the whole call chain of next
next();
});
})
```
### Shutdown

@@ -287,3 +314,2 @@

ProviderEventEmitter,
ProviderStatus,
ResolutionDetails

@@ -314,6 +340,4 @@ } from '@openfeature/server-sdk';

status?: ProviderStatus | undefined;
// implement with "new OpenFeatureEventEmitter()", and use "emit()" to emit events
events?: ProviderEventEmitter<AnyProviderEvent> | undefined;
events?: ProviderEventEmitter<AnyProviderEvent> | undefined;

@@ -320,0 +344,0 @@ initialize?(context?: EvaluationContext | undefined): Promise<void> {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc