@commet/node 1.7.1 → 1.9.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/dist/index.mjs CHANGED
@@ -1,61 +1,46 @@
1
1
  // src/customer.ts
2
2
  var CustomerContext = class {
3
- constructor(externalId, resources) {
4
- /**
5
- * Feature access methods - delegates to FeaturesResource
6
- */
3
+ constructor(customerId, resources) {
7
4
  this.features = {
8
- get: (code, options) => this.featuresResource.get({ code, externalId: this.externalId }, options),
5
+ get: (code, options) => this.featuresResource.get({ code, customerId: this.customerId }, options),
9
6
  check: (code, options) => this.featuresResource.check(
10
- { code, externalId: this.externalId },
7
+ { code, customerId: this.customerId },
11
8
  options
12
9
  ),
13
10
  canUse: (code, options) => this.featuresResource.canUse(
14
- { code, externalId: this.externalId },
11
+ { code, customerId: this.customerId },
15
12
  options
16
13
  ),
17
- list: (options) => this.featuresResource.list(this.externalId, options)
14
+ list: (options) => this.featuresResource.list(this.customerId, options)
18
15
  };
19
- /**
20
- * Seat management methods - delegates to SeatsResource
21
- */
22
16
  this.seats = {
23
17
  add: (seatType, count = 1, options) => this.seatsResource.add(
24
- { externalId: this.externalId, seatType, count },
18
+ { customerId: this.customerId, seatType, count },
25
19
  options
26
20
  ),
27
21
  remove: (seatType, count = 1, options) => this.seatsResource.remove(
28
- { externalId: this.externalId, seatType, count },
22
+ { customerId: this.customerId, seatType, count },
29
23
  options
30
24
  ),
31
25
  set: (seatType, count, options) => this.seatsResource.set(
32
- { externalId: this.externalId, seatType, count },
26
+ { customerId: this.customerId, seatType, count },
33
27
  options
34
28
  ),
35
- getBalance: (seatType) => this.seatsResource.getBalance({ externalId: this.externalId, seatType })
29
+ getBalance: (seatType) => this.seatsResource.getBalance({ customerId: this.customerId, seatType })
36
30
  };
37
- /**
38
- * Usage tracking methods - delegates to UsageResource
39
- */
40
31
  this.usage = {
41
32
  track: (feature, value, properties, options) => this.usageResource.track(
42
- { externalId: this.externalId, feature, value, properties },
33
+ { customerId: this.customerId, feature, value, properties },
43
34
  options
44
35
  )
45
36
  };
46
- /**
47
- * Subscription methods - delegates to SubscriptionsResource
48
- */
49
37
  this.subscription = {
50
- get: () => this.subscriptionsResource.get(this.externalId)
38
+ get: () => this.subscriptionsResource.get(this.customerId)
51
39
  };
52
- /**
53
- * Portal methods - delegates to PortalResource
54
- */
55
40
  this.portal = {
56
- getUrl: (options) => this.portalResource.getUrl({ externalId: this.externalId }, options)
41
+ getUrl: (options) => this.portalResource.getUrl({ customerId: this.customerId }, options)
57
42
  };
58
- this.externalId = externalId;
43
+ this.customerId = customerId;
59
44
  this.featuresResource = resources.features;
60
45
  this.seatsResource = resources.seats;
61
46
  this.usageResource = resources.usage;
@@ -89,14 +74,14 @@ var CustomersResource = class {
89
74
  this.httpClient = httpClient;
90
75
  }
91
76
  /**
92
- * Create a customer (idempotent with externalId)
77
+ * Create a customer (idempotent when id is provided)
93
78
  */
94
79
  async create(params, options) {
95
80
  return this.httpClient.post(
96
81
  "/customers",
97
82
  {
98
83
  billingEmail: params.email,
99
- externalId: params.externalId,
84
+ externalId: params.id,
100
85
  fullName: params.fullName,
101
86
  domain: params.domain,
102
87
  website: params.website,
@@ -115,7 +100,7 @@ var CustomersResource = class {
115
100
  async createBatch(params, options) {
116
101
  const customers = params.customers.map((c) => ({
117
102
  billingEmail: c.email,
118
- externalId: c.externalId,
103
+ externalId: c.id,
119
104
  fullName: c.fullName,
120
105
  domain: c.domain,
121
106
  website: c.website,
@@ -141,14 +126,14 @@ var CustomersResource = class {
141
126
  `/customers/${params.customerId}`,
142
127
  {
143
128
  billingEmail: params.email,
144
- externalId: params.externalId,
145
129
  fullName: params.fullName,
146
130
  domain: params.domain,
147
131
  website: params.website,
148
132
  timezone: params.timezone,
149
133
  language: params.language,
150
134
  industry: params.industry,
151
- metadata: params.metadata
135
+ metadata: params.metadata,
136
+ address: params.address
152
137
  },
153
138
  options
154
139
  );
@@ -176,98 +161,41 @@ var FeaturesResource = class {
176
161
  constructor(httpClient) {
177
162
  this.httpClient = httpClient;
178
163
  }
179
- /**
180
- * Get detailed feature access/usage for a customer
181
- *
182
- * @example
183
- * ```typescript
184
- * const seats = await commet.features.get({ code: "team_members", externalId: "user_123" });
185
- * console.log(seats.current, seats.included, seats.remaining);
186
- * ```
187
- */
188
164
  async get(params, options) {
189
- const { code, externalId } = params;
190
165
  return this.httpClient.get(
191
- `/features/${code}`,
192
- { externalId },
166
+ `/features/${params.code}`,
167
+ { customerId: params.customerId },
193
168
  options
194
169
  );
195
170
  }
196
- /**
197
- * Check if a boolean feature is enabled for a customer
198
- *
199
- * @example
200
- * ```typescript
201
- * const { allowed } = await commet.features.check({
202
- * code: "custom_branding",
203
- * externalId: "user_123"
204
- * });
205
- * if (!allowed) redirect("/upgrade");
206
- * ```
207
- */
208
171
  async check(params, options) {
209
- const { code, externalId } = params;
210
172
  const result = await this.httpClient.get(
211
- `/features/${code}`,
212
- { externalId },
173
+ `/features/${params.code}`,
174
+ { customerId: params.customerId },
213
175
  options
214
176
  );
215
177
  if (!result.success || !result.data) {
216
178
  return {
217
179
  success: false,
218
- data: { allowed: false },
219
- message: result.message
180
+ code: result.code,
181
+ message: result.message,
182
+ details: result.details
220
183
  };
221
184
  }
222
185
  return {
223
186
  success: true,
224
- data: { allowed: result.data.allowed },
225
- message: result.message
187
+ data: { allowed: result.data.allowed }
226
188
  };
227
189
  }
228
- /**
229
- * Check if customer can use one more unit of a feature
230
- *
231
- * Returns whether the customer can add one more (allowed)
232
- * and whether they'll be charged extra (willBeCharged).
233
- *
234
- * @example
235
- * ```typescript
236
- * const { allowed, willBeCharged } = await commet.features.canUse({
237
- * code: "team_members",
238
- * externalId: "user_123"
239
- * });
240
- *
241
- * if (!allowed) {
242
- * return { error: "Upgrade to add more members" };
243
- * }
244
- *
245
- * if (willBeCharged) {
246
- * // Show confirmation: "This will cost $10/month extra"
247
- * }
248
- * ```
249
- */
250
190
  async canUse(params, options) {
251
- const { code, externalId } = params;
252
191
  return this.httpClient.get(
253
- `/features/${code}`,
254
- { externalId, action: "canUse" },
192
+ `/features/${params.code}`,
193
+ { customerId: params.customerId, action: "canUse" },
255
194
  options
256
195
  );
257
196
  }
258
- /**
259
- * List all features for a customer's active subscription
260
- *
261
- * @example
262
- * ```typescript
263
- * const features = await commet.features.list({ externalId: "user_123" });
264
- * for (const feature of features) {
265
- * console.log(feature.code, feature.allowed);
266
- * }
267
- * ```
268
- */
269
- async list(externalId, options) {
270
- return this.httpClient.get("/features", { externalId }, options);
197
+ async list(customerId, options) {
198
+ return this.httpClient.get("/features", { customerId }, options);
271
199
  }
272
200
  };
273
201
 
@@ -311,14 +239,6 @@ var PortalResource = class {
311
239
  constructor(httpClient) {
312
240
  this.httpClient = httpClient;
313
241
  }
314
- /**
315
- * Get a portal URL
316
- *
317
- * @example
318
- * ```typescript
319
- * const portal = await commet.portal.getUrl({ externalId: 'user_123' });
320
- * ```
321
- */
322
242
  async getUrl(params, options) {
323
243
  return this.httpClient.post("/portal/request-access", params, options);
324
244
  }
@@ -329,99 +249,27 @@ var SeatsResource = class {
329
249
  constructor(httpClient) {
330
250
  this.httpClient = httpClient;
331
251
  }
332
- /**
333
- * Add seats
334
- *
335
- * @example
336
- * ```typescript
337
- * await commet.seats.add({
338
- * externalId: 'user_123',
339
- * seatType: 'editor',
340
- * count: 5
341
- * });
342
- * ```
343
- */
344
252
  async add(params, options) {
345
253
  return this.httpClient.post("/seats", params, options);
346
254
  }
347
- /**
348
- * Remove seats
349
- *
350
- * @example
351
- * ```typescript
352
- * await commet.seats.remove({
353
- * externalId: 'user_123',
354
- * seatType: 'editor',
355
- * count: 2
356
- * });
357
- * ```
358
- */
359
255
  async remove(params, options) {
360
256
  return this.httpClient.delete("/seats", params, options);
361
257
  }
362
- /**
363
- * Set seats to a specific count
364
- *
365
- * @example
366
- * ```typescript
367
- * await commet.seats.set({
368
- * externalId: 'user_123',
369
- * seatType: 'editor',
370
- * count: 10
371
- * });
372
- * ```
373
- */
374
258
  async set(params, options) {
375
259
  return this.httpClient.put("/seats", params, options);
376
260
  }
377
- /**
378
- * Set all seat types
379
- *
380
- * @example
381
- * ```typescript
382
- * await commet.seats.setAll({
383
- * externalId: 'user_123',
384
- * seats: { editor: 10, viewer: 50 }
385
- * });
386
- * ```
387
- */
388
261
  async setAll(params, options) {
389
262
  return this.httpClient.put("/seats/bulk", params, options);
390
263
  }
391
- /**
392
- * Get balance for a seat type
393
- *
394
- * @example
395
- * ```typescript
396
- * const balance = await commet.seats.getBalance({
397
- * externalId: 'user_123',
398
- * seatType: 'editor'
399
- * });
400
- * ```
401
- */
402
264
  async getBalance(params) {
403
- const { customerId, externalId, seatType } = params;
404
265
  return this.httpClient.get("/seats/balance", {
405
- customerId,
406
- externalId,
407
- seatType
266
+ customerId: params.customerId,
267
+ seatType: params.seatType
408
268
  });
409
269
  }
410
- /**
411
- * Get all seat balances
412
- *
413
- * @example
414
- * ```typescript
415
- * const balances = await commet.seats.getAllBalances({
416
- * externalId: 'user_123'
417
- * });
418
- * ```
419
- */
420
270
  async getAllBalances(params) {
421
- const { customerId, externalId } = params;
422
271
  return this.httpClient.get("/seats/balances", {
423
- customerId,
424
- externalId
272
+ customerId: params.customerId
425
273
  });
426
274
  }
427
275
  };
@@ -455,8 +303,8 @@ var SubscriptionsResource = class {
455
303
  * const sub = await commet.subscriptions.get('user_123');
456
304
  * ```
457
305
  */
458
- async get(externalId) {
459
- return this.httpClient.get("/subscriptions/active", { externalId });
306
+ async get(customerId) {
307
+ return this.httpClient.get("/subscriptions/active", { customerId });
460
308
  }
461
309
  /**
462
310
  * Cancel a subscription
@@ -487,7 +335,6 @@ var UsageResource = class {
487
335
  const eventData = {
488
336
  feature: params.feature,
489
337
  customerId: params.customerId,
490
- externalId: params.externalId,
491
338
  idempotencyKey: params.idempotencyKey,
492
339
  timestamp: params.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
493
340
  properties: params.properties ? Object.entries(params.properties).map(([property, value]) => ({
@@ -510,36 +357,6 @@ var UsageResource = class {
510
357
  }
511
358
  return this.httpClient.post("/usage/events", eventData, options);
512
359
  }
513
- async trackBatch(params, options) {
514
- const events = params.events.map((event) => {
515
- const eventData = {
516
- feature: event.feature,
517
- customerId: event.customerId,
518
- externalId: event.externalId,
519
- idempotencyKey: event.idempotencyKey,
520
- timestamp: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
521
- properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
522
- property,
523
- value
524
- })) : void 0
525
- };
526
- if ("model" in event && event.model) {
527
- eventData.model = event.model;
528
- eventData.inputTokens = event.inputTokens;
529
- eventData.outputTokens = event.outputTokens;
530
- if (event.cacheReadTokens) {
531
- eventData.cacheReadTokens = event.cacheReadTokens;
532
- }
533
- if (event.cacheWriteTokens) {
534
- eventData.cacheWriteTokens = event.cacheWriteTokens;
535
- }
536
- } else {
537
- eventData.value = event.value;
538
- }
539
- return eventData;
540
- });
541
- return this.httpClient.post("/usage/events/batch", { events }, options);
542
- }
543
360
  };
544
361
 
545
362
  // src/resources/webhooks.ts
@@ -707,7 +524,7 @@ var CommetHTTPClient = class {
707
524
  const headers = {
708
525
  "x-api-key": this.config.apiKey,
709
526
  "Content-Type": "application/json",
710
- "User-Agent": "commet/0.1.0"
527
+ "User-Agent": "commet-node/1.9.0"
711
528
  };
712
529
  if (options?.idempotencyKey) {
713
530
  headers["Idempotency-Key"] = options.idempotencyKey;
@@ -753,13 +570,6 @@ var CommetHTTPClient = class {
753
570
  responseText
754
571
  );
755
572
  }
756
- if (response.status === 404) {
757
- return {
758
- success: false,
759
- code: "not_found",
760
- message: "Resource not found"
761
- };
762
- }
763
573
  throw new CommetAPIError(
764
574
  `Invalid JSON response: ${response.status} ${response.statusText}`,
765
575
  response.status,
@@ -814,7 +624,10 @@ var CommetHTTPClient = class {
814
624
  }
815
625
  return responseData;
816
626
  } catch (error) {
817
- if (error instanceof TypeError && error.message.includes("fetch")) {
627
+ const isNetworkError = error instanceof TypeError && error.message.includes("fetch");
628
+ const isTimeoutError = error instanceof DOMException && error.name === "AbortError";
629
+ const isTimeoutErrorModern = typeof globalThis.DOMException !== "undefined" && error instanceof DOMException && error.name === "TimeoutError";
630
+ if (isNetworkError || isTimeoutError || isTimeoutErrorModern) {
818
631
  if (attempt <= this.retryConfig.maxRetries) {
819
632
  const delay = Math.min(
820
633
  this.retryConfig.baseDelay * 2 ** (attempt - 1),
@@ -918,8 +731,8 @@ var Commet = class {
918
731
  * await customer.usage.track("api_call");
919
732
  * ```
920
733
  */
921
- customer(externalId) {
922
- return new CustomerContext(externalId, {
734
+ customer(customerId) {
735
+ return new CustomerContext(customerId, {
923
736
  features: this.features,
924
737
  seats: this.seats,
925
738
  usage: this.usage,