@commet/node 0.3.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 ADDED
@@ -0,0 +1,186 @@
1
+ # @commet/node
2
+
3
+ TypeScript SDK for Commet billing platform - track usage, manage seats, and handle customers.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @commet/node
9
+ # or
10
+ pnpm add @commet/node
11
+ # or
12
+ yarn add @commet/node
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Commet } from '@commet/node';
19
+
20
+ const commet = new Commet({
21
+ apiKey: process.env.COMMET_API_KEY!,
22
+ environment: 'production', // or 'sandbox' (default)
23
+ debug: false, // Enable debug logging
24
+ });
25
+ ```
26
+
27
+ ## Usage Examples
28
+
29
+ ### Usage Events (Consumption-Based Billing)
30
+
31
+ ```typescript
32
+ // Send a single event
33
+ await commet.usage.events.create({
34
+ eventType: 'api_call',
35
+ customerId: 'cus_123',
36
+ timestamp: new Date().toISOString(),
37
+ properties: [
38
+ { property: 'endpoint', value: '/api/users' },
39
+ { property: 'method', value: 'GET' }
40
+ ]
41
+ });
42
+
43
+ // Batch events
44
+ await commet.usage.events.createBatch({
45
+ events: [
46
+ { eventType: 'api_call', customerId: 'cus_123' },
47
+ { eventType: 'api_call', customerId: 'cus_456' },
48
+ ]
49
+ });
50
+
51
+ // List events
52
+ const events = await commet.usage.events.list({
53
+ customerId: 'cus_123',
54
+ limit: 100
55
+ });
56
+ ```
57
+
58
+ ### Seat Management (Per-Seat Licensing)
59
+
60
+ ```typescript
61
+ // Add seats
62
+ await commet.seats.add('cus_123', 'admin_seat', 5);
63
+
64
+ // Remove seats
65
+ await commet.seats.remove('cus_123', 'admin_seat', 2);
66
+
67
+ // Set exact count
68
+ await commet.seats.set('cus_123', 'admin_seat', 10);
69
+
70
+ // Get balance
71
+ const balance = await commet.seats.getBalance('cus_123', 'admin_seat');
72
+ console.log(balance.current); // 10
73
+
74
+ // Bulk update
75
+ await commet.seats.bulkUpdate('cus_123', {
76
+ admin_seat: 5,
77
+ editor_seat: 20,
78
+ viewer_seat: 100
79
+ });
80
+ ```
81
+
82
+ ### Customer Management
83
+
84
+ ```typescript
85
+ // Create customer
86
+ const customer = await commet.customers.create({
87
+ legalName: 'Acme Corporation',
88
+ displayName: 'Acme',
89
+ currency: 'USD',
90
+ taxStatus: 'TAXED',
91
+ address: {
92
+ line1: '123 Main St',
93
+ city: 'San Francisco',
94
+ state: 'CA',
95
+ postalCode: '94105',
96
+ country: 'US'
97
+ },
98
+ billingEmail: 'billing@acme.com'
99
+ });
100
+
101
+ // Update customer
102
+ await commet.customers.update('cus_123', {
103
+ displayName: 'Acme Inc',
104
+ billingEmail: 'finance@acme.com'
105
+ });
106
+
107
+ // List customers
108
+ const customers = await commet.customers.list({
109
+ isActive: true,
110
+ limit: 50
111
+ });
112
+
113
+ // Deactivate customer
114
+ await commet.customers.deactivate('cus_123');
115
+ ```
116
+
117
+ ## API Reference
118
+
119
+ ### Configuration
120
+
121
+ ```typescript
122
+ interface CommetConfig {
123
+ apiKey: string; // Required: Your Commet API key
124
+ environment?: 'sandbox' | 'production'; // Default: 'sandbox'
125
+ debug?: boolean; // Default: false
126
+ timeout?: number; // Request timeout in ms (default: 30000)
127
+ retries?: number; // Max retry attempts (default: 3)
128
+ }
129
+ ```
130
+
131
+ ### Resources
132
+
133
+ - `commet.usage.events` - Usage event tracking
134
+ - `commet.usage.metrics` - Usage metrics (read-only)
135
+ - `commet.seats` - Seat management
136
+ - `commet.customers` - Customer CRUD operations
137
+
138
+ ### Error Handling
139
+
140
+ ```typescript
141
+ import { CommetAPIError, CommetValidationError } from '@commet/node';
142
+
143
+ try {
144
+ await commet.usage.events.create({ ... });
145
+ } catch (error) {
146
+ if (error instanceof CommetValidationError) {
147
+ console.error('Validation errors:', error.validationErrors);
148
+ } else if (error instanceof CommetAPIError) {
149
+ console.error('API error:', error.statusCode, error.message);
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## Environment Detection
155
+
156
+ ```typescript
157
+ // Check environment
158
+ console.log(commet.getEnvironment()); // 'sandbox' | 'production'
159
+ console.log(commet.isSandbox()); // boolean
160
+ console.log(commet.isProduction()); // boolean
161
+ ```
162
+
163
+ ## TypeScript Support
164
+
165
+ Fully typed with TypeScript. All API responses and parameters are type-safe.
166
+
167
+ ```typescript
168
+ import type {
169
+ Customer,
170
+ UsageEvent,
171
+ SeatBalance,
172
+ Currency
173
+ } from '@commet/node';
174
+ ```
175
+
176
+ ## Links
177
+
178
+ - [Documentation](https://docs.commet.co)
179
+ - [API Reference](https://docs.commet.co/api)
180
+ - [GitHub](https://github.com/commet-labs/commet-node)
181
+ - [Issues](https://github.com/commet-labs/commet-node/issues)
182
+
183
+ ## License
184
+
185
+ MIT
186
+
@@ -0,0 +1,368 @@
1
+ type Environment = "sandbox" | "production";
2
+ type CommetConfig = {
3
+ apiKey: string;
4
+ environment?: Environment;
5
+ debug?: boolean;
6
+ timeout?: number;
7
+ retries?: number;
8
+ };
9
+ interface ApiResponse<T = unknown> {
10
+ success: boolean;
11
+ data?: T;
12
+ error?: string;
13
+ message?: string;
14
+ hasMore?: boolean;
15
+ nextCursor?: string;
16
+ }
17
+ interface PaginatedResponse<T> {
18
+ data: T[];
19
+ hasMore: boolean;
20
+ nextCursor?: string;
21
+ totalCount?: number;
22
+ }
23
+ interface PaginatedList<T> extends PaginatedResponse<T> {
24
+ next(): Promise<PaginatedList<T>>;
25
+ all(): Promise<T[]>;
26
+ }
27
+ declare class CommetError extends Error {
28
+ code?: string | undefined;
29
+ statusCode?: number | undefined;
30
+ details?: unknown | undefined;
31
+ constructor(message: string, code?: string | undefined, statusCode?: number | undefined, details?: unknown | undefined);
32
+ }
33
+ declare class CommetAPIError extends CommetError {
34
+ statusCode: number;
35
+ code?: string | undefined;
36
+ details?: unknown | undefined;
37
+ constructor(message: string, statusCode: number, code?: string | undefined, details?: unknown | undefined);
38
+ }
39
+ declare class CommetValidationError extends CommetError {
40
+ validationErrors: Record<string, string[]>;
41
+ constructor(message: string, validationErrors: Record<string, string[]>);
42
+ }
43
+ type CustomerID = `cus_${string}`;
44
+ type AgreementID = `agr_${string}`;
45
+ type InvoiceID = `inv_${string}`;
46
+ type PhaseID = `phs_${string}`;
47
+ type ItemID = `itm_${string}`;
48
+ type ProductID = `prd_${string}`;
49
+ type EventID = `evt_${string}`;
50
+ type WebhookID = `wh_${string}`;
51
+ type Currency = "USD" | "EUR" | "GBP" | "CAD" | "AUD" | "JPY" | "ARS" | "BRL" | "MXN" | "CLP";
52
+ interface ListParams extends Record<string, unknown> {
53
+ limit?: number;
54
+ cursor?: string;
55
+ startDate?: string;
56
+ endDate?: string;
57
+ }
58
+ interface RetrieveOptions {
59
+ expand?: string[];
60
+ }
61
+ interface RequestOptions {
62
+ idempotencyKey?: string;
63
+ timeout?: number;
64
+ }
65
+
66
+ declare class CommetHTTPClient {
67
+ private config;
68
+ private environment;
69
+ private retryConfig;
70
+ constructor(config: CommetConfig, environment: Environment);
71
+ get<T = unknown>(endpoint: string, params?: Record<string, unknown>, options?: RequestOptions): Promise<ApiResponse<T>>;
72
+ post<T = unknown>(endpoint: string, data?: unknown, options?: RequestOptions): Promise<ApiResponse<T>>;
73
+ put<T = unknown>(endpoint: string, data?: unknown, options?: RequestOptions): Promise<ApiResponse<T>>;
74
+ delete<T = unknown>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>>;
75
+ /**
76
+ * Core request method with retry logic
77
+ */
78
+ private request;
79
+ /**
80
+ * Execute real API request with retry logic
81
+ */
82
+ private executeRequest;
83
+ /**
84
+ * Get base URL based on environment
85
+ */
86
+ private getBaseURL;
87
+ /**
88
+ * Build full URL from endpoint and params
89
+ */
90
+ private buildURL;
91
+ /**
92
+ * Generate idempotency key
93
+ */
94
+ private generateIdempotencyKey;
95
+ /**
96
+ * Sleep for specified milliseconds
97
+ */
98
+ private sleep;
99
+ }
100
+
101
+ interface Customer {
102
+ id: CustomerID;
103
+ organizationId: string;
104
+ externalId?: string;
105
+ legalName: string;
106
+ displayName?: string;
107
+ domain?: string;
108
+ website?: string;
109
+ taxStatus: "TAXED" | "TAX_EXEMPT" | "REVERSE_CHARGE" | "NOT_APPLICABLE";
110
+ currency: Currency;
111
+ addressId: string;
112
+ billingEmail?: string;
113
+ paymentTerms?: string;
114
+ timezone?: string;
115
+ language?: string;
116
+ industry?: string;
117
+ employeeCount?: string;
118
+ metadata?: Record<string, unknown>;
119
+ isActive: boolean;
120
+ createdAt: string;
121
+ updatedAt: string;
122
+ }
123
+ interface CreateCustomerBaseParams {
124
+ externalId?: string;
125
+ legalName: string;
126
+ displayName?: string;
127
+ domain?: string;
128
+ website?: string;
129
+ currency?: Currency;
130
+ billingEmail?: string;
131
+ paymentTerms?: string;
132
+ timezone?: string;
133
+ language?: string;
134
+ industry?: string;
135
+ employeeCount?: string;
136
+ metadata?: Record<string, unknown>;
137
+ }
138
+ interface CustomerAddress {
139
+ line1: string;
140
+ line2?: string;
141
+ city: string;
142
+ state?: string;
143
+ postalCode: string;
144
+ country: string;
145
+ region?: string;
146
+ }
147
+ interface CreateCustomerTaxed extends CreateCustomerBaseParams {
148
+ taxStatus: "TAXED";
149
+ address: CustomerAddress;
150
+ }
151
+ interface CreateCustomerOtherTaxStatus extends CreateCustomerBaseParams {
152
+ taxStatus?: "TAX_EXEMPT" | "REVERSE_CHARGE" | "NOT_APPLICABLE";
153
+ address?: CustomerAddress;
154
+ }
155
+ type CreateCustomerParams = CreateCustomerTaxed | CreateCustomerOtherTaxStatus;
156
+ interface UpdateCustomerParams {
157
+ externalId?: string;
158
+ legalName?: string;
159
+ displayName?: string;
160
+ domain?: string;
161
+ website?: string;
162
+ taxStatus?: "TAXED" | "TAX_EXEMPT" | "REVERSE_CHARGE" | "NOT_APPLICABLE";
163
+ currency?: Currency;
164
+ billingEmail?: string;
165
+ paymentTerms?: string;
166
+ timezone?: string;
167
+ language?: string;
168
+ industry?: string;
169
+ employeeCount?: string;
170
+ metadata?: Record<string, unknown>;
171
+ isActive?: boolean;
172
+ }
173
+ interface ListCustomersParams extends ListParams {
174
+ externalId?: string;
175
+ taxStatus?: "TAXED" | "TAX_EXEMPT" | "REVERSE_CHARGE" | "NOT_APPLICABLE";
176
+ currency?: Currency;
177
+ isActive?: boolean;
178
+ search?: string;
179
+ }
180
+ /**
181
+ * Customer resource for managing customer data
182
+ */
183
+ declare class CustomersResource {
184
+ private httpClient;
185
+ constructor(httpClient: CommetHTTPClient);
186
+ create(params: CreateCustomerParams, options?: RequestOptions): Promise<ApiResponse<Customer>>;
187
+ retrieve(customerId: CustomerID, options?: RetrieveOptions): Promise<ApiResponse<Customer>>;
188
+ update(customerId: CustomerID, params: UpdateCustomerParams, options?: RequestOptions): Promise<ApiResponse<Customer>>;
189
+ list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>>;
190
+ /**
191
+ * Deactivate a customer (soft delete)
192
+ */
193
+ deactivate(customerId: CustomerID, options?: RequestOptions): Promise<ApiResponse<Customer>>;
194
+ }
195
+
196
+ interface SeatBalance {
197
+ id: string;
198
+ organizationId: string;
199
+ customerId: CustomerID;
200
+ seatType: string;
201
+ balance: number;
202
+ asOf: string;
203
+ createdAt: string;
204
+ updatedAt: string;
205
+ }
206
+ interface SeatEvent {
207
+ id: string;
208
+ organizationId: string;
209
+ customerId: CustomerID;
210
+ seatType: string;
211
+ eventType: "add" | "remove" | "set";
212
+ quantity: number;
213
+ previousBalance?: number;
214
+ newBalance: number;
215
+ ts: string;
216
+ createdAt: string;
217
+ }
218
+ interface SeatBalanceResponse {
219
+ current: number;
220
+ asOf: string;
221
+ }
222
+ interface BulkSeatUpdate {
223
+ [seatType: string]: number;
224
+ }
225
+ interface ListSeatEventsParams extends ListParams {
226
+ customerId?: CustomerID;
227
+ seatType?: string;
228
+ eventType?: "add" | "remove" | "set";
229
+ }
230
+ /**
231
+ * Seats resource for seat-based billing management
232
+ */
233
+ declare class SeatsResource {
234
+ private httpClient;
235
+ constructor(httpClient: CommetHTTPClient);
236
+ add(customerId: CustomerID, seatType: string, count: number, options?: RequestOptions): Promise<ApiResponse<SeatEvent>>;
237
+ remove(customerId: CustomerID, seatType: string, count: number, options?: RequestOptions): Promise<ApiResponse<SeatEvent>>;
238
+ set(customerId: CustomerID, seatType: string, count: number, options?: RequestOptions): Promise<ApiResponse<SeatEvent>>;
239
+ bulkUpdate(customerId: CustomerID, seats: BulkSeatUpdate, options?: RequestOptions): Promise<ApiResponse<SeatEvent[]>>;
240
+ getBalance(customerId: CustomerID, seatType: string): Promise<ApiResponse<SeatBalanceResponse>>;
241
+ getAllBalances(customerId: CustomerID): Promise<ApiResponse<Record<string, SeatBalanceResponse>>>;
242
+ getHistory(customerId: CustomerID, seatType: string, params?: ListSeatEventsParams): Promise<ApiResponse<SeatEvent[]>>;
243
+ listEvents(params?: ListSeatEventsParams): Promise<ApiResponse<SeatEvent[]>>;
244
+ }
245
+
246
+ interface UsageEvent {
247
+ id: EventID;
248
+ organizationId: string;
249
+ customerId: CustomerID;
250
+ eventType: string;
251
+ idempotencyKey?: string;
252
+ ts: string;
253
+ properties?: UsageEventProperty[];
254
+ createdAt: string;
255
+ }
256
+ interface UsageEventProperty {
257
+ id: string;
258
+ usageEventId: EventID;
259
+ property: string;
260
+ value: string;
261
+ createdAt: string;
262
+ }
263
+ interface CreateUsageEventParams {
264
+ eventType: string;
265
+ customerId: CustomerID;
266
+ idempotencyKey?: string;
267
+ timestamp?: string;
268
+ properties?: Array<{
269
+ property: string;
270
+ value: string;
271
+ }>;
272
+ }
273
+ interface CreateBatchUsageEventsParams {
274
+ events: CreateUsageEventParams[];
275
+ }
276
+ interface BatchResult<T> {
277
+ successful: T[];
278
+ failed: Array<{
279
+ index: number;
280
+ error: string;
281
+ data: CreateUsageEventParams;
282
+ }>;
283
+ }
284
+ interface ListUsageEventsParams extends ListParams {
285
+ customerId?: CustomerID;
286
+ eventType?: string;
287
+ idempotencyKey?: string;
288
+ }
289
+ /**
290
+ * Usage Events resource - Track business events for usage-based billing
291
+ */
292
+ declare class UsageEventsResource {
293
+ private httpClient;
294
+ constructor(httpClient: CommetHTTPClient);
295
+ create(params: CreateUsageEventParams, options?: RequestOptions): Promise<ApiResponse<UsageEvent>>;
296
+ createBatch(params: CreateBatchUsageEventsParams, options?: RequestOptions): Promise<ApiResponse<BatchResult<UsageEvent>>>;
297
+ retrieve(eventId: EventID): Promise<ApiResponse<UsageEvent>>;
298
+ list(params?: ListUsageEventsParams): Promise<ApiResponse<UsageEvent[]>>;
299
+ delete(eventId: EventID, options?: RequestOptions): Promise<ApiResponse<{
300
+ deleted: boolean;
301
+ }>>;
302
+ }
303
+ interface UsageMetric {
304
+ id: string;
305
+ organizationId: string;
306
+ name: string;
307
+ eventType: string;
308
+ aggregation: "count" | "unique" | "sum";
309
+ property?: string;
310
+ filters?: UsageMetricFilter[];
311
+ createdAt: string;
312
+ updatedAt: string;
313
+ }
314
+ interface UsageMetricFilter {
315
+ id: string;
316
+ usageMetricId: string;
317
+ property: string;
318
+ operator: "equals" | "not_equals" | "greater_than" | "less_than" | "contains";
319
+ value: string;
320
+ createdAt: string;
321
+ }
322
+ /**
323
+ * Usage Metrics resource - Read-only access to metrics
324
+ */
325
+ declare class UsageMetricsResource {
326
+ private httpClient;
327
+ constructor(httpClient: CommetHTTPClient);
328
+ list(): Promise<ApiResponse<UsageMetric[]>>;
329
+ retrieve(metricId: string): Promise<ApiResponse<UsageMetric>>;
330
+ }
331
+ /**
332
+ * Usage resource combining events and metrics
333
+ */
334
+ declare class UsageResource {
335
+ readonly events: UsageEventsResource;
336
+ readonly metrics: UsageMetricsResource;
337
+ constructor(httpClient: CommetHTTPClient);
338
+ }
339
+
340
+ /**
341
+ * Main Commet SDK client
342
+ */
343
+ declare class Commet {
344
+ private httpClient;
345
+ private environment;
346
+ readonly customers: CustomersResource;
347
+ readonly usage: UsageResource;
348
+ readonly seats: SeatsResource;
349
+ constructor(config: CommetConfig);
350
+ getEnvironment(): Environment;
351
+ isSandbox(): boolean;
352
+ isProduction(): boolean;
353
+ }
354
+
355
+ /**
356
+ * Check if environment is sandbox
357
+ */
358
+ declare function isSandbox(environment: Environment): boolean;
359
+ /**
360
+ * Check if environment is production
361
+ */
362
+ declare function isProduction(environment: Environment): boolean;
363
+
364
+ /**
365
+ * Commet SDK - Billing and usage tracking SDK
366
+ */
367
+
368
+ export { type AgreementID, type ApiResponse, type BatchResult, type BulkSeatUpdate, Commet, CommetAPIError, type CommetConfig, CommetError, CommetValidationError, type CreateBatchUsageEventsParams, type CreateCustomerParams, type CreateUsageEventParams, type Currency, type Customer, type CustomerID, type Environment, type EventID, type InvoiceID, type ItemID, type ListCustomersParams, type ListParams, type ListSeatEventsParams, type ListUsageEventsParams, type PaginatedList, type PaginatedResponse, type PhaseID, type ProductID, type RequestOptions, type RetrieveOptions, type SeatBalance, type SeatBalanceResponse, type SeatEvent, type UpdateCustomerParams, type UsageEvent, type UsageEventProperty, type UsageMetric, type UsageMetricFilter, type WebhookID, Commet as default, isProduction, isSandbox };