@commet/node 0.10.1 → 1.0.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
@@ -3,23 +3,84 @@ var CustomersResource = class {
3
3
  constructor(httpClient) {
4
4
  this.httpClient = httpClient;
5
5
  }
6
+ /**
7
+ * Create a customer (idempotent with externalId)
8
+ */
6
9
  async create(params, options) {
7
- return this.httpClient.post("/customers", params, options);
10
+ return this.httpClient.post(
11
+ "/customers",
12
+ {
13
+ billingEmail: params.email,
14
+ externalId: params.externalId,
15
+ legalName: params.legalName,
16
+ displayName: params.displayName,
17
+ domain: params.domain,
18
+ website: params.website,
19
+ timezone: params.timezone,
20
+ language: params.language,
21
+ industry: params.industry,
22
+ metadata: params.metadata,
23
+ address: params.address
24
+ },
25
+ options
26
+ );
8
27
  }
9
- async retrieve(customerId, options) {
10
- const params = options?.expand ? { expand: options.expand.join(",") } : void 0;
11
- return this.httpClient.get(`/customers/${customerId}`, params);
28
+ /**
29
+ * Create multiple customers in batch
30
+ */
31
+ async createBatch(params, options) {
32
+ const customers = params.customers.map((c) => ({
33
+ billingEmail: c.email,
34
+ externalId: c.externalId,
35
+ legalName: c.legalName,
36
+ displayName: c.displayName,
37
+ domain: c.domain,
38
+ website: c.website,
39
+ timezone: c.timezone,
40
+ language: c.language,
41
+ industry: c.industry,
42
+ metadata: c.metadata,
43
+ address: c.address
44
+ }));
45
+ return this.httpClient.post("/customers/batch", { customers }, options);
12
46
  }
47
+ /**
48
+ * Get a customer by ID
49
+ */
50
+ async get(customerId) {
51
+ return this.httpClient.get(`/customers/${customerId}`);
52
+ }
53
+ /**
54
+ * Update a customer
55
+ */
13
56
  async update(customerId, params, options) {
14
- return this.httpClient.put(`/customers/${customerId}`, params, options);
57
+ return this.httpClient.put(
58
+ `/customers/${customerId}`,
59
+ {
60
+ billingEmail: params.email,
61
+ externalId: params.externalId,
62
+ legalName: params.legalName,
63
+ displayName: params.displayName,
64
+ domain: params.domain,
65
+ website: params.website,
66
+ timezone: params.timezone,
67
+ language: params.language,
68
+ industry: params.industry,
69
+ metadata: params.metadata
70
+ },
71
+ options
72
+ );
15
73
  }
74
+ /**
75
+ * List customers with optional filters
76
+ */
16
77
  async list(params) {
17
78
  return this.httpClient.get("/customers", params);
18
79
  }
19
80
  /**
20
- * Deactivate a customer (soft delete)
81
+ * Archive a customer
21
82
  */
22
- async deactivate(customerId, options) {
83
+ async archive(customerId, options) {
23
84
  return this.httpClient.put(
24
85
  `/customers/${customerId}`,
25
86
  { isActive: false },
@@ -28,58 +89,134 @@ var CustomersResource = class {
28
89
  }
29
90
  };
30
91
 
92
+ // src/resources/plans.ts
93
+ var PlansResource = class {
94
+ constructor(httpClient) {
95
+ this.httpClient = httpClient;
96
+ }
97
+ /**
98
+ * List all available plans
99
+ *
100
+ * @example
101
+ * ```typescript
102
+ * // List public plans
103
+ * const plans = await commet.plans.list();
104
+ *
105
+ * // Include private plans
106
+ * const allPlans = await commet.plans.list({ includePrivate: true });
107
+ * ```
108
+ */
109
+ async list(params) {
110
+ return this.httpClient.get("/plans", params);
111
+ }
112
+ /**
113
+ * Get a specific plan by ID
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * const plan = await commet.plans.get('plan_xxx');
118
+ * console.log(plan.data.name); // "Pro"
119
+ * console.log(plan.data.prices); // [{ billingInterval: 'monthly', price: 9900 }]
120
+ * ```
121
+ */
122
+ async get(planId) {
123
+ return this.httpClient.get(`/plans/${planId}`);
124
+ }
125
+ };
126
+
127
+ // src/resources/portal.ts
128
+ var PortalResource = class {
129
+ constructor(httpClient) {
130
+ this.httpClient = httpClient;
131
+ }
132
+ /**
133
+ * Get a portal URL
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const portal = await commet.portal.getUrl({ externalId: 'user_123' });
138
+ * ```
139
+ */
140
+ async getUrl(params, options) {
141
+ return this.httpClient.post("/portal/request-access", params, options);
142
+ }
143
+ };
144
+
31
145
  // src/resources/seats.ts
32
146
  var SeatsResource = class {
33
147
  constructor(httpClient) {
34
148
  this.httpClient = httpClient;
35
149
  }
150
+ /**
151
+ * Add seats
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * await commet.seats.add({
156
+ * externalId: 'user_123',
157
+ * seatType: 'editor',
158
+ * count: 5
159
+ * });
160
+ * ```
161
+ */
36
162
  async add(params, options) {
37
- return this.httpClient.post(
38
- "/seats",
39
- {
40
- customerId: params.customerId,
41
- externalId: params.externalId,
42
- seatType: params.seatType,
43
- count: params.count
44
- },
45
- options
46
- );
163
+ return this.httpClient.post("/seats", params, options);
47
164
  }
165
+ /**
166
+ * Remove seats
167
+ *
168
+ * @example
169
+ * ```typescript
170
+ * await commet.seats.remove({
171
+ * externalId: 'user_123',
172
+ * seatType: 'editor',
173
+ * count: 2
174
+ * });
175
+ * ```
176
+ */
48
177
  async remove(params, options) {
49
- return this.httpClient.delete(
50
- "/seats",
51
- {
52
- customerId: params.customerId,
53
- externalId: params.externalId,
54
- seatType: params.seatType,
55
- count: params.count
56
- },
57
- options
58
- );
178
+ return this.httpClient.delete("/seats", params, options);
59
179
  }
180
+ /**
181
+ * Set seats to a specific count
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * await commet.seats.set({
186
+ * externalId: 'user_123',
187
+ * seatType: 'editor',
188
+ * count: 10
189
+ * });
190
+ * ```
191
+ */
60
192
  async set(params, options) {
61
- return this.httpClient.put(
62
- "/seats",
63
- {
64
- customerId: params.customerId,
65
- externalId: params.externalId,
66
- seatType: params.seatType,
67
- count: params.count
68
- },
69
- options
70
- );
193
+ return this.httpClient.put("/seats", params, options);
71
194
  }
72
- async bulkUpdate(params, options) {
73
- return this.httpClient.put(
74
- "/seats/bulk",
75
- {
76
- customerId: params.customerId,
77
- externalId: params.externalId,
78
- seats: params.seats
79
- },
80
- options
81
- );
195
+ /**
196
+ * Set all seat types
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * await commet.seats.setAll({
201
+ * externalId: 'user_123',
202
+ * seats: { editor: 10, viewer: 50 }
203
+ * });
204
+ * ```
205
+ */
206
+ async setAll(params, options) {
207
+ return this.httpClient.put("/seats/bulk", params, options);
82
208
  }
209
+ /**
210
+ * Get balance for a seat type
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * const balance = await commet.seats.getBalance({
215
+ * externalId: 'user_123',
216
+ * seatType: 'editor'
217
+ * });
218
+ * ```
219
+ */
83
220
  async getBalance(params) {
84
221
  return this.httpClient.get("/seats/balance", {
85
222
  customerId: params.customerId,
@@ -87,15 +224,22 @@ var SeatsResource = class {
87
224
  seatType: params.seatType
88
225
  });
89
226
  }
227
+ /**
228
+ * Get all seat balances
229
+ *
230
+ * @example
231
+ * ```typescript
232
+ * const balances = await commet.seats.getAllBalances({
233
+ * externalId: 'user_123'
234
+ * });
235
+ * ```
236
+ */
90
237
  async getAllBalances(params) {
91
238
  return this.httpClient.get("/seats/balances", {
92
239
  customerId: params.customerId,
93
240
  externalId: params.externalId
94
241
  });
95
242
  }
96
- async listEvents(params) {
97
- return this.httpClient.get("/seats/events", params);
98
- }
99
243
  };
100
244
 
101
245
  // src/resources/subscriptions.ts
@@ -104,29 +248,15 @@ var SubscriptionsResource = class {
104
248
  this.httpClient = httpClient;
105
249
  }
106
250
  /**
107
- * Create a subscription with multiple items (products)
251
+ * Create a subscription with a plan
108
252
  *
109
253
  * @example
110
254
  * ```typescript
111
- * // Free plan - Multiple products
112
255
  * await commet.subscriptions.create({
113
- * externalId: "org_123",
114
- * items: [
115
- * { priceId: "price_tasks_free", quantity: 1 },
116
- * { priceId: "price_usage_free" },
117
- * { priceId: "price_seats_free", initialSeats: 1 }
118
- * ]
119
- * });
120
- *
121
- * // Pro plan upgrade
122
- * await commet.subscriptions.create({
123
- * customerId: "cus_xxx",
124
- * items: [
125
- * { priceId: "price_tasks_pro" },
126
- * { priceId: "price_usage_pro" },
127
- * { priceId: "price_seats_pro", initialSeats: 5 }
128
- * ],
129
- * status: "active"
256
+ * externalId: 'user_123',
257
+ * planCode: 'pro', // autocomplete works after `commet pull`
258
+ * billingInterval: 'yearly',
259
+ * initialSeats: { editor: 5 }
130
260
  * });
131
261
  * ```
132
262
  */
@@ -134,44 +264,47 @@ var SubscriptionsResource = class {
134
264
  return this.httpClient.post("/subscriptions", params, options);
135
265
  }
136
266
  /**
137
- * Retrieve a subscription by ID
267
+ * Get the active subscription for a customer
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * const sub = await commet.subscriptions.get({ externalId: 'user_123' });
272
+ * ```
138
273
  */
139
- async retrieve(subscriptionId, options) {
140
- const params = options?.expand ? { expand: options.expand.join(",") } : void 0;
141
- return this.httpClient.get(`/subscriptions/${subscriptionId}`, params);
274
+ async get(params) {
275
+ return this.httpClient.get("/subscriptions/active", params);
142
276
  }
143
277
  /**
144
- * List subscriptions with optional filters
278
+ * Change the plan of a subscription (upgrade/downgrade)
145
279
  *
146
280
  * @example
147
281
  * ```typescript
148
- * // List all active subscriptions for a customer
149
- * await commet.subscriptions.list({
150
- * customerId: "cus_xxx",
151
- * status: "active"
152
- * });
153
- *
154
- * // Using externalId
155
- * await commet.subscriptions.list({
156
- * externalId: "my-customer-123"
282
+ * await commet.subscriptions.changePlan('sub_xxx', {
283
+ * planCode: 'enterprise' // autocomplete works after `commet pull`
157
284
  * });
158
285
  * ```
159
286
  */
160
- async list(params) {
161
- return this.httpClient.get("/subscriptions", params);
287
+ async changePlan(subscriptionId, params, options) {
288
+ return this.httpClient.post(
289
+ `/subscriptions/${subscriptionId}/change-plan`,
290
+ params,
291
+ options
292
+ );
162
293
  }
163
294
  /**
164
295
  * Cancel a subscription
165
296
  *
166
297
  * @example
167
298
  * ```typescript
168
- * await commet.subscriptions.cancel("sub_xxx");
299
+ * await commet.subscriptions.cancel('sub_xxx', {
300
+ * reason: 'switched_to_competitor'
301
+ * });
169
302
  * ```
170
303
  */
171
- async cancel(subscriptionId, options) {
304
+ async cancel(subscriptionId, params, options) {
172
305
  return this.httpClient.post(
173
306
  `/subscriptions/${subscriptionId}/cancel`,
174
- {},
307
+ params || {},
175
308
  options
176
309
  );
177
310
  }
@@ -182,28 +315,59 @@ var UsageResource = class {
182
315
  constructor(httpClient) {
183
316
  this.httpClient = httpClient;
184
317
  }
185
- async create(params, options) {
318
+ /**
319
+ * Track a usage event
320
+ *
321
+ * @example
322
+ * ```typescript
323
+ * await commet.usage.track({
324
+ * externalId: 'user_123',
325
+ * eventType: 'api_call',
326
+ * idempotencyKey: `evt_${requestId}`,
327
+ * properties: { endpoint: '/users', method: 'GET' }
328
+ * });
329
+ * ```
330
+ */
331
+ async track(params, options) {
186
332
  const eventData = {
187
- ...params,
188
- ts: params.timestamp || (/* @__PURE__ */ new Date()).toISOString()
333
+ eventType: params.eventType,
334
+ customerId: params.customerId,
335
+ externalId: params.externalId,
336
+ idempotencyKey: params.idempotencyKey,
337
+ ts: params.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
338
+ properties: params.properties ? Object.entries(params.properties).map(([property, value]) => ({
339
+ property,
340
+ value
341
+ })) : void 0
189
342
  };
190
343
  return this.httpClient.post("/usage/events", eventData, options);
191
344
  }
192
- async createBatch(params, options) {
193
- return this.httpClient.post("/usage/events/batch", params, options);
194
- }
195
- async retrieve(eventId) {
196
- return this.httpClient.get(`/usage/events/${eventId}`);
197
- }
198
- async list(params) {
199
- return this.httpClient.get("/usage/events", params);
200
- }
201
- async delete(eventId, options) {
202
- return this.httpClient.delete(
203
- `/usage/events/${eventId}`,
204
- void 0,
205
- options
206
- );
345
+ /**
346
+ * Track multiple usage events in a batch
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * await commet.usage.trackBatch({
351
+ * events: [
352
+ * { externalId: 'user_123', eventType: 'api_call', idempotencyKey: 'evt_1' },
353
+ * { externalId: 'user_456', eventType: 'api_call', idempotencyKey: 'evt_2' }
354
+ * ]
355
+ * });
356
+ * ```
357
+ */
358
+ async trackBatch(params, options) {
359
+ const events = params.events.map((event) => ({
360
+ eventType: event.eventType,
361
+ customerId: event.customerId,
362
+ externalId: event.externalId,
363
+ idempotencyKey: event.idempotencyKey,
364
+ ts: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
365
+ properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
366
+ property,
367
+ value
368
+ })) : void 0
369
+ }));
370
+ return this.httpClient.post("/usage/events/batch", { events }, options);
207
371
  }
208
372
  };
209
373
 
@@ -406,7 +570,6 @@ var CommetHTTPClient = class {
406
570
  let responseData;
407
571
  let responseText;
408
572
  try {
409
- const responseClone = response.clone();
410
573
  responseData = await response.json();
411
574
  responseText = "";
412
575
  } catch (jsonError) {
@@ -421,6 +584,12 @@ var CommetHTTPClient = class {
421
584
  responseText
422
585
  );
423
586
  }
587
+ if (response.status === 404) {
588
+ return {
589
+ success: false,
590
+ error: "Resource not found"
591
+ };
592
+ }
424
593
  throw new CommetAPIError(
425
594
  `Invalid JSON response: ${response.status} ${response.statusText}`,
426
595
  response.status,
@@ -546,9 +715,11 @@ var Commet = class {
546
715
  this.environment = config.environment || "sandbox";
547
716
  this.httpClient = new CommetHTTPClient(config, this.environment);
548
717
  this.customers = new CustomersResource(this.httpClient);
718
+ this.plans = new PlansResource(this.httpClient);
549
719
  this.usage = new UsageResource(this.httpClient);
550
720
  this.seats = new SeatsResource(this.httpClient);
551
721
  this.subscriptions = new SubscriptionsResource(this.httpClient);
722
+ this.portal = new PortalResource(this.httpClient);
552
723
  this.webhooks = new Webhooks();
553
724
  if (config.debug) {
554
725
  console.log(`[Commet SDK] Initialized in ${this.environment} mode`);