@spaire/supabase 1.0.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 ADDED
@@ -0,0 +1,124 @@
1
+ # @spaire/supabase
2
+
3
+ Payments and Checkouts made dead simple with Supabase Edge Functions.
4
+
5
+ `npm install @spaire/supabase`
6
+
7
+ ## Checkout
8
+
9
+ Create a Checkout handler which takes care of redirections.
10
+
11
+ ```typescript
12
+ // supabase/functions/checkout/index.ts
13
+ import { Checkout } from "@spaire/supabase";
14
+
15
+ const handler = Checkout({
16
+ accessToken: Deno.env.get("SPAIRE_ACCESS_TOKEN"),
17
+ successUrl: Deno.env.get("SUCCESS_URL"),
18
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Checkout
19
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
20
+ theme: "dark", // Enforces the theme - System-preferred theme will be set if left omitted
21
+ });
22
+
23
+ Deno.serve(handler);
24
+ ```
25
+
26
+ ### Query Params
27
+
28
+ Pass query params to this route.
29
+
30
+ - products `?products=123`
31
+ - customerId (optional) `?products=123&customerId=xxx`
32
+ - customerExternalId (optional) `?products=123&customerExternalId=xxx`
33
+ - customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
34
+ - customerName (optional) `?products=123&customerName=Jane`
35
+ - customerBillingAddress (optional) `URL-Encoded JSON string`
36
+ - customerTaxId (optional) `?products=123&customerTaxId=xxx`
37
+ - customerIpAddress (optional) `?products=123&customerIpAddress=192.168.1.1`
38
+ - customerMetadata (optional) `URL-Encoded JSON string`
39
+ - allowDiscountCodes (optional) `?products=123&allowDiscountCodes=true`
40
+ - discountId (optional) `?products=123&discountId=xxx`
41
+ - seats (optional) `?products=123&seats=5` - Number of seats for seat-based products
42
+ - metadata (optional) `URL-Encoded JSON string`
43
+
44
+ ## Customer Portal
45
+
46
+ Create a customer portal where your customer can view orders and subscriptions.
47
+
48
+ ```typescript
49
+ // supabase/functions/portal/index.ts
50
+ import { CustomerPortal } from "@spaire/supabase";
51
+
52
+ const handler = CustomerPortal({
53
+ accessToken: Deno.env.get("SPAIRE_ACCESS_TOKEN")!,
54
+ getCustomerId: async (req: Request) => {
55
+ // Function to resolve a Spaire Customer ID
56
+ // You can extract customer ID from auth headers, cookies, etc.
57
+ return "123";
58
+ },
59
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Customer Portal
60
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
61
+ });
62
+
63
+ Deno.serve(handler);
64
+ ```
65
+
66
+ ## Webhooks
67
+
68
+ A simple utility which resolves incoming webhook payloads by validating the webhook signature.
69
+
70
+ ```typescript
71
+ // supabase/functions/webhooks/index.ts
72
+ import { Webhooks } from "@spaire/supabase";
73
+
74
+ const handler = Webhooks({
75
+ webhookSecret: Deno.env.get("SPAIRE_WEBHOOK_SECRET")!,
76
+ onPayload: async (payload) => {
77
+ // Handle the payload
78
+ // No need to return an acknowledge response
79
+ },
80
+ });
81
+
82
+ Deno.serve(handler);
83
+ ```
84
+
85
+ ### Payload Handlers
86
+
87
+ The Webhook handler also supports granular handlers for easy integration.
88
+
89
+ - onCheckoutCreated: (payload) => Promise<void>
90
+ - onCheckoutUpdated: (payload) => Promise<void>
91
+ - onOrderCreated: (payload) => Promise<void>
92
+ - onOrderUpdated: (payload) => Promise<void>
93
+ - onOrderPaid: (payload) => Promise<void>
94
+ - onOrderRefunded: (payload) => Promise<void>
95
+ - onRefundCreated: (payload) => Promise<void>
96
+ - onRefundUpdated: (payload) => Promise<void>
97
+ - onSubscriptionCreated: (payload) => Promise<void>
98
+ - onSubscriptionUpdated: (payload) => Promise<void>
99
+ - onSubscriptionActive: (payload) => Promise<void>
100
+ - onSubscriptionCanceled: (payload) => Promise<void>
101
+ - onSubscriptionRevoked: (payload) => Promise<void>
102
+ - onSubscriptionUncanceled: (payload) => Promise<void>
103
+ - onProductCreated: (payload) => Promise<void>
104
+ - onProductUpdated: (payload) => Promise<void>
105
+ - onOrganizationUpdated: (payload) => Promise<void>
106
+ - onBenefitCreated: (payload) => Promise<void>
107
+ - onBenefitUpdated: (payload) => Promise<void>
108
+ - onBenefitGrantCreated: (payload) => Promise<void>
109
+ - onBenefitGrantUpdated: (payload) => Promise<void>
110
+ - onBenefitGrantRevoked: (payload) => Promise<void>
111
+ - onCustomerCreated: (payload) => Promise<void>
112
+ - onCustomerUpdated: (payload) => Promise<void>
113
+ - onCustomerDeleted: (payload) => Promise<void>
114
+ - onCustomerStateChanged: (payload) => Promise<void>
115
+
116
+ ## Edge Runtime Compatibility
117
+
118
+ This adapter is built to work with Supabase Edge Functions, which run on the Deno runtime. It uses standard Web APIs (`Request`, `Response`) that are compatible with edge environments, making it ideal for:
119
+
120
+ - Supabase Edge Functions
121
+ - Deno Deploy
122
+ - Other Deno-based edge runtimes
123
+
124
+ All handlers return standard `Response` objects and accept standard `Request` objects, ensuring maximum compatibility with edge runtimes.
package/dist/index.cjs ADDED
@@ -0,0 +1,386 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Checkout: () => Checkout,
24
+ CustomerPortal: () => CustomerPortal,
25
+ EntitlementStrategy: () => EntitlementStrategy,
26
+ Entitlements: () => Entitlements,
27
+ Webhooks: () => Webhooks
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/checkout/checkout.ts
32
+ var import_sdk = require("@spaire/sdk");
33
+ var Checkout = ({
34
+ accessToken,
35
+ successUrl,
36
+ returnUrl,
37
+ server,
38
+ theme,
39
+ includeCheckoutId = true
40
+ }) => {
41
+ const spaire = new import_sdk.Spaire({
42
+ accessToken,
43
+ server
44
+ });
45
+ return async (req) => {
46
+ const url = new URL(req.url);
47
+ const products = url.searchParams.getAll("products");
48
+ if (products.length === 0) {
49
+ return new Response(
50
+ JSON.stringify({ error: "Missing products in query params" }),
51
+ {
52
+ status: 400,
53
+ headers: { "Content-Type": "application/json" }
54
+ }
55
+ );
56
+ }
57
+ const success = successUrl ? new URL(successUrl) : void 0;
58
+ if (success && includeCheckoutId) {
59
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
60
+ }
61
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
62
+ try {
63
+ const result = await spaire.checkouts.create({
64
+ products,
65
+ successUrl: success ? decodeURI(success.toString()) : void 0,
66
+ customerId: url.searchParams.get("customerId") ?? void 0,
67
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
68
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
69
+ customerName: url.searchParams.get("customerName") ?? void 0,
70
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
71
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
72
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
73
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
74
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
75
+ discountId: url.searchParams.get("discountId") ?? void 0,
76
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
77
+ seats: url.searchParams.has("seats") ? Number.parseInt(url.searchParams.get("seats") ?? "1", 10) : void 0,
78
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
79
+ });
80
+ const redirectUrl = new URL(result.url);
81
+ if (theme) {
82
+ redirectUrl.searchParams.set("theme", theme);
83
+ }
84
+ return new Response(null, {
85
+ status: 302,
86
+ headers: {
87
+ Location: redirectUrl.toString()
88
+ }
89
+ });
90
+ } catch (error) {
91
+ console.error(error);
92
+ return new Response(null, { status: 500 });
93
+ }
94
+ };
95
+ };
96
+
97
+ // src/customerPortal/customerPortal.ts
98
+ var import_sdk2 = require("@spaire/sdk");
99
+ var CustomerPortal = ({
100
+ accessToken,
101
+ server,
102
+ getCustomerId,
103
+ returnUrl
104
+ }) => {
105
+ const spaire = new import_sdk2.Spaire({
106
+ accessToken,
107
+ server
108
+ });
109
+ return async (req) => {
110
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
111
+ const customerId = await getCustomerId(req);
112
+ if (!customerId) {
113
+ return new Response(JSON.stringify({ error: "customerId not defined" }), {
114
+ status: 400,
115
+ headers: { "Content-Type": "application/json" }
116
+ });
117
+ }
118
+ try {
119
+ const result = await spaire.customerSessions.create({
120
+ customerId,
121
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
122
+ });
123
+ return new Response(null, {
124
+ status: 302,
125
+ headers: {
126
+ Location: result.customerPortalUrl
127
+ }
128
+ });
129
+ } catch (error) {
130
+ console.error(error);
131
+ return new Response(null, { status: 500 });
132
+ }
133
+ };
134
+ };
135
+
136
+ // ../adapter-utils/dist/index.js
137
+ var handleWebhookPayload = async (payload, { webhookSecret, entitlements, onPayload, ...eventHandlers }) => {
138
+ const promises = [];
139
+ if (onPayload) {
140
+ promises.push(onPayload(payload));
141
+ }
142
+ switch (payload.type) {
143
+ case "checkout.created":
144
+ if (eventHandlers.onCheckoutCreated) {
145
+ promises.push(eventHandlers.onCheckoutCreated(payload));
146
+ }
147
+ break;
148
+ case "checkout.updated":
149
+ if (eventHandlers.onCheckoutUpdated) {
150
+ promises.push(eventHandlers.onCheckoutUpdated(payload));
151
+ }
152
+ break;
153
+ case "order.created":
154
+ if (eventHandlers.onOrderCreated) {
155
+ promises.push(eventHandlers.onOrderCreated(payload));
156
+ }
157
+ break;
158
+ case "order.updated":
159
+ if (eventHandlers.onOrderUpdated) {
160
+ promises.push(eventHandlers.onOrderUpdated(payload));
161
+ }
162
+ break;
163
+ case "order.paid":
164
+ if (eventHandlers.onOrderPaid) {
165
+ promises.push(eventHandlers.onOrderPaid(payload));
166
+ }
167
+ break;
168
+ case "subscription.created":
169
+ if (eventHandlers.onSubscriptionCreated) {
170
+ promises.push(eventHandlers.onSubscriptionCreated(payload));
171
+ }
172
+ break;
173
+ case "subscription.updated":
174
+ if (eventHandlers.onSubscriptionUpdated) {
175
+ promises.push(eventHandlers.onSubscriptionUpdated(payload));
176
+ }
177
+ break;
178
+ case "subscription.active":
179
+ if (eventHandlers.onSubscriptionActive) {
180
+ promises.push(eventHandlers.onSubscriptionActive(payload));
181
+ }
182
+ break;
183
+ case "subscription.canceled":
184
+ if (eventHandlers.onSubscriptionCanceled) {
185
+ promises.push(eventHandlers.onSubscriptionCanceled(payload));
186
+ }
187
+ break;
188
+ case "subscription.uncanceled":
189
+ if (eventHandlers.onSubscriptionUncanceled) {
190
+ promises.push(eventHandlers.onSubscriptionUncanceled(payload));
191
+ }
192
+ break;
193
+ case "subscription.revoked":
194
+ if (eventHandlers.onSubscriptionRevoked) {
195
+ promises.push(eventHandlers.onSubscriptionRevoked(payload));
196
+ }
197
+ break;
198
+ case "product.created":
199
+ if (eventHandlers.onProductCreated) {
200
+ promises.push(eventHandlers.onProductCreated(payload));
201
+ }
202
+ break;
203
+ case "product.updated":
204
+ if (eventHandlers.onProductUpdated) {
205
+ promises.push(eventHandlers.onProductUpdated(payload));
206
+ }
207
+ break;
208
+ case "organization.updated":
209
+ if (eventHandlers.onOrganizationUpdated) {
210
+ promises.push(eventHandlers.onOrganizationUpdated(payload));
211
+ }
212
+ break;
213
+ case "benefit.created":
214
+ if (eventHandlers.onBenefitCreated) {
215
+ promises.push(eventHandlers.onBenefitCreated(payload));
216
+ }
217
+ break;
218
+ case "benefit.updated":
219
+ if (eventHandlers.onBenefitUpdated) {
220
+ promises.push(eventHandlers.onBenefitUpdated(payload));
221
+ }
222
+ break;
223
+ case "benefit_grant.created":
224
+ if (eventHandlers.onBenefitGrantCreated) {
225
+ promises.push(eventHandlers.onBenefitGrantCreated(payload));
226
+ }
227
+ break;
228
+ case "benefit_grant.updated":
229
+ if (eventHandlers.onBenefitGrantUpdated) {
230
+ promises.push(eventHandlers.onBenefitGrantUpdated(payload));
231
+ }
232
+ break;
233
+ case "benefit_grant.revoked":
234
+ if (eventHandlers.onBenefitGrantRevoked) {
235
+ promises.push(eventHandlers.onBenefitGrantRevoked(payload));
236
+ }
237
+ break;
238
+ case "customer.created":
239
+ if (eventHandlers.onCustomerCreated) {
240
+ promises.push(eventHandlers.onCustomerCreated(payload));
241
+ }
242
+ break;
243
+ case "customer.updated":
244
+ if (eventHandlers.onCustomerUpdated) {
245
+ promises.push(eventHandlers.onCustomerUpdated(payload));
246
+ }
247
+ break;
248
+ case "customer.deleted":
249
+ if (eventHandlers.onCustomerDeleted) {
250
+ promises.push(eventHandlers.onCustomerDeleted(payload));
251
+ }
252
+ break;
253
+ case "customer.state_changed":
254
+ if (eventHandlers.onCustomerStateChanged) {
255
+ promises.push(eventHandlers.onCustomerStateChanged(payload));
256
+ }
257
+ break;
258
+ case "order.refunded":
259
+ if (eventHandlers.onOrderRefunded) {
260
+ promises.push(eventHandlers.onOrderRefunded(payload));
261
+ }
262
+ break;
263
+ case "refund.created":
264
+ if (eventHandlers.onRefundCreated) {
265
+ promises.push(eventHandlers.onRefundCreated(payload));
266
+ }
267
+ break;
268
+ case "refund.updated":
269
+ if (eventHandlers.onRefundUpdated) {
270
+ promises.push(eventHandlers.onRefundUpdated(payload));
271
+ }
272
+ break;
273
+ }
274
+ switch (payload.type) {
275
+ case "benefit_grant.created":
276
+ case "benefit_grant.revoked":
277
+ if (entitlements) {
278
+ for (const handler of entitlements.handlers) {
279
+ promises.push(handler(payload));
280
+ }
281
+ }
282
+ }
283
+ return Promise.all(promises);
284
+ };
285
+ var EntitlementStrategy = class {
286
+ grantCallbacks = [];
287
+ revokeCallbacks = [];
288
+ grant(callback) {
289
+ this.grantCallbacks.push(callback);
290
+ return this;
291
+ }
292
+ revoke(callback) {
293
+ this.revokeCallbacks.push(callback);
294
+ return this;
295
+ }
296
+ handler(slug) {
297
+ return async (payload) => {
298
+ if (payload.data.benefit.description === slug) {
299
+ switch (payload.type) {
300
+ case "benefit_grant.created":
301
+ await Promise.all(
302
+ this.grantCallbacks.map(
303
+ (callback) => callback({
304
+ customer: payload.data.customer,
305
+ properties: payload.data.properties,
306
+ payload
307
+ })
308
+ )
309
+ );
310
+ break;
311
+ case "benefit_grant.revoked":
312
+ await Promise.all(
313
+ this.revokeCallbacks.map(
314
+ (callback) => callback({
315
+ customer: payload.data.customer,
316
+ properties: payload.data.properties,
317
+ payload
318
+ })
319
+ )
320
+ );
321
+ break;
322
+ }
323
+ }
324
+ };
325
+ }
326
+ };
327
+ var Entitlements = class {
328
+ static handlers = [];
329
+ static use(slug, strategy) {
330
+ this.handlers.push(strategy.handler(slug));
331
+ return this;
332
+ }
333
+ };
334
+
335
+ // src/webhooks/webhooks.ts
336
+ var import_webhooks = require("@spaire/sdk/webhooks");
337
+ var Webhooks = ({
338
+ webhookSecret,
339
+ entitlements,
340
+ onPayload,
341
+ ...eventHandlers
342
+ }) => {
343
+ return async (request) => {
344
+ const requestBody = await request.text();
345
+ const webhookHeaders = {
346
+ "webhook-id": request.headers.get("webhook-id") ?? "",
347
+ "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
348
+ "webhook-signature": request.headers.get("webhook-signature") ?? ""
349
+ };
350
+ let webhookPayload;
351
+ try {
352
+ webhookPayload = (0, import_webhooks.validateEvent)(
353
+ requestBody,
354
+ webhookHeaders,
355
+ webhookSecret
356
+ );
357
+ } catch (error) {
358
+ if (error instanceof import_webhooks.WebhookVerificationError) {
359
+ return new Response(JSON.stringify({ received: false }), {
360
+ status: 403,
361
+ headers: { "Content-Type": "application/json" }
362
+ });
363
+ }
364
+ throw error;
365
+ }
366
+ await handleWebhookPayload(webhookPayload, {
367
+ webhookSecret,
368
+ entitlements,
369
+ onPayload,
370
+ ...eventHandlers
371
+ });
372
+ return new Response(JSON.stringify({ received: true }), {
373
+ status: 200,
374
+ headers: { "Content-Type": "application/json" }
375
+ });
376
+ };
377
+ };
378
+ // Annotate the CommonJS export names for ESM import in node:
379
+ 0 && (module.exports = {
380
+ Checkout,
381
+ CustomerPortal,
382
+ EntitlementStrategy,
383
+ Entitlements,
384
+ Webhooks
385
+ });
386
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/checkout/checkout.ts","../src/customerPortal/customerPortal.ts","../../adapter-utils/dist/index.js","../src/webhooks/webhooks.ts"],"sourcesContent":["export * from \"./checkout/checkout.js\";\nexport * from \"./customerPortal/customerPortal.js\";\nexport * from \"./webhooks/webhooks.js\";\n","import { Spaire } from \"@spaire/sdk\";\n\nexport interface CheckoutConfig {\n\taccessToken?: string;\n\tsuccessUrl?: string;\n\treturnUrl?: string;\n\tincludeCheckoutId?: boolean;\n\tserver?: \"sandbox\" | \"production\";\n\ttheme?: \"light\" | \"dark\";\n}\n\nexport const Checkout = ({\n\taccessToken,\n\tsuccessUrl,\n\treturnUrl,\n\tserver,\n\ttheme,\n\tincludeCheckoutId = true,\n}: CheckoutConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\treturn async (req: Request) => {\n\t\tconst url = new URL(req.url);\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ error: \"Missing products in query params\" }),\n\t\t\t\t{\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst success = successUrl ? new URL(successUrl) : undefined;\n\n\t\tif (success && includeCheckoutId) {\n\t\t\tsuccess.searchParams.set(\"checkoutId\", \"{CHECKOUT_ID}\");\n\t\t}\n\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\ttry {\n\t\t\tconst result = await spaire.checkouts.create({\n\t\t\t\tproducts,\n\t\t\t\tsuccessUrl: success ? decodeURI(success.toString()) : undefined,\n\t\t\t\tcustomerId: url.searchParams.get(\"customerId\") ?? undefined,\n\t\t\t\texternalCustomerId:\n\t\t\t\t\turl.searchParams.get(\"customerExternalId\") ?? undefined,\n\t\t\t\tcustomerEmail: url.searchParams.get(\"customerEmail\") ?? undefined,\n\t\t\t\tcustomerName: url.searchParams.get(\"customerName\") ?? undefined,\n\t\t\t\tcustomerBillingAddress: url.searchParams.has(\"customerBillingAddress\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerBillingAddress\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tcustomerTaxId: url.searchParams.get(\"customerTaxId\") ?? undefined,\n\t\t\t\tcustomerIpAddress:\n\t\t\t\t\turl.searchParams.get(\"customerIpAddress\") ?? undefined,\n\t\t\t\tcustomerMetadata: url.searchParams.has(\"customerMetadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerMetadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tallowDiscountCodes: url.searchParams.has(\"allowDiscountCodes\")\n\t\t\t\t\t? url.searchParams.get(\"allowDiscountCodes\") === \"true\"\n\t\t\t\t\t: undefined,\n\t\t\t\tdiscountId: url.searchParams.get(\"discountId\") ?? undefined,\n\t\t\t\tmetadata: url.searchParams.has(\"metadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"metadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tseats: url.searchParams.has(\"seats\")\n\t\t\t\t\t? Number.parseInt(url.searchParams.get(\"seats\") ?? \"1\", 10)\n\t\t\t\t\t: undefined,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\tconst redirectUrl = new URL(result.url);\n\n\t\t\tif (theme) {\n\t\t\t\tredirectUrl.searchParams.set(\"theme\", theme);\n\t\t\t}\n\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 302,\n\t\t\t\theaders: {\n\t\t\t\t\tLocation: redirectUrl.toString(),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn new Response(null, { status: 500 });\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\n\nexport interface CustomerPortalConfig {\n\taccessToken: string;\n\tgetCustomerId: (req: Request) => Promise<string>;\n\tserver: \"sandbox\" | \"production\";\n\treturnUrl?: string;\n}\n\nexport const CustomerPortal = ({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\treturn async (req: Request) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\tconst customerId = await getCustomerId(req);\n\n\t\tif (!customerId) {\n\t\t\treturn new Response(JSON.stringify({ error: \"customerId not defined\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await spaire.customerSessions.create({\n\t\t\t\tcustomerId,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 302,\n\t\t\t\theaders: {\n\t\t\t\t\tLocation: result.customerPortalUrl,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn new Response(null, { status: 500 });\n\t\t}\n\t};\n};\n","// src/webhooks/webhooks.ts\nvar handleWebhookPayload = async (payload, { webhookSecret, entitlements, onPayload, ...eventHandlers }) => {\n const promises = [];\n if (onPayload) {\n promises.push(onPayload(payload));\n }\n switch (payload.type) {\n case \"checkout.created\":\n if (eventHandlers.onCheckoutCreated) {\n promises.push(eventHandlers.onCheckoutCreated(payload));\n }\n break;\n case \"checkout.updated\":\n if (eventHandlers.onCheckoutUpdated) {\n promises.push(eventHandlers.onCheckoutUpdated(payload));\n }\n break;\n case \"order.created\":\n if (eventHandlers.onOrderCreated) {\n promises.push(eventHandlers.onOrderCreated(payload));\n }\n break;\n case \"order.updated\":\n if (eventHandlers.onOrderUpdated) {\n promises.push(eventHandlers.onOrderUpdated(payload));\n }\n break;\n case \"order.paid\":\n if (eventHandlers.onOrderPaid) {\n promises.push(eventHandlers.onOrderPaid(payload));\n }\n break;\n case \"subscription.created\":\n if (eventHandlers.onSubscriptionCreated) {\n promises.push(eventHandlers.onSubscriptionCreated(payload));\n }\n break;\n case \"subscription.updated\":\n if (eventHandlers.onSubscriptionUpdated) {\n promises.push(eventHandlers.onSubscriptionUpdated(payload));\n }\n break;\n case \"subscription.active\":\n if (eventHandlers.onSubscriptionActive) {\n promises.push(eventHandlers.onSubscriptionActive(payload));\n }\n break;\n case \"subscription.canceled\":\n if (eventHandlers.onSubscriptionCanceled) {\n promises.push(eventHandlers.onSubscriptionCanceled(payload));\n }\n break;\n case \"subscription.uncanceled\":\n if (eventHandlers.onSubscriptionUncanceled) {\n promises.push(eventHandlers.onSubscriptionUncanceled(payload));\n }\n break;\n case \"subscription.revoked\":\n if (eventHandlers.onSubscriptionRevoked) {\n promises.push(eventHandlers.onSubscriptionRevoked(payload));\n }\n break;\n case \"product.created\":\n if (eventHandlers.onProductCreated) {\n promises.push(eventHandlers.onProductCreated(payload));\n }\n break;\n case \"product.updated\":\n if (eventHandlers.onProductUpdated) {\n promises.push(eventHandlers.onProductUpdated(payload));\n }\n break;\n case \"organization.updated\":\n if (eventHandlers.onOrganizationUpdated) {\n promises.push(eventHandlers.onOrganizationUpdated(payload));\n }\n break;\n case \"benefit.created\":\n if (eventHandlers.onBenefitCreated) {\n promises.push(eventHandlers.onBenefitCreated(payload));\n }\n break;\n case \"benefit.updated\":\n if (eventHandlers.onBenefitUpdated) {\n promises.push(eventHandlers.onBenefitUpdated(payload));\n }\n break;\n case \"benefit_grant.created\":\n if (eventHandlers.onBenefitGrantCreated) {\n promises.push(eventHandlers.onBenefitGrantCreated(payload));\n }\n break;\n case \"benefit_grant.updated\":\n if (eventHandlers.onBenefitGrantUpdated) {\n promises.push(eventHandlers.onBenefitGrantUpdated(payload));\n }\n break;\n case \"benefit_grant.revoked\":\n if (eventHandlers.onBenefitGrantRevoked) {\n promises.push(eventHandlers.onBenefitGrantRevoked(payload));\n }\n break;\n case \"customer.created\":\n if (eventHandlers.onCustomerCreated) {\n promises.push(eventHandlers.onCustomerCreated(payload));\n }\n break;\n case \"customer.updated\":\n if (eventHandlers.onCustomerUpdated) {\n promises.push(eventHandlers.onCustomerUpdated(payload));\n }\n break;\n case \"customer.deleted\":\n if (eventHandlers.onCustomerDeleted) {\n promises.push(eventHandlers.onCustomerDeleted(payload));\n }\n break;\n case \"customer.state_changed\":\n if (eventHandlers.onCustomerStateChanged) {\n promises.push(eventHandlers.onCustomerStateChanged(payload));\n }\n break;\n case \"order.refunded\":\n if (eventHandlers.onOrderRefunded) {\n promises.push(eventHandlers.onOrderRefunded(payload));\n }\n break;\n case \"refund.created\":\n if (eventHandlers.onRefundCreated) {\n promises.push(eventHandlers.onRefundCreated(payload));\n }\n break;\n case \"refund.updated\":\n if (eventHandlers.onRefundUpdated) {\n promises.push(eventHandlers.onRefundUpdated(payload));\n }\n break;\n }\n switch (payload.type) {\n case \"benefit_grant.created\":\n case \"benefit_grant.revoked\":\n if (entitlements) {\n for (const handler of entitlements.handlers) {\n promises.push(handler(payload));\n }\n }\n }\n return Promise.all(promises);\n};\n\n// src/entitlement/entitlement.ts\nvar EntitlementStrategy = class {\n grantCallbacks = [];\n revokeCallbacks = [];\n grant(callback) {\n this.grantCallbacks.push(callback);\n return this;\n }\n revoke(callback) {\n this.revokeCallbacks.push(callback);\n return this;\n }\n handler(slug) {\n return async (payload) => {\n if (payload.data.benefit.description === slug) {\n switch (payload.type) {\n case \"benefit_grant.created\":\n await Promise.all(\n this.grantCallbacks.map(\n (callback) => callback({\n customer: payload.data.customer,\n properties: payload.data.properties,\n payload\n })\n )\n );\n break;\n case \"benefit_grant.revoked\":\n await Promise.all(\n this.revokeCallbacks.map(\n (callback) => callback({\n customer: payload.data.customer,\n properties: payload.data.properties,\n payload\n })\n )\n );\n break;\n }\n }\n };\n }\n};\nvar Entitlements = class {\n static handlers = [];\n static use(slug, strategy) {\n this.handlers.push(strategy.handler(slug));\n return this;\n }\n};\nexport {\n EntitlementStrategy,\n Entitlements,\n handleWebhookPayload\n};\n","import {\n\ttype WebhooksConfig,\n\thandleWebhookPayload,\n} from \"@spaire/adapter-utils\";\nimport {\n\tWebhookVerificationError,\n\tvalidateEvent,\n} from \"@spaire/sdk/webhooks\";\n\nexport {\n\ttype EntitlementContext,\n\ttype EntitlementHandler,\n\ttype EntitlementProperties,\n\tEntitlementStrategy,\n\tEntitlements,\n} from \"@spaire/adapter-utils\";\n\nexport const Webhooks = ({\n\twebhookSecret,\n\tentitlements,\n\tonPayload,\n\t...eventHandlers\n}: WebhooksConfig) => {\n\treturn async (request: Request) => {\n\t\tconst requestBody = await request.text();\n\n\t\tconst webhookHeaders = {\n\t\t\t\"webhook-id\": request.headers.get(\"webhook-id\") ?? \"\",\n\t\t\t\"webhook-timestamp\": request.headers.get(\"webhook-timestamp\") ?? \"\",\n\t\t\t\"webhook-signature\": request.headers.get(\"webhook-signature\") ?? \"\",\n\t\t};\n\n\t\tlet webhookPayload: ReturnType<typeof validateEvent>;\n\t\ttry {\n\t\t\twebhookPayload = validateEvent(\n\t\t\t\trequestBody,\n\t\t\t\twebhookHeaders,\n\t\t\t\twebhookSecret,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn new Response(JSON.stringify({ received: false }), {\n\t\t\t\t\tstatus: 403,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\n\t\tawait handleWebhookPayload(webhookPayload, {\n\t\t\twebhookSecret,\n\t\t\tentitlements,\n\t\t\tonPayload,\n\t\t\t...eventHandlers,\n\t\t});\n\n\t\treturn new Response(JSON.stringify({ received: true }), {\n\t\t\tstatus: 200,\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t});\n\t};\n};\n"],"mappings":"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","names":["import_sdk"]}
@@ -0,0 +1,24 @@
1
+ import { WebhooksConfig } from '@spaire/adapter-utils';
2
+ export { EntitlementContext, EntitlementHandler, EntitlementProperties, EntitlementStrategy, Entitlements } from '@spaire/adapter-utils';
3
+
4
+ interface CheckoutConfig {
5
+ accessToken?: string;
6
+ successUrl?: string;
7
+ returnUrl?: string;
8
+ includeCheckoutId?: boolean;
9
+ server?: "sandbox" | "production";
10
+ theme?: "light" | "dark";
11
+ }
12
+ declare const Checkout: ({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => (req: Request) => Promise<Response>;
13
+
14
+ interface CustomerPortalConfig {
15
+ accessToken: string;
16
+ getCustomerId: (req: Request) => Promise<string>;
17
+ server: "sandbox" | "production";
18
+ returnUrl?: string;
19
+ }
20
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => (req: Request) => Promise<Response>;
21
+
22
+ declare const Webhooks: ({ webhookSecret, entitlements, onPayload, ...eventHandlers }: WebhooksConfig) => (request: Request) => Promise<Response>;
23
+
24
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
@@ -0,0 +1,24 @@
1
+ import { WebhooksConfig } from '@spaire/adapter-utils';
2
+ export { EntitlementContext, EntitlementHandler, EntitlementProperties, EntitlementStrategy, Entitlements } from '@spaire/adapter-utils';
3
+
4
+ interface CheckoutConfig {
5
+ accessToken?: string;
6
+ successUrl?: string;
7
+ returnUrl?: string;
8
+ includeCheckoutId?: boolean;
9
+ server?: "sandbox" | "production";
10
+ theme?: "light" | "dark";
11
+ }
12
+ declare const Checkout: ({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => (req: Request) => Promise<Response>;
13
+
14
+ interface CustomerPortalConfig {
15
+ accessToken: string;
16
+ getCustomerId: (req: Request) => Promise<string>;
17
+ server: "sandbox" | "production";
18
+ returnUrl?: string;
19
+ }
20
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => (req: Request) => Promise<Response>;
21
+
22
+ declare const Webhooks: ({ webhookSecret, entitlements, onPayload, ...eventHandlers }: WebhooksConfig) => (request: Request) => Promise<Response>;
23
+
24
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
package/dist/index.js ADDED
@@ -0,0 +1,358 @@
1
+ // src/checkout/checkout.ts
2
+ import { Spaire } from "@spaire/sdk";
3
+ var Checkout = ({
4
+ accessToken,
5
+ successUrl,
6
+ returnUrl,
7
+ server,
8
+ theme,
9
+ includeCheckoutId = true
10
+ }) => {
11
+ const spaire = new Spaire({
12
+ accessToken,
13
+ server
14
+ });
15
+ return async (req) => {
16
+ const url = new URL(req.url);
17
+ const products = url.searchParams.getAll("products");
18
+ if (products.length === 0) {
19
+ return new Response(
20
+ JSON.stringify({ error: "Missing products in query params" }),
21
+ {
22
+ status: 400,
23
+ headers: { "Content-Type": "application/json" }
24
+ }
25
+ );
26
+ }
27
+ const success = successUrl ? new URL(successUrl) : void 0;
28
+ if (success && includeCheckoutId) {
29
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
30
+ }
31
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
32
+ try {
33
+ const result = await spaire.checkouts.create({
34
+ products,
35
+ successUrl: success ? decodeURI(success.toString()) : void 0,
36
+ customerId: url.searchParams.get("customerId") ?? void 0,
37
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
38
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
39
+ customerName: url.searchParams.get("customerName") ?? void 0,
40
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
41
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
42
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
43
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
44
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
45
+ discountId: url.searchParams.get("discountId") ?? void 0,
46
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
47
+ seats: url.searchParams.has("seats") ? Number.parseInt(url.searchParams.get("seats") ?? "1", 10) : void 0,
48
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
49
+ });
50
+ const redirectUrl = new URL(result.url);
51
+ if (theme) {
52
+ redirectUrl.searchParams.set("theme", theme);
53
+ }
54
+ return new Response(null, {
55
+ status: 302,
56
+ headers: {
57
+ Location: redirectUrl.toString()
58
+ }
59
+ });
60
+ } catch (error) {
61
+ console.error(error);
62
+ return new Response(null, { status: 500 });
63
+ }
64
+ };
65
+ };
66
+
67
+ // src/customerPortal/customerPortal.ts
68
+ import { Spaire as Spaire2 } from "@spaire/sdk";
69
+ var CustomerPortal = ({
70
+ accessToken,
71
+ server,
72
+ getCustomerId,
73
+ returnUrl
74
+ }) => {
75
+ const spaire = new Spaire2({
76
+ accessToken,
77
+ server
78
+ });
79
+ return async (req) => {
80
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
81
+ const customerId = await getCustomerId(req);
82
+ if (!customerId) {
83
+ return new Response(JSON.stringify({ error: "customerId not defined" }), {
84
+ status: 400,
85
+ headers: { "Content-Type": "application/json" }
86
+ });
87
+ }
88
+ try {
89
+ const result = await spaire.customerSessions.create({
90
+ customerId,
91
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
92
+ });
93
+ return new Response(null, {
94
+ status: 302,
95
+ headers: {
96
+ Location: result.customerPortalUrl
97
+ }
98
+ });
99
+ } catch (error) {
100
+ console.error(error);
101
+ return new Response(null, { status: 500 });
102
+ }
103
+ };
104
+ };
105
+
106
+ // ../adapter-utils/dist/index.js
107
+ var handleWebhookPayload = async (payload, { webhookSecret, entitlements, onPayload, ...eventHandlers }) => {
108
+ const promises = [];
109
+ if (onPayload) {
110
+ promises.push(onPayload(payload));
111
+ }
112
+ switch (payload.type) {
113
+ case "checkout.created":
114
+ if (eventHandlers.onCheckoutCreated) {
115
+ promises.push(eventHandlers.onCheckoutCreated(payload));
116
+ }
117
+ break;
118
+ case "checkout.updated":
119
+ if (eventHandlers.onCheckoutUpdated) {
120
+ promises.push(eventHandlers.onCheckoutUpdated(payload));
121
+ }
122
+ break;
123
+ case "order.created":
124
+ if (eventHandlers.onOrderCreated) {
125
+ promises.push(eventHandlers.onOrderCreated(payload));
126
+ }
127
+ break;
128
+ case "order.updated":
129
+ if (eventHandlers.onOrderUpdated) {
130
+ promises.push(eventHandlers.onOrderUpdated(payload));
131
+ }
132
+ break;
133
+ case "order.paid":
134
+ if (eventHandlers.onOrderPaid) {
135
+ promises.push(eventHandlers.onOrderPaid(payload));
136
+ }
137
+ break;
138
+ case "subscription.created":
139
+ if (eventHandlers.onSubscriptionCreated) {
140
+ promises.push(eventHandlers.onSubscriptionCreated(payload));
141
+ }
142
+ break;
143
+ case "subscription.updated":
144
+ if (eventHandlers.onSubscriptionUpdated) {
145
+ promises.push(eventHandlers.onSubscriptionUpdated(payload));
146
+ }
147
+ break;
148
+ case "subscription.active":
149
+ if (eventHandlers.onSubscriptionActive) {
150
+ promises.push(eventHandlers.onSubscriptionActive(payload));
151
+ }
152
+ break;
153
+ case "subscription.canceled":
154
+ if (eventHandlers.onSubscriptionCanceled) {
155
+ promises.push(eventHandlers.onSubscriptionCanceled(payload));
156
+ }
157
+ break;
158
+ case "subscription.uncanceled":
159
+ if (eventHandlers.onSubscriptionUncanceled) {
160
+ promises.push(eventHandlers.onSubscriptionUncanceled(payload));
161
+ }
162
+ break;
163
+ case "subscription.revoked":
164
+ if (eventHandlers.onSubscriptionRevoked) {
165
+ promises.push(eventHandlers.onSubscriptionRevoked(payload));
166
+ }
167
+ break;
168
+ case "product.created":
169
+ if (eventHandlers.onProductCreated) {
170
+ promises.push(eventHandlers.onProductCreated(payload));
171
+ }
172
+ break;
173
+ case "product.updated":
174
+ if (eventHandlers.onProductUpdated) {
175
+ promises.push(eventHandlers.onProductUpdated(payload));
176
+ }
177
+ break;
178
+ case "organization.updated":
179
+ if (eventHandlers.onOrganizationUpdated) {
180
+ promises.push(eventHandlers.onOrganizationUpdated(payload));
181
+ }
182
+ break;
183
+ case "benefit.created":
184
+ if (eventHandlers.onBenefitCreated) {
185
+ promises.push(eventHandlers.onBenefitCreated(payload));
186
+ }
187
+ break;
188
+ case "benefit.updated":
189
+ if (eventHandlers.onBenefitUpdated) {
190
+ promises.push(eventHandlers.onBenefitUpdated(payload));
191
+ }
192
+ break;
193
+ case "benefit_grant.created":
194
+ if (eventHandlers.onBenefitGrantCreated) {
195
+ promises.push(eventHandlers.onBenefitGrantCreated(payload));
196
+ }
197
+ break;
198
+ case "benefit_grant.updated":
199
+ if (eventHandlers.onBenefitGrantUpdated) {
200
+ promises.push(eventHandlers.onBenefitGrantUpdated(payload));
201
+ }
202
+ break;
203
+ case "benefit_grant.revoked":
204
+ if (eventHandlers.onBenefitGrantRevoked) {
205
+ promises.push(eventHandlers.onBenefitGrantRevoked(payload));
206
+ }
207
+ break;
208
+ case "customer.created":
209
+ if (eventHandlers.onCustomerCreated) {
210
+ promises.push(eventHandlers.onCustomerCreated(payload));
211
+ }
212
+ break;
213
+ case "customer.updated":
214
+ if (eventHandlers.onCustomerUpdated) {
215
+ promises.push(eventHandlers.onCustomerUpdated(payload));
216
+ }
217
+ break;
218
+ case "customer.deleted":
219
+ if (eventHandlers.onCustomerDeleted) {
220
+ promises.push(eventHandlers.onCustomerDeleted(payload));
221
+ }
222
+ break;
223
+ case "customer.state_changed":
224
+ if (eventHandlers.onCustomerStateChanged) {
225
+ promises.push(eventHandlers.onCustomerStateChanged(payload));
226
+ }
227
+ break;
228
+ case "order.refunded":
229
+ if (eventHandlers.onOrderRefunded) {
230
+ promises.push(eventHandlers.onOrderRefunded(payload));
231
+ }
232
+ break;
233
+ case "refund.created":
234
+ if (eventHandlers.onRefundCreated) {
235
+ promises.push(eventHandlers.onRefundCreated(payload));
236
+ }
237
+ break;
238
+ case "refund.updated":
239
+ if (eventHandlers.onRefundUpdated) {
240
+ promises.push(eventHandlers.onRefundUpdated(payload));
241
+ }
242
+ break;
243
+ }
244
+ switch (payload.type) {
245
+ case "benefit_grant.created":
246
+ case "benefit_grant.revoked":
247
+ if (entitlements) {
248
+ for (const handler of entitlements.handlers) {
249
+ promises.push(handler(payload));
250
+ }
251
+ }
252
+ }
253
+ return Promise.all(promises);
254
+ };
255
+ var EntitlementStrategy = class {
256
+ grantCallbacks = [];
257
+ revokeCallbacks = [];
258
+ grant(callback) {
259
+ this.grantCallbacks.push(callback);
260
+ return this;
261
+ }
262
+ revoke(callback) {
263
+ this.revokeCallbacks.push(callback);
264
+ return this;
265
+ }
266
+ handler(slug) {
267
+ return async (payload) => {
268
+ if (payload.data.benefit.description === slug) {
269
+ switch (payload.type) {
270
+ case "benefit_grant.created":
271
+ await Promise.all(
272
+ this.grantCallbacks.map(
273
+ (callback) => callback({
274
+ customer: payload.data.customer,
275
+ properties: payload.data.properties,
276
+ payload
277
+ })
278
+ )
279
+ );
280
+ break;
281
+ case "benefit_grant.revoked":
282
+ await Promise.all(
283
+ this.revokeCallbacks.map(
284
+ (callback) => callback({
285
+ customer: payload.data.customer,
286
+ properties: payload.data.properties,
287
+ payload
288
+ })
289
+ )
290
+ );
291
+ break;
292
+ }
293
+ }
294
+ };
295
+ }
296
+ };
297
+ var Entitlements = class {
298
+ static handlers = [];
299
+ static use(slug, strategy) {
300
+ this.handlers.push(strategy.handler(slug));
301
+ return this;
302
+ }
303
+ };
304
+
305
+ // src/webhooks/webhooks.ts
306
+ import {
307
+ WebhookVerificationError,
308
+ validateEvent
309
+ } from "@spaire/sdk/webhooks";
310
+ var Webhooks = ({
311
+ webhookSecret,
312
+ entitlements,
313
+ onPayload,
314
+ ...eventHandlers
315
+ }) => {
316
+ return async (request) => {
317
+ const requestBody = await request.text();
318
+ const webhookHeaders = {
319
+ "webhook-id": request.headers.get("webhook-id") ?? "",
320
+ "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
321
+ "webhook-signature": request.headers.get("webhook-signature") ?? ""
322
+ };
323
+ let webhookPayload;
324
+ try {
325
+ webhookPayload = validateEvent(
326
+ requestBody,
327
+ webhookHeaders,
328
+ webhookSecret
329
+ );
330
+ } catch (error) {
331
+ if (error instanceof WebhookVerificationError) {
332
+ return new Response(JSON.stringify({ received: false }), {
333
+ status: 403,
334
+ headers: { "Content-Type": "application/json" }
335
+ });
336
+ }
337
+ throw error;
338
+ }
339
+ await handleWebhookPayload(webhookPayload, {
340
+ webhookSecret,
341
+ entitlements,
342
+ onPayload,
343
+ ...eventHandlers
344
+ });
345
+ return new Response(JSON.stringify({ received: true }), {
346
+ status: 200,
347
+ headers: { "Content-Type": "application/json" }
348
+ });
349
+ };
350
+ };
351
+ export {
352
+ Checkout,
353
+ CustomerPortal,
354
+ EntitlementStrategy,
355
+ Entitlements,
356
+ Webhooks
357
+ };
358
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/checkout/checkout.ts","../src/customerPortal/customerPortal.ts","../../adapter-utils/dist/index.js","../src/webhooks/webhooks.ts"],"sourcesContent":["import { Spaire } from \"@spaire/sdk\";\n\nexport interface CheckoutConfig {\n\taccessToken?: string;\n\tsuccessUrl?: string;\n\treturnUrl?: string;\n\tincludeCheckoutId?: boolean;\n\tserver?: \"sandbox\" | \"production\";\n\ttheme?: \"light\" | \"dark\";\n}\n\nexport const Checkout = ({\n\taccessToken,\n\tsuccessUrl,\n\treturnUrl,\n\tserver,\n\ttheme,\n\tincludeCheckoutId = true,\n}: CheckoutConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\treturn async (req: Request) => {\n\t\tconst url = new URL(req.url);\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn new Response(\n\t\t\t\tJSON.stringify({ error: \"Missing products in query params\" }),\n\t\t\t\t{\n\t\t\t\t\tstatus: 400,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst success = successUrl ? new URL(successUrl) : undefined;\n\n\t\tif (success && includeCheckoutId) {\n\t\t\tsuccess.searchParams.set(\"checkoutId\", \"{CHECKOUT_ID}\");\n\t\t}\n\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\ttry {\n\t\t\tconst result = await spaire.checkouts.create({\n\t\t\t\tproducts,\n\t\t\t\tsuccessUrl: success ? decodeURI(success.toString()) : undefined,\n\t\t\t\tcustomerId: url.searchParams.get(\"customerId\") ?? undefined,\n\t\t\t\texternalCustomerId:\n\t\t\t\t\turl.searchParams.get(\"customerExternalId\") ?? undefined,\n\t\t\t\tcustomerEmail: url.searchParams.get(\"customerEmail\") ?? undefined,\n\t\t\t\tcustomerName: url.searchParams.get(\"customerName\") ?? undefined,\n\t\t\t\tcustomerBillingAddress: url.searchParams.has(\"customerBillingAddress\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerBillingAddress\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tcustomerTaxId: url.searchParams.get(\"customerTaxId\") ?? undefined,\n\t\t\t\tcustomerIpAddress:\n\t\t\t\t\turl.searchParams.get(\"customerIpAddress\") ?? undefined,\n\t\t\t\tcustomerMetadata: url.searchParams.has(\"customerMetadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"customerMetadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tallowDiscountCodes: url.searchParams.has(\"allowDiscountCodes\")\n\t\t\t\t\t? url.searchParams.get(\"allowDiscountCodes\") === \"true\"\n\t\t\t\t\t: undefined,\n\t\t\t\tdiscountId: url.searchParams.get(\"discountId\") ?? undefined,\n\t\t\t\tmetadata: url.searchParams.has(\"metadata\")\n\t\t\t\t\t? JSON.parse(url.searchParams.get(\"metadata\") ?? \"{}\")\n\t\t\t\t\t: undefined,\n\t\t\t\tseats: url.searchParams.has(\"seats\")\n\t\t\t\t\t? Number.parseInt(url.searchParams.get(\"seats\") ?? \"1\", 10)\n\t\t\t\t\t: undefined,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\tconst redirectUrl = new URL(result.url);\n\n\t\t\tif (theme) {\n\t\t\t\tredirectUrl.searchParams.set(\"theme\", theme);\n\t\t\t}\n\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 302,\n\t\t\t\theaders: {\n\t\t\t\t\tLocation: redirectUrl.toString(),\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn new Response(null, { status: 500 });\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\n\nexport interface CustomerPortalConfig {\n\taccessToken: string;\n\tgetCustomerId: (req: Request) => Promise<string>;\n\tserver: \"sandbox\" | \"production\";\n\treturnUrl?: string;\n}\n\nexport const CustomerPortal = ({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig) => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\treturn async (req: Request) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\tconst customerId = await getCustomerId(req);\n\n\t\tif (!customerId) {\n\t\t\treturn new Response(JSON.stringify({ error: \"customerId not defined\" }), {\n\t\t\t\tstatus: 400,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await spaire.customerSessions.create({\n\t\t\t\tcustomerId,\n\t\t\t\treturnUrl: retUrl ? decodeURI(retUrl.toString()) : undefined,\n\t\t\t});\n\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 302,\n\t\t\t\theaders: {\n\t\t\t\t\tLocation: result.customerPortalUrl,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn new Response(null, { status: 500 });\n\t\t}\n\t};\n};\n","// src/webhooks/webhooks.ts\nvar handleWebhookPayload = async (payload, { webhookSecret, entitlements, onPayload, ...eventHandlers }) => {\n const promises = [];\n if (onPayload) {\n promises.push(onPayload(payload));\n }\n switch (payload.type) {\n case \"checkout.created\":\n if (eventHandlers.onCheckoutCreated) {\n promises.push(eventHandlers.onCheckoutCreated(payload));\n }\n break;\n case \"checkout.updated\":\n if (eventHandlers.onCheckoutUpdated) {\n promises.push(eventHandlers.onCheckoutUpdated(payload));\n }\n break;\n case \"order.created\":\n if (eventHandlers.onOrderCreated) {\n promises.push(eventHandlers.onOrderCreated(payload));\n }\n break;\n case \"order.updated\":\n if (eventHandlers.onOrderUpdated) {\n promises.push(eventHandlers.onOrderUpdated(payload));\n }\n break;\n case \"order.paid\":\n if (eventHandlers.onOrderPaid) {\n promises.push(eventHandlers.onOrderPaid(payload));\n }\n break;\n case \"subscription.created\":\n if (eventHandlers.onSubscriptionCreated) {\n promises.push(eventHandlers.onSubscriptionCreated(payload));\n }\n break;\n case \"subscription.updated\":\n if (eventHandlers.onSubscriptionUpdated) {\n promises.push(eventHandlers.onSubscriptionUpdated(payload));\n }\n break;\n case \"subscription.active\":\n if (eventHandlers.onSubscriptionActive) {\n promises.push(eventHandlers.onSubscriptionActive(payload));\n }\n break;\n case \"subscription.canceled\":\n if (eventHandlers.onSubscriptionCanceled) {\n promises.push(eventHandlers.onSubscriptionCanceled(payload));\n }\n break;\n case \"subscription.uncanceled\":\n if (eventHandlers.onSubscriptionUncanceled) {\n promises.push(eventHandlers.onSubscriptionUncanceled(payload));\n }\n break;\n case \"subscription.revoked\":\n if (eventHandlers.onSubscriptionRevoked) {\n promises.push(eventHandlers.onSubscriptionRevoked(payload));\n }\n break;\n case \"product.created\":\n if (eventHandlers.onProductCreated) {\n promises.push(eventHandlers.onProductCreated(payload));\n }\n break;\n case \"product.updated\":\n if (eventHandlers.onProductUpdated) {\n promises.push(eventHandlers.onProductUpdated(payload));\n }\n break;\n case \"organization.updated\":\n if (eventHandlers.onOrganizationUpdated) {\n promises.push(eventHandlers.onOrganizationUpdated(payload));\n }\n break;\n case \"benefit.created\":\n if (eventHandlers.onBenefitCreated) {\n promises.push(eventHandlers.onBenefitCreated(payload));\n }\n break;\n case \"benefit.updated\":\n if (eventHandlers.onBenefitUpdated) {\n promises.push(eventHandlers.onBenefitUpdated(payload));\n }\n break;\n case \"benefit_grant.created\":\n if (eventHandlers.onBenefitGrantCreated) {\n promises.push(eventHandlers.onBenefitGrantCreated(payload));\n }\n break;\n case \"benefit_grant.updated\":\n if (eventHandlers.onBenefitGrantUpdated) {\n promises.push(eventHandlers.onBenefitGrantUpdated(payload));\n }\n break;\n case \"benefit_grant.revoked\":\n if (eventHandlers.onBenefitGrantRevoked) {\n promises.push(eventHandlers.onBenefitGrantRevoked(payload));\n }\n break;\n case \"customer.created\":\n if (eventHandlers.onCustomerCreated) {\n promises.push(eventHandlers.onCustomerCreated(payload));\n }\n break;\n case \"customer.updated\":\n if (eventHandlers.onCustomerUpdated) {\n promises.push(eventHandlers.onCustomerUpdated(payload));\n }\n break;\n case \"customer.deleted\":\n if (eventHandlers.onCustomerDeleted) {\n promises.push(eventHandlers.onCustomerDeleted(payload));\n }\n break;\n case \"customer.state_changed\":\n if (eventHandlers.onCustomerStateChanged) {\n promises.push(eventHandlers.onCustomerStateChanged(payload));\n }\n break;\n case \"order.refunded\":\n if (eventHandlers.onOrderRefunded) {\n promises.push(eventHandlers.onOrderRefunded(payload));\n }\n break;\n case \"refund.created\":\n if (eventHandlers.onRefundCreated) {\n promises.push(eventHandlers.onRefundCreated(payload));\n }\n break;\n case \"refund.updated\":\n if (eventHandlers.onRefundUpdated) {\n promises.push(eventHandlers.onRefundUpdated(payload));\n }\n break;\n }\n switch (payload.type) {\n case \"benefit_grant.created\":\n case \"benefit_grant.revoked\":\n if (entitlements) {\n for (const handler of entitlements.handlers) {\n promises.push(handler(payload));\n }\n }\n }\n return Promise.all(promises);\n};\n\n// src/entitlement/entitlement.ts\nvar EntitlementStrategy = class {\n grantCallbacks = [];\n revokeCallbacks = [];\n grant(callback) {\n this.grantCallbacks.push(callback);\n return this;\n }\n revoke(callback) {\n this.revokeCallbacks.push(callback);\n return this;\n }\n handler(slug) {\n return async (payload) => {\n if (payload.data.benefit.description === slug) {\n switch (payload.type) {\n case \"benefit_grant.created\":\n await Promise.all(\n this.grantCallbacks.map(\n (callback) => callback({\n customer: payload.data.customer,\n properties: payload.data.properties,\n payload\n })\n )\n );\n break;\n case \"benefit_grant.revoked\":\n await Promise.all(\n this.revokeCallbacks.map(\n (callback) => callback({\n customer: payload.data.customer,\n properties: payload.data.properties,\n payload\n })\n )\n );\n break;\n }\n }\n };\n }\n};\nvar Entitlements = class {\n static handlers = [];\n static use(slug, strategy) {\n this.handlers.push(strategy.handler(slug));\n return this;\n }\n};\nexport {\n EntitlementStrategy,\n Entitlements,\n handleWebhookPayload\n};\n","import {\n\ttype WebhooksConfig,\n\thandleWebhookPayload,\n} from \"@spaire/adapter-utils\";\nimport {\n\tWebhookVerificationError,\n\tvalidateEvent,\n} from \"@spaire/sdk/webhooks\";\n\nexport {\n\ttype EntitlementContext,\n\ttype EntitlementHandler,\n\ttype EntitlementProperties,\n\tEntitlementStrategy,\n\tEntitlements,\n} from \"@spaire/adapter-utils\";\n\nexport const Webhooks = ({\n\twebhookSecret,\n\tentitlements,\n\tonPayload,\n\t...eventHandlers\n}: WebhooksConfig) => {\n\treturn async (request: Request) => {\n\t\tconst requestBody = await request.text();\n\n\t\tconst webhookHeaders = {\n\t\t\t\"webhook-id\": request.headers.get(\"webhook-id\") ?? \"\",\n\t\t\t\"webhook-timestamp\": request.headers.get(\"webhook-timestamp\") ?? \"\",\n\t\t\t\"webhook-signature\": request.headers.get(\"webhook-signature\") ?? \"\",\n\t\t};\n\n\t\tlet webhookPayload: ReturnType<typeof validateEvent>;\n\t\ttry {\n\t\t\twebhookPayload = validateEvent(\n\t\t\t\trequestBody,\n\t\t\t\twebhookHeaders,\n\t\t\t\twebhookSecret,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn new Response(JSON.stringify({ received: false }), {\n\t\t\t\t\tstatus: 403,\n\t\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\n\t\tawait handleWebhookPayload(webhookPayload, {\n\t\t\twebhookSecret,\n\t\t\tentitlements,\n\t\t\tonPayload,\n\t\t\t...eventHandlers,\n\t\t});\n\n\t\treturn new Response(JSON.stringify({ received: true }), {\n\t\t\tstatus: 200,\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t});\n\t};\n};\n"],"mappings":"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","names":["Spaire"]}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@spaire/supabase",
3
+ "version": "1.0.1",
4
+ "main": "./dist/index.cjs",
5
+ "module": "./dist/index.js",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ "import": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
11
+ },
12
+ "require": {
13
+ "types": "./dist/index.d.cts",
14
+ "require": "./dist/index.cjs"
15
+ }
16
+ },
17
+ "type": "module",
18
+ "engines": {
19
+ "node": ">=16"
20
+ },
21
+ "scripts": {
22
+ "build": "tsup ./src/index.ts --format esm,cjs --dts --clean --sourcemap",
23
+ "dev": "tsc --watch",
24
+ "check": "biome check --write ./src",
25
+ "test": "vitest",
26
+ "test:watch": "vitest --watch",
27
+ "test:coverage": "vitest --coverage"
28
+ },
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "dependencies": {
33
+ "@spaire/sdk": "^0.45.1"
34
+ },
35
+ "devDependencies": {
36
+ "@biomejs/biome": "1.9.4",
37
+ "@spaire/adapter-utils": "workspace:*",
38
+ "@sindresorhus/tsconfig": "^7.0.0",
39
+ "tsup": "^8.3.5",
40
+ "vitest": "^3.2.4"
41
+ }
42
+ }