@fonderie/react-billing 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Fonderie, Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # @fonderie/react-billing
2
+
3
+ React hooks for Fonderie billing — `usePlans`, `usePlan`, `useSubscription`,
4
+ `useCheckout`, `useBillingPortal`, `useUsage`, and `useRecordUsage`. Thin
5
+ bindings over [`@fonderie/client`](https://github.com/fonderie-js/sdk/tree/main/packages/client):
6
+ loading/error state and the request itself, nothing else. Bring your own UI.
7
+
8
+ ## Install
9
+
10
+ ```sh
11
+ npm install @fonderie/react-billing
12
+ ```
13
+
14
+ ## Use
15
+
16
+ ```tsx
17
+ import { FonderieClient } from '@fonderie/client';
18
+ import { usePlans, useCheckout, useSubscription } from '@fonderie/react-billing';
19
+
20
+ const client = new FonderieClient({ baseUrl: 'https://api.example.com/v1' });
21
+
22
+ function Pricing() {
23
+ const { plans, isLoading } = usePlans(client.billing);
24
+ const { checkout } = useCheckout(client.billing);
25
+
26
+ return (
27
+ <ul>
28
+ {plans.map((plan) => (
29
+ <li key={plan.id}>
30
+ {plan.name}
31
+ <button onClick={async () => { window.location.href = await checkout({ plan: plan.name }); }}>
32
+ Choose
33
+ </button>
34
+ </li>
35
+ ))}
36
+ </ul>
37
+ );
38
+ }
39
+
40
+ function Account() {
41
+ const { subscription } = useSubscription(client.billing);
42
+ return <p>Plan: {subscription?.plan ?? 'none'}</p>;
43
+ }
44
+ ```
45
+
46
+ Each hook takes the same `BillingClient` instance (`client.billing`) —
47
+ construct one `FonderieClient` at the app root and pass it down (React
48
+ context or a prop). The client's access token is shared with `client.auth`
49
+ automatically, so signing in via
50
+ [`@fonderie/react-auth`](https://github.com/fonderie-js/sdk/tree/main/packages/react-auth)
51
+ is enough to authenticate billing requests too. Billing by workspace instead
52
+ of by user? Call `client.billing.setWorkspaceId(id)`.
53
+
54
+ Want pre-built screens instead of wiring your own pricing table?
55
+ See [`@fonderie/react-billing-screens`](https://github.com/fonderie-js/sdk/tree/main/packages/react-billing-screens).
56
+
57
+ ## Why this exists
58
+
59
+ You've shipped this plumbing before — auth, teams, billing, messaging —
60
+ and the next project will ask for it again. Fonderie packages it once:
61
+ plain TypeScript modules for
62
+ [`@fonderie/core`](https://github.com/fonderie-js/sdk/tree/main/packages/core),
63
+ PostgreSQL-backed, self-hosted, MIT. No external control plane, no
64
+ per-seat anything. Register the modules you need; skip the ones you don't.
65
+
66
+ **This package owns** the React binding for billing — state management
67
+ around `@fonderie/client`, nothing more. No business logic lives here; it
68
+ lives in `@fonderie/billing` on the server.
69
+
70
+ Browse the whole set at
71
+ [fonderie-js/sdk](https://github.com/fonderie-js/sdk) · follow
72
+ [@fonderiejs](https://x.com/fonderiejs)
73
+
74
+ ## License
75
+
76
+ MIT © Fonderie, Inc.
package/dist/index.cjs ADDED
@@ -0,0 +1,285 @@
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
+ FonderieApiError: () => import_client9.FonderieApiError,
24
+ useBillingPortal: () => useBillingPortal,
25
+ useCheckout: () => useCheckout,
26
+ usePlan: () => usePlan,
27
+ usePlanAdmin: () => usePlanAdmin,
28
+ usePlans: () => usePlans,
29
+ useRecordUsage: () => useRecordUsage,
30
+ useSubscription: () => useSubscription,
31
+ useUsage: () => useUsage
32
+ });
33
+ module.exports = __toCommonJS(index_exports);
34
+ var import_client9 = require("@fonderie/client");
35
+
36
+ // src/hooks/useBillingPortal.ts
37
+ var import_client = require("@fonderie/client");
38
+ var import_react = require("react");
39
+ function useBillingPortal(client) {
40
+ const [isLoading, setIsLoading] = (0, import_react.useState)(false);
41
+ const [error, setError] = (0, import_react.useState)(null);
42
+ const openPortal = (0, import_react.useCallback)(async () => {
43
+ setIsLoading(true);
44
+ setError(null);
45
+ try {
46
+ const { result } = await client.createPortalSession();
47
+ return result.url;
48
+ } catch (err) {
49
+ const apiError = err instanceof import_client.FonderieApiError ? err : new import_client.FonderieApiError("unknown", String(err), 0);
50
+ setError(apiError);
51
+ throw apiError;
52
+ } finally {
53
+ setIsLoading(false);
54
+ }
55
+ }, [client]);
56
+ return { openPortal, isLoading, error };
57
+ }
58
+
59
+ // src/hooks/useCheckout.ts
60
+ var import_client2 = require("@fonderie/client");
61
+ var import_react2 = require("react");
62
+ function useCheckout(client) {
63
+ const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
64
+ const [error, setError] = (0, import_react2.useState)(null);
65
+ const checkout = (0, import_react2.useCallback)(
66
+ async (input) => {
67
+ setIsLoading(true);
68
+ setError(null);
69
+ try {
70
+ const { result } = await client.createCheckoutSession(input);
71
+ return result.url;
72
+ } catch (err) {
73
+ const apiError = err instanceof import_client2.FonderieApiError ? err : new import_client2.FonderieApiError("unknown", String(err), 0);
74
+ setError(apiError);
75
+ throw apiError;
76
+ } finally {
77
+ setIsLoading(false);
78
+ }
79
+ },
80
+ [client]
81
+ );
82
+ return { checkout, isLoading, error };
83
+ }
84
+
85
+ // src/hooks/usePlan.ts
86
+ var import_client3 = require("@fonderie/client");
87
+ var import_react3 = require("react");
88
+ function usePlan(client, planId) {
89
+ const [plan, setPlan] = (0, import_react3.useState)(null);
90
+ const [isLoading, setIsLoading] = (0, import_react3.useState)(true);
91
+ const [error, setError] = (0, import_react3.useState)(null);
92
+ const refresh = (0, import_react3.useCallback)(async () => {
93
+ setIsLoading(true);
94
+ setError(null);
95
+ try {
96
+ const { result } = await client.getPlan(planId);
97
+ setPlan(result.plan);
98
+ } catch (err) {
99
+ const apiError = err instanceof import_client3.FonderieApiError ? err : new import_client3.FonderieApiError("unknown", String(err), 0);
100
+ setError(apiError);
101
+ } finally {
102
+ setIsLoading(false);
103
+ }
104
+ }, [client, planId]);
105
+ (0, import_react3.useEffect)(() => {
106
+ void refresh();
107
+ }, [refresh]);
108
+ return { plan, isLoading, error, refresh };
109
+ }
110
+
111
+ // src/hooks/usePlanAdmin.ts
112
+ var import_client4 = require("@fonderie/client");
113
+ var import_react4 = require("react");
114
+ function usePlanAdmin(client) {
115
+ const [isLoading, setIsLoading] = (0, import_react4.useState)(false);
116
+ const [error, setError] = (0, import_react4.useState)(null);
117
+ const createPlan = (0, import_react4.useCallback)(
118
+ async (input) => {
119
+ setIsLoading(true);
120
+ setError(null);
121
+ try {
122
+ const { result } = await client.createPlan(input);
123
+ return result.plan;
124
+ } catch (err) {
125
+ const apiError = err instanceof import_client4.FonderieApiError ? err : new import_client4.FonderieApiError("unknown", String(err), 0);
126
+ setError(apiError);
127
+ throw apiError;
128
+ } finally {
129
+ setIsLoading(false);
130
+ }
131
+ },
132
+ [client]
133
+ );
134
+ const updatePlan = (0, import_react4.useCallback)(
135
+ async (planId, input) => {
136
+ setIsLoading(true);
137
+ setError(null);
138
+ try {
139
+ const { result } = await client.updatePlan(planId, input);
140
+ return result.plan;
141
+ } catch (err) {
142
+ const apiError = err instanceof import_client4.FonderieApiError ? err : new import_client4.FonderieApiError("unknown", String(err), 0);
143
+ setError(apiError);
144
+ throw apiError;
145
+ } finally {
146
+ setIsLoading(false);
147
+ }
148
+ },
149
+ [client]
150
+ );
151
+ const deletePlan = (0, import_react4.useCallback)(
152
+ async (planId) => {
153
+ setIsLoading(true);
154
+ setError(null);
155
+ try {
156
+ await client.deletePlan(planId);
157
+ } catch (err) {
158
+ const apiError = err instanceof import_client4.FonderieApiError ? err : new import_client4.FonderieApiError("unknown", String(err), 0);
159
+ setError(apiError);
160
+ throw apiError;
161
+ } finally {
162
+ setIsLoading(false);
163
+ }
164
+ },
165
+ [client]
166
+ );
167
+ return { createPlan, updatePlan, deletePlan, isLoading, error };
168
+ }
169
+
170
+ // src/hooks/usePlans.ts
171
+ var import_client5 = require("@fonderie/client");
172
+ var import_react5 = require("react");
173
+ function usePlans(client) {
174
+ const [plans, setPlans] = (0, import_react5.useState)([]);
175
+ const [isLoading, setIsLoading] = (0, import_react5.useState)(true);
176
+ const [error, setError] = (0, import_react5.useState)(null);
177
+ const refresh = (0, import_react5.useCallback)(async () => {
178
+ setIsLoading(true);
179
+ setError(null);
180
+ try {
181
+ const { result } = await client.listPlans();
182
+ setPlans(result.plans);
183
+ } catch (err) {
184
+ const apiError = err instanceof import_client5.FonderieApiError ? err : new import_client5.FonderieApiError("unknown", String(err), 0);
185
+ setError(apiError);
186
+ } finally {
187
+ setIsLoading(false);
188
+ }
189
+ }, [client]);
190
+ (0, import_react5.useEffect)(() => {
191
+ void refresh();
192
+ }, [refresh]);
193
+ return { plans, isLoading, error, refresh };
194
+ }
195
+
196
+ // src/hooks/useRecordUsage.ts
197
+ var import_client6 = require("@fonderie/client");
198
+ var import_react6 = require("react");
199
+ function useRecordUsage(client) {
200
+ const [isLoading, setIsLoading] = (0, import_react6.useState)(false);
201
+ const [error, setError] = (0, import_react6.useState)(null);
202
+ const recordUsage = (0, import_react6.useCallback)(
203
+ async (input) => {
204
+ setIsLoading(true);
205
+ setError(null);
206
+ try {
207
+ await client.recordUsage(input);
208
+ } catch (err) {
209
+ const apiError = err instanceof import_client6.FonderieApiError ? err : new import_client6.FonderieApiError("unknown", String(err), 0);
210
+ setError(apiError);
211
+ throw apiError;
212
+ } finally {
213
+ setIsLoading(false);
214
+ }
215
+ },
216
+ [client]
217
+ );
218
+ return { recordUsage, isLoading, error };
219
+ }
220
+
221
+ // src/hooks/useSubscription.ts
222
+ var import_client7 = require("@fonderie/client");
223
+ var import_react7 = require("react");
224
+ function useSubscription(client) {
225
+ const [subscription, setSubscription] = (0, import_react7.useState)(null);
226
+ const [isLoading, setIsLoading] = (0, import_react7.useState)(true);
227
+ const [error, setError] = (0, import_react7.useState)(null);
228
+ const refresh = (0, import_react7.useCallback)(async () => {
229
+ setIsLoading(true);
230
+ setError(null);
231
+ try {
232
+ const { result } = await client.getSubscription();
233
+ setSubscription(result.subscription);
234
+ } catch (err) {
235
+ const apiError = err instanceof import_client7.FonderieApiError ? err : new import_client7.FonderieApiError("unknown", String(err), 0);
236
+ if (apiError.status !== 404) setError(apiError);
237
+ setSubscription(null);
238
+ } finally {
239
+ setIsLoading(false);
240
+ }
241
+ }, [client]);
242
+ (0, import_react7.useEffect)(() => {
243
+ void refresh();
244
+ }, [refresh]);
245
+ return { subscription, isLoading, error, refresh };
246
+ }
247
+
248
+ // src/hooks/useUsage.ts
249
+ var import_client8 = require("@fonderie/client");
250
+ var import_react8 = require("react");
251
+ function useUsage(client, metric) {
252
+ const [total, setTotal] = (0, import_react8.useState)(null);
253
+ const [isLoading, setIsLoading] = (0, import_react8.useState)(true);
254
+ const [error, setError] = (0, import_react8.useState)(null);
255
+ const refresh = (0, import_react8.useCallback)(async () => {
256
+ setIsLoading(true);
257
+ setError(null);
258
+ try {
259
+ const { result } = await client.getUsage(metric);
260
+ setTotal(result.total);
261
+ } catch (err) {
262
+ const apiError = err instanceof import_client8.FonderieApiError ? err : new import_client8.FonderieApiError("unknown", String(err), 0);
263
+ setError(apiError);
264
+ } finally {
265
+ setIsLoading(false);
266
+ }
267
+ }, [client, metric]);
268
+ (0, import_react8.useEffect)(() => {
269
+ void refresh();
270
+ }, [refresh]);
271
+ return { total, isLoading, error, refresh };
272
+ }
273
+ // Annotate the CommonJS export names for ESM import in node:
274
+ 0 && (module.exports = {
275
+ FonderieApiError,
276
+ useBillingPortal,
277
+ useCheckout,
278
+ usePlan,
279
+ usePlanAdmin,
280
+ usePlans,
281
+ useRecordUsage,
282
+ useSubscription,
283
+ useUsage
284
+ });
285
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/useBillingPortal.ts","../src/hooks/useCheckout.ts","../src/hooks/usePlan.ts","../src/hooks/usePlanAdmin.ts","../src/hooks/usePlans.ts","../src/hooks/useRecordUsage.ts","../src/hooks/useSubscription.ts","../src/hooks/useUsage.ts"],"sourcesContent":["export type {\n\tBillingClient,\n\tICheckoutInput,\n\tICreatePlanInput,\n\tIPlanDTO,\n\tIPlanFeature,\n\tIRecordUsageInput,\n\tISubscriptionDTO,\n\tIUpdatePlanInput,\n\tSubscriberType,\n} from '@fonderie/client';\nexport { FonderieApiError } from '@fonderie/client';\nexport type {\n\tIUseBillingPortalReturn,\n\tIUseCheckoutReturn,\n\tIUsePlanAdminReturn,\n\tIUsePlanReturn,\n\tIUsePlansReturn,\n\tIUseRecordUsageReturn,\n\tIUseSubscriptionReturn,\n\tIUseUsageReturn,\n} from './hooks';\nexport {\n\tuseBillingPortal,\n\tuseCheckout,\n\tusePlan,\n\tusePlanAdmin,\n\tusePlans,\n\tuseRecordUsage,\n\tuseSubscription,\n\tuseUsage,\n} from './hooks';\n","import type { BillingClient } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUseBillingPortalReturn {\n\topenPortal: () => Promise<string>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\nexport function useBillingPortal(client: BillingClient): IUseBillingPortalReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst openPortal = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.createPortalSession();\n\t\t\treturn result.url;\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t\tthrow apiError;\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client]);\n\n\treturn { openPortal, isLoading, error };\n}\n","import type { BillingClient, ICheckoutInput } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUseCheckoutReturn {\n\tcheckout: (input: ICheckoutInput) => Promise<string>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\nexport function useCheckout(client: BillingClient): IUseCheckoutReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst checkout = useCallback(\n\t\tasync (input: ICheckoutInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst { result } = await client.createCheckoutSession(input);\n\t\t\t\treturn result.url;\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\treturn { checkout, isLoading, error };\n}\n","import type { BillingClient, IPlanDTO } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUsePlanReturn {\n\tplan: IPlanDTO | null;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function usePlan(client: BillingClient, planId: string): IUsePlanReturn {\n\tconst [plan, setPlan] = useState<IPlanDTO | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.getPlan(planId);\n\t\t\tsetPlan(result.plan);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client, planId]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { plan, isLoading, error, refresh };\n}\n","import type { BillingClient, ICreatePlanInput, IPlanDTO, IUpdatePlanInput } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUsePlanAdminReturn {\n\tcreatePlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;\n\tupdatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;\n\tdeletePlan: (planId: string) => Promise<void>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\n// Action-only, like useUpdateRole/useWorkspaceProfile — pair with usePlans()\n// for the list and call its refresh() after a write.\n//\n// Unlike every other write in this SDK, @fonderie/billing does not gate\n// createPlan/updatePlan/deletePlan with requireAuth or an admin token — the\n// server trusts the caller to authorize access itself. Gate the UI that\n// calls this hook behind your own admin check before shipping it.\nexport function usePlanAdmin(client: BillingClient): IUsePlanAdminReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst createPlan = useCallback(\n\t\tasync (input: ICreatePlanInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst { result } = await client.createPlan(input);\n\t\t\t\treturn result.plan;\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\tconst updatePlan = useCallback(\n\t\tasync (planId: string, input: IUpdatePlanInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst { result } = await client.updatePlan(planId, input);\n\t\t\t\treturn result.plan;\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\tconst deletePlan = useCallback(\n\t\tasync (planId: string) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tawait client.deletePlan(planId);\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\treturn { createPlan, updatePlan, deletePlan, isLoading, error };\n}\n","import type { BillingClient, IPlanDTO } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUsePlansReturn {\n\tplans: IPlanDTO[];\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function usePlans(client: BillingClient): IUsePlansReturn {\n\tconst [plans, setPlans] = useState<IPlanDTO[]>([]);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.listPlans();\n\t\t\tsetPlans(result.plans);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { plans, isLoading, error, refresh };\n}\n","import type { BillingClient, IRecordUsageInput } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUseRecordUsageReturn {\n\trecordUsage: (input: IRecordUsageInput) => Promise<void>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\nexport function useRecordUsage(client: BillingClient): IUseRecordUsageReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst recordUsage = useCallback(\n\t\tasync (input: IRecordUsageInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tawait client.recordUsage(input);\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\treturn { recordUsage, isLoading, error };\n}\n","import type { BillingClient, ISubscriptionDTO } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUseSubscriptionReturn {\n\tsubscription: ISubscriptionDTO | null;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function useSubscription(client: BillingClient): IUseSubscriptionReturn {\n\tconst [subscription, setSubscription] = useState<ISubscriptionDTO | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.getSubscription();\n\t\t\tsetSubscription(result.subscription);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t// No active subscription is a normal, expected state — not an error banner.\n\t\t\tif (apiError.status !== 404) setError(apiError);\n\t\t\tsetSubscription(null);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { subscription, isLoading, error, refresh };\n}\n","import type { BillingClient } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUseUsageReturn {\n\ttotal: number | null;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function useUsage(client: BillingClient, metric: string): IUseUsageReturn {\n\tconst [total, setTotal] = useState<number | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.getUsage(metric);\n\t\t\tsetTotal(result.total);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client, metric]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { total, isLoading, error, refresh };\n}\n"],"mappings":"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","names":["import_client","import_client","import_react","import_client","import_react","import_client","import_react","import_client","import_react","import_client","import_react","import_client","import_react","import_client","import_react"]}
@@ -0,0 +1,66 @@
1
+ import { FonderieApiError, BillingClient, ICheckoutInput, IPlanDTO, ICreatePlanInput, IUpdatePlanInput, IRecordUsageInput, ISubscriptionDTO } from '@fonderie/client';
2
+ export { BillingClient, FonderieApiError, ICheckoutInput, ICreatePlanInput, IPlanDTO, IPlanFeature, IRecordUsageInput, ISubscriptionDTO, IUpdatePlanInput, SubscriberType } from '@fonderie/client';
3
+
4
+ interface IUseBillingPortalReturn {
5
+ openPortal: () => Promise<string>;
6
+ isLoading: boolean;
7
+ error: FonderieApiError | null;
8
+ }
9
+ declare function useBillingPortal(client: BillingClient): IUseBillingPortalReturn;
10
+
11
+ interface IUseCheckoutReturn {
12
+ checkout: (input: ICheckoutInput) => Promise<string>;
13
+ isLoading: boolean;
14
+ error: FonderieApiError | null;
15
+ }
16
+ declare function useCheckout(client: BillingClient): IUseCheckoutReturn;
17
+
18
+ interface IUsePlanReturn {
19
+ plan: IPlanDTO | null;
20
+ isLoading: boolean;
21
+ error: FonderieApiError | null;
22
+ refresh: () => Promise<void>;
23
+ }
24
+ declare function usePlan(client: BillingClient, planId: string): IUsePlanReturn;
25
+
26
+ interface IUsePlanAdminReturn {
27
+ createPlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;
28
+ updatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;
29
+ deletePlan: (planId: string) => Promise<void>;
30
+ isLoading: boolean;
31
+ error: FonderieApiError | null;
32
+ }
33
+ declare function usePlanAdmin(client: BillingClient): IUsePlanAdminReturn;
34
+
35
+ interface IUsePlansReturn {
36
+ plans: IPlanDTO[];
37
+ isLoading: boolean;
38
+ error: FonderieApiError | null;
39
+ refresh: () => Promise<void>;
40
+ }
41
+ declare function usePlans(client: BillingClient): IUsePlansReturn;
42
+
43
+ interface IUseRecordUsageReturn {
44
+ recordUsage: (input: IRecordUsageInput) => Promise<void>;
45
+ isLoading: boolean;
46
+ error: FonderieApiError | null;
47
+ }
48
+ declare function useRecordUsage(client: BillingClient): IUseRecordUsageReturn;
49
+
50
+ interface IUseSubscriptionReturn {
51
+ subscription: ISubscriptionDTO | null;
52
+ isLoading: boolean;
53
+ error: FonderieApiError | null;
54
+ refresh: () => Promise<void>;
55
+ }
56
+ declare function useSubscription(client: BillingClient): IUseSubscriptionReturn;
57
+
58
+ interface IUseUsageReturn {
59
+ total: number | null;
60
+ isLoading: boolean;
61
+ error: FonderieApiError | null;
62
+ refresh: () => Promise<void>;
63
+ }
64
+ declare function useUsage(client: BillingClient, metric: string): IUseUsageReturn;
65
+
66
+ export { type IUseBillingPortalReturn, type IUseCheckoutReturn, type IUsePlanAdminReturn, type IUsePlanReturn, type IUsePlansReturn, type IUseRecordUsageReturn, type IUseSubscriptionReturn, type IUseUsageReturn, useBillingPortal, useCheckout, usePlan, usePlanAdmin, usePlans, useRecordUsage, useSubscription, useUsage };
@@ -0,0 +1,66 @@
1
+ import { FonderieApiError, BillingClient, ICheckoutInput, IPlanDTO, ICreatePlanInput, IUpdatePlanInput, IRecordUsageInput, ISubscriptionDTO } from '@fonderie/client';
2
+ export { BillingClient, FonderieApiError, ICheckoutInput, ICreatePlanInput, IPlanDTO, IPlanFeature, IRecordUsageInput, ISubscriptionDTO, IUpdatePlanInput, SubscriberType } from '@fonderie/client';
3
+
4
+ interface IUseBillingPortalReturn {
5
+ openPortal: () => Promise<string>;
6
+ isLoading: boolean;
7
+ error: FonderieApiError | null;
8
+ }
9
+ declare function useBillingPortal(client: BillingClient): IUseBillingPortalReturn;
10
+
11
+ interface IUseCheckoutReturn {
12
+ checkout: (input: ICheckoutInput) => Promise<string>;
13
+ isLoading: boolean;
14
+ error: FonderieApiError | null;
15
+ }
16
+ declare function useCheckout(client: BillingClient): IUseCheckoutReturn;
17
+
18
+ interface IUsePlanReturn {
19
+ plan: IPlanDTO | null;
20
+ isLoading: boolean;
21
+ error: FonderieApiError | null;
22
+ refresh: () => Promise<void>;
23
+ }
24
+ declare function usePlan(client: BillingClient, planId: string): IUsePlanReturn;
25
+
26
+ interface IUsePlanAdminReturn {
27
+ createPlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;
28
+ updatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;
29
+ deletePlan: (planId: string) => Promise<void>;
30
+ isLoading: boolean;
31
+ error: FonderieApiError | null;
32
+ }
33
+ declare function usePlanAdmin(client: BillingClient): IUsePlanAdminReturn;
34
+
35
+ interface IUsePlansReturn {
36
+ plans: IPlanDTO[];
37
+ isLoading: boolean;
38
+ error: FonderieApiError | null;
39
+ refresh: () => Promise<void>;
40
+ }
41
+ declare function usePlans(client: BillingClient): IUsePlansReturn;
42
+
43
+ interface IUseRecordUsageReturn {
44
+ recordUsage: (input: IRecordUsageInput) => Promise<void>;
45
+ isLoading: boolean;
46
+ error: FonderieApiError | null;
47
+ }
48
+ declare function useRecordUsage(client: BillingClient): IUseRecordUsageReturn;
49
+
50
+ interface IUseSubscriptionReturn {
51
+ subscription: ISubscriptionDTO | null;
52
+ isLoading: boolean;
53
+ error: FonderieApiError | null;
54
+ refresh: () => Promise<void>;
55
+ }
56
+ declare function useSubscription(client: BillingClient): IUseSubscriptionReturn;
57
+
58
+ interface IUseUsageReturn {
59
+ total: number | null;
60
+ isLoading: boolean;
61
+ error: FonderieApiError | null;
62
+ refresh: () => Promise<void>;
63
+ }
64
+ declare function useUsage(client: BillingClient, metric: string): IUseUsageReturn;
65
+
66
+ export { type IUseBillingPortalReturn, type IUseCheckoutReturn, type IUsePlanAdminReturn, type IUsePlanReturn, type IUsePlansReturn, type IUseRecordUsageReturn, type IUseSubscriptionReturn, type IUseUsageReturn, useBillingPortal, useCheckout, usePlan, usePlanAdmin, usePlans, useRecordUsage, useSubscription, useUsage };
package/dist/index.js ADDED
@@ -0,0 +1,252 @@
1
+ // src/index.ts
2
+ import { FonderieApiError as FonderieApiError9 } from "@fonderie/client";
3
+
4
+ // src/hooks/useBillingPortal.ts
5
+ import { FonderieApiError } from "@fonderie/client";
6
+ import { useCallback, useState } from "react";
7
+ function useBillingPortal(client) {
8
+ const [isLoading, setIsLoading] = useState(false);
9
+ const [error, setError] = useState(null);
10
+ const openPortal = useCallback(async () => {
11
+ setIsLoading(true);
12
+ setError(null);
13
+ try {
14
+ const { result } = await client.createPortalSession();
15
+ return result.url;
16
+ } catch (err) {
17
+ const apiError = err instanceof FonderieApiError ? err : new FonderieApiError("unknown", String(err), 0);
18
+ setError(apiError);
19
+ throw apiError;
20
+ } finally {
21
+ setIsLoading(false);
22
+ }
23
+ }, [client]);
24
+ return { openPortal, isLoading, error };
25
+ }
26
+
27
+ // src/hooks/useCheckout.ts
28
+ import { FonderieApiError as FonderieApiError2 } from "@fonderie/client";
29
+ import { useCallback as useCallback2, useState as useState2 } from "react";
30
+ function useCheckout(client) {
31
+ const [isLoading, setIsLoading] = useState2(false);
32
+ const [error, setError] = useState2(null);
33
+ const checkout = useCallback2(
34
+ async (input) => {
35
+ setIsLoading(true);
36
+ setError(null);
37
+ try {
38
+ const { result } = await client.createCheckoutSession(input);
39
+ return result.url;
40
+ } catch (err) {
41
+ const apiError = err instanceof FonderieApiError2 ? err : new FonderieApiError2("unknown", String(err), 0);
42
+ setError(apiError);
43
+ throw apiError;
44
+ } finally {
45
+ setIsLoading(false);
46
+ }
47
+ },
48
+ [client]
49
+ );
50
+ return { checkout, isLoading, error };
51
+ }
52
+
53
+ // src/hooks/usePlan.ts
54
+ import { FonderieApiError as FonderieApiError3 } from "@fonderie/client";
55
+ import { useCallback as useCallback3, useEffect, useState as useState3 } from "react";
56
+ function usePlan(client, planId) {
57
+ const [plan, setPlan] = useState3(null);
58
+ const [isLoading, setIsLoading] = useState3(true);
59
+ const [error, setError] = useState3(null);
60
+ const refresh = useCallback3(async () => {
61
+ setIsLoading(true);
62
+ setError(null);
63
+ try {
64
+ const { result } = await client.getPlan(planId);
65
+ setPlan(result.plan);
66
+ } catch (err) {
67
+ const apiError = err instanceof FonderieApiError3 ? err : new FonderieApiError3("unknown", String(err), 0);
68
+ setError(apiError);
69
+ } finally {
70
+ setIsLoading(false);
71
+ }
72
+ }, [client, planId]);
73
+ useEffect(() => {
74
+ void refresh();
75
+ }, [refresh]);
76
+ return { plan, isLoading, error, refresh };
77
+ }
78
+
79
+ // src/hooks/usePlanAdmin.ts
80
+ import { FonderieApiError as FonderieApiError4 } from "@fonderie/client";
81
+ import { useCallback as useCallback4, useState as useState4 } from "react";
82
+ function usePlanAdmin(client) {
83
+ const [isLoading, setIsLoading] = useState4(false);
84
+ const [error, setError] = useState4(null);
85
+ const createPlan = useCallback4(
86
+ async (input) => {
87
+ setIsLoading(true);
88
+ setError(null);
89
+ try {
90
+ const { result } = await client.createPlan(input);
91
+ return result.plan;
92
+ } catch (err) {
93
+ const apiError = err instanceof FonderieApiError4 ? err : new FonderieApiError4("unknown", String(err), 0);
94
+ setError(apiError);
95
+ throw apiError;
96
+ } finally {
97
+ setIsLoading(false);
98
+ }
99
+ },
100
+ [client]
101
+ );
102
+ const updatePlan = useCallback4(
103
+ async (planId, input) => {
104
+ setIsLoading(true);
105
+ setError(null);
106
+ try {
107
+ const { result } = await client.updatePlan(planId, input);
108
+ return result.plan;
109
+ } catch (err) {
110
+ const apiError = err instanceof FonderieApiError4 ? err : new FonderieApiError4("unknown", String(err), 0);
111
+ setError(apiError);
112
+ throw apiError;
113
+ } finally {
114
+ setIsLoading(false);
115
+ }
116
+ },
117
+ [client]
118
+ );
119
+ const deletePlan = useCallback4(
120
+ async (planId) => {
121
+ setIsLoading(true);
122
+ setError(null);
123
+ try {
124
+ await client.deletePlan(planId);
125
+ } catch (err) {
126
+ const apiError = err instanceof FonderieApiError4 ? err : new FonderieApiError4("unknown", String(err), 0);
127
+ setError(apiError);
128
+ throw apiError;
129
+ } finally {
130
+ setIsLoading(false);
131
+ }
132
+ },
133
+ [client]
134
+ );
135
+ return { createPlan, updatePlan, deletePlan, isLoading, error };
136
+ }
137
+
138
+ // src/hooks/usePlans.ts
139
+ import { FonderieApiError as FonderieApiError5 } from "@fonderie/client";
140
+ import { useCallback as useCallback5, useEffect as useEffect2, useState as useState5 } from "react";
141
+ function usePlans(client) {
142
+ const [plans, setPlans] = useState5([]);
143
+ const [isLoading, setIsLoading] = useState5(true);
144
+ const [error, setError] = useState5(null);
145
+ const refresh = useCallback5(async () => {
146
+ setIsLoading(true);
147
+ setError(null);
148
+ try {
149
+ const { result } = await client.listPlans();
150
+ setPlans(result.plans);
151
+ } catch (err) {
152
+ const apiError = err instanceof FonderieApiError5 ? err : new FonderieApiError5("unknown", String(err), 0);
153
+ setError(apiError);
154
+ } finally {
155
+ setIsLoading(false);
156
+ }
157
+ }, [client]);
158
+ useEffect2(() => {
159
+ void refresh();
160
+ }, [refresh]);
161
+ return { plans, isLoading, error, refresh };
162
+ }
163
+
164
+ // src/hooks/useRecordUsage.ts
165
+ import { FonderieApiError as FonderieApiError6 } from "@fonderie/client";
166
+ import { useCallback as useCallback6, useState as useState6 } from "react";
167
+ function useRecordUsage(client) {
168
+ const [isLoading, setIsLoading] = useState6(false);
169
+ const [error, setError] = useState6(null);
170
+ const recordUsage = useCallback6(
171
+ async (input) => {
172
+ setIsLoading(true);
173
+ setError(null);
174
+ try {
175
+ await client.recordUsage(input);
176
+ } catch (err) {
177
+ const apiError = err instanceof FonderieApiError6 ? err : new FonderieApiError6("unknown", String(err), 0);
178
+ setError(apiError);
179
+ throw apiError;
180
+ } finally {
181
+ setIsLoading(false);
182
+ }
183
+ },
184
+ [client]
185
+ );
186
+ return { recordUsage, isLoading, error };
187
+ }
188
+
189
+ // src/hooks/useSubscription.ts
190
+ import { FonderieApiError as FonderieApiError7 } from "@fonderie/client";
191
+ import { useCallback as useCallback7, useEffect as useEffect3, useState as useState7 } from "react";
192
+ function useSubscription(client) {
193
+ const [subscription, setSubscription] = useState7(null);
194
+ const [isLoading, setIsLoading] = useState7(true);
195
+ const [error, setError] = useState7(null);
196
+ const refresh = useCallback7(async () => {
197
+ setIsLoading(true);
198
+ setError(null);
199
+ try {
200
+ const { result } = await client.getSubscription();
201
+ setSubscription(result.subscription);
202
+ } catch (err) {
203
+ const apiError = err instanceof FonderieApiError7 ? err : new FonderieApiError7("unknown", String(err), 0);
204
+ if (apiError.status !== 404) setError(apiError);
205
+ setSubscription(null);
206
+ } finally {
207
+ setIsLoading(false);
208
+ }
209
+ }, [client]);
210
+ useEffect3(() => {
211
+ void refresh();
212
+ }, [refresh]);
213
+ return { subscription, isLoading, error, refresh };
214
+ }
215
+
216
+ // src/hooks/useUsage.ts
217
+ import { FonderieApiError as FonderieApiError8 } from "@fonderie/client";
218
+ import { useCallback as useCallback8, useEffect as useEffect4, useState as useState8 } from "react";
219
+ function useUsage(client, metric) {
220
+ const [total, setTotal] = useState8(null);
221
+ const [isLoading, setIsLoading] = useState8(true);
222
+ const [error, setError] = useState8(null);
223
+ const refresh = useCallback8(async () => {
224
+ setIsLoading(true);
225
+ setError(null);
226
+ try {
227
+ const { result } = await client.getUsage(metric);
228
+ setTotal(result.total);
229
+ } catch (err) {
230
+ const apiError = err instanceof FonderieApiError8 ? err : new FonderieApiError8("unknown", String(err), 0);
231
+ setError(apiError);
232
+ } finally {
233
+ setIsLoading(false);
234
+ }
235
+ }, [client, metric]);
236
+ useEffect4(() => {
237
+ void refresh();
238
+ }, [refresh]);
239
+ return { total, isLoading, error, refresh };
240
+ }
241
+ export {
242
+ FonderieApiError9 as FonderieApiError,
243
+ useBillingPortal,
244
+ useCheckout,
245
+ usePlan,
246
+ usePlanAdmin,
247
+ usePlans,
248
+ useRecordUsage,
249
+ useSubscription,
250
+ useUsage
251
+ };
252
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/useBillingPortal.ts","../src/hooks/useCheckout.ts","../src/hooks/usePlan.ts","../src/hooks/usePlanAdmin.ts","../src/hooks/usePlans.ts","../src/hooks/useRecordUsage.ts","../src/hooks/useSubscription.ts","../src/hooks/useUsage.ts"],"sourcesContent":["export type {\n\tBillingClient,\n\tICheckoutInput,\n\tICreatePlanInput,\n\tIPlanDTO,\n\tIPlanFeature,\n\tIRecordUsageInput,\n\tISubscriptionDTO,\n\tIUpdatePlanInput,\n\tSubscriberType,\n} from '@fonderie/client';\nexport { FonderieApiError } from '@fonderie/client';\nexport type {\n\tIUseBillingPortalReturn,\n\tIUseCheckoutReturn,\n\tIUsePlanAdminReturn,\n\tIUsePlanReturn,\n\tIUsePlansReturn,\n\tIUseRecordUsageReturn,\n\tIUseSubscriptionReturn,\n\tIUseUsageReturn,\n} from './hooks';\nexport {\n\tuseBillingPortal,\n\tuseCheckout,\n\tusePlan,\n\tusePlanAdmin,\n\tusePlans,\n\tuseRecordUsage,\n\tuseSubscription,\n\tuseUsage,\n} from './hooks';\n","import type { BillingClient } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUseBillingPortalReturn {\n\topenPortal: () => Promise<string>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\nexport function useBillingPortal(client: BillingClient): IUseBillingPortalReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst openPortal = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.createPortalSession();\n\t\t\treturn result.url;\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t\tthrow apiError;\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client]);\n\n\treturn { openPortal, isLoading, error };\n}\n","import type { BillingClient, ICheckoutInput } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUseCheckoutReturn {\n\tcheckout: (input: ICheckoutInput) => Promise<string>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\nexport function useCheckout(client: BillingClient): IUseCheckoutReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst checkout = useCallback(\n\t\tasync (input: ICheckoutInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst { result } = await client.createCheckoutSession(input);\n\t\t\t\treturn result.url;\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\treturn { checkout, isLoading, error };\n}\n","import type { BillingClient, IPlanDTO } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUsePlanReturn {\n\tplan: IPlanDTO | null;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function usePlan(client: BillingClient, planId: string): IUsePlanReturn {\n\tconst [plan, setPlan] = useState<IPlanDTO | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.getPlan(planId);\n\t\t\tsetPlan(result.plan);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client, planId]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { plan, isLoading, error, refresh };\n}\n","import type { BillingClient, ICreatePlanInput, IPlanDTO, IUpdatePlanInput } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUsePlanAdminReturn {\n\tcreatePlan: (input: ICreatePlanInput) => Promise<IPlanDTO>;\n\tupdatePlan: (planId: string, input: IUpdatePlanInput) => Promise<IPlanDTO>;\n\tdeletePlan: (planId: string) => Promise<void>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\n// Action-only, like useUpdateRole/useWorkspaceProfile — pair with usePlans()\n// for the list and call its refresh() after a write.\n//\n// Unlike every other write in this SDK, @fonderie/billing does not gate\n// createPlan/updatePlan/deletePlan with requireAuth or an admin token — the\n// server trusts the caller to authorize access itself. Gate the UI that\n// calls this hook behind your own admin check before shipping it.\nexport function usePlanAdmin(client: BillingClient): IUsePlanAdminReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst createPlan = useCallback(\n\t\tasync (input: ICreatePlanInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst { result } = await client.createPlan(input);\n\t\t\t\treturn result.plan;\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\tconst updatePlan = useCallback(\n\t\tasync (planId: string, input: IUpdatePlanInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tconst { result } = await client.updatePlan(planId, input);\n\t\t\t\treturn result.plan;\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\tconst deletePlan = useCallback(\n\t\tasync (planId: string) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tawait client.deletePlan(planId);\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\treturn { createPlan, updatePlan, deletePlan, isLoading, error };\n}\n","import type { BillingClient, IPlanDTO } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUsePlansReturn {\n\tplans: IPlanDTO[];\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function usePlans(client: BillingClient): IUsePlansReturn {\n\tconst [plans, setPlans] = useState<IPlanDTO[]>([]);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.listPlans();\n\t\t\tsetPlans(result.plans);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { plans, isLoading, error, refresh };\n}\n","import type { BillingClient, IRecordUsageInput } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useState } from 'react';\n\nexport interface IUseRecordUsageReturn {\n\trecordUsage: (input: IRecordUsageInput) => Promise<void>;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n}\n\nexport function useRecordUsage(client: BillingClient): IUseRecordUsageReturn {\n\tconst [isLoading, setIsLoading] = useState(false);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst recordUsage = useCallback(\n\t\tasync (input: IRecordUsageInput) => {\n\t\t\tsetIsLoading(true);\n\t\t\tsetError(null);\n\t\t\ttry {\n\t\t\t\tawait client.recordUsage(input);\n\t\t\t} catch (err) {\n\t\t\t\tconst apiError =\n\t\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t\tsetError(apiError);\n\t\t\t\tthrow apiError;\n\t\t\t} finally {\n\t\t\t\tsetIsLoading(false);\n\t\t\t}\n\t\t},\n\t\t[client],\n\t);\n\n\treturn { recordUsage, isLoading, error };\n}\n","import type { BillingClient, ISubscriptionDTO } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUseSubscriptionReturn {\n\tsubscription: ISubscriptionDTO | null;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function useSubscription(client: BillingClient): IUseSubscriptionReturn {\n\tconst [subscription, setSubscription] = useState<ISubscriptionDTO | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.getSubscription();\n\t\t\tsetSubscription(result.subscription);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\t// No active subscription is a normal, expected state — not an error banner.\n\t\t\tif (apiError.status !== 404) setError(apiError);\n\t\t\tsetSubscription(null);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { subscription, isLoading, error, refresh };\n}\n","import type { BillingClient } from '@fonderie/client';\nimport { FonderieApiError } from '@fonderie/client';\nimport { useCallback, useEffect, useState } from 'react';\n\nexport interface IUseUsageReturn {\n\ttotal: number | null;\n\tisLoading: boolean;\n\terror: FonderieApiError | null;\n\trefresh: () => Promise<void>;\n}\n\nexport function useUsage(client: BillingClient, metric: string): IUseUsageReturn {\n\tconst [total, setTotal] = useState<number | null>(null);\n\tconst [isLoading, setIsLoading] = useState(true);\n\tconst [error, setError] = useState<FonderieApiError | null>(null);\n\n\tconst refresh = useCallback(async () => {\n\t\tsetIsLoading(true);\n\t\tsetError(null);\n\t\ttry {\n\t\t\tconst { result } = await client.getUsage(metric);\n\t\t\tsetTotal(result.total);\n\t\t} catch (err) {\n\t\t\tconst apiError =\n\t\t\t\terr instanceof FonderieApiError ? err : new FonderieApiError('unknown', String(err), 0);\n\t\t\tsetError(apiError);\n\t\t} finally {\n\t\t\tsetIsLoading(false);\n\t\t}\n\t}, [client, metric]);\n\n\tuseEffect(() => {\n\t\tvoid refresh();\n\t}, [refresh]);\n\n\treturn { total, isLoading, error, refresh };\n}\n"],"mappings":"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","names":["FonderieApiError","FonderieApiError","useCallback","useState","FonderieApiError","useCallback","useState","FonderieApiError","useCallback","useState","FonderieApiError","useCallback","useEffect","useState","FonderieApiError","useCallback","useState","FonderieApiError","useCallback","useEffect","useState","FonderieApiError","useCallback","useEffect","useState"]}
package/package.json ADDED
@@ -0,0 +1,66 @@
1
+ {
2
+ "name": "@fonderie/react-billing",
3
+ "version": "0.1.0",
4
+ "description": "React hooks for Fonderie billing — thin bindings over @fonderie/client.",
5
+ "keywords": [
6
+ "fonderie-js",
7
+ "react",
8
+ "billing",
9
+ "stripe",
10
+ "hooks",
11
+ "typescript"
12
+ ],
13
+ "license": "MIT",
14
+ "type": "module",
15
+ "engines": {
16
+ "node": ">=20"
17
+ },
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs"
23
+ }
24
+ },
25
+ "main": "./dist/index.cjs",
26
+ "module": "./dist/index.js",
27
+ "types": "./dist/index.d.ts",
28
+ "scripts": {
29
+ "build": "tsup",
30
+ "dev": "tsup --watch",
31
+ "typecheck": "tsc --noEmit",
32
+ "lint": "biome lint src",
33
+ "format": "biome format --write src",
34
+ "check": "biome check --write src"
35
+ },
36
+ "dependencies": {
37
+ "@fonderie/client": "*"
38
+ },
39
+ "peerDependencies": {
40
+ "react": ">=18.0.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^25.6.0",
44
+ "@types/react": "^18.0.0",
45
+ "react": "^18.0.0",
46
+ "tsup": "^8.5.1",
47
+ "typescript": "^6.0.3"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "files": [
53
+ "dist",
54
+ "LICENSE",
55
+ "README.md"
56
+ ],
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/fonderiejs/fonderie.git",
60
+ "directory": "packages/react-billing"
61
+ },
62
+ "homepage": "https://github.com/fonderiejs/fonderie/tree/main/packages/react-billing#readme",
63
+ "bugs": {
64
+ "url": "https://github.com/fonderiejs/fonderie/issues"
65
+ }
66
+ }