@commet/node 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 CHANGED
@@ -29,7 +29,7 @@ const commet = new Commet({
29
29
  ### Usage Events (Consumption-Based Billing)
30
30
 
31
31
  ```typescript
32
- // Send a single event
32
+ // Send a single event using customerId (Commet's ID)
33
33
  await commet.usage.create({
34
34
  eventType: 'api_call',
35
35
  customerId: 'cus_123',
@@ -40,17 +40,28 @@ await commet.usage.create({
40
40
  ]
41
41
  });
42
42
 
43
+ // OR use your own externalId
44
+ await commet.usage.create({
45
+ eventType: 'api_call',
46
+ externalId: 'my-customer-123', // Your own customer ID
47
+ timestamp: new Date().toISOString(),
48
+ properties: [
49
+ { property: 'endpoint', value: '/api/users' },
50
+ { property: 'method', value: 'GET' }
51
+ ]
52
+ });
53
+
43
54
  // Batch events
44
55
  await commet.usage.createBatch({
45
56
  events: [
46
- { eventType: 'api_call', customerId: 'cus_123' },
57
+ { eventType: 'api_call', externalId: 'my-customer-123' },
47
58
  { eventType: 'api_call', customerId: 'cus_456' },
48
59
  ]
49
60
  });
50
61
 
51
62
  // List events
52
63
  const events = await commet.usage.list({
53
- customerId: 'cus_123',
64
+ externalId: 'my-customer-123', // Or use customerId
54
65
  limit: 100
55
66
  });
56
67
  ```
@@ -58,42 +69,42 @@ const events = await commet.usage.list({
58
69
  ### Seat Management (Per-Seat Licensing)
59
70
 
60
71
  ```typescript
61
- // Add seats
72
+ // Add seats using customerId or externalId
62
73
  await commet.seats.add({
63
- customerId: 'cus_123',
74
+ externalId: 'my-customer-123', // Or use customerId: 'cus_123'
64
75
  seatType: 'admin',
65
76
  count: 5
66
77
  });
67
78
 
68
79
  // Remove seats
69
80
  await commet.seats.remove({
70
- customerId: 'cus_123',
81
+ externalId: 'my-customer-123',
71
82
  seatType: 'admin',
72
83
  count: 2
73
84
  });
74
85
 
75
86
  // Set exact count
76
87
  await commet.seats.set({
77
- customerId: 'cus_123',
88
+ externalId: 'my-customer-123',
78
89
  seatType: 'admin',
79
90
  count: 10
80
91
  });
81
92
 
82
93
  // Get balance
83
94
  const balance = await commet.seats.getBalance({
84
- customerId: 'cus_123',
95
+ externalId: 'my-customer-123',
85
96
  seatType: 'admin'
86
97
  });
87
98
  console.log(balance.data.current); // 10
88
99
 
89
100
  // Get all balances for a customer
90
101
  const allBalances = await commet.seats.getAllBalances({
91
- customerId: 'cus_123'
102
+ externalId: 'my-customer-123'
92
103
  });
93
104
 
94
105
  // Bulk update multiple seat types
95
106
  await commet.seats.bulkUpdate({
96
- customerId: 'cus_123',
107
+ externalId: 'my-customer-123',
97
108
  seats: {
98
109
  admin: 5,
99
110
  editor: 20,
@@ -103,7 +114,7 @@ await commet.seats.bulkUpdate({
103
114
 
104
115
  // List seat events
105
116
  const events = await commet.seats.listEvents({
106
- customerId: 'cus_123',
117
+ externalId: 'my-customer-123',
107
118
  limit: 50
108
119
  });
109
120
  ```
package/dist/index.d.mts CHANGED
@@ -251,33 +251,40 @@ interface BulkSeatUpdate {
251
251
  [seatType: string]: number;
252
252
  }
253
253
  interface AddSeatsParams {
254
- customerId: CustomerID;
254
+ customerId?: CustomerID;
255
+ externalId?: string;
255
256
  seatType: GeneratedSeatType;
256
257
  count: number;
257
258
  }
258
259
  interface RemoveSeatsParams {
259
- customerId: CustomerID;
260
+ customerId?: CustomerID;
261
+ externalId?: string;
260
262
  seatType: GeneratedSeatType;
261
263
  count: number;
262
264
  }
263
265
  interface SetSeatsParams {
264
- customerId: CustomerID;
266
+ customerId?: CustomerID;
267
+ externalId?: string;
265
268
  seatType: GeneratedSeatType;
266
269
  count: number;
267
270
  }
268
271
  interface BulkUpdateSeatsParams {
269
- customerId: CustomerID;
272
+ customerId?: CustomerID;
273
+ externalId?: string;
270
274
  seats: BulkSeatUpdate;
271
275
  }
272
276
  interface GetBalanceParams {
273
- customerId: CustomerID;
277
+ customerId?: CustomerID;
278
+ externalId?: string;
274
279
  seatType: GeneratedSeatType;
275
280
  }
276
281
  interface GetAllBalancesParams {
277
- customerId: CustomerID;
282
+ customerId?: CustomerID;
283
+ externalId?: string;
278
284
  }
279
285
  interface ListSeatEventsParams extends ListParams {
280
286
  customerId?: CustomerID;
287
+ externalId?: string;
281
288
  seatType?: GeneratedSeatType;
282
289
  eventType?: "add" | "remove" | "set";
283
290
  }
@@ -315,7 +322,8 @@ interface UsageEventProperty {
315
322
  }
316
323
  interface CreateUsageEventParams {
317
324
  eventType: GeneratedEventType;
318
- customerId: CustomerID;
325
+ customerId?: CustomerID;
326
+ externalId?: string;
319
327
  idempotencyKey?: string;
320
328
  timestamp?: string;
321
329
  properties?: Array<{
@@ -336,6 +344,7 @@ interface BatchResult<T> {
336
344
  }
337
345
  interface ListUsageEventsParams extends ListParams {
338
346
  customerId?: CustomerID;
347
+ externalId?: string;
339
348
  eventType?: GeneratedEventType;
340
349
  idempotencyKey?: string;
341
350
  }
package/dist/index.d.ts CHANGED
@@ -251,33 +251,40 @@ interface BulkSeatUpdate {
251
251
  [seatType: string]: number;
252
252
  }
253
253
  interface AddSeatsParams {
254
- customerId: CustomerID;
254
+ customerId?: CustomerID;
255
+ externalId?: string;
255
256
  seatType: GeneratedSeatType;
256
257
  count: number;
257
258
  }
258
259
  interface RemoveSeatsParams {
259
- customerId: CustomerID;
260
+ customerId?: CustomerID;
261
+ externalId?: string;
260
262
  seatType: GeneratedSeatType;
261
263
  count: number;
262
264
  }
263
265
  interface SetSeatsParams {
264
- customerId: CustomerID;
266
+ customerId?: CustomerID;
267
+ externalId?: string;
265
268
  seatType: GeneratedSeatType;
266
269
  count: number;
267
270
  }
268
271
  interface BulkUpdateSeatsParams {
269
- customerId: CustomerID;
272
+ customerId?: CustomerID;
273
+ externalId?: string;
270
274
  seats: BulkSeatUpdate;
271
275
  }
272
276
  interface GetBalanceParams {
273
- customerId: CustomerID;
277
+ customerId?: CustomerID;
278
+ externalId?: string;
274
279
  seatType: GeneratedSeatType;
275
280
  }
276
281
  interface GetAllBalancesParams {
277
- customerId: CustomerID;
282
+ customerId?: CustomerID;
283
+ externalId?: string;
278
284
  }
279
285
  interface ListSeatEventsParams extends ListParams {
280
286
  customerId?: CustomerID;
287
+ externalId?: string;
281
288
  seatType?: GeneratedSeatType;
282
289
  eventType?: "add" | "remove" | "set";
283
290
  }
@@ -315,7 +322,8 @@ interface UsageEventProperty {
315
322
  }
316
323
  interface CreateUsageEventParams {
317
324
  eventType: GeneratedEventType;
318
- customerId: CustomerID;
325
+ customerId?: CustomerID;
326
+ externalId?: string;
319
327
  idempotencyKey?: string;
320
328
  timestamp?: string;
321
329
  properties?: Array<{
@@ -336,6 +344,7 @@ interface BatchResult<T> {
336
344
  }
337
345
  interface ListUsageEventsParams extends ListParams {
338
346
  customerId?: CustomerID;
347
+ externalId?: string;
339
348
  eventType?: GeneratedEventType;
340
349
  idempotencyKey?: string;
341
350
  }
package/dist/index.js CHANGED
@@ -70,6 +70,7 @@ var SeatsResource = class {
70
70
  "/seats",
71
71
  {
72
72
  customerId: params.customerId,
73
+ externalId: params.externalId,
73
74
  seatType: params.seatType,
74
75
  count: params.count
75
76
  },
@@ -81,6 +82,7 @@ var SeatsResource = class {
81
82
  "/seats",
82
83
  {
83
84
  customerId: params.customerId,
85
+ externalId: params.externalId,
84
86
  seatType: params.seatType,
85
87
  count: params.count
86
88
  },
@@ -92,6 +94,7 @@ var SeatsResource = class {
92
94
  "/seats",
93
95
  {
94
96
  customerId: params.customerId,
97
+ externalId: params.externalId,
95
98
  seatType: params.seatType,
96
99
  count: params.count
97
100
  },
@@ -101,19 +104,25 @@ var SeatsResource = class {
101
104
  async bulkUpdate(params, options) {
102
105
  return this.httpClient.put(
103
106
  "/seats/bulk",
104
- { customerId: params.customerId, seats: params.seats },
107
+ {
108
+ customerId: params.customerId,
109
+ externalId: params.externalId,
110
+ seats: params.seats
111
+ },
105
112
  options
106
113
  );
107
114
  }
108
115
  async getBalance(params) {
109
116
  return this.httpClient.get("/seats/balance", {
110
117
  customerId: params.customerId,
118
+ externalId: params.externalId,
111
119
  seatType: params.seatType
112
120
  });
113
121
  }
114
122
  async getAllBalances(params) {
115
123
  return this.httpClient.get("/seats/balances", {
116
- customerId: params.customerId
124
+ customerId: params.customerId,
125
+ externalId: params.externalId
117
126
  });
118
127
  }
119
128
  async listEvents(params) {
@@ -339,14 +348,14 @@ var CommetHTTPClient = class {
339
348
  * Get base URL based on environment
340
349
  */
341
350
  getBaseURL() {
342
- return this.environment === "production" ? "https://billing.commet.co" : "https://sandbox.commet.co";
351
+ return this.environment === "production" ? "https://api.commet.co" : "https://api.sandbox.commet.co";
343
352
  }
344
353
  /**
345
354
  * Build full URL from endpoint and params
346
355
  */
347
356
  buildURL(endpoint, params) {
348
357
  const baseURL = this.getBaseURL();
349
- const fullPath = `/api${endpoint.startsWith("/") ? endpoint : `/${endpoint}`}`;
358
+ const fullPath = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
350
359
  if (this.config.debug) {
351
360
  console.log(
352
361
  `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`
@@ -399,7 +408,7 @@ var Commet = class {
399
408
  if (config.debug) {
400
409
  console.log(`[Commet SDK] Initialized in ${this.environment} mode`);
401
410
  console.log("API Key:", `${config.apiKey.substring(0, 12)}...`);
402
- const baseURL = this.environment === "production" ? "https://billing.commet.co" : "https://sandbox.commet.co";
411
+ const baseURL = this.environment === "production" ? "https://api.commet.co" : "https://api.sandbox.commet.co";
403
412
  console.log("Base URL:", baseURL);
404
413
  }
405
414
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/resources/customers.ts","../src/resources/seats.ts","../src/resources/usage.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts"],"sourcesContent":["/**\n * Commet SDK - Billing and usage tracking SDK\n */\nexport { Commet } from \"./client\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedEventType,\n GeneratedSeatType,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n AgreementID,\n InvoiceID,\n PhaseID,\n ItemID,\n ProductID,\n EventID,\n WebhookID,\n ListParams,\n RetrieveOptions,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Resource type exports\nexport type {\n Customer,\n CreateCustomerParams,\n UpdateCustomerParams,\n ListCustomersParams,\n} from \"./resources/customers\";\n\nexport type {\n UsageEvent,\n UsageEventProperty,\n CreateUsageEventParams,\n CreateBatchUsageEventsParams,\n BatchResult,\n ListUsageEventsParams,\n} from \"./resources/usage\";\n\nexport type {\n SeatBalance,\n SeatEvent,\n SeatBalanceResponse,\n BulkSeatUpdate,\n AddSeatsParams,\n RemoveSeatsParams,\n SetSeatsParams,\n BulkUpdateSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n ListSeatEventsParams,\n} from \"./resources/seats\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n","import type {\n ApiResponse,\n Currency,\n CustomerID,\n ListParams,\n RequestOptions,\n RetrieveOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency: Currency;\n addressId: string;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n// Base fields shared by all customer creation scenarios\ninterface CreateCustomerBaseParams {\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n}\n\n// Address structure\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n region?: string;\n}\n\n// When taxStatus is TAXED, address is required\ninterface CreateCustomerTaxed extends CreateCustomerBaseParams {\n taxStatus: \"TAXED\";\n address: CustomerAddress;\n}\n\n// For other tax statuses, address is optional\ninterface CreateCustomerOtherTaxStatus extends CreateCustomerBaseParams {\n taxStatus?: \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n address?: CustomerAddress;\n}\n\n// Union type that enforces the constraint\nexport type CreateCustomerParams =\n | CreateCustomerTaxed\n | CreateCustomerOtherTaxStatus;\n\nexport interface UpdateCustomerParams {\n externalId?: string;\n legalName?: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive?: boolean;\n}\n\nexport interface ListCustomersParams extends ListParams {\n externalId?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n isActive?: boolean;\n search?: string;\n}\n\n/**\n * Customer resource for managing customer data\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\"/customers\", params, options);\n }\n\n async retrieve(\n customerId: CustomerID,\n options?: RetrieveOptions,\n ): Promise<ApiResponse<Customer>> {\n const params = options?.expand\n ? { expand: options.expand.join(\",\") }\n : undefined;\n return this.httpClient.get(`/customers/${customerId}`, params);\n }\n\n async update(\n customerId: CustomerID,\n params: UpdateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(`/customers/${customerId}`, params, options);\n }\n\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params);\n }\n\n /**\n * Deactivate a customer (soft delete)\n */\n async deactivate(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatBalance {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n balance: number;\n asOf: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalanceResponse {\n current: number;\n asOf: string;\n}\n\nexport interface BulkSeatUpdate {\n [seatType: string]: number;\n}\n\nexport interface AddSeatsParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveSeatsParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetSeatsParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface BulkUpdateSeatsParams {\n customerId: CustomerID;\n seats: BulkSeatUpdate;\n}\n\nexport interface GetBalanceParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId: CustomerID;\n}\n\nexport interface ListSeatEventsParams extends ListParams {\n customerId?: CustomerID;\n seatType?: GeneratedSeatType;\n eventType?: \"add\" | \"remove\" | \"set\";\n}\n\n/**\n * Seats resource for seat-based billing management\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async add(\n params: AddSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\n \"/seats\",\n {\n customerId: params.customerId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async remove(\n params: RemoveSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\n \"/seats\",\n {\n customerId: params.customerId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async set(\n params: SetSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\n \"/seats\",\n {\n customerId: params.customerId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async bulkUpdate(\n params: BulkUpdateSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\n \"/seats/bulk\",\n { customerId: params.customerId, seats: params.seats },\n options,\n );\n }\n\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalanceResponse>> {\n return this.httpClient.get(\"/seats/balance\", {\n customerId: params.customerId,\n seatType: params.seatType,\n });\n }\n\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalanceResponse>>> {\n return this.httpClient.get(\"/seats/balances\", {\n customerId: params.customerId,\n });\n }\n\n async listEvents(\n params?: ListSeatEventsParams,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.get(\"/seats/events\", params);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedEventType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n eventType: GeneratedEventType;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface CreateUsageEventParams {\n eventType: GeneratedEventType;\n customerId: CustomerID;\n idempotencyKey?: string; // For idempotency\n timestamp?: string; // ISO string, defaults to now\n properties?: Array<{\n property: string;\n value: string;\n }>;\n}\n\nexport interface CreateBatchUsageEventsParams {\n events: CreateUsageEventParams[];\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateUsageEventParams;\n }>;\n}\n\nexport interface ListUsageEventsParams extends ListParams {\n customerId?: CustomerID;\n eventType?: GeneratedEventType;\n idempotencyKey?: string;\n}\n\n/**\n * Usage Events resource - Track business events for usage-based billing\n */\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateUsageEventParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData = {\n ...params,\n ts: params.timestamp || new Date().toISOString(),\n };\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n async createBatch(\n params: CreateBatchUsageEventsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n return this.httpClient.post(\"/usage/events/batch\", params, options);\n }\n\n async retrieve(eventId: EventID): Promise<ApiResponse<UsageEvent>> {\n return this.httpClient.get(`/usage/events/${eventId}`);\n }\n\n async list(\n params?: ListUsageEventsParams,\n ): Promise<ApiResponse<UsageEvent[]>> {\n return this.httpClient.get(\"/usage/events\", params);\n }\n\n async delete(\n eventId: EventID,\n options?: RequestOptions,\n ): Promise<ApiResponse<{ deleted: boolean }>> {\n return this.httpClient.delete(\n `/usage/events/${eventId}`,\n undefined,\n options,\n );\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet.d.ts file that augments this interface with your\n * organization's specific event and seat types.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.events.create({\n * eventType: 'api_call', // Autocomplete works!\n * customerId: 'cus_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: <explanation>\nexport interface CommetGeneratedTypes {}\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedEventType = CommetGeneratedTypes extends {\n eventType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n const responseClone = response.clone();\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n errors?: Record<string, string[]>;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle different error types\n if (response.status === 400 && errorData.errors) {\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errorData.errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://billing.commet.co\"\n : \"https://sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path with /api prefix\n const fullPath = `/api${endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomersResource } from \"./resources/customers\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { UsageResource } from \"./resources/usage\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://billing.commet.co\"\n : \"https://sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n"],"mappings":"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","names":["data"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/resources/customers.ts","../src/resources/seats.ts","../src/resources/usage.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts"],"sourcesContent":["/**\n * Commet SDK - Billing and usage tracking SDK\n */\nexport { Commet } from \"./client\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedEventType,\n GeneratedSeatType,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n AgreementID,\n InvoiceID,\n PhaseID,\n ItemID,\n ProductID,\n EventID,\n WebhookID,\n ListParams,\n RetrieveOptions,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Resource type exports\nexport type {\n Customer,\n CreateCustomerParams,\n UpdateCustomerParams,\n ListCustomersParams,\n} from \"./resources/customers\";\n\nexport type {\n UsageEvent,\n UsageEventProperty,\n CreateUsageEventParams,\n CreateBatchUsageEventsParams,\n BatchResult,\n ListUsageEventsParams,\n} from \"./resources/usage\";\n\nexport type {\n SeatBalance,\n SeatEvent,\n SeatBalanceResponse,\n BulkSeatUpdate,\n AddSeatsParams,\n RemoveSeatsParams,\n SetSeatsParams,\n BulkUpdateSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n ListSeatEventsParams,\n} from \"./resources/seats\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n","import type {\n ApiResponse,\n Currency,\n CustomerID,\n ListParams,\n RequestOptions,\n RetrieveOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency: Currency;\n addressId: string;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n// Base fields shared by all customer creation scenarios\ninterface CreateCustomerBaseParams {\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n}\n\n// Address structure\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n region?: string;\n}\n\n// When taxStatus is TAXED, address is required\ninterface CreateCustomerTaxed extends CreateCustomerBaseParams {\n taxStatus: \"TAXED\";\n address: CustomerAddress;\n}\n\n// For other tax statuses, address is optional\ninterface CreateCustomerOtherTaxStatus extends CreateCustomerBaseParams {\n taxStatus?: \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n address?: CustomerAddress;\n}\n\n// Union type that enforces the constraint\nexport type CreateCustomerParams =\n | CreateCustomerTaxed\n | CreateCustomerOtherTaxStatus;\n\nexport interface UpdateCustomerParams {\n externalId?: string;\n legalName?: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive?: boolean;\n}\n\nexport interface ListCustomersParams extends ListParams {\n externalId?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n isActive?: boolean;\n search?: string;\n}\n\n/**\n * Customer resource for managing customer data\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\"/customers\", params, options);\n }\n\n async retrieve(\n customerId: CustomerID,\n options?: RetrieveOptions,\n ): Promise<ApiResponse<Customer>> {\n const params = options?.expand\n ? { expand: options.expand.join(\",\") }\n : undefined;\n return this.httpClient.get(`/customers/${customerId}`, params);\n }\n\n async update(\n customerId: CustomerID,\n params: UpdateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(`/customers/${customerId}`, params, options);\n }\n\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params);\n }\n\n /**\n * Deactivate a customer (soft delete)\n */\n async deactivate(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatBalance {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n balance: number;\n asOf: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalanceResponse {\n current: number;\n asOf: string;\n}\n\nexport interface BulkSeatUpdate {\n [seatType: string]: number;\n}\n\nexport interface AddSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface BulkUpdateSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seats: BulkSeatUpdate;\n}\n\nexport interface GetBalanceParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId?: CustomerID;\n externalId?: string;\n}\n\nexport interface ListSeatEventsParams extends ListParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType?: GeneratedSeatType;\n eventType?: \"add\" | \"remove\" | \"set\";\n}\n\n/**\n * Seats resource for seat-based billing management\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async add(\n params: AddSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\n \"/seats\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async remove(\n params: RemoveSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\n \"/seats\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async set(\n params: SetSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\n \"/seats\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async bulkUpdate(\n params: BulkUpdateSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\n \"/seats/bulk\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seats: params.seats,\n },\n options,\n );\n }\n\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalanceResponse>> {\n return this.httpClient.get(\"/seats/balance\", {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n });\n }\n\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalanceResponse>>> {\n return this.httpClient.get(\"/seats/balances\", {\n customerId: params.customerId,\n externalId: params.externalId,\n });\n }\n\n async listEvents(\n params?: ListSeatEventsParams,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.get(\"/seats/events\", params);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedEventType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n eventType: GeneratedEventType;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface CreateUsageEventParams {\n eventType: GeneratedEventType;\n customerId?: CustomerID;\n externalId?: string;\n idempotencyKey?: string; // For idempotency\n timestamp?: string; // ISO string, defaults to now\n properties?: Array<{\n property: string;\n value: string;\n }>;\n}\n\nexport interface CreateBatchUsageEventsParams {\n events: CreateUsageEventParams[];\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateUsageEventParams;\n }>;\n}\n\nexport interface ListUsageEventsParams extends ListParams {\n customerId?: CustomerID;\n externalId?: string;\n eventType?: GeneratedEventType;\n idempotencyKey?: string;\n}\n\n/**\n * Usage Events resource - Track business events for usage-based billing\n */\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateUsageEventParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData = {\n ...params,\n ts: params.timestamp || new Date().toISOString(),\n };\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n async createBatch(\n params: CreateBatchUsageEventsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n return this.httpClient.post(\"/usage/events/batch\", params, options);\n }\n\n async retrieve(eventId: EventID): Promise<ApiResponse<UsageEvent>> {\n return this.httpClient.get(`/usage/events/${eventId}`);\n }\n\n async list(\n params?: ListUsageEventsParams,\n ): Promise<ApiResponse<UsageEvent[]>> {\n return this.httpClient.get(\"/usage/events\", params);\n }\n\n async delete(\n eventId: EventID,\n options?: RequestOptions,\n ): Promise<ApiResponse<{ deleted: boolean }>> {\n return this.httpClient.delete(\n `/usage/events/${eventId}`,\n undefined,\n options,\n );\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet.d.ts file that augments this interface with your\n * organization's specific event and seat types.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.events.create({\n * eventType: 'api_call', // Autocomplete works!\n * customerId: 'cus_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: <explanation>\nexport interface CommetGeneratedTypes {}\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedEventType = CommetGeneratedTypes extends {\n eventType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n const responseClone = response.clone();\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n errors?: Record<string, string[]>;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle different error types\n if (response.status === 400 && errorData.errors) {\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errorData.errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://api.commet.co\"\n : \"https://api.sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path (no /api prefix needed - it's in the domain now)\n const fullPath = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomersResource } from \"./resources/customers\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { UsageResource } from \"./resources/usage\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://api.commet.co\"\n : \"https://api.sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC2GO,IAAM,oBAAN,MAAwB;AAAA,EAC7B,YAAoB,YAA8B;AAA9B;AAAA,EAA+B;AAAA,EAEnD,MAAM,OACJ,QACA,SACgC;AAChC,WAAO,KAAK,WAAW,KAAK,cAAc,QAAQ,OAAO;AAAA,EAC3D;AAAA,EAEA,MAAM,SACJ,YACA,SACgC;AAChC,UAAM,SAAS,SAAS,SACpB,EAAE,QAAQ,QAAQ,OAAO,KAAK,GAAG,EAAE,IACnC;AACJ,WAAO,KAAK,WAAW,IAAI,cAAc,UAAU,IAAI,MAAM;AAAA,EAC/D;AAAA,EAEA,MAAM,OACJ,YACA,QACA,SACgC;AAChC,WAAO,KAAK,WAAW,IAAI,cAAc,UAAU,IAAI,QAAQ,OAAO;AAAA,EACxE;AAAA,EAEA,MAAM,KAAK,QAAgE;AACzE,WAAO,KAAK,WAAW,IAAI,cAAc,MAAM;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,WACJ,YACA,SACgC;AAChC,WAAO,KAAK,WAAW;AAAA,MACrB,cAAc,UAAU;AAAA,MACxB,EAAE,UAAU,MAAM;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AACF;;;AC9DO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAAoB,YAA8B;AAA9B;AAAA,EAA+B;AAAA,EAEnD,MAAM,IACJ,QACA,SACiC;AACjC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,QACE,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,OAAO,OAAO;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,OACJ,QACA,SACiC;AACjC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,QACE,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,OAAO,OAAO;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IACJ,QACA,SACiC;AACjC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,QACE,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO;AAAA,QACjB,OAAO,OAAO;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WACJ,QACA,SACmC;AACnC,WAAO,KAAK,WAAW;AAAA,MACrB;AAAA,MACA;AAAA,QACE,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,OAAO,OAAO;AAAA,MAChB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,WACJ,QAC2C;AAC3C,WAAO,KAAK,WAAW,IAAI,kBAAkB;AAAA,MAC3C,YAAY,OAAO;AAAA,MACnB,YAAY,OAAO;AAAA,MACnB,UAAU,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,eACJ,QAC2D;AAC3D,WAAO,KAAK,WAAW,IAAI,mBAAmB;AAAA,MAC5C,YAAY,OAAO;AAAA,MACnB,YAAY,OAAO;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,WACJ,QACmC;AACnC,WAAO,KAAK,WAAW,IAAI,iBAAiB,MAAM;AAAA,EACpD;AACF;;;ACpHO,IAAM,gBAAN,MAAoB;AAAA,EACzB,YAAoB,YAA8B;AAA9B;AAAA,EAA+B;AAAA,EAEnD,MAAM,OACJ,QACA,SACkC;AAClC,UAAM,YAAY;AAAA,MAChB,GAAG;AAAA,MACH,IAAI,OAAO,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACjD;AAEA,WAAO,KAAK,WAAW,KAAK,iBAAiB,WAAW,OAAO;AAAA,EACjE;AAAA,EAEA,MAAM,YACJ,QACA,SAC+C;AAC/C,WAAO,KAAK,WAAW,KAAK,uBAAuB,QAAQ,OAAO;AAAA,EACpE;AAAA,EAEA,MAAM,SAAS,SAAoD;AACjE,WAAO,KAAK,WAAW,IAAI,iBAAiB,OAAO,EAAE;AAAA,EACvD;AAAA,EAEA,MAAM,KACJ,QACoC;AACpC,WAAO,KAAK,WAAW,IAAI,iBAAiB,MAAM;AAAA,EACpD;AAAA,EAEA,MAAM,OACJ,SACA,SAC4C;AAC5C,WAAO,KAAK,WAAW;AAAA,MACrB,iBAAiB,OAAO;AAAA,MACxB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;;;ACxEO,IAAM,cAAN,cAA0B,MAAM;AAAA,EACrC,YACE,SACO,MACA,YACA,SACP;AACA,UAAM,OAAO;AAJN;AACA;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,iBAAN,cAA6B,YAAY;AAAA,EAC9C,YACE,SACO,YACA,MACA,SACP;AACA,UAAM,SAAS,MAAM,YAAY,OAAO;AAJjC;AACA;AACA;AAGP,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,wBAAN,cAAoC,YAAY;AAAA,EACrD,YACE,SACO,kBACP;AACA,UAAM,OAAO;AAFN;AAGP,SAAK,OAAO;AAAA,EACd;AACF;;;ACnDA,IAAM,uBAAoC;AAAA,EACxC,YAAY;AAAA,EACZ,WAAW;AAAA;AAAA,EACX,UAAU;AAAA;AAAA,EACV,sBAAsB,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AACrD;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAK5B,YAAY,QAAsB,aAA0B;AAC1D,SAAK,SAAS;AACd,SAAK,cAAc;AACnB,SAAK,cAAc;AAAA,MACjB,GAAG;AAAA,MACH,YAAY,OAAO,WAAW,qBAAqB;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAM,IACJ,UACA,QACA,SACyB;AACzB,WAAO,KAAK,QAAQ,OAAO,UAAU,QAAW,SAAS,MAAM;AAAA,EACjE;AAAA,EAEA,MAAM,KACJ,UACA,MACA,SACyB;AACzB,WAAO,KAAK,QAAQ,QAAQ,UAAU,MAAM,OAAO;AAAA,EACrD;AAAA,EAEA,MAAM,IACJ,UACA,MACA,SACyB;AACzB,WAAO,KAAK,QAAQ,OAAO,UAAU,MAAM,OAAO;AAAA,EACpD;AAAA,EAEA,MAAM,OACJ,UACA,MACA,SACyB;AACzB,WAAO,KAAK,QAAQ,UAAU,UAAU,MAAM,OAAO;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,QACZ,QACA,UACA,MACA,SACA,QACyB;AACzB,UAAM,MAAM,KAAK,SAAS,UAAU,MAAM;AAC1C,WAAO,KAAK,eAAe,QAAQ,KAAK,MAAM,OAAO;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,MAAc,eACZ,QACA,KACA,MACA,SACA,UAAU,GACe;AACzB,QAAI;AACF,YAAM,UAAkC;AAAA,QACtC,aAAa,KAAK,OAAO;AAAA,QACzB,gBAAgB;AAAA,QAChB,cAAc;AAAA,MAChB;AAEA,UAAI,SAAS,gBAAgB;AAC3B,gBAAQ,iBAAiB,IAAI,QAAQ;AAAA,MACvC,WAAW,WAAW,UAAU,MAAM;AACpC,gBAAQ,iBAAiB,IAAI,KAAK,uBAAuB;AAAA,MAC3D;AAEA,YAAM,gBAA6B;AAAA,QACjC;AAAA,QACA;AAAA,QACA,QAAQ,YAAY;AAAA,UAClB,SAAS,WAAW,KAAK,OAAO,WAAW;AAAA,QAC7C;AAAA,MACF;AAEA,UAAI,MAAM;AACR,sBAAc,OAAO,KAAK,UAAU,IAAI;AAAA,MAC1C;AAEA,UAAI,KAAK,OAAO,OAAO;AACrB,gBAAQ,IAAI,gBAAgB,MAAM,IAAI,GAAG,EAAE;AAC3C,YAAI,MAAM;AACR,kBAAQ,IAAI,iBAAiB,KAAK,UAAU,MAAM,MAAM,CAAC,CAAC;AAAA,QAC5D;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,MAAM,KAAK,aAAa;AAE/C,UAAI,KAAK,OAAO,OAAO;AACrB,gBAAQ;AAAA,UACN,iCAAiC,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,QACzE;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AAEJ,UAAI;AACF,cAAM,gBAAgB,SAAS,MAAM;AACrC,uBAAe,MAAM,SAAS,KAAK;AACnC,uBAAe;AAAA,MACjB,SAAS,WAAW;AAClB,YAAI;AACF,yBAAe,MAAM,SAAS,KAAK;AAAA,QACrC,SAAS,WAAW;AAClB,yBAAe;AAAA,QACjB;AACA,YAAI,KAAK,OAAO,OAAO;AACrB,kBAAQ;AAAA,YACN;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,cAAM,IAAI;AAAA,UACR,0BAA0B,SAAS,MAAM,IAAI,SAAS,UAAU;AAAA,UAChE,SAAS;AAAA,UACT;AAAA,UACA,EAAE,aAAa;AAAA,QACjB;AAAA,MACF;AAEA,UAAI,CAAC,SAAS,IAAI;AAEhB,YACE,WAAW,KAAK,YAAY,cAC5B,KAAK,YAAY,qBAAqB,SAAS,SAAS,MAAM,GAC9D;AACA,gBAAM,QAAQ,KAAK;AAAA,YACjB,KAAK,YAAY,YAAY,MAAM,UAAU;AAAA,YAC7C,KAAK,YAAY;AAAA,UACnB;AAEA,cAAI,KAAK,OAAO,OAAO;AACrB,oBAAQ;AAAA,cACN,4BAA4B,KAAK,eAAe,OAAO,IAAI,KAAK,YAAY,UAAU;AAAA,YACxF;AAAA,UACF;AAEA,gBAAM,KAAK,MAAM,KAAK;AACtB,iBAAO,KAAK,eAAe,QAAQ,KAAK,MAAM,SAAS,UAAU,CAAC;AAAA,QACpE;AAGA,YAAI,KAAK,OAAO,OAAO;AACrB,kBAAQ;AAAA,YACN;AAAA,YACA,KAAK,UAAU,cAAc,MAAM,CAAC;AAAA,UACtC;AAAA,QACF;AAGA,cAAM,kBAAkB,CACtBA,UAMG;AACH,iBAAO,OAAOA,UAAS,YAAYA,UAAS;AAAA,QAC9C;AAEA,cAAM,YAAY,gBAAgB,YAAY,IAAI,eAAe,CAAC;AAGlE,YAAI,SAAS,WAAW,OAAO,UAAU,QAAQ;AAC/C,gBAAM,IAAI;AAAA,YACR,UAAU,WAAW;AAAA,YACrB,UAAU;AAAA,UACZ;AAAA,QACF;AAEA,cAAM,IAAI;AAAA,UACR,UAAU,WAAW,8BAA8B,SAAS,MAAM;AAAA,UAClE,SAAS;AAAA,UACT,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AAAA,MACF;AAEA,UAAI,KAAK,OAAO,OAAO;AACrB,gBAAQ,IAAI,0BAA0B,YAAY;AAAA,MACpD;AAEA,aAAO;AAAA,IACT,SAAS,OAAO;AAEd,UAAI,iBAAiB,aAAa,MAAM,QAAQ,SAAS,OAAO,GAAG;AACjE,YAAI,WAAW,KAAK,YAAY,YAAY;AAC1C,gBAAM,QAAQ,KAAK;AAAA,YACjB,KAAK,YAAY,YAAY,MAAM,UAAU;AAAA,YAC7C,KAAK,YAAY;AAAA,UACnB;AAEA,cAAI,KAAK,OAAO,OAAO;AACrB,oBAAQ,IAAI,2CAA2C,KAAK,IAAI;AAAA,UAClE;AAEA,gBAAM,KAAK,MAAM,KAAK;AACtB,iBAAO,KAAK,eAAe,QAAQ,KAAK,MAAM,SAAS,UAAU,CAAC;AAAA,QACpE;AAAA,MACF;AAEA,YAAM;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAqB;AAC3B,WAAO,KAAK,gBAAgB,eACxB,0BACA;AAAA,EACN;AAAA;AAAA;AAAA;AAAA,EAKQ,SAAS,UAAkB,QAA0C;AAC3E,UAAM,UAAU,KAAK,WAAW;AAGhC,UAAM,WAAW,SAAS,WAAW,GAAG,IAAI,WAAW,IAAI,QAAQ;AAGnE,QAAI,KAAK,OAAO,OAAO;AACrB,cAAQ;AAAA,QACN,wCAAwC,OAAO,eAAe,QAAQ,eAAe,QAAQ;AAAA,MAC/F;AAAA,IACF;AAEA,UAAM,MAAM,IAAI,IAAI,UAAU,OAAO;AAErC,QAAI,QAAQ;AACV,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,YAAI,UAAU,UAAa,UAAU,MAAM;AACzC,cAAI,aAAa,OAAO,KAAK,OAAO,KAAK,CAAC;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAAW,IAAI,SAAS;AAG9B,QAAI,KAAK,OAAO,OAAO;AACrB,cAAQ,IAAI,2BAA2B,QAAQ,EAAE;AAAA,IACnD;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,yBAAiC;AAEvC,WAAO,OAAO,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,CAAC,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKQ,MAAM,IAA2B;AACvC,WAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,EACzD;AACF;;;ACvSO,IAAM,SAAN,MAAa;AAAA,EAQlB,YAAY,QAAsB;AAChC,QAAI,CAAC,OAAO,QAAQ;AAClB,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,QAAI,CAAC,OAAO,OAAO,WAAW,KAAK,GAAG;AACpC,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAGA,SAAK,cAAc,OAAO,eAAe;AAEzC,SAAK,aAAa,IAAI,iBAAiB,QAAQ,KAAK,WAAW;AAC/D,SAAK,YAAY,IAAI,kBAAkB,KAAK,UAAU;AACtD,SAAK,QAAQ,IAAI,cAAc,KAAK,UAAU;AAC9C,SAAK,QAAQ,IAAI,cAAc,KAAK,UAAU;AAE9C,QAAI,OAAO,OAAO;AAChB,cAAQ,IAAI,+BAA+B,KAAK,WAAW,OAAO;AAClE,cAAQ,IAAI,YAAY,GAAG,OAAO,OAAO,UAAU,GAAG,EAAE,CAAC,KAAK;AAC9D,YAAM,UACJ,KAAK,gBAAgB,eACjB,0BACA;AACN,cAAQ,IAAI,aAAa,OAAO;AAAA,IAClC;AAAA,EACF;AAAA,EAEA,iBAA8B;AAC5B,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,YAAqB;AACnB,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AAAA,EAEA,eAAwB;AACtB,WAAO,KAAK,gBAAgB;AAAA,EAC9B;AACF;;;ACrDO,SAAS,UAAU,aAAmC;AAC3D,SAAO,gBAAgB;AACzB;AAKO,SAAS,aAAa,aAAmC;AAC9D,SAAO,gBAAgB;AACzB;;;AP0DA,IAAO,gBAAQ;","names":["data"]}
package/dist/index.mjs CHANGED
@@ -38,6 +38,7 @@ var SeatsResource = class {
38
38
  "/seats",
39
39
  {
40
40
  customerId: params.customerId,
41
+ externalId: params.externalId,
41
42
  seatType: params.seatType,
42
43
  count: params.count
43
44
  },
@@ -49,6 +50,7 @@ var SeatsResource = class {
49
50
  "/seats",
50
51
  {
51
52
  customerId: params.customerId,
53
+ externalId: params.externalId,
52
54
  seatType: params.seatType,
53
55
  count: params.count
54
56
  },
@@ -60,6 +62,7 @@ var SeatsResource = class {
60
62
  "/seats",
61
63
  {
62
64
  customerId: params.customerId,
65
+ externalId: params.externalId,
63
66
  seatType: params.seatType,
64
67
  count: params.count
65
68
  },
@@ -69,19 +72,25 @@ var SeatsResource = class {
69
72
  async bulkUpdate(params, options) {
70
73
  return this.httpClient.put(
71
74
  "/seats/bulk",
72
- { customerId: params.customerId, seats: params.seats },
75
+ {
76
+ customerId: params.customerId,
77
+ externalId: params.externalId,
78
+ seats: params.seats
79
+ },
73
80
  options
74
81
  );
75
82
  }
76
83
  async getBalance(params) {
77
84
  return this.httpClient.get("/seats/balance", {
78
85
  customerId: params.customerId,
86
+ externalId: params.externalId,
79
87
  seatType: params.seatType
80
88
  });
81
89
  }
82
90
  async getAllBalances(params) {
83
91
  return this.httpClient.get("/seats/balances", {
84
- customerId: params.customerId
92
+ customerId: params.customerId,
93
+ externalId: params.externalId
85
94
  });
86
95
  }
87
96
  async listEvents(params) {
@@ -307,14 +316,14 @@ var CommetHTTPClient = class {
307
316
  * Get base URL based on environment
308
317
  */
309
318
  getBaseURL() {
310
- return this.environment === "production" ? "https://billing.commet.co" : "https://sandbox.commet.co";
319
+ return this.environment === "production" ? "https://api.commet.co" : "https://api.sandbox.commet.co";
311
320
  }
312
321
  /**
313
322
  * Build full URL from endpoint and params
314
323
  */
315
324
  buildURL(endpoint, params) {
316
325
  const baseURL = this.getBaseURL();
317
- const fullPath = `/api${endpoint.startsWith("/") ? endpoint : `/${endpoint}`}`;
326
+ const fullPath = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
318
327
  if (this.config.debug) {
319
328
  console.log(
320
329
  `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`
@@ -367,7 +376,7 @@ var Commet = class {
367
376
  if (config.debug) {
368
377
  console.log(`[Commet SDK] Initialized in ${this.environment} mode`);
369
378
  console.log("API Key:", `${config.apiKey.substring(0, 12)}...`);
370
- const baseURL = this.environment === "production" ? "https://billing.commet.co" : "https://sandbox.commet.co";
379
+ const baseURL = this.environment === "production" ? "https://api.commet.co" : "https://api.sandbox.commet.co";
371
380
  console.log("Base URL:", baseURL);
372
381
  }
373
382
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/resources/customers.ts","../src/resources/seats.ts","../src/resources/usage.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts","../src/index.ts"],"sourcesContent":["import type {\n ApiResponse,\n Currency,\n CustomerID,\n ListParams,\n RequestOptions,\n RetrieveOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency: Currency;\n addressId: string;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n// Base fields shared by all customer creation scenarios\ninterface CreateCustomerBaseParams {\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n}\n\n// Address structure\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n region?: string;\n}\n\n// When taxStatus is TAXED, address is required\ninterface CreateCustomerTaxed extends CreateCustomerBaseParams {\n taxStatus: \"TAXED\";\n address: CustomerAddress;\n}\n\n// For other tax statuses, address is optional\ninterface CreateCustomerOtherTaxStatus extends CreateCustomerBaseParams {\n taxStatus?: \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n address?: CustomerAddress;\n}\n\n// Union type that enforces the constraint\nexport type CreateCustomerParams =\n | CreateCustomerTaxed\n | CreateCustomerOtherTaxStatus;\n\nexport interface UpdateCustomerParams {\n externalId?: string;\n legalName?: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive?: boolean;\n}\n\nexport interface ListCustomersParams extends ListParams {\n externalId?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n isActive?: boolean;\n search?: string;\n}\n\n/**\n * Customer resource for managing customer data\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\"/customers\", params, options);\n }\n\n async retrieve(\n customerId: CustomerID,\n options?: RetrieveOptions,\n ): Promise<ApiResponse<Customer>> {\n const params = options?.expand\n ? { expand: options.expand.join(\",\") }\n : undefined;\n return this.httpClient.get(`/customers/${customerId}`, params);\n }\n\n async update(\n customerId: CustomerID,\n params: UpdateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(`/customers/${customerId}`, params, options);\n }\n\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params);\n }\n\n /**\n * Deactivate a customer (soft delete)\n */\n async deactivate(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatBalance {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n balance: number;\n asOf: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalanceResponse {\n current: number;\n asOf: string;\n}\n\nexport interface BulkSeatUpdate {\n [seatType: string]: number;\n}\n\nexport interface AddSeatsParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveSeatsParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetSeatsParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface BulkUpdateSeatsParams {\n customerId: CustomerID;\n seats: BulkSeatUpdate;\n}\n\nexport interface GetBalanceParams {\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId: CustomerID;\n}\n\nexport interface ListSeatEventsParams extends ListParams {\n customerId?: CustomerID;\n seatType?: GeneratedSeatType;\n eventType?: \"add\" | \"remove\" | \"set\";\n}\n\n/**\n * Seats resource for seat-based billing management\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async add(\n params: AddSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\n \"/seats\",\n {\n customerId: params.customerId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async remove(\n params: RemoveSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\n \"/seats\",\n {\n customerId: params.customerId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async set(\n params: SetSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\n \"/seats\",\n {\n customerId: params.customerId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async bulkUpdate(\n params: BulkUpdateSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\n \"/seats/bulk\",\n { customerId: params.customerId, seats: params.seats },\n options,\n );\n }\n\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalanceResponse>> {\n return this.httpClient.get(\"/seats/balance\", {\n customerId: params.customerId,\n seatType: params.seatType,\n });\n }\n\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalanceResponse>>> {\n return this.httpClient.get(\"/seats/balances\", {\n customerId: params.customerId,\n });\n }\n\n async listEvents(\n params?: ListSeatEventsParams,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.get(\"/seats/events\", params);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedEventType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n eventType: GeneratedEventType;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface CreateUsageEventParams {\n eventType: GeneratedEventType;\n customerId: CustomerID;\n idempotencyKey?: string; // For idempotency\n timestamp?: string; // ISO string, defaults to now\n properties?: Array<{\n property: string;\n value: string;\n }>;\n}\n\nexport interface CreateBatchUsageEventsParams {\n events: CreateUsageEventParams[];\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateUsageEventParams;\n }>;\n}\n\nexport interface ListUsageEventsParams extends ListParams {\n customerId?: CustomerID;\n eventType?: GeneratedEventType;\n idempotencyKey?: string;\n}\n\n/**\n * Usage Events resource - Track business events for usage-based billing\n */\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateUsageEventParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData = {\n ...params,\n ts: params.timestamp || new Date().toISOString(),\n };\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n async createBatch(\n params: CreateBatchUsageEventsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n return this.httpClient.post(\"/usage/events/batch\", params, options);\n }\n\n async retrieve(eventId: EventID): Promise<ApiResponse<UsageEvent>> {\n return this.httpClient.get(`/usage/events/${eventId}`);\n }\n\n async list(\n params?: ListUsageEventsParams,\n ): Promise<ApiResponse<UsageEvent[]>> {\n return this.httpClient.get(\"/usage/events\", params);\n }\n\n async delete(\n eventId: EventID,\n options?: RequestOptions,\n ): Promise<ApiResponse<{ deleted: boolean }>> {\n return this.httpClient.delete(\n `/usage/events/${eventId}`,\n undefined,\n options,\n );\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet.d.ts file that augments this interface with your\n * organization's specific event and seat types.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.events.create({\n * eventType: 'api_call', // Autocomplete works!\n * customerId: 'cus_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: <explanation>\nexport interface CommetGeneratedTypes {}\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedEventType = CommetGeneratedTypes extends {\n eventType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n const responseClone = response.clone();\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n errors?: Record<string, string[]>;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle different error types\n if (response.status === 400 && errorData.errors) {\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errorData.errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://billing.commet.co\"\n : \"https://sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path with /api prefix\n const fullPath = `/api${endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomersResource } from \"./resources/customers\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { UsageResource } from \"./resources/usage\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://billing.commet.co\"\n : \"https://sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n","/**\n * Commet SDK - Billing and usage tracking SDK\n */\nexport { Commet } from \"./client\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedEventType,\n GeneratedSeatType,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n AgreementID,\n InvoiceID,\n PhaseID,\n ItemID,\n ProductID,\n EventID,\n WebhookID,\n ListParams,\n RetrieveOptions,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Resource type exports\nexport type {\n Customer,\n CreateCustomerParams,\n UpdateCustomerParams,\n ListCustomersParams,\n} from \"./resources/customers\";\n\nexport type {\n UsageEvent,\n UsageEventProperty,\n CreateUsageEventParams,\n CreateBatchUsageEventsParams,\n BatchResult,\n ListUsageEventsParams,\n} from \"./resources/usage\";\n\nexport type {\n SeatBalance,\n SeatEvent,\n SeatBalanceResponse,\n BulkSeatUpdate,\n AddSeatsParams,\n RemoveSeatsParams,\n SetSeatsParams,\n BulkUpdateSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n ListSeatEventsParams,\n} from \"./resources/seats\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n"],"mappings":"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","names":["data"]}
1
+ {"version":3,"sources":["../src/resources/customers.ts","../src/resources/seats.ts","../src/resources/usage.ts","../src/types/common.ts","../src/utils/http.ts","../src/client.ts","../src/utils/environment.ts","../src/index.ts"],"sourcesContent":["import type {\n ApiResponse,\n Currency,\n CustomerID,\n ListParams,\n RequestOptions,\n RetrieveOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface Customer {\n id: CustomerID;\n organizationId: string;\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency: Currency;\n addressId: string;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\n// Base fields shared by all customer creation scenarios\ninterface CreateCustomerBaseParams {\n externalId?: string;\n legalName: string;\n displayName?: string;\n domain?: string;\n website?: string;\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n}\n\n// Address structure\nexport interface CustomerAddress {\n line1: string;\n line2?: string;\n city: string;\n state?: string;\n postalCode: string;\n country: string; // ISO-2\n region?: string;\n}\n\n// When taxStatus is TAXED, address is required\ninterface CreateCustomerTaxed extends CreateCustomerBaseParams {\n taxStatus: \"TAXED\";\n address: CustomerAddress;\n}\n\n// For other tax statuses, address is optional\ninterface CreateCustomerOtherTaxStatus extends CreateCustomerBaseParams {\n taxStatus?: \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n address?: CustomerAddress;\n}\n\n// Union type that enforces the constraint\nexport type CreateCustomerParams =\n | CreateCustomerTaxed\n | CreateCustomerOtherTaxStatus;\n\nexport interface UpdateCustomerParams {\n externalId?: string;\n legalName?: string;\n displayName?: string;\n domain?: string;\n website?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n billingEmail?: string;\n paymentTerms?: string;\n timezone?: string;\n language?: string;\n industry?: string;\n employeeCount?: string;\n metadata?: Record<string, unknown>;\n isActive?: boolean;\n}\n\nexport interface ListCustomersParams extends ListParams {\n externalId?: string;\n taxStatus?: \"TAXED\" | \"TAX_EXEMPT\" | \"REVERSE_CHARGE\" | \"NOT_APPLICABLE\";\n currency?: Currency;\n isActive?: boolean;\n search?: string;\n}\n\n/**\n * Customer resource for managing customer data\n */\nexport class CustomersResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.post(\"/customers\", params, options);\n }\n\n async retrieve(\n customerId: CustomerID,\n options?: RetrieveOptions,\n ): Promise<ApiResponse<Customer>> {\n const params = options?.expand\n ? { expand: options.expand.join(\",\") }\n : undefined;\n return this.httpClient.get(`/customers/${customerId}`, params);\n }\n\n async update(\n customerId: CustomerID,\n params: UpdateCustomerParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(`/customers/${customerId}`, params, options);\n }\n\n async list(params?: ListCustomersParams): Promise<ApiResponse<Customer[]>> {\n return this.httpClient.get(\"/customers\", params);\n }\n\n /**\n * Deactivate a customer (soft delete)\n */\n async deactivate(\n customerId: CustomerID,\n options?: RequestOptions,\n ): Promise<ApiResponse<Customer>> {\n return this.httpClient.put(\n `/customers/${customerId}`,\n { isActive: false },\n options,\n );\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n GeneratedSeatType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface SeatBalance {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n balance: number;\n asOf: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface SeatEvent {\n id: string;\n organizationId: string;\n customerId: CustomerID;\n seatType: GeneratedSeatType;\n eventType: \"add\" | \"remove\" | \"set\";\n quantity: number;\n previousBalance?: number;\n newBalance: number;\n ts: string;\n createdAt: string;\n}\n\nexport interface SeatBalanceResponse {\n current: number;\n asOf: string;\n}\n\nexport interface BulkSeatUpdate {\n [seatType: string]: number;\n}\n\nexport interface AddSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface RemoveSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface SetSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n count: number;\n}\n\nexport interface BulkUpdateSeatsParams {\n customerId?: CustomerID;\n externalId?: string;\n seats: BulkSeatUpdate;\n}\n\nexport interface GetBalanceParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType: GeneratedSeatType;\n}\n\nexport interface GetAllBalancesParams {\n customerId?: CustomerID;\n externalId?: string;\n}\n\nexport interface ListSeatEventsParams extends ListParams {\n customerId?: CustomerID;\n externalId?: string;\n seatType?: GeneratedSeatType;\n eventType?: \"add\" | \"remove\" | \"set\";\n}\n\n/**\n * Seats resource for seat-based billing management\n */\nexport class SeatsResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async add(\n params: AddSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.post(\n \"/seats\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async remove(\n params: RemoveSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.delete(\n \"/seats\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async set(\n params: SetSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent>> {\n return this.httpClient.put(\n \"/seats\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n count: params.count,\n },\n options,\n );\n }\n\n async bulkUpdate(\n params: BulkUpdateSeatsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.put(\n \"/seats/bulk\",\n {\n customerId: params.customerId,\n externalId: params.externalId,\n seats: params.seats,\n },\n options,\n );\n }\n\n async getBalance(\n params: GetBalanceParams,\n ): Promise<ApiResponse<SeatBalanceResponse>> {\n return this.httpClient.get(\"/seats/balance\", {\n customerId: params.customerId,\n externalId: params.externalId,\n seatType: params.seatType,\n });\n }\n\n async getAllBalances(\n params: GetAllBalancesParams,\n ): Promise<ApiResponse<Record<string, SeatBalanceResponse>>> {\n return this.httpClient.get(\"/seats/balances\", {\n customerId: params.customerId,\n externalId: params.externalId,\n });\n }\n\n async listEvents(\n params?: ListSeatEventsParams,\n ): Promise<ApiResponse<SeatEvent[]>> {\n return this.httpClient.get(\"/seats/events\", params);\n }\n}\n","import type {\n ApiResponse,\n CustomerID,\n EventID,\n GeneratedEventType,\n ListParams,\n RequestOptions,\n} from \"../types/common\";\nimport type { CommetHTTPClient } from \"../utils/http\";\n\nexport interface UsageEvent {\n id: EventID;\n organizationId: string;\n customerId: CustomerID;\n eventType: GeneratedEventType;\n idempotencyKey?: string;\n ts: string;\n properties?: UsageEventProperty[];\n createdAt: string;\n}\n\nexport interface UsageEventProperty {\n id: string;\n usageEventId: EventID;\n property: string;\n value: string;\n createdAt: string;\n}\n\nexport interface CreateUsageEventParams {\n eventType: GeneratedEventType;\n customerId?: CustomerID;\n externalId?: string;\n idempotencyKey?: string; // For idempotency\n timestamp?: string; // ISO string, defaults to now\n properties?: Array<{\n property: string;\n value: string;\n }>;\n}\n\nexport interface CreateBatchUsageEventsParams {\n events: CreateUsageEventParams[];\n}\n\nexport interface BatchResult<T> {\n successful: T[];\n failed: Array<{\n index: number;\n error: string;\n data: CreateUsageEventParams;\n }>;\n}\n\nexport interface ListUsageEventsParams extends ListParams {\n customerId?: CustomerID;\n externalId?: string;\n eventType?: GeneratedEventType;\n idempotencyKey?: string;\n}\n\n/**\n * Usage Events resource - Track business events for usage-based billing\n */\nexport class UsageResource {\n constructor(private httpClient: CommetHTTPClient) {}\n\n async create(\n params: CreateUsageEventParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<UsageEvent>> {\n const eventData = {\n ...params,\n ts: params.timestamp || new Date().toISOString(),\n };\n\n return this.httpClient.post(\"/usage/events\", eventData, options);\n }\n\n async createBatch(\n params: CreateBatchUsageEventsParams,\n options?: RequestOptions,\n ): Promise<ApiResponse<BatchResult<UsageEvent>>> {\n return this.httpClient.post(\"/usage/events/batch\", params, options);\n }\n\n async retrieve(eventId: EventID): Promise<ApiResponse<UsageEvent>> {\n return this.httpClient.get(`/usage/events/${eventId}`);\n }\n\n async list(\n params?: ListUsageEventsParams,\n ): Promise<ApiResponse<UsageEvent[]>> {\n return this.httpClient.get(\"/usage/events\", params);\n }\n\n async delete(\n eventId: EventID,\n options?: RequestOptions,\n ): Promise<ApiResponse<{ deleted: boolean }>> {\n return this.httpClient.delete(\n `/usage/events/${eventId}`,\n undefined,\n options,\n );\n }\n}\n","export type Environment = \"sandbox\" | \"production\";\n\nexport type CommetConfig = {\n apiKey: string;\n environment?: Environment;\n debug?: boolean;\n timeout?: number;\n retries?: number;\n};\n\n// API Response types\nexport interface ApiResponse<T = unknown> {\n success: boolean;\n data?: T;\n error?: string;\n message?: string;\n // Pagination fields (optional, included for list endpoints)\n hasMore?: boolean;\n nextCursor?: string;\n}\n\nexport interface PaginatedResponse<T> {\n data: T[];\n hasMore: boolean;\n nextCursor?: string;\n totalCount?: number;\n}\n\nexport interface PaginatedList<T> extends PaginatedResponse<T> {\n next(): Promise<PaginatedList<T>>;\n all(): Promise<T[]>;\n}\n\n// Error types\nexport class CommetError extends Error {\n constructor(\n message: string,\n public code?: string,\n public statusCode?: number,\n public details?: unknown,\n ) {\n super(message);\n this.name = \"CommetError\";\n }\n}\n\nexport class CommetAPIError extends CommetError {\n constructor(\n message: string,\n public statusCode: number,\n public code?: string,\n public details?: unknown,\n ) {\n super(message, code, statusCode, details);\n this.name = \"CommetAPIError\";\n }\n}\n\nexport class CommetValidationError extends CommetError {\n constructor(\n message: string,\n public validationErrors: Record<string, string[]>,\n ) {\n super(message);\n this.name = \"CommetValidationError\";\n }\n}\n\nexport type CustomerID = `cus_${string}`;\nexport type AgreementID = `agr_${string}`;\nexport type InvoiceID = `inv_${string}`;\nexport type PhaseID = `phs_${string}`;\nexport type ItemID = `itm_${string}`;\nexport type ProductID = `prd_${string}`;\nexport type EventID = `evt_${string}`;\nexport type WebhookID = `wh_${string}`;\n\n// Currency enum\nexport type Currency =\n | \"USD\"\n | \"EUR\"\n | \"GBP\"\n | \"CAD\"\n | \"AUD\"\n | \"JPY\"\n | \"ARS\"\n | \"BRL\"\n | \"MXN\"\n | \"CLP\";\n\n// Common parameters\nexport interface ListParams extends Record<string, unknown> {\n limit?: number;\n cursor?: string;\n startDate?: string;\n endDate?: string;\n}\n\nexport interface RetrieveOptions {\n expand?: string[];\n}\n\n// Request options\nexport interface RequestOptions {\n idempotencyKey?: string;\n timeout?: number;\n}\n\n/**\n * Generated types interface - augmented by CLI after 'commet pull'\n *\n * This interface gets filled by module augmentation when you run `commet pull`.\n * The CLI generates a .commet.d.ts file that augments this interface with your\n * organization's specific event and seat types.\n *\n * @example\n * // After running `commet pull`, TypeScript will automatically know your types:\n * await commet.usage.events.create({\n * eventType: 'api_call', // Autocomplete works!\n * customerId: 'cus_123'\n * });\n */\n\n// biome-ignore lint/suspicious/noEmptyInterface: <explanation>\nexport interface CommetGeneratedTypes {}\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedEventType = CommetGeneratedTypes extends {\n eventType: infer T;\n}\n ? T\n : string;\n\n/**\n * Helper type that provides fallback to string if types are not generated\n */\nexport type GeneratedSeatType = CommetGeneratedTypes extends {\n seatType: infer T;\n}\n ? T\n : string;\n","import type {\n ApiResponse,\n CommetConfig,\n Environment,\n RequestOptions,\n} from \"../types/common\";\nimport { CommetAPIError, CommetValidationError } from \"../types/common\";\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n retryableStatusCodes: number[];\n}\n\nconst DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxRetries: 3,\n baseDelay: 1000, // 1s\n maxDelay: 8000, // 8s\n retryableStatusCodes: [408, 429, 500, 502, 503, 504],\n};\n\nexport class CommetHTTPClient {\n private config: CommetConfig;\n private environment: Environment;\n private retryConfig: RetryConfig;\n\n constructor(config: CommetConfig, environment: Environment) {\n this.config = config;\n this.environment = environment;\n this.retryConfig = {\n ...DEFAULT_RETRY_CONFIG,\n maxRetries: config.retries ?? DEFAULT_RETRY_CONFIG.maxRetries,\n };\n }\n\n async get<T = unknown>(\n endpoint: string,\n params?: Record<string, unknown>,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"GET\", endpoint, undefined, options, params);\n }\n\n async post<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"POST\", endpoint, data, options);\n }\n\n async put<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"PUT\", endpoint, data, options);\n }\n\n async delete<T = unknown>(\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n ): Promise<ApiResponse<T>> {\n return this.request(\"DELETE\", endpoint, data, options);\n }\n\n /**\n * Core request method with retry logic\n */\n private async request<T = unknown>(\n method: string,\n endpoint: string,\n data?: unknown,\n options?: RequestOptions,\n params?: Record<string, unknown>,\n ): Promise<ApiResponse<T>> {\n const url = this.buildURL(endpoint, params);\n return this.executeRequest(method, url, data, options);\n }\n\n /**\n * Execute real API request with retry logic\n */\n private async executeRequest<T = unknown>(\n method: string,\n url: string,\n data?: unknown,\n options?: RequestOptions,\n attempt = 1,\n ): Promise<ApiResponse<T>> {\n try {\n const headers: Record<string, string> = {\n \"x-api-key\": this.config.apiKey,\n \"Content-Type\": \"application/json\",\n \"User-Agent\": \"commet/0.1.0\",\n };\n\n if (options?.idempotencyKey) {\n headers[\"Idempotency-Key\"] = options.idempotencyKey;\n } else if (method === \"POST\" && data) {\n headers[\"Idempotency-Key\"] = this.generateIdempotencyKey();\n }\n\n const requestConfig: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(\n options?.timeout ?? this.config.timeout ?? 30000,\n ),\n };\n\n if (data) {\n requestConfig.body = JSON.stringify(data);\n }\n\n if (this.config.debug) {\n console.log(`[Commet SDK] ${method} ${url}`);\n if (data) {\n console.log(\"Request data:\", JSON.stringify(data, null, 2));\n }\n }\n\n const response = await fetch(url, requestConfig);\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Response status: ${response.status} ${response.statusText}`,\n );\n }\n\n let responseData: unknown;\n let responseText: string;\n\n try {\n const responseClone = response.clone();\n responseData = await response.json();\n responseText = \"\";\n } catch (jsonError) {\n try {\n responseText = await response.text();\n } catch (textError) {\n responseText = \"Failed to read response body\";\n }\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Failed to parse JSON response:\",\n responseText,\n );\n }\n throw new CommetAPIError(\n `Invalid JSON response: ${response.status} ${response.statusText}`,\n response.status,\n \"INVALID_JSON\",\n { responseText },\n );\n }\n\n if (!response.ok) {\n // Check if we should retry\n if (\n attempt <= this.retryConfig.maxRetries &&\n this.retryConfig.retryableStatusCodes.includes(response.status)\n ) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Retrying in ${delay}ms (attempt ${attempt}/${this.retryConfig.maxRetries})`,\n );\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n\n // Log error response for debugging\n if (this.config.debug) {\n console.log(\n \"[Commet SDK] Error response:\",\n JSON.stringify(responseData, null, 2),\n );\n }\n\n // Type guard for error response\n const isErrorResponse = (\n data: unknown,\n ): data is {\n message?: string;\n errors?: Record<string, string[]>;\n code?: string;\n details?: unknown;\n } => {\n return typeof data === \"object\" && data !== null;\n };\n\n const errorData = isErrorResponse(responseData) ? responseData : {};\n\n // Handle different error types\n if (response.status === 400 && errorData.errors) {\n throw new CommetValidationError(\n errorData.message || \"Validation failed\",\n errorData.errors,\n );\n }\n\n throw new CommetAPIError(\n errorData.message || `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n errorData.details,\n );\n }\n\n if (this.config.debug) {\n console.log(\"[Commet SDK] Response:\", responseData);\n }\n\n return responseData as ApiResponse<T>;\n } catch (error) {\n // Handle network errors and timeouts\n if (error instanceof TypeError && error.message.includes(\"fetch\")) {\n if (attempt <= this.retryConfig.maxRetries) {\n const delay = Math.min(\n this.retryConfig.baseDelay * 2 ** (attempt - 1),\n this.retryConfig.maxDelay,\n );\n\n if (this.config.debug) {\n console.log(`[Commet SDK] Network error, retrying in ${delay}ms`);\n }\n\n await this.sleep(delay);\n return this.executeRequest(method, url, data, options, attempt + 1);\n }\n }\n\n throw error;\n }\n }\n\n /**\n * Get base URL based on environment\n */\n private getBaseURL(): string {\n return this.environment === \"production\"\n ? \"https://api.commet.co\"\n : \"https://api.sandbox.commet.co\";\n }\n\n /**\n * Build full URL from endpoint and params\n */\n private buildURL(endpoint: string, params?: Record<string, unknown>): string {\n const baseURL = this.getBaseURL();\n\n // Construct full path (no /api prefix needed - it's in the domain now)\n const fullPath = endpoint.startsWith(\"/\") ? endpoint : `/${endpoint}`;\n\n // Debug logging\n if (this.config.debug) {\n console.log(\n `[Commet SDK] Building URL - baseURL: ${baseURL}, endpoint: ${endpoint}, fullPath: ${fullPath}`,\n );\n }\n\n const url = new URL(fullPath, baseURL);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value));\n }\n }\n }\n\n const finalUrl = url.toString();\n\n // Debug final URL\n if (this.config.debug) {\n console.log(`[Commet SDK] Final URL: ${finalUrl}`);\n }\n\n return finalUrl;\n }\n\n /**\n * Generate idempotency key\n */\n private generateIdempotencyKey(): string {\n // Generate UUID-like key for idempotency\n return `sdk_${Date.now()}_${Math.random().toString(36).substring(2)}`;\n }\n\n /**\n * Sleep for specified milliseconds\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n","import { CustomersResource } from \"./resources/customers\";\nimport { SeatsResource } from \"./resources/seats\";\nimport { UsageResource } from \"./resources/usage\";\nimport type { CommetConfig, Environment } from \"./types/common\";\nimport { CommetHTTPClient } from \"./utils/http\";\n\n/**\n * Main Commet SDK client\n */\nexport class Commet {\n private httpClient: CommetHTTPClient;\n private environment: Environment;\n\n public readonly customers: CustomersResource;\n public readonly usage: UsageResource;\n public readonly seats: SeatsResource;\n\n constructor(config: CommetConfig) {\n if (!config.apiKey) {\n throw new Error(\"Commet SDK: API key is required\");\n }\n\n if (!config.apiKey.startsWith(\"ck_\")) {\n throw new Error(\n \"Commet SDK: Invalid API key format. Expected format: ck_xxx...\",\n );\n }\n\n // Default to sandbox for safety\n this.environment = config.environment || \"sandbox\";\n\n this.httpClient = new CommetHTTPClient(config, this.environment);\n this.customers = new CustomersResource(this.httpClient);\n this.usage = new UsageResource(this.httpClient);\n this.seats = new SeatsResource(this.httpClient);\n\n if (config.debug) {\n console.log(`[Commet SDK] Initialized in ${this.environment} mode`);\n console.log(\"API Key:\", `${config.apiKey.substring(0, 12)}...`);\n const baseURL =\n this.environment === \"production\"\n ? \"https://api.commet.co\"\n : \"https://api.sandbox.commet.co\";\n console.log(\"Base URL:\", baseURL);\n }\n }\n\n getEnvironment(): Environment {\n return this.environment;\n }\n\n isSandbox(): boolean {\n return this.environment === \"sandbox\";\n }\n\n isProduction(): boolean {\n return this.environment === \"production\";\n }\n}\n","import type { Environment } from \"../types/common\";\n\n/**\n * Check if environment is sandbox\n */\nexport function isSandbox(environment: Environment): boolean {\n return environment === \"sandbox\";\n}\n\n/**\n * Check if environment is production\n */\nexport function isProduction(environment: Environment): boolean {\n return environment === \"production\";\n}\n","/**\n * Commet SDK - Billing and usage tracking SDK\n */\nexport { Commet } from \"./client\";\n\n// Type exports\nexport type {\n CommetConfig,\n CommetGeneratedTypes,\n GeneratedEventType,\n GeneratedSeatType,\n Environment,\n ApiResponse,\n PaginatedResponse,\n PaginatedList,\n Currency,\n CustomerID,\n AgreementID,\n InvoiceID,\n PhaseID,\n ItemID,\n ProductID,\n EventID,\n WebhookID,\n ListParams,\n RetrieveOptions,\n RequestOptions,\n} from \"./types/common\";\n\n// Error exports\nexport {\n CommetError,\n CommetAPIError,\n CommetValidationError,\n} from \"./types/common\";\n\n// Resource type exports\nexport type {\n Customer,\n CreateCustomerParams,\n UpdateCustomerParams,\n ListCustomersParams,\n} from \"./resources/customers\";\n\nexport type {\n UsageEvent,\n UsageEventProperty,\n CreateUsageEventParams,\n CreateBatchUsageEventsParams,\n BatchResult,\n ListUsageEventsParams,\n} from \"./resources/usage\";\n\nexport type {\n SeatBalance,\n SeatEvent,\n SeatBalanceResponse,\n BulkSeatUpdate,\n AddSeatsParams,\n RemoveSeatsParams,\n SetSeatsParams,\n BulkUpdateSeatsParams,\n GetBalanceParams,\n GetAllBalancesParams,\n ListSeatEventsParams,\n} from \"./resources/seats\";\n\n// Utility exports\nexport { isSandbox, isProduction } from \"./utils/environment\";\n\n// Default export\nimport { Commet } from \"./client\";\nexport default Commet;\n"],"mappings":"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","names":["data"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commet/node",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Commet SDK for Node.js - Billing and usage tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -31,7 +31,6 @@
31
31
  "zod": "^3.22.4"
32
32
  },
33
33
  "devDependencies": {
34
- "@biomejs/biome": "^1.9.4",
35
34
  "@types/node": "^20.10.0",
36
35
  "tsup": "^8.0.1",
37
36
  "typescript": "^5.3.3"
@@ -55,7 +54,7 @@
55
54
  "build": "tsup",
56
55
  "dev": "tsup --watch",
57
56
  "lint": "biome lint src/",
58
- "lint:fix": "biome lint --apply src/",
57
+ "lint:fix": "biome lint --write src/",
59
58
  "typecheck": "tsc --noEmit"
60
59
  }
61
60
  }