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

@openfeature/js-sdk

Package Overview
Dependencies
Maintainers
2
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@openfeature/js-sdk - npm Package Compare versions

Comparing version 1.1.0-experimental-9d746fab8c970534ef33d8da3fa80a5e44601b1e to 1.1.0

42

dist/cjs/index.js

@@ -60,3 +60,2 @@ "use strict";

__export(src_exports, {
ApiEvents: () => ApiEvents,
ErrorCode: () => ErrorCode,

@@ -69,3 +68,2 @@ FlagNotFoundError: () => FlagNotFoundError,

ParseError: () => ParseError,
ProviderEvents: () => ProviderEvents,
StandardResolutionReasons: () => StandardResolutionReasons,

@@ -77,5 +75,2 @@ TargetingKeyMissingError: () => TargetingKeyMissingError,

// src/open-feature.ts
var import_events = require("events");
// src/logger.ts

@@ -133,13 +128,2 @@ var LOG_LEVELS = ["error", "warn", "info", "debug"];

// src/types.ts
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
ProviderEvents2["Ready"] = "PROVIDER_READY";
ProviderEvents2["Error"] = "PROVIDER_ERROR";
ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
ProviderEvents2["Shutdown"] = "PROVIDER_SHUTDOWN";
return ProviderEvents2;
})(ProviderEvents || {});
var ApiEvents = /* @__PURE__ */ ((ApiEvents2) => {
ApiEvents2["ProviderChanged"] = "providerChanged";
return ApiEvents2;
})(ApiEvents || {});
var StandardResolutionReasons = {

@@ -151,2 +135,3 @@ TARGETING_MATCH: "TARGETING_MATCH",

UNKNOWN: "UNKNOWN",
STATIC: "STATIC",
CACHED: "CACHED",

@@ -172,3 +157,2 @@ ERROR: "ERROR"

this._hooks = [];
this._handlerWrappers = [];
this.metadata = {

@@ -179,11 +163,3 @@ name: options.name,

this._context = context;
this.attachListeners();
OpenFeatureAPI.getInstance().events.on("providerChanged" /* ProviderChanged */, () => this.attachListeners());
}
addHandler(eventType, handler) {
this._handlerWrappers.push({ eventType, handler });
if (eventType === "PROVIDER_READY" /* Ready */ && this.providerAccessor().ready) {
handler();
}
}
setLogger(logger) {

@@ -363,10 +339,2 @@ this._clientLogger = new SafeLogger(logger);

}
attachListeners() {
Object.values(ProviderEvents).forEach((e) => {
var _a;
return (_a = this.providerAccessor().events) == null ? void 0 : _a.on(e, () => {
this._handlerWrappers.filter((wrapper) => wrapper.eventType === e).forEach((wrapper) => wrapper.handler());
});
});
}
};

@@ -419,3 +387,2 @@

