@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/README.md +4 -4
- package/dist/index.d.mts +169 -177
- package/dist/index.d.ts +169 -177
- package/dist/index.js +95 -193
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +95 -193
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -44,182 +44,67 @@ module.exports = __toCommonJS(index_exports);
|
|
|
44
44
|
|
|
45
45
|
// src/customer.ts
|
|
46
46
|
var CustomerContext = class {
|
|
47
|
-
constructor(
|
|
47
|
+
constructor(externalId, resources) {
|
|
48
48
|
/**
|
|
49
|
-
* Feature access methods -
|
|
49
|
+
* Feature access methods - delegates to FeaturesResource
|
|
50
50
|
*/
|
|
51
51
|
this.features = {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Check if a boolean feature is enabled
|
|
64
|
-
*/
|
|
65
|
-
check: async (code, options) => {
|
|
66
|
-
const result = await this.httpClient.get(
|
|
67
|
-
`/features/${code}`,
|
|
68
|
-
{ externalId: this.externalId },
|
|
69
|
-
options
|
|
70
|
-
);
|
|
71
|
-
if (!result.success || !result.data) {
|
|
72
|
-
return {
|
|
73
|
-
success: false,
|
|
74
|
-
data: { allowed: false },
|
|
75
|
-
message: result.message
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
return {
|
|
79
|
-
success: true,
|
|
80
|
-
data: { allowed: result.data.allowed },
|
|
81
|
-
message: result.message
|
|
82
|
-
};
|
|
83
|
-
},
|
|
84
|
-
/**
|
|
85
|
-
* Check if customer can use one more unit
|
|
86
|
-
*/
|
|
87
|
-
canUse: (code, options) => {
|
|
88
|
-
return this.httpClient.get(
|
|
89
|
-
`/features/${code}`,
|
|
90
|
-
{ externalId: this.externalId, action: "canUse" },
|
|
91
|
-
options
|
|
92
|
-
);
|
|
93
|
-
},
|
|
94
|
-
/**
|
|
95
|
-
* List all features
|
|
96
|
-
*/
|
|
97
|
-
list: (options) => {
|
|
98
|
-
return this.httpClient.get(
|
|
99
|
-
"/features",
|
|
100
|
-
{ externalId: this.externalId },
|
|
101
|
-
options
|
|
102
|
-
);
|
|
103
|
-
}
|
|
52
|
+
get: (code, options) => this.featuresResource.get({ code, externalId: this.externalId }, options),
|
|
53
|
+
check: (code, options) => this.featuresResource.check(
|
|
54
|
+
{ code, externalId: this.externalId },
|
|
55
|
+
options
|
|
56
|
+
),
|
|
57
|
+
canUse: (code, options) => this.featuresResource.canUse(
|
|
58
|
+
{ code, externalId: this.externalId },
|
|
59
|
+
options
|
|
60
|
+
),
|
|
61
|
+
list: (options) => this.featuresResource.list(this.externalId, options)
|
|
104
62
|
};
|
|
105
63
|
/**
|
|
106
|
-
* Seat management methods
|
|
64
|
+
* Seat management methods - delegates to SeatsResource
|
|
107
65
|
*/
|
|
108
66
|
this.seats = {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
remove: (seatType, count = 1, options) => {
|
|
123
|
-
return this.httpClient.post(
|
|
124
|
-
"/seats/remove",
|
|
125
|
-
{ externalId: this.externalId, seatType, count },
|
|
126
|
-
options
|
|
127
|
-
);
|
|
128
|
-
},
|
|
129
|
-
/**
|
|
130
|
-
* Set total seat count
|
|
131
|
-
*/
|
|
132
|
-
set: (seatType, count, options) => {
|
|
133
|
-
return this.httpClient.post(
|
|
134
|
-
"/seats/set",
|
|
135
|
-
{ externalId: this.externalId, seatType, count },
|
|
136
|
-
options
|
|
137
|
-
);
|
|
138
|
-
},
|
|
139
|
-
/**
|
|
140
|
-
* Get current seat balance
|
|
141
|
-
*/
|
|
142
|
-
getBalance: (seatType, options) => {
|
|
143
|
-
return this.httpClient.get(
|
|
144
|
-
"/seats/balance",
|
|
145
|
-
{ externalId: this.externalId, seatType },
|
|
146
|
-
options
|
|
147
|
-
);
|
|
148
|
-
}
|
|
67
|
+
add: (seatType, count = 1, options) => this.seatsResource.add(
|
|
68
|
+
{ externalId: this.externalId, seatType, count },
|
|
69
|
+
options
|
|
70
|
+
),
|
|
71
|
+
remove: (seatType, count = 1, options) => this.seatsResource.remove(
|
|
72
|
+
{ externalId: this.externalId, seatType, count },
|
|
73
|
+
options
|
|
74
|
+
),
|
|
75
|
+
set: (seatType, count, options) => this.seatsResource.set(
|
|
76
|
+
{ externalId: this.externalId, seatType, count },
|
|
77
|
+
options
|
|
78
|
+
),
|
|
79
|
+
getBalance: (seatType) => this.seatsResource.getBalance({ externalId: this.externalId, seatType })
|
|
149
80
|
};
|
|
150
81
|
/**
|
|
151
|
-
* Usage tracking methods
|
|
82
|
+
* Usage tracking methods - delegates to UsageResource
|
|
152
83
|
*/
|
|
153
84
|
this.usage = {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
return this.httpClient.post(
|
|
159
|
-
"/usage",
|
|
160
|
-
{
|
|
161
|
-
externalId: this.externalId,
|
|
162
|
-
eventType,
|
|
163
|
-
properties
|
|
164
|
-
},
|
|
165
|
-
options
|
|
166
|
-
);
|
|
167
|
-
}
|
|
85
|
+
track: (eventType, properties, options) => this.usageResource.track(
|
|
86
|
+
{ externalId: this.externalId, eventType, properties },
|
|
87
|
+
options
|
|
88
|
+
)
|
|
168
89
|
};
|
|
169
90
|
/**
|
|
170
|
-
* Subscription methods
|
|
91
|
+
* Subscription methods - delegates to SubscriptionsResource
|
|
171
92
|
*/
|
|
172
93
|
this.subscription = {
|
|
173
|
-
|
|
174
|
-
* Get active subscription
|
|
175
|
-
*/
|
|
176
|
-
get: (options) => {
|
|
177
|
-
return this.httpClient.get(
|
|
178
|
-
"/subscriptions/active",
|
|
179
|
-
{ externalId: this.externalId },
|
|
180
|
-
options
|
|
181
|
-
);
|
|
182
|
-
},
|
|
183
|
-
/**
|
|
184
|
-
* Cancel subscription
|
|
185
|
-
*/
|
|
186
|
-
cancel: (params, options) => {
|
|
187
|
-
return this.httpClient.get(
|
|
188
|
-
"/subscriptions/active",
|
|
189
|
-
{ externalId: this.externalId }
|
|
190
|
-
).then((result) => {
|
|
191
|
-
if (!result.success || !result.data) {
|
|
192
|
-
return {
|
|
193
|
-
success: false,
|
|
194
|
-
data: null,
|
|
195
|
-
message: "No active subscription found"
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
return this.httpClient.post(
|
|
199
|
-
`/subscriptions/${result.data.id}/cancel`,
|
|
200
|
-
params || {},
|
|
201
|
-
options
|
|
202
|
-
);
|
|
203
|
-
});
|
|
204
|
-
}
|
|
94
|
+
get: () => this.subscriptionsResource.get(this.externalId)
|
|
205
95
|
};
|
|
206
96
|
/**
|
|
207
|
-
* Portal methods
|
|
97
|
+
* Portal methods - delegates to PortalResource
|
|
208
98
|
*/
|
|
209
99
|
this.portal = {
|
|
210
|
-
|
|
211
|
-
* Get customer portal URL
|
|
212
|
-
*/
|
|
213
|
-
getUrl: (options) => {
|
|
214
|
-
return this.httpClient.get(
|
|
215
|
-
"/portal/url",
|
|
216
|
-
{ externalId: this.externalId },
|
|
217
|
-
options
|
|
218
|
-
);
|
|
219
|
-
}
|
|
100
|
+
getUrl: (options) => this.portalResource.getUrl({ externalId: this.externalId }, options)
|
|
220
101
|
};
|
|
221
|
-
this.httpClient = httpClient;
|
|
222
102
|
this.externalId = externalId;
|
|
103
|
+
this.featuresResource = resources.features;
|
|
104
|
+
this.seatsResource = resources.seats;
|
|
105
|
+
this.usageResource = resources.usage;
|
|
106
|
+
this.subscriptionsResource = resources.subscriptions;
|
|
107
|
+
this.portalResource = resources.portal;
|
|
223
108
|
}
|
|
224
109
|
};
|
|
225
110
|
|
|
@@ -278,9 +163,9 @@ var CustomersResource = class {
|
|
|
278
163
|
/**
|
|
279
164
|
* Update a customer
|
|
280
165
|
*/
|
|
281
|
-
async update(
|
|
166
|
+
async update(params, options) {
|
|
282
167
|
return this.httpClient.put(
|
|
283
|
-
`/customers/${customerId}`,
|
|
168
|
+
`/customers/${params.customerId}`,
|
|
284
169
|
{
|
|
285
170
|
billingEmail: params.email,
|
|
286
171
|
externalId: params.externalId,
|
|
@@ -324,11 +209,12 @@ var FeaturesResource = class {
|
|
|
324
209
|
*
|
|
325
210
|
* @example
|
|
326
211
|
* ```typescript
|
|
327
|
-
* const seats = await commet.features.get("team_members", "user_123");
|
|
212
|
+
* const seats = await commet.features.get({ code: "team_members", externalId: "user_123" });
|
|
328
213
|
* console.log(seats.current, seats.included, seats.remaining);
|
|
329
214
|
* ```
|
|
330
215
|
*/
|
|
331
|
-
async get(
|
|
216
|
+
async get(params, options) {
|
|
217
|
+
const { code, externalId } = params;
|
|
332
218
|
return this.httpClient.get(
|
|
333
219
|
`/features/${code}`,
|
|
334
220
|
{ externalId },
|
|
@@ -340,11 +226,15 @@ var FeaturesResource = class {
|
|
|
340
226
|
*
|
|
341
227
|
* @example
|
|
342
228
|
* ```typescript
|
|
343
|
-
* const { allowed } = await commet.features.check(
|
|
229
|
+
* const { allowed } = await commet.features.check({
|
|
230
|
+
* code: "custom_branding",
|
|
231
|
+
* externalId: "user_123"
|
|
232
|
+
* });
|
|
344
233
|
* if (!allowed) redirect("/upgrade");
|
|
345
234
|
* ```
|
|
346
235
|
*/
|
|
347
|
-
async check(
|
|
236
|
+
async check(params, options) {
|
|
237
|
+
const { code, externalId } = params;
|
|
348
238
|
const result = await this.httpClient.get(
|
|
349
239
|
`/features/${code}`,
|
|
350
240
|
{ externalId },
|
|
@@ -371,7 +261,10 @@ var FeaturesResource = class {
|
|
|
371
261
|
*
|
|
372
262
|
* @example
|
|
373
263
|
* ```typescript
|
|
374
|
-
* const { allowed, willBeCharged } = await commet.features.canUse(
|
|
264
|
+
* const { allowed, willBeCharged } = await commet.features.canUse({
|
|
265
|
+
* code: "team_members",
|
|
266
|
+
* externalId: "user_123"
|
|
267
|
+
* });
|
|
375
268
|
*
|
|
376
269
|
* if (!allowed) {
|
|
377
270
|
* return { error: "Upgrade to add more members" };
|
|
@@ -382,7 +275,8 @@ var FeaturesResource = class {
|
|
|
382
275
|
* }
|
|
383
276
|
* ```
|
|
384
277
|
*/
|
|
385
|
-
async canUse(
|
|
278
|
+
async canUse(params, options) {
|
|
279
|
+
const { code, externalId } = params;
|
|
386
280
|
return this.httpClient.get(
|
|
387
281
|
`/features/${code}`,
|
|
388
282
|
{ externalId, action: "canUse" },
|
|
@@ -394,7 +288,7 @@ var FeaturesResource = class {
|
|
|
394
288
|
*
|
|
395
289
|
* @example
|
|
396
290
|
* ```typescript
|
|
397
|
-
* const features = await commet.features.list("user_123");
|
|
291
|
+
* const features = await commet.features.list({ externalId: "user_123" });
|
|
398
292
|
* for (const feature of features) {
|
|
399
293
|
* console.log(feature.code, feature.allowed);
|
|
400
294
|
* }
|
|
@@ -534,10 +428,11 @@ var SeatsResource = class {
|
|
|
534
428
|
* ```
|
|
535
429
|
*/
|
|
536
430
|
async getBalance(params) {
|
|
431
|
+
const { customerId, externalId, seatType } = params;
|
|
537
432
|
return this.httpClient.get("/seats/balance", {
|
|
538
|
-
customerId
|
|
539
|
-
externalId
|
|
540
|
-
seatType
|
|
433
|
+
customerId,
|
|
434
|
+
externalId,
|
|
435
|
+
seatType
|
|
541
436
|
});
|
|
542
437
|
}
|
|
543
438
|
/**
|
|
@@ -551,9 +446,10 @@ var SeatsResource = class {
|
|
|
551
446
|
* ```
|
|
552
447
|
*/
|
|
553
448
|
async getAllBalances(params) {
|
|
449
|
+
const { customerId, externalId } = params;
|
|
554
450
|
return this.httpClient.get("/seats/balances", {
|
|
555
|
-
customerId
|
|
556
|
-
externalId
|
|
451
|
+
customerId,
|
|
452
|
+
externalId
|
|
557
453
|
});
|
|
558
454
|
}
|
|
559
455
|
};
|
|
@@ -584,25 +480,26 @@ var SubscriptionsResource = class {
|
|
|
584
480
|
*
|
|
585
481
|
* @example
|
|
586
482
|
* ```typescript
|
|
587
|
-
* const sub = await commet.subscriptions.get(
|
|
483
|
+
* const sub = await commet.subscriptions.get('user_123');
|
|
588
484
|
* ```
|
|
589
485
|
*/
|
|
590
|
-
async get(
|
|
591
|
-
return this.httpClient.get("/subscriptions/active",
|
|
486
|
+
async get(externalId) {
|
|
487
|
+
return this.httpClient.get("/subscriptions/active", { externalId });
|
|
592
488
|
}
|
|
593
489
|
/**
|
|
594
490
|
* Change the plan of a subscription (upgrade/downgrade)
|
|
595
491
|
*
|
|
596
492
|
* @example
|
|
597
493
|
* ```typescript
|
|
598
|
-
* await commet.subscriptions.changePlan(
|
|
494
|
+
* await commet.subscriptions.changePlan({
|
|
495
|
+
* subscriptionId: 'sub_xxx',
|
|
599
496
|
* planCode: 'enterprise' // autocomplete works after `commet pull`
|
|
600
497
|
* });
|
|
601
498
|
* ```
|
|
602
499
|
*/
|
|
603
|
-
async changePlan(
|
|
500
|
+
async changePlan(params, options) {
|
|
604
501
|
return this.httpClient.post(
|
|
605
|
-
`/subscriptions/${subscriptionId}/change-plan`,
|
|
502
|
+
`/subscriptions/${params.subscriptionId}/change-plan`,
|
|
606
503
|
params,
|
|
607
504
|
options
|
|
608
505
|
);
|
|
@@ -612,14 +509,15 @@ var SubscriptionsResource = class {
|
|
|
612
509
|
*
|
|
613
510
|
* @example
|
|
614
511
|
* ```typescript
|
|
615
|
-
* await commet.subscriptions.cancel(
|
|
512
|
+
* await commet.subscriptions.cancel({
|
|
513
|
+
* subscriptionId: 'sub_xxx',
|
|
616
514
|
* reason: 'switched_to_competitor'
|
|
617
515
|
* });
|
|
618
516
|
* ```
|
|
619
517
|
*/
|
|
620
|
-
async cancel(
|
|
518
|
+
async cancel(params, options) {
|
|
621
519
|
return this.httpClient.post(
|
|
622
|
-
`/subscriptions/${subscriptionId}/cancel`,
|
|
520
|
+
`/subscriptions/${params.subscriptionId}/cancel`,
|
|
623
521
|
params || {},
|
|
624
522
|
options
|
|
625
523
|
);
|
|
@@ -723,12 +621,13 @@ var Webhooks = class {
|
|
|
723
621
|
* }
|
|
724
622
|
* ```
|
|
725
623
|
*/
|
|
726
|
-
verify(
|
|
624
|
+
verify(params) {
|
|
625
|
+
const { payload, signature, secret } = params;
|
|
727
626
|
if (!signature || !secret || !payload) {
|
|
728
627
|
return false;
|
|
729
628
|
}
|
|
730
629
|
try {
|
|
731
|
-
const expectedSignature = this.generateSignature(payload, secret);
|
|
630
|
+
const expectedSignature = this.generateSignature({ payload, secret });
|
|
732
631
|
return import_node_crypto.default.timingSafeEqual(
|
|
733
632
|
Buffer.from(signature, "hex"),
|
|
734
633
|
Buffer.from(expectedSignature, "hex")
|
|
@@ -741,24 +640,20 @@ var Webhooks = class {
|
|
|
741
640
|
* Generate HMAC-SHA256 signature (internal use)
|
|
742
641
|
* @internal
|
|
743
642
|
*/
|
|
744
|
-
generateSignature(
|
|
643
|
+
generateSignature(params) {
|
|
644
|
+
const { payload, secret } = params;
|
|
745
645
|
return import_node_crypto.default.createHmac("sha256", secret).update(payload).digest("hex");
|
|
746
646
|
}
|
|
747
647
|
/**
|
|
748
648
|
* Parse and verify webhook payload in one step
|
|
749
649
|
*
|
|
750
|
-
* @param rawBody - Raw request body as string
|
|
751
|
-
* @param signature - Value from X-Commet-Signature header
|
|
752
|
-
* @param secret - Your webhook secret from Commet dashboard
|
|
753
|
-
* @returns Parsed payload if valid, null if invalid
|
|
754
|
-
*
|
|
755
650
|
* @example
|
|
756
651
|
* ```typescript
|
|
757
|
-
* const payload = commet.webhooks.verifyAndParse(
|
|
652
|
+
* const payload = commet.webhooks.verifyAndParse({
|
|
758
653
|
* rawBody,
|
|
759
654
|
* signature,
|
|
760
|
-
* process.env.COMMET_WEBHOOK_SECRET
|
|
761
|
-
* );
|
|
655
|
+
* secret: process.env.COMMET_WEBHOOK_SECRET
|
|
656
|
+
* });
|
|
762
657
|
*
|
|
763
658
|
* if (!payload) {
|
|
764
659
|
* return new Response('Invalid signature', { status: 401 });
|
|
@@ -770,12 +665,13 @@ var Webhooks = class {
|
|
|
770
665
|
* }
|
|
771
666
|
* ```
|
|
772
667
|
*/
|
|
773
|
-
verifyAndParse(
|
|
774
|
-
|
|
668
|
+
verifyAndParse(params) {
|
|
669
|
+
const { rawBody, signature, secret } = params;
|
|
670
|
+
if (!this.verify({ payload: rawBody, signature, secret })) {
|
|
775
671
|
return null;
|
|
776
672
|
}
|
|
777
673
|
try {
|
|
778
|
-
return JSON.parse(rawBody);
|
|
674
|
+
return JSON.parse(params.rawBody);
|
|
779
675
|
} catch {
|
|
780
676
|
return null;
|
|
781
677
|
}
|
|
@@ -1059,7 +955,13 @@ var Commet = class {
|
|
|
1059
955
|
* ```
|
|
1060
956
|
*/
|
|
1061
957
|
customer(externalId) {
|
|
1062
|
-
return new CustomerContext(
|
|
958
|
+
return new CustomerContext(externalId, {
|
|
959
|
+
features: this.features,
|
|
960
|
+
seats: this.seats,
|
|
961
|
+
usage: this.usage,
|
|
962
|
+
subscriptions: this.subscriptions,
|
|
963
|
+
portal: this.portal
|
|
964
|
+
});
|
|
1063
965
|
}
|
|
1064
966
|
getEnvironment() {
|
|
1065
967
|
return this.environment;
|