paddle-checkout-accelerator 2.1.0 → 2.2.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.
Files changed (81) hide show
  1. package/bin/paddle-checkout-accelerator.js +247 -0
  2. package/dist/index.cjs +1150 -0
  3. package/dist/index.d.cts +290 -0
  4. package/dist/index.d.ts +290 -0
  5. package/dist/index.js +1079 -0
  6. package/package.json +14 -7
  7. package/recipes/nextjs/app/billing.ts +1 -1
  8. package/dist/package/index.d.ts +0 -28
  9. package/dist/package/index.js +0 -28
  10. package/dist/src/components/paddle/BillingHistory.d.ts +0 -1
  11. package/dist/src/components/paddle/BillingHistory.js +0 -17
  12. package/dist/src/components/paddle/CustomerPortal.d.ts +0 -1
  13. package/dist/src/components/paddle/CustomerPortal.js +0 -5
  14. package/dist/src/components/paddle/CustomerPortalButton.d.ts +0 -1
  15. package/dist/src/components/paddle/CustomerPortalButton.js +0 -31
  16. package/dist/src/components/paddle/InlineCheckout.d.ts +0 -5
  17. package/dist/src/components/paddle/InlineCheckout.js +0 -13
  18. package/dist/src/components/paddle/PricingTable.d.ts +0 -1
  19. package/dist/src/components/paddle/PricingTable.js +0 -27
  20. package/dist/src/components/paddle/SubscriptionCard.d.ts +0 -6
  21. package/dist/src/components/paddle/SubscriptionCard.js +0 -5
  22. package/dist/src/components/paddle/TrialBanner.d.ts +0 -5
  23. package/dist/src/components/paddle/TrialBanner.js +0 -5
  24. package/dist/src/components/paddle/UpgradeModal.d.ts +0 -11
  25. package/dist/src/components/paddle/UpgradeModal.js +0 -35
  26. package/dist/src/components/paddle/UsageMeter.d.ts +0 -6
  27. package/dist/src/components/paddle/UsageMeter.js +0 -8
  28. package/dist/src/components/paddle/gates/SubscriptionGate.d.ts +0 -7
  29. package/dist/src/components/paddle/gates/SubscriptionGate.js +0 -8
  30. package/dist/src/lib/billing/adapters/index.d.ts +0 -3
  31. package/dist/src/lib/billing/adapters/index.js +0 -3
  32. package/dist/src/lib/billing/adapters/memory.d.ts +0 -2
  33. package/dist/src/lib/billing/adapters/memory.js +0 -41
  34. package/dist/src/lib/billing/adapters/prisma/index.d.ts +0 -28
  35. package/dist/src/lib/billing/adapters/prisma/index.js +0 -80
  36. package/dist/src/lib/billing/adapters/types.d.ts +0 -13
  37. package/dist/src/lib/billing/adapters/types.js +0 -1
  38. package/dist/src/lib/billing/configure.d.ts +0 -6
  39. package/dist/src/lib/billing/configure.js +0 -13
  40. package/dist/src/lib/billing/customer-repair.d.ts +0 -4
  41. package/dist/src/lib/billing/customer-repair.js +0 -19
  42. package/dist/src/lib/billing/demo-seed.d.ts +0 -1
  43. package/dist/src/lib/billing/demo-seed.js +0 -13
  44. package/dist/src/lib/billing/entitlements.d.ts +0 -3
  45. package/dist/src/lib/billing/entitlements.js +0 -16
  46. package/dist/src/lib/billing/events.d.ts +0 -12
  47. package/dist/src/lib/billing/events.js +0 -20
  48. package/dist/src/lib/billing/plans.d.ts +0 -9
  49. package/dist/src/lib/billing/plans.js +0 -41
  50. package/dist/src/lib/billing/protection.d.ts +0 -6
  51. package/dist/src/lib/billing/protection.js +0 -16
  52. package/dist/src/lib/billing/refresh.d.ts +0 -1
  53. package/dist/src/lib/billing/refresh.js +0 -32
  54. package/dist/src/lib/billing/subscriptions.d.ts +0 -16
  55. package/dist/src/lib/billing/subscriptions.js +0 -36
  56. package/dist/src/lib/billing/teams.d.ts +0 -42
  57. package/dist/src/lib/billing/teams.js +0 -104
  58. package/dist/src/lib/billing/usage.d.ts +0 -17
  59. package/dist/src/lib/billing/usage.js +0 -40
  60. package/dist/src/lib/billing/webhook-sync.d.ts +0 -26
  61. package/dist/src/lib/billing/webhook-sync.js +0 -39
  62. package/dist/src/lib/paddle/api.d.ts +0 -1
  63. package/dist/src/lib/paddle/api.js +0 -21
  64. package/dist/src/lib/paddle/client.d.ts +0 -1
  65. package/dist/src/lib/paddle/client.js +0 -13
  66. package/dist/src/lib/paddle/customers.d.ts +0 -15
  67. package/dist/src/lib/paddle/customers.js +0 -14
  68. package/dist/src/lib/paddle/events.d.ts +0 -10
  69. package/dist/src/lib/paddle/events.js +0 -11
  70. package/dist/src/lib/paddle/hooks.d.ts +0 -4
  71. package/dist/src/lib/paddle/hooks.js +0 -11
  72. package/dist/src/lib/paddle/portal.d.ts +0 -8
  73. package/dist/src/lib/paddle/portal.js +0 -28
  74. package/dist/src/lib/paddle/subscriptions.d.ts +0 -20
  75. package/dist/src/lib/paddle/subscriptions.js +0 -10
  76. package/dist/src/lib/paddle/types.d.ts +0 -8
  77. package/dist/src/lib/paddle/types.js +0 -1
  78. package/dist/src/lib/paddle/webhook.d.ts +0 -1
  79. package/dist/src/lib/paddle/webhook.js +0 -8
  80. package/dist/src/lib/utils.d.ts +0 -2
  81. package/dist/src/lib/utils.js +0 -5
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "paddle-checkout-accelerator",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "scripts": {
5
5
  "dev": "next dev",
6
6
  "build": "next build",
7
7
  "start": "next start",
8
8
  "lint": "eslint",
9
9
  "test": "vitest run",
10
- "build:package": "tsc -p tsconfig.package.json",
10
+ "build:package": "tsup",
11
11
  "prepack": "npm run build:package"
12
12
  },