constructor() {
this.events = new import_events.EventEmitter();
this._provider = NOOP_PROVIDER;

@@ -463,6 +430,3 @@ this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;

setProvider(provider) {
if (this._provider !== provider) {
this.events.emit("providerChanged" /* ProviderChanged */);
this._provider = provider;
}
this._provider = provider;
return this;

@@ -574,3 +538,2 @@ }

0 && (module.exports = {
ApiEvents,
ErrorCode,

@@ -583,3 +546,2 @@ FlagNotFoundError,

ParseError,
ProviderEvents,
StandardResolutionReasons,

@@ -586,0 +548,0 @@ TargetingKeyMissingError,

@@ -41,5 +41,2 @@ var __defProp = Object.defineProperty;

// src/open-feature.ts
import { EventEmitter } from "events";
// src/logger.ts

@@ -97,13 +94,2 @@ var LOG_LEVELS = ["error", "warn", "info", "debug"];

// src/types.ts
var ProviderEvents = /* @__PURE__ */ ((ProviderEvents2) => {
ProviderEvents2["Ready"] = "PROVIDER_READY";
ProviderEvents2["Error"] = "PROVIDER_ERROR";
ProviderEvents2["ConfigurationChanged"] = "PROVIDER_CONFIGURATION_CHANGED";
ProviderEvents2["Shutdown"] = "PROVIDER_SHUTDOWN";
return ProviderEvents2;
})(ProviderEvents || {});
var ApiEvents = /* @__PURE__ */ ((ApiEvents2) => {
ApiEvents2["ProviderChanged"] = "providerChanged";
return ApiEvents2;
})(ApiEvents || {});
var StandardResolutionReasons = {

@@ -115,2 +101,3 @@ TARGETING_MATCH: "TARGETING_MATCH",

UNKNOWN: "UNKNOWN",
STATIC: "STATIC",
CACHED: "CACHED",

@@ -136,3 +123,2 @@ ERROR: "ERROR"

this._hooks = [];
this._handlerWrappers = [];
this.metadata = {

@@ -143,11 +129,3 @@ name: options.name,

this._context = context;
this.attachListeners();
OpenFeatureAPI.getInstance().events.on("providerChanged" /* ProviderChanged */, () => this.attachListeners());
}
addHandler(eventType, handler) {
this._handlerWrappers.push({ eventType, handler });
if (eventType === "PROVIDER_READY" /* Ready */ && this.providerAccessor().ready) {
handler();
}
}
setLogger(logger) {

@@ -327,10 +305,2 @@ this._clientLogger = new SafeLogger(logger);

}
attachListeners() {
Object.values(ProviderEvents).forEach((e) => {
var _a;
return (_a = this.providerAccessor().events) == null ? void 0 : _a.on(e, () => {
this._handlerWrappers.filter((wrapper) => wrapper.eventType === e).forEach((wrapper) => wrapper.handler());
});
});
}
};

@@ -383,3 +353,2 @@

constructor() {
this.events = new EventEmitter();
this._provider = NOOP_PROVIDER;

@@ -427,6 +396,3 @@ this._transactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;

setProvider(provider) {
if (this._provider !== provider) {
this.events.emit("providerChanged" /* ProviderChanged */);
this._provider = provider;
}
this._provider = provider;
return this;

@@ -537,3 +503,2 @@ }

export {
ApiEvents,
ErrorCode,

@@ -546,3 +511,2 @@ FlagNotFoundError,

ParseError,
ProviderEvents,
StandardResolutionReasons,

@@ -549,0 +513,0 @@ TargetingKeyMissingError,

9

dist/types/client.d.ts

@@ -1,3 +0,3 @@

import { Client, ClientMetadata, EvaluationContext, EvaluationDetails, EventProvider, FlagEvaluationOptions, FlagValue, Handler, Hook, JsonValue, Logger, Provider, ProviderEvents } from './types';
declare type OpenFeatureClientOptions = {
import { Client, ClientMetadata, EvaluationContext, EvaluationDetails, FlagEvaluationOptions, FlagValue, Hook, JsonValue, Logger, Provider } from './types';
type OpenFeatureClientOptions = {
name?: string;

@@ -13,5 +13,3 @@ version?: string;

private _clientLogger?;
private _handlerWrappers;
constructor(providerAccessor: () => Provider & Partial<EventProvider>, globalLogger: () => Logger, options: OpenFeatureClientOptions, context?: EvaluationContext);
addHandler(eventType: ProviderEvents, handler: Handler): void;
constructor(providerAccessor: () => Provider, globalLogger: () => Logger, options: OpenFeatureClientOptions, context?: EvaluationContext);
setLogger(logger: Logger): OpenFeatureClient;

@@ -38,4 +36,3 @@ setContext(context: EvaluationContext): OpenFeatureClient;

private get _logger();
private attachListeners;
}
export {};

@@ -1,6 +0,3 @@

/// <reference types="node" />
import { EventEmitter } from 'events';
import { Client, EvaluationContext, FlagValue, GlobalApi, Hook, Logger, Provider, ProviderMetadata, TransactionContext, TransactionContextPropagator } from './types';
export declare class OpenFeatureAPI implements GlobalApi {
events: EventEmitter;
private _provider;

@@ -7,0 +4,0 @@ private _transactionContextPropagator;

@@ -1,38 +0,14 @@

/// <reference types="node" />
import EventEmitter from 'events';
export declare type PrimitiveValue = null | boolean | string | number;
export interface EventProvider {
readonly events: EventEmitter;
readonly ready: boolean;
}
export declare enum ProviderEvents {
Ready = "PROVIDER_READY",
Error = "PROVIDER_ERROR",
ConfigurationChanged = "PROVIDER_CONFIGURATION_CHANGED",
Shutdown = "PROVIDER_SHUTDOWN"
}
export declare enum ApiEvents {
ProviderChanged = "providerChanged"
}
export interface Eventing {
addHandler(notificationType: string, handler: Handler): void;
}
export declare type EventContext = {
notificationType: string;
[key: string]: unknown;
};
export declare type Handler = (eventContext?: EventContext) => void;
export declare type EventCallbackMessage = (eventContext: EventContext) => void;
export declare type JsonObject = {
export type PrimitiveValue = null | boolean | string | number;
export type JsonObject = {
[key: string]: JsonValue;
};
export declare type JsonArray = JsonValue[];
export type JsonArray = JsonValue[];
/**
* Represents a JSON node value.
*/
export declare type JsonValue = PrimitiveValue | JsonObject | JsonArray;
export type JsonValue = PrimitiveValue | JsonObject | JsonArray;
/**
* Represents a JSON node value, or Date.
*/
export declare type EvaluationContextValue = PrimitiveValue | Date | {
export type EvaluationContextValue = PrimitiveValue | Date | {
[key: string]: EvaluationContextValue;

@@ -43,3 +19,3 @@ } | EvaluationContextValue[];

*/
export declare type EvaluationContext = {
export type EvaluationContext = {
/**

@@ -52,4 +28,4 @@ * A string uniquely identifying the subject (end-user, or client service) of a flag evaluation.

} & Record<string, EvaluationContextValue>;
export declare type FlagValue = boolean | string | number | JsonValue;
export declare type FlagValueType = 'boolean' | 'string' | 'number' | 'object';
export type FlagValue = boolean | string | number | JsonValue;
export type FlagValueType = 'boolean' | 'string' | 'number' | 'object';
export interface FlagEvaluationOptions {

@@ -213,4 +189,8 @@ hooks?: Hook[];

/**
* A cached value was resolved.
* The resolved value is static (no dynamic evaluation).
*/
readonly STATIC: "STATIC";
/**
* The resolved value was retrieved from cache.
*/
readonly CACHED: "CACHED";

@@ -254,4 +234,4 @@ /**

}
export declare type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>);
export declare type ResolutionDetails<U> = {
export type ResolutionReason = keyof typeof StandardResolutionReasons | (string & Record<never, never>);
export type ResolutionDetails<U> = {
value: U;

@@ -263,6 +243,6 @@ variant?: string;

};
export declare type EvaluationDetails<T extends FlagValue> = {
export type EvaluationDetails<T extends FlagValue> = {
flagKey: string;
} & ResolutionDetails<T>;
export interface Client extends EvaluationLifeCycle<Client>, Features, ManageContext<Client>, ManageLogger<Client>, Eventing {
export interface Client extends EvaluationLifeCycle<Client>, Features, ManageContext<Client>, ManageLogger<Client> {
readonly metadata: ClientMetadata;

@@ -349,3 +329,3 @@ }

}
export declare type HookHints = Readonly<Record<string, unknown>>;
export type HookHints = Readonly<Record<string, unknown>>;
interface Metadata {

@@ -411,3 +391,3 @@ }

*/
export declare type TransactionContext = EvaluationContext;
export type TransactionContext = EvaluationContext;
interface ManageTransactionContextPropagator<T> extends TransactionContextPropagator {

@@ -414,0 +394,0 @@ /**

{
"name": "@openfeature/js-sdk",
"version": "1.1.0-experimental-9d746fab8c970534ef33d8da3fa80a5e44601b1e",
"version": "1.1.0",
"description": "OpenFeature SDK for JavaScript",

@@ -41,2 +41,3 @@ "main": "./dist/cjs/index.js",

"exports": {
"types": "./dist/types/index.d.ts",
"import": "./dist/esm/index.js",

@@ -48,7 +49,7 @@ "require": "./dist/cjs/index.js",

"@openfeature/flagd-provider": "~0.7.0",
"@types/jest": "^28.1.4",
"@types/jest": "^29.0.0",
"@types/node": "^18.0.3",
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"esbuild": "^0.15.1",
"esbuild": "^0.16.0",
"eslint": "^8.14.0",

@@ -61,7 +62,7 @@ "eslint-config-prettier": "^8.5.0",

"eslint-plugin-jsdoc": "^39.3.6",
"jest": "^28.1.3",
"jest": "^29.0.0",
"jest-cucumber": "^3.0.1",
"jest-junit": "^14.0.0",
"jest-junit": "^15.0.0",
"prettier": "^2.6.2",
"ts-jest": "^28.0.8",
"ts-jest": "^29.0.0",
"ts-node": "^10.8.2",

@@ -68,0 +69,0 @@ "typedoc": "^0.23.16",

@@ -10,7 +10,17 @@ # OpenFeature SDK for JavaScript

This is the JavaScript implementation of [OpenFeature](https://openfeature.dev), a vendor-agnostic abstraction library for evaluating feature flags.
<p align="center">
<strong>
<a href="https://docs.openfeature.dev/docs/tutorials/getting-started/node">Getting Started<a/>
&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://open-feature.github.io/js-sdk">API Documentation<a/>
</strong>
</p>
---
This is the JavaScript implementation of [OpenFeature][openfeature-website], a vendor-agnostic abstraction library for evaluating feature flags.
We support multiple data types for flags (numbers, strings, booleans, objects) as well as hooks, which can alter the lifecycle of a flag evaluation.
**This library is intended to be used in server-side contexts and has only experimental support for web usage.**
> This library is intended to be used in server-side contexts and has only **experimental support** for web usage. Client-side support can be tracked [here][client-side-github-issue].

@@ -31,2 +41,4 @@ ## Installation

To configure the SDK you'll need to add a provider to the `OpenFeature` global signleton. From there, you can generate a `client` which is usable by your code. While you'll likely want a provider for your specific backend, we've provided a `NoopProvider`, which simply returns the default value.
```typescript

@@ -60,4 +72,44 @@ import { OpenFeature } from '@openfeature/js-sdk';

A list of available providers can be found [here][server-side-artifacts].
For complete documentation, visit: https://docs.openfeature.dev/docs/category/concepts
## Hooks
Implement your own hook by conforming to the [Hook interface][hook-interface].
All of the hook stages (before, after, error, and finally) are optional.
```typescript
import { OpenFeature, Hook, HookContext } from '@openfeature/js-sdk';
// Example hook that logs if an error occurs during flag evaluation
export class GlobalDebugHook implements Hook {
after(hookContext: HookContext, err: Error) {
console.log('hook context', hookContext);
console.error(err);
}
}
```
Register the hook at global, client, or invocation level.
```typescript
import { OpenFeature } from '@openfeature/js-sdk';
// This hook used is used for example purposes
import { GlobalDebugHook, ClientDebugHook, InvocationDebugHook } from './debug-hook';
// A global hook will run on every flag evaluation
OpenFeature.addHooks(new GlobalDebugHook());
const client = OpenFeature.getClient('my-app');
// A client hook will run on every flag evaluation executed by this client
client.addHooks(new ClientDebugHook());
// An invocation hook will only run on the registred flag evaluation method
const boolValue = await client.getBooleanValue('boolFlag', false, {}, { hooks: [new InvocationDebugHook()] });
```
A list of available hooks can be found [here][server-side-artifacts].
## Contributing

@@ -67,5 +119,5 @@

Our community meetings are held regularly and open to everyone. Check the [OpenFeature community calendar](https://calendar.google.com/calendar/u/0?cid=MHVhN2kxaGl2NWRoMThiMjd0b2FoNjM2NDRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ) for specific dates and for the Zoom meeting links.
Our community meetings are held regularly and open to everyone. Check the [OpenFeature community calendar](https://calendar.google.com/calendar/u/0?cid=MHVhN2kxaGl2NWRoMThiMjd0b2FoNjM2NDRAZ3JvdXAuY2FsZW5kYXIuZ29vZ2xlLmNvbQ) for specific dates and the Zoom meeting links.
Thanks so much to our contributors.
### Thanks to everyone that has already contributed

@@ -81,1 +133,6 @@ <a href="https://github.com/open-feature/js-sdk/graphs/contributors">

[Apache License 2.0](LICENSE)
[openfeature-website]: https://openfeature.dev
[server-side-artifacts]: https://docs.openfeature.dev/docs/reference/technologies/server/javascript
[hook-interface]: https://open-feature.github.io/js-sdk/interfaces/Hook.html
[client-side-github-issue]: https://github.com/open-feature/spec/issues/167

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