@spaire/tanstack-start 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,104 @@
1
+ # @spaire/tanstack-start
2
+
3
+ Payments and Checkouts made dead simple with [Tanstack Start](https://tanstack.com/start)
4
+
5
+ `pnpm install @spaire/tanstack-start zod`
6
+
7
+ ## Checkout
8
+
9
+ Create a Checkout handler which takes care of redirections.
10
+
11
+ ```typescript
12
+ // routes/api/checkout.ts
13
+ import { Checkout } from "@spaire/tanstack-start";
14
+ import { createAPIFileRoute } from "@tanstack/react-start/api";
15
+
16
+ export const APIRoute = createAPIFileRoute("/api/checkout")({
17
+ GET: Checkout({
18
+ accessToken: process.env.SPAIRE_ACCESS_TOKEN,
19
+ successUrl: process.env.SUCCESS_URL,
20
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Checkout
21
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
22
+ theme: "dark" // Enforces the theme - System-preferred theme will be set if left omitted
23
+ }),
24
+ });
25
+ ```
26
+
27
+ ### Query Params
28
+
29
+ Pass query params to this route.
30
+
31
+ - products `?products=123`
32
+ - customerId (optional) `?products=123&customerId=xxx`
33
+ - customerExternalId (optional) `?products=123&customerExternalId=xxx`
34
+ - customerEmail (optional) `?products=123&customerEmail=janedoe@gmail.com`
35
+ - customerName (optional) `?products=123&customerName=Jane`
36
+ - seats (optional) `?products=123&seats=5` - Number of seats for seat-based products
37
+ - metadata (optional) `URL-Encoded JSON string`
38
+
39
+ ## Customer Portal
40
+
41
+ Create a customer portal where your customer can view orders and subscriptions.
42
+
43
+ ```typescript
44
+ // routes/api/portal.ts
45
+ import { CustomerPortal } from "@spaire/tanstack-start";
46
+ import { createAPIFileRoute } from "@tanstack/react-start/api";
47
+ import { getSupabaseServerClient } from "~/servers/supabase-server";
48
+
49
+ export const APIRoute = createAPIFileRoute("/api/portal")({
50
+ GET: CustomerPortal({
51
+ accessToken: process.env.SPAIRE_ACCESS_TOKEN,
52
+ getCustomerId: async (request: Request) => "", // Fuction to resolve a Spaire Customer ID
53
+ returnUrl: "https://myapp.com", // Optional Return URL, which renders a Back-button in the Customer Portal
54
+ server: "sandbox", // Use sandbox if you're testing Spaire - omit the parameter or pass 'production' otherwise
55
+ }),
56
+ });
57
+ ```
58
+
59
+ ## Webhooks
60
+
61
+ A simple utility which resolves incoming webhook payloads by signing the webhook secret properly.
62
+
63
+ ```typescript
64
+ // api/webhook/spaire.ts
65
+ import { Webhooks } from "@spaire/tanstack-start";
66
+ import { createAPIFileRoute } from "@tanstack/react-start/api";
67
+
68
+ export const APIRoute = createAPIFileRoute("/api/webhook/spaire")({
69
+ POST: Webhooks({
70
+ webhookSecret: process.env.SPAIRE_WEBHOOK_SECRET!,
71
+ onPayload: async (payload) => {
72
+ // Handle the payload
73
+ // No need to return an acknowledge response
74
+ },
75
+ }),
76
+ });
77
+ ```
78
+
79
+ #### Payload Handlers
80
+
81
+ The Webhook handler also supports granular handlers for easy integration.
82
+
83
+ - onCheckoutCreated: (payload) =>
84
+ - onCheckoutUpdated: (payload) =>
85
+ - onOrderCreated: (payload) =>
86
+ - onOrderUpdated: (payload) =>
87
+ - onOrderPaid: (payload) =>
88
+ - onSubscriptionCreated: (payload) =>
89
+ - onSubscriptionUpdated: (payload) =>
90
+ - onSubscriptionActive: (payload) =>
91
+ - onSubscriptionCanceled: (payload) =>
92
+ - onSubscriptionRevoked: (payload) =>
93
+ - onProductCreated: (payload) =>
94
+ - onProductUpdated: (payload) =>
95
+ - onOrganizationUpdated: (payload) =>
96
+ - onBenefitCreated: (payload) =>
97
+ - onBenefitUpdated: (payload) =>
98
+ - onBenefitGrantCreated: (payload) =>
99
+ - onBenefitGrantUpdated: (payload) =>
100
+ - onBenefitGrantRevoked: (payload) =>
101
+ - onCustomerCreated: (payload) =>
102
+ - onCustomerUpdated: (payload) =>
103
+ - onCustomerDeleted: (payload) =>
104
+ - 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 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 ({ request }) => {
46
+ const url = new URL(request.url);
47
+ const products = url.searchParams.getAll("products");
48
+ if (products.length === 0) {
49
+ return Response.json(
50
+ { error: "Missing products in query params" },
51
+ { status: 400 }
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 Response.redirect(redirectUrl.toString());
82
+ } catch (error) {
83
+ console.error(error);
84
+ return Response.error();
85
+ }
86
+ };
87
+ };
88
+
89
+ // src/customerPortal/customerPortal.ts
90
+ var import_sdk2 = require("@spaire/sdk");
91
+ var CustomerPortal = ({
92
+ accessToken,
93
+ server,
94
+ getCustomerId,
95
+ returnUrl
96
+ }) => {
97
+ const spaire = new import_sdk2.Spaire({
98
+ accessToken,
99
+ server
100
+ });
101
+ return async ({ request }) => {
102
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
103
+ const customerId = await getCustomerId(request);
104
+ if (!customerId) {
105
+ return Response.json(
106
+ { error: "customerId not defined" },
107
+ { status: 400 }
108
+ );
109
+ }
110
+ try {
111
+ const result = await spaire.customerSessions.create({
112
+ customerId,
113
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
114
+ });
115
+ return Response.redirect(result.customerPortalUrl);
116
+ } catch (error) {
117
+ console.error(error);
118
+ return Response.error();
119
+ }
120
+ };
121
+ };
122
+
123
+ // src/webhooks/webhooks.ts
124
+ var import_adapter_utils = require("@spaire/adapter-utils");
125
+ var import_webhooks = require("@spaire/sdk/webhooks");
126
+ var import_adapter_utils2 = require("@spaire/adapter-utils");
127
+ var Webhooks = ({
128
+ webhookSecret,
129
+ entitlements,
130
+ onPayload,
131
+ ...eventHandlers
132
+ }) => {
133
+ return async ({ request }) => {
134
+ const requestBody = await request.text();
135
+ const webhookHeaders = {
136
+ "webhook-id": request.headers.get("webhook-id") ?? "",
137
+ "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
138
+ "webhook-signature": request.headers.get("webhook-signature") ?? ""
139
+ };
140
+ let webhookPayload;
141
+ try {
142
+ webhookPayload = (0, import_webhooks.validateEvent)(
143
+ requestBody,
144
+ webhookHeaders,
145
+ webhookSecret
146
+ );
147
+ } catch (error) {
148
+ if (error instanceof import_webhooks.WebhookVerificationError) {
149
+ return Response.json({ received: false }, { status: 403 });
150
+ }
151
+ throw error;
152
+ }
153
+ await (0, import_adapter_utils.handleWebhookPayload)(webhookPayload, {
154
+ webhookSecret,
155
+ entitlements,
156
+ onPayload,
157
+ ...eventHandlers
158
+ });
159
+ return Response.json({ 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\";\n// @ts-expect-error - TODO: fix this\nimport type { StartAPIMethodCallback } from \"@tanstack/react-start/api\";\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 = <TPath extends string = string>({\n\taccessToken,\n\tsuccessUrl,\n\treturnUrl,\n\tserver,\n\ttheme,\n\tincludeCheckoutId = true,\n}: CheckoutConfig): StartAPIMethodCallback<TPath> => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\t// @ts-expect-error - TODO: fix this\n\treturn async ({ request }) => {\n\t\tconst url = new URL(request.url);\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.error();\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\n// @ts-expect-error - TODO: fix this\nimport type { StartAPIMethodCallback } from \"@tanstack/react-start/api\";\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 = <TPath extends string = string>({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig): StartAPIMethodCallback<TPath> => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\t// @ts-expect-error - TODO: fix this\n\treturn async ({ request }) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\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\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.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\";\n// @ts-expect-error - TODO: fix this\nimport type { StartAPIMethodCallback } from \"@tanstack/react-start/api\";\n\nexport {\n\tEntitlementStrategy,\n\tEntitlements,\n\ttype EntitlementContext,\n\ttype EntitlementHandler,\n\ttype EntitlementProperties,\n} from \"@spaire/adapter-utils\";\n\nexport const Webhooks = <TPath extends string = string>({\n\twebhookSecret,\n\tentitlements,\n\tonPayload,\n\t...eventHandlers\n}: WebhooksConfig): StartAPIMethodCallback<TPath> => {\n\t// @ts-expect-error - TODO: fix this\n\treturn async ({ 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 Response.json({ received: false }, { status: 403 });\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 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 { StartAPIMethodCallback } from '@tanstack/react-start/api';
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: <TPath extends string = string>({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => StartAPIMethodCallback<TPath>;
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: <TPath extends string = string>({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => StartAPIMethodCallback<TPath>;
22
+
23
+ declare const Webhooks: <TPath extends string = string>({ webhookSecret, entitlements, onPayload, ...eventHandlers }: WebhooksConfig) => StartAPIMethodCallback<TPath>;
24
+
25
+ export { Checkout, type CheckoutConfig, CustomerPortal, type CustomerPortalConfig, Webhooks };
@@ -0,0 +1,25 @@
1
+ import { StartAPIMethodCallback } from '@tanstack/react-start/api';
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: <TPath extends string = string>({ accessToken, successUrl, returnUrl, server, theme, includeCheckoutId, }: CheckoutConfig) => StartAPIMethodCallback<TPath>;
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: <TPath extends string = string>({ accessToken, server, getCustomerId, returnUrl, }: CustomerPortalConfig) => StartAPIMethodCallback<TPath>;
22
+
23
+ declare const Webhooks: <TPath extends string = string>({ webhookSecret, entitlements, onPayload, ...eventHandlers }: WebhooksConfig) => StartAPIMethodCallback<TPath>;
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
+ 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 ({ request }) => {
16
+ const url = new URL(request.url);
17
+ const products = url.searchParams.getAll("products");
18
+ if (products.length === 0) {
19
+ return Response.json(
20
+ { error: "Missing products in query params" },
21
+ { status: 400 }
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 Response.redirect(redirectUrl.toString());
52
+ } catch (error) {
53
+ console.error(error);
54
+ return Response.error();
55
+ }
56
+ };
57
+ };
58
+
59
+ // src/customerPortal/customerPortal.ts
60
+ import { Spaire as Spaire2 } from "@spaire/sdk";
61
+ var CustomerPortal = ({
62
+ accessToken,
63
+ server,
64
+ getCustomerId,
65
+ returnUrl
66
+ }) => {
67
+ const spaire = new Spaire2({
68
+ accessToken,
69
+ server
70
+ });
71
+ return async ({ request }) => {
72
+ const retUrl = returnUrl ? new URL(returnUrl) : void 0;
73
+ const customerId = await getCustomerId(request);
74
+ if (!customerId) {
75
+ return Response.json(
76
+ { error: "customerId not defined" },
77
+ { status: 400 }
78
+ );
79
+ }
80
+ try {
81
+ const result = await spaire.customerSessions.create({
82
+ customerId,
83
+ returnUrl: retUrl ? decodeURI(retUrl.toString()) : void 0
84
+ });
85
+ return Response.redirect(result.customerPortalUrl);
86
+ } catch (error) {
87
+ console.error(error);
88
+ return Response.error();
89
+ }
90
+ };
91
+ };
92
+
93
+ // src/webhooks/webhooks.ts
94
+ import {
95
+ handleWebhookPayload
96
+ } from "@spaire/adapter-utils";
97
+ import { WebhookVerificationError, validateEvent } from "@spaire/sdk/webhooks";
98
+ import {
99
+ EntitlementStrategy,
100
+ Entitlements
101
+ } from "@spaire/adapter-utils";
102
+ var Webhooks = ({
103
+ webhookSecret,
104
+ entitlements,
105
+ onPayload,
106
+ ...eventHandlers
107
+ }) => {
108
+ return async ({ request }) => {
109
+ const requestBody = await request.text();
110
+ const webhookHeaders = {
111
+ "webhook-id": request.headers.get("webhook-id") ?? "",
112
+ "webhook-timestamp": request.headers.get("webhook-timestamp") ?? "",
113
+ "webhook-signature": request.headers.get("webhook-signature") ?? ""
114
+ };
115
+ let webhookPayload;
116
+ try {
117
+ webhookPayload = validateEvent(
118
+ requestBody,
119
+ webhookHeaders,
120
+ webhookSecret
121
+ );
122
+ } catch (error) {
123
+ if (error instanceof WebhookVerificationError) {
124
+ return Response.json({ received: false }, { status: 403 });
125
+ }
126
+ throw error;
127
+ }
128
+ await handleWebhookPayload(webhookPayload, {
129
+ webhookSecret,
130
+ entitlements,
131
+ onPayload,
132
+ ...eventHandlers
133
+ });
134
+ return Response.json({ 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\";\n// @ts-expect-error - TODO: fix this\nimport type { StartAPIMethodCallback } from \"@tanstack/react-start/api\";\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 = <TPath extends string = string>({\n\taccessToken,\n\tsuccessUrl,\n\treturnUrl,\n\tserver,\n\ttheme,\n\tincludeCheckoutId = true,\n}: CheckoutConfig): StartAPIMethodCallback<TPath> => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\t// @ts-expect-error - TODO: fix this\n\treturn async ({ request }) => {\n\t\tconst url = new URL(request.url);\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.error();\n\t\t}\n\t};\n};\n","import { Spaire } from \"@spaire/sdk\";\n// @ts-expect-error - TODO: fix this\nimport type { StartAPIMethodCallback } from \"@tanstack/react-start/api\";\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 = <TPath extends string = string>({\n\taccessToken,\n\tserver,\n\tgetCustomerId,\n\treturnUrl,\n}: CustomerPortalConfig): StartAPIMethodCallback<TPath> => {\n\tconst spaire = new Spaire({\n\t\taccessToken,\n\t\tserver,\n\t});\n\n\t// @ts-expect-error - TODO: fix this\n\treturn async ({ request }) => {\n\t\tconst retUrl = returnUrl ? new URL(returnUrl) : undefined;\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\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.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\";\n// @ts-expect-error - TODO: fix this\nimport type { StartAPIMethodCallback } from \"@tanstack/react-start/api\";\n\nexport {\n\tEntitlementStrategy,\n\tEntitlements,\n\ttype EntitlementContext,\n\ttype EntitlementHandler,\n\ttype EntitlementProperties,\n} from \"@spaire/adapter-utils\";\n\nexport const Webhooks = <TPath extends string = string>({\n\twebhookSecret,\n\tentitlements,\n\tonPayload,\n\t...eventHandlers\n}: WebhooksConfig): StartAPIMethodCallback<TPath> => {\n\t// @ts-expect-error - TODO: fix this\n\treturn async ({ 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 Response.json({ received: false }, { status: 403 });\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 Response.json({ received: true });\n\t};\n};\n"],"mappings":"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","names":["Spaire"]}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@spaire/tanstack-start",
3
+ "version": "2.0.0",
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
+ },
26
+ "files": [
27
+ "dist"
28
+ ],
29
+ "dependencies": {
30
+ "@spaire/adapter-utils": "^2.0.0",
31
+ "@spaire/sdk": "^0.45.1",
32
+ "@tanstack/react-start": "^1.140.0"
33
+ },
34
+ "devDependencies": {
35
+ "@biomejs/biome": "1.9.4",
36
+ "@sindresorhus/tsconfig": "^7.0.0",
37
+ "tsup": "^8.5.1",
38
+ "vitest": "^2.1.8"
39
+ },
40
+ "ava": {
41
+ "extensions": {
42
+ "ts": "module",
43
+ "tsx": "module"
44
+ },
45
+ "nodeArguments": [
46
+ "--loader=ts-node/esm"
47
+ ]
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ }
52
+ }