-
Notifications
You must be signed in to change notification settings - Fork 4
feat!: Update dependencies and encapsulate client construction. #35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,11 +20,11 @@ | |
| ], | ||
| "license": "Apache-2.0", | ||
| "peerDependencies": { | ||
| "@openfeature/js-sdk": "^1.0.0", | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The OpenFeature SDK was renamed to make it clear that their is a client and server version. |
||
| "@launchdarkly/node-server-sdk": "8.x" | ||
| "@openfeature/server-sdk": "^1.6.3", | ||
| "@launchdarkly/node-server-sdk": "9.x" | ||
| }, | ||
| "devDependencies": { | ||
| "@openfeature/js-sdk": "^1.0.0", | ||
| "@openfeature/server-sdk": "^1.6.3", | ||
| "@types/jest": "^27.4.1", | ||
| "@typescript-eslint/eslint-plugin": "^5.22.0", | ||
| "@typescript-eslint/parser": "^5.22.0", | ||
|
|
@@ -34,7 +34,7 @@ | |
| "eslint-plugin-import": "^2.26.0", | ||
| "jest": "^27.5.1", | ||
| "jest-junit": "^14.0.1", | ||
| "@launchdarkly/node-server-sdk": "8.x", | ||
| "@launchdarkly/node-server-sdk": "9.x", | ||
| "ts-jest": "^27.1.4", | ||
| "typescript": "^4.7.4" | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,14 +2,20 @@ import { | |
| ErrorCode, | ||
| EvaluationContext, FlagValue, Hook, | ||
| JsonValue, | ||
| Provider, ProviderMetadata, ResolutionDetails, StandardResolutionReasons, | ||
| } from '@openfeature/js-sdk'; | ||
| OpenFeatureEventEmitter, | ||
| Provider, | ||
| ProviderEvents, | ||
| ProviderMetadata, | ||
| ProviderStatus, | ||
| ResolutionDetails, | ||
| StandardResolutionReasons, | ||
| } from '@openfeature/server-sdk'; | ||
| import { | ||
| basicLogger, LDClient, LDLogger, | ||
| basicLogger, init, LDClient, LDLogger, LDOptions, | ||
| } from '@launchdarkly/node-server-sdk'; | ||
| import { LaunchDarklyProviderOptions } from './LaunchDarklyProviderOptions'; | ||
| import translateContext from './translateContext'; | ||
| import translateResult from './translateResult'; | ||
| import SafeLogger from './SafeLogger'; | ||
|
|
||
| /** | ||
| * Create a ResolutionDetails for an evaluation that produced a type different | ||
|
|
@@ -31,20 +37,67 @@ function wrongTypeResult<T>(value: T): ResolutionDetails<T> { | |
| export default class LaunchDarklyProvider implements Provider { | ||
| private readonly logger: LDLogger; | ||
|
|
||
| private readonly client: LDClient; | ||
|
|
||
| private readonly clientConstructionError: any; | ||
|
|
||
| readonly metadata: ProviderMetadata = { | ||
| name: 'launchdarkly-node-provider', | ||
| }; | ||
|
|
||
| private innerStatus: ProviderStatus = ProviderStatus.NOT_READY; | ||
|
|
||
| public readonly events = new OpenFeatureEventEmitter(); | ||
|
|
||
| /** | ||
| * Get the status of the LaunchDarkly provider. | ||
| */ | ||
| public get status() { | ||
| return this.innerStatus; | ||
| } | ||
|
|
||
| /** | ||
| * Construct a {@link LaunchDarklyProvider}. | ||
| * @param client The LaunchDarkly client instance to use. | ||
| */ | ||
| constructor(private readonly client: LDClient, options: LaunchDarklyProviderOptions = {}) { | ||
| constructor(sdkKey: string, options: LDOptions = {}) { | ||
| if (options.logger) { | ||
| this.logger = options.logger; | ||
| this.logger = new SafeLogger(options.logger, basicLogger({ level: 'info' })); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a fix, it should have had this already. |
||
| } else { | ||
| this.logger = basicLogger({ level: 'info' }); | ||
| } | ||
| try { | ||
| this.client = init(sdkKey, { | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are a few cases where the constructor fails. I am capturing it and letting the OF SDK handle it. That seems most in the spirit of the functionality. Maybe a little less convenient though. |
||
| ...options, | ||
| wrapperName: 'open-feature/node-server', | ||
| // The wrapper version should be kept on its own line to allow easy updates using | ||
| // release-please. | ||
| wrapperVersion: '0.4.0', // x-release-please-version | ||
| }); | ||
| this.client.on('update', ({ key }: { key: string }) => this.events.emit(ProviderEvents.ConfigurationChanged, { flagsChanged: [key] })); | ||
| } catch (e) { | ||
| this.clientConstructionError = e; | ||
| this.logger.error(`Encountered unrecoverable initialization error, ${e}`); | ||
| this.innerStatus = ProviderStatus.ERROR; | ||
| } | ||
| } | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
| async initialize(context?: EvaluationContext): Promise<void> { | ||
| if (!this.client) { | ||
| // The client could not be constructed. | ||
| if (this.clientConstructionError) { | ||
| throw this.clientConstructionError; | ||
| } | ||
| throw new Error('Unknown problem encountered during initialization'); | ||
| } | ||
| try { | ||
| await this.client.waitForInitialization(); | ||
| this.innerStatus = ProviderStatus.READY; | ||
| } catch (e) { | ||
| this.innerStatus = ProviderStatus.ERROR; | ||
| throw e; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -169,4 +222,22 @@ export default class LaunchDarklyProvider implements Provider { | |
| private translateContext(context: EvaluationContext) { | ||
| return translateContext(this.logger, context); | ||
| } | ||
|
|
||
| /** | ||
| * Get the LDClient instance used by this provider. | ||
| * | ||
| * @returns The client for this provider. | ||
| */ | ||
| public getClient(): LDClient { | ||
| return this.client; | ||
| } | ||
|
|
||
| /** | ||
| * Called by OpenFeature when it needs to close the provider. This will flush | ||
| * events from the LDClient and then close it. | ||
| */ | ||
| async onClose(): Promise<void> { | ||
| await this.client.flush(); | ||
| this.client.close(); | ||
| } | ||
| } | ||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OpenFeature SDK requires node 16.