@bucketco/openfeature-node-provider
Advanced tools
Comparing version
@@ -27,18 +27,13 @@ "use strict"; | ||
const defaultTranslator = (context) => { | ||
var _a, _b, _c, _d; | ||
const userId = (_a = context.targetingKey) !== null && _a !== void 0 ? _a : context["id"]; | ||
const user = userId | ||
? { | ||
id: String(userId), | ||
name: (_b = context["name"]) === null || _b === void 0 ? void 0 : _b.toString(), | ||
email: (_c = context["email"]) === null || _c === void 0 ? void 0 : _c.toString(), | ||
country: (_d = context["country"]) === null || _d === void 0 ? void 0 : _d.toString(), | ||
} | ||
: undefined; | ||
const company = context["companyId"] | ||
? { | ||
id: String(context["companyId"]), | ||
name: context["companyName"], | ||
} | ||
: undefined; | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
const user = { | ||
id: (_a = context.targetingKey) !== null && _a !== void 0 ? _a : (_b = context["id"]) === null || _b === void 0 ? void 0 : _b.toString(), | ||
name: (_c = context["name"]) === null || _c === void 0 ? void 0 : _c.toString(), | ||
email: (_d = context["email"]) === null || _d === void 0 ? void 0 : _d.toString(), | ||
country: (_e = context["country"]) === null || _e === void 0 ? void 0 : _e.toString(), | ||
}; | ||
const company = { | ||
id: (_f = context["companyId"]) === null || _f === void 0 ? void 0 : _f.toString(), | ||
name: (_g = context["companyName"]) === null || _g === void 0 ? void 0 : _g.toString(), | ||
}; | ||
return { | ||
@@ -64,2 +59,8 @@ user, | ||
} | ||
initialize() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this._client.initialize(); | ||
this.status = server_sdk_1.ServerProviderStatus.READY; | ||
}); | ||
} | ||
resolveBooleanEvaluation(flagKey, defaultValue, context) { | ||
@@ -108,6 +109,20 @@ const features = this._client.getFeatures(this.contextTranslator(context)); | ||
} | ||
initialize() { | ||
track(trackingEventName, context, trackingEventDetails) { | ||
var _a, _b, _c, _d; | ||
const translatedContext = context | ||
? this.contextTranslator(context) | ||
: undefined; | ||
const userId = (_a = translatedContext === null || translatedContext === void 0 ? void 0 : translatedContext.user) === null || _a === void 0 ? void 0 : _a.id; | ||
if (!userId) { | ||
(_b = this._client.logger) === null || _b === void 0 ? void 0 : _b.warn("No user ID provided for tracking event"); | ||
return; | ||
} | ||
void this._client.track(String(userId), trackingEventName, { | ||
attributes: trackingEventDetails, | ||
companyId: (_d = (_c = translatedContext === null || translatedContext === void 0 ? void 0 : translatedContext.company) === null || _c === void 0 ? void 0 : _c.id) === null || _d === void 0 ? void 0 : _d.toString(), | ||
}); | ||
} | ||
onClose() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield this._client.initialize(); | ||
this.status = server_sdk_1.ServerProviderStatus.READY; | ||
yield this._client.flush(); | ||
}); | ||
@@ -114,0 +129,0 @@ } |
@@ -23,2 +23,4 @@ "use strict"; | ||
initialize: vitest_1.vi.fn().mockResolvedValue({}), | ||
flush: vitest_1.vi.fn(), | ||
track: vitest_1.vi.fn(), | ||
}; | ||
@@ -35,2 +37,5 @@ const secretKey = "sec_fakeSecretKey______"; // must be 23 characters long | ||
}; | ||
(0, vitest_1.beforeEach)(() => { | ||
vitest_1.vi.clearAllMocks(); | ||
}); | ||
(0, vitest_1.describe)("BucketNodeProvider", () => { | ||
@@ -49,2 +54,6 @@ let provider; | ||
(0, vitest_1.it)("calls the constructor", () => { | ||
provider = new index_1.BucketNodeProvider({ | ||
secretKey, | ||
contextTranslator: translatorFn, | ||
}); | ||
(0, vitest_1.expect)(newBucketClient).toHaveBeenCalledTimes(1); | ||
@@ -105,3 +114,24 @@ (0, vitest_1.expect)(newBucketClient).toHaveBeenCalledWith({ secretKey }); | ||
}); | ||
(0, vitest_1.describe)("onClose", () => { | ||
(0, vitest_1.it)("calls flush", () => __awaiter(void 0, void 0, void 0, function* () { | ||
yield provider.onClose(); | ||
(0, vitest_1.expect)(bucketClientMock.flush).toHaveBeenCalledTimes(1); | ||
})); | ||
}); | ||
(0, vitest_1.describe)("track", () => { | ||
(0, vitest_1.it)("should track", () => __awaiter(void 0, void 0, void 0, function* () { | ||
(0, vitest_1.expect)(translatorFn).toHaveBeenCalledTimes(0); | ||
provider.track("event", context, { | ||
action: "click", | ||
}); | ||
(0, vitest_1.expect)(translatorFn).toHaveBeenCalledTimes(1); | ||
(0, vitest_1.expect)(translatorFn).toHaveBeenCalledWith(context); | ||
(0, vitest_1.expect)(bucketClientMock.track).toHaveBeenCalledTimes(1); | ||
(0, vitest_1.expect)(bucketClientMock.track).toHaveBeenCalledWith("42", "event", { | ||
attributes: { action: "click" }, | ||
companyId: bucketContext.company.id, | ||
}); | ||
})); | ||
}); | ||
}); | ||
//# sourceMappingURL=index.test.js.map |
@@ -1,2 +0,2 @@ | ||
import { EvaluationContext, JsonValue, OpenFeatureEventEmitter, Paradigm, Provider, ResolutionDetails, ServerProviderStatus } from "@openfeature/server-sdk"; | ||
import { EvaluationContext, JsonValue, OpenFeatureEventEmitter, Paradigm, Provider, ResolutionDetails, ServerProviderStatus, TrackingEventDetails } from "@openfeature/server-sdk"; | ||
import { BucketClient, ClientOptions, Context as BucketContext } from "@bucketco/node-sdk"; | ||
@@ -17,2 +17,3 @@ type ProviderOptions = ClientOptions & { | ||
constructor({ contextTranslator, ...opts }: ProviderOptions); | ||
initialize(): Promise<void>; | ||
resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext): Promise<ResolutionDetails<boolean>>; | ||
@@ -22,4 +23,5 @@ resolveStringEvaluation(_flagKey: string, defaultValue: string): Promise<ResolutionDetails<string>>; | ||
resolveObjectEvaluation<T extends JsonValue>(_flagKey: string, defaultValue: T): Promise<ResolutionDetails<T>>; | ||
initialize(): Promise<void>; | ||
track(trackingEventName: string, context?: EvaluationContext, trackingEventDetails?: TrackingEventDetails): void; | ||
onClose(): Promise<void>; | ||
} | ||
export {}; |
{ | ||
"name": "@bucketco/openfeature-node-provider", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"license": "MIT", | ||
@@ -34,4 +34,4 @@ "repository": { | ||
"@bucketco/tsconfig": "~0.0.2", | ||
"@openfeature/core": "^1.4.0", | ||
"@openfeature/server-sdk": ">=1.13.5", | ||
"@openfeature/core": "^1.5.0", | ||
"@openfeature/server-sdk": ">=1.16.1", | ||
"@types/node": "~20.14.9", | ||
@@ -48,8 +48,8 @@ "eslint": "~8.56.0", | ||
"dependencies": { | ||
"@bucketco/node-sdk": ">=1.0.0" | ||
"@bucketco/node-sdk": ">=1.4.2" | ||
}, | ||
"peerDependencies": { | ||
"@openfeature/server-sdk": ">=1.13.5" | ||
"@openfeature/server-sdk": ">=1.16.1" | ||
}, | ||
"gitHead": "79236ec1dce82ee6ae1ada4a6908eb8a236b1bd0" | ||
"gitHead": "ca07a2ca2f0bd732edf859dc991dd849a67df006" | ||
} |
# Bucket Node.js OpenFeature Provider | ||
This provider is an OpenFeature implementation for [Bucket](https://bucket.co) feature management service. | ||
The official OpenFeature Node.js provider for [Bucket](https://bucket.co) feature management service. | ||
@@ -32,7 +32,8 @@ ## Installation | ||
```javascript | ||
import { BucketNodeProvider } from "@openfeature/bucket-node-provider"; | ||
import { BucketNodeProvider } from "@bucketco/openfeature-node-provider"; | ||
import { OpenFeature } from "@openfeature/server-sdk"; | ||
const provider = new BucketNodeProvider({ secretKey }); | ||
OpenFeature.setProvider(provider); | ||
await OpenFeature.setProviderAndWait(provider); | ||
@@ -50,2 +51,4 @@ // set a value to the global context | ||
const client = OpenFeature.getClient(); | ||
const enterpriseFeatureEnabled = await client.getBooleanValue( | ||
@@ -110,8 +113,6 @@ "enterpriseFeature", | ||
## Building | ||
# License | ||
Run `nx package providers-bucket-node` to build the library. | ||
MIT License | ||
## Running unit tests | ||
Run `nx test providers-bucket-node` to execute the unit tests via [Jest](https://jestjs.io). | ||
Copyright (c) 2024 Bucket ApS |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
28209
17.55%286
19.67%116
0.87%Updated