@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.mjs
CHANGED
|
@@ -1,181 +1,66 @@
|
|
|
1
1
|
// src/customer.ts
|
|
2
2
|
var CustomerContext = class {
|
|
3
|
-
constructor(
|
|
3
|
+
constructor(externalId, resources) {
|
|
4
4
|
/**
|
|
5
|
-
* Feature access methods -
|
|
5
|
+
* Feature access methods - delegates to FeaturesResource
|
|
6
6
|
*/
|
|
7
7
|
this.features = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
495
|
-
externalId
|
|
496
|
-
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
|
|
512
|
-
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(
|
|
439
|
+
* const sub = await commet.subscriptions.get('user_123');
|
|
544
440
|
* ```
|
|
545
441
|
*/
|
|
546
|
-
async get(
|
|
547
|
-
return this.httpClient.get("/subscriptions/active",
|
|
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(
|
|
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(
|
|
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(
|
|
468
|
+
* await commet.subscriptions.cancel({
|
|
469
|
+
* subscriptionId: 'sub_xxx',
|
|
572
470
|
* reason: 'switched_to_competitor'
|
|
573
471
|
* });
|
|
574
472
|
* ```
|
|
575
473
|
*/
|
|
576
|
-
async cancel(
|
|
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(
|
|
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(
|
|
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(
|
|
730
|
-
|
|
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(
|
|
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;
|