@commet/node 1.1.0 → 1.2.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,181 +1,66 @@
1
1
  // src/customer.ts
2
2
  var CustomerContext = class {
3
- constructor(httpClient, externalId) {
3
+ constructor(externalId, resources) {
4
4
  /**
5
- * Feature access methods - check what the customer can use
5
+ * Feature access methods - delegates to FeaturesResource
6
6
  */
7
7
  this.features = {
8
- /**
9
- * Get detailed feature access/usage
10
- */
11
- get: (code, options) => {
12
- return this.httpClient.get(
13
- `/features/${code}`,
14
- { externalId: this.externalId },
15
- options
16
- );
17
- },
18
- /**
19
- * Check if a boolean feature is enabled
20
- */
21
- check: async (code, options) => {
22
- const result = await this.httpClient.get(
23
- `/features/${code}`,
24
- { externalId: this.externalId },
25
- options
26
- );
27
- if (!result.success || !result.data) {
28
- return {
29
- success: false,
30
- data: { allowed: false },
31
- message: result.message
32
- };
33
- }
34
- return {
35
- success: true,
36
- data: { allowed: result.data.allowed },
37
- message: result.message
38
- };
39
- },
40
- /**
41
- * Check if customer can use one more unit
42
- */
43
- canUse: (code, options) => {
44
- return this.httpClient.get(
45
- `/features/${code}`,
46
- { externalId: this.externalId, action: "canUse" },
47
- options
48
- );
49
- },
50
- /**
51
- * List all features
52
- */
53
- list: (options) => {
54
- return this.httpClient.get(
55
- "/features",
56
- { externalId: this.externalId },
57
- options
58
- );
59
- }
8
+ get: (code, options) => this.featuresResource.get({ code, externalId: this.externalId }, options),
9
+ check: (code, options) => this.featuresResource.check(
10
+ { code, externalId: this.externalId },
11
+ options
12
+ ),
13
+ canUse: (code, options) => this.featuresResource.canUse(
14
+ { code, externalId: this.externalId },
15
+ options
16
+ ),
17
+ list: (options) => this.featuresResource.list(this.externalId, options)
60
18
  };
61
19
  /**
62
- * Seat management methods
20
+ * Seat management methods - delegates to SeatsResource
63
21
  */
64
22
  this.seats = {
65
- /**
66
- * Add seats
67
- */
68
- add: (seatType, count = 1, options) => {
69
- return this.httpClient.post(
70
- "/seats/add",
71
- { externalId: this.externalId, seatType, count },
72
- options
73
- );
74
- },
75
- /**
76
- * Remove seats
77
- */
78
- remove: (seatType, count = 1, options) => {
79
- return this.httpClient.post(
80
- "/seats/remove",
81
- { externalId: this.externalId, seatType, count },
82
- options
83
- );
84
- },
85
- /**
86
- * Set total seat count
87
- */
88
- set: (seatType, count, options) => {
89
- return this.httpClient.post(
90
- "/seats/set",
91
- { externalId: this.externalId, seatType, count },
92
- options
93
- );
94
- },
95
- /**
96
- * Get current seat balance
97
- */
98
- getBalance: (seatType, options) => {
99
- return this.httpClient.get(
100
- "/seats/balance",
101
- { externalId: this.externalId, seatType },
102
- options
103
- );
104
- }
23
+ add: (seatType, count = 1, options) => this.seatsResource.add(
24
+ { externalId: this.externalId, seatType, count },
25
+ options
26
+ ),
27
+ remove: (seatType, count = 1, options) => this.seatsResource.remove(
28
+ { externalId: this.externalId, seatType, count },
29
+ options
30
+ ),
31
+ set: (seatType, count, options) => this.seatsResource.set(
32
+ { externalId: this.externalId, seatType, count },
33
+ options
34
+ ),
35
+ getBalance: (seatType) => this.seatsResource.getBalance({ externalId: this.externalId, seatType })
105
36
  };
106
37
  /**
107
- * Usage tracking methods
38
+ * Usage tracking methods - delegates to UsageResource
108
39
  */
109
40
  this.usage = {
110
- /**
111
- * Track a usage event
112
- */
113
- track: (eventType, properties, options) => {
114
- return this.httpClient.post(
115
- "/usage",
116
- {
117
- externalId: this.externalId,
118
- eventType,
119
- properties
120
- },
121
- options
122
- );
123
- }
41
+ track: (eventType, properties, options) => this.usageResource.track(
42
+ { externalId: this.externalId, eventType, properties },
43
+ options
44
+ )
124
45
  };
125
46
  /**
126
- * Subscription methods
47
+ * Subscription methods - delegates to SubscriptionsResource
127
48
  */
128
49
  this.subscription = {
129
- /**
130
- * Get active subscription
131
- */
132
- get: (options) => {
133
- return this.httpClient.get(
134
- "/subscriptions/active",
135
- { externalId: this.externalId },
136
- options
137
- );
138
- },
139
- /**
140
- * Cancel subscription
141
- */
142
- cancel: (params, options) => {
143
- return this.httpClient.get(
144
- "/subscriptions/active",
145
- { externalId: this.externalId }
146
- ).then((result) => {
147
- if (!result.success || !result.data) {
148
- return {
149
- success: false,
150
- data: null,
151
- message: "No active subscription found"
152
- };
153
- }
154
- return this.httpClient.post(
155
- `/subscriptions/${result.data.id}/cancel`,
156
- params || {},
157
- options
158
- );
159
- });
160
- }
50
+ get: () => this.subscriptionsResource.get(this.externalId)
161
51
  };
162
52
  /**
163
- * Portal methods
53
+ * Portal methods - delegates to PortalResource
164
54
  */
165
55
  this.portal = {
166
- /**
167
- * Get customer portal URL
168
- */
169
- getUrl: (options) => {
170
- return this.httpClient.get(
171
- "/portal/url",
172
- { externalId: this.externalId },
173
- options
174
- );
175
- }
56
+ getUrl: (options) => this.portalResource.getUrl({ externalId: this.externalId }, options)
176
57
  };
177
- this.httpClient = httpClient;
178
58
  this.externalId = externalId;
59
+ this.featuresResource = resources.features;
60
+ this.seatsResource = resources.seats;
61
+ this.usageResource = resources.usage;
62
+ this.subscriptionsResource = resources.subscriptions;
63
+ this.portalResource = resources.portal;
179
64
  }
180
65
  };
181
66
 
@@ -234,9 +119,9 @@ var CustomersResource = class {
234
119
  /**
235
120
  * Update a customer
236
121
  */
237
- async update(customerId, params, options) {
122
+ async update(params, options) {
238
123
  return this.httpClient.put(
239
- `/customers/${customerId}`,
124
+ `/customers/${params.customerId}`,
240
125
  {
241
126
  billingEmail: params.email,
242
127
  externalId: params.externalId,
@@ -280,11 +165,12 @@ var FeaturesResource = class {
280
165
  *
281
166
  * @example
282
167
  * ```typescript
283
- * const seats = await commet.features.get("team_members", "user_123");
168
+ * const seats = await commet.features.get({ code: "team_members", externalId: "user_123" });
284
169
  * console.log(seats.current, seats.included, seats.remaining);
285
170
  * ```
286
171
  */
287
- async get(code, externalId, options) {
172
+ async get(params, options) {
173
+ const { code, externalId } = params;
288
174
  return this.httpClient.get(
289
175
  `/features/${code}`,
290
176
  { externalId },
@@ -296,11 +182,15 @@ var FeaturesResource = class {
296
182
  *
297
183
  * @example
298
184
  * ```typescript
299
- * const { allowed } = await commet.features.check("custom_branding", "user_123");
185
+ * const { allowed } = await commet.features.check({
186
+ * code: "custom_branding",
187
+ * externalId: "user_123"
188
+ * });
300
189
  * if (!allowed) redirect("/upgrade");
301
190
  * ```
302
191
  */
303
- async check(code, externalId, options) {
192
+ async check(params, options) {
193
+ const { code, externalId } = params;
304
194
  const result = await this.httpClient.get(
305
195
  `/features/${code}`,
306
196
  { externalId },
@@ -327,7 +217,10 @@ var FeaturesResource = class {
327
217
  *
328
218
  * @example
329
219
  * ```typescript
330
- * const { allowed, willBeCharged } = await commet.features.canUse("team_members", "user_123");
220
+ * const { allowed, willBeCharged } = await commet.features.canUse({
221
+ * code: "team_members",
222
+ * externalId: "user_123"
223
+ * });
331
224
  *
332
225
  * if (!allowed) {
333
226
  * return { error: "Upgrade to add more members" };
@@ -338,7 +231,8 @@ var FeaturesResource = class {
338
231
  * }
339
232
  * ```
340
233
  */
341
- async canUse(code, externalId, options) {
234
+ async canUse(params, options) {
235
+ const { code, externalId } = params;
342
236
  return this.httpClient.get(
343
237
  `/features/${code}`,
344
238
  { externalId, action: "canUse" },
@@ -350,7 +244,7 @@ var FeaturesResource = class {
350
244
  *
351
245
  * @example
352
246
  * ```typescript
353
- * const features = await commet.features.list("user_123");
247
+ * const features = await commet.features.list({ externalId: "user_123" });
354
248
  * for (const feature of features) {
355
249
  * console.log(feature.code, feature.allowed);
356
250
  * }
@@ -490,10 +384,11 @@ var SeatsResource = class {
490
384
  * ```
491
385
  */
492
386
  async getBalance(params) {
387
+ const { customerId, externalId, seatType } = params;
493
388
  return this.httpClient.get("/seats/balance", {
494
- customerId: params.customerId,
495
- externalId: params.externalId,
496
- seatType: params.seatType
389
+ customerId,
390
+ externalId,
391
+ seatType
497
392
  });
498
393
  }
499
394
  /**
@@ -507,9 +402,10 @@ var SeatsResource = class {
507
402
  * ```
508
403
  */
509
404
  async getAllBalances(params) {
405
+ const { customerId, externalId } = params;
510
406
  return this.httpClient.get("/seats/balances", {
511
- customerId: params.customerId,
512
- externalId: params.externalId
407
+ customerId,
408
+ externalId
513
409
  });
514
410
  }
515
411
  };
@@ -540,25 +436,26 @@ var SubscriptionsResource = class {
540
436
  *
541
437
  * @example
542
438
  * ```typescript
543
- * const sub = await commet.subscriptions.get({ externalId: 'user_123' });
439
+ * const sub = await commet.subscriptions.get('user_123');
544
440
  * ```
545
441
  */
546
- async get(params) {
547
- return this.httpClient.get("/subscriptions/active", params);
442
+ async get(externalId) {
443
+ return this.httpClient.get("/subscriptions/active", { externalId });
548
444
  }
549
445
  /**
550
446
  * Change the plan of a subscription (upgrade/downgrade)
551
447
  *
552
448
  * @example
553
449
  * ```typescript
554
- * await commet.subscriptions.changePlan('sub_xxx', {
450
+ * await commet.subscriptions.changePlan({
451
+ * subscriptionId: 'sub_xxx',
555
452
  * planCode: 'enterprise' // autocomplete works after `commet pull`
556
453
  * });
557
454
  * ```
558
455
  */
559
- async changePlan(subscriptionId, params, options) {
456
+ async changePlan(params, options) {
560
457
  return this.httpClient.post(
561
- `/subscriptions/${subscriptionId}/change-plan`,
458
+ `/subscriptions/${params.subscriptionId}/change-plan`,
562
459
  params,
563
460
  options
564
461
  );
@@ -568,14 +465,15 @@ var SubscriptionsResource = class {
568
465
  *
569
466
  * @example
570
467
  * ```typescript
571
- * await commet.subscriptions.cancel('sub_xxx', {
468
+ * await commet.subscriptions.cancel({
469
+ * subscriptionId: 'sub_xxx',
572
470
  * reason: 'switched_to_competitor'
573
471
  * });
574
472
  * ```
575
473
  */
576
- async cancel(subscriptionId, params, options) {
474
+ async cancel(params, options) {
577
475
  return this.httpClient.post(
578
- `/subscriptions/${subscriptionId}/cancel`,
476
+ `/subscriptions/${params.subscriptionId}/cancel`,
579
477
  params || {},
580
478
  options
581
479
  );
@@ -679,12 +577,13 @@ var Webhooks = class {
679
577
  * }
680
578
  * ```
681
579
  */
682
- verify(payload, signature, secret) {
580
+ verify(params) {
581
+ const { payload, signature, secret } = params;
683
582
  if (!signature || !secret || !payload) {
684
583
  return false;
685
584
  }
686
585
  try {
687
- const expectedSignature = this.generateSignature(payload, secret);
586
+ const expectedSignature = this.generateSignature({ payload, secret });
688
587
  return crypto.timingSafeEqual(
689
588
  Buffer.from(signature, "hex"),
690
589
  Buffer.from(expectedSignature, "hex")
@@ -697,24 +596,20 @@ var Webhooks = class {
697
596
  * Generate HMAC-SHA256 signature (internal use)
698
597
  * @internal
699
598
  */
700
- generateSignature(payload, secret) {
599
+ generateSignature(params) {
600
+ const { payload, secret } = params;
701
601
  return crypto.createHmac("sha256", secret).update(payload).digest("hex");
702
602
  }
703
603
  /**
704
604
  * Parse and verify webhook payload in one step
705
605
  *
706
- * @param rawBody - Raw request body as string
707
- * @param signature - Value from X-Commet-Signature header
708
- * @param secret - Your webhook secret from Commet dashboard
709
- * @returns Parsed payload if valid, null if invalid
710
- *
711
606
  * @example
712
607
  * ```typescript
713
- * const payload = commet.webhooks.verifyAndParse(
608
+ * const payload = commet.webhooks.verifyAndParse({
714
609
  * rawBody,
715
610
  * signature,
716
- * process.env.COMMET_WEBHOOK_SECRET
717
- * );
611
+ * secret: process.env.COMMET_WEBHOOK_SECRET
612
+ * });
718
613
  *
719
614
  * if (!payload) {
720
615
  * return new Response('Invalid signature', { status: 401 });
@@ -726,12 +621,13 @@ var Webhooks = class {
726
621
  * }
727
622
  * ```
728
623
  */
729
- verifyAndParse(rawBody, signature, secret) {
730
- if (!this.verify(rawBody, signature, secret)) {
624
+ verifyAndParse(params) {
625
+ const { rawBody, signature, secret } = params;
626
+ if (!this.verify({ payload: rawBody, signature, secret })) {
731
627
  return null;
732
628
  }
733
629
  try {
734
- return JSON.parse(rawBody);
630
+ return JSON.parse(params.rawBody);
735
631
  } catch {
736
632
  return null;
737
633
  }
@@ -1015,7 +911,13 @@ var Commet = class {
1015
911
  * ```
1016
912
  */
1017
913
  customer(externalId) {
1018
- return new CustomerContext(this.httpClient, externalId);
914
+ return new CustomerContext(externalId, {
915
+ features: this.features,
916
+ seats: this.seats,
917
+ usage: this.usage,
918
+ subscriptions: this.subscriptions,
919
+ portal: this.portal
920
+ });
1019
921
  }
1020
922
  getEnvironment() {
1021
923
  return this.environment;