1
+ import { Headers , type Request , fetch } from "@cloudflare/workers-types" ;
2
+ import type { CoreAuthInput } from "src/core/types.js" ;
1
3
import type {
2
4
ClientUsageV2Event ,
3
5
UsageV2Event ,
4
6
UsageV2Source ,
5
7
} from "../core/usageV2.js" ;
8
+ import { extractAuthorizationData } from "./index.js" ;
6
9
7
10
type UsageV2Options = {
8
11
usageBaseUrl : string ;
9
12
source : UsageV2Source ;
10
- } & (
11
- | { serviceKey : string ; thirdwebClientId ?: never ; thirdwebSecretKey ?: never }
12
- | { serviceKey ?: never ; thirdwebClientId : string ; thirdwebSecretKey ?: never }
13
- | { serviceKey ?: never ; thirdwebClientId ?: never ; thirdwebSecretKey : string }
14
- ) ;
13
+ authInput : CoreAuthInput & { req : Request } ;
14
+ serviceKey ?: string ;
15
+ } ;
15
16
16
17
/**
17
18
* Send usageV2 events from either internal services or public clients.
18
19
*
19
- * Exactly one authentication method must be provided:
20
- * - serviceKey: for internal services
21
- * - thirdwebClientId: for public clients (MUST be the user's project)
22
- * - thirdwebSecretKey: for public clients (MUST be the user's project)
23
- *
24
- * NOTE: `team_id` is required if `serviceKey` is provided.
25
- *
26
20
* This method may throw. To call this non-blocking:
27
21
* ```ts
28
22
* void sendUsageV2Events(...).catch((e) => console.error(e))
@@ -34,19 +28,23 @@ export async function sendUsageV2Events<T extends UsageV2Options>(
34
28
: ClientUsageV2Event [ ] ,
35
29
options : T ,
36
30
) : Promise < void > {
31
+ const { usageBaseUrl, source, authInput, serviceKey } = options ;
32
+ const { clientId, secretKey } = await extractAuthorizationData ( authInput ) ;
33
+
34
+ // Forward headers from the origin request.
37
35
// Determine endpoint and auth header based on provided credentials.
38
36
let url : string ;
39
- const headers : HeadersInit = { "Content-Type" : "application/json" } ;
40
-
41
- if ( options . serviceKey ) {
42
- url = ` ${ options . usageBaseUrl } /usage-v2/ ${ options . source } ` ;
43
- headers [ "x-service-api-key" ] = options . serviceKey ;
44
- } else if ( options . thirdwebSecretKey ) {
45
- url = ` ${ options . usageBaseUrl } /usage-v2/ ${ options . source } /client` ;
46
- headers [ "x-secret-key" ] = options . thirdwebSecretKey ;
47
- } else if ( options . thirdwebClientId ) {
48
- url = ` ${ options . usageBaseUrl } /usage-v2/ ${ options . source } /client` ;
49
- headers [ "x-client-id" ] = options . thirdwebClientId ;
37
+ const headers = new Headers ( authInput . req . headers ) ;
38
+ headers . set ( "Content-Type" , "application/json" ) ;
39
+ if ( serviceKey ) {
40
+ // If a service key is provided, call the non-public usage endpoint.
41
+ url = ` ${ usageBaseUrl } /usage-v2/ ${ source } ` ;
42
+ headers . set ( "x-service-api-key" , serviceKey ) ;
43
+ } else if ( clientId ) {
44
+ url = ` ${ usageBaseUrl } /usage-v2/ ${ source } /client` ;
45
+ headers . set ( "x-client-id" , clientId ) ;
46
+ } else if ( secretKey ) {
47
+ url = ` ${ usageBaseUrl } /usage-v2/ ${ source } /client` ;
50
48
} else {
51
49
throw new Error ( "[UsageV2] No authentication method provided." ) ;
52
50
}
@@ -56,7 +54,6 @@ export async function sendUsageV2Events<T extends UsageV2Options>(
56
54
headers,
57
55
body : JSON . stringify ( { events } ) ,
58
56
} ) ;
59
-
60
57
if ( ! resp . ok ) {
61
58
throw new Error (
62
59
`[UsageV2] Unexpected response ${ resp . status } : ${ await resp . text ( ) } ` ,
0 commit comments