11import type {
2- Provider ,
32 EvaluationContext ,
43 JsonValue ,
54 Logger ,
65 Paradigm ,
6+ Provider ,
77 ProviderMetadata ,
88 ResolutionDetails ,
99 HookContext ,
@@ -20,14 +20,20 @@ import type { DDRum } from './rumIntegration'
2020
2121export type DatadogProviderOptions = {
2222 /**
23- * The RUM application ID .
23+ * The application key for Datadog. Required for initializing the Datadog Flagging client .
2424 */
2525 applicationId : string
26+
2627 /**
27- * The client token for Datadog. Required for authenticating your application with Datadog .
28+ * The client token for Datadog. Required for initializing the Datadog Flagging client .
2829 */
2930 clientToken : string
3031
32+ /**
33+ * The application environment.
34+ */
35+ env : string
36+
3137 /**
3238 * The site to use for the Datadog API.
3339 */
@@ -52,6 +58,15 @@ export type DatadogProviderOptions = {
5258 */
5359 ddExposureLogging ?: boolean
5460 }
61+ /**
62+ * Custom headers to add to the request to the Datadog API.
63+ */
64+ customHeaders ?: Record < string , string >
65+
66+ /**
67+ * Whether to overwrite the default request headers.
68+ */
69+ overwriteRequestHeaders ?: boolean
5570}
5671
5772// We need to use a class here to properly implement the OpenFeature Provider interface
@@ -164,18 +179,45 @@ export class DatadogProvider implements Provider {
164179async function fetchConfiguration ( options : DatadogProviderOptions , context : EvaluationContext ) : Promise < Configuration > {
165180 const baseUrl = options . site || 'https://dd.datad0g.com'
166181
167- const parameters = [ `application_id=${ options . applicationId } ` , `client_token=${ options . clientToken } ` ]
182+ // Stringify all context values
183+ const stringifiedContext : Record < string , string > = { }
184+ for ( const [ key , value ] of Object . entries ( context ) ) {
185+ stringifiedContext [ key ] = typeof value === 'string' ? value : JSON . stringify ( value )
186+ }
168187
169- const response = await fetch ( `${ baseUrl } /api/unstable/precompute-assignments? ${ parameters . join ( '&' ) } ` , {
188+ const response = await fetch ( `${ baseUrl } /api/unstable/precompute-assignments` , {
170189 method : 'POST' ,
171190 headers : {
172- 'Content-Type' : 'application/json' ,
173- 'DD-API-KEY' : options . clientToken ,
191+ 'Content-Type' : 'application/vnd.api+json' ,
192+ ...( ! options . overwriteRequestHeaders
193+ ? {
194+ 'dd-client-token' : options . clientToken ,
195+ 'dd-application-id' : options . applicationId ,
196+ }
197+ : { } ) ,
198+ ...options . customHeaders ,
174199 } ,
175200 body : JSON . stringify ( {
176- context,
201+ data : {
202+ type : 'precompute-assignments-request' ,
203+ attributes : {
204+ env : {
205+ name : options . env ,
206+ } ,
207+ subject : {
208+ targeting_key : context . targetingKey || '' ,
209+ targeting_attributes : stringifiedContext ,
210+ } ,
211+ } ,
212+ } ,
177213 } ) ,
178214 } )
179215 const precomputed = await response . json ( )
180- return { precomputed }
216+ return {
217+ precomputed : {
218+ response : precomputed ,
219+ context,
220+ fetchedAt : dateNow ( ) ,
221+ } ,
222+ }
181223}
0 commit comments