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
1 change: 1 addition & 0 deletions packages/flagging/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
3 changes: 2 additions & 1 deletion packages/flagging/src/openfeature/provider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ describe('DatadogProvider', () => {
addAction: jasmine.createSpy('addAction'),
}
provider = new DatadogProvider({
applicationId: 'xxx',
clientToken: 'xxx',
applicationId: 'xxx',
env: 'test',
site: 'http://localhost:8000',
rum: {
sdk: mockDatadogRum,
Expand Down
60 changes: 51 additions & 9 deletions packages/flagging/src/openfeature/provider.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {
Provider,
EvaluationContext,
JsonValue,
Logger,
Paradigm,
Provider,
ProviderMetadata,
ResolutionDetails,
HookContext,
Expand All @@ -20,14 +20,20 @@ import type { DDRum } from './rumIntegration'

export type DatadogProviderOptions = {
/**
* The RUM application ID.
* The application key for Datadog. Required for initializing the Datadog Flagging 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 Flagging client.
*/
clientToken: string

/**
* The application environment.
*/
env: string

/**
* The site to use for the Datadog API.
*/
Expand All @@ -52,6 +58,15 @@ export type DatadogProviderOptions = {
*/
ddExposureLogging?: boolean
}
/**
* Custom headers to add to the request to the Datadog API.
*/
customHeaders?: Record<string, string>

/**
* Whether to overwrite the default request headers.
*/
overwriteRequestHeaders?: boolean
}

// We need to use a class here to properly implement the OpenFeature Provider interface
Expand Down Expand Up @@ -164,18 +179,45 @@ export class DatadogProvider implements Provider {
async function fetchConfiguration(options: DatadogProviderOptions, context: EvaluationContext): Promise<Configuration> {
const baseUrl = options.site || 'https://dd.datad0g.com'

const parameters = [`application_id=${options.applicationId}`, `client_token=${options.clientToken}`]
// Stringify all context values
const stringifiedContext: Record<string, string> = {}
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?${parameters.join('&')}`, {
const response = await fetch(`${baseUrl}/api/unstable/precompute-assignments`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'DD-API-KEY': options.clientToken,
'Content-Type': 'application/vnd.api+json',
...(!options.overwriteRequestHeaders
? {
'dd-client-token': options.clientToken,
'dd-application-id': options.applicationId,
}
: {}),
...options.customHeaders,
},
body: JSON.stringify({
context,
data: {
type: 'precompute-assignments-request',
attributes: {
env: {
name: options.env,
},
subject: {
targeting_key: context.targetingKey || '',
targeting_attributes: stringifiedContext,
},
},
},
}),
})
const precomputed = await response.json()
return { precomputed }
return {
precomputed: {
response: precomputed,
context,
fetchedAt: dateNow(),
},
}
}