feat: expose js sdk identity without proxy wrappers#1377
feat: expose js sdk identity without proxy wrappers#1377jonathannorris wants to merge 10 commits intomainfrom
Conversation
Carry framework metadata on SDK-owned clients so client metadata and hook contexts expose js sdk identity without relying on Proxy wrappers in the framework packages. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
There was a problem hiding this comment.
Code Review
This pull request introduces framework and SDK metadata to OpenFeature clients across Angular, Nest, and React. It adds a setFrameworkMetadata utility and updates the core OpenFeatureClient to include 'sdk' and 'framework' fields in its metadata. Review feedback recommends removing the manual client caching in the Angular FeatureFlagService to avoid potential stale references and simplify the code by relying on the SDK's internal client registry.
packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts
Outdated
Show resolved
Hide resolved
packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts
Outdated
Show resolved
Hide resolved
Use the current OpenFeature client for each Angular evaluation so framework metadata stays aligned with SDK lifecycle changes and test teardown. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
There was a problem hiding this comment.
Pull request overview
This PR enhances JS SDK client identification by extending ClientMetadata with sdk and framework, setting sdk in base web/server clients, and enabling React/Angular/Nest wrappers to mark framework identity on the underlying SDK-owned client instances (so client.metadata and hook clientMetadata stay aligned without proxy wrappers).
Changes:
- Extend core
ClientMetadatawithsdk(web/server) andframework(react/angular/nest) and add an internal helper to apply framework metadata when supported. - Populate
metadata.sdkin the web and serverOpenFeatureClientimplementations; allow framework wrappers to setmetadata.framework. - Update React/Angular/Nest integrations and tests to ensure framework metadata is visible on
client.metadataand in hook contexts; Angular additionally caches framework-aware clients by domain.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/client/client.ts | Adds sdk/framework fields to ClientMetadata and introduces MetadataClient / internal FrameworkMetadataClient typing. |
| packages/shared/src/client/framework-metadata.ts | Adds internal setFrameworkMetadata helper (duck-typed call into supported clients). |
| packages/shared/src/client/index.ts | Re-exports the new internal helper module. |
| packages/web/src/client/internal/open-feature-client.ts | Sets metadata.sdk = 'web' and supports updating framework via setFrameworkMetadata. |
| packages/web/src/client/client.ts | Refactors Client to extend MetadataClient (keeps metadata in the public surface). |
| packages/web/test/client.spec.ts | Adds coverage for metadata.sdk === 'web'. |
| packages/server/src/client/internal/open-feature-client.ts | Sets metadata.sdk = 'server' and supports updating framework via setFrameworkMetadata. |
| packages/server/src/client/client.ts | Refactors Client to extend MetadataClient. |
| packages/server/test/client.spec.ts | Adds coverage for metadata.sdk === 'server'. |
| packages/react/src/provider/provider.tsx | Applies 'react' framework metadata to the stable client used by the provider. |
| packages/react/test/provider.spec.tsx | Ensures react framework metadata appears on client.metadata and in hook contexts; clears hooks between tests. |
| packages/nest/src/open-feature.module.ts | Applies 'nest' framework metadata to injected clients created by module factories. |
| packages/nest/src/utils.ts | Applies 'nest' framework metadata to clients returned from getClientForEvaluation. |
| packages/nest/test/open-feature.module.spec.ts | Tests injected clients and hook contexts include framework: 'nest'. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts | Adds per-domain client caching and applies 'angular' framework metadata to created clients. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.service.spec.ts | Adds hook-context assertion for angular framework metadata; clears hooks in teardown. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.directive.ts | Applies 'angular' framework metadata to directive-owned client instance. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts
Outdated
Show resolved
Hide resolved
Expose version and framework metadata through new getClient overloads while keeping domain as the optional first argument. Remove shared framework metadata helpers and keep the remaining React client-marking logic local to the provider. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Inline the remaining Angular and Nest helper wrappers now that they only forward to framework-aware getClient overloads. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Keep the legacy server getClient(domain, version, context) form parsing its third-argument context while expanding overload coverage for the supported web and server getClient signatures. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Set client metadata sdk to js-web or js-server, add paradigm as client or server, and update framework-facing tests to validate the new metadata shape across the JS SDKs. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
There was a problem hiding this comment.
Pull request overview
This PR extends client metadata across the JS SDKs to expose SDK family/paradigm and framework identity, and wires that through client construction so providers/hooks can observe it (e.g., for telemetry).
Changes:
- Extend core
ClientMetadatawithsdk,paradigm, andframework, plusClientMetadataOptions. - Add
getClient(domain?, options)overloads (web/server) and propagate framework metadata into created clients. - Update React/Angular/Nest integrations and tests to ensure framework identity is visible via
client.metadataand hookclientMetadata.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/client/client.ts | Adds new metadata fields/types and ClientMetadataOptions/MetadataClient. |
| packages/web/src/open-feature.ts | Adds getClient overload supporting metadata options and passes framework into client creation. |
| packages/web/src/client/internal/open-feature-client.ts | Adds sdk/paradigm/framework to metadata and an internal setter for framework metadata. |
| packages/web/src/client/client.ts | Switches Client to extend MetadataClient (metadata accessor via shared interface). |
| packages/web/test/open-feature.spec.ts | Adds overload coverage tests for web getClient. |
| packages/web/test/client.spec.ts | Asserts sdk + paradigm exposed in metadata (web). |
| packages/server/src/open-feature.ts | Adds getClient overload supporting metadata options and updates argument parsing. |
| packages/server/src/client/internal/open-feature-client.ts | Adds sdk/paradigm/framework to metadata and an internal setter for framework metadata. |
| packages/server/src/client/client.ts | Switches Client to extend MetadataClient (metadata accessor via shared interface). |
| packages/server/test/open-feature.spec.ts | Adds overload coverage tests for server getClient (domain/context/version/options combinations). |
| packages/server/test/client.spec.ts | Asserts sdk + paradigm exposed in metadata (server). |
| packages/react/src/provider/provider.tsx | Ensures React provider-created (or provided) clients surface framework: 'react'. |
| packages/react/test/provider.spec.tsx | Adds expectations for React framework metadata and hook-context propagation. |
| packages/nest/src/open-feature.module.ts | Ensures injected Nest clients are created with framework: 'nest'. |
| packages/nest/src/utils.ts | Ensures evaluation clients are created with framework: 'nest'. |
| packages/nest/test/open-feature.module.spec.ts | Adds expectations for Nest framework metadata and hook-context propagation. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts | Creates clients with framework: 'angular' for evaluations. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.directive.ts | Creates clients with framework: 'angular' for directive evaluations. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.service.spec.ts | Adds hook-context assertion for Angular framework metadata propagation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Drop the unused server-side framework metadata mutator and clarify why the React provider casts before calling the internal client helper. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
Remove the public client metadata options overloads and restore the original getClient signatures. Framework SDKs now mark SDK-owned client instances locally so framework metadata still flows into client and hook metadata without a public API change. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces framework-specific metadata (Angular, Nest, and React) to OpenFeature clients by updating the core ClientMetadata interface and implementing a setFrameworkMetadata method in the web and server SDKs. While the implementation successfully surfaces SDK family, paradigm, and framework information in hook contexts, there is significant code duplication of internal utility types and helper functions within the Angular and Nest packages. It is recommended to consolidate these helpers into shared utility files within their respective packages to adhere to DRY principles and improve maintainability.
packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts
Outdated
Show resolved
Hide resolved
Move Angular and Nest framework-marking casts into package-local helpers, clarify the server internal mutator comment, and inline the now-unneeded private client factory helpers in web and server. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
There was a problem hiding this comment.
Pull request overview
This PR extends the JS SDK client metadata model so providers/hooks can identify the SDK family (js-web/js-server), runtime paradigm (client/server), and (when applicable) the framework (react/angular/nest) without using proxy wrappers, while keeping the existing OpenFeature.getClient(...) public API unchanged.
Changes:
- Extend
ClientMetadatawithsdk,paradigm, andframework, and introduce aMetadataClientinterface for shared typing. - Populate
sdk/paradigmin the concrete web/server client implementations and add an internalsetFrameworkMetadatamutator used by framework SDKs. - Update React/Angular/Nest wrappers and add tests to ensure framework identity is surfaced via
client.metadataand hook contexts.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/shared/src/client/client.ts | Adds JS identity fields to ClientMetadata and introduces MetadataClient. |
| packages/web/src/client/internal/open-feature-client.ts | Populates web client metadata (sdk, paradigm, framework) and adds internal setFrameworkMetadata. |
| packages/web/src/client/client.ts | Switches the web Client interface to include metadata via MetadataClient. |
| packages/web/test/open-feature.spec.ts | Adds coverage for web getClient overload forms and expected metadata. |
| packages/web/test/client.spec.ts | Verifies web client exposes sdk and paradigm in metadata. |
| packages/server/src/client/internal/open-feature-client.ts | Populates server client metadata (sdk, paradigm, framework) and adds internal setFrameworkMetadata. |
| packages/server/src/client/client.ts | Switches the server Client interface to include metadata via MetadataClient. |
| packages/server/test/open-feature.spec.ts | Adds coverage for server getClient overload forms, context behavior, and expected metadata. |
| packages/server/test/client.spec.ts | Verifies server client exposes sdk and paradigm in metadata. |
| packages/react/src/provider/provider.tsx | Marks SDK-owned clients as React-backed via internal framework metadata setter without wrappers. |
| packages/react/test/provider.spec.tsx | Adds assertions that React metadata is present on clients and hook contexts; clears hooks between tests. |
| packages/nest/src/framework-metadata.ts | Adds helper to mark SDK-owned server clients as Nest-backed while preserving identity. |
| packages/nest/src/utils.ts | Ensures getClientForEvaluation returns a Nest-marked client. |
| packages/nest/src/open-feature.module.ts | Ensures injected clients are marked as Nest-backed. |
| packages/nest/test/open-feature.module.spec.ts | Adds tests for Nest framework metadata on injected clients and hook contexts. |
| packages/angular/projects/angular-sdk/src/lib/framework-metadata.ts | Adds helper to mark SDK-owned web clients as Angular-backed while preserving identity. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts | Marks the service’s client as Angular-backed for evaluations. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.directive.ts | Marks directive-created clients as Angular-backed. |
| packages/angular/projects/angular-sdk/src/lib/feature-flag.service.spec.ts | Adds test ensuring Angular metadata is present in hook contexts and clears hooks after tests. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
packages/angular/projects/angular-sdk/src/lib/feature-flag.service.ts
Outdated
Show resolved
Hide resolved
Restore Angular's previous empty-string domain behavior so unbound clients continue to resolve through the default OpenFeature client path. Signed-off-by: Jonathan Norris <jonathan.norris@dynatrace.com>
| * @returns {Client} the same client instance | ||
| */ | ||
| export function setAngularFrameworkMetadata(client: Client): Client { | ||
| (client as FrameworkMetadataClient).setFrameworkMetadata?.('angular'); |
There was a problem hiding this comment.
Not sure I'm particularly a fan of relying on type-casts to enable this
| const stableClient = React.useMemo(() => client || OpenFeature.getClient(domain), [client, domain]); | ||
| const stableClient = React.useMemo(() => { | ||
| if (client) { | ||
| return setReactFrameworkMetadata(client); |
There was a problem hiding this comment.
This mutates a user-provided client that might also be used elsewhere, this seems problematic?
Summary
ClientMetadatawith JS-specific identity fields:sdk,paradigm, andframeworksdk/paradigmin the basewebandserverclientsgetClient(...)API unchangedclient.metadataand hookclientMetadataexpose framework identity without aProxyMotivation
Relates to #1375.
Today providers and hooks can access
clientMetadata, but the JS SDKs do not expose enough identity to tell whether a call came fromjs-webvsjs-server, or fromreact,angular, ornest.This version avoids
Proxy, keeps the existing publicgetClient(...)signatures in place, and treats framework identity as internal framework-owned metadata rather than a new public client-construction API.Usage
Notes
getClient(...)signatures remain unchangedframeworkinternally on the SDK-owned client instances they useclientprop path preserves the provided client instance and marks it locally so metadata stays aligned with provider-created clientsRelated Issues