@usagetap/sdk 0.7.0 → 0.8.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 +75 -2
- 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-nU5xk2pN.d.cts → client-BzbMP-fp.d.cts} +34 -1
- package/dist/{client-nU5xk2pN.d.ts → client-BzbMP-fp.d.ts} +34 -1
- package/dist/express/index.d.cts +1 -1
- package/dist/express/index.d.ts +1 -1
- package/dist/index.cjs +56 -4
- 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 +56 -4
- 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,9 +405,10 @@ 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`, `changePlan`, `call_begin`, `call_end`, and `checkUsage`.
|
|
408
|
+
- `UsageTapClient` – minimal HTTP client for `createCustomer`, `changePlan`, `incrementCustomMeter`, `call_begin`, `call_end`, and `checkUsage`.
|
|
409
409
|
- `createCustomer` – idempotently ensure a customer subscription exists before starting a call.
|
|
410
410
|
- `changePlan` – switch a customer to a different usage plan with configurable strategy (immediate reset, prorated, or scheduled).
|
|
411
|
+
- `incrementCustomMeter` – track custom usage metrics beyond standard LLM counters (agent actions, documents, API calls, etc.).
|
|
411
412
|
- `checkUsage` – lightweight method to query current usage status without creating a call session.
|
|
412
413
|
- `wrapFetch` – wraps a fetch function to automatically instrument OpenAI API calls (minimal integration).
|
|
413
414
|
- `createIdempotencyKey` – helper for generating UsageTap-compatible idempotency keys.
|
|
@@ -438,7 +439,7 @@ console.log("Plan:", snapshot.data.plan);
|
|
|
438
439
|
console.log("Allowed entitlements:", snapshot.data.allowed);
|
|
439
440
|
```
|
|
440
441
|
|
|
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
|
|
442
|
+
This returns the same rich subscription snapshot surfaces by `call_begin` and `checkUsage`, making it safe to cache the response for onboarding flows. Pass `idempotencyKey` in `CreateCustomerOptions` when you need deterministic keys across services; otherwise the client auto-generates one by default. Both `idempotencyKey` (preferred) and `idempotency` (deprecated) are supported.
|
|
442
443
|
|
|
443
444
|
### Change a customer's plan
|
|
444
445
|
|
|
@@ -477,6 +478,78 @@ console.log("Balances:", usageStatus.data.balances);
|
|
|
477
478
|
|
|
478
479
|
This returns the same rich usage snapshot as `call_begin` (meters, entitlements, subscription details, plan info, balances) but without creating a call record. Use this for dashboard widgets, pre-flight checks, or displaying quota status to users.
|
|
479
480
|
|
|
481
|
+
### Increment custom meters
|
|
482
|
+
|
|
483
|
+
Custom meters allow you to track usage beyond standard LLM metrics—ideal for agent actions, document processing, API calls, or any custom usage you need to meter.
|
|
484
|
+
|
|
485
|
+
```ts
|
|
486
|
+
const result = await usageTap.incrementCustomMeter({
|
|
487
|
+
customerId: "cust_123",
|
|
488
|
+
meterSlot: "CUSTOM1", // or "CUSTOM2"
|
|
489
|
+
amount: 5,
|
|
490
|
+
feature: "agent_actions",
|
|
491
|
+
tags: ["workflow_automation"],
|
|
492
|
+
metadata: {
|
|
493
|
+
workflowId: "wf_abc123",
|
|
494
|
+
actionType: "email_send",
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
|
|
498
|
+
console.log("Event recorded:", result.data.eventId);
|
|
499
|
+
console.log("Remaining quota:", result.data.meter.remaining);
|
|
500
|
+
console.log("Blocked:", result.data.blocked);
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
**Parameters:**
|
|
504
|
+
|
|
505
|
+
- `customerId` (string, required): Customer identifier
|
|
506
|
+
- `meterSlot` ("CUSTOM1" | "CUSTOM2", required): Which custom meter to increment
|
|
507
|
+
- `amount` (number, required): Positive number to decrement from quota
|
|
508
|
+
- `feature` (string, optional): Feature identifier for tracking
|
|
509
|
+
- `tags` (string[], optional): Tags for categorization
|
|
510
|
+
- `metadata` (object, optional): Additional metadata
|
|
511
|
+
|
|
512
|
+
The method returns the updated meter snapshot showing remaining quota, limits, and usage. If the customer's plan has `limitType: "BLOCK"` and quota is exceeded, a `UsageTapError` is thrown with code `USAGETAP_AUTH_ERROR`.
|
|
513
|
+
|
|
514
|
+
**Use cases:**
|
|
515
|
+
|
|
516
|
+
```ts
|
|
517
|
+
// Track agent tool invocations
|
|
518
|
+
await usageTap.incrementCustomMeter({
|
|
519
|
+
customerId: "cust_123",
|
|
520
|
+
meterSlot: "CUSTOM1",
|
|
521
|
+
amount: 1,
|
|
522
|
+
feature: "agent.tool_call",
|
|
523
|
+
tags: ["web_search"],
|
|
524
|
+
});
|
|
525
|
+
|
|
526
|
+
// Track document processing (10 pages)
|
|
527
|
+
await usageTap.incrementCustomMeter({
|
|
528
|
+
customerId: "cust_456",
|
|
529
|
+
meterSlot: "CUSTOM2",
|
|
530
|
+
amount: 10,
|
|
531
|
+
feature: "document.ocr",
|
|
532
|
+
metadata: { documentId: "doc_789", pages: 10 },
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
// Track external API calls
|
|
536
|
+
await usageTap.incrementCustomMeter({
|
|
537
|
+
customerId: "cust_789",
|
|
538
|
+
meterSlot: "CUSTOM1",
|
|
539
|
+
amount: 1,
|
|
540
|
+
feature: "external_api.maps",
|
|
541
|
+
tags: ["geocoding"],
|
|
542
|
+
});
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
**Important notes:**
|
|
546
|
+
|
|
547
|
+
1. Custom meters must be enabled in the customer's usage plan
|
|
548
|
+
2. The `amount` decrements the remaining quota (like token usage)
|
|
549
|
+
3. With `BLOCK` policy, exceeding quota throws an error
|
|
550
|
+
4. With `DOWNGRADE` policy, usage continues but quota can go negative
|
|
551
|
+
5. Unlimited meters don't track usage but still record events for analytics
|
|
552
|
+
|
|
480
553
|
## Response envelope (canonical only)
|
|
481
554
|
|
|
482
555
|
UsageTap responds exclusively with the canonical `{ result, data, correlationId }` envelope for every endpoint. The SDK automatically sends `Accept: application/vnd.usagetap.v1+json`, parses the envelope, and returns strongly typed data structures. Transitional `raw` payloads and the `normalize*` helpers have been removed—`response.data` already contains the canonical shape you should persist or render.
|
|
@@ -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-BzbMP-fp.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-BzbMP-fp.js';
|
|
3
3
|
|
|
4
4
|
interface OpenAIAdapterInit {
|
|
5
5
|
client: OpenAI;
|
|
@@ -26,6 +26,7 @@ interface MeterSummary {
|
|
|
26
26
|
used: number | null;
|
|
27
27
|
unlimited: boolean;
|
|
28
28
|
ratio: number | null;
|
|
29
|
+
label?: string;
|
|
29
30
|
}
|
|
30
31
|
type MeterSnapshot = Record<string, MeterSummary>;
|
|
31
32
|
type RemainingRatios = Record<string, number | null | undefined>;
|
|
@@ -64,7 +65,15 @@ interface BeginCallRequest {
|
|
|
64
65
|
requested?: RequestedEntitlements;
|
|
65
66
|
feature?: string;
|
|
66
67
|
tags?: string[];
|
|
68
|
+
/**
|
|
69
|
+
* Idempotency key for safe retries. When omitted, UsageTap derives a key deterministically.
|
|
70
|
+
* @deprecated Use idempotencyKey instead
|
|
71
|
+
*/
|
|
67
72
|
idempotency?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Idempotency key for safe retries. When omitted, UsageTap derives a key deterministically.
|
|
75
|
+
*/
|
|
76
|
+
idempotencyKey?: string;
|
|
68
77
|
customerName?: string;
|
|
69
78
|
customerEmail?: string;
|
|
70
79
|
stripeCustomerId?: string;
|
|
@@ -75,6 +84,8 @@ interface BalanceSummary {
|
|
|
75
84
|
tokensRemaining?: number;
|
|
76
85
|
searchesRemaining?: number;
|
|
77
86
|
audioSecondsRemaining?: number;
|
|
87
|
+
customMeter1Remaining?: number;
|
|
88
|
+
customMeter2Remaining?: number;
|
|
78
89
|
}
|
|
79
90
|
interface PlanSummary {
|
|
80
91
|
id: string | null;
|
|
@@ -283,6 +294,27 @@ interface ChangePlanResponseBody {
|
|
|
283
294
|
success: boolean;
|
|
284
295
|
subscription: SubscriptionSnapshot;
|
|
285
296
|
}
|
|
297
|
+
type CustomMeterSlot = "CUSTOM1" | "CUSTOM2";
|
|
298
|
+
interface IncrementCustomMeterRequest {
|
|
299
|
+
customerId: string;
|
|
300
|
+
meterSlot: CustomMeterSlot;
|
|
301
|
+
amount: number;
|
|
302
|
+
feature?: string;
|
|
303
|
+
tags?: string[];
|
|
304
|
+
metadata?: Record<string, unknown>;
|
|
305
|
+
}
|
|
306
|
+
interface IncrementCustomMeterOptions extends RequestOptions {
|
|
307
|
+
correlationId?: string;
|
|
308
|
+
idempotencyKey?: string;
|
|
309
|
+
}
|
|
310
|
+
interface IncrementCustomMeterResponseBody {
|
|
311
|
+
success: boolean;
|
|
312
|
+
eventId: string;
|
|
313
|
+
meterSlot: CustomMeterSlot;
|
|
314
|
+
amount: number;
|
|
315
|
+
meter: MeterSummary;
|
|
316
|
+
blocked: boolean;
|
|
317
|
+
}
|
|
286
318
|
|
|
287
319
|
declare class UsageTapClient {
|
|
288
320
|
private readonly apiKey;
|
|
@@ -302,6 +334,7 @@ declare class UsageTapClient {
|
|
|
302
334
|
checkUsage(request: CheckUsageRequest, options?: CheckUsageOptions): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>>;
|
|
303
335
|
createCustomer(request: CreateCustomerRequest, options?: CreateCustomerOptions): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>>;
|
|
304
336
|
changePlan(request: ChangePlanRequest, options?: ChangePlanOptions): Promise<UsageTapSuccessResponse<ChangePlanResponseBody>>;
|
|
337
|
+
incrementCustomMeter(request: IncrementCustomMeterRequest, options?: IncrementCustomMeterOptions): Promise<UsageTapSuccessResponse<IncrementCustomMeterResponseBody>>;
|
|
305
338
|
withUsage<T>(beginRequest: BeginCallRequest, handler: (context: WithUsageContext) => Promise<T>, options?: WithUsageOptions): Promise<T>;
|
|
306
339
|
private request;
|
|
307
340
|
private requestGet;
|
|
@@ -314,4 +347,4 @@ declare class UsageTapClient {
|
|
|
314
347
|
private toApiError;
|
|
315
348
|
}
|
|
316
349
|
|
|
317
|
-
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type
|
|
350
|
+
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type UsageTapResultStatus as D, type EndCallRequest as E, type UsageTapLogEntry as F, type WithUsageContext as G, type ModelHints as H, type IncrementCustomMeterOptions as I, type IdempotencyMetadata as J, 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 IncrementCustomMeterRequest as m, type IncrementCustomMeterResponseBody as n, type CustomMeterSlot as o, type EndCallOptions as p, type EndCallResponseBody as q, type BalanceSummary as r, type EntitlementHints as s, type MeterSnapshot as t, type MeteredUsage as u, type RequestedEntitlements as v, type RetryOptions as w, type UsageTapClientOptions as x, type UsageTapErrorResponse as y, type UsageTapResultEnvelope as z };
|
|
@@ -26,6 +26,7 @@ interface MeterSummary {
|
|
|
26
26
|
used: number | null;
|
|
27
27
|
unlimited: boolean;
|
|
28
28
|
ratio: number | null;
|
|
29
|
+
label?: string;
|
|
29
30
|
}
|
|
30
31
|
type MeterSnapshot = Record<string, MeterSummary>;
|
|
31
32
|
type RemainingRatios = Record<string, number | null | undefined>;
|
|
@@ -64,7 +65,15 @@ interface BeginCallRequest {
|
|
|
64
65
|
requested?: RequestedEntitlements;
|
|
65
66
|
feature?: string;
|
|
66
67
|
tags?: string[];
|
|
68
|
+
/**
|
|
69
|
+
* Idempotency key for safe retries. When omitted, UsageTap derives a key deterministically.
|
|
70
|
+
* @deprecated Use idempotencyKey instead
|
|
71
|
+
*/
|
|
67
72
|
idempotency?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Idempotency key for safe retries. When omitted, UsageTap derives a key deterministically.
|
|
75
|
+
*/
|
|
76
|
+
idempotencyKey?: string;
|
|
68
77
|
customerName?: string;
|
|
69
78
|
customerEmail?: string;
|
|
70
79
|
stripeCustomerId?: string;
|
|
@@ -75,6 +84,8 @@ interface BalanceSummary {
|
|
|
75
84
|
tokensRemaining?: number;
|
|
76
85
|
searchesRemaining?: number;
|
|
77
86
|
audioSecondsRemaining?: number;
|
|
87
|
+
customMeter1Remaining?: number;
|
|
88
|
+
customMeter2Remaining?: number;
|
|
78
89
|
}
|
|
79
90
|
interface PlanSummary {
|
|
80
91
|
id: string | null;
|
|
@@ -283,6 +294,27 @@ interface ChangePlanResponseBody {
|
|
|
283
294
|
success: boolean;
|
|
284
295
|
subscription: SubscriptionSnapshot;
|
|
285
296
|
}
|
|
297
|
+
type CustomMeterSlot = "CUSTOM1" | "CUSTOM2";
|
|
298
|
+
interface IncrementCustomMeterRequest {
|
|
299
|
+
customerId: string;
|
|
300
|
+
meterSlot: CustomMeterSlot;
|
|
301
|
+
amount: number;
|
|
302
|
+
feature?: string;
|
|
303
|
+
tags?: string[];
|
|
304
|
+
metadata?: Record<string, unknown>;
|
|
305
|
+
}
|
|
306
|
+
interface IncrementCustomMeterOptions extends RequestOptions {
|
|
307
|
+
correlationId?: string;
|
|
308
|
+
idempotencyKey?: string;
|
|
309
|
+
}
|
|
310
|
+
interface IncrementCustomMeterResponseBody {
|
|
311
|
+
success: boolean;
|
|
312
|
+
eventId: string;
|
|
313
|
+
meterSlot: CustomMeterSlot;
|
|
314
|
+
amount: number;
|
|
315
|
+
meter: MeterSummary;
|
|
316
|
+
blocked: boolean;
|
|
317
|
+
}
|
|
286
318
|
|
|
287
319
|
declare class UsageTapClient {
|
|
288
320
|
private readonly apiKey;
|
|
@@ -302,6 +334,7 @@ declare class UsageTapClient {
|
|
|
302
334
|
checkUsage(request: CheckUsageRequest, options?: CheckUsageOptions): Promise<UsageTapSuccessResponse<CheckUsageResponseBody>>;
|
|
303
335
|
createCustomer(request: CreateCustomerRequest, options?: CreateCustomerOptions): Promise<UsageTapSuccessResponse<CreateCustomerResponseBody>>;
|
|
304
336
|
changePlan(request: ChangePlanRequest, options?: ChangePlanOptions): Promise<UsageTapSuccessResponse<ChangePlanResponseBody>>;
|
|
337
|
+
incrementCustomMeter(request: IncrementCustomMeterRequest, options?: IncrementCustomMeterOptions): Promise<UsageTapSuccessResponse<IncrementCustomMeterResponseBody>>;
|
|
305
338
|
withUsage<T>(beginRequest: BeginCallRequest, handler: (context: WithUsageContext) => Promise<T>, options?: WithUsageOptions): Promise<T>;
|
|
306
339
|
private request;
|
|
307
340
|
private requestGet;
|
|
@@ -314,4 +347,4 @@ declare class UsageTapClient {
|
|
|
314
347
|
private toApiError;
|
|
315
348
|
}
|
|
316
349
|
|
|
317
|
-
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type
|
|
350
|
+
export { type AllowedEntitlements as A, type BeginCallRequest as B, type CreateCustomerOptions as C, type UsageTapResultStatus as D, type EndCallRequest as E, type UsageTapLogEntry as F, type WithUsageContext as G, type ModelHints as H, type IncrementCustomMeterOptions as I, type IdempotencyMetadata as J, 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 IncrementCustomMeterRequest as m, type IncrementCustomMeterResponseBody as n, type CustomMeterSlot as o, type EndCallOptions as p, type EndCallResponseBody as q, type BalanceSummary as r, type EntitlementHints as s, type MeterSnapshot as t, type MeteredUsage as u, type RequestedEntitlements as v, type RetryOptions as w, type UsageTapClientOptions as x, type UsageTapErrorResponse as y, type UsageTapResultEnvelope 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-BzbMP-fp.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-BzbMP-fp.js';
|
|
4
4
|
import { WrapOpenAIContext, WrapOpenAIOptions, wrapOpenAI, pipeToResponse } from '../adapters/openai.js';
|
|
5
5
|
|
|
6
6
|
interface ExpressUsageTapContext {
|
package/dist/index.cjs
CHANGED
|
@@ -121,6 +121,7 @@ var CALL_END_PATH = "call_end";
|
|
|
121
121
|
var CHECK_USAGE_PATH = "customers/{customerId}/usage";
|
|
122
122
|
var CREATE_CUSTOMER_PATH = "customers";
|
|
123
123
|
var CHANGE_PLAN_PATH = "customers/{customerId}/change_plan";
|
|
124
|
+
var INCREMENT_CUSTOM_METER_PATH = "custom_meter";
|
|
124
125
|
var AUTH_HEADER = "authorization";
|
|
125
126
|
var API_KEY_HEADER = "x-api-key";
|
|
126
127
|
var CORRELATION_HEADER = "x-usage-correlation-id";
|
|
@@ -128,7 +129,7 @@ var IDEMPOTENCY_HEADER = "idempotency-key";
|
|
|
128
129
|
var SDK_HEADER = "x-usage-sdk";
|
|
129
130
|
var USER_AGENT = "UsageTapClient";
|
|
130
131
|
var CANONICAL_MEDIA_TYPE = "application/vnd.usagetap.v1+json";
|
|
131
|
-
var SDK_VERSION = "0.
|
|
132
|
+
var SDK_VERSION = "0.8.0" ;
|
|
132
133
|
var HAS_WINDOW = typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
|
|
133
134
|
var UsageTapClient = class {
|
|
134
135
|
apiKey;
|
|
@@ -188,13 +189,14 @@ var UsageTapClient = class {
|
|
|
188
189
|
this.autoIdempotency = options.autoIdempotency ?? true;
|
|
189
190
|
}
|
|
190
191
|
async beginCall(request, options = {}) {
|
|
191
|
-
const idempotencyKey = request.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
192
|
+
const idempotencyKey = request.idempotencyKey ?? request.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
192
193
|
const payload = {
|
|
193
194
|
...request,
|
|
194
195
|
feature: request.feature ?? this.defaultFeature,
|
|
195
196
|
tags: this.mergeTags(request.tags)
|
|
196
197
|
};
|
|
197
198
|
if (idempotencyKey) {
|
|
199
|
+
payload.idempotencyKey = idempotencyKey;
|
|
198
200
|
payload.idempotency = idempotencyKey;
|
|
199
201
|
}
|
|
200
202
|
const response = await this.request(
|
|
@@ -289,9 +291,59 @@ var UsageTapClient = class {
|
|
|
289
291
|
);
|
|
290
292
|
return response;
|
|
291
293
|
}
|
|
294
|
+
async incrementCustomMeter(request, options = {}) {
|
|
295
|
+
if (!request?.customerId) {
|
|
296
|
+
throw new UsageTapError(
|
|
297
|
+
"USAGETAP_BAD_REQUEST",
|
|
298
|
+
"incrementCustomMeter requires customerId"
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
if (!request?.meterSlot) {
|
|
302
|
+
throw new UsageTapError(
|
|
303
|
+
"USAGETAP_BAD_REQUEST",
|
|
304
|
+
"incrementCustomMeter requires meterSlot"
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
if (!["CUSTOM1", "CUSTOM2"].includes(request.meterSlot)) {
|
|
308
|
+
throw new UsageTapError(
|
|
309
|
+
"USAGETAP_BAD_REQUEST",
|
|
310
|
+
"meterSlot must be CUSTOM1 or CUSTOM2"
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
if (typeof request.amount !== "number" || !Number.isFinite(request.amount) || request.amount <= 0) {
|
|
314
|
+
throw new UsageTapError(
|
|
315
|
+
"USAGETAP_BAD_REQUEST",
|
|
316
|
+
"incrementCustomMeter requires a positive numeric amount"
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
const idempotencyKey = options.idempotencyKey ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
320
|
+
const payload = {
|
|
321
|
+
customerId: request.customerId,
|
|
322
|
+
meterSlot: request.meterSlot,
|
|
323
|
+
amount: request.amount
|
|
324
|
+
};
|
|
325
|
+
if (request.feature) {
|
|
326
|
+
payload.feature = request.feature;
|
|
327
|
+
}
|
|
328
|
+
if (request.tags && request.tags.length > 0) {
|
|
329
|
+
payload.tags = request.tags;
|
|
330
|
+
}
|
|
331
|
+
if (request.metadata) {
|
|
332
|
+
payload.metadata = request.metadata;
|
|
333
|
+
}
|
|
334
|
+
const response = await this.request(
|
|
335
|
+
INCREMENT_CUSTOM_METER_PATH,
|
|
336
|
+
payload,
|
|
337
|
+
{
|
|
338
|
+
...options,
|
|
339
|
+
idempotencyKey
|
|
340
|
+
}
|
|
341
|
+
);
|
|
342
|
+
return response;
|
|
343
|
+
}
|
|
292
344
|
async withUsage(beginRequest, handler, options = {}) {
|
|
293
|
-
const idempotencyKey = beginRequest.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
294
|
-
const beginPayload = idempotencyKey ? { ...beginRequest, idempotency: idempotencyKey } : { ...beginRequest };
|
|
345
|
+
const idempotencyKey = beginRequest.idempotencyKey ?? beginRequest.idempotency ?? (this.autoIdempotency ? this.idempotencyGenerator() : void 0);
|
|
346
|
+
const beginPayload = idempotencyKey ? { ...beginRequest, idempotencyKey, idempotency: idempotencyKey } : { ...beginRequest };
|
|
295
347
|
const beginResponse = await this.beginCall(beginPayload, options);
|
|
296
348
|
let usage = {};
|
|
297
349
|
const initialStripeCustomerId = typeof beginResponse.data.stripeCustomerId === "string" ? beginResponse.data.stripeCustomerId : typeof beginRequest.stripeCustomerId === "string" ? beginRequest.stripeCustomerId : void 0;
|