@spaire/astro 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,91 @@
1
+ # @spaire/astro
2
+
3
+ Payments and Checkouts made dead simple with Astro.
4
+
5
+ `pnpm install @spaire/astro`
6
+
7
+ ## Checkout
8
+
9
+ Create a Checkout handler which takes care of redirections.
10
+
11
+ ```typescript
12
+ import { Checkout } from "@spaire/astro";
13
+ import { SPAIRE_ACCESS_TOKEN, SPAIRE_SUCCESS_URL } from "astro:env/server";
14
+
15
+ export const GET = Checkout({
16
+ accessToken: SPAIRE_ACCESS_TOKEN,
17
+ successUrl: SPAIRE_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
+
24
+ ### Query Params
25
+
26
+ Pass query params to this route.
27
+
28
+ - products `?products=123`
29
+ - customerId (optional) `?products=123&customerId=xxx`
30
+ - customerExternalId (optional) `?products=123&customerExternalId=xxx`
31
+ - customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
32
+ - customerName (optional) `?products=123&customerName=Jane`
33
+ - seats (optional) `?products=123&seats=5` - Number of seats for seat-based products
34
+ - metadata (optional) `URL-Encoded JSON string`
35
+
36
+ ## Customer Portal
37
+
38
+ Create a customer portal where your customer can view orders and subscriptions.
39
+
40
+ ```typescript
41
+ import { CustomerPortal } from "@spaire/astro";
42
+ import { SPAIRE_ACCESS_TOKEN } from "astro:env/server";
43
+
44
+ export const GET = CustomerPortal({
45
+ accessToken: SPAIRE_ACCESS_TOKEN,
46
+ getCustomerId: (event) => "", // Fuction to resolve a Spaire Customer ID
47
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Customer Portal
48
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
49
+ });
50
+ ```
51
+
52
+ ## Webhooks
53
+
54
+ A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
55
+
56
+ ```typescript
57
+ import { Webhooks } from '@spaire/astro';
58
+ import { SPAIRE_WEBHOOK_SECRET } from "astro:env/server"
59
+
60
+ export const POST = Webhooks({
61
+ webhookSecret: SPAIRE_WEBHOOK_SECRET,
62
+ onPayload: async (payload) => /** Handle payload */,
63
+ })
64
+ ```
65
+
66
+ #### Payload Handlers
67
+
68
+ The Webhook handler also supports granular handlers for easy integration.
69
+
70
+ - onCheckoutCreated: (payload) =>
71
+ - onCheckoutUpdated: (payload) =>
72
+ - onOrderCreated: (payload) =>
73
+ - onOrderUpdated: (payload) =>
74
+ - onOrderPaid: (payload) =>
75
+ - onSubscriptionCreated: (payload) =>
76
+ - onSubscriptionUpdated: (payload) =>
77
+ - onSubscriptionActive: (payload) =>
78
+ - onSubscriptionCanceled: (payload) =>
79
+ - onSubscriptionRevoked: (payload) =>
80
+ - onProductCreated: (payload) =>
81
+ - onProductUpdated: (payload) =>
82
+ - onOrganizationUpdated: (payload) =>
83
+ - onBenefitCreated: (payload) =>
84
+ - onBenefitUpdated: (payload) =>
85
+ - onBenefitGrantCreated: (payload) =>
86
+ - onBenefitGrantUpdated: (payload) =>
87
+ - onBenefitGrantRevoked: (payload) =>
88
+ - onCustomerCreated: (payload) =>
89
+ - onCustomerUpdated: (payload) =>
90
+ - onCustomerDeleted: (payload) =>
91
+ - onCustomerStateChanged: (payload) =>
package/dist/index.cjs ADDED
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Checkout: () => Checkout,
34
+ CustomerPortal: () => CustomerPortal,
35
+ EntitlementStrategy: () => import_adapter_utils2.EntitlementStrategy,
36
+ Entitlements: () => import_adapter_utils2.Entitlements,
37
+ Webhooks: () => Webhooks
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+
41
+ // src/checkout/checkout.ts
42
+ var import_sdk = require("@spaire/sdk");
43
+ var Checkout = ({
44
+ accessToken,
45
+ successUrl,
46
+ returnUrl,
47
+ server,
48
+ theme,
49
+ includeCheckoutId = true
50
+ }) => {
51
+ return async ({ url }) => {
52
+ if (!accessToken) {
53
+ const { getSecret } = await import("astro:env/server");
54
+ accessToken = getSecret("SPAIRE_ACCESS_TOKEN");
55
+ }
56
+ const spaire = new import_sdk.Spaire({
57
+ accessToken,
58
+ server
59
+ });
60
+ const products = url.searchParams.getAll("products");
61
+ if (products.length === 0) {
62
+ return Response.json(
63
+ { error: "Missing products in query params" },
64
+ { status: 400 }
65
+ );
66
+ }
67
+ const success = successUrl ? new URL(successUrl) : void 0;
68
+ if (success && includeCheckoutId) {
69
+ success.searchParams.set("checkoutId", "{CHECKOUT_ID}");
70
+ }
71
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
72
+ try {
73
+ const result = await spaire.checkouts.create({
74
+ products,
75
+ successUrl: success ? decodeURI(success.toString()) : void 0,
76
+ customerId: url.searchParams.get("customerId") ?? void 0,
77
+ externalCustomerId: url.searchParams.get("customerExternalId") ?? void 0,
78
+ customerEmail: url.searchParams.get("customerEmail") ?? void 0,
79
+ customerName: url.searchParams.get("customerName") ?? void 0,
80
+ customerBillingAddress: url.searchParams.has("customerBillingAddress") ? JSON.parse(url.searchParams.get("customerBillingAddress") ?? "{}") : void 0,
81
+ customerTaxId: url.searchParams.get("customerTaxId") ?? void 0,
82
+ customerIpAddress: url.searchParams.get("customerIpAddress") ?? void 0,
83
+ customerMetadata: url.searchParams.has("customerMetadata") ? JSON.parse(url.searchParams.get("customerMetadata") ?? "{}") : void 0,
84
+ allowDiscountCodes: url.searchParams.has("allowDiscountCodes") ? url.searchParams.get("allowDiscountCodes") === "true" : void 0,
85
+ discountId: url.searchParams.get("discountId") ?? void 0,
86
+ metadata: url.searchParams.has("metadata") ? JSON.parse(url.searchParams.get("metadata") ?? "{}") : void 0,
87
+ seats: url.searchParams.has("seats") ? Number.parseInt(url.searchParams.get("seats") ?? "1", 10) : void 0,
88
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
89
+ });
90
+ const redirectUrl = new URL(result.url);
91
+ if (theme) {
92
+ redirectUrl.searchParams.set("theme", theme);
93
+ }
94
+ return Response.redirect(redirectUrl.toString());
95
+ } catch (error) {
96
+ console.error(error);
97
+ return Response.json({ error: "Internal server error" }, { status: 500 });
98
+ }
99
+ };
100
+ };
101
+
102
+ // src/customerPortal/customerPortal.ts
103
+ var import_sdk2 = require("@spaire/sdk");
104
+ var CustomerPortal = ({
105
+ accessToken,
106
+ server,
107
+ getCustomerId,
108
+ returnUrl
109
+ }) => {
110
+ return async ({ request }) => {
111
+ if (!accessToken) {
112
+ const { getSecret } = await import("astro:env/server");
113
+ accessToken = getSecret("SPAIRE_ACCESS_TOKEN");
114
+ }
115
+ const spaire = new import_sdk2.Spaire({
116
+ accessToken,
117
+ server
118
+ });
119
+ const customerId = await getCustomerId(request);
120
+ if (!customerId) {
121
+ return Response.json(
122
+ { error: "customerId not defined" },
123
+ { status: 400 }
124
+ );
125
+ }
126
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
127
+ try {
128
+ const result = await spaire.customerSessions.create({
129
+ customerId,
130
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
131
+ });
132
+ return Response.redirect(result.customerPortalUrl);
133
+ } catch (error) {
134
+ console.error(error);
135
+ return Response.json({ error: "Internal server error" }, { status: 500 });
136
+ }
137
+ };
138
+ };
139
+
140
+ // src/webhooks/webhooks.ts
141
+ var import_adapter_utils = require("@spaire/adapter-utils");
142
+ var import_webhooks = require("@spaire/sdk/webhooks");
143
+ var import_adapter_utils2 = require("@spaire/adapter-utils");
144
+ var Webhooks = ({
145
+ webhookSecret,
146
+ onPayload,
147
+ entitlements,
148
+ ...eventHandlers
149
+ }) => {
150
+ return async ({ request }) => {
151
+ if (request.method !== "POST") {
152
+ return Response.json({ message: "Method not allowed" }, { status: 405 });
153
+ }
154
+ const requestBody = await request.text();
155
+ const webhookHeaders = {
156
+ "webhook-id": request.headers.get("webhook-id") ?? "",
157
+ "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
158
+ "webhook-signature": request.headers.get("webhook-signature") ?? ""
159
+ };
160
+ let webhookPayload;
161
+ try {
162
+ webhookPayload = (0, import_webhooks.validateEvent)(
163
+ requestBody,
164
+ webhookHeaders,
165
+ webhookSecret
166
+ );
167
+ } catch (error) {
168
+ console.log(error);
169
+ if (error instanceof import_webhooks.WebhookVerificationError) {
170
+ return Response.json({ received: false }, { status: 403 });
171
+ }
172
+ return Response.json({ error: "Internal server error" }, { status: 500 });
173
+ }
174
+ await (0, import_adapter_utils.handleWebhookPayload)(webhookPayload, {
175
+ webhookSecret,
176
+ entitlements,
177
+ onPayload,
178
+ ...eventHandlers
179
+ });
180
+ return Response.json({ received: true });
181
+ };
182
+ };
183
+ // Annotate the CommonJS export names for ESM import in node:
184
+ 0 && (module.exports = {
185
+ Checkout,
186
+ CustomerPortal,
187
+ EntitlementStrategy,
188
+ Entitlements,
189
+ Webhooks
190
+ });
191
+ //# 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 { APIRoute } from \"astro\";\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): APIRoute => {\n\treturn async ({ url }) => {\n\t\tif (!accessToken) {\n\t\t\tconst { getSecret } = await import(\"astro:env/server\");\n\t\t\taccessToken = getSecret(\"SPAIRE_ACCESS_TOKEN\");\n\t\t}\n\n\t\tconst spaire = new Spaire({\n\t\t\taccessToken,\n\t\t\tserver,\n\t\t});\n\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn Response.json(\n\t\t\t\t{ error: \"Missing products in query params\" },\n\t\t\t\t{ status: 400 },\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 Response.redirect(redirectUrl.toString());\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn Response.json({ error: \"Internal server error\" }, { status: 500 });\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\nimport type { APIRoute } from \"astro\";\n\nexport interface CustomerPortalConfig {\n\taccessToken?: string;\n\tgetCustomerId: (req: Request) => Promise<string>;\n\treturnUrl?: string;\n\tserver?: \"sandbox\" | \"production\";\n}\n\nexport const CustomerPortal = ({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig): APIRoute => {\n\treturn async ({ request }) => {\n\t\tif (!accessToken) {\n\t\t\tconst { getSecret } = await import(\"astro:env/server\");\n\t\t\taccessToken = getSecret(\"SPAIRE_ACCESS_TOKEN\");\n\t\t}\n\n\t\tconst spaire = new Spaire({\n\t\t\taccessToken,\n\t\t\tserver,\n\t\t});\n\n\t\tconst customerId = await getCustomerId(request);\n\n\t\tif (!customerId) {\n\t\t\treturn Response.json(\n\t\t\t\t{ error: \"customerId not defined\" },\n\t\t\t\t{ status: 400 },\n\t\t\t);\n\t\t}\n\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\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 Response.redirect(result.customerPortalUrl);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn Response.json({ error: \"Internal server error\" }, { status: 500 });\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 { APIRoute } from \"astro\";\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): APIRoute => {\n\treturn async ({ request }) => {\n\t\tif (request.method !== \"POST\") {\n\t\t\treturn Response.json({ message: \"Method not allowed\" }, { status: 405 });\n\t\t}\n\n\t\tconst requestBody = await request.text();\n\n\t\tconst webhookHeaders: Record<string, string> = {\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\tconsole.log(error);\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn Response.json({ received: false }, { status: 403 });\n\t\t\t}\n\n\t\t\treturn Response.json({ error: \"Internal server error\" }, { status: 500 });\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 Response.json({ received: true });\n\t};\n};\n"],"mappings":"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","names":["import_sdk","import_adapter_utils"]}
@@ -0,0 +1,25 @@
1
+ import { APIRoute } from 'astro';
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) => APIRoute;
14
+
15
+ interface CustomerPortalConfig {
16
+ accessToken?: string;
17
+ getCustomerId: (req: Request) => Promise<string>;
18
+ returnUrl?: string;
19
+ server?: "sandbox" | "production";
20
+ }
21
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => APIRoute;
22
+
23
+ declare const Webhooks: ({ webhookSecret, onPayload, entitlements, ...eventHandlers }: WebhooksConfig) => APIRoute;
24
+
25
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
@@ -0,0 +1,25 @@
1
+ import { APIRoute } from 'astro';
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) => APIRoute;
14
+
15
+ interface CustomerPortalConfig {
16
+ accessToken?: string;
17
+ getCustomerId: (req: Request) => Promise<string>;
18
+ returnUrl?: string;
19
+ server?: "sandbox" | "production";
20
+ }
21
+ declare const CustomerPortal: ({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => APIRoute;
22
+
23
+ declare const Webhooks: ({ webhookSecret, onPayload, entitlements, ...eventHandlers }: WebhooksConfig) => APIRoute;
24
+
25
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
package/dist/index.js ADDED
@@ -0,0 +1,155 @@
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
+ return async ({ url }) => {
12
+ if (!accessToken) {
13
+ const { getSecret } = await import("astro:env/server");
14
+ accessToken = getSecret("SPAIRE_ACCESS_TOKEN");
15
+ }
16
+ const spaire = new Spaire({
17
+ accessToken,
18
+ server
19
+ });
20
+ const products = url.searchParams.getAll("products");
21
+ if (products.length === 0) {
22
+ return Response.json(
23
+ { error: "Missing products in query params" },
24
+ { status: 400 }
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 Response.redirect(redirectUrl.toString());
55
+ } catch (error) {
56
+ console.error(error);
57
+ return Response.json({ error: "Internal server error" }, { status: 500 });
58
+ }
59
+ };
60
+ };
61
+
62
+ // src/customerPortal/customerPortal.ts
63
+ import { Spaire as Spaire2 } from "@spaire/sdk";
64
+ var CustomerPortal = ({
65
+ accessToken,
66
+ server,
67
+ getCustomerId,
68
+ returnUrl
69
+ }) => {
70
+ return async ({ request }) => {
71
+ if (!accessToken) {
72
+ const { getSecret } = await import("astro:env/server");
73
+ accessToken = getSecret("SPAIRE_ACCESS_TOKEN");
74
+ }
75
+ const spaire = new Spaire2({
76
+ accessToken,
77
+ server
78
+ });
79
+ const customerId = await getCustomerId(request);
80
+ if (!customerId) {
81
+ return Response.json(
82
+ { error: "customerId not defined" },
83
+ { status: 400 }
84
+ );
85
+ }
86
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
87
+ try {
88
+ const result = await spaire.customerSessions.create({
89
+ customerId,
90
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
91
+ });
92
+ return Response.redirect(result.customerPortalUrl);
93
+ } catch (error) {
94
+ console.error(error);
95
+ return Response.json({ error: "Internal server error" }, { status: 500 });
96
+ }
97
+ };
98
+ };
99
+
100
+ // src/webhooks/webhooks.ts
101
+ import {
102
+ handleWebhookPayload
103
+ } from "@spaire/adapter-utils";
104
+ import { WebhookVerificationError, validateEvent } from "@spaire/sdk/webhooks";
105
+ import {
106
+ EntitlementStrategy,
107
+ Entitlements
108
+ } from "@spaire/adapter-utils";
109
+ var Webhooks = ({
110
+ webhookSecret,
111
+ onPayload,
112
+ entitlements,
113
+ ...eventHandlers
114
+ }) => {
115
+ return async ({ request }) => {
116
+ if (request.method !== "POST") {
117
+ return Response.json({ message: "Method not allowed" }, { status: 405 });
118
+ }
119
+ const requestBody = await request.text();
120
+ const webhookHeaders = {
121
+ "webhook-id": request.headers.get("webhook-id") ?? "",
122
+ "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
123
+ "webhook-signature": request.headers.get("webhook-signature") ?? ""
124
+ };
125
+ let webhookPayload;
126
+ try {
127
+ webhookPayload = validateEvent(
128
+ requestBody,
129
+ webhookHeaders,
130
+ webhookSecret
131
+ );
132
+ } catch (error) {
133
+ console.log(error);
134
+ if (error instanceof WebhookVerificationError) {
135
+ return Response.json({ received: false }, { status: 403 });
136
+ }
137
+ return Response.json({ error: "Internal server error" }, { status: 500 });
138
+ }
139
+ await handleWebhookPayload(webhookPayload, {
140
+ webhookSecret,
141
+ entitlements,
142
+ onPayload,
143
+ ...eventHandlers
144
+ });
145
+ return Response.json({ received: true });
146
+ };
147
+ };
148
+ export {
149
+ Checkout,
150
+ CustomerPortal,
151
+ EntitlementStrategy,
152
+ Entitlements,
153
+ Webhooks
154
+ };
155
+ //# 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 { APIRoute } from \"astro\";\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): APIRoute => {\n\treturn async ({ url }) => {\n\t\tif (!accessToken) {\n\t\t\tconst { getSecret } = await import(\"astro:env/server\");\n\t\t\taccessToken = getSecret(\"SPAIRE_ACCESS_TOKEN\");\n\t\t}\n\n\t\tconst spaire = new Spaire({\n\t\t\taccessToken,\n\t\t\tserver,\n\t\t});\n\n\t\tconst products = url.searchParams.getAll(\"products\");\n\n\t\tif (products.length === 0) {\n\t\t\treturn Response.json(\n\t\t\t\t{ error: \"Missing products in query params\" },\n\t\t\t\t{ status: 400 },\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 Response.redirect(redirectUrl.toString());\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn Response.json({ error: \"Internal server error\" }, { status: 500 });\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\nimport type { APIRoute } from \"astro\";\n\nexport interface CustomerPortalConfig {\n\taccessToken?: string;\n\tgetCustomerId: (req: Request) => Promise<string>;\n\treturnUrl?: string;\n\tserver?: \"sandbox\" | \"production\";\n}\n\nexport const CustomerPortal = ({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig): APIRoute => {\n\treturn async ({ request }) => {\n\t\tif (!accessToken) {\n\t\t\tconst { getSecret } = await import(\"astro:env/server\");\n\t\t\taccessToken = getSecret(\"SPAIRE_ACCESS_TOKEN\");\n\t\t}\n\n\t\tconst spaire = new Spaire({\n\t\t\taccessToken,\n\t\t\tserver,\n\t\t});\n\n\t\tconst customerId = await getCustomerId(request);\n\n\t\tif (!customerId) {\n\t\t\treturn Response.json(\n\t\t\t\t{ error: \"customerId not defined\" },\n\t\t\t\t{ status: 400 },\n\t\t\t);\n\t\t}\n\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\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 Response.redirect(result.customerPortalUrl);\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\treturn Response.json({ error: \"Internal server error\" }, { status: 500 });\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 { APIRoute } from \"astro\";\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): APIRoute => {\n\treturn async ({ request }) => {\n\t\tif (request.method !== \"POST\") {\n\t\t\treturn Response.json({ message: \"Method not allowed\" }, { status: 405 });\n\t\t}\n\n\t\tconst requestBody = await request.text();\n\n\t\tconst webhookHeaders: Record<string, string> = {\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\tconsole.log(error);\n\t\t\tif (error instanceof WebhookVerificationError) {\n\t\t\t\treturn Response.json({ received: false }, { status: 403 });\n\t\t\t}\n\n\t\t\treturn Response.json({ error: \"Internal server error\" }, { status: 500 });\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 Response.json({ received: true });\n\t};\n};\n"],"mappings":"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","names":["Spaire"]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@spaire/astro",
3
+ "version": "2.0.0",
4
+ "description": "Spaire integration for Astro",
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
+ "type": "module",
19
+ "engines": {
20
+ "node": ">=16"
21
+ },
22
+ "scripts": {
23
+ "test": "vitest",
24
+ "build": "tsup ./src/index.ts --format esm,cjs --dts --clean --sourcemap --external 'astro:env/server'",
25
+ "dev": "tsc --watch",
26
+ "check": "biome check --write ./src"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "keywords": [
32
+ "spaire",
33
+ "withastro",
34
+ "payments",
35
+ "subscriptions"
36
+ ],
37
+ "peerDependencies": {
38
+ "astro": "^5.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@biomejs/biome": "1.9.4",
42
+ "@sindresorhus/tsconfig": "^7.0.0",
43
+ "@types/node": "^20.0.0",
44
+ "prettier": "^3.7.4",
45
+ "tsup": "^8.5.1",
46
+ "vitest": "^2.1.8"
47
+ },
48
+ "dependencies": {
49
+ "@spaire/adapter-utils": "^2.0.0",
50
+ "@spaire/sdk": "^0.45.1"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ }
55
+ }