13
13
  "dependencies": {
@@ -37,23 +37,30 @@
37
37
  "eslint": "^9",
38
38
  "eslint-config-next": "16.2.9",
39
39
  "tailwindcss": "^4",
40
+ "tsup": "^8.5.1",
40
41
  "typescript": "^5",
41
42
  "vitest": "^4.1.8"
42
43
  },
43
44
  "type": "module",
44
- "main": "./dist/package/index.js",
45
- "types": "./dist/package/index.d.ts",
45
+ "main": "./dist/index.cjs",
46
+ "types": "./dist/index.d.ts",
46
47
  "exports": {
47
48
  ".": {
48
- "types": "./dist/package/index.d.ts",
49
- "import": "./dist/package/index.js"
49
+ "types": "./dist/index.d.ts",
50
+ "import": "./dist/index.js",
51
+ "require": "./dist/index.cjs"
50
52
  }
51
53
  },
52
54
  "files": [
53
55
  "dist",
56
+ "bin",
54
57
  "README.md",
55
58
  "LICENSE",
56
59
  "docs",
57
60
  "recipes"
58
- ]
61
+ ],
62
+ "module": "./dist/index.js",
63
+ "bin": {
64
+ "paddle-checkout-accelerator": "./bin/paddle-checkout-accelerator.js"
65
+ }
59
66
  }
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  configureBilling,
3
3
  createPrismaBillingAdapter,
4
- } from "@namahlogisticspaddle-checkout-accelerator";
4
+ } from "paddle-checkout-accelerator";
5
5
 
6
6
  import { prisma } from "@/lib/prisma";
7
7
 
