Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 78 additions & 18 deletions packages/openfeature-node-provider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,23 @@ The official OpenFeature Node.js provider for [Bucket](https://bucket.co) featur

## Installation

```
$ npm install @bucketco/openfeature-node-provider
```shell
npm install @bucketco/openfeature-node-provider
```

#### Required peer dependencies
### Required peer dependencies

The OpenFeature SDK is required as peer dependency.

The minimum required version of `@openfeature/server-sdk` currently is `1.13.5`.

The minimum required version of `@bucketco/node-sdk` currently is `2.0.0`.

```
$ npm install @openfeature/server-sdk @bucketco/node-sdk
```shell
npm install @openfeature/server-sdk @bucketco/node-sdk
```

## Usage

The provider uses the [Bucket Node.js SDK](https://docs.bucket.co/quickstart/supported-languages-frameworks/node.js-sdk).

The available options can be found in the [Bucket Node.js SDK](https://github.com/bucketco/bucket-javascript-sdk/tree/main/packages/node-sdk#initialization-options).

### Example using the default configuration
Expand Down Expand Up @@ -56,6 +53,59 @@ const enterpriseFeatureEnabled = await client.getBooleanValue(
);
```

## Feature resolution methods

The Bucket OpenFeature Provider implements the OpenFeature evaluation interface for different value types. Each method handles the resolution of feature flags according to the OpenFeature specification.

### Common behavior

All resolution methods share these behaviors:

- Return default value with `PROVIDER_NOT_READY` if client is not initialized,
- Return default value with `FLAG_NOT_FOUND` if flag doesn't exist,
- Return default value with `ERROR` if there was a type mismatch,
- Return evaluated value with `TARGETING_MATCH` on successful resolution.

### Type-Specific Methods

#### Boolean Resolution

```ts
client.getBooleanValue("my-flag", false);
```

Returns the feature's enabled state. This is the most common use case for feature flags.

#### String Resolution

```ts
client.getStringValue("my-flag", "default");
```

Returns the feature's remote config key (also known as "variant"). Useful for multi-variate use cases.

#### Number Resolution

```ts
client.getNumberValue("my-flag", 0);
```

Not directly supported by Bucket. Use `getObjectValue` instead for numeric configurations.

#### Object Resolution

```ts
// works for any type:
client.getObjectValue("my-flag", { defaultValue: true });
client.getObjectValue("my-flag", "string-value");
client.getObjectValue("my-flag", 199);
```

Returns the feature's remote config payload with type validation. This is the most flexible method,
allowing for complex configuration objects or simple types.

The object resolution performs runtime type checking between the default value and the feature payload to ensure type safety.

## Translating Evaluation Context

Bucket uses a context object of the following shape:
Expand All @@ -69,11 +119,19 @@ export type BucketContext = {
/**
* The user context. If the user is set, the user ID is required.
*/
user?: { id: string; [k: string]: any };
user?: {
id: string;
name?: string;
email?: string;
avatar?: string;
[k: string]: any;
};

/**
* The company context. If the company is set, the company ID is required.
*/
company?: { id: string; [k: string]: any };
company?: { id: string; name?: string; avatar?: string; [k: string]: any };

/**
* The other context. This is used for any additional context that is not related to user or company.
*/
Expand All @@ -91,14 +149,17 @@ import { BucketNodeProvider } from "@openfeature/bucket-node-provider";
const contextTranslator = (context: EvaluationContext): BucketContext => {
return {
user: {
id: context.targetingKey,
id: context.targetingKey ?? context["userId"]?.toString(),
name: context["name"]?.toString(),
email: context["email"]?.toString(),
avatar: context["avatar"]?.toString(),
country: context["country"]?.toString(),
},
company: {
id: context["companyId"],
name: context["companyName"],
id: context["companyId"]?.toString(),
name: context["companyName"]?.toString(),
avatar: context["companyAvatar"]?.toString(),
plan: context["companyPlan"]?.toString(),
},
};
};
Expand All @@ -115,7 +176,7 @@ It's straight forward to start sending tracking events through OpenFeature.

Simply call the "track" method on the OpenFeature client:

```ts
```typescript
import { BucketNodeProvider } from "@bucketco/openfeature-node-provider";
import { OpenFeature } from "@openfeature/server-sdk";

Expand All @@ -132,8 +193,7 @@ const enterpriseFeatureEnabled = await client.track(
);
```

# License

MIT License
## License

Copyright (c) 2025 Bucket ApS
> MIT License
> Copyright (c) 2025 Bucket ApS
4 changes: 2 additions & 2 deletions packages/openfeature-node-provider/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@bucketco/openfeature-node-provider",
"version": "0.2.1",
"version": "0.3.0-alpha.0",
"license": "MIT",
"repository": {
"type": "git",
Expand Down Expand Up @@ -44,7 +44,7 @@
"vitest": "~1.6.0"
},
"dependencies": {
"@bucketco/node-sdk": ">=1.4.2"
"@bucketco/node-sdk": "1.6.0-alpha.3"
},
"peerDependencies": {
"@openfeature/server-sdk": ">=1.16.1"
Expand Down
Loading