@spaire/elysia 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @spaire/elysia
2
+
3
+ Payments and Checkouts made dead simple with Elysia.
4
+
5
+ `pnpm install @spaire/elysia zod`
6
+
7
+ ## Checkout
8
+
9
+ Create a Checkout handler which takes care of redirections.
10
+
11
+ ```typescript
12
+ import { Elysia } from "elysia";
13
+ import { Checkout } from "@spaire/elysia";
14
+
15
+ const app = new Elysia();
16
+
17
+ app.get(
18
+ "/checkout",
19
+ Checkout({
20
+ accessToken: "xxx", // Or set an environment variable to SPAIRE_ACCESS_TOKEN
21
+ successUrl: process.env.SUCCESS_URL,
22
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Checkout
23
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
24
+ theme: "dark" // Enforces the theme - System-preferred theme will be set if left omitted
25
+ }),
26
+ );
27
+ ```
28
+
29
+ ### Query Params
30
+
31
+ Pass query params to this route.
32
+
33
+ - products `?products=123`
34
+ - customerId (optional) `?products=123&customerId=xxx`
35
+ - customerExternalId (optional) `?products=123&customerExternalId=xxx`
36
+ - customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
37
+ - customerName (optional) `?products=123&customerName=Jane`
38
+ - seats (optional) `?products=123&seats=5` - Number of seats for seat-based products
39
+ - metadata (optional) `URL-Encoded JSON string`
40
+
41
+ ## Customer Portal
42
+
43
+ Create a customer portal where your customer can view orders and subscriptions.
44
+
45
+ ```typescript
46
+ import { Elysia } from "elysia";
47
+ import { CustomerPortal } from "@spaire/elysia";
48
+
49
+ const app = new Elysia();
50
+
51
+ app.get(
52
+ "/portal",
53
+ CustomerPortal({
54
+ accessToken: "xxx", // Or set an environment variable to SPAIRE_ACCESS_TOKEN
55
+ getCustomerId: (event) => "", // Fuction to resolve a Spaire Customer ID
56
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Customer Portal
57
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
58
+ }),
59
+ );
60
+ ```
61
+
62
+ ## Webhooks
63
+
64
+ A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
65
+
66
+ ```typescript
67
+ import { Elysia } from 'elysia'
68
+ import { Webhooks } from "@spaire/elysia";
69
+
70
+ const app = new Elysia()
71
+
72
+ app.post('/spaire/webhooks', Webhooks({
73
+ webhookSecret: process.env.SPAIRE_WEBHOOK_SECRET!,
74
+ onPayload: async (payload) => /** Handle payload */,
75
+ }))
76
+ ```
77
+
78
+ #### Payload Handlers
79
+
80
+ The Webhook handler also supports granular handlers for easy integration.
81
+
82
+ - onCheckoutCreated: (payload) =>
83
+ - onCheckoutUpdated: (payload) =>
84
+ - onOrderCreated: (payload) =>
85
+ - onOrderUpdated: (payload) =>
86
+ - onOrderPaid: (payload) =>
87
+ - onSubscriptionCreated: (payload) =>
88
+ - onSubscriptionUpdated: (payload) =>
89
+ - onSubscriptionActive: (payload) =>
90
+ - onSubscriptionCanceled: (payload) =>
91
+ - onSubscriptionRevoked: (payload) =>
92
+ - onProductCreated: (payload) =>
93
+ - onProductUpdated: (payload) =>
94
+ - onOrganizationUpdated: (payload) =>
95
+ - onBenefitCreated: (payload) =>
96
+ - onBenefitUpdated: (payload) =>
97
+ - onBenefitGrantCreated: (payload) =>
98
+ - onBenefitGrantUpdated: (payload) =>
99
+ - onBenefitGrantRevoked: (payload) =>
100
+ - onCustomerCreated: (payload) =>
101
+ - onCustomerUpdated: (payload) =>
102
+ - onCustomerDeleted: (payload) =>
103
+ - onCustomerStateChanged: (payload) =>
package/dist/index.cjs ADDED
@@ -0,0 +1,170 @@
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: () => import_adapter_utils2.EntitlementStrategy,
26
+ Entitlements: () => import_adapter_utils2.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 import_elysia = require("elysia");
34
+ var Checkout = ({
35
+ accessToken,
36
+ successUrl,
37
+ returnUrl,
38
+ server,
39
+ theme,
40
+ includeCheckoutId = true
41
+ }) => {
42
+ const spaire = new import_sdk.Spaire({
43
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
44
+ server
45
+ });
46
+ return async (ctx) => {
47
+ const url = new URL(ctx.request.url);
48
+ const products = url.searchParams.getAll("products");
49
+ if (products.length === 0) {
50
+ return (0, import_elysia.status)(400, {
51
+ error: "Missing products in query params"
52
+ });
53
+ }
54
+ const success = successUrl ? new URL(successUrl) : void 0;
55
+ if (success && includeCheckoutId) {
56
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
57
+ }
58
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
59
+ try {
60
+ const result = await spaire.checkouts.create({
61
+ products,
62
+ successUrl: success ? decodeURI(success.toString()) : void 0,
63
+ customerId: url.searchParams.get("customerId") ?? void 0,
64
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
65
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
66
+ customerName: url.searchParams.get("customerName") ?? void 0,
67
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
68
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
69
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
70
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
71
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
72
+ discountId: url.searchParams.get("discountId") ?? void 0,
73
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
74
+ seats: url.searchParams.has("seats") ? Number.parseInt(url.searchParams.get("seats") ?? "1", 10) : void 0,
75
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
76
+ });
77
+ const redirectUrl = new URL(result.url);
78
+ if (theme) {
79
+ redirectUrl.searchParams.set("theme", theme);
80
+ }
81
+ return ctx.redirect(redirectUrl.toString());
82
+ } catch (error) {
83
+ console.error(error);
84
+ return { error: "Internal server error" };
85
+ }
86
+ };
87
+ };
88
+
89
+ // src/customerPortal/customerPortal.ts
90
+ var import_sdk2 = require("@spaire/sdk");
91
+ var import_elysia2 = require("elysia");
92
+ var CustomerPortal = ({
93
+ accessToken,
94
+ server,
95
+ getCustomerId,
96
+ returnUrl
97
+ }) => {
98
+ const spaire = new import_sdk2.Spaire({
99
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
100
+ server
101
+ });
102
+ return async (ctx) => {
103
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
104
+ const customerId = await getCustomerId(ctx.request);
105
+ if (!customerId) {
106
+ return (0, import_elysia2.status)(400, { error: "customerId not defined" });
107
+ }
108
+ try {
109
+ const result = await spaire.customerSessions.create({
110
+ customerId,
111
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
112
+ });
113
+ return ctx.redirect(result.customerPortalUrl);
114
+ } catch (error) {
115
+ console.error(error);
116
+ return (0, import_elysia2.status)(500, { error: "Internal server error" });
117
+ }
118
+ };
119
+ };
120
+
121
+ // src/webhooks/webhooks.ts
122
+ var import_adapter_utils = require("@spaire/adapter-utils");
123
+ var import_webhooks = require("@spaire/sdk/webhooks");
124
+ var import_elysia3 = require("elysia");
125
+ var import_adapter_utils2 = require("@spaire/adapter-utils");
126
+ var Webhooks = ({
127
+ webhookSecret,
128
+ onPayload,
129
+ entitlements,
130
+ ...eventHandlers
131
+ }) => {
132
+ return async (ctx) => {
133
+ const requestBody = await ctx.request.text();
134
+ const webhookHeaders = {
135
+ "webhook-id": ctx.request.headers.get("webhook-id") ?? "",
136
+ "webhook-timestamp": ctx.request.headers.get("webhook-timestamp") ?? "",
137
+ "webhook-signature": ctx.request.headers.get("webhook-signature") ?? ""
138
+ };
139
+ let webhookPayload;
140
+ try {
141
+ webhookPayload = (0, import_webhooks.validateEvent)(
142
+ requestBody,
143
+ webhookHeaders,
144
+ webhookSecret
145
+ );
146
+ } catch (error) {
147
+ console.log(error);
148
+ if (error instanceof import_webhooks.WebhookVerificationError) {
149
+ return (0, import_elysia3.status)(400, { received: false });
150
+ }
151
+ return (0, import_elysia3.status)(500, { error: "Internal server error" });
152
+ }
153
+ await (0, import_adapter_utils.handleWebhookPayload)(webhookPayload, {
154
+ webhookSecret,
155
+ entitlements,
156
+ onPayload,
157
+ ...eventHandlers
158
+ });
159
+ return { received: true };
160
+ };
161
+ };
162
+ // Annotate the CommonJS export names for ESM import in node:
163
+ 0 && (module.exports = {
164
+ Checkout,
165
+ CustomerPortal,
166
+ EntitlementStrategy,
167
+ Entitlements,
168
+ Webhooks
169
+ });
170
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/checkout/checkout.ts","../src/customerPortal/customerPortal.ts","../src/webhooks/webhooks.ts"],"sourcesContent":["export * from \"./checkout/checkout\";\nexport * from \"./customerPortal/customerPortal\";\nexport * from \"./webhooks/webhooks\";\n","import { Spaire } from \"@spaire/sdk\";\nimport { type Context, status } from \"elysia\";\nimport type { InlineHandler } from \"elysia/types\";\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): InlineHandler => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (ctx: Context) => {\n\t\tconst url = new URL(ctx.request.url);\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn status(400, {\n\t\t\t\terror: \"Missing products in query params\",\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 ctx.redirect(redirectUrl.toString());\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn { error: \"Internal server error\" };\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\nimport { type Context, status } from \"elysia\";\nimport type { InlineHandler } from \"elysia/types\";\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): InlineHandler => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (ctx: Context) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\tconst customerId = await getCustomerId(ctx.request);\n\n\t\tif (!customerId) {\n\t\t\treturn status(400, { error: \"customerId not defined\" });\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 ctx.redirect(result.customerPortalUrl);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn status(500, { error: \"Internal server error\" });\n\t\t}\n\t};\n};\n","import {\n\ttype WebhooksConfig,\n\thandleWebhookPayload,\n} from \"@spaire/adapter-utils\";\nimport { WebhookVerificationError, validateEvent } from \"@spaire/sdk/webhooks\";\nimport { type Context, status } from \"elysia\";\nimport type { InlineHandler } from \"elysia/types\";\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\tonPayload,\n\tentitlements,\n\t...eventHandlers\n}: WebhooksConfig): InlineHandler => {\n\treturn async (ctx: Context) => {\n\t\tconst requestBody = await ctx.request.text();\n\n\t\tconst webhookHeaders: Record<string, string> = {\n\t\t\t\"webhook-id\": ctx.request.headers.get(\"webhook-id\") ?? \"\",\n\t\t\t\"webhook-timestamp\": ctx.request.headers.get(\"webhook-timestamp\") ?? \"\",\n\t\t\t\"webhook-signature\": ctx.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\tconsole.log(error);\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn status(400, { received: false });\n\t\t\t}\n\n\t\t\treturn status(500, { error: \"Internal server 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 { received: true };\n\t};\n};\n"],"mappings":"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","names":["import_sdk","import_elysia","import_elysia","import_adapter_utils"]}
@@ -0,0 +1,25 @@
1
+ import { InlineHandler } from 'elysia/types';
2
+ import { WebhooksConfig } from '@spaire/adapter-utils';
3
+ export { EntitlementContext, EntitlementHandler, EntitlementProperties, EntitlementStrategy, Entitlements } from '@spaire/adapter-utils';
4
+
5
+ interface CheckoutConfig {
6
+ accessToken?: string;
7
+ successUrl?: string;
8
+ returnUrl?: string;
9
+ includeCheckoutId?: boolean;
10
+ server?: "sandbox" | "production";
11
+ theme?: "light" | "dark";
12
+ }
13
+ declare const Checkout: ({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => InlineHandler;
14
+
15
+ interface CustomerPortalConfig {
16
+ accessToken?: string;
17
+ getCustomerId: (req: Request) => Promise<string>;
18
+ server?: "sandbox" | "production";
19
+ returnUrl?: string;
20
+ }
21
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => InlineHandler;
22
+
23
+ declare const Webhooks: ({ webhookSecret, onPayload, entitlements, ...eventHandlers }: WebhooksConfig) => InlineHandler;
24
+
25
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
@@ -0,0 +1,25 @@
1
+ import { InlineHandler } from 'elysia/types';
2
+ import { WebhooksConfig } from '@spaire/adapter-utils';
3
+ export { EntitlementContext, EntitlementHandler, EntitlementProperties, EntitlementStrategy, Entitlements } from '@spaire/adapter-utils';
4
+
5
+ interface CheckoutConfig {
6
+ accessToken?: string;
7
+ successUrl?: string;
8
+ returnUrl?: string;
9
+ includeCheckoutId?: boolean;
10
+ server?: "sandbox" | "production";
11
+ theme?: "light" | "dark";
12
+ }
13
+ declare const Checkout: ({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => InlineHandler;
14
+
15
+ interface CustomerPortalConfig {
16
+ accessToken?: string;
17
+ getCustomerId: (req: Request) => Promise<string>;
18
+ server?: "sandbox" | "production";
19
+ returnUrl?: string;
20
+ }
21
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => InlineHandler;
22
+
23
+ declare const Webhooks: ({ webhookSecret, onPayload, entitlements, ...eventHandlers }: WebhooksConfig) => InlineHandler;
24
+
25
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
package/dist/index.js ADDED
@@ -0,0 +1,144 @@
1
+ // src/checkout/checkout.ts
2
+ import { Spaire } from "@spaire/sdk";
3
+ import { status } from "elysia";
4
+ var Checkout = ({
5
+ accessToken,
6
+ successUrl,
7
+ returnUrl,
8
+ server,
9
+ theme,
10
+ includeCheckoutId = true
11
+ }) => {
12
+ const spaire = new Spaire({
13
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
14
+ server
15
+ });
16
+ return async (ctx) => {
17
+ const url = new URL(ctx.request.url);
18
+ const products = url.searchParams.getAll("products");
19
+ if (products.length === 0) {
20
+ return status(400, {
21
+ error: "Missing products in query params"
22
+ });
23
+ }
24
+ const success = successUrl ? new URL(successUrl) : void 0;
25
+ if (success && includeCheckoutId) {
26
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
27
+ }
28
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
29
+ try {
30
+ const result = await spaire.checkouts.create({
31
+ products,
32
+ successUrl: success ? decodeURI(success.toString()) : void 0,
33
+ customerId: url.searchParams.get("customerId") ?? void 0,
34
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
35
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
36
+ customerName: url.searchParams.get("customerName") ?? void 0,
37
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
38
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
39
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
40
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
41
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
42
+ discountId: url.searchParams.get("discountId") ?? void 0,
43
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
44
+ seats: url.searchParams.has("seats") ? Number.parseInt(url.searchParams.get("seats") ?? "1", 10) : void 0,
45
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
46
+ });
47
+ const redirectUrl = new URL(result.url);
48
+ if (theme) {
49
+ redirectUrl.searchParams.set("theme", theme);
50
+ }
51
+ return ctx.redirect(redirectUrl.toString());
52
+ } catch (error) {
53
+ console.error(error);
54
+ return { error: "Internal server error" };
55
+ }
56
+ };
57
+ };
58
+
59
+ // src/customerPortal/customerPortal.ts
60
+ import { Spaire as Spaire2 } from "@spaire/sdk";
61
+ import { status as status2 } from "elysia";
62
+ var CustomerPortal = ({
63
+ accessToken,
64
+ server,
65
+ getCustomerId,
66
+ returnUrl
67
+ }) => {
68
+ const spaire = new Spaire2({
69
+ accessToken: accessToken ?? process.env["SPAIRE_ACCESS_TOKEN"],
70
+ server
71
+ });
72
+ return async (ctx) => {
73
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
74
+ const customerId = await getCustomerId(ctx.request);
75
+ if (!customerId) {
76
+ return status2(400, { error: "customerId not defined" });
77
+ }
78
+ try {
79
+ const result = await spaire.customerSessions.create({
80
+ customerId,
81
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
82
+ });
83
+ return ctx.redirect(result.customerPortalUrl);
84
+ } catch (error) {
85
+ console.error(error);
86
+ return status2(500, { error: "Internal server error" });
87
+ }
88
+ };
89
+ };
90
+
91
+ // src/webhooks/webhooks.ts
92
+ import {
93
+ handleWebhookPayload
94
+ } from "@spaire/adapter-utils";
95
+ import { WebhookVerificationError, validateEvent } from "@spaire/sdk/webhooks";
96
+ import { status as status3 } from "elysia";
97
+ import {
98
+ EntitlementStrategy,
99
+ Entitlements
100
+ } from "@spaire/adapter-utils";
101
+ var Webhooks = ({
102
+ webhookSecret,
103
+ onPayload,
104
+ entitlements,
105
+ ...eventHandlers
106
+ }) => {
107
+ return async (ctx) => {
108
+ const requestBody = await ctx.request.text();
109
+ const webhookHeaders = {
110
+ "webhook-id": ctx.request.headers.get("webhook-id") ?? "",
111
+ "webhook-timestamp": ctx.request.headers.get("webhook-timestamp") ?? "",
112
+ "webhook-signature": ctx.request.headers.get("webhook-signature") ?? ""
113
+ };
114
+ let webhookPayload;
115
+ try {
116
+ webhookPayload = validateEvent(
117
+ requestBody,
118
+ webhookHeaders,
119
+ webhookSecret
120
+ );
121
+ } catch (error) {
122
+ console.log(error);
123
+ if (error instanceof WebhookVerificationError) {
124
+ return status3(400, { received: false });
125
+ }
126
+ return status3(500, { error: "Internal server error" });
127
+ }
128
+ await handleWebhookPayload(webhookPayload, {
129
+ webhookSecret,
130
+ entitlements,
131
+ onPayload,
132
+ ...eventHandlers
133
+ });
134
+ return { received: true };
135
+ };
136
+ };
137
+ export {
138
+ Checkout,
139
+ CustomerPortal,
140
+ EntitlementStrategy,
141
+ Entitlements,
142
+ Webhooks
143
+ };
144
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/checkout/checkout.ts","../src/customerPortal/customerPortal.ts","../src/webhooks/webhooks.ts"],"sourcesContent":["import { Spaire } from \"@spaire/sdk\";\nimport { type Context, status } from \"elysia\";\nimport type { InlineHandler } from \"elysia/types\";\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): InlineHandler => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (ctx: Context) => {\n\t\tconst url = new URL(ctx.request.url);\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn status(400, {\n\t\t\t\terror: \"Missing products in query params\",\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 ctx.redirect(redirectUrl.toString());\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn { error: \"Internal server error\" };\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\nimport { type Context, status } from \"elysia\";\nimport type { InlineHandler } from \"elysia/types\";\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): InlineHandler => {\n\tconst spaire = new Spaire({\n\t\taccessToken: accessToken ?? process.env[\"SPAIRE_ACCESS_TOKEN\"],\n\t\tserver,\n\t});\n\n\treturn async (ctx: Context) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\n\n\t\tconst customerId = await getCustomerId(ctx.request);\n\n\t\tif (!customerId) {\n\t\t\treturn status(400, { error: \"customerId not defined\" });\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 ctx.redirect(result.customerPortalUrl);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn status(500, { error: \"Internal server error\" });\n\t\t}\n\t};\n};\n","import {\n\ttype WebhooksConfig,\n\thandleWebhookPayload,\n} from \"@spaire/adapter-utils\";\nimport { WebhookVerificationError, validateEvent } from \"@spaire/sdk/webhooks\";\nimport { type Context, status } from \"elysia\";\nimport type { InlineHandler } from \"elysia/types\";\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\tonPayload,\n\tentitlements,\n\t...eventHandlers\n}: WebhooksConfig): InlineHandler => {\n\treturn async (ctx: Context) => {\n\t\tconst requestBody = await ctx.request.text();\n\n\t\tconst webhookHeaders: Record<string, string> = {\n\t\t\t\"webhook-id\": ctx.request.headers.get(\"webhook-id\") ?? \"\",\n\t\t\t\"webhook-timestamp\": ctx.request.headers.get(\"webhook-timestamp\") ?? \"\",\n\t\t\t\"webhook-signature\": ctx.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\tconsole.log(error);\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn status(400, { received: false });\n\t\t\t}\n\n\t\t\treturn status(500, { error: \"Internal server 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 { received: true };\n\t};\n};\n"],"mappings":"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","names":["Spaire","status","status"]}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@spaire/elysia",
3
+ "version": "2.0.0",
4
+ "description": "Spaire integration for Elysia",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ "import": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "require": {
14
+ "types": "./dist/index.d.cts",
15
+ "require": "./dist/index.cjs"
16
+ }
17
+ },
18
+ "engines": {
19
+ "node": ">=18"
20
+ },
21
+ "type": "module",
22
+ "scripts": {
23
+ "test": "vitest",
24
+ "build": "tsup ./src/index.ts --format esm,cjs --dts --clean --sourcemap",
25
+ "dev": "tsc --watch",
26
+ "check": "biome check --write ./src"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "keywords": [
32
+ "spaire",
33
+ "elysia",
34
+ "payments",
35
+ "subscriptions"
36
+ ],
37
+ "devDependencies": {
38
+ "@biomejs/biome": "1.9.4",
39
+ "@sindresorhus/tsconfig": "^7.0.0",
40
+ "@types/node": "^20.0.0",
41
+ "elysia": "^1.4.18",
42
+ "memoirist": "^0.4.0",
43
+ "prettier": "^3.7.4",
44
+ "tsup": "^8.5.1",
45
+ "vitest": "^2.1.8"
46
+ },
47
+ "dependencies": {
48
+ "@spaire/adapter-utils": "^2.0.0",
49
+ "@spaire/sdk": "^0.45.1"
50
+ },
51
+ "peerDependencies": {
52
+ "elysia": "^1.2.10"
53
+ },
54
+ "publishConfig": {
55
+ "access": "public"
56
+ }
57
+ }