@polar-sh/sdk 0.16.2 → 0.17.1
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 +26 -0
- package/docs/sdks/polar/README.md +3 -1
- package/docs/sdks/users/README.md +5 -1
- package/funcs/advertisementsList.d.ts +3 -1
- package/funcs/advertisementsList.d.ts.map +1 -1
- package/funcs/advertisementsList.js +7 -6
- package/funcs/advertisementsList.js.map +1 -1
- package/funcs/articlesList.d.ts +3 -1
- package/funcs/articlesList.d.ts.map +1 -1
- package/funcs/articlesList.js +7 -6
- package/funcs/articlesList.js.map +1 -1
- package/funcs/benefitsGrants.d.ts +3 -1
- package/funcs/benefitsGrants.d.ts.map +1 -1
- package/funcs/benefitsGrants.js +7 -6
- package/funcs/benefitsGrants.js.map +1 -1
- package/funcs/benefitsList.d.ts +3 -1
- package/funcs/benefitsList.d.ts.map +1 -1
- package/funcs/benefitsList.js +7 -6
- package/funcs/benefitsList.js.map +1 -1
- package/funcs/checkoutLinksList.d.ts +3 -1
- package/funcs/checkoutLinksList.d.ts.map +1 -1
- package/funcs/checkoutLinksList.js +7 -6
- package/funcs/checkoutLinksList.js.map +1 -1
- package/funcs/checkoutsCustomList.d.ts +3 -1
- package/funcs/checkoutsCustomList.d.ts.map +1 -1
- package/funcs/checkoutsCustomList.js +7 -6
- package/funcs/checkoutsCustomList.js.map +1 -1
- package/funcs/customFieldsList.d.ts +3 -1
- package/funcs/customFieldsList.d.ts.map +1 -1
- package/funcs/customFieldsList.js +7 -6
- package/funcs/customFieldsList.js.map +1 -1
- package/funcs/discountsList.d.ts +3 -1
- package/funcs/discountsList.d.ts.map +1 -1
- package/funcs/discountsList.js +7 -6
- package/funcs/discountsList.js.map +1 -1
- package/funcs/externalOrganizationsList.d.ts +3 -1
- package/funcs/externalOrganizationsList.d.ts.map +1 -1
- package/funcs/externalOrganizationsList.js +7 -6
- package/funcs/externalOrganizationsList.js.map +1 -1
- package/funcs/filesList.d.ts +3 -1
- package/funcs/filesList.d.ts.map +1 -1
- package/funcs/filesList.js +7 -6
- package/funcs/filesList.js.map +1 -1
- package/funcs/licenseKeysList.d.ts +3 -1
- package/funcs/licenseKeysList.d.ts.map +1 -1
- package/funcs/licenseKeysList.js +7 -6
- package/funcs/licenseKeysList.js.map +1 -1
- package/funcs/oauth2ClientsList.d.ts +3 -1
- package/funcs/oauth2ClientsList.d.ts.map +1 -1
- package/funcs/oauth2ClientsList.js +7 -6
- package/funcs/oauth2ClientsList.js.map +1 -1
- package/funcs/ordersList.d.ts +3 -1
- package/funcs/ordersList.d.ts.map +1 -1
- package/funcs/ordersList.js +7 -6
- package/funcs/ordersList.js.map +1 -1
- package/funcs/organizationsList.d.ts +3 -1
- package/funcs/organizationsList.d.ts.map +1 -1
- package/funcs/organizationsList.js +7 -6
- package/funcs/organizationsList.js.map +1 -1
- package/funcs/productsList.d.ts +3 -1
- package/funcs/productsList.d.ts.map +1 -1
- package/funcs/productsList.js +7 -6
- package/funcs/productsList.js.map +1 -1
- package/funcs/repositoriesList.d.ts +3 -1
- package/funcs/repositoriesList.d.ts.map +1 -1
- package/funcs/repositoriesList.js +7 -6
- package/funcs/repositoriesList.js.map +1 -1
- package/funcs/subscriptionsList.d.ts +3 -1
- package/funcs/subscriptionsList.d.ts.map +1 -1
- package/funcs/subscriptionsList.js +7 -6
- package/funcs/subscriptionsList.js.map +1 -1
- package/funcs/usersAdvertisementsList.d.ts +3 -1
- package/funcs/usersAdvertisementsList.d.ts.map +1 -1
- package/funcs/usersAdvertisementsList.js +7 -6
- package/funcs/usersAdvertisementsList.js.map +1 -1
- package/funcs/usersBenefitsList.d.ts +3 -1
- package/funcs/usersBenefitsList.d.ts.map +1 -1
- package/funcs/usersBenefitsList.js +7 -6
- package/funcs/usersBenefitsList.js.map +1 -1
- package/funcs/usersDownloadablesList.d.ts +3 -1
- package/funcs/usersDownloadablesList.d.ts.map +1 -1
- package/funcs/usersDownloadablesList.js +7 -6
- package/funcs/usersDownloadablesList.js.map +1 -1
- package/funcs/usersLicenseKeysList.d.ts +3 -1
- package/funcs/usersLicenseKeysList.d.ts.map +1 -1
- package/funcs/usersLicenseKeysList.js +7 -6
- package/funcs/usersLicenseKeysList.js.map +1 -1
- package/funcs/usersOrdersList.d.ts +3 -1
- package/funcs/usersOrdersList.d.ts.map +1 -1
- package/funcs/usersOrdersList.js +7 -6
- package/funcs/usersOrdersList.js.map +1 -1
- package/funcs/usersSubscriptionsList.d.ts +3 -1
- package/funcs/usersSubscriptionsList.d.ts.map +1 -1
- package/funcs/usersSubscriptionsList.js +7 -6
- package/funcs/usersSubscriptionsList.js.map +1 -1
- package/jest.config.js +5 -0
- package/lib/config.d.ts +3 -3
- package/lib/config.js +3 -3
- package/lib/primitives.d.ts +2 -0
- package/lib/primitives.d.ts.map +1 -1
- package/lib/primitives.js +53 -0
- package/lib/primitives.js.map +1 -1
- package/models/components/order.d.ts +3 -0
- package/models/components/order.d.ts.map +1 -1
- package/models/components/order.js +5 -0
- package/models/components/order.js.map +1 -1
- package/package.json +8 -2
- package/sdk/advertisements.d.ts +3 -1
- package/sdk/advertisements.d.ts.map +1 -1
- package/sdk/advertisements.js.map +1 -1
- package/sdk/articles.d.ts +3 -1
- package/sdk/articles.d.ts.map +1 -1
- package/sdk/benefits.d.ts +6 -2
- package/sdk/benefits.d.ts.map +1 -1
- package/sdk/benefits.js.map +1 -1
- package/sdk/checkoutlinks.d.ts +3 -1
- package/sdk/checkoutlinks.d.ts.map +1 -1
- package/sdk/checkoutlinks.js.map +1 -1
- package/sdk/clients.d.ts +3 -1
- package/sdk/clients.d.ts.map +1 -1
- package/sdk/clients.js.map +1 -1
- package/sdk/custom.d.ts +3 -1
- package/sdk/custom.d.ts.map +1 -1
- package/sdk/custom.js.map +1 -1
- package/sdk/customfields.d.ts +3 -1
- package/sdk/customfields.d.ts.map +1 -1
- package/sdk/customfields.js.map +1 -1
- package/sdk/discounts.d.ts +3 -1
- package/sdk/discounts.d.ts.map +1 -1
- package/sdk/downloadables.d.ts +3 -1
- package/sdk/downloadables.d.ts.map +1 -1
- package/sdk/downloadables.js.map +1 -1
- package/sdk/externalorganizations.d.ts +3 -1
- package/sdk/externalorganizations.d.ts.map +1 -1
- package/sdk/externalorganizations.js.map +1 -1
- package/sdk/files.d.ts +3 -1
- package/sdk/files.d.ts.map +1 -1
- package/sdk/licensekeys.d.ts +3 -1
- package/sdk/licensekeys.d.ts.map +1 -1
- package/sdk/licensekeys.js.map +1 -1
- package/sdk/orders.d.ts +3 -1
- package/sdk/orders.d.ts.map +1 -1
- package/sdk/organizations.d.ts +3 -1
- package/sdk/organizations.d.ts.map +1 -1
- package/sdk/organizations.js.map +1 -1
- package/sdk/polaradvertisements.d.ts +3 -1
- package/sdk/polaradvertisements.d.ts.map +1 -1
- package/sdk/polaradvertisements.js.map +1 -1
- package/sdk/polarbenefits.d.ts +3 -1
- package/sdk/polarbenefits.d.ts.map +1 -1
- package/sdk/polarbenefits.js.map +1 -1
- package/sdk/polarlicensekeys.d.ts +3 -1
- package/sdk/polarlicensekeys.d.ts.map +1 -1
- package/sdk/polarlicensekeys.js.map +1 -1
- package/sdk/polarorders.d.ts +3 -1
- package/sdk/polarorders.d.ts.map +1 -1
- package/sdk/polarorders.js.map +1 -1
- package/sdk/polarsubscriptions.d.ts +3 -1
- package/sdk/polarsubscriptions.d.ts.map +1 -1
- package/sdk/polarsubscriptions.js.map +1 -1
- package/sdk/products.d.ts +3 -1
- package/sdk/products.d.ts.map +1 -1
- package/sdk/repositories.d.ts +3 -1
- package/sdk/repositories.d.ts.map +1 -1
- package/sdk/repositories.js.map +1 -1
- package/sdk/subscriptions.d.ts +3 -1
- package/sdk/subscriptions.d.ts.map +1 -1
- package/sdk/subscriptions.js.map +1 -1
- package/src/funcs/advertisementsList.ts +26 -20
- package/src/funcs/articlesList.ts +26 -20
- package/src/funcs/benefitsGrants.ts +27 -21
- package/src/funcs/benefitsList.ts +26 -20
- package/src/funcs/checkoutLinksList.ts +26 -20
- package/src/funcs/checkoutsCustomList.ts +26 -20
- package/src/funcs/customFieldsList.ts +26 -20
- package/src/funcs/discountsList.ts +26 -20
- package/src/funcs/externalOrganizationsList.ts +26 -20
- package/src/funcs/filesList.ts +26 -20
- package/src/funcs/licenseKeysList.ts +28 -22
- package/src/funcs/oauth2ClientsList.ts +26 -20
- package/src/funcs/ordersList.ts +26 -20
- package/src/funcs/organizationsList.ts +26 -20
- package/src/funcs/productsList.ts +26 -20
- package/src/funcs/repositoriesList.ts +26 -20
- package/src/funcs/subscriptionsList.ts +26 -20
- package/src/funcs/usersAdvertisementsList.ts +26 -20
- package/src/funcs/usersBenefitsList.ts +26 -20
- package/src/funcs/usersDownloadablesList.ts +26 -20
- package/src/funcs/usersLicenseKeysList.ts +28 -22
- package/src/funcs/usersOrdersList.ts +26 -20
- package/src/funcs/usersSubscriptionsList.ts +26 -20
- package/src/lib/config.ts +3 -3
- package/src/lib/primitives.ts +62 -0
- package/src/models/components/order.ts +12 -0
- package/src/sdk/advertisements.ts +3 -1
- package/src/sdk/articles.ts +1 -1
- package/src/sdk/benefits.ts +4 -2
- package/src/sdk/checkoutlinks.ts +3 -1
- package/src/sdk/clients.ts +3 -1
- package/src/sdk/custom.ts +3 -1
- package/src/sdk/customfields.ts +3 -1
- package/src/sdk/discounts.ts +1 -1
- package/src/sdk/downloadables.ts +3 -1
- package/src/sdk/externalorganizations.ts +3 -1
- package/src/sdk/files.ts +1 -1
- package/src/sdk/licensekeys.ts +3 -1
- package/src/sdk/orders.ts +1 -1
- package/src/sdk/organizations.ts +3 -1
- package/src/sdk/polaradvertisements.ts +3 -1
- package/src/sdk/polarbenefits.ts +3 -1
- package/src/sdk/polarlicensekeys.ts +3 -1
- package/src/sdk/polarorders.ts +3 -1
- package/src/sdk/polarsubscriptions.ts +3 -1
- package/src/sdk/products.ts +1 -1
- package/src/sdk/repositories.ts +3 -1
- package/src/sdk/subscriptions.ts +3 -1
- package/src/types/operations.ts +11 -5
- package/src/webhooks/index.test.ts +115 -0
- package/src/webhooks/index.ts +96 -0
- package/types/operations.d.ts +5 -3
- package/types/operations.d.ts.map +1 -1
- package/types/operations.js +3 -0
- package/types/operations.js.map +1 -1
- package/webhooks/index.d.ts +6 -0
- package/webhooks/index.d.ts.map +1 -0
- package/webhooks/index.js +76 -0
- package/webhooks/index.js.map +1 -0
- package/webhooks/index.test.d.ts +2 -0
- package/webhooks/index.test.d.ts.map +1 -0
- package/webhooks/index.test.js +107 -0
- package/webhooks/index.test.js.map +1 -0
package/src/types/operations.ts
CHANGED
|
@@ -6,9 +6,10 @@ import { Result } from "./fp.js";
|
|
|
6
6
|
|
|
7
7
|
export type Paginator<V> = () => Promise<V & { next: Paginator<V> }> | null;
|
|
8
8
|
|
|
9
|
-
export type PageIterator<V> = V & {
|
|
9
|
+
export type PageIterator<V, PageState = unknown> = V & {
|
|
10
10
|
next: Paginator<V>;
|
|
11
11
|
[Symbol.asyncIterator]: () => AsyncIterableIterator<V>;
|
|
12
|
+
"~next"?: PageState | undefined;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
export function createPageIterator<V>(
|
|
@@ -40,7 +41,9 @@ export function createPageIterator<V>(
|
|
|
40
41
|
* terminates. It is useful in paginated SDK functions that have early return
|
|
41
42
|
* paths when things go wrong.
|
|
42
43
|
*/
|
|
43
|
-
export function haltIterator<V extends object>(
|
|
44
|
+
export function haltIterator<V extends object>(
|
|
45
|
+
v: V,
|
|
46
|
+
): PageIterator<V, undefined> {
|
|
44
47
|
return {
|
|
45
48
|
...v,
|
|
46
49
|
next: () => null,
|
|
@@ -54,9 +57,9 @@ export function haltIterator<V extends object>(v: V): PageIterator<V> {
|
|
|
54
57
|
* Converts an async iterator of `Result<V, E>` into an async iterator of `V`.
|
|
55
58
|
* When error results occur, the underlying error value is thrown.
|
|
56
59
|
*/
|
|
57
|
-
export async function unwrapResultIterator<V>(
|
|
58
|
-
iteratorPromise: Promise<PageIterator<Result<V, unknown
|
|
59
|
-
): Promise<PageIterator<V>> {
|
|
60
|
+
export async function unwrapResultIterator<V, PageState>(
|
|
61
|
+
iteratorPromise: Promise<PageIterator<Result<V, unknown>, PageState>>,
|
|
62
|
+
): Promise<PageIterator<V, PageState>> {
|
|
60
63
|
const resultIter = await iteratorPromise;
|
|
61
64
|
|
|
62
65
|
if (!resultIter.ok) {
|
|
@@ -66,6 +69,7 @@ export async function unwrapResultIterator<V>(
|
|
|
66
69
|
return {
|
|
67
70
|
...resultIter.value,
|
|
68
71
|
next: unwrapPaginator(resultIter.next),
|
|
72
|
+
"~next": resultIter["~next"],
|
|
69
73
|
[Symbol.asyncIterator]: async function* paginator() {
|
|
70
74
|
for await (const page of resultIter) {
|
|
71
75
|
if (!page.ok) {
|
|
@@ -97,3 +101,5 @@ function unwrapPaginator<V>(
|
|
|
97
101
|
});
|
|
98
102
|
};
|
|
99
103
|
}
|
|
104
|
+
|
|
105
|
+
export const URL_OVERRIDE = Symbol("URL_OVERRIDE");
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { randomUUID } from "crypto";
|
|
2
|
+
import { Webhook } from "standardwebhooks"
|
|
3
|
+
import { validateEvent, WebhookVerificationError } from ".";
|
|
4
|
+
import { SDKValidationError } from "../models/errors";
|
|
5
|
+
import { WebhookCheckoutCreatedPayload$inboundSchema } from "../models/components";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
const ORGANIZATION_ID = randomUUID().toString();
|
|
9
|
+
const PRODUCT_ID = randomUUID().toString();
|
|
10
|
+
const PRICE_ID = randomUUID().toString();
|
|
11
|
+
|
|
12
|
+
const price = {
|
|
13
|
+
id: PRICE_ID,
|
|
14
|
+
created_at: new Date().toISOString(),
|
|
15
|
+
modified_at: null,
|
|
16
|
+
is_archived: false,
|
|
17
|
+
product_id: PRODUCT_ID,
|
|
18
|
+
price_currency: "usd",
|
|
19
|
+
price_amount: 1000,
|
|
20
|
+
type: "one_time",
|
|
21
|
+
amount_type: "fixed",
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const product = {
|
|
25
|
+
id: PRODUCT_ID,
|
|
26
|
+
created_at: new Date().toISOString(),
|
|
27
|
+
modified_at: null,
|
|
28
|
+
name: "Product",
|
|
29
|
+
description: null,
|
|
30
|
+
is_recurring: false,
|
|
31
|
+
is_archived: false,
|
|
32
|
+
organization_id: ORGANIZATION_ID,
|
|
33
|
+
prices: [price],
|
|
34
|
+
benefits: [],
|
|
35
|
+
medias: [],
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const checkoutCreated = {
|
|
39
|
+
type: "checkout.created",
|
|
40
|
+
data: {
|
|
41
|
+
id: randomUUID().toString(),
|
|
42
|
+
created_at: new Date().toISOString(),
|
|
43
|
+
modified_at: null,
|
|
44
|
+
status: "open",
|
|
45
|
+
client_secret: "CLIENT_SECRET",
|
|
46
|
+
url: "https://polar.sh/checkout/CLIENT_SECRET",
|
|
47
|
+
expires_at: new Date().toISOString(),
|
|
48
|
+
success_url: "https://polar.sh/checkout/CLIENT_SECRET/confirmation",
|
|
49
|
+
embed_origin: null,
|
|
50
|
+
tax_amount: 0,
|
|
51
|
+
amount: 1000,
|
|
52
|
+
currency: "usd",
|
|
53
|
+
subtotal_amount: 1000,
|
|
54
|
+
total_amount: 1000,
|
|
55
|
+
product_id: PRODUCT_ID,
|
|
56
|
+
product_price_id: PRICE_ID,
|
|
57
|
+
discount_id: null,
|
|
58
|
+
allow_discount_codes: true,
|
|
59
|
+
is_discount_applicable: true,
|
|
60
|
+
is_free_product_price: false,
|
|
61
|
+
is_payment_required: true,
|
|
62
|
+
is_payment_setup_required: false,
|
|
63
|
+
is_payment_form_required: true,
|
|
64
|
+
customer_id: null,
|
|
65
|
+
customer_name: null,
|
|
66
|
+
customer_email: null,
|
|
67
|
+
customer_ip_address: null,
|
|
68
|
+
customer_billing_address: null,
|
|
69
|
+
customer_tax_id: null,
|
|
70
|
+
payment_processor_metadata: {},
|
|
71
|
+
metadata: {},
|
|
72
|
+
product: product,
|
|
73
|
+
product_price: price,
|
|
74
|
+
discount: null,
|
|
75
|
+
subscription_id: null,
|
|
76
|
+
attached_custom_fields: [],
|
|
77
|
+
custom_field_data: {},
|
|
78
|
+
payment_processor: 'stripe',
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const WEBHOOK_SECRET = "TestSecret";
|
|
83
|
+
const WEBHOOK_SECRET_BASE64 = Buffer.from(WEBHOOK_SECRET, 'utf-8').toString('base64');
|
|
84
|
+
|
|
85
|
+
const getHeaders = (body: string, webhookId: string = "WEBHOOK_ID", timestamp?: Date) => {
|
|
86
|
+
const _timestamp = timestamp || new Date()
|
|
87
|
+
const signature = new Webhook(WEBHOOK_SECRET_BASE64).sign(webhookId, _timestamp, body);
|
|
88
|
+
return {
|
|
89
|
+
"webhook-id": webhookId,
|
|
90
|
+
"webhook-timestamp": Math.floor(_timestamp.getTime() / 1000).toString(),
|
|
91
|
+
"webhook-signature": signature,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
describe('validateEvent', () => {
|
|
96
|
+
it('should validate signature and parse payload', () => {
|
|
97
|
+
const body = JSON.stringify(checkoutCreated);
|
|
98
|
+
const headers = getHeaders(body);
|
|
99
|
+
const parsed = validateEvent(body, headers, WEBHOOK_SECRET);
|
|
100
|
+
expect(parsed).toEqual(WebhookCheckoutCreatedPayload$inboundSchema.parse(checkoutCreated));
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should throw error if signature is invalid', () => {
|
|
104
|
+
const body = JSON.stringify(checkoutCreated);
|
|
105
|
+
const headers = getHeaders(body);
|
|
106
|
+
expect(() => validateEvent(body, headers, "AnotherSecret")).toThrow(WebhookVerificationError);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should throw error if payload is invalid', () => {
|
|
110
|
+
const body = '{"type": "unknown"}';
|
|
111
|
+
const headers = getHeaders(body);
|
|
112
|
+
|
|
113
|
+
expect(() => validateEvent(body, headers, WEBHOOK_SECRET)).toThrow(SDKValidationError);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Webhook, WebhookVerificationError as _WebhookVerificationError } from "standardwebhooks"
|
|
2
|
+
import {
|
|
3
|
+
WebhookBenefitCreatedPayload$inboundSchema,
|
|
4
|
+
WebhookBenefitGrantCreatedPayload$inboundSchema,
|
|
5
|
+
WebhookBenefitGrantRevokedPayload$inboundSchema,
|
|
6
|
+
WebhookBenefitGrantUpdatedPayload$inboundSchema,
|
|
7
|
+
WebhookBenefitUpdatedPayload$inboundSchema,
|
|
8
|
+
WebhookCheckoutCreatedPayload$inboundSchema,
|
|
9
|
+
WebhookCheckoutUpdatedPayload$inboundSchema,
|
|
10
|
+
WebhookOrderCreatedPayload$inboundSchema,
|
|
11
|
+
WebhookOrganizationUpdatedPayload$inboundSchema,
|
|
12
|
+
WebhookPledgeCreatedPayload$inboundSchema,
|
|
13
|
+
WebhookPledgeUpdatedPayload$inboundSchema,
|
|
14
|
+
WebhookProductCreatedPayload$inboundSchema,
|
|
15
|
+
WebhookProductUpdatedPayload$inboundSchema,
|
|
16
|
+
WebhookSubscriptionActivePayload$inboundSchema,
|
|
17
|
+
WebhookSubscriptionCanceledPayload$inboundSchema,
|
|
18
|
+
WebhookSubscriptionCreatedPayload$inboundSchema,
|
|
19
|
+
WebhookSubscriptionRevokedPayload$inboundSchema,
|
|
20
|
+
WebhookSubscriptionUpdatedPayload$inboundSchema,
|
|
21
|
+
} from '../models/components'
|
|
22
|
+
import { SDKValidationError } from "../models/errors";
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class WebhookVerificationError extends Error {
|
|
26
|
+
constructor(message: string) {
|
|
27
|
+
super(message);
|
|
28
|
+
this.message = message;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const parseEvent = (parsed: any) => {
|
|
33
|
+
try {
|
|
34
|
+
switch (parsed.type) {
|
|
35
|
+
case 'benefit.created':
|
|
36
|
+
return WebhookBenefitCreatedPayload$inboundSchema.parse(parsed);
|
|
37
|
+
case 'benefit_grant.created':
|
|
38
|
+
return WebhookBenefitGrantCreatedPayload$inboundSchema.parse(parsed);
|
|
39
|
+
case 'benefit_grant.revoked':
|
|
40
|
+
return WebhookBenefitGrantRevokedPayload$inboundSchema.parse(parsed);
|
|
41
|
+
case 'benefit_grant.updated':
|
|
42
|
+
return WebhookBenefitGrantUpdatedPayload$inboundSchema.parse(parsed);
|
|
43
|
+
case 'benefit.updated':
|
|
44
|
+
return WebhookBenefitUpdatedPayload$inboundSchema.parse(parsed);
|
|
45
|
+
case 'checkout.created':
|
|
46
|
+
return WebhookCheckoutCreatedPayload$inboundSchema.parse(parsed);
|
|
47
|
+
case 'checkout.updated':
|
|
48
|
+
return WebhookCheckoutUpdatedPayload$inboundSchema.parse(parsed);
|
|
49
|
+
case 'order.created':
|
|
50
|
+
return WebhookOrderCreatedPayload$inboundSchema.parse(parsed);
|
|
51
|
+
case 'organization.updated':
|
|
52
|
+
return WebhookOrganizationUpdatedPayload$inboundSchema.parse(parsed);
|
|
53
|
+
case 'pledge.created':
|
|
54
|
+
return WebhookPledgeCreatedPayload$inboundSchema.parse(parsed);
|
|
55
|
+
case 'pledge.updated':
|
|
56
|
+
return WebhookPledgeUpdatedPayload$inboundSchema.parse(parsed);
|
|
57
|
+
case 'product.created':
|
|
58
|
+
return WebhookProductCreatedPayload$inboundSchema.parse(parsed);
|
|
59
|
+
case 'product.updated':
|
|
60
|
+
return WebhookProductUpdatedPayload$inboundSchema.parse(parsed);
|
|
61
|
+
case 'subscription.active':
|
|
62
|
+
return WebhookSubscriptionActivePayload$inboundSchema.parse(parsed);
|
|
63
|
+
case 'subscription.canceled':
|
|
64
|
+
return WebhookSubscriptionCanceledPayload$inboundSchema.parse(parsed);
|
|
65
|
+
case 'subscription.created':
|
|
66
|
+
return WebhookSubscriptionCreatedPayload$inboundSchema.parse(parsed);
|
|
67
|
+
case 'subscription.revoked':
|
|
68
|
+
return WebhookSubscriptionRevokedPayload$inboundSchema.parse(parsed);
|
|
69
|
+
case 'subscription.updated':
|
|
70
|
+
return WebhookSubscriptionUpdatedPayload$inboundSchema.parse(parsed);
|
|
71
|
+
default:
|
|
72
|
+
throw new SDKValidationError(`Unknown event type: ${parsed.type}`, parsed.type, parsed);
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
throw new SDKValidationError('Failed to parse event', error, parsed)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const validateEvent = (body: string | Buffer, headers: Record<string, string>, secret: string) => {
|
|
80
|
+
const base64Secret = Buffer.from(secret, 'utf-8').toString('base64');
|
|
81
|
+
const webhook = new Webhook(base64Secret);
|
|
82
|
+
try {
|
|
83
|
+
const parsed = webhook.verify(body, headers);
|
|
84
|
+
return parseEvent(parsed);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error instanceof _WebhookVerificationError) {
|
|
87
|
+
throw new WebhookVerificationError(error.message);
|
|
88
|
+
}
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export {
|
|
94
|
+
validateEvent,
|
|
95
|
+
WebhookVerificationError,
|
|
96
|
+
}
|
package/types/operations.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import { Result } from "./fp.js";
|
|
|
2
2
|
export type Paginator<V> = () => Promise<V & {
|
|
3
3
|
next: Paginator<V>;
|
|
4
4
|
}> | null;
|
|
5
|
-
export type PageIterator<V> = V & {
|
|
5
|
+
export type PageIterator<V, PageState = unknown> = V & {
|
|
6
6
|
next: Paginator<V>;
|
|
7
7
|
[Symbol.asyncIterator]: () => AsyncIterableIterator<V>;
|
|
8
|
+
"~next"?: PageState | undefined;
|
|
8
9
|
};
|
|
9
10
|
export declare function createPageIterator<V>(page: V & {
|
|
10
11
|
next: Paginator<V>;
|
|
@@ -16,10 +17,11 @@ export declare function createPageIterator<V>(page: V & {
|
|
|
16
17
|
* terminates. It is useful in paginated SDK functions that have early return
|
|
17
18
|
* paths when things go wrong.
|
|
18
19
|
*/
|
|
19
|
-
export declare function haltIterator<V extends object>(v: V): PageIterator<V>;
|
|
20
|
+
export declare function haltIterator<V extends object>(v: V): PageIterator<V, undefined>;
|
|
20
21
|
/**
|
|
21
22
|
* Converts an async iterator of `Result<V, E>` into an async iterator of `V`.
|
|
22
23
|
* When error results occur, the underlying error value is thrown.
|
|
23
24
|
*/
|
|
24
|
-
export declare function unwrapResultIterator<V>(iteratorPromise: Promise<PageIterator<Result<V, unknown
|
|
25
|
+
export declare function unwrapResultIterator<V, PageState>(iteratorPromise: Promise<PageIterator<Result<V, unknown>, PageState>>): Promise<PageIterator<V, PageState>>;
|
|
26
|
+
export declare const URL_OVERRIDE: unique symbol;
|
|
25
27
|
//# sourceMappingURL=operations.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../src/types/operations.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC;AAE5E,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG;
|
|
1
|
+
{"version":3,"file":"operations.d.ts","sourceRoot":"","sources":["../src/types/operations.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC,GAAG,IAAI,CAAC;AAE5E,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,SAAS,GAAG,OAAO,IAAI,CAAC,GAAG;IACrD,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,qBAAqB,CAAC,CAAC,CAAC,CAAC;IACvD,OAAO,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;CACjC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,IAAI,EAAE,CAAC,GAAG;IAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;CAAE,EAChC,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,OAAO,GACtB;IACD,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,MAAM,qBAAqB,CAAC,CAAC,CAAC,CAAC;CACxD,CAiBA;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,MAAM,EAC3C,CAAC,EAAE,CAAC,GACH,YAAY,CAAC,CAAC,EAAE,SAAS,CAAC,CAQ5B;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,SAAS,EACrD,eAAe,EAAE,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC,GACpE,OAAO,CAAC,YAAY,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAoBrC;AAuBD,eAAO,MAAM,YAAY,eAAyB,CAAC"}
|
package/types/operations.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.URL_OVERRIDE = void 0;
|
|
6
7
|
exports.createPageIterator = createPageIterator;
|
|
7
8
|
exports.haltIterator = haltIterator;
|
|
8
9
|
exports.unwrapResultIterator = unwrapResultIterator;
|
|
@@ -49,6 +50,7 @@ async function unwrapResultIterator(iteratorPromise) {
|
|
|
49
50
|
return {
|
|
50
51
|
...resultIter.value,
|
|
51
52
|
next: unwrapPaginator(resultIter.next),
|
|
53
|
+
"~next": resultIter["~next"],
|
|
52
54
|
[Symbol.asyncIterator]: async function* paginator() {
|
|
53
55
|
for await (const page of resultIter) {
|
|
54
56
|
if (!page.ok) {
|
|
@@ -77,4 +79,5 @@ function unwrapPaginator(paginator) {
|
|
|
77
79
|
});
|
|
78
80
|
};
|
|
79
81
|
}
|
|
82
|
+
exports.URL_OVERRIDE = Symbol("URL_OVERRIDE");
|
|
80
83
|
//# sourceMappingURL=operations.js.map
|
package/types/operations.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/types/operations.ts"],"names":[],"mappings":";AAAA;;GAEG
|
|
1
|
+
{"version":3,"file":"operations.js","sourceRoot":"","sources":["../src/types/operations.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAYH,gDAsBC;AAOD,oCAUC;AAMD,oDAsBC;AAnED,SAAgB,kBAAkB,CAChC,IAAgC,EAChC,IAAuB;IAIvB,OAAO;QACL,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,SAAS;YAC/C,MAAM,IAAI,CAAC;YACX,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACf,OAAO;YACT,CAAC;YAED,IAAI,CAAC,GAAuB,IAAI,CAAC;YACjC,KAAK,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvD,MAAM,CAAC,CAAC;gBACR,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAgB,YAAY,CAC1B,CAAI;IAEJ,OAAO;QACL,GAAG,CAAC;QACJ,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI;QAChB,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,SAAS;YAC/C,MAAM,CAAC,CAAC;QACV,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACI,KAAK,UAAU,oBAAoB,CACxC,eAAqE;IAErE,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC;IAEzC,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,MAAM,UAAU,CAAC,KAAK,CAAC;IACzB,CAAC;IAED,OAAO;QACL,GAAG,UAAU,CAAC,KAAK;QACnB,IAAI,EAAE,eAAe,CAAC,UAAU,CAAC,IAAI,CAAC;QACtC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC;QAC5B,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,SAAS;YAC/C,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;gBACpC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;oBACb,MAAM,IAAI,CAAC,KAAK,CAAC;gBACnB,CAAC;gBACD,MAAM,IAAI,CAAC,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CACtB,SAAwC;IAExC,OAAO,GAAG,EAAE;QACV,MAAM,UAAU,GAAG,SAAS,EAAE,CAAC;QAC/B,IAAI,UAAU,IAAI,IAAI,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBACZ,MAAM,GAAG,CAAC,KAAK,CAAC;YAClB,CAAC;YACD,MAAM,GAAG,GAAG;gBACV,GAAG,GAAG,CAAC,KAAK;gBACZ,IAAI,EAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;aAChC,CAAC;YACF,OAAO,GAAG,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAEY,QAAA,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare class WebhookVerificationError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
declare const validateEvent: (body: string | Buffer, headers: Record<string, string>, secret: string) => import("../models/components").WebhookBenefitCreatedPayload | import("../models/components").WebhookBenefitGrantCreatedPayload | import("../models/components").WebhookBenefitGrantRevokedPayload | import("../models/components").WebhookBenefitGrantUpdatedPayload | import("../models/components").WebhookBenefitUpdatedPayload | import("../models/components").WebhookCheckoutCreatedPayload | import("../models/components").WebhookCheckoutUpdatedPayload | import("../models/components").WebhookOrderCreatedPayload | import("../models/components").WebhookOrganizationUpdatedPayload | import("../models/components").WebhookPledgeCreatedPayload | import("../models/components").WebhookPledgeUpdatedPayload | import("../models/components").WebhookProductCreatedPayload | import("../models/components").WebhookProductUpdatedPayload | import("../models/components").WebhookSubscriptionActivePayload | import("../models/components").WebhookSubscriptionCanceledPayload | import("../models/components").WebhookSubscriptionCreatedPayload | import("../models/components").WebhookSubscriptionRevokedPayload | import("../models/components").WebhookSubscriptionUpdatedPayload;
|
|
5
|
+
export { validateEvent, WebhookVerificationError, };
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/webhooks/index.ts"],"names":[],"mappings":"AAwBA,cAAM,wBAAyB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM;CAI9B;AAiDD,QAAA,MAAM,aAAa,SAAU,MAAM,GAAG,MAAM,WAAW,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,MAAM,yoCAY5F,CAAA;AAED,OAAO,EACH,aAAa,EACb,wBAAwB,GAC3B,CAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WebhookVerificationError = exports.validateEvent = void 0;
|
|
4
|
+
const standardwebhooks_1 = require("standardwebhooks");
|
|
5
|
+
const components_1 = require("../models/components");
|
|
6
|
+
const errors_1 = require("../models/errors");
|
|
7
|
+
class WebhookVerificationError extends Error {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.message = message;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.WebhookVerificationError = WebhookVerificationError;
|
|
14
|
+
const parseEvent = (parsed) => {
|
|
15
|
+
try {
|
|
16
|
+
switch (parsed.type) {
|
|
17
|
+
case 'benefit.created':
|
|
18
|
+
return components_1.WebhookBenefitCreatedPayload$inboundSchema.parse(parsed);
|
|
19
|
+
case 'benefit_grant.created':
|
|
20
|
+
return components_1.WebhookBenefitGrantCreatedPayload$inboundSchema.parse(parsed);
|
|
21
|
+
case 'benefit_grant.revoked':
|
|
22
|
+
return components_1.WebhookBenefitGrantRevokedPayload$inboundSchema.parse(parsed);
|
|
23
|
+
case 'benefit_grant.updated':
|
|
24
|
+
return components_1.WebhookBenefitGrantUpdatedPayload$inboundSchema.parse(parsed);
|
|
25
|
+
case 'benefit.updated':
|
|
26
|
+
return components_1.WebhookBenefitUpdatedPayload$inboundSchema.parse(parsed);
|
|
27
|
+
case 'checkout.created':
|
|
28
|
+
return components_1.WebhookCheckoutCreatedPayload$inboundSchema.parse(parsed);
|
|
29
|
+
case 'checkout.updated':
|
|
30
|
+
return components_1.WebhookCheckoutUpdatedPayload$inboundSchema.parse(parsed);
|
|
31
|
+
case 'order.created':
|
|
32
|
+
return components_1.WebhookOrderCreatedPayload$inboundSchema.parse(parsed);
|
|
33
|
+
case 'organization.updated':
|
|
34
|
+
return components_1.WebhookOrganizationUpdatedPayload$inboundSchema.parse(parsed);
|
|
35
|
+
case 'pledge.created':
|
|
36
|
+
return components_1.WebhookPledgeCreatedPayload$inboundSchema.parse(parsed);
|
|
37
|
+
case 'pledge.updated':
|
|
38
|
+
return components_1.WebhookPledgeUpdatedPayload$inboundSchema.parse(parsed);
|
|
39
|
+
case 'product.created':
|
|
40
|
+
return components_1.WebhookProductCreatedPayload$inboundSchema.parse(parsed);
|
|
41
|
+
case 'product.updated':
|
|
42
|
+
return components_1.WebhookProductUpdatedPayload$inboundSchema.parse(parsed);
|
|
43
|
+
case 'subscription.active':
|
|
44
|
+
return components_1.WebhookSubscriptionActivePayload$inboundSchema.parse(parsed);
|
|
45
|
+
case 'subscription.canceled':
|
|
46
|
+
return components_1.WebhookSubscriptionCanceledPayload$inboundSchema.parse(parsed);
|
|
47
|
+
case 'subscription.created':
|
|
48
|
+
return components_1.WebhookSubscriptionCreatedPayload$inboundSchema.parse(parsed);
|
|
49
|
+
case 'subscription.revoked':
|
|
50
|
+
return components_1.WebhookSubscriptionRevokedPayload$inboundSchema.parse(parsed);
|
|
51
|
+
case 'subscription.updated':
|
|
52
|
+
return components_1.WebhookSubscriptionUpdatedPayload$inboundSchema.parse(parsed);
|
|
53
|
+
default:
|
|
54
|
+
throw new errors_1.SDKValidationError(`Unknown event type: ${parsed.type}`, parsed.type, parsed);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
throw new errors_1.SDKValidationError('Failed to parse event', error, parsed);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const validateEvent = (body, headers, secret) => {
|
|
62
|
+
const base64Secret = Buffer.from(secret, 'utf-8').toString('base64');
|
|
63
|
+
const webhook = new standardwebhooks_1.Webhook(base64Secret);
|
|
64
|
+
try {
|
|
65
|
+
const parsed = webhook.verify(body, headers);
|
|
66
|
+
return parseEvent(parsed);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (error instanceof standardwebhooks_1.WebhookVerificationError) {
|
|
70
|
+
throw new WebhookVerificationError(error.message);
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
exports.validateEvent = validateEvent;
|
|
76
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/webhooks/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/webhooks/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const crypto_1 = require("crypto");
|
|
4
|
+
const standardwebhooks_1 = require("standardwebhooks");
|
|
5
|
+
const _1 = require(".");
|
|
6
|
+
const errors_1 = require("../models/errors");
|
|
7
|
+
const components_1 = require("../models/components");
|
|
8
|
+
const ORGANIZATION_ID = (0, crypto_1.randomUUID)().toString();
|
|
9
|
+
const PRODUCT_ID = (0, crypto_1.randomUUID)().toString();
|
|
10
|
+
const PRICE_ID = (0, crypto_1.randomUUID)().toString();
|
|
11
|
+
const price = {
|
|
12
|
+
id: PRICE_ID,
|
|
13
|
+
created_at: new Date().toISOString(),
|
|
14
|
+
modified_at: null,
|
|
15
|
+
is_archived: false,
|
|
16
|
+
product_id: PRODUCT_ID,
|
|
17
|
+
price_currency: "usd",
|
|
18
|
+
price_amount: 1000,
|
|
19
|
+
type: "one_time",
|
|
20
|
+
amount_type: "fixed",
|
|
21
|
+
};
|
|
22
|
+
const product = {
|
|
23
|
+
id: PRODUCT_ID,
|
|
24
|
+
created_at: new Date().toISOString(),
|
|
25
|
+
modified_at: null,
|
|
26
|
+
name: "Product",
|
|
27
|
+
description: null,
|
|
28
|
+
is_recurring: false,
|
|
29
|
+
is_archived: false,
|
|
30
|
+
organization_id: ORGANIZATION_ID,
|
|
31
|
+
prices: [price],
|
|
32
|
+
benefits: [],
|
|
33
|
+
medias: [],
|
|
34
|
+
};
|
|
35
|
+
const checkoutCreated = {
|
|
36
|
+
type: "checkout.created",
|
|
37
|
+
data: {
|
|
38
|
+
id: (0, crypto_1.randomUUID)().toString(),
|
|
39
|
+
created_at: new Date().toISOString(),
|
|
40
|
+
modified_at: null,
|
|
41
|
+
status: "open",
|
|
42
|
+
client_secret: "CLIENT_SECRET",
|
|
43
|
+
url: "https://polar.sh/checkout/CLIENT_SECRET",
|
|
44
|
+
expires_at: new Date().toISOString(),
|
|
45
|
+
success_url: "https://polar.sh/checkout/CLIENT_SECRET/confirmation",
|
|
46
|
+
embed_origin: null,
|
|
47
|
+
tax_amount: 0,
|
|
48
|
+
amount: 1000,
|
|
49
|
+
currency: "usd",
|
|
50
|
+
subtotal_amount: 1000,
|
|
51
|
+
total_amount: 1000,
|
|
52
|
+
product_id: PRODUCT_ID,
|
|
53
|
+
product_price_id: PRICE_ID,
|
|
54
|
+
discount_id: null,
|
|
55
|
+
allow_discount_codes: true,
|
|
56
|
+
is_discount_applicable: true,
|
|
57
|
+
is_free_product_price: false,
|
|
58
|
+
is_payment_required: true,
|
|
59
|
+
is_payment_setup_required: false,
|
|
60
|
+
is_payment_form_required: true,
|
|
61
|
+
customer_id: null,
|
|
62
|
+
customer_name: null,
|
|
63
|
+
customer_email: null,
|
|
64
|
+
customer_ip_address: null,
|
|
65
|
+
customer_billing_address: null,
|
|
66
|
+
customer_tax_id: null,
|
|
67
|
+
payment_processor_metadata: {},
|
|
68
|
+
metadata: {},
|
|
69
|
+
product: product,
|
|
70
|
+
product_price: price,
|
|
71
|
+
discount: null,
|
|
72
|
+
subscription_id: null,
|
|
73
|
+
attached_custom_fields: [],
|
|
74
|
+
custom_field_data: {},
|
|
75
|
+
payment_processor: 'stripe',
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
const WEBHOOK_SECRET = "TestSecret";
|
|
79
|
+
const WEBHOOK_SECRET_BASE64 = Buffer.from(WEBHOOK_SECRET, 'utf-8').toString('base64');
|
|
80
|
+
const getHeaders = (body, webhookId = "WEBHOOK_ID", timestamp) => {
|
|
81
|
+
const _timestamp = timestamp || new Date();
|
|
82
|
+
const signature = new standardwebhooks_1.Webhook(WEBHOOK_SECRET_BASE64).sign(webhookId, _timestamp, body);
|
|
83
|
+
return {
|
|
84
|
+
"webhook-id": webhookId,
|
|
85
|
+
"webhook-timestamp": Math.floor(_timestamp.getTime() / 1000).toString(),
|
|
86
|
+
"webhook-signature": signature,
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
describe('validateEvent', () => {
|
|
90
|
+
it('should validate signature and parse payload', () => {
|
|
91
|
+
const body = JSON.stringify(checkoutCreated);
|
|
92
|
+
const headers = getHeaders(body);
|
|
93
|
+
const parsed = (0, _1.validateEvent)(body, headers, WEBHOOK_SECRET);
|
|
94
|
+
expect(parsed).toEqual(components_1.WebhookCheckoutCreatedPayload$inboundSchema.parse(checkoutCreated));
|
|
95
|
+
});
|
|
96
|
+
it('should throw error if signature is invalid', () => {
|
|
97
|
+
const body = JSON.stringify(checkoutCreated);
|
|
98
|
+
const headers = getHeaders(body);
|
|
99
|
+
expect(() => (0, _1.validateEvent)(body, headers, "AnotherSecret")).toThrow(_1.WebhookVerificationError);
|
|
100
|
+
});
|
|
101
|
+
it('should throw error if payload is invalid', () => {
|
|
102
|
+
const body = '{"type": "unknown"}';
|
|
103
|
+
const headers = getHeaders(body);
|
|
104
|
+
expect(() => (0, _1.validateEvent)(body, headers, WEBHOOK_SECRET)).toThrow(errors_1.SDKValidationError);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
//# sourceMappingURL=index.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/webhooks/index.test.ts"],"names":[],"mappings":"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"}
|