@ai-billing/nextjs 0.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.
Files changed (93) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +50 -0
  3. package/dist/index.cjs +36 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +4 -0
  6. package/dist/index.d.ts +4 -0
  7. package/dist/index.js +10 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/polar/CreditTopUpPolar.cjs +278 -0
  10. package/dist/polar/CreditTopUpPolar.cjs.map +1 -0
  11. package/dist/polar/CreditTopUpPolar.d.cts +9 -0
  12. package/dist/polar/CreditTopUpPolar.d.ts +9 -0
  13. package/dist/polar/CreditTopUpPolar.js +244 -0
  14. package/dist/polar/CreditTopUpPolar.js.map +1 -0
  15. package/dist/polar/CreditUsagePolar.cjs +133 -0
  16. package/dist/polar/CreditUsagePolar.cjs.map +1 -0
  17. package/dist/polar/CreditUsagePolar.d.cts +10 -0
  18. package/dist/polar/CreditUsagePolar.d.ts +10 -0
  19. package/dist/polar/CreditUsagePolar.js +107 -0
  20. package/dist/polar/CreditUsagePolar.js.map +1 -0
  21. package/dist/polar/createCheckout.cjs +47 -0
  22. package/dist/polar/createCheckout.cjs.map +1 -0
  23. package/dist/polar/createCheckout.d.cts +9 -0
  24. package/dist/polar/createCheckout.d.ts +9 -0
  25. package/dist/polar/createCheckout.js +23 -0
  26. package/dist/polar/createCheckout.js.map +1 -0
  27. package/dist/polar/fetchPolarConfig.cjs +52 -0
  28. package/dist/polar/fetchPolarConfig.cjs.map +1 -0
  29. package/dist/polar/fetchPolarConfig.d.cts +6 -0
  30. package/dist/polar/fetchPolarConfig.d.ts +6 -0
  31. package/dist/polar/fetchPolarConfig.js +28 -0
  32. package/dist/polar/fetchPolarConfig.js.map +1 -0
  33. package/dist/polar/fetchPolarUsage.cjs +64 -0
  34. package/dist/polar/fetchPolarUsage.cjs.map +1 -0
  35. package/dist/polar/fetchPolarUsage.d.cts +9 -0
  36. package/dist/polar/fetchPolarUsage.d.ts +9 -0
  37. package/dist/polar/fetchPolarUsage.js +40 -0
  38. package/dist/polar/fetchPolarUsage.js.map +1 -0
  39. package/dist/polar/fetchTopUpConfig.cjs +55 -0
  40. package/dist/polar/fetchTopUpConfig.cjs.map +1 -0
  41. package/dist/polar/fetchTopUpConfig.d.cts +10 -0
  42. package/dist/polar/fetchTopUpConfig.d.ts +10 -0
  43. package/dist/polar/fetchTopUpConfig.js +31 -0
  44. package/dist/polar/fetchTopUpConfig.js.map +1 -0
  45. package/dist/polar/types.cjs +17 -0
  46. package/dist/polar/types.cjs.map +1 -0
  47. package/dist/polar/types.d.cts +18 -0
  48. package/dist/polar/types.d.ts +18 -0
  49. package/dist/polar/types.js +1 -0
  50. package/dist/polar/types.js.map +1 -0
  51. package/dist/server.cjs +44 -0
  52. package/dist/server.cjs.map +1 -0
  53. package/dist/server.d.cts +8 -0
  54. package/dist/server.d.ts +8 -0
  55. package/dist/server.js +15 -0
  56. package/dist/server.js.map +1 -0
  57. package/dist/stripe/CreditUsageStripe.cjs +158 -0
  58. package/dist/stripe/CreditUsageStripe.cjs.map +1 -0
  59. package/dist/stripe/CreditUsageStripe.d.cts +11 -0
  60. package/dist/stripe/CreditUsageStripe.d.ts +11 -0
  61. package/dist/stripe/CreditUsageStripe.js +132 -0
  62. package/dist/stripe/CreditUsageStripe.js.map +1 -0
  63. package/dist/stripe/fetchStripeConfig.cjs +52 -0
  64. package/dist/stripe/fetchStripeConfig.cjs.map +1 -0
  65. package/dist/stripe/fetchStripeConfig.d.cts +6 -0
  66. package/dist/stripe/fetchStripeConfig.d.ts +6 -0
  67. package/dist/stripe/fetchStripeConfig.js +28 -0
  68. package/dist/stripe/fetchStripeConfig.js.map +1 -0
  69. package/dist/stripe/fetchStripeUsage.cjs +67 -0
  70. package/dist/stripe/fetchStripeUsage.cjs.map +1 -0
  71. package/dist/stripe/fetchStripeUsage.d.cts +9 -0
  72. package/dist/stripe/fetchStripeUsage.d.ts +9 -0
  73. package/dist/stripe/fetchStripeUsage.js +33 -0
  74. package/dist/stripe/fetchStripeUsage.js.map +1 -0
  75. package/dist/stripe/types.cjs +17 -0
  76. package/dist/stripe/types.cjs.map +1 -0
  77. package/dist/stripe/types.d.cts +9 -0
  78. package/dist/stripe/types.d.ts +9 -0
  79. package/dist/stripe/types.js +1 -0
  80. package/dist/stripe/types.js.map +1 -0
  81. package/dist/styles.cjs +83 -0
  82. package/dist/styles.cjs.map +1 -0
  83. package/dist/styles.d.cts +11 -0
  84. package/dist/styles.d.ts +11 -0
  85. package/dist/styles.js +53 -0
  86. package/dist/styles.js.map +1 -0
  87. package/dist/utils.cjs +53 -0
  88. package/dist/utils.cjs.map +1 -0
  89. package/dist/utils.d.cts +20 -0
  90. package/dist/utils.d.ts +20 -0
  91. package/dist/utils.js +26 -0
  92. package/dist/utils.js.map +1 -0
  93. package/package.json +82 -0