@@ -1,28 +0,0 @@
1
- export * from "../src/components/paddle/UpgradeModal";
2
- export * from "../src/components/paddle/UsageMeter";
3
- export * from "../src/components/paddle/TrialBanner";
4
- export * from "../src/components/paddle/BillingHistory";
5
- export * from "../src/components/paddle/CustomerPortalButton";
6
- export * from "../src/components/paddle/SubscriptionCard";
7
- export * from "../src/components/paddle/gates/SubscriptionGate";
8
- export * from "../src/lib/paddle/hooks";
9
- export * from "../src/lib/paddle/client";
10
- export * from "../src/lib/paddle/types";
11
- export * from "../src/lib/paddle/webhook";
12
- export * from "../src/lib/billing/plans";
13
- export * from "../src/lib/billing/subscriptions";
14
- export * from "../src/lib/billing/entitlements";
15
- export * from "../src/lib/billing/usage";
16
- export * from "../src/lib/billing/webhook-sync";
17
- export * from "../src/lib/billing/adapters";
18
- export * from "../src/lib/billing/protection";
19
- export * from "../src/lib/billing/demo-seed";
20
- export * from "../src/lib/paddle/portal";
21
- export * from "../src/lib/paddle/api";
22
- export * from "../src/lib/paddle/subscriptions";
23
- export * from "../src/lib/billing/refresh";
24
- export * from "../src/lib/paddle/customers";
25
- export * from "../src/lib/billing/customer-repair";
26
- export * from "../src/lib/billing/teams";
27
- export * from "../src/lib/billing/events";
28
- export * from "../src/lib/billing/configure";
@@ -1,28 +0,0 @@
1
- export * from "../src/components/paddle/UpgradeModal";
2
- export * from "../src/components/paddle/UsageMeter";
3
- export * from "../src/components/paddle/TrialBanner";
4
- export * from "../src/components/paddle/BillingHistory";
5
- export * from "../src/components/paddle/CustomerPortalButton";
6
- export * from "../src/components/paddle/SubscriptionCard";
7
- export * from "../src/components/paddle/gates/SubscriptionGate";
8
- export * from "../src/lib/paddle/hooks";
9
- export * from "../src/lib/paddle/client";
10
- export * from "../src/lib/paddle/types";
11
- export * from "../src/lib/paddle/webhook";
12
- export * from "../src/lib/billing/plans";
13
- export * from "../src/lib/billing/subscriptions";
14
- export * from "../src/lib/billing/entitlements";
15
- export * from "../src/lib/billing/usage";
16
- export * from "../src/lib/billing/webhook-sync";
17
- export * from "../src/lib/billing/adapters";
18
- export * from "../src/lib/billing/protection";
19
- export * from "../src/lib/billing/demo-seed";
20
- export * from "../src/lib/paddle/portal";
21
- export * from "../src/lib/paddle/api";
22
- export * from "../src/lib/paddle/subscriptions";
23
- export * from "../src/lib/billing/refresh";
24
- export * from "../src/lib/paddle/customers";
25
- export * from "../src/lib/billing/customer-repair";
26
- export * from "../src/lib/billing/teams";
27
- export * from "../src/lib/billing/events";
28
- export * from "../src/lib/billing/configure";
@@ -1 +0,0 @@
1
- export declare function BillingHistory(): import("react").JSX.Element;
@@ -1,17 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- const invoices = [
4
- {
5
- id: "INV-001",
6
- amount: "$79",
7
- status: "Paid",
8
- },
9
- {
10
- id: "INV-002",
11
- amount: "$79",
12
- status: "Paid",
13
- },
14
- ];
15
- export function BillingHistory() {
16
- return (_jsx("div", { className: "rounded-xl border", children: invoices.map((invoice) => (_jsxs("div", { className: "flex justify-between border-b p-4", children: [_jsx("div", { children: invoice.id }), _jsx("div", { children: invoice.amount }), _jsx("div", { children: invoice.status })] }, invoice.id))) }));
17
- }
@@ -1 +0,0 @@
1
- export default function CustomerPortal(): import("react").JSX.Element;
@@ -1,5 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- export default function CustomerPortal() {
4
- return (_jsxs("div", { className: "rounded-3xl border p-8", children: [_jsx("h2", { className: "text-3xl font-bold", children: "Customer Portal" }), _jsxs("div", { className: "mt-8 space-y-4", children: [_jsx("div", { className: "rounded-xl border p-4", children: "Current Plan: Pro" }), _jsx("div", { className: "rounded-xl border p-4", children: "Status: Active" }), _jsx("div", { className: "rounded-xl border p-4", children: "Renewal Date: July 1, 2026" }), _jsx("button", { className: "rounded-xl bg-black px-5 py-3 text-white", children: "Manage Subscription" })] })] }));
5
- }
@@ -1 +0,0 @@
1
- export declare function CustomerPortalButton(): import("react").JSX.Element;
@@ -1,31 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
4
- export function CustomerPortalButton() {
5
- const [loading, setLoading] = useState(false);
6
- const [error, setError] = useState(null);
7
- async function launchPortal() {
8
- try {
9
- setLoading(true);
10
- setError(null);
11
- const response = await fetch("/api/paddle/portal-session", { method: "POST" });
12
- const data = (await response.json());
13
- if (!response.ok || !data.success || !data.url) {
14
- throw new Error(data.error ??
15
- "Unable to open billing portal");
16
- }
17
- window.location.href = data.url;
18
- }
19
- catch (err) {
20
- setError(err instanceof Error
21
- ? err.message
22
- : "Unable to open billing portal");
23
- }
24
- finally {
25
- setLoading(false);
26
- }
27
- }
28
- return (_jsxs("div", { className: "space-y-3", children: [_jsx("button", { onClick: launchPortal, disabled: loading, className: "rounded-xl bg-black px-4 py-3 text-white disabled:opacity-60", children: loading
29
- ? "Opening Billing..."
30
- : "Manage Billing" }), error && (_jsx("div", { className: "rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: error }))] }));
31
- }
@@ -1,5 +0,0 @@
1
- interface Props {
2
- priceId: string;
3
- }
4
- export default function InlineCheckout({ priceId, }: Props): import("react").JSX.Element;
5
- export {};
@@ -1,13 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useEffect, useState } from "react";
4
- export default function InlineCheckout({ priceId, }) {
5
- const [loading, setLoading] = useState(true);
6
- useEffect(() => {
7
- const timer = setTimeout(() => {
8
- setLoading(false);
9
- }, 1500);
10
- return () => clearTimeout(timer);
11
- }, []);
12
- return (_jsx("div", { className: "rounded-3xl border bg-white p-6", children: loading ? (_jsxs("div", { className: "space-y-4 animate-pulse", children: [_jsx("div", { className: "h-10 rounded bg-gray-100" }), _jsx("div", { className: "h-10 rounded bg-gray-100" }), _jsx("div", { className: "h-40 rounded bg-gray-100" })] })) : (_jsxs("div", { children: [_jsx("div", { className: "mb-4 text-sm text-gray-500", children: "Paddle Inline Checkout" }), _jsx("div", { id: "paddle-inline-checkout", "data-price-id": priceId, className: "min-h-[500px] rounded-xl border" })] })) }));
13
- }
@@ -1 +0,0 @@
1
- export default function PricingTable(): import("react").JSX.Element;
@@ -1,27 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Check } from "lucide-react";
4
- const plans = [
5
- {
6
- name: "Starter",
7
- price: "$29",
8
- features: [
9
- "1 Project",
10
- "Lifetime Updates",
11
- "Source Code"
12
- ]
13
- },
14
- {
15
- name: "Pro",
16
- price: "$79",
17
- featured: true,
18
- features: [
19
- "Unlimited Projects",
20
- "Premium Components",
21
- "Priority Support"
22
- ]
23
- }
24
- ];
25
- export default function PricingTable() {
26
- return (_jsx("div", { className: "grid gap-8 md:grid-cols-2", children: plans.map((plan) => (_jsxs("div", { className: `rounded-3xl border p-8 ${plan.featured ? "ring-2 ring-black" : ""}`, children: [_jsx("h3", { className: "text-2xl font-bold", children: plan.name }), _jsx("div", { className: "mt-6 text-5xl font-bold", children: plan.price }), _jsx("ul", { className: "mt-8 space-y-4", children: plan.features.map((feature) => (_jsxs("li", { className: "flex gap-3", children: [_jsx(Check, { size: 18 }), feature] }, feature))) }), _jsx("button", { className: "mt-8 w-full rounded-xl bg-black py-3 text-white", children: "Buy Now" })] }, plan.name))) }));
27
- }
@@ -1,6 +0,0 @@
1
- interface SubscriptionCardProps {
2
- plan: string;
3
- status: string;
4
- }
5
- export declare function SubscriptionCard({ plan, status, }: SubscriptionCardProps): import("react").JSX.Element;
6
- export {};
@@ -1,5 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- export function SubscriptionCard({ plan, status, }) {
4
- return (_jsxs("div", { className: "rounded-2xl border p-6", children: [_jsx("div", { className: "text-sm text-gray-500", children: "Current Plan" }), _jsx("div", { className: "mt-2 text-3xl font-bold", children: plan }), _jsxs("div", { className: "mt-4", children: ["Status: ", status] })] }));
5
- }
@@ -1,5 +0,0 @@
1
- interface TrialBannerProps {
2
- daysRemaining: number;
3
- }
4
- export declare function TrialBanner({ daysRemaining, }: TrialBannerProps): import("react").JSX.Element;
5
- export {};
@@ -1,5 +0,0 @@
1
- "use client";
2
- import { jsxs as _jsxs } from "react/jsx-runtime";
3
- export function TrialBanner({ daysRemaining, }) {
4
- return (_jsxs("div", { className: "rounded-xl border border-yellow-300 bg-yellow-50 p-4", children: ["Trial expires in", " ", _jsxs("strong", { children: [daysRemaining, " days"] }), "."] }));
5
- }
@@ -1,11 +0,0 @@
1
- interface UpgradeModalProps {
2
- open: boolean;
3
- onClose: () => void;
4
- currentPlan: string;
5
- targetPlan: string;
6
- targetPriceId: string;
7
- yearlySavings?: string;
8
- onUpgradeSuccess?: (data: unknown) => void;
9
- }
10
- export declare function UpgradeModal({ open, onClose, currentPlan, targetPlan, targetPriceId, yearlySavings, onUpgradeSuccess, }: UpgradeModalProps): import("react").JSX.Element | null;
11
- export {};
@@ -1,35 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState } from "react";
4
- import { ArrowRight, Check, Loader2, X, } from "lucide-react";
5
- import { openCheckout } from "@/lib/paddle/hooks";
6
- export function UpgradeModal({ open, onClose, currentPlan, targetPlan, targetPriceId, yearlySavings, onUpgradeSuccess, }) {
7
- const [loading, setLoading] = useState(false);
8
- const [error, setError] = useState(null);
9
- if (!open)
10
- return null;
11
- async function handleUpgrade() {
12
- try {
13
- setLoading(true);
14
- setError(null);
15
- await openCheckout([
16
- {
17
- priceId: targetPriceId,
18
- quantity: 1,
19
- },
20
- ]);
21
- onUpgradeSuccess?.({
22
- targetPlan,
23
- });
24
- }
25
- catch (err) {
26
- setError(err instanceof Error
27
- ? err.message
28
- : "Unable to launch checkout");
29
- }
30
- finally {
31
- setLoading(false);
32
- }
33
- }
34
- return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", children: _jsxs("div", { className: "w-full max-w-lg rounded-3xl border bg-white shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b p-6", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold", children: "Upgrade Plan" }), _jsx("p", { className: "mt-1 text-sm text-slate-500", children: "Unlock additional features" })] }), _jsx("button", { onClick: onClose, className: "rounded-lg p-2 hover:bg-slate-100", children: _jsx(X, { size: 18 }) })] }), _jsxs("div", { className: "p-6", children: [_jsx("div", { className: "rounded-2xl border p-5", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm text-slate-500", children: "Current" }), _jsx("div", { className: "mt-1 font-semibold", children: currentPlan })] }), _jsx(ArrowRight, { className: "text-slate-400", size: 20 }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "text-sm text-slate-500", children: "Upgrade To" }), _jsx("div", { className: "mt-1 font-semibold", children: targetPlan })] })] }) }), _jsx("div", { className: "mt-6 rounded-2xl bg-slate-50 p-5", children: _jsxs("ul", { className: "space-y-3", children: [_jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Unlimited projects"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Advanced billing"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Priority support"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Team access"] })] }) }), yearlySavings && (_jsxs("div", { className: "mt-4 rounded-xl border border-emerald-200 bg-emerald-50 p-3 text-sm", children: ["Save ", yearlySavings] })), error && (_jsx("div", { className: "mt-4 rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: error })), _jsx("button", { onClick: handleUpgrade, disabled: loading, className: "mt-6 flex w-full items-center justify-center gap-2 rounded-2xl bg-black px-5 py-4 text-white transition hover:opacity-90 disabled:opacity-50", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin" }), "Launching Checkout..."] })) : (_jsxs(_Fragment, { children: ["Upgrade Now", _jsx(ArrowRight, { size: 18 })] })) })] })] }) }));
35
- }
@@ -1,6 +0,0 @@
1
- interface UsageMeterProps {
2
- current: number;
3
- limit: number;
4
- }
5
- export declare function UsageMeter({ current, limit, }: UsageMeterProps): import("react").JSX.Element;
6
- export {};
@@ -1,8 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- export function UsageMeter({ current, limit, }) {
4
- const percentage = Math.min(100, (current / limit) * 100);
5
- return (_jsxs("div", { className: "rounded-xl border p-5", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { children: "Usage" }), _jsxs("span", { children: [current, "/", limit] })] }), _jsx("div", { className: "mt-3 h-3 rounded-full bg-gray-100", children: _jsx("div", { className: "h-3 rounded-full bg-black", style: {
6
- width: `${percentage}%`,
7
- } }) })] }));
8
- }
@@ -1,7 +0,0 @@
1
- interface SubscriptionGateProps {
2
- active: boolean;
3
- children: React.ReactNode;
4
- fallback?: React.ReactNode;
5
- }
6
- export declare function SubscriptionGate({ active, children, fallback, }: SubscriptionGateProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined>;
7
- export {};
@@ -1,8 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
- export function SubscriptionGate({ active, children, fallback, }) {
4
- if (!active) {
5
- return (fallback ?? (_jsx("div", { className: "rounded-xl border p-6", children: "Upgrade required." })));
6
- }
7
- return _jsx(_Fragment, { children: children });
8
- }
@@ -1,3 +0,0 @@
1
- export * from "./types";
2
- export * from "./memory";
3
- export * from "./prisma";
@@ -1,3 +0,0 @@
1
- export * from "./types";
2
- export * from "./memory";
3
- export * from "./prisma";
@@ -1,2 +0,0 @@
1
- import type { BillingAdapter } from "./types";
2
- export declare const memoryBillingAdapter: BillingAdapter;
@@ -1,41 +0,0 @@
1
- const subscriptions = new Map();
2
- const usage = new Map();
3
- const teams = new Map();
4
- const billingEvents = new Map();
5
- function usageKey(userId, key, period) {
6
- return `${userId}:${key}:${period}`;
7
- }
8
- export const memoryBillingAdapter = {
9
- async getSubscription(userId) {
10
- return subscriptions.get(userId) ?? null;
11
- },
12
- async upsertSubscription(record) {
13
- subscriptions.set(record.userId, record);
14
- return record;
15
- },
16
- async getUsage(userId, key, period) {
17
- return (usage.get(usageKey(userId, key, period)) ?? 0);
18
- },
19
- async incrementUsage(userId, key, period, amount) {
20
- const id = usageKey(userId, key, period);
21
- const next = (usage.get(id) ?? 0) + amount;
22
- usage.set(id, next);
23
- return next;
24
- },
25
- async getTeam(teamId) {
26
- return teams.get(teamId) ?? null;
27
- },
28
- async upsertTeam(team) {
29
- teams.set(team.teamId, team);
30
- return team;
31
- },
32
- async recordBillingEvent(event) {
33
- const current = billingEvents.get(event.userId) ?? [];
34
- current.unshift(event);
35
- billingEvents.set(event.userId, current);
36
- return event;
37
- },
38
- async getBillingEvents(userId) {
39
- return (billingEvents.get(userId) ?? []);
40
- },
41
- };
@@ -1,28 +0,0 @@
1
- import type { BillingAdapter } from "../types";
2
- import type { SubscriptionRecord } from "../../subscriptions";
3
- import type { TeamRecord } from "../../teams";
4
- import type { BillingEvent } from "../../events";
5
- type PrismaLike = {
6
- subscription: {
7
- findUnique(args: unknown): Promise<SubscriptionRecord | null>;
8
- upsert(args: unknown): Promise<SubscriptionRecord>;
9
- };
10
- usageEvent: {
11
- findUnique(args: unknown): Promise<{
12
- count: number;
13
- } | null>;
14
- upsert(args: unknown): Promise<{
15
- count: number;
16
- }>;
17
- };
18
- team: {
19
- findUnique(args: unknown): Promise<TeamRecord | null>;
20
- upsert(args: unknown): Promise<TeamRecord>;
21
- };
22
- billingEvent: {
23
- create(args: unknown): Promise<BillingEvent>;
24
- findMany(args: unknown): Promise<BillingEvent[]>;
25
- };
26
- };
27
- export declare function createPrismaBillingAdapter(prisma: PrismaLike): BillingAdapter;
28
- export {};
@@ -1,80 +0,0 @@
1
- export function createPrismaBillingAdapter(prisma) {
2
- return {
3
- async getSubscription(userId) {
4
- return prisma.subscription.findUnique({
5
- where: { userId },
6
- });
7
- },
8
- async upsertSubscription(record) {
9
- return prisma.subscription.upsert({
10
- where: {
11
- userId: record.userId,
12
- },
13
- create: record,
14
- update: record,
15
- });
16
- },
17
- async getUsage(userId, key, period) {
18
- const usage = await prisma.usageEvent.findUnique({
19
- where: {
20
- userId_key_period: {
21
- userId,
22
- key,
23
- period,
24
- },
25
- },
26
- });
27
- return usage?.count ?? 0;
28
- },
29
- async incrementUsage(userId, key, period, amount) {
30
- const usage = await prisma.usageEvent.upsert({
31
- where: {
32
- userId_key_period: {
33
- userId,
34
- key,
35
- period,
36
- },
37
- },
38
- create: {
39
- userId,
40
- key,
41
- period,
42
- count: amount,
43
- },
44
- update: {
45
- count: {
46
- increment: amount,
47
- },
48
- },
49
- });
50
- return usage.count;
51
- },
52
- async getTeam(teamId) {
53
- return prisma.team.findUnique({
54
- where: { teamId },
55
- });
56
- },
57
- async upsertTeam(team) {
58
- return prisma.team.upsert({
59
- where: {
60
- teamId: team.teamId,
61
- },
62
- create: team,
63
- update: team,
64
- });
65
- },
66
- async recordBillingEvent(event) {
67
- return prisma.billingEvent.create({
68
- data: event,
69
- });
70
- },
71
- async getBillingEvents(userId) {
72
- return prisma.billingEvent.findMany({
73
- where: { userId },
74
- orderBy: {
75
- createdAt: "desc",
76
- },
77
- });
78
- },
79
- };
80
- }
@@ -1,13 +0,0 @@
1
- import type { SubscriptionRecord } from "../subscriptions";
2
- import type { TeamRecord } from "../teams";
3
- import type { BillingEvent } from "../events";
4
- export interface BillingAdapter {
5
- getSubscription(userId: string): Promise<SubscriptionRecord | null>;
6
- upsertSubscription(record: SubscriptionRecord): Promise<SubscriptionRecord>;
7
- getUsage(userId: string, key: string, period: string): Promise<number>;
8
- incrementUsage(userId: string, key: string, period: string, amount: number): Promise<number>;
9
- getTeam?(teamId: string): Promise<TeamRecord | null>;
10
- upsertTeam?(team: TeamRecord): Promise<TeamRecord>;
11
- recordBillingEvent?(event: BillingEvent): Promise<BillingEvent>;
12
- getBillingEvents?(userId: string): Promise<BillingEvent[]>;
13
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- import type { BillingAdapter } from "./adapters";
2
- export declare function configureBilling({ adapter, }: {
3
- adapter: BillingAdapter;
4
- }): {
5
- adapterConfigured: boolean;
6
- };
@@ -1,13 +0,0 @@
1
- import { setBillingAdapter } from "./subscriptions";
2
- import { setUsageAdapter } from "./usage";
3
- import { setTeamAdapter } from "./teams";
4
- import { setBillingEventAdapter } from "./events";
5
- export function configureBilling({ adapter, }) {
6
- setBillingAdapter(adapter);
7
- setUsageAdapter(adapter);
8
- setTeamAdapter(adapter);
9
- setBillingEventAdapter(adapter);
10
- return {
11
- adapterConfigured: true,
12
- };
13
- }
@@ -1,4 +0,0 @@
1
- export declare function repairSubscriptionByEmail(email: string): Promise<{
2
- customer: import("@/lib/paddle/customers").PaddleCustomer;
3
- subscription: import("./subscriptions").SubscriptionRecord;
4
- }>;
@@ -1,19 +0,0 @@
1
- import { findFirstPaddleCustomerByEmail } from "@/lib/paddle/customers";
2
- import { fetchPaddleSubscriptionsForCustomer } from "@/lib/paddle/subscriptions";
3
- import { refreshSubscriptionFromPaddle } from "./refresh";
4
- export async function repairSubscriptionByEmail(email) {
5
- const customer = await findFirstPaddleCustomerByEmail(email);
6
- if (!customer) {
7
- throw new Error("No Paddle customer found for email");
8
- }
9
- const subscriptions = await fetchPaddleSubscriptionsForCustomer(customer.id);
10
- const activeSubscription = subscriptions.data?.find((sub) => ["active", "trialing", "past_due"].includes(sub.status));
11
- if (!activeSubscription) {
12
- throw new Error("No active Paddle subscription found for customer");
13
- }
14
- const repaired = await refreshSubscriptionFromPaddle(activeSubscription.id);
15
- return {
16
- customer,
17
- subscription: repaired,
18
- };
19
- }
@@ -1 +0,0 @@
1
- export declare function seedDemoBilling(): Promise<void>;
@@ -1,13 +0,0 @@
1
- import { upsertSubscription } from "./subscriptions";
2
- let seeded = false;
3
- export async function seedDemoBilling() {
4
- if (seeded) {
5
- return;
6
- }
7
- await upsertSubscription({
8
- userId: "demo-user-1",
9
- plan: "pro",
10
- status: "active",
11
- });
12
- seeded = true;
13
- }
@@ -1,3 +0,0 @@
1
- import { type FeatureKey } from "./plans";
2
- export declare function hasFeature(userId: string, feature: FeatureKey): Promise<boolean>;
3
- export declare function requireFeature(userId: string, feature: FeatureKey): Promise<boolean>;
@@ -1,16 +0,0 @@
1
- import { plans } from "./plans";
2
- import { getSubscription, isSubscriptionActive } from "./subscriptions";
3
- export async function hasFeature(userId, feature) {
4
- const subscription = await getSubscription(userId);
5
- if (!isSubscriptionActive(subscription)) {
6
- return false;
7
- }
8
- return plans[subscription.plan].features.includes(feature);
9
- }
10
- export async function requireFeature(userId, feature) {
11
- const allowed = await hasFeature(userId, feature);
12
- if (!allowed) {
13
- throw new Error(`Feature not available: ${feature}`);
14
- }
15
- return true;
16
- }