From d267c28d1a958f3b177a5da7fccfb8e3a3c3a356 Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Thu, 5 Jun 2025 14:39:06 -0700 Subject: [PATCH 1/6] temporarily add authorization via api key --- .../flagging/src/openfeature/provider.spec.ts | 3 ++ packages/flagging/src/openfeature/provider.ts | 28 ++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/flagging/src/openfeature/provider.spec.ts b/packages/flagging/src/openfeature/provider.spec.ts index 184b2126f3..53c2e70a8c 100644 --- a/packages/flagging/src/openfeature/provider.spec.ts +++ b/packages/flagging/src/openfeature/provider.spec.ts @@ -8,8 +8,11 @@ describe('DatadogProvider', () => { beforeEach(() => { provider = new DatadogProvider({ + apiKey: 'xxx', + applicationKey: 'xxx', applicationId: 'xxx', clientToken: 'xxx', + env: 'test', baseUrl: 'http://localhost:8000', }) mockLogger = { diff --git a/packages/flagging/src/openfeature/provider.ts b/packages/flagging/src/openfeature/provider.ts index e0fea6190b..45dafaeb18 100644 --- a/packages/flagging/src/openfeature/provider.ts +++ b/packages/flagging/src/openfeature/provider.ts @@ -1,9 +1,9 @@ import type { - Provider, EvaluationContext, JsonValue, Logger, Paradigm, + Provider, ProviderMetadata, ResolutionDetails, } from '@openfeature/web-sdk' @@ -15,14 +15,29 @@ import { evaluate } from '../evaluation' export type DatadogProviderOptions = { /** - * The RUM application ID. + * The API key for Datadog. Required for authenticating your application with Datadog. + */ + apiKey: string + /** + * The application key for Datadog. Required for authenticating your application with Datadog. + */ + applicationKey: string + + /** + * The application key for Datadog. Required for initializing the Datadog RUM client. */ applicationId: string + /** - * The client token for Datadog. Required for authenticating your application with Datadog. + * The client token for Datadog. Required for initializing the Datadog RUM client. */ clientToken: string + /** + * The environment for Datadog. + */ + env: string + baseUrl?: string initialConfiguration?: Configuration @@ -111,13 +126,12 @@ export class DatadogProvider implements Provider { async function fetchConfiguration(options: DatadogProviderOptions, context: EvaluationContext): Promise { const baseUrl = options.baseUrl || 'https://dd.datad0g.com' - const parameters = [`application_id=${options.applicationId}`, `client_token=${options.clientToken}`] - - const response = await fetch(`${baseUrl}/api/unstable/precompute-assignments?${parameters.join('&')}`, { + const response = await fetch(`${baseUrl}/api/unstable/precompute-assignments`, { method: 'POST', headers: { 'Content-Type': 'application/json', - 'DD-API-KEY': options.clientToken, + 'dd-api-key': options.apiKey, + 'dd-application-key': options.applicationKey, }, body: JSON.stringify({ context, From dddd3cc10f9430a900b43d84a2c0677edd375705 Mon Sep 17 00:00:00 2001 From: Leo Romanovsky Date: Thu, 5 Jun 2025 20:00:40 -0700 Subject: [PATCH 2/6] match api --- packages/flagging/src/openfeature/provider.ts | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/flagging/src/openfeature/provider.ts b/packages/flagging/src/openfeature/provider.ts index 45dafaeb18..f2f4653e64 100644 --- a/packages/flagging/src/openfeature/provider.ts +++ b/packages/flagging/src/openfeature/provider.ts @@ -129,12 +129,25 @@ async function fetchConfiguration(options: DatadogProviderOptions, context: Eval const response = await fetch(`${baseUrl}/api/unstable/precompute-assignments`, { method: 'POST', headers: { - 'Content-Type': 'application/json', + 'Content-Type': 'application/vnd.api+json', 'dd-api-key': options.apiKey, 'dd-application-key': options.applicationKey, }, body: JSON.stringify({ - context, + data: { + type: 'precompute-assignments-request', + attributes: { + env: { + name: options.env, + }, + subject: { + targeting_key: context.targetingKey || '', + targeting_attributes: { + ...context, + }, + }, + }, + }, }), }) const precomputed = await response.json() From 97682e6039f64817ecec543c0a66730bc2b203a3 Mon Sep 17 00:00:00 2001 From: Tyler Potter Date: Fri, 27 Jun 2025 23:33:47 -0600 Subject: [PATCH 3/6] gitignore --- packages/flagging/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/flagging/.gitignore diff --git a/packages/flagging/.gitignore b/packages/flagging/.gitignore new file mode 100644 index 0000000000..4c49bd78f1 --- /dev/null +++ b/packages/flagging/.gitignore @@ -0,0 +1 @@ +.env From ea451195ae578ab0c77ef16908dcc780b8b378f5 Mon Sep 17 00:00:00 2001 From: Tyler Potter Date: Fri, 27 Jun 2025 23:42:46 -0600 Subject: [PATCH 4/6] custom headers and fix response shape --- packages/flagging/src/openfeature/provider.ts | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/packages/flagging/src/openfeature/provider.ts b/packages/flagging/src/openfeature/provider.ts index 083c2e9614..ef22f627a6 100644 --- a/packages/flagging/src/openfeature/provider.ts +++ b/packages/flagging/src/openfeature/provider.ts @@ -19,15 +19,6 @@ import { evaluate } from '../evaluation' import type { DDRum } from './rumIntegration' export type DatadogProviderOptions = { - /** - * The API key for Datadog. Required for authenticating your application with Datadog. - */ - apiKey: string - /** - * The application key for Datadog. Required for authenticating your application with Datadog. - */ - applicationKey: string - /** * The application key for Datadog. Required for initializing the Datadog RUM client. */ @@ -43,7 +34,6 @@ export type DatadogProviderOptions = { */ env: string - /** * The site to use for the Datadog API. */ @@ -68,6 +58,15 @@ export type DatadogProviderOptions = { */ ddExposureLogging?: boolean } + /** + * Custom headers to add to the request to the Datadog API. + */ + customHeaders?: Record + + /** + * Whether to overwrite the default request headers. + */ + overwriteRequestHeaders?: boolean } // We need to use a class here to properly implement the OpenFeature Provider interface @@ -180,12 +179,22 @@ export class DatadogProvider implements Provider { async function fetchConfiguration(options: DatadogProviderOptions, context: EvaluationContext): Promise { const baseUrl = options.site || 'https://dd.datad0g.com' + // Stringify all context values + const stringifiedContext: Record = {} + for (const [key, value] of Object.entries(context)) { + stringifiedContext[key] = typeof value === 'string' ? value : JSON.stringify(value) + } + const response = await fetch(`${baseUrl}/api/unstable/precompute-assignments`, { method: 'POST', headers: { 'Content-Type': 'application/vnd.api+json', - 'dd-api-key': options.apiKey, - 'dd-application-key': options.applicationKey, + ...(!options.overwriteRequestHeaders ? + { + 'dd-client-token': options.clientToken, + 'dd-application-id': options.applicationId + } : {}), + ...options.customHeaders, }, body: JSON.stringify({ data: { @@ -196,14 +205,18 @@ async function fetchConfiguration(options: DatadogProviderOptions, context: Eval }, subject: { targeting_key: context.targetingKey || '', - targeting_attributes: { - ...context, - }, + targeting_attributes: stringifiedContext, }, }, }, }), }) const precomputed = await response.json() - return { precomputed } + return { + precomputed: { + response: precomputed, + context, + fetchedAt: Date.now(), + }, + } } From beb2b5a9fa4cf4d1174c0195915c521860f0104b Mon Sep 17 00:00:00 2001 From: Tyler Potter Date: Fri, 27 Jun 2025 23:54:35 -0600 Subject: [PATCH 5/6] fixes --- packages/flagging/src/openfeature/provider.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/flagging/src/openfeature/provider.ts b/packages/flagging/src/openfeature/provider.ts index ef22f627a6..a0ad03105c 100644 --- a/packages/flagging/src/openfeature/provider.ts +++ b/packages/flagging/src/openfeature/provider.ts @@ -20,17 +20,17 @@ import type { DDRum } from './rumIntegration' export type DatadogProviderOptions = { /** - * The application key for Datadog. Required for initializing the Datadog RUM client. + * The application key for Datadog. Required for initializing the Datadog Flagging client. */ applicationId: string /** - * The client token for Datadog. Required for initializing the Datadog RUM client. + * The client token for Datadog. Required for initializing the Datadog Flagging client. */ clientToken: string /** - * The environment for Datadog. + * The application environment. */ env: string @@ -216,7 +216,7 @@ async function fetchConfiguration(options: DatadogProviderOptions, context: Eval precomputed: { response: precomputed, context, - fetchedAt: Date.now(), + fetchedAt: dateNow(), }, } } From 31f1d587a830440784ce77fe0be8f8e46fc57c3a Mon Sep 17 00:00:00 2001 From: Tyler Potter Date: Fri, 27 Jun 2025 23:58:29 -0600 Subject: [PATCH 6/6] missing fixes --- packages/flagging/src/openfeature/provider.spec.ts | 4 +--- packages/flagging/src/openfeature/provider.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/packages/flagging/src/openfeature/provider.spec.ts b/packages/flagging/src/openfeature/provider.spec.ts index e15ed34910..dacb53a7f8 100644 --- a/packages/flagging/src/openfeature/provider.spec.ts +++ b/packages/flagging/src/openfeature/provider.spec.ts @@ -15,10 +15,8 @@ describe('DatadogProvider', () => { addAction: jasmine.createSpy('addAction'), } provider = new DatadogProvider({ - apiKey: 'xxx', - applicationKey: 'xxx', - applicationId: 'xxx', clientToken: 'xxx', + applicationId: 'xxx', env: 'test', site: 'http://localhost:8000', rum: { diff --git a/packages/flagging/src/openfeature/provider.ts b/packages/flagging/src/openfeature/provider.ts index a0ad03105c..f338f1ba87 100644 --- a/packages/flagging/src/openfeature/provider.ts +++ b/packages/flagging/src/openfeature/provider.ts @@ -189,11 +189,12 @@ async function fetchConfiguration(options: DatadogProviderOptions, context: Eval method: 'POST', headers: { 'Content-Type': 'application/vnd.api+json', - ...(!options.overwriteRequestHeaders ? - { - 'dd-client-token': options.clientToken, - 'dd-application-id': options.applicationId - } : {}), + ...(!options.overwriteRequestHeaders + ? { + 'dd-client-token': options.clientToken, + 'dd-application-id': options.applicationId, + } + : {}), ...options.customHeaders, }, body: JSON.stringify({