@polar-sh/sdk 0.17.0 → 0.17.2
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 +43 -12
- 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/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/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
|
@@ -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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"}
|