@usagetap/sdk 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -1
- package/dist/adapters/openai.d.cts +1 -1
- package/dist/adapters/openai.d.ts +1 -1
- package/dist/adapters/openrouter.d.cts +1 -1
- package/dist/adapters/openrouter.d.ts +1 -1
- package/dist/{client-DAY6cR0C.d.cts → client-nU5xk2pN.d.cts} +16 -1
- package/dist/{client-DAY6cR0C.d.ts → client-nU5xk2pN.d.ts} +16 -1
- package/dist/express/index.d.cts +1 -1
- package/dist/express/index.d.ts +1 -1
- package/dist/index.cjs +39 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +39 -2
- package/dist/index.mjs.map +1 -1
- package/dist/openai/index.d.cts +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -405,8 +405,9 @@ const { begin, end, vendor, endUsage } = envelope.data;
|
|
|
405
405
|
|
|
406
406
|
Key exports from `@usagetap/sdk`:
|
|
407
407
|
|
|
408
|
-
- `UsageTapClient` – minimal HTTP client for `createCustomer`, `call_begin`, `call_end`, and `checkUsage`.
|
|
408
|
+
- `UsageTapClient` – minimal HTTP client for `createCustomer`, `changePlan`, `call_begin`, `call_end`, and `checkUsage`.
|
|
409
409
|
- `createCustomer` – idempotently ensure a customer subscription exists before starting a call.
|
|
410
|
+
- `changePlan` – switch a customer to a different usage plan with configurable strategy (immediate reset, prorated, or scheduled).
|
|
410
411
|
- `checkUsage` – lightweight method to query current usage status without creating a call session.
|
|
411
412
|
- `wrapFetch` – wraps a fetch function to automatically instrument OpenAI API calls (minimal integration).
|
|
412
413
|
- `createIdempotencyKey` – helper for generating UsageTap-compatible idempotency keys.
|
|
@@ -439,6 +440,28 @@ console.log("Allowed entitlements:", snapshot.data.allowed);
|
|
|
439
440
|
|
|
440
441
|
This returns the same rich subscription snapshot surfaces by `call_begin` and `checkUsage`, making it safe to cache the response for onboarding flows. Pass an `idempotencyKey` in `CreateCustomerOptions` when you need deterministic keys across services; otherwise the client auto-generates one by default.
|
|
441
442
|
|
|
443
|
+
### Change a customer's plan
|
|
444
|
+
|
|
445
|
+
Use `changePlan` to switch a customer to a different usage plan. You can control how the change is applied with the `strategy` option:
|
|
446
|
+
|
|
447
|
+
```ts
|
|
448
|
+
const result = await usageTap.changePlan({
|
|
449
|
+
customerId: "cust_123",
|
|
450
|
+
planId: "plan_premium_v2",
|
|
451
|
+
strategy: "IMMEDIATE_RESET", // or "IMMEDIATE_PRORATED" or "AT_NEXT_REPLENISH"
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
console.log("Plan changed:", result.data.success);
|
|
455
|
+
console.log("New subscription:", result.data.subscription);
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
**Strategy options:**
|
|
459
|
+
- `IMMEDIATE_RESET`: Switch plan immediately and reset all usage counters to zero
|
|
460
|
+
- `IMMEDIATE_PRORATED`: Switch plan immediately and prorate existing usage against new limits
|
|
461
|
+
- `AT_NEXT_REPLENISH`: Schedule the plan change for the next replenishment cycle (default)
|
|
462
|
+
|
|
463
|
+
The response includes the updated subscription details, including the new plan version, limits, and next replenishment timestamp. If `strategy: "AT_NEXT_REPLENISH"` is used, the `subscription.pending` field will indicate the scheduled plan change.
|
|
464
|
+
|
|
442
465
|
### Check usage without creating a call
|
|
443
466
|
|
|
444
467
|
When you need to display current quota status, plan details, or remaining balances without tracking a vendor call, use `checkUsage()`:
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { B as BeginCallRequest, U as UsageTapClient, W as WithUsageOptions, V as VendorHints, a as UsageTapSuccessResponse, b as BeginCallResponseBody, E as EndCallRequest } from '../client-
|
|
2
|
+
import { B as BeginCallRequest, U as UsageTapClient, W as WithUsageOptions, V as VendorHints, a as UsageTapSuccessResponse, b as BeginCallResponseBody, E as EndCallRequest } from '../client-nU5xk2pN.cjs';
|
|
3
3
|
|
|
4
4
|
interface OpenAIAdapterInit {
|
|
5
5
|
client: OpenAI;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
|
-
import { B as BeginCallRequest, U as UsageTapClient, W as WithUsageOptions, V as VendorHints, a as UsageTapSuccessResponse, b as BeginCallResponseBody, E as EndCallRequest } from '../client-
|
|
2
|
+
import { B as BeginCallRequest, U as UsageTapClient, W as WithUsageOptions, V as VendorHints, a as UsageTapSuccessResponse, b as BeginCallResponseBody, E as EndCallRequest } from '../client-nU5xk2pN.js';
|
|
3
3
|
|
|
4
4
|
interface OpenAIAdapterInit {
|
|
5
5
|
client: OpenAI;
|
|
@@ -269,6 +269,20 @@ interface CreateCustomerOptions extends RequestOptions {
|
|
|
269
269
|
interface CreateCustomerResponseBody extends CheckUsageResponseBody {
|
|
270
270
|
newCustomer: boolean;
|
|
271
271
|
}
|
|
272
|
+
type ChangePlanStrategy = "IMMEDIATE_RESET" | "IMMEDIATE_PRORATED" | "AT_NEXT_REPLENISH";
|
|
273
|
+
interface ChangePlanRequest {
|
|
274
|
+
customerId: string;
|
|
275
|
+
planId: string;
|
|
276
|
+
strategy?: ChangePlanStrategy;
|
|
277
|
+
}
|
|
278
|
+
interface ChangePlanOptions extends RequestOptions {
|
|
279
|
+
correlationId?: string;
|
|
280
|
+
idempotencyKey?: string;
|
|
281
|
+
}
|
|
282
|
+
interface ChangePlanResponseBody {
|
|
283
|
+
success: boolean;
|
|
284
|
+
subscription: SubscriptionSnapshot;
|
|
285
|
+
}
|
|
272
286
|
|
|
273
287
|
declare class UsageTapClient {
|
|
274
288
|
private readonly apiKey;
|
|
@@ -287,6 +301,7 @@ declare class UsageTapClient {
|
|
|
287
301
|
endCall(request: EndCallRequest, options?: EndCallOptions): Promise<UsageTapSuccessResponse<EndCallResponseBody>>;
|
|
288
302
|
checkUsage(request: CheckUsageRequest, options?: CheckUsageOptions): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>>;
|
|
289
303
|
createCustomer(request: CreateCustomerRequest, options?: CreateCustomerOptions): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>>;
|
|
304
|
+
changePlan(request: ChangePlanRequest, options?: ChangePlanOptions): Promise<UsageTapSuccessResponse<ChangePlanResponseBody>>;
|
|
290
305
|
withUsage<T>(beginRequest: BeginCallRequest, handler: (context: WithUsageContext) => Promise<T>, options?: WithUsageOptions): Promise<T>;
|
|
291
306
|
private request;
|
|
292
307
|
private requestGet;
|
|
@@ -299,4 +314,4 @@ declare class UsageTapClient {
|
|
|
299
314
|
private toApiError;
|
|
300
315
|
}
|
|
301
316
|
|
|
302
|
-
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type EndCallRequest as E, type IdempotencyMetadata as I, type LimitType as L, type MeterSummary as M, type PlanSummary as P, type RemainingRatios as R, type SubscriptionSnapshot as S, UsageTapClient as U, type VendorHints as V, type WithUsageOptions as W, type UsageTapSuccessResponse as a, type BeginCallResponseBody as b, type BeginCallOptions as c, type CreateCustomerRequest as d, type CreateCustomerResponseBody as e, type CheckUsageOptions as f, type CheckUsageRequest as g, type CheckUsageResponseBody as h, type
|
|
317
|
+
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type ModelHints as D, type EndCallRequest as E, type IdempotencyMetadata as I, type LimitType as L, type MeterSummary as M, type PlanSummary as P, type RemainingRatios as R, type SubscriptionSnapshot as S, UsageTapClient as U, type VendorHints as V, type WithUsageOptions as W, type UsageTapSuccessResponse as a, type BeginCallResponseBody as b, type BeginCallOptions as c, type CreateCustomerRequest as d, type CreateCustomerResponseBody as e, type CheckUsageOptions as f, type CheckUsageRequest as g, type CheckUsageResponseBody as h, type ChangePlanOptions as i, type ChangePlanRequest as j, type ChangePlanResponseBody as k, type ChangePlanStrategy as l, type EndCallOptions as m, type EndCallResponseBody as n, type BalanceSummary as o, type EntitlementHints as p, type MeterSnapshot as q, type MeteredUsage as r, type RequestedEntitlements as s, type RetryOptions as t, type UsageTapClientOptions as u, type UsageTapErrorResponse as v, type UsageTapResultEnvelope as w, type UsageTapResultStatus as x, type UsageTapLogEntry as y, type WithUsageContext as z };
|
|
@@ -269,6 +269,20 @@ interface CreateCustomerOptions extends RequestOptions {
|
|
|
269
269
|
interface CreateCustomerResponseBody extends CheckUsageResponseBody {
|
|
270
270
|
newCustomer: boolean;
|
|
271
271
|
}
|
|
272
|
+
type ChangePlanStrategy = "IMMEDIATE_RESET" | "IMMEDIATE_PRORATED" | "AT_NEXT_REPLENISH";
|
|
273
|
+
interface ChangePlanRequest {
|
|
274
|
+
customerId: string;
|
|
275
|
+
planId: string;
|
|
276
|
+
strategy?: ChangePlanStrategy;
|
|
277
|
+
}
|
|
278
|
+
interface ChangePlanOptions extends RequestOptions {
|
|
279
|
+
correlationId?: string;
|
|
280
|
+
idempotencyKey?: string;
|
|
281
|
+
}
|
|
282
|
+
interface ChangePlanResponseBody {
|
|
283
|
+
success: boolean;
|
|
284
|
+
subscription: SubscriptionSnapshot;
|
|
285
|
+
}
|
|
272
286
|
|
|
273
287
|
declare class UsageTapClient {
|
|
274
288
|
private readonly apiKey;
|
|
@@ -287,6 +301,7 @@ declare class UsageTapClient {
|
|
|
287
301
|
endCall(request: EndCallRequest, options?: EndCallOptions): Promise<UsageTapSuccessResponse<EndCallResponseBody>>;
|
|
288
302
|
checkUsage(request: CheckUsageRequest, options?: CheckUsageOptions): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>>;
|
|
289
303
|
createCustomer(request: CreateCustomerRequest, options?: CreateCustomerOptions): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>>;
|
|
304
|
+
changePlan(request: ChangePlanRequest, options?: ChangePlanOptions): Promise<UsageTapSuccessResponse<ChangePlanResponseBody>>;
|
|
290
305
|
withUsage<T>(beginRequest: BeginCallRequest, handler: (context: WithUsageContext) => Promise<T>, options?: WithUsageOptions): Promise<T>;
|
|
291
306
|
private request;
|
|
292
307
|
private requestGet;
|
|
@@ -299,4 +314,4 @@ declare class UsageTapClient {
|
|
|
299
314
|
private toApiError;
|
|
300
315
|
}
|
|
301
316
|
|
|
302
|
-
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type EndCallRequest as E, type IdempotencyMetadata as I, type LimitType as L, type MeterSummary as M, type PlanSummary as P, type RemainingRatios as R, type SubscriptionSnapshot as S, UsageTapClient as U, type VendorHints as V, type WithUsageOptions as W, type UsageTapSuccessResponse as a, type BeginCallResponseBody as b, type BeginCallOptions as c, type CreateCustomerRequest as d, type CreateCustomerResponseBody as e, type CheckUsageOptions as f, type CheckUsageRequest as g, type CheckUsageResponseBody as h, type
|
|
317
|
+
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type ModelHints as D, type EndCallRequest as E, type IdempotencyMetadata as I, type LimitType as L, type MeterSummary as M, type PlanSummary as P, type RemainingRatios as R, type SubscriptionSnapshot as S, UsageTapClient as U, type VendorHints as V, type WithUsageOptions as W, type UsageTapSuccessResponse as a, type BeginCallResponseBody as b, type BeginCallOptions as c, type CreateCustomerRequest as d, type CreateCustomerResponseBody as e, type CheckUsageOptions as f, type CheckUsageRequest as g, type CheckUsageResponseBody as h, type ChangePlanOptions as i, type ChangePlanRequest as j, type ChangePlanResponseBody as k, type ChangePlanStrategy as l, type EndCallOptions as m, type EndCallResponseBody as n, type BalanceSummary as o, type EntitlementHints as p, type MeterSnapshot as q, type MeteredUsage as r, type RequestedEntitlements as s, type RetryOptions as t, type UsageTapClientOptions as u, type UsageTapErrorResponse as v, type UsageTapResultEnvelope as w, type UsageTapResultStatus as x, type UsageTapLogEntry as y, type WithUsageContext as z };
|
package/dist/express/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
2
|
import { Request, Response, NextFunction } from 'express';
|
|
3
|
-
import { U as UsageTapClient } from '../client-
|
|
3
|
+
import { U as UsageTapClient } from '../client-nU5xk2pN.cjs';
|
|
4
4
|
import { WrapOpenAIContext, WrapOpenAIOptions, wrapOpenAI, pipeToResponse } from '../adapters/openai.cjs';
|
|
5
5
|
|
|
6
6
|
interface ExpressUsageTapContext {
|
package/dist/express/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
2
|
import { Request, Response, NextFunction } from 'express';
|
|
3
|
-
import { U as UsageTapClient } from '../client-
|
|
3
|
+
import { U as UsageTapClient } from '../client-nU5xk2pN.js';
|
|
4
4
|
import { WrapOpenAIContext, WrapOpenAIOptions, wrapOpenAI, pipeToResponse } from '../adapters/openai.js';
|
|
5
5
|
|
|
6
6
|
interface ExpressUsageTapContext {
|
package/dist/index.cjs
CHANGED
|
@@ -120,6 +120,7 @@ var CALL_BEGIN_PATH = "call_begin";
|
|
|
120
120
|
var CALL_END_PATH = "call_end";
|
|
121
121
|
var CHECK_USAGE_PATH = "customers/{customerId}/usage";
|
|
122
122
|
var CREATE_CUSTOMER_PATH = "customers";
|
|
123
|
+
var CHANGE_PLAN_PATH = "customers/{customerId}/change_plan";
|
|
123
124
|
var AUTH_HEADER = "authorization";
|
|
124
125
|
var API_KEY_HEADER = "x-api-key";
|
|
125
126
|
var CORRELATION_HEADER = "x-usage-correlation-id";
|
|
@@ -127,7 +128,7 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
|
127
128
|
var SDK_HEADER = "x-usage-sdk";
|
|
128
129
|
var USER_AGENT = "UsageTapClient";
|
|
129
130
|
var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
|
|
130
|
-
var SDK_VERSION = "0.
|
|
131
|
+
var SDK_VERSION = "0.7.0" ;
|
|
131
132
|
var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
|
|
132
133
|
var UsageTapClient = class {
|
|
133
134
|
apiKey;
|
|
@@ -176,7 +177,7 @@ var UsageTapClient = class {
|
|
|
176
177
|
const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);
|
|
177
178
|
this.baseUrl = new URL(normalizedBaseUrl);
|
|
178
179
|
this.apiKey = options.apiKey;
|
|
179
|
-
this.fetchImpl = fetchCandidate;
|
|
180
|
+
this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);
|
|
180
181
|
this.defaultFeature = options.defaultFeature;
|
|
181
182
|
this.defaultTags = options.defaultTags?.length ? dedupeStrings(options.defaultTags) : void 0;
|
|
182
183
|
this.defaultHeaders = options.headers ? normalizeHeaderDictionary(options.headers) : {};
|
|
@@ -256,6 +257,38 @@ var UsageTapClient = class {
|
|
|
256
257
|
);
|
|
257
258
|
return response;
|
|
258
259
|
}
|
|
260
|
+
async changePlan(request, options = {}) {
|
|
261
|
+
if (!request?.customerId) {
|
|
262
|
+
throw new UsageTapError(
|
|
263
|
+
"USAGETAP_BAD_REQUEST",
|
|
264
|
+
"changePlan requires customerId"
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
if (!request?.planId) {
|
|
268
|
+
throw new UsageTapError(
|
|
269
|
+
"USAGETAP_BAD_REQUEST",
|
|
270
|
+
"changePlan requires planId"
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
const path = CHANGE_PLAN_PATH.replace(
|
|
274
|
+
"{customerId}",
|
|
275
|
+
encodeURIComponent(request.customerId)
|
|
276
|
+
);
|
|
277
|
+
const idempotencyKey = options.idempotencyKey ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
278
|
+
const payload = {
|
|
279
|
+
planId: request.planId,
|
|
280
|
+
strategy: request.strategy ?? "IMMEDIATE_RESET"
|
|
281
|
+
};
|
|
282
|
+
const response = await this.request(
|
|
283
|
+
path,
|
|
284
|
+
payload,
|
|
285
|
+
{
|
|
286
|
+
...options,
|
|
287
|
+
idempotencyKey
|
|
288
|
+
}
|
|
289
|
+
);
|
|
290
|
+
return response;
|
|
291
|
+
}
|
|
259
292
|
async withUsage(beginRequest, handler, options = {}) {
|
|
260
293
|
const idempotencyKey = beginRequest.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
261
294
|
const beginPayload = idempotencyKey ? { ...beginRequest, idempotency: idempotencyKey } : { ...beginRequest };
|
|
@@ -621,6 +654,10 @@ function dedupeStrings(values) {
|
|
|
621
654
|
new Set(values.map((value) => value.trim()).filter(Boolean))
|
|
622
655
|
);
|
|
623
656
|
}
|
|
657
|
+
function wrapFetchImplementation(fetchCandidate, preferGlobalContext) {
|
|
658
|
+
const target = preferGlobalContext ? globalThis : void 0;
|
|
659
|
+
return ((...args) => target ? Reflect.apply(fetchCandidate, target, args) : fetchCandidate(...args));
|
|
660
|
+
}
|
|
624
661
|
function wrapEndCallError(error, correlationId) {
|
|
625
662
|
if (isUsageTapError(error)) {
|
|
626
663
|
return new UsageTapError("USAGETAP_END_CALL_ERROR", error.message, {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/retry.ts","../src/client.ts","../src/adapters/fetch-wrapper.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export type UsageTapErrorCode =\r\n | \"USAGETAP_BROWSER_RUNTIME\"\r\n | \"USAGETAP_AUTH_ERROR\"\r\n | \"USAGETAP_BAD_REQUEST\"\r\n | \"USAGETAP_INVALID_RESPONSE\"\r\n | \"USAGETAP_NETWORK_ERROR\"\r\n | \"USAGETAP_RATE_LIMITED\"\r\n | \"USAGETAP_SERVER_ERROR\"\r\n | \"USAGETAP_RETRY_EXHAUSTED\"\r\n | \"USAGETAP_END_CALL_ERROR\";\r\n\r\nexport interface UsageTapErrorInit {\r\n status?: number;\r\n retryable?: boolean;\r\n correlationId?: string;\r\n details?: Record<string, unknown>;\r\n cause?: unknown;\r\n}\r\n\r\nexport class UsageTapError extends Error {\r\n public readonly code: UsageTapErrorCode;\r\n public readonly status?: number;\r\n public readonly retryable: boolean;\r\n public readonly correlationId?: string;\r\n public readonly details?: Record<string, unknown>;\r\n\r\n constructor(code: UsageTapErrorCode, message: string, init: UsageTapErrorInit = {}) {\r\n super(message, init.cause ? { cause: init.cause as Error } : undefined);\r\n this.name = \"UsageTapError\";\r\n this.code = code;\r\n this.status = init.status;\r\n this.retryable = init.retryable ?? false;\r\n this.correlationId = init.correlationId;\r\n this.details = init.details;\r\n }\r\n\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n code: this.code,\r\n status: this.status,\r\n retryable: this.retryable,\r\n correlationId: this.correlationId,\r\n details: this.details,\r\n };\r\n }\r\n}\r\n\r\nexport function isUsageTapError(error: unknown): error is UsageTapError {\r\n return error instanceof UsageTapError;\r\n}\r\n","export function createIdempotencyKey(): string {\r\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n\r\n const random = (): string => Math.random().toString(16).slice(2, 10);\r\n return `${random()}-${random()}`;\r\n}\r\n","import type { RetryOptions } from \"./types\";\r\n\r\nexport interface ResolvedRetryOptions {\r\n maxAttempts: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n jitterRatio: number;\r\n}\r\n\r\nconst DEFAULTS: ResolvedRetryOptions = {\r\n maxAttempts: 3,\r\n baseDelayMs: 250,\r\n maxDelayMs: 5000,\r\n jitterRatio: 0.2,\r\n};\r\n\r\nexport function resolveRetryOptions(\r\n base?: RetryOptions,\r\n override?: RetryOptions,\r\n): ResolvedRetryOptions {\r\n const merged = { ...DEFAULTS, ...base, ...override } satisfies ResolvedRetryOptions;\r\n return {\r\n maxAttempts: Math.max(1, Math.floor(merged.maxAttempts)),\r\n baseDelayMs: Math.max(0, merged.baseDelayMs),\r\n maxDelayMs: Math.max(merged.baseDelayMs, merged.maxDelayMs),\r\n jitterRatio: Math.min(Math.max(merged.jitterRatio, 0), 1),\r\n };\r\n}\r\n\r\nexport async function sleep(delayMs: number, signal?: AbortSignal): Promise<void> {\r\n if (delayMs <= 0) {\r\n signal?.throwIfAborted?.();\r\n return;\r\n }\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, delayMs);\r\n\r\n const cleanup = (): void => {\r\n clearTimeout(timer);\r\n signal?.removeEventListener(\"abort\", onAbort);\r\n };\r\n\r\n const onAbort = (): void => {\r\n cleanup();\r\n const abortError = new Error(\"Aborted\");\r\n abortError.name = \"AbortError\";\r\n reject(abortError);\r\n };\r\n\r\n if (signal) {\r\n if (signal.aborted) {\r\n onAbort();\r\n return;\r\n }\r\n signal.addEventListener(\"abort\", onAbort, { once: true });\r\n }\r\n });\r\n}\r\n\r\nexport function computeDelay(attempt: number, options: ResolvedRetryOptions): number {\r\n const exp = options.baseDelayMs * Math.pow(2, attempt - 1);\r\n const capped = Math.min(exp, options.maxDelayMs);\r\n const jitter = capped * options.jitterRatio;\r\n const min = capped - jitter;\r\n const max = capped + jitter;\r\n return Math.max(0, Math.random() * (max - min) + min);\r\n}\r\n\r\nexport async function runWithRetry<T>(\r\n operation: (attempt: number) => Promise<T>,\r\n options: ResolvedRetryOptions,\r\n shouldRetry: (error: unknown) => boolean,\r\n onSchedule?: (attempt: number, delayMs: number, error: unknown) => void,\r\n signal?: AbortSignal,\r\n): Promise<T> {\r\n let attempt = 0;\r\n let lastError: unknown;\r\n while (attempt < options.maxAttempts) {\r\n attempt += 1;\r\n signal?.throwIfAborted?.();\r\n\r\n try {\r\n return await operation(attempt);\r\n } catch (error) {\r\n lastError = error;\r\n if (attempt >= options.maxAttempts || !shouldRetry(error)) {\r\n throw error;\r\n }\r\n const delayMs = computeDelay(attempt, options);\r\n onSchedule?.(attempt, delayMs, error);\r\n await sleep(delayMs, signal);\r\n }\r\n }\r\n\r\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\r\n}\r\n","import type {\r\n BeginCallOptions,\r\n BeginCallRequest,\r\n BeginCallResponseBody,\r\n CreateCustomerOptions,\r\n CreateCustomerRequest,\r\n CreateCustomerResponseBody,\r\n CheckUsageOptions,\r\n CheckUsageRequest,\r\n CheckUsageResponseBody,\r\n EndCallOptions,\r\n EndCallRequest,\r\n EndCallResponseBody,\r\n UsageTapClientOptions,\r\n UsageTapLogEntry,\r\n UsageTapSuccessResponse,\r\n WithUsageContext,\r\n WithUsageOptions,\r\n} from \"./types\";\r\nimport {\r\n UsageTapError,\r\n type UsageTapErrorCode,\r\n isUsageTapError,\r\n} from \"./errors\";\r\nimport { createIdempotencyKey } from \"./idempotency\";\r\nimport {\r\n runWithRetry,\r\n resolveRetryOptions,\r\n type ResolvedRetryOptions,\r\n} from \"./retry\";\r\nimport type { RetryOptions } from \"./types\";\r\n\r\nconst CALL_BEGIN_PATH = \"call_begin\";\r\nconst CALL_END_PATH = \"call_end\";\r\nconst CHECK_USAGE_PATH = \"customers/{customerId}/usage\";\r\nconst CREATE_CUSTOMER_PATH = \"customers\";\r\nconst AUTH_HEADER = \"authorization\";\r\nconst API_KEY_HEADER = \"x-api-key\";\r\nconst CORRELATION_HEADER = \"x-usage-correlation-id\";\r\nconst IDEMPOTENCY_HEADER = \"idempotency-key\";\r\nconst SDK_HEADER = \"x-usage-sdk\";\r\nconst USER_AGENT = \"UsageTapClient\";\r\nconst CANONICAL_MEDIA_TYPE = \"application/vnd.usagetap.v1+json\";\r\n\r\ndeclare const __SDK_VERSION__: string | undefined;\r\nconst SDK_VERSION =\r\n typeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.1.0\";\r\nconst HAS_WINDOW =\r\n typeof globalThis !== \"undefined\" &&\r\n typeof (globalThis as Record<string, unknown>).window !== \"undefined\";\r\n\r\ntype HeadersDict = Record<string, string>;\r\n\r\ntype InternalRequestOptions = {\r\n signal?: AbortSignal;\r\n headers?: HeadersDict;\r\n retries?: RetryOptions;\r\n correlationId?: string;\r\n idempotencyKey?: string;\r\n};\r\n\r\ntype EnvelopeShape = {\r\n result?: {\r\n status?: string;\r\n code?: string;\r\n message?: string;\r\n timestamp?: string;\r\n };\r\n data?: unknown;\r\n error?: {\r\n code?: string;\r\n message?: string;\r\n details?: Record<string, unknown>;\r\n };\r\n correlationId?: string;\r\n};\r\n\r\nexport class UsageTapClient {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: URL;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultFeature?: string;\r\n private readonly defaultTags?: string[];\r\n private readonly defaultHeaders: HeadersDict;\r\n private readonly retryDefaults: ResolvedRetryOptions;\r\n private readonly idempotencyGenerator: () => string;\r\n private readonly logFn?: (entry: UsageTapLogEntry) => void;\r\n private readonly authHeader: typeof AUTH_HEADER | typeof API_KEY_HEADER;\r\n private readonly autoIdempotency: boolean;\r\n\r\n constructor(options: UsageTapClientOptions) {\r\n if (!options) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient options are required\"\r\n );\r\n }\r\n\r\n if (!options.apiKey) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires an apiKey\"\r\n );\r\n }\r\n\r\n if (!options.baseUrl) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires a baseUrl\"\r\n );\r\n }\r\n\r\n if (HAS_WINDOW && !options.allowBrowser) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BROWSER_RUNTIME\",\r\n \"UsageTapClient is designed for server-side environments. Pass allowBrowser=true only for testing.\"\r\n );\r\n }\r\n\r\n const fetchCandidate = options.fetchImpl ?? globalThis.fetch;\r\n if (typeof fetchCandidate !== \"function\") {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"A global fetch implementation was not found. Pass fetchImpl in UsageTapClientOptions.\"\r\n );\r\n }\r\n\r\n const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);\r\n this.baseUrl = new URL(normalizedBaseUrl);\r\n this.apiKey = options.apiKey;\r\n this.fetchImpl = fetchCandidate;\r\n this.defaultFeature = options.defaultFeature;\r\n this.defaultTags = options.defaultTags?.length\r\n ? dedupeStrings(options.defaultTags)\r\n : undefined;\r\n this.defaultHeaders = options.headers\r\n ? normalizeHeaderDictionary(options.headers)\r\n : {};\r\n this.retryDefaults = resolveRetryOptions(options.retries);\r\n this.idempotencyGenerator =\r\n options.idempotencyGenerator ?? createIdempotencyKey;\r\n this.logFn = options.onLog;\r\n this.authHeader = options.useApiKeyHeader ? API_KEY_HEADER : AUTH_HEADER;\r\n this.autoIdempotency = options.autoIdempotency ?? true;\r\n }\r\n\r\n async beginCall(\r\n request: BeginCallRequest,\r\n options: BeginCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<BeginCallResponseBody>> {\r\n const idempotencyKey =\r\n request.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const payload: BeginCallRequest = {\r\n ...request,\r\n feature: request.feature ?? this.defaultFeature,\r\n tags: this.mergeTags(request.tags),\r\n } satisfies BeginCallRequest;\r\n if (idempotencyKey) {\r\n payload.idempotency = idempotencyKey;\r\n }\r\n\r\n const response = await this.request<BeginCallResponseBody>(\r\n CALL_BEGIN_PATH,\r\n payload,\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async endCall(\r\n request: EndCallRequest,\r\n options: EndCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<EndCallResponseBody>> {\r\n if (!request?.callId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"endCall requires callId\"\r\n );\r\n }\r\n\r\n const payload = { ...request } satisfies EndCallRequest;\r\n const response = await this.request<EndCallResponseBody>(\r\n CALL_END_PATH,\r\n payload,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async checkUsage(\r\n request: CheckUsageRequest,\r\n options: CheckUsageOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"checkUsage requires customerId\"\r\n );\r\n }\r\n\r\n const path = CHECK_USAGE_PATH.replace(\r\n \"{customerId}\",\r\n encodeURIComponent(request.customerId)\r\n );\r\n const response = await this.requestGet<CheckUsageResponseBody>(\r\n path,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async createCustomer(\r\n request: CreateCustomerRequest,\r\n options: CreateCustomerOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"createCustomer requires customerId\"\r\n );\r\n }\r\n\r\n const idempotencyKey =\r\n options.idempotencyKey ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n\r\n const response = await this.request<CreateCustomerResponseBody>(\r\n CREATE_CUSTOMER_PATH,\r\n { ...request },\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async withUsage<T>(\r\n beginRequest: BeginCallRequest,\r\n handler: (context: WithUsageContext) => Promise<T>,\r\n options: WithUsageOptions = {}\r\n ): Promise<T> {\r\n const idempotencyKey =\r\n beginRequest.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const beginPayload = idempotencyKey\r\n ? { ...beginRequest, idempotency: idempotencyKey }\r\n : { ...beginRequest };\r\n const beginResponse = await this.beginCall(beginPayload, options);\r\n\r\n let usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const initialStripeCustomerId =\r\n typeof beginResponse.data.stripeCustomerId === \"string\"\r\n ? beginResponse.data.stripeCustomerId\r\n : typeof beginRequest.stripeCustomerId === \"string\"\r\n ? beginRequest.stripeCustomerId\r\n : undefined;\r\n if (initialStripeCustomerId) {\r\n usage = { ...usage, stripeCustomerId: initialStripeCustomerId };\r\n }\r\n let errorPayload: EndCallRequest[\"error\"] | undefined;\r\n let handlerResult: T | undefined;\r\n let handlerError: unknown;\r\n let endCallError: unknown;\r\n\r\n const context: WithUsageContext = {\r\n begin: beginResponse,\r\n setUsage: (u) => {\r\n usage = { ...usage, ...u };\r\n },\r\n setError: (err) => {\r\n errorPayload = err;\r\n },\r\n };\r\n\r\n try {\r\n handlerResult = await handler(context);\r\n } catch (error) {\r\n handlerError = error;\r\n if (!errorPayload) {\r\n errorPayload = {\r\n code: options.defaultErrorCode ?? \"VENDOR_ERROR\",\r\n message: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n } finally {\r\n try {\r\n await this.endCall(\r\n {\r\n callId: beginResponse.data.callId,\r\n ...(usage as Partial<Omit<EndCallRequest, \"callId\" | \"error\">>),\r\n error: errorPayload,\r\n },\r\n {\r\n ...options,\r\n correlationId: beginResponse.correlationId,\r\n }\r\n );\r\n } catch (error) {\r\n endCallError = error;\r\n }\r\n }\r\n\r\n if (handlerError) {\r\n throw handlerError;\r\n }\r\n\r\n if (endCallError) {\r\n throw wrapEndCallError(endCallError, beginResponse.correlationId);\r\n }\r\n\r\n return handlerResult as T;\r\n }\r\n\r\n private async request<T>(\r\n path: string,\r\n payload: unknown,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const body = payload !== undefined ? JSON.stringify(payload) : undefined;\r\n const headers = this.composeHeaders(body, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"POST\",\r\n headers,\r\n body,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async requestGet<T>(\r\n path: string,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const headers = this.composeHeaders(undefined, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"GET\",\r\n headers,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async performFetch<T>(init: {\r\n url: string;\r\n method: string;\r\n headers: HeadersDict;\r\n body?: string;\r\n signal?: AbortSignal;\r\n }): Promise<UsageTapSuccessResponse<T>> {\r\n let response: Response;\r\n try {\r\n response = await this.fetchImpl(init.url, {\r\n method: init.method,\r\n headers: init.headers,\r\n body: init.body,\r\n signal: init.signal,\r\n });\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"Failed to reach UsageTap\",\r\n {\r\n retryable: true,\r\n cause: error,\r\n }\r\n );\r\n }\r\n\r\n const correlationId = response.headers.get(CORRELATION_HEADER) ?? undefined;\r\n const text = await response.text();\r\n let payload: EnvelopeShape | undefined;\r\n\r\n if (text) {\r\n try {\r\n payload = JSON.parse(text) as EnvelopeShape;\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap returned invalid JSON\",\r\n {\r\n retryable: false,\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n throw this.toHttpError(response.status, payload, correlationId);\r\n }\r\n\r\n if (!payload?.result || payload.result.status !== \"ACCEPTED\") {\r\n throw this.toApiError(payload, correlationId);\r\n }\r\n\r\n const resolvedCorrelation = payload.correlationId ?? correlationId;\r\n if (\r\n payload.data === undefined ||\r\n payload.data === null ||\r\n !resolvedCorrelation\r\n ) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap response missing data or correlationId\",\r\n {\r\n correlationId: resolvedCorrelation ?? correlationId,\r\n }\r\n );\r\n }\r\n\r\n return {\r\n result: {\r\n status: payload.result.status as \"ACCEPTED\",\r\n code: payload.result.code,\r\n message: payload.result.message,\r\n timestamp: payload.result.timestamp,\r\n },\r\n data: payload.data as T,\r\n correlationId: resolvedCorrelation,\r\n } satisfies UsageTapSuccessResponse<T>;\r\n }\r\n\r\n private composeHeaders(\r\n body: string | undefined,\r\n options: InternalRequestOptions\r\n ): HeadersDict {\r\n const headers: HeadersDict = {\r\n ...this.defaultHeaders,\r\n [SDK_HEADER]: `js/${SDK_VERSION}`,\r\n \"content-type\": \"application/json\",\r\n accept: CANONICAL_MEDIA_TYPE,\r\n };\r\n\r\n if (!HAS_WINDOW) {\r\n // Browsers forbid setting user-agent; only attach it server-side.\r\n headers[\"user-agent\"] = `${USER_AGENT}/${SDK_VERSION}`;\r\n }\r\n\r\n if (this.authHeader === API_KEY_HEADER) {\r\n headers[API_KEY_HEADER] = this.apiKey;\r\n } else {\r\n headers[AUTH_HEADER] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n if (options.idempotencyKey) {\r\n headers[IDEMPOTENCY_HEADER] = options.idempotencyKey;\r\n }\r\n\r\n if (options.correlationId) {\r\n headers[CORRELATION_HEADER] = options.correlationId;\r\n }\r\n\r\n if (!body) {\r\n delete headers[\"content-type\"];\r\n }\r\n\r\n if (options.headers) {\r\n Object.assign(headers, normalizeHeaderDictionary(options.headers));\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n private log(entry: UsageTapLogEntry): void {\r\n this.logFn?.(entry);\r\n }\r\n\r\n private mergeTags(tags?: string[]): string[] | undefined {\r\n if (!tags && !this.defaultTags) {\r\n return undefined;\r\n }\r\n\r\n const combined = [...(this.defaultTags ?? []), ...(tags ?? [])].filter(\r\n Boolean\r\n );\r\n return combined.length ? dedupeStrings(combined) : undefined;\r\n }\r\n\r\n private shouldRetry(error: unknown): boolean {\r\n if (isUsageTapError(error)) {\r\n return Boolean(error.retryable);\r\n }\r\n\r\n if (error instanceof Error && error.name === \"AbortError\") {\r\n return false;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private toHttpError(\r\n status: number,\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const code = mapStatusToErrorCode(status);\r\n const retryable = isRetryableStatus(status);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n `UsageTap responded with HTTP ${status}`;\r\n\r\n return new UsageTapError(code, message, {\r\n status,\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n\r\n private toApiError(\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const normalizedCode =\r\n payload?.error?.code ?? payload?.result?.code ?? \"UNKNOWN\";\r\n const retryable = isRetryableApiCode(normalizedCode);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n \"UsageTap reported an error\";\r\n\r\n return new UsageTapError(mapApiCodeToError(normalizedCode), message, {\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n}\r\n\r\nfunction mapStatusToErrorCode(status: number): UsageTapErrorCode {\r\n if (status === 401 || status === 403) return \"USAGETAP_AUTH_ERROR\";\r\n if (status === 400 || status === 404 || status === 409)\r\n return \"USAGETAP_BAD_REQUEST\";\r\n if (status === 429) return \"USAGETAP_RATE_LIMITED\";\r\n if (status >= 500) return \"USAGETAP_SERVER_ERROR\";\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction isRetryableStatus(status: number): boolean {\r\n return (\r\n status === 408 ||\r\n status === 425 ||\r\n status === 429 ||\r\n status === 500 ||\r\n status === 502 ||\r\n status === 503 ||\r\n status === 504\r\n );\r\n}\r\n\r\nfunction isRetryableApiCode(code: string): boolean {\r\n const normalized = code.toUpperCase();\r\n return (\r\n normalized.includes(\"TRANSIENT\") ||\r\n normalized.includes(\"RETRY\") ||\r\n normalized.includes(\"TIMEOUT\") ||\r\n normalized.includes(\"THROTTLE\") ||\r\n normalized.includes(\"RATE_LIMIT\")\r\n );\r\n}\r\n\r\nfunction mapApiCodeToError(code: string): UsageTapErrorCode {\r\n const normalized = code.toUpperCase();\r\n if (normalized.includes(\"AUTH\") || normalized.includes(\"TOKEN\")) {\r\n return \"USAGETAP_AUTH_ERROR\";\r\n }\r\n if (normalized.includes(\"RATE\") || normalized.includes(\"THROTTLE\")) {\r\n return \"USAGETAP_RATE_LIMITED\";\r\n }\r\n if (normalized.includes(\"SERVER\") || normalized.includes(\"TRANSIENT\")) {\r\n return \"USAGETAP_SERVER_ERROR\";\r\n }\r\n if (\r\n normalized.includes(\"IDEMPOTENCY\") ||\r\n normalized.includes(\"VALIDATION\") ||\r\n normalized.includes(\"REQUEST\")\r\n ) {\r\n return \"USAGETAP_BAD_REQUEST\";\r\n }\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction sanitizeDetails(\r\n payload: EnvelopeShape | undefined\r\n): Record<string, unknown> | undefined {\r\n if (!payload) return undefined;\r\n const details: Record<string, unknown> = {};\r\n if (payload.result) details.result = payload.result;\r\n if (payload.error) details.error = payload.error;\r\n return Object.keys(details).length ? details : undefined;\r\n}\r\n\r\nfunction normalizeBaseUrl(baseUrl: string): string {\r\n const trimmed = baseUrl.trim();\r\n if (!trimmed) return trimmed;\r\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\r\n}\r\n\r\nfunction normalizeHeaderDictionary(dict: Record<string, string>): HeadersDict {\r\n return Object.keys(dict).reduce<HeadersDict>((acc, key) => {\r\n acc[key.toLowerCase()] = dict[key];\r\n return acc;\r\n }, {});\r\n}\r\n\r\nfunction dedupeStrings(values: string[]): string[] {\r\n return Array.from(\r\n new Set(values.map((value) => value.trim()).filter(Boolean))\r\n );\r\n}\r\n\r\nfunction wrapEndCallError(\r\n error: unknown,\r\n correlationId?: string\r\n): UsageTapError {\r\n if (isUsageTapError(error)) {\r\n return new UsageTapError(\"USAGETAP_END_CALL_ERROR\", error.message, {\r\n correlationId: error.correlationId ?? correlationId,\r\n details: error.details,\r\n cause: error,\r\n });\r\n }\r\n\r\n return new UsageTapError(\r\n \"USAGETAP_END_CALL_ERROR\",\r\n \"Failed to finalize UsageTap call\",\r\n {\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n}\r\n","import { UsageTapClient } from \"../client\";\r\nimport type { BeginCallRequest, EndCallRequest } from \"../types\";\r\n\r\nexport interface WrapFetchContext extends Omit<BeginCallRequest, \"idempotency\"> {\r\n customerId: string;\r\n}\r\n\r\nexport interface WrapFetchOptions {\r\n /**\r\n * Context for UsageTap begin calls.\r\n * Can be overridden per-request via special headers.\r\n */\r\n defaultContext: WrapFetchContext;\r\n \r\n /**\r\n * Optional custom fetch implementation to wrap.\r\n * Defaults to global fetch.\r\n */\r\n baseFetch?: typeof fetch;\r\n \r\n /**\r\n * Generate idempotency keys automatically if not provided.\r\n * Default: true\r\n */\r\n autoIdempotency?: boolean;\r\n \r\n /**\r\n * Detect OpenAI-compatible endpoints by URL pattern.\r\n * Default: detects /v1/chat/completions and /v1/responses\r\n */\r\n isOpenAIEndpoint?: (url: string) => boolean;\r\n}\r\n\r\ninterface CallState {\r\n callId: string;\r\n correlationId?: string;\r\n usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>;\r\n finalized: boolean;\r\n}\r\n\r\ntype JsonRecord = Record<string, unknown>;\r\n\r\nfunction isJsonRecord(value: unknown): value is JsonRecord {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction readString(value: unknown): string | undefined {\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nfunction readNumber(value: unknown): number | undefined {\r\n return typeof value === \"number\" ? value : undefined;\r\n}\r\n\r\nfunction parseJsonRecord(text: string): JsonRecord | undefined {\r\n try {\r\n const parsed = JSON.parse(text) as unknown;\r\n return isJsonRecord(parsed) ? parsed : undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction parseStringArray(value: string): string[] | undefined {\r\n try {\r\n const parsed = JSON.parse(value) as unknown;\r\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\r\n return parsed;\r\n }\r\n } catch {\r\n return undefined;\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Wraps a fetch implementation to automatically instrument OpenAI API calls\r\n * with UsageTap begin/end tracking.\r\n * \r\n * Example:\r\n * ```ts\r\n * const wrappedFetch = wrapFetch(usageTap, {\r\n * defaultContext: { customerId: \"cust_123\", feature: \"chat\" }\r\n * });\r\n * \r\n * const openai = new OpenAI({\r\n * apiKey: process.env.OPENAI_API_KEY!,\r\n * fetch: wrappedFetch,\r\n * });\r\n * ```\r\n */\r\nexport function wrapFetch(\r\n usageTap: UsageTapClient,\r\n options: WrapFetchOptions,\r\n): typeof fetch {\r\n const {\r\n defaultContext,\r\n baseFetch = globalThis.fetch,\r\n autoIdempotency = true,\r\n isOpenAIEndpoint = defaultIsOpenAIEndpoint,\r\n } = options;\r\n\r\n return async function wrappedFetch(\r\n input: string | URL | Request,\r\n init?: RequestInit,\r\n ): Promise<Response> {\r\n const url = typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\r\n \r\n // Only intercept OpenAI endpoints\r\n if (!isOpenAIEndpoint(url)) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Parse request body to extract context overrides and detect streaming\r\n let body: JsonRecord | undefined;\r\n let isStreaming = false;\r\n const contextOverride: Partial<WrapFetchContext> = {};\r\n\r\n try {\r\n if (init?.body && typeof init.body === \"string\") {\r\n const parsedBody = parseJsonRecord(init.body);\r\n if (!parsedBody) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n body = parsedBody;\r\n isStreaming = parsedBody.stream === true;\r\n\r\n // Check for context overrides in special headers\r\n const headers = new Headers(init.headers);\r\n const customerIdHeader = headers.get(\"x-usagetap-customer-id\");\r\n const featureHeader = headers.get(\"x-usagetap-feature\");\r\n const tagsHeader = headers.get(\"x-usagetap-tags\");\r\n\r\n if (customerIdHeader) {\r\n contextOverride.customerId = customerIdHeader;\r\n }\r\n if (featureHeader) {\r\n contextOverride.feature = featureHeader;\r\n }\r\n if (tagsHeader) {\r\n const tags = parseStringArray(tagsHeader);\r\n if (tags) {\r\n contextOverride.tags = tags;\r\n }\r\n }\r\n }\r\n } catch {\r\n // If body parsing fails, proceed without interception\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Merge context\r\n const context: BeginCallRequest = {\r\n ...defaultContext,\r\n ...contextOverride,\r\n idempotency: autoIdempotency ? crypto.randomUUID() : undefined,\r\n };\r\n\r\n // Begin the call\r\n let callState: CallState | undefined;\r\n try {\r\n const beginResponse = await usageTap.beginCall(context);\r\n callState = {\r\n callId: beginResponse.data.callId,\r\n correlationId: beginResponse.correlationId,\r\n usage: {},\r\n finalized: false,\r\n };\r\n } catch (error) {\r\n // If begin fails, proceed with original fetch but log error\r\n console.error(\"[wrapFetch] Failed to begin call:\", error);\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Add correlation header to vendor request\r\n const modifiedInit = {\r\n ...init,\r\n headers: {\r\n ...init?.headers,\r\n \"x-usage-correlation-id\": callState.correlationId || \"\",\r\n },\r\n };\r\n\r\n // Call the vendor API\r\n try {\r\n const response = await baseFetch(input, modifiedInit);\r\n \r\n if (isStreaming) {\r\n // Wrap streaming response\r\n return wrapStreamingResponse(response, callState, usageTap);\r\n } else {\r\n // Handle non-streaming response\r\n return await wrapNonStreamingResponse(response, callState, usageTap, body);\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // Vendor call failed\r\n await finalizeCall(callState, usageTap, {\r\n code: \"VENDOR_ERROR\",\r\n message,\r\n });\r\n throw error;\r\n }\r\n };\r\n}\r\n\r\nfunction defaultIsOpenAIEndpoint(url: string): boolean {\r\n return (\r\n url.includes(\"/v1/chat/completions\") ||\r\n url.includes(\"/v1/responses\") ||\r\n url.includes(\"/v1/embeddings\")\r\n );\r\n}\r\n\r\nasync function wrapNonStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n requestBody: JsonRecord | undefined,\r\n): Promise<Response> {\r\n // Clone response to read body\r\n const clonedResponse = response.clone();\r\n \r\n try {\r\n const parsed = await clonedResponse.json();\r\n const usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n\r\n if (isJsonRecord(parsed)) {\r\n const usageBlock = parsed.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n usage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n usage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n usage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n usage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const modelFromResponse = readString(parsed.model);\r\n if (modelFromResponse) {\r\n usage.modelUsed = modelFromResponse;\r\n }\r\n }\r\n\r\n if (!usage.modelUsed && requestBody) {\r\n const requestModel = readString(requestBody.model);\r\n if (requestModel) {\r\n usage.modelUsed = requestModel;\r\n }\r\n }\r\n\r\n // Finalize the call\r\n await finalizeCall(callState, usageTap, undefined, usage);\r\n\r\n return response;\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // If we can't parse response, finalize with error\r\n await finalizeCall(callState, usageTap, {\r\n code: \"RESPONSE_PARSE_ERROR\",\r\n message,\r\n });\r\n return response;\r\n }\r\n}\r\n\r\nfunction wrapStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n): Response {\r\n if (!response.body) {\r\n // No body to stream, finalize now\r\n void finalizeCall(callState, usageTap, {\r\n code: \"NO_RESPONSE_BODY\",\r\n message: \"Streaming response has no body\",\r\n });\r\n return response;\r\n }\r\n\r\n const originalBody = response.body;\r\n const accumulatedUsage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const textDecoder = new TextDecoder();\r\n\r\n const transformStream = new TransformStream({\r\n transform(chunk: Uint8Array, controller) {\r\n controller.enqueue(chunk);\r\n \r\n // Try to parse usage from SSE data\r\n try {\r\n const text = textDecoder.decode(chunk, { stream: true });\r\n const lines = text.split(\"\\n\");\r\n \r\n for (const line of lines) {\r\n if (line.startsWith(\"data: \")) {\r\n const data = line.slice(6);\r\n if (data === \"[DONE]\") continue;\r\n \r\n const parsedRecord = parseJsonRecord(data);\r\n if (!parsedRecord) {\r\n continue;\r\n }\r\n\r\n const usageBlock = parsedRecord.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n accumulatedUsage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n accumulatedUsage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n accumulatedUsage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n accumulatedUsage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const model = readString(parsedRecord.model);\r\n if (model) {\r\n accumulatedUsage.modelUsed = model;\r\n }\r\n }\r\n }\r\n } catch {\r\n // Ignore decode errors\r\n }\r\n },\r\n\r\n async flush() {\r\n // Stream completed successfully\r\n await finalizeCall(callState, usageTap, undefined, accumulatedUsage);\r\n },\r\n });\r\n\r\n // Handle stream errors and cancellation\r\n const wrappedBody = originalBody.pipeThrough(transformStream);\r\n \r\n // Note: Response doesn't have signal property, abort handling happens via stream closure\r\n\r\n return new Response(wrappedBody, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n });\r\n}\r\n\r\nasync function finalizeCall(\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n error?: { code: string; message: string },\r\n usage?: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>,\r\n): Promise<void> {\r\n if (callState.finalized) return;\r\n callState.finalized = true;\r\n\r\n try {\r\n await usageTap.endCall({\r\n callId: callState.callId,\r\n ...callState.usage,\r\n ...usage,\r\n error,\r\n });\r\n } catch (err) {\r\n console.error(\"[wrapFetch] Failed to finalize call:\", err);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/retry.ts","../src/client.ts","../src/adapters/fetch-wrapper.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["export type UsageTapErrorCode =\r\n | \"USAGETAP_BROWSER_RUNTIME\"\r\n | \"USAGETAP_AUTH_ERROR\"\r\n | \"USAGETAP_BAD_REQUEST\"\r\n | \"USAGETAP_INVALID_RESPONSE\"\r\n | \"USAGETAP_NETWORK_ERROR\"\r\n | \"USAGETAP_RATE_LIMITED\"\r\n | \"USAGETAP_SERVER_ERROR\"\r\n | \"USAGETAP_RETRY_EXHAUSTED\"\r\n | \"USAGETAP_END_CALL_ERROR\";\r\n\r\nexport interface UsageTapErrorInit {\r\n status?: number;\r\n retryable?: boolean;\r\n correlationId?: string;\r\n details?: Record<string, unknown>;\r\n cause?: unknown;\r\n}\r\n\r\nexport class UsageTapError extends Error {\r\n public readonly code: UsageTapErrorCode;\r\n public readonly status?: number;\r\n public readonly retryable: boolean;\r\n public readonly correlationId?: string;\r\n public readonly details?: Record<string, unknown>;\r\n\r\n constructor(code: UsageTapErrorCode, message: string, init: UsageTapErrorInit = {}) {\r\n super(message, init.cause ? { cause: init.cause as Error } : undefined);\r\n this.name = \"UsageTapError\";\r\n this.code = code;\r\n this.status = init.status;\r\n this.retryable = init.retryable ?? false;\r\n this.correlationId = init.correlationId;\r\n this.details = init.details;\r\n }\r\n\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n code: this.code,\r\n status: this.status,\r\n retryable: this.retryable,\r\n correlationId: this.correlationId,\r\n details: this.details,\r\n };\r\n }\r\n}\r\n\r\nexport function isUsageTapError(error: unknown): error is UsageTapError {\r\n return error instanceof UsageTapError;\r\n}\r\n","export function createIdempotencyKey(): string {\r\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n\r\n const random = (): string => Math.random().toString(16).slice(2, 10);\r\n return `${random()}-${random()}`;\r\n}\r\n","import type { RetryOptions } from \"./types\";\r\n\r\nexport interface ResolvedRetryOptions {\r\n maxAttempts: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n jitterRatio: number;\r\n}\r\n\r\nconst DEFAULTS: ResolvedRetryOptions = {\r\n maxAttempts: 3,\r\n baseDelayMs: 250,\r\n maxDelayMs: 5000,\r\n jitterRatio: 0.2,\r\n};\r\n\r\nexport function resolveRetryOptions(\r\n base?: RetryOptions,\r\n override?: RetryOptions,\r\n): ResolvedRetryOptions {\r\n const merged = { ...DEFAULTS, ...base, ...override } satisfies ResolvedRetryOptions;\r\n return {\r\n maxAttempts: Math.max(1, Math.floor(merged.maxAttempts)),\r\n baseDelayMs: Math.max(0, merged.baseDelayMs),\r\n maxDelayMs: Math.max(merged.baseDelayMs, merged.maxDelayMs),\r\n jitterRatio: Math.min(Math.max(merged.jitterRatio, 0), 1),\r\n };\r\n}\r\n\r\nexport async function sleep(delayMs: number, signal?: AbortSignal): Promise<void> {\r\n if (delayMs <= 0) {\r\n signal?.throwIfAborted?.();\r\n return;\r\n }\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, delayMs);\r\n\r\n const cleanup = (): void => {\r\n clearTimeout(timer);\r\n signal?.removeEventListener(\"abort\", onAbort);\r\n };\r\n\r\n const onAbort = (): void => {\r\n cleanup();\r\n const abortError = new Error(\"Aborted\");\r\n abortError.name = \"AbortError\";\r\n reject(abortError);\r\n };\r\n\r\n if (signal) {\r\n if (signal.aborted) {\r\n onAbort();\r\n return;\r\n }\r\n signal.addEventListener(\"abort\", onAbort, { once: true });\r\n }\r\n });\r\n}\r\n\r\nexport function computeDelay(attempt: number, options: ResolvedRetryOptions): number {\r\n const exp = options.baseDelayMs * Math.pow(2, attempt - 1);\r\n const capped = Math.min(exp, options.maxDelayMs);\r\n const jitter = capped * options.jitterRatio;\r\n const min = capped - jitter;\r\n const max = capped + jitter;\r\n return Math.max(0, Math.random() * (max - min) + min);\r\n}\r\n\r\nexport async function runWithRetry<T>(\r\n operation: (attempt: number) => Promise<T>,\r\n options: ResolvedRetryOptions,\r\n shouldRetry: (error: unknown) => boolean,\r\n onSchedule?: (attempt: number, delayMs: number, error: unknown) => void,\r\n signal?: AbortSignal,\r\n): Promise<T> {\r\n let attempt = 0;\r\n let lastError: unknown;\r\n while (attempt < options.maxAttempts) {\r\n attempt += 1;\r\n signal?.throwIfAborted?.();\r\n\r\n try {\r\n return await operation(attempt);\r\n } catch (error) {\r\n lastError = error;\r\n if (attempt >= options.maxAttempts || !shouldRetry(error)) {\r\n throw error;\r\n }\r\n const delayMs = computeDelay(attempt, options);\r\n onSchedule?.(attempt, delayMs, error);\r\n await sleep(delayMs, signal);\r\n }\r\n }\r\n\r\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\r\n}\r\n","import type {\r\n BeginCallOptions,\r\n BeginCallRequest,\r\n BeginCallResponseBody,\r\n CreateCustomerOptions,\r\n CreateCustomerRequest,\r\n CreateCustomerResponseBody,\r\n CheckUsageOptions,\r\n CheckUsageRequest,\r\n CheckUsageResponseBody,\r\n ChangePlanOptions,\r\n ChangePlanRequest,\r\n ChangePlanResponseBody,\r\n EndCallOptions,\r\n EndCallRequest,\r\n EndCallResponseBody,\r\n UsageTapClientOptions,\r\n UsageTapLogEntry,\r\n UsageTapSuccessResponse,\r\n WithUsageContext,\r\n WithUsageOptions,\r\n} from \"./types\";\r\nimport {\r\n UsageTapError,\r\n type UsageTapErrorCode,\r\n isUsageTapError,\r\n} from \"./errors\";\r\nimport { createIdempotencyKey } from \"./idempotency\";\r\nimport {\r\n runWithRetry,\r\n resolveRetryOptions,\r\n type ResolvedRetryOptions,\r\n} from \"./retry\";\r\nimport type { RetryOptions } from \"./types\";\r\n\r\nconst CALL_BEGIN_PATH = \"call_begin\";\r\nconst CALL_END_PATH = \"call_end\";\r\nconst CHECK_USAGE_PATH = \"customers/{customerId}/usage\";\r\nconst CREATE_CUSTOMER_PATH = \"customers\";\r\nconst CHANGE_PLAN_PATH = \"customers/{customerId}/change_plan\";\r\nconst AUTH_HEADER = \"authorization\";\r\nconst API_KEY_HEADER = \"x-api-key\";\r\nconst CORRELATION_HEADER = \"x-usage-correlation-id\";\r\nconst IDEMPOTENCY_HEADER = \"idempotency-key\";\r\nconst SDK_HEADER = \"x-usage-sdk\";\r\nconst USER_AGENT = \"UsageTapClient\";\r\nconst CANONICAL_MEDIA_TYPE = \"application/vnd.usagetap.v1+json\";\r\n\r\ndeclare const __SDK_VERSION__: string | undefined;\r\nconst SDK_VERSION =\r\n typeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.1.0\";\r\nconst HAS_WINDOW =\r\n typeof globalThis !== \"undefined\" &&\r\n typeof (globalThis as Record<string, unknown>).window !== \"undefined\";\r\n\r\ntype HeadersDict = Record<string, string>;\r\n\r\ntype InternalRequestOptions = {\r\n signal?: AbortSignal;\r\n headers?: HeadersDict;\r\n retries?: RetryOptions;\r\n correlationId?: string;\r\n idempotencyKey?: string;\r\n};\r\n\r\ntype EnvelopeShape = {\r\n result?: {\r\n status?: string;\r\n code?: string;\r\n message?: string;\r\n timestamp?: string;\r\n };\r\n data?: unknown;\r\n error?: {\r\n code?: string;\r\n message?: string;\r\n details?: Record<string, unknown>;\r\n };\r\n correlationId?: string;\r\n};\r\n\r\nexport class UsageTapClient {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: URL;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultFeature?: string;\r\n private readonly defaultTags?: string[];\r\n private readonly defaultHeaders: HeadersDict;\r\n private readonly retryDefaults: ResolvedRetryOptions;\r\n private readonly idempotencyGenerator: () => string;\r\n private readonly logFn?: (entry: UsageTapLogEntry) => void;\r\n private readonly authHeader: typeof AUTH_HEADER | typeof API_KEY_HEADER;\r\n private readonly autoIdempotency: boolean;\r\n\r\n constructor(options: UsageTapClientOptions) {\r\n if (!options) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient options are required\"\r\n );\r\n }\r\n\r\n if (!options.apiKey) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires an apiKey\"\r\n );\r\n }\r\n\r\n if (!options.baseUrl) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires a baseUrl\"\r\n );\r\n }\r\n\r\n if (HAS_WINDOW && !options.allowBrowser) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BROWSER_RUNTIME\",\r\n \"UsageTapClient is designed for server-side environments. Pass allowBrowser=true only for testing.\"\r\n );\r\n }\r\n\r\n const fetchCandidate = options.fetchImpl ?? globalThis.fetch;\r\n if (typeof fetchCandidate !== \"function\") {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"A global fetch implementation was not found. Pass fetchImpl in UsageTapClientOptions.\"\r\n );\r\n }\r\n\r\n const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);\r\n this.baseUrl = new URL(normalizedBaseUrl);\r\n this.apiKey = options.apiKey;\r\n this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);\r\n this.defaultFeature = options.defaultFeature;\r\n this.defaultTags = options.defaultTags?.length\r\n ? dedupeStrings(options.defaultTags)\r\n : undefined;\r\n this.defaultHeaders = options.headers\r\n ? normalizeHeaderDictionary(options.headers)\r\n : {};\r\n this.retryDefaults = resolveRetryOptions(options.retries);\r\n this.idempotencyGenerator =\r\n options.idempotencyGenerator ?? createIdempotencyKey;\r\n this.logFn = options.onLog;\r\n this.authHeader = options.useApiKeyHeader ? API_KEY_HEADER : AUTH_HEADER;\r\n this.autoIdempotency = options.autoIdempotency ?? true;\r\n }\r\n\r\n async beginCall(\r\n request: BeginCallRequest,\r\n options: BeginCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<BeginCallResponseBody>> {\r\n const idempotencyKey =\r\n request.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const payload: BeginCallRequest = {\r\n ...request,\r\n feature: request.feature ?? this.defaultFeature,\r\n tags: this.mergeTags(request.tags),\r\n } satisfies BeginCallRequest;\r\n if (idempotencyKey) {\r\n payload.idempotency = idempotencyKey;\r\n }\r\n\r\n const response = await this.request<BeginCallResponseBody>(\r\n CALL_BEGIN_PATH,\r\n payload,\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async endCall(\r\n request: EndCallRequest,\r\n options: EndCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<EndCallResponseBody>> {\r\n if (!request?.callId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"endCall requires callId\"\r\n );\r\n }\r\n\r\n const payload = { ...request } satisfies EndCallRequest;\r\n const response = await this.request<EndCallResponseBody>(\r\n CALL_END_PATH,\r\n payload,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async checkUsage(\r\n request: CheckUsageRequest,\r\n options: CheckUsageOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"checkUsage requires customerId\"\r\n );\r\n }\r\n\r\n const path = CHECK_USAGE_PATH.replace(\r\n \"{customerId}\",\r\n encodeURIComponent(request.customerId)\r\n );\r\n const response = await this.requestGet<CheckUsageResponseBody>(\r\n path,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async createCustomer(\r\n request: CreateCustomerRequest,\r\n options: CreateCustomerOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"createCustomer requires customerId\"\r\n );\r\n }\r\n\r\n const idempotencyKey =\r\n options.idempotencyKey ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n\r\n const response = await this.request<CreateCustomerResponseBody>(\r\n CREATE_CUSTOMER_PATH,\r\n { ...request },\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async changePlan(\r\n request: ChangePlanRequest,\r\n options: ChangePlanOptions = {}\r\n ): Promise<UsageTapSuccessResponse<ChangePlanResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"changePlan requires customerId\"\r\n );\r\n }\r\n\r\n if (!request?.planId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"changePlan requires planId\"\r\n );\r\n }\r\n\r\n const path = CHANGE_PLAN_PATH.replace(\r\n \"{customerId}\",\r\n encodeURIComponent(request.customerId)\r\n );\r\n\r\n const idempotencyKey =\r\n options.idempotencyKey ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n\r\n const payload: Record<string, unknown> = {\r\n planId: request.planId,\r\n strategy: request.strategy ?? \"IMMEDIATE_RESET\",\r\n };\r\n\r\n const response = await this.request<ChangePlanResponseBody>(\r\n path,\r\n payload,\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async withUsage<T>(\r\n beginRequest: BeginCallRequest,\r\n handler: (context: WithUsageContext) => Promise<T>,\r\n options: WithUsageOptions = {}\r\n ): Promise<T> {\r\n const idempotencyKey =\r\n beginRequest.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const beginPayload = idempotencyKey\r\n ? { ...beginRequest, idempotency: idempotencyKey }\r\n : { ...beginRequest };\r\n const beginResponse = await this.beginCall(beginPayload, options);\r\n\r\n let usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const initialStripeCustomerId =\r\n typeof beginResponse.data.stripeCustomerId === \"string\"\r\n ? beginResponse.data.stripeCustomerId\r\n : typeof beginRequest.stripeCustomerId === \"string\"\r\n ? beginRequest.stripeCustomerId\r\n : undefined;\r\n if (initialStripeCustomerId) {\r\n usage = { ...usage, stripeCustomerId: initialStripeCustomerId };\r\n }\r\n let errorPayload: EndCallRequest[\"error\"] | undefined;\r\n let handlerResult: T | undefined;\r\n let handlerError: unknown;\r\n let endCallError: unknown;\r\n\r\n const context: WithUsageContext = {\r\n begin: beginResponse,\r\n setUsage: (u) => {\r\n usage = { ...usage, ...u };\r\n },\r\n setError: (err) => {\r\n errorPayload = err;\r\n },\r\n };\r\n\r\n try {\r\n handlerResult = await handler(context);\r\n } catch (error) {\r\n handlerError = error;\r\n if (!errorPayload) {\r\n errorPayload = {\r\n code: options.defaultErrorCode ?? \"VENDOR_ERROR\",\r\n message: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n } finally {\r\n try {\r\n await this.endCall(\r\n {\r\n callId: beginResponse.data.callId,\r\n ...(usage as Partial<Omit<EndCallRequest, \"callId\" | \"error\">>),\r\n error: errorPayload,\r\n },\r\n {\r\n ...options,\r\n correlationId: beginResponse.correlationId,\r\n }\r\n );\r\n } catch (error) {\r\n endCallError = error;\r\n }\r\n }\r\n\r\n if (handlerError) {\r\n throw handlerError;\r\n }\r\n\r\n if (endCallError) {\r\n throw wrapEndCallError(endCallError, beginResponse.correlationId);\r\n }\r\n\r\n return handlerResult as T;\r\n }\r\n\r\n private async request<T>(\r\n path: string,\r\n payload: unknown,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const body = payload !== undefined ? JSON.stringify(payload) : undefined;\r\n const headers = this.composeHeaders(body, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"POST\",\r\n headers,\r\n body,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async requestGet<T>(\r\n path: string,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const headers = this.composeHeaders(undefined, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"GET\",\r\n headers,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async performFetch<T>(init: {\r\n url: string;\r\n method: string;\r\n headers: HeadersDict;\r\n body?: string;\r\n signal?: AbortSignal;\r\n }): Promise<UsageTapSuccessResponse<T>> {\r\n let response: Response;\r\n try {\r\n response = await this.fetchImpl(init.url, {\r\n method: init.method,\r\n headers: init.headers,\r\n body: init.body,\r\n signal: init.signal,\r\n });\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"Failed to reach UsageTap\",\r\n {\r\n retryable: true,\r\n cause: error,\r\n }\r\n );\r\n }\r\n\r\n const correlationId = response.headers.get(CORRELATION_HEADER) ?? undefined;\r\n const text = await response.text();\r\n let payload: EnvelopeShape | undefined;\r\n\r\n if (text) {\r\n try {\r\n payload = JSON.parse(text) as EnvelopeShape;\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap returned invalid JSON\",\r\n {\r\n retryable: false,\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n throw this.toHttpError(response.status, payload, correlationId);\r\n }\r\n\r\n if (!payload?.result || payload.result.status !== \"ACCEPTED\") {\r\n throw this.toApiError(payload, correlationId);\r\n }\r\n\r\n const resolvedCorrelation = payload.correlationId ?? correlationId;\r\n if (\r\n payload.data === undefined ||\r\n payload.data === null ||\r\n !resolvedCorrelation\r\n ) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap response missing data or correlationId\",\r\n {\r\n correlationId: resolvedCorrelation ?? correlationId,\r\n }\r\n );\r\n }\r\n\r\n return {\r\n result: {\r\n status: payload.result.status as \"ACCEPTED\",\r\n code: payload.result.code,\r\n message: payload.result.message,\r\n timestamp: payload.result.timestamp,\r\n },\r\n data: payload.data as T,\r\n correlationId: resolvedCorrelation,\r\n } satisfies UsageTapSuccessResponse<T>;\r\n }\r\n\r\n private composeHeaders(\r\n body: string | undefined,\r\n options: InternalRequestOptions\r\n ): HeadersDict {\r\n const headers: HeadersDict = {\r\n ...this.defaultHeaders,\r\n [SDK_HEADER]: `js/${SDK_VERSION}`,\r\n \"content-type\": \"application/json\",\r\n accept: CANONICAL_MEDIA_TYPE,\r\n };\r\n\r\n if (!HAS_WINDOW) {\r\n // Browsers forbid setting user-agent; only attach it server-side.\r\n headers[\"user-agent\"] = `${USER_AGENT}/${SDK_VERSION}`;\r\n }\r\n\r\n if (this.authHeader === API_KEY_HEADER) {\r\n headers[API_KEY_HEADER] = this.apiKey;\r\n } else {\r\n headers[AUTH_HEADER] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n if (options.idempotencyKey) {\r\n headers[IDEMPOTENCY_HEADER] = options.idempotencyKey;\r\n }\r\n\r\n if (options.correlationId) {\r\n headers[CORRELATION_HEADER] = options.correlationId;\r\n }\r\n\r\n if (!body) {\r\n delete headers[\"content-type\"];\r\n }\r\n\r\n if (options.headers) {\r\n Object.assign(headers, normalizeHeaderDictionary(options.headers));\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n private log(entry: UsageTapLogEntry): void {\r\n this.logFn?.(entry);\r\n }\r\n\r\n private mergeTags(tags?: string[]): string[] | undefined {\r\n if (!tags && !this.defaultTags) {\r\n return undefined;\r\n }\r\n\r\n const combined = [...(this.defaultTags ?? []), ...(tags ?? [])].filter(\r\n Boolean\r\n );\r\n return combined.length ? dedupeStrings(combined) : undefined;\r\n }\r\n\r\n private shouldRetry(error: unknown): boolean {\r\n if (isUsageTapError(error)) {\r\n return Boolean(error.retryable);\r\n }\r\n\r\n if (error instanceof Error && error.name === \"AbortError\") {\r\n return false;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private toHttpError(\r\n status: number,\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const code = mapStatusToErrorCode(status);\r\n const retryable = isRetryableStatus(status);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n `UsageTap responded with HTTP ${status}`;\r\n\r\n return new UsageTapError(code, message, {\r\n status,\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n\r\n private toApiError(\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const normalizedCode =\r\n payload?.error?.code ?? payload?.result?.code ?? \"UNKNOWN\";\r\n const retryable = isRetryableApiCode(normalizedCode);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n \"UsageTap reported an error\";\r\n\r\n return new UsageTapError(mapApiCodeToError(normalizedCode), message, {\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n}\r\n\r\nfunction mapStatusToErrorCode(status: number): UsageTapErrorCode {\r\n if (status === 401 || status === 403) return \"USAGETAP_AUTH_ERROR\";\r\n if (status === 400 || status === 404 || status === 409)\r\n return \"USAGETAP_BAD_REQUEST\";\r\n if (status === 429) return \"USAGETAP_RATE_LIMITED\";\r\n if (status >= 500) return \"USAGETAP_SERVER_ERROR\";\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction isRetryableStatus(status: number): boolean {\r\n return (\r\n status === 408 ||\r\n status === 425 ||\r\n status === 429 ||\r\n status === 500 ||\r\n status === 502 ||\r\n status === 503 ||\r\n status === 504\r\n );\r\n}\r\n\r\nfunction isRetryableApiCode(code: string): boolean {\r\n const normalized = code.toUpperCase();\r\n return (\r\n normalized.includes(\"TRANSIENT\") ||\r\n normalized.includes(\"RETRY\") ||\r\n normalized.includes(\"TIMEOUT\") ||\r\n normalized.includes(\"THROTTLE\") ||\r\n normalized.includes(\"RATE_LIMIT\")\r\n );\r\n}\r\n\r\nfunction mapApiCodeToError(code: string): UsageTapErrorCode {\r\n const normalized = code.toUpperCase();\r\n if (normalized.includes(\"AUTH\") || normalized.includes(\"TOKEN\")) {\r\n return \"USAGETAP_AUTH_ERROR\";\r\n }\r\n if (normalized.includes(\"RATE\") || normalized.includes(\"THROTTLE\")) {\r\n return \"USAGETAP_RATE_LIMITED\";\r\n }\r\n if (normalized.includes(\"SERVER\") || normalized.includes(\"TRANSIENT\")) {\r\n return \"USAGETAP_SERVER_ERROR\";\r\n }\r\n if (\r\n normalized.includes(\"IDEMPOTENCY\") ||\r\n normalized.includes(\"VALIDATION\") ||\r\n normalized.includes(\"REQUEST\")\r\n ) {\r\n return \"USAGETAP_BAD_REQUEST\";\r\n }\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction sanitizeDetails(\r\n payload: EnvelopeShape | undefined\r\n): Record<string, unknown> | undefined {\r\n if (!payload) return undefined;\r\n const details: Record<string, unknown> = {};\r\n if (payload.result) details.result = payload.result;\r\n if (payload.error) details.error = payload.error;\r\n return Object.keys(details).length ? details : undefined;\r\n}\r\n\r\nfunction normalizeBaseUrl(baseUrl: string): string {\r\n const trimmed = baseUrl.trim();\r\n if (!trimmed) return trimmed;\r\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\r\n}\r\n\r\nfunction normalizeHeaderDictionary(dict: Record<string, string>): HeadersDict {\r\n return Object.keys(dict).reduce<HeadersDict>((acc, key) => {\r\n acc[key.toLowerCase()] = dict[key];\r\n return acc;\r\n }, {});\r\n}\r\n\r\nfunction dedupeStrings(values: string[]): string[] {\r\n return Array.from(\r\n new Set(values.map((value) => value.trim()).filter(Boolean))\r\n );\r\n}\r\n\r\nfunction wrapFetchImplementation(\r\n fetchCandidate: typeof fetch,\r\n preferGlobalContext: boolean\r\n): typeof fetch {\r\n const target = preferGlobalContext ? globalThis : undefined;\r\n return ((...args: Parameters<typeof fetch>) =>\r\n target\r\n ? Reflect.apply(fetchCandidate, target, args)\r\n : fetchCandidate(...args)) as typeof fetch;\r\n}\r\n\r\nfunction wrapEndCallError(\r\n error: unknown,\r\n correlationId?: string\r\n): UsageTapError {\r\n if (isUsageTapError(error)) {\r\n return new UsageTapError(\"USAGETAP_END_CALL_ERROR\", error.message, {\r\n correlationId: error.correlationId ?? correlationId,\r\n details: error.details,\r\n cause: error,\r\n });\r\n }\r\n\r\n return new UsageTapError(\r\n \"USAGETAP_END_CALL_ERROR\",\r\n \"Failed to finalize UsageTap call\",\r\n {\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n}\r\n","import { UsageTapClient } from \"../client\";\r\nimport type { BeginCallRequest, EndCallRequest } from \"../types\";\r\n\r\nexport interface WrapFetchContext extends Omit<BeginCallRequest, \"idempotency\"> {\r\n customerId: string;\r\n}\r\n\r\nexport interface WrapFetchOptions {\r\n /**\r\n * Context for UsageTap begin calls.\r\n * Can be overridden per-request via special headers.\r\n */\r\n defaultContext: WrapFetchContext;\r\n \r\n /**\r\n * Optional custom fetch implementation to wrap.\r\n * Defaults to global fetch.\r\n */\r\n baseFetch?: typeof fetch;\r\n \r\n /**\r\n * Generate idempotency keys automatically if not provided.\r\n * Default: true\r\n */\r\n autoIdempotency?: boolean;\r\n \r\n /**\r\n * Detect OpenAI-compatible endpoints by URL pattern.\r\n * Default: detects /v1/chat/completions and /v1/responses\r\n */\r\n isOpenAIEndpoint?: (url: string) => boolean;\r\n}\r\n\r\ninterface CallState {\r\n callId: string;\r\n correlationId?: string;\r\n usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>;\r\n finalized: boolean;\r\n}\r\n\r\ntype JsonRecord = Record<string, unknown>;\r\n\r\nfunction isJsonRecord(value: unknown): value is JsonRecord {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction readString(value: unknown): string | undefined {\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nfunction readNumber(value: unknown): number | undefined {\r\n return typeof value === \"number\" ? value : undefined;\r\n}\r\n\r\nfunction parseJsonRecord(text: string): JsonRecord | undefined {\r\n try {\r\n const parsed = JSON.parse(text) as unknown;\r\n return isJsonRecord(parsed) ? parsed : undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction parseStringArray(value: string): string[] | undefined {\r\n try {\r\n const parsed = JSON.parse(value) as unknown;\r\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\r\n return parsed;\r\n }\r\n } catch {\r\n return undefined;\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Wraps a fetch implementation to automatically instrument OpenAI API calls\r\n * with UsageTap begin/end tracking.\r\n * \r\n * Example:\r\n * ```ts\r\n * const wrappedFetch = wrapFetch(usageTap, {\r\n * defaultContext: { customerId: \"cust_123\", feature: \"chat\" }\r\n * });\r\n * \r\n * const openai = new OpenAI({\r\n * apiKey: process.env.OPENAI_API_KEY!,\r\n * fetch: wrappedFetch,\r\n * });\r\n * ```\r\n */\r\nexport function wrapFetch(\r\n usageTap: UsageTapClient,\r\n options: WrapFetchOptions,\r\n): typeof fetch {\r\n const {\r\n defaultContext,\r\n baseFetch = globalThis.fetch,\r\n autoIdempotency = true,\r\n isOpenAIEndpoint = defaultIsOpenAIEndpoint,\r\n } = options;\r\n\r\n return async function wrappedFetch(\r\n input: string | URL | Request,\r\n init?: RequestInit,\r\n ): Promise<Response> {\r\n const url = typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\r\n \r\n // Only intercept OpenAI endpoints\r\n if (!isOpenAIEndpoint(url)) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Parse request body to extract context overrides and detect streaming\r\n let body: JsonRecord | undefined;\r\n let isStreaming = false;\r\n const contextOverride: Partial<WrapFetchContext> = {};\r\n\r\n try {\r\n if (init?.body && typeof init.body === \"string\") {\r\n const parsedBody = parseJsonRecord(init.body);\r\n if (!parsedBody) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n body = parsedBody;\r\n isStreaming = parsedBody.stream === true;\r\n\r\n // Check for context overrides in special headers\r\n const headers = new Headers(init.headers);\r\n const customerIdHeader = headers.get(\"x-usagetap-customer-id\");\r\n const featureHeader = headers.get(\"x-usagetap-feature\");\r\n const tagsHeader = headers.get(\"x-usagetap-tags\");\r\n\r\n if (customerIdHeader) {\r\n contextOverride.customerId = customerIdHeader;\r\n }\r\n if (featureHeader) {\r\n contextOverride.feature = featureHeader;\r\n }\r\n if (tagsHeader) {\r\n const tags = parseStringArray(tagsHeader);\r\n if (tags) {\r\n contextOverride.tags = tags;\r\n }\r\n }\r\n }\r\n } catch {\r\n // If body parsing fails, proceed without interception\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Merge context\r\n const context: BeginCallRequest = {\r\n ...defaultContext,\r\n ...contextOverride,\r\n idempotency: autoIdempotency ? crypto.randomUUID() : undefined,\r\n };\r\n\r\n // Begin the call\r\n let callState: CallState | undefined;\r\n try {\r\n const beginResponse = await usageTap.beginCall(context);\r\n callState = {\r\n callId: beginResponse.data.callId,\r\n correlationId: beginResponse.correlationId,\r\n usage: {},\r\n finalized: false,\r\n };\r\n } catch (error) {\r\n // If begin fails, proceed with original fetch but log error\r\n console.error(\"[wrapFetch] Failed to begin call:\", error);\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Add correlation header to vendor request\r\n const modifiedInit = {\r\n ...init,\r\n headers: {\r\n ...init?.headers,\r\n \"x-usage-correlation-id\": callState.correlationId || \"\",\r\n },\r\n };\r\n\r\n // Call the vendor API\r\n try {\r\n const response = await baseFetch(input, modifiedInit);\r\n \r\n if (isStreaming) {\r\n // Wrap streaming response\r\n return wrapStreamingResponse(response, callState, usageTap);\r\n } else {\r\n // Handle non-streaming response\r\n return await wrapNonStreamingResponse(response, callState, usageTap, body);\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // Vendor call failed\r\n await finalizeCall(callState, usageTap, {\r\n code: \"VENDOR_ERROR\",\r\n message,\r\n });\r\n throw error;\r\n }\r\n };\r\n}\r\n\r\nfunction defaultIsOpenAIEndpoint(url: string): boolean {\r\n return (\r\n url.includes(\"/v1/chat/completions\") ||\r\n url.includes(\"/v1/responses\") ||\r\n url.includes(\"/v1/embeddings\")\r\n );\r\n}\r\n\r\nasync function wrapNonStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n requestBody: JsonRecord | undefined,\r\n): Promise<Response> {\r\n // Clone response to read body\r\n const clonedResponse = response.clone();\r\n \r\n try {\r\n const parsed = await clonedResponse.json();\r\n const usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n\r\n if (isJsonRecord(parsed)) {\r\n const usageBlock = parsed.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n usage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n usage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n usage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n usage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const modelFromResponse = readString(parsed.model);\r\n if (modelFromResponse) {\r\n usage.modelUsed = modelFromResponse;\r\n }\r\n }\r\n\r\n if (!usage.modelUsed && requestBody) {\r\n const requestModel = readString(requestBody.model);\r\n if (requestModel) {\r\n usage.modelUsed = requestModel;\r\n }\r\n }\r\n\r\n // Finalize the call\r\n await finalizeCall(callState, usageTap, undefined, usage);\r\n\r\n return response;\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // If we can't parse response, finalize with error\r\n await finalizeCall(callState, usageTap, {\r\n code: \"RESPONSE_PARSE_ERROR\",\r\n message,\r\n });\r\n return response;\r\n }\r\n}\r\n\r\nfunction wrapStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n): Response {\r\n if (!response.body) {\r\n // No body to stream, finalize now\r\n void finalizeCall(callState, usageTap, {\r\n code: \"NO_RESPONSE_BODY\",\r\n message: \"Streaming response has no body\",\r\n });\r\n return response;\r\n }\r\n\r\n const originalBody = response.body;\r\n const accumulatedUsage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const textDecoder = new TextDecoder();\r\n\r\n const transformStream = new TransformStream({\r\n transform(chunk: Uint8Array, controller) {\r\n controller.enqueue(chunk);\r\n \r\n // Try to parse usage from SSE data\r\n try {\r\n const text = textDecoder.decode(chunk, { stream: true });\r\n const lines = text.split(\"\\n\");\r\n \r\n for (const line of lines) {\r\n if (line.startsWith(\"data: \")) {\r\n const data = line.slice(6);\r\n if (data === \"[DONE]\") continue;\r\n \r\n const parsedRecord = parseJsonRecord(data);\r\n if (!parsedRecord) {\r\n continue;\r\n }\r\n\r\n const usageBlock = parsedRecord.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n accumulatedUsage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n accumulatedUsage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n accumulatedUsage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n accumulatedUsage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const model = readString(parsedRecord.model);\r\n if (model) {\r\n accumulatedUsage.modelUsed = model;\r\n }\r\n }\r\n }\r\n } catch {\r\n // Ignore decode errors\r\n }\r\n },\r\n\r\n async flush() {\r\n // Stream completed successfully\r\n await finalizeCall(callState, usageTap, undefined, accumulatedUsage);\r\n },\r\n });\r\n\r\n // Handle stream errors and cancellation\r\n const wrappedBody = originalBody.pipeThrough(transformStream);\r\n \r\n // Note: Response doesn't have signal property, abort handling happens via stream closure\r\n\r\n return new Response(wrappedBody, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n });\r\n}\r\n\r\nasync function finalizeCall(\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n error?: { code: string; message: string },\r\n usage?: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>,\r\n): Promise<void> {\r\n if (callState.finalized) return;\r\n callState.finalized = true;\r\n\r\n try {\r\n await usageTap.endCall({\r\n callId: callState.callId,\r\n ...callState.usage,\r\n ...usage,\r\n error,\r\n });\r\n } catch (err) {\r\n console.error(\"[wrapFetch] Failed to finalize call:\", err);\r\n }\r\n}\r\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UsageTapClient, B as BeginCallRequest } from './client-
|
|
2
|
-
export { A as AllowedEntitlements,
|
|
1
|
+
import { U as UsageTapClient, B as BeginCallRequest } from './client-nU5xk2pN.cjs';
|
|
2
|
+
export { A as AllowedEntitlements, o as BalanceSummary, c as BeginCallOptions, b as BeginCallResponseBody, i as ChangePlanOptions, j as ChangePlanRequest, k as ChangePlanResponseBody, l as ChangePlanStrategy, f as CheckUsageOptions, g as CheckUsageRequest, h as CheckUsageResponseBody, C as CreateCustomerOptions, d as CreateCustomerRequest, e as CreateCustomerResponseBody, m as EndCallOptions, E as EndCallRequest, n as EndCallResponseBody, p as EntitlementHints, I as IdempotencyMetadata, L as LimitType, q as MeterSnapshot, M as MeterSummary, r as MeteredUsage, D as ModelHints, P as PlanSummary, R as RemainingRatios, s as RequestedEntitlements, t as RetryOptions, S as SubscriptionSnapshot, u as UsageTapClientOptions, v as UsageTapErrorResponse, y as UsageTapLogEntry, w as UsageTapResultEnvelope, x as UsageTapResultStatus, a as UsageTapSuccessResponse, V as VendorHints, z as WithUsageContext, W as WithUsageOptions } from './client-nU5xk2pN.cjs';
|
|
3
3
|
|
|
4
4
|
type UsageTapErrorCode = "USAGETAP_BROWSER_RUNTIME" | "USAGETAP_AUTH_ERROR" | "USAGETAP_BAD_REQUEST" | "USAGETAP_INVALID_RESPONSE" | "USAGETAP_NETWORK_ERROR" | "USAGETAP_RATE_LIMITED" | "USAGETAP_SERVER_ERROR" | "USAGETAP_RETRY_EXHAUSTED" | "USAGETAP_END_CALL_ERROR";
|
|
5
5
|
interface UsageTapErrorInit {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { U as UsageTapClient, B as BeginCallRequest } from './client-
|
|
2
|
-
export { A as AllowedEntitlements,
|
|
1
|
+
import { U as UsageTapClient, B as BeginCallRequest } from './client-nU5xk2pN.js';
|
|
2
|
+
export { A as AllowedEntitlements, o as BalanceSummary, c as BeginCallOptions, b as BeginCallResponseBody, i as ChangePlanOptions, j as ChangePlanRequest, k as ChangePlanResponseBody, l as ChangePlanStrategy, f as CheckUsageOptions, g as CheckUsageRequest, h as CheckUsageResponseBody, C as CreateCustomerOptions, d as CreateCustomerRequest, e as CreateCustomerResponseBody, m as EndCallOptions, E as EndCallRequest, n as EndCallResponseBody, p as EntitlementHints, I as IdempotencyMetadata, L as LimitType, q as MeterSnapshot, M as MeterSummary, r as MeteredUsage, D as ModelHints, P as PlanSummary, R as RemainingRatios, s as RequestedEntitlements, t as RetryOptions, S as SubscriptionSnapshot, u as UsageTapClientOptions, v as UsageTapErrorResponse, y as UsageTapLogEntry, w as UsageTapResultEnvelope, x as UsageTapResultStatus, a as UsageTapSuccessResponse, V as VendorHints, z as WithUsageContext, W as WithUsageOptions } from './client-nU5xk2pN.js';
|
|
3
3
|
|
|
4
4
|
type UsageTapErrorCode = "USAGETAP_BROWSER_RUNTIME" | "USAGETAP_AUTH_ERROR" | "USAGETAP_BAD_REQUEST" | "USAGETAP_INVALID_RESPONSE" | "USAGETAP_NETWORK_ERROR" | "USAGETAP_RATE_LIMITED" | "USAGETAP_SERVER_ERROR" | "USAGETAP_RETRY_EXHAUSTED" | "USAGETAP_END_CALL_ERROR";
|
|
5
5
|
interface UsageTapErrorInit {
|
package/dist/index.mjs
CHANGED
|
@@ -118,6 +118,7 @@ var CALL_BEGIN_PATH = "call_begin";
|
|
|
118
118
|
var CALL_END_PATH = "call_end";
|
|
119
119
|
var CHECK_USAGE_PATH = "customers/{customerId}/usage";
|
|
120
120
|
var CREATE_CUSTOMER_PATH = "customers";
|
|
121
|
+
var CHANGE_PLAN_PATH = "customers/{customerId}/change_plan";
|
|
121
122
|
var AUTH_HEADER = "authorization";
|
|
122
123
|
var API_KEY_HEADER = "x-api-key";
|
|
123
124
|
var CORRELATION_HEADER = "x-usage-correlation-id";
|
|
@@ -125,7 +126,7 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
|
125
126
|
var SDK_HEADER = "x-usage-sdk";
|
|
126
127
|
var USER_AGENT = "UsageTapClient";
|
|
127
128
|
var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
|
|
128
|
-
var SDK_VERSION = "0.
|
|
129
|
+
var SDK_VERSION = "0.7.0" ;
|
|
129
130
|
var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
|
|
130
131
|
var UsageTapClient = class {
|
|
131
132
|
apiKey;
|
|
@@ -174,7 +175,7 @@ var UsageTapClient = class {
|
|
|
174
175
|
const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);
|
|
175
176
|
this.baseUrl = new URL(normalizedBaseUrl);
|
|
176
177
|
this.apiKey = options.apiKey;
|
|
177
|
-
this.fetchImpl = fetchCandidate;
|
|
178
|
+
this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);
|
|
178
179
|
this.defaultFeature = options.defaultFeature;
|
|
179
180
|
this.defaultTags = options.defaultTags?.length ? dedupeStrings(options.defaultTags) : void 0;
|
|
180
181
|
this.defaultHeaders = options.headers ? normalizeHeaderDictionary(options.headers) : {};
|
|
@@ -254,6 +255,38 @@ var UsageTapClient = class {
|
|
|
254
255
|
);
|
|
255
256
|
return response;
|
|
256
257
|
}
|
|
258
|
+
async changePlan(request, options = {}) {
|
|
259
|
+
if (!request?.customerId) {
|
|
260
|
+
throw new UsageTapError(
|
|
261
|
+
"USAGETAP_BAD_REQUEST",
|
|
262
|
+
"changePlan requires customerId"
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
if (!request?.planId) {
|
|
266
|
+
throw new UsageTapError(
|
|
267
|
+
"USAGETAP_BAD_REQUEST",
|
|
268
|
+
"changePlan requires planId"
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
const path = CHANGE_PLAN_PATH.replace(
|
|
272
|
+
"{customerId}",
|
|
273
|
+
encodeURIComponent(request.customerId)
|
|
274
|
+
);
|
|
275
|
+
const idempotencyKey = options.idempotencyKey ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
276
|
+
const payload = {
|
|
277
|
+
planId: request.planId,
|
|
278
|
+
strategy: request.strategy ?? "IMMEDIATE_RESET"
|
|
279
|
+
};
|
|
280
|
+
const response = await this.request(
|
|
281
|
+
path,
|
|
282
|
+
payload,
|
|
283
|
+
{
|
|
284
|
+
...options,
|
|
285
|
+
idempotencyKey
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
return response;
|
|
289
|
+
}
|
|
257
290
|
async withUsage(beginRequest, handler, options = {}) {
|
|
258
291
|
const idempotencyKey = beginRequest.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
259
292
|
const beginPayload = idempotencyKey ? { ...beginRequest, idempotency: idempotencyKey } : { ...beginRequest };
|
|
@@ -619,6 +652,10 @@ function dedupeStrings(values) {
|
|
|
619
652
|
new Set(values.map((value) => value.trim()).filter(Boolean))
|
|
620
653
|
);
|
|
621
654
|
}
|
|
655
|
+
function wrapFetchImplementation(fetchCandidate, preferGlobalContext) {
|
|
656
|
+
const target = preferGlobalContext ? globalThis : void 0;
|
|
657
|
+
return ((...args) => target ? Reflect.apply(fetchCandidate, target, args) : fetchCandidate(...args));
|
|
658
|
+
}
|
|
622
659
|
function wrapEndCallError(error, correlationId) {
|
|
623
660
|
if (isUsageTapError(error)) {
|
|
624
661
|
return new UsageTapError("USAGETAP_END_CALL_ERROR", error.message, {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/retry.ts","../src/client.ts","../src/adapters/fetch-wrapper.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export type UsageTapErrorCode =\r\n | \"USAGETAP_BROWSER_RUNTIME\"\r\n | \"USAGETAP_AUTH_ERROR\"\r\n | \"USAGETAP_BAD_REQUEST\"\r\n | \"USAGETAP_INVALID_RESPONSE\"\r\n | \"USAGETAP_NETWORK_ERROR\"\r\n | \"USAGETAP_RATE_LIMITED\"\r\n | \"USAGETAP_SERVER_ERROR\"\r\n | \"USAGETAP_RETRY_EXHAUSTED\"\r\n | \"USAGETAP_END_CALL_ERROR\";\r\n\r\nexport interface UsageTapErrorInit {\r\n status?: number;\r\n retryable?: boolean;\r\n correlationId?: string;\r\n details?: Record<string, unknown>;\r\n cause?: unknown;\r\n}\r\n\r\nexport class UsageTapError extends Error {\r\n public readonly code: UsageTapErrorCode;\r\n public readonly status?: number;\r\n public readonly retryable: boolean;\r\n public readonly correlationId?: string;\r\n public readonly details?: Record<string, unknown>;\r\n\r\n constructor(code: UsageTapErrorCode, message: string, init: UsageTapErrorInit = {}) {\r\n super(message, init.cause ? { cause: init.cause as Error } : undefined);\r\n this.name = \"UsageTapError\";\r\n this.code = code;\r\n this.status = init.status;\r\n this.retryable = init.retryable ?? false;\r\n this.correlationId = init.correlationId;\r\n this.details = init.details;\r\n }\r\n\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n code: this.code,\r\n status: this.status,\r\n retryable: this.retryable,\r\n correlationId: this.correlationId,\r\n details: this.details,\r\n };\r\n }\r\n}\r\n\r\nexport function isUsageTapError(error: unknown): error is UsageTapError {\r\n return error instanceof UsageTapError;\r\n}\r\n","export function createIdempotencyKey(): string {\r\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n\r\n const random = (): string => Math.random().toString(16).slice(2, 10);\r\n return `${random()}-${random()}`;\r\n}\r\n","import type { RetryOptions } from \"./types\";\r\n\r\nexport interface ResolvedRetryOptions {\r\n maxAttempts: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n jitterRatio: number;\r\n}\r\n\r\nconst DEFAULTS: ResolvedRetryOptions = {\r\n maxAttempts: 3,\r\n baseDelayMs: 250,\r\n maxDelayMs: 5000,\r\n jitterRatio: 0.2,\r\n};\r\n\r\nexport function resolveRetryOptions(\r\n base?: RetryOptions,\r\n override?: RetryOptions,\r\n): ResolvedRetryOptions {\r\n const merged = { ...DEFAULTS, ...base, ...override } satisfies ResolvedRetryOptions;\r\n return {\r\n maxAttempts: Math.max(1, Math.floor(merged.maxAttempts)),\r\n baseDelayMs: Math.max(0, merged.baseDelayMs),\r\n maxDelayMs: Math.max(merged.baseDelayMs, merged.maxDelayMs),\r\n jitterRatio: Math.min(Math.max(merged.jitterRatio, 0), 1),\r\n };\r\n}\r\n\r\nexport async function sleep(delayMs: number, signal?: AbortSignal): Promise<void> {\r\n if (delayMs <= 0) {\r\n signal?.throwIfAborted?.();\r\n return;\r\n }\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, delayMs);\r\n\r\n const cleanup = (): void => {\r\n clearTimeout(timer);\r\n signal?.removeEventListener(\"abort\", onAbort);\r\n };\r\n\r\n const onAbort = (): void => {\r\n cleanup();\r\n const abortError = new Error(\"Aborted\");\r\n abortError.name = \"AbortError\";\r\n reject(abortError);\r\n };\r\n\r\n if (signal) {\r\n if (signal.aborted) {\r\n onAbort();\r\n return;\r\n }\r\n signal.addEventListener(\"abort\", onAbort, { once: true });\r\n }\r\n });\r\n}\r\n\r\nexport function computeDelay(attempt: number, options: ResolvedRetryOptions): number {\r\n const exp = options.baseDelayMs * Math.pow(2, attempt - 1);\r\n const capped = Math.min(exp, options.maxDelayMs);\r\n const jitter = capped * options.jitterRatio;\r\n const min = capped - jitter;\r\n const max = capped + jitter;\r\n return Math.max(0, Math.random() * (max - min) + min);\r\n}\r\n\r\nexport async function runWithRetry<T>(\r\n operation: (attempt: number) => Promise<T>,\r\n options: ResolvedRetryOptions,\r\n shouldRetry: (error: unknown) => boolean,\r\n onSchedule?: (attempt: number, delayMs: number, error: unknown) => void,\r\n signal?: AbortSignal,\r\n): Promise<T> {\r\n let attempt = 0;\r\n let lastError: unknown;\r\n while (attempt < options.maxAttempts) {\r\n attempt += 1;\r\n signal?.throwIfAborted?.();\r\n\r\n try {\r\n return await operation(attempt);\r\n } catch (error) {\r\n lastError = error;\r\n if (attempt >= options.maxAttempts || !shouldRetry(error)) {\r\n throw error;\r\n }\r\n const delayMs = computeDelay(attempt, options);\r\n onSchedule?.(attempt, delayMs, error);\r\n await sleep(delayMs, signal);\r\n }\r\n }\r\n\r\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\r\n}\r\n","import type {\r\n BeginCallOptions,\r\n BeginCallRequest,\r\n BeginCallResponseBody,\r\n CreateCustomerOptions,\r\n CreateCustomerRequest,\r\n CreateCustomerResponseBody,\r\n CheckUsageOptions,\r\n CheckUsageRequest,\r\n CheckUsageResponseBody,\r\n EndCallOptions,\r\n EndCallRequest,\r\n EndCallResponseBody,\r\n UsageTapClientOptions,\r\n UsageTapLogEntry,\r\n UsageTapSuccessResponse,\r\n WithUsageContext,\r\n WithUsageOptions,\r\n} from \"./types\";\r\nimport {\r\n UsageTapError,\r\n type UsageTapErrorCode,\r\n isUsageTapError,\r\n} from \"./errors\";\r\nimport { createIdempotencyKey } from \"./idempotency\";\r\nimport {\r\n runWithRetry,\r\n resolveRetryOptions,\r\n type ResolvedRetryOptions,\r\n} from \"./retry\";\r\nimport type { RetryOptions } from \"./types\";\r\n\r\nconst CALL_BEGIN_PATH = \"call_begin\";\r\nconst CALL_END_PATH = \"call_end\";\r\nconst CHECK_USAGE_PATH = \"customers/{customerId}/usage\";\r\nconst CREATE_CUSTOMER_PATH = \"customers\";\r\nconst AUTH_HEADER = \"authorization\";\r\nconst API_KEY_HEADER = \"x-api-key\";\r\nconst CORRELATION_HEADER = \"x-usage-correlation-id\";\r\nconst IDEMPOTENCY_HEADER = \"idempotency-key\";\r\nconst SDK_HEADER = \"x-usage-sdk\";\r\nconst USER_AGENT = \"UsageTapClient\";\r\nconst CANONICAL_MEDIA_TYPE = \"application/vnd.usagetap.v1+json\";\r\n\r\ndeclare const __SDK_VERSION__: string | undefined;\r\nconst SDK_VERSION =\r\n typeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.1.0\";\r\nconst HAS_WINDOW =\r\n typeof globalThis !== \"undefined\" &&\r\n typeof (globalThis as Record<string, unknown>).window !== \"undefined\";\r\n\r\ntype HeadersDict = Record<string, string>;\r\n\r\ntype InternalRequestOptions = {\r\n signal?: AbortSignal;\r\n headers?: HeadersDict;\r\n retries?: RetryOptions;\r\n correlationId?: string;\r\n idempotencyKey?: string;\r\n};\r\n\r\ntype EnvelopeShape = {\r\n result?: {\r\n status?: string;\r\n code?: string;\r\n message?: string;\r\n timestamp?: string;\r\n };\r\n data?: unknown;\r\n error?: {\r\n code?: string;\r\n message?: string;\r\n details?: Record<string, unknown>;\r\n };\r\n correlationId?: string;\r\n};\r\n\r\nexport class UsageTapClient {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: URL;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultFeature?: string;\r\n private readonly defaultTags?: string[];\r\n private readonly defaultHeaders: HeadersDict;\r\n private readonly retryDefaults: ResolvedRetryOptions;\r\n private readonly idempotencyGenerator: () => string;\r\n private readonly logFn?: (entry: UsageTapLogEntry) => void;\r\n private readonly authHeader: typeof AUTH_HEADER | typeof API_KEY_HEADER;\r\n private readonly autoIdempotency: boolean;\r\n\r\n constructor(options: UsageTapClientOptions) {\r\n if (!options) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient options are required\"\r\n );\r\n }\r\n\r\n if (!options.apiKey) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires an apiKey\"\r\n );\r\n }\r\n\r\n if (!options.baseUrl) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires a baseUrl\"\r\n );\r\n }\r\n\r\n if (HAS_WINDOW && !options.allowBrowser) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BROWSER_RUNTIME\",\r\n \"UsageTapClient is designed for server-side environments. Pass allowBrowser=true only for testing.\"\r\n );\r\n }\r\n\r\n const fetchCandidate = options.fetchImpl ?? globalThis.fetch;\r\n if (typeof fetchCandidate !== \"function\") {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"A global fetch implementation was not found. Pass fetchImpl in UsageTapClientOptions.\"\r\n );\r\n }\r\n\r\n const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);\r\n this.baseUrl = new URL(normalizedBaseUrl);\r\n this.apiKey = options.apiKey;\r\n this.fetchImpl = fetchCandidate;\r\n this.defaultFeature = options.defaultFeature;\r\n this.defaultTags = options.defaultTags?.length\r\n ? dedupeStrings(options.defaultTags)\r\n : undefined;\r\n this.defaultHeaders = options.headers\r\n ? normalizeHeaderDictionary(options.headers)\r\n : {};\r\n this.retryDefaults = resolveRetryOptions(options.retries);\r\n this.idempotencyGenerator =\r\n options.idempotencyGenerator ?? createIdempotencyKey;\r\n this.logFn = options.onLog;\r\n this.authHeader = options.useApiKeyHeader ? API_KEY_HEADER : AUTH_HEADER;\r\n this.autoIdempotency = options.autoIdempotency ?? true;\r\n }\r\n\r\n async beginCall(\r\n request: BeginCallRequest,\r\n options: BeginCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<BeginCallResponseBody>> {\r\n const idempotencyKey =\r\n request.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const payload: BeginCallRequest = {\r\n ...request,\r\n feature: request.feature ?? this.defaultFeature,\r\n tags: this.mergeTags(request.tags),\r\n } satisfies BeginCallRequest;\r\n if (idempotencyKey) {\r\n payload.idempotency = idempotencyKey;\r\n }\r\n\r\n const response = await this.request<BeginCallResponseBody>(\r\n CALL_BEGIN_PATH,\r\n payload,\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async endCall(\r\n request: EndCallRequest,\r\n options: EndCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<EndCallResponseBody>> {\r\n if (!request?.callId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"endCall requires callId\"\r\n );\r\n }\r\n\r\n const payload = { ...request } satisfies EndCallRequest;\r\n const response = await this.request<EndCallResponseBody>(\r\n CALL_END_PATH,\r\n payload,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async checkUsage(\r\n request: CheckUsageRequest,\r\n options: CheckUsageOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"checkUsage requires customerId\"\r\n );\r\n }\r\n\r\n const path = CHECK_USAGE_PATH.replace(\r\n \"{customerId}\",\r\n encodeURIComponent(request.customerId)\r\n );\r\n const response = await this.requestGet<CheckUsageResponseBody>(\r\n path,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async createCustomer(\r\n request: CreateCustomerRequest,\r\n options: CreateCustomerOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"createCustomer requires customerId\"\r\n );\r\n }\r\n\r\n const idempotencyKey =\r\n options.idempotencyKey ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n\r\n const response = await this.request<CreateCustomerResponseBody>(\r\n CREATE_CUSTOMER_PATH,\r\n { ...request },\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async withUsage<T>(\r\n beginRequest: BeginCallRequest,\r\n handler: (context: WithUsageContext) => Promise<T>,\r\n options: WithUsageOptions = {}\r\n ): Promise<T> {\r\n const idempotencyKey =\r\n beginRequest.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const beginPayload = idempotencyKey\r\n ? { ...beginRequest, idempotency: idempotencyKey }\r\n : { ...beginRequest };\r\n const beginResponse = await this.beginCall(beginPayload, options);\r\n\r\n let usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const initialStripeCustomerId =\r\n typeof beginResponse.data.stripeCustomerId === \"string\"\r\n ? beginResponse.data.stripeCustomerId\r\n : typeof beginRequest.stripeCustomerId === \"string\"\r\n ? beginRequest.stripeCustomerId\r\n : undefined;\r\n if (initialStripeCustomerId) {\r\n usage = { ...usage, stripeCustomerId: initialStripeCustomerId };\r\n }\r\n let errorPayload: EndCallRequest[\"error\"] | undefined;\r\n let handlerResult: T | undefined;\r\n let handlerError: unknown;\r\n let endCallError: unknown;\r\n\r\n const context: WithUsageContext = {\r\n begin: beginResponse,\r\n setUsage: (u) => {\r\n usage = { ...usage, ...u };\r\n },\r\n setError: (err) => {\r\n errorPayload = err;\r\n },\r\n };\r\n\r\n try {\r\n handlerResult = await handler(context);\r\n } catch (error) {\r\n handlerError = error;\r\n if (!errorPayload) {\r\n errorPayload = {\r\n code: options.defaultErrorCode ?? \"VENDOR_ERROR\",\r\n message: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n } finally {\r\n try {\r\n await this.endCall(\r\n {\r\n callId: beginResponse.data.callId,\r\n ...(usage as Partial<Omit<EndCallRequest, \"callId\" | \"error\">>),\r\n error: errorPayload,\r\n },\r\n {\r\n ...options,\r\n correlationId: beginResponse.correlationId,\r\n }\r\n );\r\n } catch (error) {\r\n endCallError = error;\r\n }\r\n }\r\n\r\n if (handlerError) {\r\n throw handlerError;\r\n }\r\n\r\n if (endCallError) {\r\n throw wrapEndCallError(endCallError, beginResponse.correlationId);\r\n }\r\n\r\n return handlerResult as T;\r\n }\r\n\r\n private async request<T>(\r\n path: string,\r\n payload: unknown,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const body = payload !== undefined ? JSON.stringify(payload) : undefined;\r\n const headers = this.composeHeaders(body, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"POST\",\r\n headers,\r\n body,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async requestGet<T>(\r\n path: string,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const headers = this.composeHeaders(undefined, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"GET\",\r\n headers,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async performFetch<T>(init: {\r\n url: string;\r\n method: string;\r\n headers: HeadersDict;\r\n body?: string;\r\n signal?: AbortSignal;\r\n }): Promise<UsageTapSuccessResponse<T>> {\r\n let response: Response;\r\n try {\r\n response = await this.fetchImpl(init.url, {\r\n method: init.method,\r\n headers: init.headers,\r\n body: init.body,\r\n signal: init.signal,\r\n });\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"Failed to reach UsageTap\",\r\n {\r\n retryable: true,\r\n cause: error,\r\n }\r\n );\r\n }\r\n\r\n const correlationId = response.headers.get(CORRELATION_HEADER) ?? undefined;\r\n const text = await response.text();\r\n let payload: EnvelopeShape | undefined;\r\n\r\n if (text) {\r\n try {\r\n payload = JSON.parse(text) as EnvelopeShape;\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap returned invalid JSON\",\r\n {\r\n retryable: false,\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n throw this.toHttpError(response.status, payload, correlationId);\r\n }\r\n\r\n if (!payload?.result || payload.result.status !== \"ACCEPTED\") {\r\n throw this.toApiError(payload, correlationId);\r\n }\r\n\r\n const resolvedCorrelation = payload.correlationId ?? correlationId;\r\n if (\r\n payload.data === undefined ||\r\n payload.data === null ||\r\n !resolvedCorrelation\r\n ) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap response missing data or correlationId\",\r\n {\r\n correlationId: resolvedCorrelation ?? correlationId,\r\n }\r\n );\r\n }\r\n\r\n return {\r\n result: {\r\n status: payload.result.status as \"ACCEPTED\",\r\n code: payload.result.code,\r\n message: payload.result.message,\r\n timestamp: payload.result.timestamp,\r\n },\r\n data: payload.data as T,\r\n correlationId: resolvedCorrelation,\r\n } satisfies UsageTapSuccessResponse<T>;\r\n }\r\n\r\n private composeHeaders(\r\n body: string | undefined,\r\n options: InternalRequestOptions\r\n ): HeadersDict {\r\n const headers: HeadersDict = {\r\n ...this.defaultHeaders,\r\n [SDK_HEADER]: `js/${SDK_VERSION}`,\r\n \"content-type\": \"application/json\",\r\n accept: CANONICAL_MEDIA_TYPE,\r\n };\r\n\r\n if (!HAS_WINDOW) {\r\n // Browsers forbid setting user-agent; only attach it server-side.\r\n headers[\"user-agent\"] = `${USER_AGENT}/${SDK_VERSION}`;\r\n }\r\n\r\n if (this.authHeader === API_KEY_HEADER) {\r\n headers[API_KEY_HEADER] = this.apiKey;\r\n } else {\r\n headers[AUTH_HEADER] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n if (options.idempotencyKey) {\r\n headers[IDEMPOTENCY_HEADER] = options.idempotencyKey;\r\n }\r\n\r\n if (options.correlationId) {\r\n headers[CORRELATION_HEADER] = options.correlationId;\r\n }\r\n\r\n if (!body) {\r\n delete headers[\"content-type\"];\r\n }\r\n\r\n if (options.headers) {\r\n Object.assign(headers, normalizeHeaderDictionary(options.headers));\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n private log(entry: UsageTapLogEntry): void {\r\n this.logFn?.(entry);\r\n }\r\n\r\n private mergeTags(tags?: string[]): string[] | undefined {\r\n if (!tags && !this.defaultTags) {\r\n return undefined;\r\n }\r\n\r\n const combined = [...(this.defaultTags ?? []), ...(tags ?? [])].filter(\r\n Boolean\r\n );\r\n return combined.length ? dedupeStrings(combined) : undefined;\r\n }\r\n\r\n private shouldRetry(error: unknown): boolean {\r\n if (isUsageTapError(error)) {\r\n return Boolean(error.retryable);\r\n }\r\n\r\n if (error instanceof Error && error.name === \"AbortError\") {\r\n return false;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private toHttpError(\r\n status: number,\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const code = mapStatusToErrorCode(status);\r\n const retryable = isRetryableStatus(status);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n `UsageTap responded with HTTP ${status}`;\r\n\r\n return new UsageTapError(code, message, {\r\n status,\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n\r\n private toApiError(\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const normalizedCode =\r\n payload?.error?.code ?? payload?.result?.code ?? \"UNKNOWN\";\r\n const retryable = isRetryableApiCode(normalizedCode);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n \"UsageTap reported an error\";\r\n\r\n return new UsageTapError(mapApiCodeToError(normalizedCode), message, {\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n}\r\n\r\nfunction mapStatusToErrorCode(status: number): UsageTapErrorCode {\r\n if (status === 401 || status === 403) return \"USAGETAP_AUTH_ERROR\";\r\n if (status === 400 || status === 404 || status === 409)\r\n return \"USAGETAP_BAD_REQUEST\";\r\n if (status === 429) return \"USAGETAP_RATE_LIMITED\";\r\n if (status >= 500) return \"USAGETAP_SERVER_ERROR\";\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction isRetryableStatus(status: number): boolean {\r\n return (\r\n status === 408 ||\r\n status === 425 ||\r\n status === 429 ||\r\n status === 500 ||\r\n status === 502 ||\r\n status === 503 ||\r\n status === 504\r\n );\r\n}\r\n\r\nfunction isRetryableApiCode(code: string): boolean {\r\n const normalized = code.toUpperCase();\r\n return (\r\n normalized.includes(\"TRANSIENT\") ||\r\n normalized.includes(\"RETRY\") ||\r\n normalized.includes(\"TIMEOUT\") ||\r\n normalized.includes(\"THROTTLE\") ||\r\n normalized.includes(\"RATE_LIMIT\")\r\n );\r\n}\r\n\r\nfunction mapApiCodeToError(code: string): UsageTapErrorCode {\r\n const normalized = code.toUpperCase();\r\n if (normalized.includes(\"AUTH\") || normalized.includes(\"TOKEN\")) {\r\n return \"USAGETAP_AUTH_ERROR\";\r\n }\r\n if (normalized.includes(\"RATE\") || normalized.includes(\"THROTTLE\")) {\r\n return \"USAGETAP_RATE_LIMITED\";\r\n }\r\n if (normalized.includes(\"SERVER\") || normalized.includes(\"TRANSIENT\")) {\r\n return \"USAGETAP_SERVER_ERROR\";\r\n }\r\n if (\r\n normalized.includes(\"IDEMPOTENCY\") ||\r\n normalized.includes(\"VALIDATION\") ||\r\n normalized.includes(\"REQUEST\")\r\n ) {\r\n return \"USAGETAP_BAD_REQUEST\";\r\n }\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction sanitizeDetails(\r\n payload: EnvelopeShape | undefined\r\n): Record<string, unknown> | undefined {\r\n if (!payload) return undefined;\r\n const details: Record<string, unknown> = {};\r\n if (payload.result) details.result = payload.result;\r\n if (payload.error) details.error = payload.error;\r\n return Object.keys(details).length ? details : undefined;\r\n}\r\n\r\nfunction normalizeBaseUrl(baseUrl: string): string {\r\n const trimmed = baseUrl.trim();\r\n if (!trimmed) return trimmed;\r\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\r\n}\r\n\r\nfunction normalizeHeaderDictionary(dict: Record<string, string>): HeadersDict {\r\n return Object.keys(dict).reduce<HeadersDict>((acc, key) => {\r\n acc[key.toLowerCase()] = dict[key];\r\n return acc;\r\n }, {});\r\n}\r\n\r\nfunction dedupeStrings(values: string[]): string[] {\r\n return Array.from(\r\n new Set(values.map((value) => value.trim()).filter(Boolean))\r\n );\r\n}\r\n\r\nfunction wrapEndCallError(\r\n error: unknown,\r\n correlationId?: string\r\n): UsageTapError {\r\n if (isUsageTapError(error)) {\r\n return new UsageTapError(\"USAGETAP_END_CALL_ERROR\", error.message, {\r\n correlationId: error.correlationId ?? correlationId,\r\n details: error.details,\r\n cause: error,\r\n });\r\n }\r\n\r\n return new UsageTapError(\r\n \"USAGETAP_END_CALL_ERROR\",\r\n \"Failed to finalize UsageTap call\",\r\n {\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n}\r\n","import { UsageTapClient } from \"../client\";\r\nimport type { BeginCallRequest, EndCallRequest } from \"../types\";\r\n\r\nexport interface WrapFetchContext extends Omit<BeginCallRequest, \"idempotency\"> {\r\n customerId: string;\r\n}\r\n\r\nexport interface WrapFetchOptions {\r\n /**\r\n * Context for UsageTap begin calls.\r\n * Can be overridden per-request via special headers.\r\n */\r\n defaultContext: WrapFetchContext;\r\n \r\n /**\r\n * Optional custom fetch implementation to wrap.\r\n * Defaults to global fetch.\r\n */\r\n baseFetch?: typeof fetch;\r\n \r\n /**\r\n * Generate idempotency keys automatically if not provided.\r\n * Default: true\r\n */\r\n autoIdempotency?: boolean;\r\n \r\n /**\r\n * Detect OpenAI-compatible endpoints by URL pattern.\r\n * Default: detects /v1/chat/completions and /v1/responses\r\n */\r\n isOpenAIEndpoint?: (url: string) => boolean;\r\n}\r\n\r\ninterface CallState {\r\n callId: string;\r\n correlationId?: string;\r\n usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>;\r\n finalized: boolean;\r\n}\r\n\r\ntype JsonRecord = Record<string, unknown>;\r\n\r\nfunction isJsonRecord(value: unknown): value is JsonRecord {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction readString(value: unknown): string | undefined {\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nfunction readNumber(value: unknown): number | undefined {\r\n return typeof value === \"number\" ? value : undefined;\r\n}\r\n\r\nfunction parseJsonRecord(text: string): JsonRecord | undefined {\r\n try {\r\n const parsed = JSON.parse(text) as unknown;\r\n return isJsonRecord(parsed) ? parsed : undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction parseStringArray(value: string): string[] | undefined {\r\n try {\r\n const parsed = JSON.parse(value) as unknown;\r\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\r\n return parsed;\r\n }\r\n } catch {\r\n return undefined;\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Wraps a fetch implementation to automatically instrument OpenAI API calls\r\n * with UsageTap begin/end tracking.\r\n * \r\n * Example:\r\n * ```ts\r\n * const wrappedFetch = wrapFetch(usageTap, {\r\n * defaultContext: { customerId: \"cust_123\", feature: \"chat\" }\r\n * });\r\n * \r\n * const openai = new OpenAI({\r\n * apiKey: process.env.OPENAI_API_KEY!,\r\n * fetch: wrappedFetch,\r\n * });\r\n * ```\r\n */\r\nexport function wrapFetch(\r\n usageTap: UsageTapClient,\r\n options: WrapFetchOptions,\r\n): typeof fetch {\r\n const {\r\n defaultContext,\r\n baseFetch = globalThis.fetch,\r\n autoIdempotency = true,\r\n isOpenAIEndpoint = defaultIsOpenAIEndpoint,\r\n } = options;\r\n\r\n return async function wrappedFetch(\r\n input: string | URL | Request,\r\n init?: RequestInit,\r\n ): Promise<Response> {\r\n const url = typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\r\n \r\n // Only intercept OpenAI endpoints\r\n if (!isOpenAIEndpoint(url)) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Parse request body to extract context overrides and detect streaming\r\n let body: JsonRecord | undefined;\r\n let isStreaming = false;\r\n const contextOverride: Partial<WrapFetchContext> = {};\r\n\r\n try {\r\n if (init?.body && typeof init.body === \"string\") {\r\n const parsedBody = parseJsonRecord(init.body);\r\n if (!parsedBody) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n body = parsedBody;\r\n isStreaming = parsedBody.stream === true;\r\n\r\n // Check for context overrides in special headers\r\n const headers = new Headers(init.headers);\r\n const customerIdHeader = headers.get(\"x-usagetap-customer-id\");\r\n const featureHeader = headers.get(\"x-usagetap-feature\");\r\n const tagsHeader = headers.get(\"x-usagetap-tags\");\r\n\r\n if (customerIdHeader) {\r\n contextOverride.customerId = customerIdHeader;\r\n }\r\n if (featureHeader) {\r\n contextOverride.feature = featureHeader;\r\n }\r\n if (tagsHeader) {\r\n const tags = parseStringArray(tagsHeader);\r\n if (tags) {\r\n contextOverride.tags = tags;\r\n }\r\n }\r\n }\r\n } catch {\r\n // If body parsing fails, proceed without interception\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Merge context\r\n const context: BeginCallRequest = {\r\n ...defaultContext,\r\n ...contextOverride,\r\n idempotency: autoIdempotency ? crypto.randomUUID() : undefined,\r\n };\r\n\r\n // Begin the call\r\n let callState: CallState | undefined;\r\n try {\r\n const beginResponse = await usageTap.beginCall(context);\r\n callState = {\r\n callId: beginResponse.data.callId,\r\n correlationId: beginResponse.correlationId,\r\n usage: {},\r\n finalized: false,\r\n };\r\n } catch (error) {\r\n // If begin fails, proceed with original fetch but log error\r\n console.error(\"[wrapFetch] Failed to begin call:\", error);\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Add correlation header to vendor request\r\n const modifiedInit = {\r\n ...init,\r\n headers: {\r\n ...init?.headers,\r\n \"x-usage-correlation-id\": callState.correlationId || \"\",\r\n },\r\n };\r\n\r\n // Call the vendor API\r\n try {\r\n const response = await baseFetch(input, modifiedInit);\r\n \r\n if (isStreaming) {\r\n // Wrap streaming response\r\n return wrapStreamingResponse(response, callState, usageTap);\r\n } else {\r\n // Handle non-streaming response\r\n return await wrapNonStreamingResponse(response, callState, usageTap, body);\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // Vendor call failed\r\n await finalizeCall(callState, usageTap, {\r\n code: \"VENDOR_ERROR\",\r\n message,\r\n });\r\n throw error;\r\n }\r\n };\r\n}\r\n\r\nfunction defaultIsOpenAIEndpoint(url: string): boolean {\r\n return (\r\n url.includes(\"/v1/chat/completions\") ||\r\n url.includes(\"/v1/responses\") ||\r\n url.includes(\"/v1/embeddings\")\r\n );\r\n}\r\n\r\nasync function wrapNonStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n requestBody: JsonRecord | undefined,\r\n): Promise<Response> {\r\n // Clone response to read body\r\n const clonedResponse = response.clone();\r\n \r\n try {\r\n const parsed = await clonedResponse.json();\r\n const usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n\r\n if (isJsonRecord(parsed)) {\r\n const usageBlock = parsed.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n usage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n usage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n usage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n usage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const modelFromResponse = readString(parsed.model);\r\n if (modelFromResponse) {\r\n usage.modelUsed = modelFromResponse;\r\n }\r\n }\r\n\r\n if (!usage.modelUsed && requestBody) {\r\n const requestModel = readString(requestBody.model);\r\n if (requestModel) {\r\n usage.modelUsed = requestModel;\r\n }\r\n }\r\n\r\n // Finalize the call\r\n await finalizeCall(callState, usageTap, undefined, usage);\r\n\r\n return response;\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // If we can't parse response, finalize with error\r\n await finalizeCall(callState, usageTap, {\r\n code: \"RESPONSE_PARSE_ERROR\",\r\n message,\r\n });\r\n return response;\r\n }\r\n}\r\n\r\nfunction wrapStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n): Response {\r\n if (!response.body) {\r\n // No body to stream, finalize now\r\n void finalizeCall(callState, usageTap, {\r\n code: \"NO_RESPONSE_BODY\",\r\n message: \"Streaming response has no body\",\r\n });\r\n return response;\r\n }\r\n\r\n const originalBody = response.body;\r\n const accumulatedUsage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const textDecoder = new TextDecoder();\r\n\r\n const transformStream = new TransformStream({\r\n transform(chunk: Uint8Array, controller) {\r\n controller.enqueue(chunk);\r\n \r\n // Try to parse usage from SSE data\r\n try {\r\n const text = textDecoder.decode(chunk, { stream: true });\r\n const lines = text.split(\"\\n\");\r\n \r\n for (const line of lines) {\r\n if (line.startsWith(\"data: \")) {\r\n const data = line.slice(6);\r\n if (data === \"[DONE]\") continue;\r\n \r\n const parsedRecord = parseJsonRecord(data);\r\n if (!parsedRecord) {\r\n continue;\r\n }\r\n\r\n const usageBlock = parsedRecord.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n accumulatedUsage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n accumulatedUsage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n accumulatedUsage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n accumulatedUsage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const model = readString(parsedRecord.model);\r\n if (model) {\r\n accumulatedUsage.modelUsed = model;\r\n }\r\n }\r\n }\r\n } catch {\r\n // Ignore decode errors\r\n }\r\n },\r\n\r\n async flush() {\r\n // Stream completed successfully\r\n await finalizeCall(callState, usageTap, undefined, accumulatedUsage);\r\n },\r\n });\r\n\r\n // Handle stream errors and cancellation\r\n const wrappedBody = originalBody.pipeThrough(transformStream);\r\n \r\n // Note: Response doesn't have signal property, abort handling happens via stream closure\r\n\r\n return new Response(wrappedBody, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n });\r\n}\r\n\r\nasync function finalizeCall(\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n error?: { code: string; message: string },\r\n usage?: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>,\r\n): Promise<void> {\r\n if (callState.finalized) return;\r\n callState.finalized = true;\r\n\r\n try {\r\n await usageTap.endCall({\r\n callId: callState.callId,\r\n ...callState.usage,\r\n ...usage,\r\n error,\r\n });\r\n } catch (err) {\r\n console.error(\"[wrapFetch] Failed to finalize call:\", err);\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/retry.ts","../src/client.ts","../src/adapters/fetch-wrapper.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["export type UsageTapErrorCode =\r\n | \"USAGETAP_BROWSER_RUNTIME\"\r\n | \"USAGETAP_AUTH_ERROR\"\r\n | \"USAGETAP_BAD_REQUEST\"\r\n | \"USAGETAP_INVALID_RESPONSE\"\r\n | \"USAGETAP_NETWORK_ERROR\"\r\n | \"USAGETAP_RATE_LIMITED\"\r\n | \"USAGETAP_SERVER_ERROR\"\r\n | \"USAGETAP_RETRY_EXHAUSTED\"\r\n | \"USAGETAP_END_CALL_ERROR\";\r\n\r\nexport interface UsageTapErrorInit {\r\n status?: number;\r\n retryable?: boolean;\r\n correlationId?: string;\r\n details?: Record<string, unknown>;\r\n cause?: unknown;\r\n}\r\n\r\nexport class UsageTapError extends Error {\r\n public readonly code: UsageTapErrorCode;\r\n public readonly status?: number;\r\n public readonly retryable: boolean;\r\n public readonly correlationId?: string;\r\n public readonly details?: Record<string, unknown>;\r\n\r\n constructor(code: UsageTapErrorCode, message: string, init: UsageTapErrorInit = {}) {\r\n super(message, init.cause ? { cause: init.cause as Error } : undefined);\r\n this.name = \"UsageTapError\";\r\n this.code = code;\r\n this.status = init.status;\r\n this.retryable = init.retryable ?? false;\r\n this.correlationId = init.correlationId;\r\n this.details = init.details;\r\n }\r\n\r\n toJSON(): Record<string, unknown> {\r\n return {\r\n name: this.name,\r\n message: this.message,\r\n code: this.code,\r\n status: this.status,\r\n retryable: this.retryable,\r\n correlationId: this.correlationId,\r\n details: this.details,\r\n };\r\n }\r\n}\r\n\r\nexport function isUsageTapError(error: unknown): error is UsageTapError {\r\n return error instanceof UsageTapError;\r\n}\r\n","export function createIdempotencyKey(): string {\r\n if (typeof globalThis.crypto?.randomUUID === \"function\") {\r\n return globalThis.crypto.randomUUID();\r\n }\r\n\r\n const random = (): string => Math.random().toString(16).slice(2, 10);\r\n return `${random()}-${random()}`;\r\n}\r\n","import type { RetryOptions } from \"./types\";\r\n\r\nexport interface ResolvedRetryOptions {\r\n maxAttempts: number;\r\n baseDelayMs: number;\r\n maxDelayMs: number;\r\n jitterRatio: number;\r\n}\r\n\r\nconst DEFAULTS: ResolvedRetryOptions = {\r\n maxAttempts: 3,\r\n baseDelayMs: 250,\r\n maxDelayMs: 5000,\r\n jitterRatio: 0.2,\r\n};\r\n\r\nexport function resolveRetryOptions(\r\n base?: RetryOptions,\r\n override?: RetryOptions,\r\n): ResolvedRetryOptions {\r\n const merged = { ...DEFAULTS, ...base, ...override } satisfies ResolvedRetryOptions;\r\n return {\r\n maxAttempts: Math.max(1, Math.floor(merged.maxAttempts)),\r\n baseDelayMs: Math.max(0, merged.baseDelayMs),\r\n maxDelayMs: Math.max(merged.baseDelayMs, merged.maxDelayMs),\r\n jitterRatio: Math.min(Math.max(merged.jitterRatio, 0), 1),\r\n };\r\n}\r\n\r\nexport async function sleep(delayMs: number, signal?: AbortSignal): Promise<void> {\r\n if (delayMs <= 0) {\r\n signal?.throwIfAborted?.();\r\n return;\r\n }\r\n\r\n await new Promise<void>((resolve, reject) => {\r\n const timer = setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, delayMs);\r\n\r\n const cleanup = (): void => {\r\n clearTimeout(timer);\r\n signal?.removeEventListener(\"abort\", onAbort);\r\n };\r\n\r\n const onAbort = (): void => {\r\n cleanup();\r\n const abortError = new Error(\"Aborted\");\r\n abortError.name = \"AbortError\";\r\n reject(abortError);\r\n };\r\n\r\n if (signal) {\r\n if (signal.aborted) {\r\n onAbort();\r\n return;\r\n }\r\n signal.addEventListener(\"abort\", onAbort, { once: true });\r\n }\r\n });\r\n}\r\n\r\nexport function computeDelay(attempt: number, options: ResolvedRetryOptions): number {\r\n const exp = options.baseDelayMs * Math.pow(2, attempt - 1);\r\n const capped = Math.min(exp, options.maxDelayMs);\r\n const jitter = capped * options.jitterRatio;\r\n const min = capped - jitter;\r\n const max = capped + jitter;\r\n return Math.max(0, Math.random() * (max - min) + min);\r\n}\r\n\r\nexport async function runWithRetry<T>(\r\n operation: (attempt: number) => Promise<T>,\r\n options: ResolvedRetryOptions,\r\n shouldRetry: (error: unknown) => boolean,\r\n onSchedule?: (attempt: number, delayMs: number, error: unknown) => void,\r\n signal?: AbortSignal,\r\n): Promise<T> {\r\n let attempt = 0;\r\n let lastError: unknown;\r\n while (attempt < options.maxAttempts) {\r\n attempt += 1;\r\n signal?.throwIfAborted?.();\r\n\r\n try {\r\n return await operation(attempt);\r\n } catch (error) {\r\n lastError = error;\r\n if (attempt >= options.maxAttempts || !shouldRetry(error)) {\r\n throw error;\r\n }\r\n const delayMs = computeDelay(attempt, options);\r\n onSchedule?.(attempt, delayMs, error);\r\n await sleep(delayMs, signal);\r\n }\r\n }\r\n\r\n throw lastError instanceof Error ? lastError : new Error(String(lastError));\r\n}\r\n","import type {\r\n BeginCallOptions,\r\n BeginCallRequest,\r\n BeginCallResponseBody,\r\n CreateCustomerOptions,\r\n CreateCustomerRequest,\r\n CreateCustomerResponseBody,\r\n CheckUsageOptions,\r\n CheckUsageRequest,\r\n CheckUsageResponseBody,\r\n ChangePlanOptions,\r\n ChangePlanRequest,\r\n ChangePlanResponseBody,\r\n EndCallOptions,\r\n EndCallRequest,\r\n EndCallResponseBody,\r\n UsageTapClientOptions,\r\n UsageTapLogEntry,\r\n UsageTapSuccessResponse,\r\n WithUsageContext,\r\n WithUsageOptions,\r\n} from \"./types\";\r\nimport {\r\n UsageTapError,\r\n type UsageTapErrorCode,\r\n isUsageTapError,\r\n} from \"./errors\";\r\nimport { createIdempotencyKey } from \"./idempotency\";\r\nimport {\r\n runWithRetry,\r\n resolveRetryOptions,\r\n type ResolvedRetryOptions,\r\n} from \"./retry\";\r\nimport type { RetryOptions } from \"./types\";\r\n\r\nconst CALL_BEGIN_PATH = \"call_begin\";\r\nconst CALL_END_PATH = \"call_end\";\r\nconst CHECK_USAGE_PATH = \"customers/{customerId}/usage\";\r\nconst CREATE_CUSTOMER_PATH = \"customers\";\r\nconst CHANGE_PLAN_PATH = \"customers/{customerId}/change_plan\";\r\nconst AUTH_HEADER = \"authorization\";\r\nconst API_KEY_HEADER = \"x-api-key\";\r\nconst CORRELATION_HEADER = \"x-usage-correlation-id\";\r\nconst IDEMPOTENCY_HEADER = \"idempotency-key\";\r\nconst SDK_HEADER = \"x-usage-sdk\";\r\nconst USER_AGENT = \"UsageTapClient\";\r\nconst CANONICAL_MEDIA_TYPE = \"application/vnd.usagetap.v1+json\";\r\n\r\ndeclare const __SDK_VERSION__: string | undefined;\r\nconst SDK_VERSION =\r\n typeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.1.0\";\r\nconst HAS_WINDOW =\r\n typeof globalThis !== \"undefined\" &&\r\n typeof (globalThis as Record<string, unknown>).window !== \"undefined\";\r\n\r\ntype HeadersDict = Record<string, string>;\r\n\r\ntype InternalRequestOptions = {\r\n signal?: AbortSignal;\r\n headers?: HeadersDict;\r\n retries?: RetryOptions;\r\n correlationId?: string;\r\n idempotencyKey?: string;\r\n};\r\n\r\ntype EnvelopeShape = {\r\n result?: {\r\n status?: string;\r\n code?: string;\r\n message?: string;\r\n timestamp?: string;\r\n };\r\n data?: unknown;\r\n error?: {\r\n code?: string;\r\n message?: string;\r\n details?: Record<string, unknown>;\r\n };\r\n correlationId?: string;\r\n};\r\n\r\nexport class UsageTapClient {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: URL;\r\n private readonly fetchImpl: typeof fetch;\r\n private readonly defaultFeature?: string;\r\n private readonly defaultTags?: string[];\r\n private readonly defaultHeaders: HeadersDict;\r\n private readonly retryDefaults: ResolvedRetryOptions;\r\n private readonly idempotencyGenerator: () => string;\r\n private readonly logFn?: (entry: UsageTapLogEntry) => void;\r\n private readonly authHeader: typeof AUTH_HEADER | typeof API_KEY_HEADER;\r\n private readonly autoIdempotency: boolean;\r\n\r\n constructor(options: UsageTapClientOptions) {\r\n if (!options) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient options are required\"\r\n );\r\n }\r\n\r\n if (!options.apiKey) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires an apiKey\"\r\n );\r\n }\r\n\r\n if (!options.baseUrl) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"UsageTapClient requires a baseUrl\"\r\n );\r\n }\r\n\r\n if (HAS_WINDOW && !options.allowBrowser) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BROWSER_RUNTIME\",\r\n \"UsageTapClient is designed for server-side environments. Pass allowBrowser=true only for testing.\"\r\n );\r\n }\r\n\r\n const fetchCandidate = options.fetchImpl ?? globalThis.fetch;\r\n if (typeof fetchCandidate !== \"function\") {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"A global fetch implementation was not found. Pass fetchImpl in UsageTapClientOptions.\"\r\n );\r\n }\r\n\r\n const normalizedBaseUrl = normalizeBaseUrl(options.baseUrl);\r\n this.baseUrl = new URL(normalizedBaseUrl);\r\n this.apiKey = options.apiKey;\r\n this.fetchImpl = wrapFetchImplementation(fetchCandidate, !options.fetchImpl);\r\n this.defaultFeature = options.defaultFeature;\r\n this.defaultTags = options.defaultTags?.length\r\n ? dedupeStrings(options.defaultTags)\r\n : undefined;\r\n this.defaultHeaders = options.headers\r\n ? normalizeHeaderDictionary(options.headers)\r\n : {};\r\n this.retryDefaults = resolveRetryOptions(options.retries);\r\n this.idempotencyGenerator =\r\n options.idempotencyGenerator ?? createIdempotencyKey;\r\n this.logFn = options.onLog;\r\n this.authHeader = options.useApiKeyHeader ? API_KEY_HEADER : AUTH_HEADER;\r\n this.autoIdempotency = options.autoIdempotency ?? true;\r\n }\r\n\r\n async beginCall(\r\n request: BeginCallRequest,\r\n options: BeginCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<BeginCallResponseBody>> {\r\n const idempotencyKey =\r\n request.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const payload: BeginCallRequest = {\r\n ...request,\r\n feature: request.feature ?? this.defaultFeature,\r\n tags: this.mergeTags(request.tags),\r\n } satisfies BeginCallRequest;\r\n if (idempotencyKey) {\r\n payload.idempotency = idempotencyKey;\r\n }\r\n\r\n const response = await this.request<BeginCallResponseBody>(\r\n CALL_BEGIN_PATH,\r\n payload,\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async endCall(\r\n request: EndCallRequest,\r\n options: EndCallOptions = {}\r\n ): Promise<UsageTapSuccessResponse<EndCallResponseBody>> {\r\n if (!request?.callId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"endCall requires callId\"\r\n );\r\n }\r\n\r\n const payload = { ...request } satisfies EndCallRequest;\r\n const response = await this.request<EndCallResponseBody>(\r\n CALL_END_PATH,\r\n payload,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async checkUsage(\r\n request: CheckUsageRequest,\r\n options: CheckUsageOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"checkUsage requires customerId\"\r\n );\r\n }\r\n\r\n const path = CHECK_USAGE_PATH.replace(\r\n \"{customerId}\",\r\n encodeURIComponent(request.customerId)\r\n );\r\n const response = await this.requestGet<CheckUsageResponseBody>(\r\n path,\r\n options\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async createCustomer(\r\n request: CreateCustomerRequest,\r\n options: CreateCustomerOptions = {}\r\n ): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"createCustomer requires customerId\"\r\n );\r\n }\r\n\r\n const idempotencyKey =\r\n options.idempotencyKey ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n\r\n const response = await this.request<CreateCustomerResponseBody>(\r\n CREATE_CUSTOMER_PATH,\r\n { ...request },\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async changePlan(\r\n request: ChangePlanRequest,\r\n options: ChangePlanOptions = {}\r\n ): Promise<UsageTapSuccessResponse<ChangePlanResponseBody>> {\r\n if (!request?.customerId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"changePlan requires customerId\"\r\n );\r\n }\r\n\r\n if (!request?.planId) {\r\n throw new UsageTapError(\r\n \"USAGETAP_BAD_REQUEST\",\r\n \"changePlan requires planId\"\r\n );\r\n }\r\n\r\n const path = CHANGE_PLAN_PATH.replace(\r\n \"{customerId}\",\r\n encodeURIComponent(request.customerId)\r\n );\r\n\r\n const idempotencyKey =\r\n options.idempotencyKey ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n\r\n const payload: Record<string, unknown> = {\r\n planId: request.planId,\r\n strategy: request.strategy ?? \"IMMEDIATE_RESET\",\r\n };\r\n\r\n const response = await this.request<ChangePlanResponseBody>(\r\n path,\r\n payload,\r\n {\r\n ...options,\r\n idempotencyKey,\r\n }\r\n );\r\n\r\n return response;\r\n }\r\n\r\n async withUsage<T>(\r\n beginRequest: BeginCallRequest,\r\n handler: (context: WithUsageContext) => Promise<T>,\r\n options: WithUsageOptions = {}\r\n ): Promise<T> {\r\n const idempotencyKey =\r\n beginRequest.idempotency ??\r\n (this.autoIdempotency ? this.idempotencyGenerator() : undefined);\r\n const beginPayload = idempotencyKey\r\n ? { ...beginRequest, idempotency: idempotencyKey }\r\n : { ...beginRequest };\r\n const beginResponse = await this.beginCall(beginPayload, options);\r\n\r\n let usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const initialStripeCustomerId =\r\n typeof beginResponse.data.stripeCustomerId === \"string\"\r\n ? beginResponse.data.stripeCustomerId\r\n : typeof beginRequest.stripeCustomerId === \"string\"\r\n ? beginRequest.stripeCustomerId\r\n : undefined;\r\n if (initialStripeCustomerId) {\r\n usage = { ...usage, stripeCustomerId: initialStripeCustomerId };\r\n }\r\n let errorPayload: EndCallRequest[\"error\"] | undefined;\r\n let handlerResult: T | undefined;\r\n let handlerError: unknown;\r\n let endCallError: unknown;\r\n\r\n const context: WithUsageContext = {\r\n begin: beginResponse,\r\n setUsage: (u) => {\r\n usage = { ...usage, ...u };\r\n },\r\n setError: (err) => {\r\n errorPayload = err;\r\n },\r\n };\r\n\r\n try {\r\n handlerResult = await handler(context);\r\n } catch (error) {\r\n handlerError = error;\r\n if (!errorPayload) {\r\n errorPayload = {\r\n code: options.defaultErrorCode ?? \"VENDOR_ERROR\",\r\n message: error instanceof Error ? error.message : String(error),\r\n };\r\n }\r\n } finally {\r\n try {\r\n await this.endCall(\r\n {\r\n callId: beginResponse.data.callId,\r\n ...(usage as Partial<Omit<EndCallRequest, \"callId\" | \"error\">>),\r\n error: errorPayload,\r\n },\r\n {\r\n ...options,\r\n correlationId: beginResponse.correlationId,\r\n }\r\n );\r\n } catch (error) {\r\n endCallError = error;\r\n }\r\n }\r\n\r\n if (handlerError) {\r\n throw handlerError;\r\n }\r\n\r\n if (endCallError) {\r\n throw wrapEndCallError(endCallError, beginResponse.correlationId);\r\n }\r\n\r\n return handlerResult as T;\r\n }\r\n\r\n private async request<T>(\r\n path: string,\r\n payload: unknown,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const body = payload !== undefined ? JSON.stringify(payload) : undefined;\r\n const headers = this.composeHeaders(body, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"POST\",\r\n headers,\r\n body,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n idempotencyKey: options.idempotencyKey,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async requestGet<T>(\r\n path: string,\r\n options: InternalRequestOptions\r\n ): Promise<UsageTapSuccessResponse<T>> {\r\n const url = new URL(path, this.baseUrl).toString();\r\n const headers = this.composeHeaders(undefined, options);\r\n const resolvedRetry = resolveRetryOptions(\r\n this.retryDefaults,\r\n options.retries\r\n );\r\n\r\n const startTime = (): number =>\r\n typeof performance !== \"undefined\" ? performance.now() : Date.now();\r\n\r\n return runWithRetry(\r\n async (attempt) => {\r\n const startedAt = startTime();\r\n this.log({\r\n event: \"request:start\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n });\r\n\r\n const response = await this.performFetch<T>({\r\n url,\r\n method: \"GET\",\r\n headers,\r\n signal: options.signal,\r\n });\r\n\r\n this.log({\r\n event: \"request:success\",\r\n path,\r\n attempt,\r\n correlationId: response.correlationId,\r\n elapsedMs: startTime() - startedAt,\r\n });\r\n\r\n return response;\r\n },\r\n resolvedRetry,\r\n (error) => this.shouldRetry(error),\r\n (attempt, delayMs, error) => {\r\n this.log({\r\n event: \"retry:scheduled\",\r\n path,\r\n attempt,\r\n correlationId: options.correlationId,\r\n error,\r\n elapsedMs: delayMs,\r\n });\r\n },\r\n options.signal\r\n ).catch((error) => {\r\n this.log({\r\n event: \"retry:exhausted\",\r\n path,\r\n attempt: resolvedRetry.maxAttempts,\r\n correlationId: options.correlationId,\r\n error,\r\n });\r\n throw error;\r\n });\r\n }\r\n\r\n private async performFetch<T>(init: {\r\n url: string;\r\n method: string;\r\n headers: HeadersDict;\r\n body?: string;\r\n signal?: AbortSignal;\r\n }): Promise<UsageTapSuccessResponse<T>> {\r\n let response: Response;\r\n try {\r\n response = await this.fetchImpl(init.url, {\r\n method: init.method,\r\n headers: init.headers,\r\n body: init.body,\r\n signal: init.signal,\r\n });\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_NETWORK_ERROR\",\r\n \"Failed to reach UsageTap\",\r\n {\r\n retryable: true,\r\n cause: error,\r\n }\r\n );\r\n }\r\n\r\n const correlationId = response.headers.get(CORRELATION_HEADER) ?? undefined;\r\n const text = await response.text();\r\n let payload: EnvelopeShape | undefined;\r\n\r\n if (text) {\r\n try {\r\n payload = JSON.parse(text) as EnvelopeShape;\r\n } catch (error) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap returned invalid JSON\",\r\n {\r\n retryable: false,\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n }\r\n }\r\n\r\n if (!response.ok) {\r\n throw this.toHttpError(response.status, payload, correlationId);\r\n }\r\n\r\n if (!payload?.result || payload.result.status !== \"ACCEPTED\") {\r\n throw this.toApiError(payload, correlationId);\r\n }\r\n\r\n const resolvedCorrelation = payload.correlationId ?? correlationId;\r\n if (\r\n payload.data === undefined ||\r\n payload.data === null ||\r\n !resolvedCorrelation\r\n ) {\r\n throw new UsageTapError(\r\n \"USAGETAP_INVALID_RESPONSE\",\r\n \"UsageTap response missing data or correlationId\",\r\n {\r\n correlationId: resolvedCorrelation ?? correlationId,\r\n }\r\n );\r\n }\r\n\r\n return {\r\n result: {\r\n status: payload.result.status as \"ACCEPTED\",\r\n code: payload.result.code,\r\n message: payload.result.message,\r\n timestamp: payload.result.timestamp,\r\n },\r\n data: payload.data as T,\r\n correlationId: resolvedCorrelation,\r\n } satisfies UsageTapSuccessResponse<T>;\r\n }\r\n\r\n private composeHeaders(\r\n body: string | undefined,\r\n options: InternalRequestOptions\r\n ): HeadersDict {\r\n const headers: HeadersDict = {\r\n ...this.defaultHeaders,\r\n [SDK_HEADER]: `js/${SDK_VERSION}`,\r\n \"content-type\": \"application/json\",\r\n accept: CANONICAL_MEDIA_TYPE,\r\n };\r\n\r\n if (!HAS_WINDOW) {\r\n // Browsers forbid setting user-agent; only attach it server-side.\r\n headers[\"user-agent\"] = `${USER_AGENT}/${SDK_VERSION}`;\r\n }\r\n\r\n if (this.authHeader === API_KEY_HEADER) {\r\n headers[API_KEY_HEADER] = this.apiKey;\r\n } else {\r\n headers[AUTH_HEADER] = `Bearer ${this.apiKey}`;\r\n }\r\n\r\n if (options.idempotencyKey) {\r\n headers[IDEMPOTENCY_HEADER] = options.idempotencyKey;\r\n }\r\n\r\n if (options.correlationId) {\r\n headers[CORRELATION_HEADER] = options.correlationId;\r\n }\r\n\r\n if (!body) {\r\n delete headers[\"content-type\"];\r\n }\r\n\r\n if (options.headers) {\r\n Object.assign(headers, normalizeHeaderDictionary(options.headers));\r\n }\r\n\r\n return headers;\r\n }\r\n\r\n private log(entry: UsageTapLogEntry): void {\r\n this.logFn?.(entry);\r\n }\r\n\r\n private mergeTags(tags?: string[]): string[] | undefined {\r\n if (!tags && !this.defaultTags) {\r\n return undefined;\r\n }\r\n\r\n const combined = [...(this.defaultTags ?? []), ...(tags ?? [])].filter(\r\n Boolean\r\n );\r\n return combined.length ? dedupeStrings(combined) : undefined;\r\n }\r\n\r\n private shouldRetry(error: unknown): boolean {\r\n if (isUsageTapError(error)) {\r\n return Boolean(error.retryable);\r\n }\r\n\r\n if (error instanceof Error && error.name === \"AbortError\") {\r\n return false;\r\n }\r\n\r\n return false;\r\n }\r\n\r\n private toHttpError(\r\n status: number,\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const code = mapStatusToErrorCode(status);\r\n const retryable = isRetryableStatus(status);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n `UsageTap responded with HTTP ${status}`;\r\n\r\n return new UsageTapError(code, message, {\r\n status,\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n\r\n private toApiError(\r\n payload: EnvelopeShape | undefined,\r\n correlationId?: string\r\n ): UsageTapError {\r\n const normalizedCode =\r\n payload?.error?.code ?? payload?.result?.code ?? \"UNKNOWN\";\r\n const retryable = isRetryableApiCode(normalizedCode);\r\n const message =\r\n payload?.error?.message ??\r\n payload?.result?.message ??\r\n \"UsageTap reported an error\";\r\n\r\n return new UsageTapError(mapApiCodeToError(normalizedCode), message, {\r\n retryable,\r\n correlationId: payload?.correlationId ?? correlationId,\r\n details: sanitizeDetails(payload),\r\n });\r\n }\r\n}\r\n\r\nfunction mapStatusToErrorCode(status: number): UsageTapErrorCode {\r\n if (status === 401 || status === 403) return \"USAGETAP_AUTH_ERROR\";\r\n if (status === 400 || status === 404 || status === 409)\r\n return \"USAGETAP_BAD_REQUEST\";\r\n if (status === 429) return \"USAGETAP_RATE_LIMITED\";\r\n if (status >= 500) return \"USAGETAP_SERVER_ERROR\";\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction isRetryableStatus(status: number): boolean {\r\n return (\r\n status === 408 ||\r\n status === 425 ||\r\n status === 429 ||\r\n status === 500 ||\r\n status === 502 ||\r\n status === 503 ||\r\n status === 504\r\n );\r\n}\r\n\r\nfunction isRetryableApiCode(code: string): boolean {\r\n const normalized = code.toUpperCase();\r\n return (\r\n normalized.includes(\"TRANSIENT\") ||\r\n normalized.includes(\"RETRY\") ||\r\n normalized.includes(\"TIMEOUT\") ||\r\n normalized.includes(\"THROTTLE\") ||\r\n normalized.includes(\"RATE_LIMIT\")\r\n );\r\n}\r\n\r\nfunction mapApiCodeToError(code: string): UsageTapErrorCode {\r\n const normalized = code.toUpperCase();\r\n if (normalized.includes(\"AUTH\") || normalized.includes(\"TOKEN\")) {\r\n return \"USAGETAP_AUTH_ERROR\";\r\n }\r\n if (normalized.includes(\"RATE\") || normalized.includes(\"THROTTLE\")) {\r\n return \"USAGETAP_RATE_LIMITED\";\r\n }\r\n if (normalized.includes(\"SERVER\") || normalized.includes(\"TRANSIENT\")) {\r\n return \"USAGETAP_SERVER_ERROR\";\r\n }\r\n if (\r\n normalized.includes(\"IDEMPOTENCY\") ||\r\n normalized.includes(\"VALIDATION\") ||\r\n normalized.includes(\"REQUEST\")\r\n ) {\r\n return \"USAGETAP_BAD_REQUEST\";\r\n }\r\n return \"USAGETAP_INVALID_RESPONSE\";\r\n}\r\n\r\nfunction sanitizeDetails(\r\n payload: EnvelopeShape | undefined\r\n): Record<string, unknown> | undefined {\r\n if (!payload) return undefined;\r\n const details: Record<string, unknown> = {};\r\n if (payload.result) details.result = payload.result;\r\n if (payload.error) details.error = payload.error;\r\n return Object.keys(details).length ? details : undefined;\r\n}\r\n\r\nfunction normalizeBaseUrl(baseUrl: string): string {\r\n const trimmed = baseUrl.trim();\r\n if (!trimmed) return trimmed;\r\n return trimmed.endsWith(\"/\") ? trimmed : `${trimmed}/`;\r\n}\r\n\r\nfunction normalizeHeaderDictionary(dict: Record<string, string>): HeadersDict {\r\n return Object.keys(dict).reduce<HeadersDict>((acc, key) => {\r\n acc[key.toLowerCase()] = dict[key];\r\n return acc;\r\n }, {});\r\n}\r\n\r\nfunction dedupeStrings(values: string[]): string[] {\r\n return Array.from(\r\n new Set(values.map((value) => value.trim()).filter(Boolean))\r\n );\r\n}\r\n\r\nfunction wrapFetchImplementation(\r\n fetchCandidate: typeof fetch,\r\n preferGlobalContext: boolean\r\n): typeof fetch {\r\n const target = preferGlobalContext ? globalThis : undefined;\r\n return ((...args: Parameters<typeof fetch>) =>\r\n target\r\n ? Reflect.apply(fetchCandidate, target, args)\r\n : fetchCandidate(...args)) as typeof fetch;\r\n}\r\n\r\nfunction wrapEndCallError(\r\n error: unknown,\r\n correlationId?: string\r\n): UsageTapError {\r\n if (isUsageTapError(error)) {\r\n return new UsageTapError(\"USAGETAP_END_CALL_ERROR\", error.message, {\r\n correlationId: error.correlationId ?? correlationId,\r\n details: error.details,\r\n cause: error,\r\n });\r\n }\r\n\r\n return new UsageTapError(\r\n \"USAGETAP_END_CALL_ERROR\",\r\n \"Failed to finalize UsageTap call\",\r\n {\r\n correlationId,\r\n cause: error,\r\n }\r\n );\r\n}\r\n","import { UsageTapClient } from \"../client\";\r\nimport type { BeginCallRequest, EndCallRequest } from \"../types\";\r\n\r\nexport interface WrapFetchContext extends Omit<BeginCallRequest, \"idempotency\"> {\r\n customerId: string;\r\n}\r\n\r\nexport interface WrapFetchOptions {\r\n /**\r\n * Context for UsageTap begin calls.\r\n * Can be overridden per-request via special headers.\r\n */\r\n defaultContext: WrapFetchContext;\r\n \r\n /**\r\n * Optional custom fetch implementation to wrap.\r\n * Defaults to global fetch.\r\n */\r\n baseFetch?: typeof fetch;\r\n \r\n /**\r\n * Generate idempotency keys automatically if not provided.\r\n * Default: true\r\n */\r\n autoIdempotency?: boolean;\r\n \r\n /**\r\n * Detect OpenAI-compatible endpoints by URL pattern.\r\n * Default: detects /v1/chat/completions and /v1/responses\r\n */\r\n isOpenAIEndpoint?: (url: string) => boolean;\r\n}\r\n\r\ninterface CallState {\r\n callId: string;\r\n correlationId?: string;\r\n usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>;\r\n finalized: boolean;\r\n}\r\n\r\ntype JsonRecord = Record<string, unknown>;\r\n\r\nfunction isJsonRecord(value: unknown): value is JsonRecord {\r\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n}\r\n\r\nfunction readString(value: unknown): string | undefined {\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nfunction readNumber(value: unknown): number | undefined {\r\n return typeof value === \"number\" ? value : undefined;\r\n}\r\n\r\nfunction parseJsonRecord(text: string): JsonRecord | undefined {\r\n try {\r\n const parsed = JSON.parse(text) as unknown;\r\n return isJsonRecord(parsed) ? parsed : undefined;\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\nfunction parseStringArray(value: string): string[] | undefined {\r\n try {\r\n const parsed = JSON.parse(value) as unknown;\r\n if (Array.isArray(parsed) && parsed.every((item) => typeof item === \"string\")) {\r\n return parsed;\r\n }\r\n } catch {\r\n return undefined;\r\n }\r\n return undefined;\r\n}\r\n\r\n/**\r\n * Wraps a fetch implementation to automatically instrument OpenAI API calls\r\n * with UsageTap begin/end tracking.\r\n * \r\n * Example:\r\n * ```ts\r\n * const wrappedFetch = wrapFetch(usageTap, {\r\n * defaultContext: { customerId: \"cust_123\", feature: \"chat\" }\r\n * });\r\n * \r\n * const openai = new OpenAI({\r\n * apiKey: process.env.OPENAI_API_KEY!,\r\n * fetch: wrappedFetch,\r\n * });\r\n * ```\r\n */\r\nexport function wrapFetch(\r\n usageTap: UsageTapClient,\r\n options: WrapFetchOptions,\r\n): typeof fetch {\r\n const {\r\n defaultContext,\r\n baseFetch = globalThis.fetch,\r\n autoIdempotency = true,\r\n isOpenAIEndpoint = defaultIsOpenAIEndpoint,\r\n } = options;\r\n\r\n return async function wrappedFetch(\r\n input: string | URL | Request,\r\n init?: RequestInit,\r\n ): Promise<Response> {\r\n const url = typeof input === \"string\" ? input : input instanceof URL ? input.href : input.url;\r\n \r\n // Only intercept OpenAI endpoints\r\n if (!isOpenAIEndpoint(url)) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Parse request body to extract context overrides and detect streaming\r\n let body: JsonRecord | undefined;\r\n let isStreaming = false;\r\n const contextOverride: Partial<WrapFetchContext> = {};\r\n\r\n try {\r\n if (init?.body && typeof init.body === \"string\") {\r\n const parsedBody = parseJsonRecord(init.body);\r\n if (!parsedBody) {\r\n return baseFetch(input, init);\r\n }\r\n\r\n body = parsedBody;\r\n isStreaming = parsedBody.stream === true;\r\n\r\n // Check for context overrides in special headers\r\n const headers = new Headers(init.headers);\r\n const customerIdHeader = headers.get(\"x-usagetap-customer-id\");\r\n const featureHeader = headers.get(\"x-usagetap-feature\");\r\n const tagsHeader = headers.get(\"x-usagetap-tags\");\r\n\r\n if (customerIdHeader) {\r\n contextOverride.customerId = customerIdHeader;\r\n }\r\n if (featureHeader) {\r\n contextOverride.feature = featureHeader;\r\n }\r\n if (tagsHeader) {\r\n const tags = parseStringArray(tagsHeader);\r\n if (tags) {\r\n contextOverride.tags = tags;\r\n }\r\n }\r\n }\r\n } catch {\r\n // If body parsing fails, proceed without interception\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Merge context\r\n const context: BeginCallRequest = {\r\n ...defaultContext,\r\n ...contextOverride,\r\n idempotency: autoIdempotency ? crypto.randomUUID() : undefined,\r\n };\r\n\r\n // Begin the call\r\n let callState: CallState | undefined;\r\n try {\r\n const beginResponse = await usageTap.beginCall(context);\r\n callState = {\r\n callId: beginResponse.data.callId,\r\n correlationId: beginResponse.correlationId,\r\n usage: {},\r\n finalized: false,\r\n };\r\n } catch (error) {\r\n // If begin fails, proceed with original fetch but log error\r\n console.error(\"[wrapFetch] Failed to begin call:\", error);\r\n return baseFetch(input, init);\r\n }\r\n\r\n // Add correlation header to vendor request\r\n const modifiedInit = {\r\n ...init,\r\n headers: {\r\n ...init?.headers,\r\n \"x-usage-correlation-id\": callState.correlationId || \"\",\r\n },\r\n };\r\n\r\n // Call the vendor API\r\n try {\r\n const response = await baseFetch(input, modifiedInit);\r\n \r\n if (isStreaming) {\r\n // Wrap streaming response\r\n return wrapStreamingResponse(response, callState, usageTap);\r\n } else {\r\n // Handle non-streaming response\r\n return await wrapNonStreamingResponse(response, callState, usageTap, body);\r\n }\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // Vendor call failed\r\n await finalizeCall(callState, usageTap, {\r\n code: \"VENDOR_ERROR\",\r\n message,\r\n });\r\n throw error;\r\n }\r\n };\r\n}\r\n\r\nfunction defaultIsOpenAIEndpoint(url: string): boolean {\r\n return (\r\n url.includes(\"/v1/chat/completions\") ||\r\n url.includes(\"/v1/responses\") ||\r\n url.includes(\"/v1/embeddings\")\r\n );\r\n}\r\n\r\nasync function wrapNonStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n requestBody: JsonRecord | undefined,\r\n): Promise<Response> {\r\n // Clone response to read body\r\n const clonedResponse = response.clone();\r\n \r\n try {\r\n const parsed = await clonedResponse.json();\r\n const usage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n\r\n if (isJsonRecord(parsed)) {\r\n const usageBlock = parsed.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n usage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n usage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n usage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n usage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const modelFromResponse = readString(parsed.model);\r\n if (modelFromResponse) {\r\n usage.modelUsed = modelFromResponse;\r\n }\r\n }\r\n\r\n if (!usage.modelUsed && requestBody) {\r\n const requestModel = readString(requestBody.model);\r\n if (requestModel) {\r\n usage.modelUsed = requestModel;\r\n }\r\n }\r\n\r\n // Finalize the call\r\n await finalizeCall(callState, usageTap, undefined, usage);\r\n\r\n return response;\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : String(error);\r\n // If we can't parse response, finalize with error\r\n await finalizeCall(callState, usageTap, {\r\n code: \"RESPONSE_PARSE_ERROR\",\r\n message,\r\n });\r\n return response;\r\n }\r\n}\r\n\r\nfunction wrapStreamingResponse(\r\n response: Response,\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n): Response {\r\n if (!response.body) {\r\n // No body to stream, finalize now\r\n void finalizeCall(callState, usageTap, {\r\n code: \"NO_RESPONSE_BODY\",\r\n message: \"Streaming response has no body\",\r\n });\r\n return response;\r\n }\r\n\r\n const originalBody = response.body;\r\n const accumulatedUsage: Partial<Omit<EndCallRequest, \"callId\" | \"error\">> = {};\r\n const textDecoder = new TextDecoder();\r\n\r\n const transformStream = new TransformStream({\r\n transform(chunk: Uint8Array, controller) {\r\n controller.enqueue(chunk);\r\n \r\n // Try to parse usage from SSE data\r\n try {\r\n const text = textDecoder.decode(chunk, { stream: true });\r\n const lines = text.split(\"\\n\");\r\n \r\n for (const line of lines) {\r\n if (line.startsWith(\"data: \")) {\r\n const data = line.slice(6);\r\n if (data === \"[DONE]\") continue;\r\n \r\n const parsedRecord = parseJsonRecord(data);\r\n if (!parsedRecord) {\r\n continue;\r\n }\r\n\r\n const usageBlock = parsedRecord.usage;\r\n if (isJsonRecord(usageBlock)) {\r\n const promptTokens = readNumber(usageBlock.prompt_tokens ?? usageBlock.input_tokens);\r\n if (promptTokens !== undefined) {\r\n accumulatedUsage.inputTokens = promptTokens;\r\n }\r\n\r\n const completionTokens = readNumber(usageBlock.completion_tokens ?? usageBlock.output_tokens);\r\n if (completionTokens !== undefined) {\r\n accumulatedUsage.responseTokens = completionTokens;\r\n }\r\n\r\n const cachedTokens = readNumber(usageBlock.prompt_cache_hit_tokens);\r\n if (cachedTokens !== undefined) {\r\n accumulatedUsage.cachedTokens = cachedTokens;\r\n }\r\n\r\n const reasoningTokens = readNumber(usageBlock.reasoning_tokens);\r\n if (reasoningTokens !== undefined) {\r\n accumulatedUsage.reasoningTokens = reasoningTokens;\r\n }\r\n }\r\n\r\n const model = readString(parsedRecord.model);\r\n if (model) {\r\n accumulatedUsage.modelUsed = model;\r\n }\r\n }\r\n }\r\n } catch {\r\n // Ignore decode errors\r\n }\r\n },\r\n\r\n async flush() {\r\n // Stream completed successfully\r\n await finalizeCall(callState, usageTap, undefined, accumulatedUsage);\r\n },\r\n });\r\n\r\n // Handle stream errors and cancellation\r\n const wrappedBody = originalBody.pipeThrough(transformStream);\r\n \r\n // Note: Response doesn't have signal property, abort handling happens via stream closure\r\n\r\n return new Response(wrappedBody, {\r\n status: response.status,\r\n statusText: response.statusText,\r\n headers: response.headers,\r\n });\r\n}\r\n\r\nasync function finalizeCall(\r\n callState: CallState,\r\n usageTap: UsageTapClient,\r\n error?: { code: string; message: string },\r\n usage?: Partial<Omit<EndCallRequest, \"callId\" | \"error\">>,\r\n): Promise<void> {\r\n if (callState.finalized) return;\r\n callState.finalized = true;\r\n\r\n try {\r\n await usageTap.endCall({\r\n callId: callState.callId,\r\n ...callState.usage,\r\n ...usage,\r\n error,\r\n });\r\n } catch (err) {\r\n console.error(\"[wrapFetch] Failed to finalize call:\", err);\r\n }\r\n}\r\n"]}
|
package/dist/openai/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { NodeResponseLike, OpenAIAdapter, OpenAIAdapterInit, OpenAIInvokeParams, OpenAIInvokeResult, OpenAIStreamParams, OpenAIStreamResult, StreamMode, StreamOpenAIRouteOptions, StreamToResponseOptions, WrapOpenAICallOptions, WrapOpenAIContext, WrapOpenAIOptions, WrapOpenAIResponseCallOptions, WrappedOpenAI, createOpenAIAdapter, pipeToResponse, streamOpenAIRoute, toNextResponse, wrapOpenAI } from '../adapters/openai.cjs';
|
|
2
2
|
export { OpenRouterAdapterInit, createOpenRouterAdapter } from '../adapters/openrouter.cjs';
|
|
3
3
|
import 'openai';
|
|
4
|
-
import '../client-
|
|
4
|
+
import '../client-nU5xk2pN.cjs';
|
package/dist/openai/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { NodeResponseLike, OpenAIAdapter, OpenAIAdapterInit, OpenAIInvokeParams, OpenAIInvokeResult, OpenAIStreamParams, OpenAIStreamResult, StreamMode, StreamOpenAIRouteOptions, StreamToResponseOptions, WrapOpenAICallOptions, WrapOpenAIContext, WrapOpenAIOptions, WrapOpenAIResponseCallOptions, WrappedOpenAI, createOpenAIAdapter, pipeToResponse, streamOpenAIRoute, toNextResponse, wrapOpenAI } from '../adapters/openai.js';
|
|
2
2
|
export { OpenRouterAdapterInit, createOpenRouterAdapter } from '../adapters/openrouter.js';
|
|
3
3
|
import 'openai';
|
|
4
|
-
import '../client-
|
|
4
|
+
import '../client-nU5xk2pN.js';
|