@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.js CHANGED
@@ -46,23 +46,84 @@ var CustomersResource = class {
46
46
  constructor(httpClient) {
47
47
  this.httpClient = httpClient;
48
48
  }
49
+ /**
50
+ * Create a customer (idempotent with externalId)
51
+ */
49
52
  async create(params, options) {
50
- return this.httpClient.post("/customers", params, options);
53
+ return this.httpClient.post(
54
+ "/customers",
55
+ {
56
+ billingEmail: params.email,
57
+ externalId: params.externalId,
58
+ legalName: params.legalName,
59
+ displayName: params.displayName,
60
+ domain: params.domain,
61
+ website: params.website,
62
+ timezone: params.timezone,
63
+ language: params.language,
64
+ industry: params.industry,
65
+ metadata: params.metadata,
66
+ address: params.address
67
+ },
68
+ options
69
+ );
51
70
  }
52
- async retrieve(customerId, options) {
53
- const params = options?.expand ? { expand: options.expand.join(",") } : void 0;
54
- return this.httpClient.get(`/customers/${customerId}`, params);
71
+ /**
72
+ * Create multiple customers in batch
73
+ */
74
+ async createBatch(params, options) {
75
+ const customers = params.customers.map((c) => ({
76
+ billingEmail: c.email,
77
+ externalId: c.externalId,
78
+ legalName: c.legalName,
79
+ displayName: c.displayName,
80
+ domain: c.domain,
81
+ website: c.website,
82
+ timezone: c.timezone,
83
+ language: c.language,
84
+ industry: c.industry,
85
+ metadata: c.metadata,
86
+ address: c.address
87
+ }));
88
+ return this.httpClient.post("/customers/batch", { customers }, options);
55
89
  }
90
+ /**
91
+ * Get a customer by ID
92
+ */
93
+ async get(customerId) {
94
+ return this.httpClient.get(`/customers/${customerId}`);
95
+ }
96
+ /**
97
+ * Update a customer
98
+ */
56
99
  async update(customerId, params, options) {
57
- return this.httpClient.put(`/customers/${customerId}`, params, options);
100
+ return this.httpClient.put(
101
+ `/customers/${customerId}`,
102
+ {
103
+ billingEmail: params.email,
104
+ externalId: params.externalId,
105
+ legalName: params.legalName,
106
+ displayName: params.displayName,
107
+ domain: params.domain,
108
+ website: params.website,
109
+ timezone: params.timezone,
110
+ language: params.language,
111
+ industry: params.industry,
112
+ metadata: params.metadata
113
+ },
114
+ options
115
+ );
58
116
  }
117
+ /**
118
+ * List customers with optional filters
119
+ */
59
120
  async list(params) {
60
121
  return this.httpClient.get("/customers", params);
61
122
  }
62
123
  /**
63
- * Deactivate a customer (soft delete)
124
+ * Archive a customer
64
125
  */
65
- async deactivate(customerId, options) {
126
+ async archive(customerId, options) {
66
127
  return this.httpClient.put(
67
128
  `/customers/${customerId}`,
68
129
  { isActive: false },
@@ -71,58 +132,134 @@ var CustomersResource = class {
71
132
  }
72
133
  };
73
134
 
135
+ // src/resources/plans.ts
136
+ var PlansResource = class {
137
+ constructor(httpClient) {
138
+ this.httpClient = httpClient;
139
+ }
140
+ /**
141
+ * List all available plans
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * // List public plans
146
+ * const plans = await commet.plans.list();
147
+ *
148
+ * // Include private plans
149
+ * const allPlans = await commet.plans.list({ includePrivate: true });
150
+ * ```
151
+ */
152
+ async list(params) {
153
+ return this.httpClient.get("/plans", params);
154
+ }
155
+ /**
156
+ * Get a specific plan by ID
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const plan = await commet.plans.get('plan_xxx');
161
+ * console.log(plan.data.name); // "Pro"
162
+ * console.log(plan.data.prices); // [{ billingInterval: 'monthly', price: 9900 }]
163
+ * ```
164
+ */
165
+ async get(planId) {
166
+ return this.httpClient.get(`/plans/${planId}`);
167
+ }
168
+ };
169
+
170
+ // src/resources/portal.ts
171
+ var PortalResource = class {
172
+ constructor(httpClient) {
173
+ this.httpClient = httpClient;
174
+ }
175
+ /**
176
+ * Get a portal URL
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const portal = await commet.portal.getUrl({ externalId: 'user_123' });
181
+ * ```
182
+ */
183
+ async getUrl(params, options) {
184
+ return this.httpClient.post("/portal/request-access", params, options);
185
+ }
186
+ };
187
+
74
188
  // src/resources/seats.ts
75
189
  var SeatsResource = class {
76
190
  constructor(httpClient) {
77
191
  this.httpClient = httpClient;
78
192
  }
193
+ /**
194
+ * Add seats
195
+ *
196
+ * @example
197
+ * ```typescript
198
+ * await commet.seats.add({
199
+ * externalId: 'user_123',
200
+ * seatType: 'editor',
201
+ * count: 5
202
+ * });
203
+ * ```
204
+ */
79
205
  async add(params, options) {
80
- return this.httpClient.post(
81
- "/seats",
82
- {
83
- customerId: params.customerId,
84
- externalId: params.externalId,
85
- seatType: params.seatType,
86
- count: params.count
87
- },
88
- options
89
- );
206
+ return this.httpClient.post("/seats", params, options);
90
207
  }
208
+ /**
209
+ * Remove seats
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * await commet.seats.remove({
214
+ * externalId: 'user_123',
215
+ * seatType: 'editor',
216
+ * count: 2
217
+ * });
218
+ * ```
219
+ */
91
220
  async remove(params, options) {
92
- return this.httpClient.delete(
93
- "/seats",
94
- {
95
- customerId: params.customerId,
96
- externalId: params.externalId,
97
- seatType: params.seatType,
98
- count: params.count
99
- },
100
- options
101
- );
221
+ return this.httpClient.delete("/seats", params, options);
102
222
  }
223
+ /**
224
+ * Set seats to a specific count
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * await commet.seats.set({
229
+ * externalId: 'user_123',
230
+ * seatType: 'editor',
231
+ * count: 10
232
+ * });
233
+ * ```
234
+ */
103
235
  async set(params, options) {
104
- return this.httpClient.put(
105
- "/seats",
106
- {
107
- customerId: params.customerId,
108
- externalId: params.externalId,
109
- seatType: params.seatType,
110
- count: params.count
111
- },
112
- options
113
- );
236
+ return this.httpClient.put("/seats", params, options);
114
237
  }
115
- async bulkUpdate(params, options) {
116
- return this.httpClient.put(
117
- "/seats/bulk",
118
- {
119
- customerId: params.customerId,
120
- externalId: params.externalId,
121
- seats: params.seats
122
- },
123
- options
124
- );
238
+ /**
239
+ * Set all seat types
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * await commet.seats.setAll({
244
+ * externalId: 'user_123',
245
+ * seats: { editor: 10, viewer: 50 }
246
+ * });
247
+ * ```
248
+ */
249
+ async setAll(params, options) {
250
+ return this.httpClient.put("/seats/bulk", params, options);
125
251
  }
252
+ /**
253
+ * Get balance for a seat type
254
+ *
255
+ * @example
256
+ * ```typescript
257
+ * const balance = await commet.seats.getBalance({
258
+ * externalId: 'user_123',
259
+ * seatType: 'editor'
260
+ * });
261
+ * ```
262
+ */
126
263
  async getBalance(params) {
127
264
  return this.httpClient.get("/seats/balance", {
128
265
  customerId: params.customerId,
@@ -130,15 +267,22 @@ var SeatsResource = class {
130
267
  seatType: params.seatType
131
268
  });
132
269
  }
270
+ /**
271
+ * Get all seat balances
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * const balances = await commet.seats.getAllBalances({
276
+ * externalId: 'user_123'
277
+ * });
278
+ * ```
279
+ */
133
280
  async getAllBalances(params) {
134
281
  return this.httpClient.get("/seats/balances", {
135
282
  customerId: params.customerId,
136
283
  externalId: params.externalId
137
284
  });
138
285
  }
139
- async listEvents(params) {
140
- return this.httpClient.get("/seats/events", params);
141
- }
142
286
  };
143
287
 
144
288
  // src/resources/subscriptions.ts
@@ -147,29 +291,15 @@ var SubscriptionsResource = class {
147
291
  this.httpClient = httpClient;
148
292
  }
149
293
  /**
150
- * Create a subscription with multiple items (products)
294
+ * Create a subscription with a plan
151
295
  *
152
296
  * @example
153
297
  * ```typescript
154
- * // Free plan - Multiple products
155
298
  * await commet.subscriptions.create({
156
- * externalId: "org_123",
157
- * items: [
158
- * { priceId: "price_tasks_free", quantity: 1 },
159
- * { priceId: "price_usage_free" },
160
- * { priceId: "price_seats_free", initialSeats: 1 }
161
- * ]
162
- * });
163
- *
164
- * // Pro plan upgrade
165
- * await commet.subscriptions.create({
166
- * customerId: "cus_xxx",
167
- * items: [
168
- * { priceId: "price_tasks_pro" },
169
- * { priceId: "price_usage_pro" },
170
- * { priceId: "price_seats_pro", initialSeats: 5 }
171
- * ],
172
- * status: "active"
299
+ * externalId: 'user_123',
300
+ * planCode: 'pro', // autocomplete works after `commet pull`
301
+ * billingInterval: 'yearly',
302
+ * initialSeats: { editor: 5 }
173
303
  * });
174
304
  * ```
175
305
  */
@@ -177,44 +307,47 @@ var SubscriptionsResource = class {
177
307
  return this.httpClient.post("/subscriptions", params, options);
178
308
  }
179
309
  /**
180
- * Retrieve a subscription by ID
310
+ * Get the active subscription for a customer
311
+ *
312
+ * @example
313
+ * ```typescript
314
+ * const sub = await commet.subscriptions.get({ externalId: 'user_123' });
315
+ * ```
181
316
  */
182
- async retrieve(subscriptionId, options) {
183
- const params = options?.expand ? { expand: options.expand.join(",") } : void 0;
184
- return this.httpClient.get(`/subscriptions/${subscriptionId}`, params);
317
+ async get(params) {
318
+ return this.httpClient.get("/subscriptions/active", params);
185
319
  }
186
320
  /**
187
- * List subscriptions with optional filters
321
+ * Change the plan of a subscription (upgrade/downgrade)
188
322
  *
189
323
  * @example
190
324
  * ```typescript
191
- * // List all active subscriptions for a customer
192
- * await commet.subscriptions.list({
193
- * customerId: "cus_xxx",
194
- * status: "active"
195
- * });
196
- *
197
- * // Using externalId
198
- * await commet.subscriptions.list({
199
- * externalId: "my-customer-123"
325
+ * await commet.subscriptions.changePlan('sub_xxx', {
326
+ * planCode: 'enterprise' // autocomplete works after `commet pull`
200
327
  * });
201
328
  * ```
202
329
  */
203
- async list(params) {
204
- return this.httpClient.get("/subscriptions", params);
330
+ async changePlan(subscriptionId, params, options) {
331
+ return this.httpClient.post(
332
+ `/subscriptions/${subscriptionId}/change-plan`,
333
+ params,
334
+ options
335
+ );
205
336
  }
206
337
  /**
207
338
  * Cancel a subscription
208
339
  *
209
340
  * @example
210
341
  * ```typescript
211
- * await commet.subscriptions.cancel("sub_xxx");
342
+ * await commet.subscriptions.cancel('sub_xxx', {
343
+ * reason: 'switched_to_competitor'
344
+ * });
212
345
  * ```
213
346
  */
214
- async cancel(subscriptionId, options) {
347
+ async cancel(subscriptionId, params, options) {
215
348
  return this.httpClient.post(
216
349
  `/subscriptions/${subscriptionId}/cancel`,
217
- {},
350
+ params || {},
218
351
  options
219
352
  );
220
353
  }
@@ -225,28 +358,59 @@ var UsageResource = class {
225
358
  constructor(httpClient) {
226
359
  this.httpClient = httpClient;
227
360
  }
228
- async create(params, options) {
361
+ /**
362
+ * Track a usage event
363
+ *
364
+ * @example
365
+ * ```typescript
366
+ * await commet.usage.track({
367
+ * externalId: 'user_123',
368
+ * eventType: 'api_call',
369
+ * idempotencyKey: `evt_${requestId}`,
370
+ * properties: { endpoint: '/users', method: 'GET' }
371
+ * });
372
+ * ```
373
+ */
374
+ async track(params, options) {
229
375
  const eventData = {
230
- ...params,
231
- ts: params.timestamp || (/* @__PURE__ */ new Date()).toISOString()
376
+ eventType: params.eventType,
377
+ customerId: params.customerId,
378
+ externalId: params.externalId,
379
+ idempotencyKey: params.idempotencyKey,
380
+ ts: params.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
381
+ properties: params.properties ? Object.entries(params.properties).map(([property, value]) => ({
382
+ property,
383
+ value
384
+ })) : void 0
232
385
  };
233
386
  return this.httpClient.post("/usage/events", eventData, options);
234
387
  }
235
- async createBatch(params, options) {
236
- return this.httpClient.post("/usage/events/batch", params, options);
237
- }
238
- async retrieve(eventId) {
239
- return this.httpClient.get(`/usage/events/${eventId}`);
240
- }
241
- async list(params) {
242
- return this.httpClient.get("/usage/events", params);
243
- }
244
- async delete(eventId, options) {
245
- return this.httpClient.delete(
246
- `/usage/events/${eventId}`,
247
- void 0,
248
- options
249
- );
388
+ /**
389
+ * Track multiple usage events in a batch
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * await commet.usage.trackBatch({
394
+ * events: [
395
+ * { externalId: 'user_123', eventType: 'api_call', idempotencyKey: 'evt_1' },
396
+ * { externalId: 'user_456', eventType: 'api_call', idempotencyKey: 'evt_2' }
397
+ * ]
398
+ * });
399
+ * ```
400
+ */
401
+ async trackBatch(params, options) {
402
+ const events = params.events.map((event) => ({
403
+ eventType: event.eventType,
404
+ customerId: event.customerId,
405
+ externalId: event.externalId,
406
+ idempotencyKey: event.idempotencyKey,
407
+ ts: event.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
408
+ properties: event.properties ? Object.entries(event.properties).map(([property, value]) => ({
409
+ property,
410
+ value
411
+ })) : void 0
412
+ }));
413
+ return this.httpClient.post("/usage/events/batch", { events }, options);
250
414
  }
251
415
  };
252
416
 
@@ -449,7 +613,6 @@ var CommetHTTPClient = class {
449
613
  let responseData;
450
614
  let responseText;
451
615
  try {
452
- const responseClone = response.clone();
453
616
  responseData = await response.json();
454
617
  responseText = "";
455
618
  } catch (jsonError) {
@@ -464,6 +627,12 @@ var CommetHTTPClient = class {
464
627
  responseText
465
628
  );
466
629
  }
630
+ if (response.status === 404) {
631
+ return {
632
+ success: false,
633
+ error: "Resource not found"
634
+ };
635
+ }
467
636
  throw new CommetAPIError(
468
637
  `Invalid JSON response: ${response.status} ${response.statusText}`,
469
638
  response.status,
@@ -589,9 +758,11 @@ var Commet = class {
589
758
  this.environment = config.environment || "sandbox";
590
759
  this.httpClient = new CommetHTTPClient(config, this.environment);
591
760
  this.customers = new CustomersResource(this.httpClient);
761
+ this.plans = new PlansResource(this.httpClient);
592
762
  this.usage = new UsageResource(this.httpClient);
593
763
  this.seats = new SeatsResource(this.httpClient);
594
764
  this.subscriptions = new SubscriptionsResource(this.httpClient);
765
+ this.portal = new PortalResource(this.httpClient);
595
766
  this.webhooks = new Webhooks();
596
767
  if (config.debug) {
597
768
  console.log(`[Commet SDK] Initialized in ${this.environment} mode`);