@@ -0,0 +1,244 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import React, { useState, useEffect, useTransition } from "react";
4
+ import { cardBase, mutedText } from "../styles.js";
5
+ import { formatCents, taxMessages } from "../utils.js";
6
+ import { createCheckout as checkoutAction } from "./createCheckout.js";
7
+ import { fetchTopUpConfig } from "./fetchTopUpConfig.js";
8
+ function LightningIcon({ selected }) {
9
+ return /* @__PURE__ */ jsx(
10
+ "div",
11
+ {
12
+ style: {
13
+ width: 36,
14
+ height: 36,
15
+ borderRadius: 10,
16
+ display: "flex",
17
+ alignItems: "center",
18
+ justifyContent: "center",
19
+ flexShrink: 0,
20
+ transition: "background 0.15s",
21
+ background: selected ? "var(--foreground)" : "var(--muted)"
22
+ },
23
+ children: /* @__PURE__ */ jsx("svg", { width: "18", height: "18", viewBox: "0 0 24 24", fill: "none", children: /* @__PURE__ */ jsx(
24
+ "path",
25
+ {
26
+ d: "M13 2L4.5 13.5H11L10 22L20.5 10.5H14L13 2Z",
27
+ fill: selected ? "var(--background)" : "var(--muted-foreground)",
28
+ stroke: selected ? "var(--background)" : "var(--muted-foreground)",
29
+ strokeWidth: "0.5",
30
+ strokeLinejoin: "round"
31
+ }
32
+ ) })
33
+ }
34
+ );
35
+ }
36
+ const CreditTopUpPolar = React.forwardRef(
37
+ ({
38
+ userId,
39
+ title = "Choose a credit bundle to top up your workspace balance.",
40
+ className,
41
+ style,
42
+ ...props
43
+ }, ref) => {
44
+ const cls = (className ?? "").trim();
45
+ const [packages, setPackages] = useState([]);
46
+ const [taxBehavior, setTaxBehavior] = useState();
47
+ const [loading, setLoading] = useState(true);
48
+ const [selectedIdx, setSelectedIdx] = useState(0);
49
+ const [isPending, startTransition] = useTransition();
50
+ const [error, setError] = useState(null);
51
+ useEffect(() => {
52
+ let cancelled = false;
53
+ setLoading(true);
54
+ (async () => {
55
+ try {
56
+ const config = await fetchTopUpConfig();
57
+ if (cancelled) return;
58
+ setPackages(config.packages);
59
+ if (config.taxBehavior) setTaxBehavior(config.taxBehavior);
60
+ } catch {
61
+ } finally {
62
+ if (!cancelled) setLoading(false);
63
+ }
64
+ })();
65
+ return () => {
66
+ cancelled = true;
67
+ };
68
+ }, []);
69
+ const selected = packages[selectedIdx] ?? null;
70
+ function handlePurchase() {
71
+ if (!selected) return;
72
+ setError(null);
73
+ startTransition(async () => {
74
+ try {
75
+ const url = await checkoutAction(
76
+ selected.id,
77
+ userId,
78
+ window.location.origin
79
+ );
80
+ window.location.href = url;
81
+ } catch (e) {
82
+ setError(String(e));
83
+ }
84
+ });
85
+ }
86
+ if (loading) {
87
+ return /* @__PURE__ */ jsx(
88
+ "div",
89
+ {
90
+ ref,
91
+ className: cls,
92
+ style: { ...cardBase, height: 120, opacity: 0.5, ...style },
93
+ ...props
94
+ }
95
+ );
96
+ }
97
+ if (packages.length === 0) {
98
+ return /* @__PURE__ */ jsx(
99
+ "div",
100
+ {
101
+ ref,
102
+ className: cls,
103
+ style: { ...cardBase, ...style },
104
+ ...props,
105
+ children: /* @__PURE__ */ jsx("p", { style: mutedText, children: "No top-up packages available." })
106
+ }
107
+ );
108
+ }
109
+ return /* @__PURE__ */ jsxs(
110
+ "div",
111
+ {
112
+ ref,
113
+ className: cls,
114
+ style: {
115
+ ...cardBase,
116
+ display: "flex",
117
+ flexDirection: "column",
118
+ ...style
119
+ },
120
+ ...props,
121
+ children: [
122
+ title && /* @__PURE__ */ jsx("p", { style: { ...mutedText, marginBottom: 12 }, children: title }),
123
+ /* @__PURE__ */ jsx("div", { style: { display: "flex", flexDirection: "column", gap: 6 }, children: packages.map((pkg, i) => {
124
+ const isSelected = i === selectedIdx;
125
+ return /* @__PURE__ */ jsxs(
126
+ "div",
127
+ {
128
+ role: "button",
129
+ tabIndex: 0,
130
+ onClick: () => setSelectedIdx(i),
131
+ onKeyDown: (e) => (e.key === "Enter" || e.key === " ") && setSelectedIdx(i),
132
+ style: {
133
+ display: "flex",
134
+ alignItems: "center",
135
+ gap: 12,
136
+ padding: "10px 14px",
137
+ borderRadius: "var(--radius, 0.75rem)",
138
+ background: isSelected ? "var(--muted)" : "transparent",
139
+ border: isSelected ? "1px solid var(--border)" : "1px solid transparent",
140
+ cursor: "pointer",
141
+ transition: "background 0.15s, border-color 0.15s",
142
+ userSelect: "none",
143
+ outline: "none"
144
+ },
145
+ children: [
146
+ /* @__PURE__ */ jsx(LightningIcon, { selected: isSelected }),
147
+ /* @__PURE__ */ jsx("div", { style: { flex: 1, minWidth: 0 }, children: /* @__PURE__ */ jsxs(
148
+ "p",
149
+ {
150
+ style: {
151
+ margin: 0,
152
+ fontSize: 14,
153
+ fontWeight: 600,
154
+ color: "var(--card-foreground)",
155
+ lineHeight: 1.3
156
+ },
157
+ children: [
158
+ "Top-up ",
159
+ formatCents(pkg.priceCents)
160
+ ]
161
+ }
162
+ ) }),
163
+ /* @__PURE__ */ jsx(
164
+ "span",
165
+ {
166
+ style: {
167
+ flexShrink: 0,
168
+ fontSize: 16,
169
+ fontWeight: 700,
170
+ color: "var(--card-foreground)"
171
+ },
172
+ children: formatCents(pkg.priceCents)
173
+ }
174
+ )
175
+ ]
176
+ },
177
+ pkg.id
178
+ );
179
+ }) }),
180
+ /* @__PURE__ */ jsxs("div", { style: { marginTop: 20 }, children: [
181
+ /* @__PURE__ */ jsx(
182
+ "button",
183
+ {
184
+ type: "button",
185
+ disabled: isPending || !selected,
186
+ onClick: handlePurchase,
187
+ style: {
188
+ fontFamily: "inherit",
189
+ width: "100%",
190
+ height: 38,
191
+ borderRadius: "var(--radius, 0.5rem)",
192
+ background: "var(--primary)",
193
+ color: "var(--primary-foreground)",
194
+ border: 0,
195
+ fontSize: 14,
196
+ fontWeight: 500,
197
+ cursor: isPending || !selected ? "not-allowed" : "pointer",
198
+ opacity: isPending ? 0.6 : 1,
199
+ display: "flex",
200
+ alignItems: "center",
201
+ justifyContent: "center",
202
+ transition: "opacity 0.15s"
203
+ },
204
+ children: isPending ? "Processing\u2026" : selected ? /* @__PURE__ */ jsxs(Fragment, { children: [
205
+ "Top-up ",
206
+ formatCents(selected.priceCents)
207
+ ] }) : "Select a package"
208
+ }
209
+ ),
210
+ error && /* @__PURE__ */ jsx(
211
+ "p",
212
+ {
213
+ style: {
214
+ marginTop: 8,
215
+ fontSize: 12,
216
+ color: "#ef4444",
217
+ textAlign: "center"
218
+ },
219
+ children: error
220
+ }
221
+ )
222
+ ] }),
223
+ taxBehavior && /* @__PURE__ */ jsx(
224
+ "p",
225
+ {
226
+ style: {
227
+ marginTop: 14,
228
+ fontSize: 11,
229
+ color: "var(--muted-foreground)",
230
+ textAlign: "center"
231
+ },
232
+ children: taxMessages[taxBehavior]
233
+ }
234
+ )
235
+ ]
236
+ }
237
+ );
238
+ }
239
+ );
240
+ CreditTopUpPolar.displayName = "CreditTopUpPolar";
241
+ export {
242
+ CreditTopUpPolar
243
+ };
244
+ //# sourceMappingURL=CreditTopUpPolar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/polar/CreditTopUpPolar.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useEffect, useTransition } from 'react';\nimport { cardBase, mutedText } from '../styles.js';\nimport { formatCents, taxMessages } from '../utils.js';\nimport { createCheckout as checkoutAction } from './createCheckout.js';\nimport { fetchTopUpConfig } from './fetchTopUpConfig.js';\nimport type { CreditPackage } from './types.js';\n\nexport interface CreditTopUpPolarProps extends React.HTMLAttributes<HTMLDivElement> {\n userId: string;\n title?: string;\n}\n\nfunction LightningIcon({ selected }: { selected: boolean }) {\n return (\n <div\n style={{\n width: 36,\n height: 36,\n borderRadius: 10,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n transition: 'background 0.15s',\n background: selected ? 'var(--foreground)' : 'var(--muted)',\n }}\n >\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M13 2L4.5 13.5H11L10 22L20.5 10.5H14L13 2Z\"\n fill={selected ? 'var(--background)' : 'var(--muted-foreground)'}\n stroke={selected ? 'var(--background)' : 'var(--muted-foreground)'}\n strokeWidth=\"0.5\"\n strokeLinejoin=\"round\"\n />\n </svg>\n </div>\n );\n}\n\nexport const CreditTopUpPolar = React.forwardRef<\n HTMLDivElement,\n CreditTopUpPolarProps\n>(\n (\n {\n userId,\n title = 'Choose a credit bundle to top up your workspace balance.',\n className,\n style,\n ...props\n },\n ref,\n ) => {\n const cls = (className ?? '').trim();\n const [packages, setPackages] = useState<CreditPackage[]>([]);\n const [taxBehavior, setTaxBehavior] = useState<\n 'inclusive' | 'exclusive' | 'location'\n >();\n const [loading, setLoading] = useState(true);\n const [selectedIdx, setSelectedIdx] = useState(0);\n const [isPending, startTransition] = useTransition();\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n try {\n const config = await fetchTopUpConfig();\n if (cancelled) return;\n setPackages(config.packages);\n if (config.taxBehavior) setTaxBehavior(config.taxBehavior);\n } catch {\n /* no data */\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, []);\n\n const selected = packages[selectedIdx] ?? null;\n\n function handlePurchase() {\n if (!selected) return;\n setError(null);\n startTransition(async () => {\n try {\n const url = await checkoutAction(\n selected.id,\n userId,\n window.location.origin,\n );\n window.location.href = url;\n } catch (e) {\n setError(String(e));\n }\n });\n }\n\n if (loading) {\n return (\n <div\n ref={ref}\n className={cls}\n style={{ ...cardBase, height: 120, opacity: 0.5, ...style }}\n {...props}\n />\n );\n }\n\n if (packages.length === 0) {\n return (\n <div\n ref={ref}\n className={cls}\n style={{ ...cardBase, ...style }}\n {...props}\n >\n <p style={mutedText}>No top-up packages available.</p>\n </div>\n );\n }\n\n return (\n <div\n ref={ref}\n className={cls}\n style={{\n ...cardBase,\n display: 'flex',\n flexDirection: 'column',\n ...style,\n }}\n {...props}\n >\n {title && <p style={{ ...mutedText, marginBottom: 12 }}>{title}</p>}\n\n <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>\n {packages.map((pkg, i) => {\n const isSelected = i === selectedIdx;\n return (\n <div\n key={pkg.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setSelectedIdx(i)}\n onKeyDown={e =>\n (e.key === 'Enter' || e.key === ' ') && setSelectedIdx(i)\n }\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: '10px 14px',\n borderRadius: 'var(--radius, 0.75rem)',\n background: isSelected ? 'var(--muted)' : 'transparent',\n border: isSelected\n ? '1px solid var(--border)'\n : '1px solid transparent',\n cursor: 'pointer',\n transition: 'background 0.15s, border-color 0.15s',\n userSelect: 'none',\n outline: 'none',\n }}\n >\n <LightningIcon selected={isSelected} />\n <div style={{ flex: 1, minWidth: 0 }}>\n <p\n style={{\n margin: 0,\n fontSize: 14,\n fontWeight: 600,\n color: 'var(--card-foreground)',\n lineHeight: 1.3,\n }}\n >\n Top-up {formatCents(pkg.priceCents)}\n </p>\n </div>\n <span\n style={{\n flexShrink: 0,\n fontSize: 16,\n fontWeight: 700,\n color: 'var(--card-foreground)',\n }}\n >\n {formatCents(pkg.priceCents)}\n </span>\n </div>\n );\n })}\n </div>\n\n <div style={{ marginTop: 20 }}>\n <button\n type=\"button\"\n disabled={isPending || !selected}\n onClick={handlePurchase}\n style={{\n fontFamily: 'inherit',\n width: '100%',\n height: 38,\n borderRadius: 'var(--radius, 0.5rem)',\n background: 'var(--primary)',\n color: 'var(--primary-foreground)',\n border: 0,\n fontSize: 14,\n fontWeight: 500,\n cursor: isPending || !selected ? 'not-allowed' : 'pointer',\n opacity: isPending ? 0.6 : 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n transition: 'opacity 0.15s',\n }}\n >\n {isPending ? (\n 'Processing…'\n ) : selected ? (\n <>Top-up {formatCents(selected.priceCents)}</>\n ) : (\n 'Select a package'\n )}\n </button>\n {error && (\n <p\n style={{\n marginTop: 8,\n fontSize: 12,\n color: '#ef4444',\n textAlign: 'center',\n }}\n >\n {error}\n </p>\n )}\n </div>\n\n {taxBehavior && (\n <p\n style={{\n marginTop: 14,\n fontSize: 11,\n color: 'var(--muted-foreground)',\n textAlign: 'center',\n }}\n >\n {taxMessages[taxBehavior]}\n </p>\n )}\n </div>\n );\n },\n);\nCreditTopUpPolar.displayName = 'CreditTopUpPolar';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ "use client";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __export = (target, all) => {
10
+ for (var name in all)
11
+ __defProp(target, name, { get: all[name], enumerable: true });
12
+ };
13
+ var __copyProps = (to, from, except, desc) => {
14
+ if (from && typeof from === "object" || typeof from === "function") {
15
+ for (let key of __getOwnPropNames(from))
16
+ if (!__hasOwnProp.call(to, key) && key !== except)
17
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
+ }
19
+ return to;
20
+ };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
29
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
+ var CreditUsagePolar_exports = {};
31
+ __export(CreditUsagePolar_exports, {
32
+ CreditUsagePolar: () => CreditUsagePolar
33
+ });
34
+ module.exports = __toCommonJS(CreditUsagePolar_exports);
35
+ var import_jsx_runtime = require("react/jsx-runtime");
36
+ var import_react = __toESM(require("react"), 1);
37
+ var import_styles = require("../styles.js");
38
+ var import_utils = require("../utils.js");
39
+ var import_fetchPolarUsage = require("./fetchPolarUsage.js");
40
+ const CreditUsagePolar = import_react.default.forwardRef(({ userId, budget, label, className, style, ...props }, ref) => {
41
+ const cls = (className ?? "").trim();
42
+ const [data, setData] = (0, import_react.useState)(null);
43
+ const [loading, setLoading] = (0, import_react.useState)(true);
44
+ (0, import_react.useEffect)(() => {
45
+ let cancelled = false;
46
+ setLoading(true);
47
+ (async () => {
48
+ try {
49
+ const result = await (0, import_fetchPolarUsage.fetchPolarUsage)(userId);
50
+ if (!cancelled) setData(result);
51
+ } catch {
52
+ if (!cancelled) setData(null);
53
+ } finally {
54
+ if (!cancelled) setLoading(false);
55
+ }
56
+ })();
57
+ return () => {
58
+ cancelled = true;
59
+ };
60
+ }, [userId]);
61
+ if (loading) {
62
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
63
+ "div",
64
+ {
65
+ ref,
66
+ className: cls,
67
+ style: { ...import_styles.cardBase, height: 120, opacity: 0.5, ...style },
68
+ ...props
69
+ }
70
+ );
71
+ }
72
+ if (!data?.found) {
73
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
74
+ "div",
75
+ {
76
+ ref,
77
+ className: cls,
78
+ style: { ...import_styles.cardBase, ...style },
79
+ ...props,
80
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: import_styles.mutedText, children: "No usage data available." })
81
+ }
82
+ );
83
+ }
84
+ const meterName = label ?? data.meterName;
85
+ const useBudget = budget !== void 0 && budget > 0;
86
+ const showBar = useBudget || data.creditedUnits > 0;
87
+ const cap = showBar ? useBudget ? budget : data.creditedUnits : 0;
88
+ const pct = cap > 0 ? Math.min(data.consumedUnits / cap * 100, 100) : 0;
89
+ const color = (0, import_utils.barColor)(pct);
90
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { ref, className: cls, style: { ...import_styles.cardBase, ...style }, ...props, children: [
91
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { style: import_styles.heading, children: meterName }),
92
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
93
+ "div",
94
+ {
95
+ style: {
96
+ display: "flex",
97
+ alignItems: "baseline",
98
+ gap: 6,
99
+ margin: "0 0 14px"
100
+ },
101
+ children: [
102
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: import_styles.bigNumber, children: (0, import_utils.fmt)(data.consumedUnits, "$") }),
103
+ showBar && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: import_styles.subLabel, children: [
104
+ "/ ",
105
+ (0, import_utils.fmt)(cap, "$")
106
+ ] })
107
+ ]
108
+ }
109
+ ),
110
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: import_styles.barTrack, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
111
+ "div",
112
+ {
113
+ style: {
114
+ height: "100%",
115
+ width: `${pct}%`,
116
+ borderRadius: 3,
117
+ background: showBar ? color : "#e5e7eb",
118
+ transition: "width 0.3s ease"
119
+ }
120
+ }
121
+ ) }),
122
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: import_styles.barLabels, children: [
123
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: showBar ? `${pct.toFixed(0)}% ${useBudget ? "used" : "consumed"}` : "0 credits" }),
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: showBar ? `${(0, import_utils.fmt)(Math.max(0, cap - data.consumedUnits), "$")} remaining` : `${(0, import_utils.fmt)(data.consumedUnits, "$")} consumed` })
125
+ ] })
126
+ ] });
127
+ });
128
+ CreditUsagePolar.displayName = "CreditUsagePolar";
129
+ // Annotate the CommonJS export names for ESM import in node:
130
+ 0 && (module.exports = {
131
+ CreditUsagePolar
132
+ });
133
+ //# sourceMappingURL=CreditUsagePolar.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/polar/CreditUsagePolar.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport {\n cardBase,\n heading,\n mutedText,\n bigNumber,\n subLabel,\n barTrack,\n barLabels,\n} from '../styles.js';\nimport { barColor, fmt } from '../utils.js';\nimport { fetchPolarUsage } from './fetchPolarUsage.js';\nimport type { PolarUsageData } from './types.js';\n\nexport interface CreditUsagePolarProps extends React.HTMLAttributes<HTMLDivElement> {\n userId: string;\n budget?: number;\n label?: string;\n}\n\nexport const CreditUsagePolar = React.forwardRef<\n HTMLDivElement,\n CreditUsagePolarProps\n>(({ userId, budget, label, className, style, ...props }, ref) => {\n const cls = (className ?? '').trim();\n const [data, setData] = useState<PolarUsageData | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n try {\n const result = await fetchPolarUsage(userId);\n if (!cancelled) setData(result);\n } catch {\n if (!cancelled) setData(null);\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [userId]);\n\n if (loading) {\n return (\n <div\n ref={ref}\n className={cls}\n style={{ ...cardBase, height: 120, opacity: 0.5, ...style }}\n {...props}\n />\n );\n }\n\n if (!data?.found) {\n return (\n <div\n ref={ref}\n className={cls}\n style={{ ...cardBase, ...style }}\n {...props}\n >\n <p style={mutedText}>No usage data available.</p>\n </div>\n );\n }\n\n const meterName = label ?? data.meterName;\n const useBudget = budget !== undefined && budget > 0;\n const showBar = useBudget || data.creditedUnits > 0;\n const cap = showBar ? (useBudget ? budget! : data.creditedUnits) : 0;\n const pct = cap > 0 ? Math.min((data.consumedUnits / cap) * 100, 100) : 0;\n const color = barColor(pct);\n\n return (\n <div ref={ref} className={cls} style={{ ...cardBase, ...style }} {...props}>\n <p style={heading}>{meterName}</p>\n <div\n style={{\n display: 'flex',\n alignItems: 'baseline',\n gap: 6,\n margin: '0 0 14px',\n }}\n >\n <span style={bigNumber}>{fmt(data.consumedUnits, '$')}</span>\n {showBar && <span style={subLabel}>/ {fmt(cap, '$')}</span>}\n </div>\n <div style={barTrack}>\n <div\n style={{\n height: '100%',\n width: `${pct}%`,\n borderRadius: 3,\n background: showBar ? color : '#e5e7eb',\n transition: 'width 0.3s ease',\n }}\n />\n </div>\n <div style={barLabels}>\n <span>\n {showBar\n ? `${pct.toFixed(0)}% ${useBudget ? 'used' : 'consumed'}`\n : '0 credits'}\n </span>\n <span>\n {showBar\n ? `${fmt(Math.max(0, cap - data.consumedUnits), '$')} remaining`\n : `${fmt(data.consumedUnits, '$')} consumed`}\n </span>\n </div>\n </div>\n );\n});\nCreditUsagePolar.displayName = 'CreditUsagePolar';\n"],"mappings":"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","names":["React"]}
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+
3
+ interface CreditUsagePolarProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ userId: string;
5
+ budget?: number;
6
+ label?: string;
7
+ }
8
+ declare const CreditUsagePolar: React.ForwardRefExoticComponent<CreditUsagePolarProps & React.RefAttributes<HTMLDivElement>>;
9
+
10
+ export { CreditUsagePolar, type CreditUsagePolarProps };
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+
3
+ interface CreditUsagePolarProps extends React.HTMLAttributes<HTMLDivElement> {
4
+ userId: string;
5
+ budget?: number;
6
+ label?: string;
7
+ }
8
+ declare const CreditUsagePolar: React.ForwardRefExoticComponent<CreditUsagePolarProps & React.RefAttributes<HTMLDivElement>>;
9
+
10
+ export { CreditUsagePolar, type CreditUsagePolarProps };
@@ -0,0 +1,107 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import React, { useState, useEffect } from "react";
4
+ import {
5
+ cardBase,
6
+ heading,
7
+ mutedText,
8
+ bigNumber,
9
+ subLabel,
10
+ barTrack,
11
+ barLabels
12
+ } from "../styles.js";
13
+ import { barColor, fmt } from "../utils.js";
14
+ import { fetchPolarUsage } from "./fetchPolarUsage.js";
15
+ const CreditUsagePolar = React.forwardRef(({ userId, budget, label, className, style, ...props }, ref) => {
16
+ const cls = (className ?? "").trim();
17
+ const [data, setData] = useState(null);
18
+ const [loading, setLoading] = useState(true);
19
+ useEffect(() => {
20
+ let cancelled = false;
21
+ setLoading(true);
22
+ (async () => {
23
+ try {
24
+ const result = await fetchPolarUsage(userId);
25
+ if (!cancelled) setData(result);
26
+ } catch {
27
+ if (!cancelled) setData(null);
28
+ } finally {
29
+ if (!cancelled) setLoading(false);
30
+ }
31
+ })();
32
+ return () => {
33
+ cancelled = true;
34
+ };
35
+ }, [userId]);
36
+ if (loading) {
37
+ return /* @__PURE__ */ jsx(
38
+ "div",
39
+ {
40
+ ref,
41
+ className: cls,
42
+ style: { ...cardBase, height: 120, opacity: 0.5, ...style },
43
+ ...props
44
+ }
45
+ );
46
+ }
47
+ if (!data?.found) {
48
+ return /* @__PURE__ */ jsx(
49
+ "div",
50
+ {
51
+ ref,
52
+ className: cls,
53
+ style: { ...cardBase, ...style },
54
+ ...props,
55
+ children: /* @__PURE__ */ jsx("p", { style: mutedText, children: "No usage data available." })
56
+ }
57
+ );
58
+ }
59
+ const meterName = label ?? data.meterName;
60
+ const useBudget = budget !== void 0 && budget > 0;
61
+ const showBar = useBudget || data.creditedUnits > 0;
62
+ const cap = showBar ? useBudget ? budget : data.creditedUnits : 0;
63
+ const pct = cap > 0 ? Math.min(data.consumedUnits / cap * 100, 100) : 0;
64
+ const color = barColor(pct);
65
+ return /* @__PURE__ */ jsxs("div", { ref, className: cls, style: { ...cardBase, ...style }, ...props, children: [
66
+ /* @__PURE__ */ jsx("p", { style: heading, children: meterName }),
67
+ /* @__PURE__ */ jsxs(
68
+ "div",
69
+ {
70
+ style: {
71
+ display: "flex",
72
+ alignItems: "baseline",
73
+ gap: 6,
74
+ margin: "0 0 14px"
75
+ },
76
+ children: [
77
+ /* @__PURE__ */ jsx("span", { style: bigNumber, children: fmt(data.consumedUnits, "$") }),
78
+ showBar && /* @__PURE__ */ jsxs("span", { style: subLabel, children: [
79
+ "/ ",
80
+ fmt(cap, "$")
81
+ ] })
82
+ ]
83
+ }
84
+ ),
85
+ /* @__PURE__ */ jsx("div", { style: barTrack, children: /* @__PURE__ */ jsx(
86
+ "div",
87
+ {
88
+ style: {
89
+ height: "100%",
90
+ width: `${pct}%`,
91
+ borderRadius: 3,
92
+ background: showBar ? color : "#e5e7eb",
93
+ transition: "width 0.3s ease"
94
+ }
95
+ }
96
+ ) }),
97
+ /* @__PURE__ */ jsxs("div", { style: barLabels, children: [
98
+ /* @__PURE__ */ jsx("span", { children: showBar ? `${pct.toFixed(0)}% ${useBudget ? "used" : "consumed"}` : "0 credits" }),
99
+ /* @__PURE__ */ jsx("span", { children: showBar ? `${fmt(Math.max(0, cap - data.consumedUnits), "$")} remaining` : `${fmt(data.consumedUnits, "$")} consumed` })
100
+ ] })
101
+ ] });
102
+ });
103
+ CreditUsagePolar.displayName = "CreditUsagePolar";
104
+ export {
105
+ CreditUsagePolar
106
+ };
107
+ //# sourceMappingURL=CreditUsagePolar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/polar/CreditUsagePolar.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState, useEffect } from 'react';\nimport {\n cardBase,\n heading,\n mutedText,\n bigNumber,\n subLabel,\n barTrack,\n barLabels,\n} from '../styles.js';\nimport { barColor, fmt } from '../utils.js';\nimport { fetchPolarUsage } from './fetchPolarUsage.js';\nimport type { PolarUsageData } from './types.js';\n\nexport interface CreditUsagePolarProps extends React.HTMLAttributes<HTMLDivElement> {\n userId: string;\n budget?: number;\n label?: string;\n}\n\nexport const CreditUsagePolar = React.forwardRef<\n HTMLDivElement,\n CreditUsagePolarProps\n>(({ userId, budget, label, className, style, ...props }, ref) => {\n const cls = (className ?? '').trim();\n const [data, setData] = useState<PolarUsageData | null>(null);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n try {\n const result = await fetchPolarUsage(userId);\n if (!cancelled) setData(result);\n } catch {\n if (!cancelled) setData(null);\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [userId]);\n\n if (loading) {\n return (\n <div\n ref={ref}\n className={cls}\n style={{ ...cardBase, height: 120, opacity: 0.5, ...style }}\n {...props}\n />\n );\n }\n\n if (!data?.found) {\n return (\n <div\n ref={ref}\n className={cls}\n style={{ ...cardBase, ...style }}\n {...props}\n >\n <p style={mutedText}>No usage data available.</p>\n </div>\n );\n }\n\n const meterName = label ?? data.meterName;\n const useBudget = budget !== undefined && budget > 0;\n const showBar = useBudget || data.creditedUnits > 0;\n const cap = showBar ? (useBudget ? budget! : data.creditedUnits) : 0;\n const pct = cap > 0 ? Math.min((data.consumedUnits / cap) * 100, 100) : 0;\n const color = barColor(pct);\n\n return (\n <div ref={ref} className={cls} style={{ ...cardBase, ...style }} {...props}>\n <p style={heading}>{meterName}</p>\n <div\n style={{\n display: 'flex',\n alignItems: 'baseline',\n gap: 6,\n margin: '0 0 14px',\n }}\n >\n <span style={bigNumber}>{fmt(data.consumedUnits, '$')}</span>\n {showBar && <span style={subLabel}>/ {fmt(cap, '$')}</span>}\n </div>\n <div style={barTrack}>\n <div\n style={{\n height: '100%',\n width: `${pct}%`,\n borderRadius: 3,\n background: showBar ? color : '#e5e7eb',\n transition: 'width 0.3s ease',\n }}\n />\n </div>\n <div style={barLabels}>\n <span>\n {showBar\n ? `${pct.toFixed(0)}% ${useBudget ? 'used' : 'consumed'}`\n : '0 credits'}\n </span>\n <span>\n {showBar\n ? `${fmt(Math.max(0, cap - data.consumedUnits), '$')} remaining`\n : `${fmt(data.consumedUnits, '$')} consumed`}\n </span>\n </div>\n </div>\n );\n});\nCreditUsagePolar.displayName = 'CreditUsagePolar';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ "use server";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var createCheckout_exports = {};
21
+ __export(createCheckout_exports, {
22
+ createCheckout: () => createCheckout
23
+ });
24
+ module.exports = __toCommonJS(createCheckout_exports);
25
+ var import_sdk = require("@polar-sh/sdk");
26
+ async function createCheckout(productId, userId, origin) {
27
+ const polar = new import_sdk.Polar({
28
+ accessToken: process.env.POLAR_ACCESS_TOKEN,
29
+ server: process.env.POLAR_SERVER ?? "sandbox"
30
+ });
31
+ try {
32
+ const checkout = await polar.checkouts.create({
33
+ products: [productId],
34
+ externalCustomerId: userId,
35
+ successUrl: `${origin}/usage`
36
+ });
37
+ return checkout.url;
38
+ } catch (error) {
39
+ console.error("Create checkout failed:", error);
40
+ throw new Error("Failed to create checkout", { cause: error });
41
+ }
42
+ }
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ createCheckout
46
+ });
47
+ //# sourceMappingURL=createCheckout.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/polar/createCheckout.ts"],"sourcesContent":["'use server';\n\nimport { Polar } from '@polar-sh/sdk';\n\n/**\n * Creates a Polar checkout session and returns the URL.\n * @param productId - the Polar product ID\n * @param userId - the external customer ID\n * @param origin - the application origin for the success URL\n */\nexport async function createCheckout(\n productId: string,\n userId: string,\n origin: string,\n) {\n const polar = new Polar({\n accessToken: process.env.POLAR_ACCESS_TOKEN,\n server: (process.env.POLAR_SERVER as 'sandbox' | 'production') ?? 'sandbox',\n });\n\n try {\n const checkout = await polar.checkouts.create({\n products: [productId],\n externalCustomerId: userId,\n successUrl: `${origin}/usage`,\n });\n return checkout.url;\n } catch (error) {\n console.error('Create checkout failed:', error);\n throw new Error('Failed to create checkout', { cause: error });\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,iBAAsB;AAQtB,eAAsB,eACpB,WACA,QACA,QACA;AACA,QAAM,QAAQ,IAAI,iBAAM;AAAA,IACtB,aAAa,QAAQ,IAAI;AAAA,IACzB,QAAS,QAAQ,IAAI,gBAA6C;AAAA,EACpE,CAAC;AAED,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,UAAU,OAAO;AAAA,MAC5C,UAAU,CAAC,SAAS;AAAA,MACpB,oBAAoB;AAAA,MACpB,YAAY,GAAG,MAAM;AAAA,IACvB,CAAC;AACD,WAAO,SAAS;AAAA,EAClB,SAAS,OAAO;AACd,YAAQ,MAAM,2BAA2B,KAAK;AAC9C,UAAM,IAAI,MAAM,6BAA6B,EAAE,OAAO,MAAM,CAAC;AAAA,EAC/D;AACF;","names":[]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Creates a Polar checkout session and returns the URL.
3
+ * @param productId - the Polar product ID
4
+ * @param userId - the external customer ID
5
+ * @param origin - the application origin for the success URL
6
+ */
7
+ declare function createCheckout(productId: string, userId: string, origin: string): Promise<string>;
8
+
9
+ export { createCheckout };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Creates a Polar checkout session and returns the URL.
3
+ * @param productId - the Polar product ID
4
+ * @param userId - the external customer ID
5
+ * @param origin - the application origin for the success URL
6
+ */
7
+ declare function createCheckout(productId: string, userId: string, origin: string): Promise<string>;
8
+
9
+ export { createCheckout };
@@ -0,0 +1,23 @@
1
+ "use server";
2
+ import { Polar } from "@polar-sh/sdk";
3
+ async function createCheckout(productId, userId, origin) {
4
+ const polar = new Polar({
5
+ accessToken: process.env.POLAR_ACCESS_TOKEN,
6
+ server: process.env.POLAR_SERVER ?? "sandbox"
7
+ });
8
+ try {
9
+ const checkout = await polar.checkouts.create({
10
+ products: [productId],
11
+ externalCustomerId: userId,
12
+ successUrl: `${origin}/usage`
13
+ });
14
+ return checkout.url;
15
+ } catch (error) {
16
+ console.error("Create checkout failed:", error);
17
+ throw new Error("Failed to create checkout", { cause: error });
18
+ }
19
+ }
20
+ export {
21
+ createCheckout
22
+ };
23
+ //# sourceMappingURL=createCheckout.js.map