@usethrottle/auth 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,252 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { ThrottleAuthConfig, ThrottleAuth, AuthSnapshot, ThrottleAccount, ThrottleAuthError, Address, AddressInput, Customer, ProfilePatch, Page, Invoice, Order, PaymentMethod, Subscription } from '../index.js';
4
- export { AuthStatus, AuthStorage, DeviceSession, Session, createAccount, createThrottleAuth, localStorageAdapter, memoryStorage } from '../index.js';
3
+
4
+ interface Customer {
5
+ id: string;
6
+ email: string;
7
+ emailVerified: boolean;
8
+ firstName?: string | null;
9
+ lastName?: string | null;
10
+ phone?: string | null;
11
+ company?: string | null;
12
+ acceptsMarketing?: boolean;
13
+ }
14
+ interface Session {
15
+ accessToken: string;
16
+ expiresAt: string;
17
+ refreshToken: string;
18
+ customer: Customer;
19
+ }
20
+ /**
21
+ * Defined here rather than in `storage.ts` so `ThrottleAuthConfig` can name it
22
+ * without importing a module that does not exist until Task 2. `storage.ts`
23
+ * imports and re-exports it.
24
+ */
25
+ interface AuthStorage {
26
+ get(key: string): string | null | Promise<string | null>;
27
+ set(key: string, value: string): void | Promise<void>;
28
+ remove(key: string): void | Promise<void>;
29
+ }
30
+ interface ThrottleAuthConfig {
31
+ publishableKey: string;
32
+ baseUrl?: string;
33
+ storage?: AuthStorage;
34
+ /** Called when a route needs a step-up proof. Return the buyer's password, or null to cancel. */
35
+ onStepUpRequired?: () => Promise<string | null>;
36
+ }
37
+ interface ProfilePatch {
38
+ firstName?: string;
39
+ lastName?: string;
40
+ phone?: string;
41
+ company?: string | null;
42
+ acceptsMarketing?: boolean;
43
+ }
44
+ interface AddressInput {
45
+ label?: string;
46
+ firstName?: string;
47
+ lastName?: string;
48
+ company?: string;
49
+ addressLine1: string;
50
+ addressLine2?: string;
51
+ city: string;
52
+ stateProvince?: string;
53
+ postalCode?: string;
54
+ countryCode: string;
55
+ phone?: string;
56
+ isDefault?: boolean;
57
+ }
58
+ interface Address {
59
+ id: string;
60
+ label: string | null;
61
+ firstName: string | null;
62
+ lastName: string | null;
63
+ company: string | null;
64
+ addressLine1: string;
65
+ addressLine2: string | null;
66
+ city: string;
67
+ stateProvince: string | null;
68
+ postalCode: string | null;
69
+ countryCode: string;
70
+ phone: string | null;
71
+ isDefault: boolean;
72
+ createdAt: string;
73
+ updatedAt: string;
74
+ }
75
+ interface PaymentMethod {
76
+ id: string;
77
+ methodType: string;
78
+ cardBrand: string | null;
79
+ cardLastFour: string | null;
80
+ cardExpMonth: number | null;
81
+ cardExpYear: number | null;
82
+ isDefault: boolean;
83
+ createdAt: string;
84
+ }
85
+ interface Order {
86
+ id: string;
87
+ orderNumber: string;
88
+ status: string;
89
+ type: string;
90
+ paymentStatus: string;
91
+ currency: string;
92
+ subtotal: number;
93
+ taxTotal: number;
94
+ discountTotal: number;
95
+ shippingTotal: number;
96
+ total: number;
97
+ buyerVatNumber: string | null;
98
+ taxReverseCharge: boolean;
99
+ billingAddress: unknown | null;
100
+ shippingAddress: unknown | null;
101
+ discountCode: string | null;
102
+ subscriptionId: string | null;
103
+ cancelledAt: string | null;
104
+ completedAt: string | null;
105
+ closedAt: string | null;
106
+ createdAt: string;
107
+ updatedAt: string;
108
+ }
109
+ interface OrderLineItem {
110
+ id: string;
111
+ name: string;
112
+ description: string | null;
113
+ quantity: number;
114
+ /** Integer minor units, like every other amount on the wire. */
115
+ unitPrice: number;
116
+ subtotal: number;
117
+ taxAmount: number;
118
+ discountAmount: number;
119
+ total: number;
120
+ imageUrl: string | null;
121
+ }
122
+ /**
123
+ * What `getOrder` returns. Deliberately NOT folded into `Order`: the list route
124
+ * does not load line items, so a required `lineItems` on `Order` would be a
125
+ * promise the list response cannot keep.
126
+ */
127
+ interface OrderDetail extends Order {
128
+ lineItems: OrderLineItem[];
129
+ }
130
+ interface Invoice {
131
+ id: string;
132
+ number: string;
133
+ status: string;
134
+ currency: string;
135
+ subtotal: number;
136
+ taxTotal: number;
137
+ shippingTotal: number;
138
+ discountTotal: number;
139
+ total: number;
140
+ amountRefunded: number;
141
+ issuedAt: string;
142
+ dueAt: string | null;
143
+ periodStart: string | null;
144
+ periodEnd: string | null;
145
+ createdAt: string;
146
+ updatedAt: string;
147
+ }
148
+ interface Subscription {
149
+ id: string;
150
+ status: string;
151
+ planReference: string;
152
+ planName: string | null;
153
+ interval: string;
154
+ amount: number;
155
+ quantity: number;
156
+ currency: string;
157
+ currentPeriodStart: string;
158
+ currentPeriodEnd: string;
159
+ trialEnd: string | null;
160
+ cancelledAt: string | null;
161
+ cancelAtPeriodEnd: boolean;
162
+ pendingPlanReference: string | null;
163
+ pendingPlanName: string | null;
164
+ pendingInterval: string | null;
165
+ pendingQuantity: number | null;
166
+ pausedAt: string | null;
167
+ lastPaymentAt: string | null;
168
+ createdAt: string;
169
+ updatedAt: string;
170
+ }
171
+
172
+ type AuthStatus = 'loading' | 'authenticated' | 'unauthenticated';
173
+ interface AuthSnapshot {
174
+ status: AuthStatus;
175
+ customer: Customer | null;
176
+ /**
177
+ * False here does NOT only mean "we emailed them and they have not clicked".
178
+ * While it is false the API may also be withholding pre-existing account
179
+ * data behind the claim cutoff — empty order lists and a 403 on `PATCH /me`
180
+ * are expected, not broken. See the plan header.
181
+ */
182
+ emailVerified: boolean;
183
+ }
184
+
185
+ interface DeviceSession {
186
+ id: string;
187
+ userAgent: string | null;
188
+ ipPrefix: string | null;
189
+ createdAt: string;
190
+ lastUsedAt: string;
191
+ current: boolean;
192
+ }
193
+ interface ThrottleAuth {
194
+ register(email: string, password: string): Promise<{
195
+ status: 'active' | 'pending';
196
+ }>;
197
+ signIn(email: string, password: string): Promise<void>;
198
+ signOut(): Promise<void>;
199
+ signOutEverywhere(): Promise<void>;
200
+ restore(): Promise<void>;
201
+ getSnapshot(): AuthSnapshot;
202
+ subscribe(fn: (s: AuthSnapshot) => void): () => void;
203
+ stepUp(password: string): Promise<void>;
204
+ call<T = any>(method: string, path: string, body?: unknown): Promise<T>;
205
+ verifyEmail(token: string): Promise<void>;
206
+ resendVerification(): Promise<void>;
207
+ forgotPassword(email: string): Promise<void>;
208
+ resetPassword(token: string, password: string): Promise<void>;
209
+ changePassword(password: string): Promise<void>;
210
+ listSessions(): Promise<DeviceSession[]>;
211
+ revokeSession(id: string): Promise<void>;
212
+ }
213
+ declare function createThrottleAuth(config: ThrottleAuthConfig): ThrottleAuth;
214
+
215
+ interface Page {
216
+ cursor?: string;
217
+ limit?: number;
218
+ }
219
+ interface ThrottleAccount {
220
+ getProfile(): Promise<Customer>;
221
+ updateProfile(patch: ProfilePatch): Promise<Customer>;
222
+ listAddresses(): Promise<Address[]>;
223
+ createAddress(input: AddressInput): Promise<Address>;
224
+ updateAddress(id: string, patch: Partial<AddressInput>): Promise<Address>;
225
+ deleteAddress(id: string): Promise<void>;
226
+ listPaymentMethods(): Promise<PaymentMethod[]>;
227
+ setDefaultPaymentMethod(id: string): Promise<PaymentMethod>;
228
+ deletePaymentMethod(id: string): Promise<void>;
229
+ listOrders(page?: Page): Promise<Order[]>;
230
+ getOrder(id: string): Promise<OrderDetail>;
231
+ listInvoices(page?: Page): Promise<Invoice[]>;
232
+ getInvoice(id: string): Promise<Invoice>;
233
+ /** A 600-second signed URL. Fetch it on click — it expires. */
234
+ getInvoicePdfUrl(id: string): Promise<{
235
+ url: string;
236
+ }>;
237
+ listSubscriptions(page?: Page): Promise<Subscription[]>;
238
+ getSubscription(id: string): Promise<Subscription>;
239
+ cancelSubscription(id: string, opts?: {
240
+ atPeriodEnd?: boolean;
241
+ }): Promise<Subscription>;
242
+ pauseSubscription(id: string): Promise<Subscription>;
243
+ resumeSubscription(id: string): Promise<Subscription>;
244
+ claimCart(cartId: string): Promise<{
245
+ cartId: string;
246
+ customerId: string;
247
+ }>;
248
+ }
249
+ declare function createAccount(auth: ThrottleAuth): ThrottleAccount;
5
250
 
6
251
  interface ThrottleAuthProviderProps extends Partial<ThrottleAuthConfig> {
7
252
  publishableKey: string;
@@ -23,6 +268,20 @@ type UseAuthResult = AuthSnapshot & {
23
268
  };
24
269
  declare function useAuth(): UseAuthResult;
25
270
 
271
+ declare class ThrottleAuthError extends Error {
272
+ readonly code: string;
273
+ readonly statusCode: number;
274
+ readonly retryAfter?: number;
275
+ readonly details?: unknown;
276
+ constructor(args: {
277
+ code: string;
278
+ message: string;
279
+ statusCode: number;
280
+ retryAfter?: number;
281
+ details?: unknown;
282
+ });
283
+ }
284
+
26
285
  interface Resource<T> {
27
286
  data: T;
28
287
  isLoading: boolean;
@@ -50,5 +309,21 @@ declare function useSubscriptions(page?: Page): Resource<Subscription[]> & {
50
309
  pause(id: string): Promise<void>;
51
310
  resume(id: string): Promise<void>;
52
311
  };
312
+ /**
313
+ * Single-resource reads for the detail views. A `null` id means "nothing
314
+ * selected" and must not call the API — `useResource` still runs, so the
315
+ * loader resolves to null rather than being skipped, which keeps the
316
+ * loading/error shape identical whether or not an id is present.
317
+ */
318
+ declare function useOrder(id: string | null): Resource<OrderDetail | null>;
319
+ declare function useInvoice(id: string | null): Resource<Invoice | null>;
320
+
321
+ declare function memoryStorage(): AuthStorage;
322
+ /**
323
+ * localStorage when it works, memory when it does not. Safari private mode,
324
+ * hardened browser settings and server-side rendering all make localStorage
325
+ * either absent or throwing; none of them may take the storefront down.
326
+ */
327
+ declare function localStorageAdapter(): AuthStorage;
53
328
 
54
- export { Address, AddressInput, AuthSnapshot, Customer, Invoice, Order, Page, PaymentMethod, ProfilePatch, type Resource, Subscription, ThrottleAccount, ThrottleAuth, ThrottleAuthConfig, ThrottleAuthError, ThrottleAuthProvider, type ThrottleAuthProviderProps, type UseAuthResult, useAddresses, useAuth, useAuthContext, useCustomer, useInvoices, useOrders, useSavedCards, useSubscriptions };
329
+ export { type Address, type AddressInput, type AuthSnapshot, type AuthStatus, type AuthStorage, type Customer, type DeviceSession, type Invoice, type Order, type Page, type PaymentMethod, type ProfilePatch, type Resource, type Session, type Subscription, type ThrottleAccount, type ThrottleAuth, type ThrottleAuthConfig, ThrottleAuthError, ThrottleAuthProvider, type ThrottleAuthProviderProps, type UseAuthResult, createAccount, createThrottleAuth, localStorageAdapter, memoryStorage, useAddresses, useAuth, useAuthContext, useCustomer, useInvoice, useInvoices, useOrder, useOrders, useSavedCards, useSubscriptions };
@@ -1,131 +1,24 @@
1
- import "../chunk-ZMNCURDE.js";
1
+ "use client";
2
2
  import {
3
- ThrottleAuthProvider,
4
- useAuth,
5
- useAuthContext
6
- } from "../chunk-IJ3DNMNG.js";
3
+ useAddresses,
4
+ useCustomer,
5
+ useInvoice,
6
+ useInvoices,
7
+ useOrder,
8
+ useOrders,
9
+ useSavedCards,
10
+ useSubscriptions
11
+ } from "../chunk-HGBAIM6B.js";
7
12
  import {
8
13
  ThrottleAuthError,
14
+ ThrottleAuthProvider,
9
15
  createAccount,
10
16
  createThrottleAuth,
11
17
  localStorageAdapter,
12
- memoryStorage
13
- } from "../chunk-OYNGTNOS.js";
14
-
15
- // src/react/hooks.ts
16
- import { useCallback, useEffect, useRef, useState } from "react";
17
- function asError(err) {
18
- if (err instanceof ThrottleAuthError) return err;
19
- const anyErr = err;
20
- return new ThrottleAuthError({
21
- code: anyErr?.code ?? "request_failed",
22
- message: anyErr?.message ?? String(err),
23
- statusCode: anyErr?.statusCode ?? 0
24
- });
25
- }
26
- function useResource(empty, load, deps) {
27
- const { status, emailVerified } = useAuth();
28
- const [data, setData] = useState(empty);
29
- const [isLoading, setIsLoading] = useState(status === "loading");
30
- const [error, setError] = useState(null);
31
- const gen = useRef(0);
32
- const alive = useRef(true);
33
- useEffect(() => {
34
- alive.current = true;
35
- return () => {
36
- alive.current = false;
37
- gen.current++;
38
- };
39
- }, []);
40
- const refetch = useCallback(async () => {
41
- const mine = ++gen.current;
42
- setIsLoading(true);
43
- try {
44
- const next = await load();
45
- if (!alive.current || gen.current !== mine) return;
46
- setData(next);
47
- setError(null);
48
- } catch (err) {
49
- if (!alive.current || gen.current !== mine) return;
50
- setError(asError(err));
51
- } finally {
52
- if (alive.current && gen.current === mine) setIsLoading(false);
53
- }
54
- }, deps);
55
- useEffect(() => {
56
- if (status !== "authenticated") {
57
- gen.current++;
58
- setData(empty);
59
- setError(null);
60
- setIsLoading(status === "loading");
61
- return;
62
- }
63
- void refetch();
64
- }, [status, emailVerified, refetch]);
65
- return { data, isLoading, error, refetch };
66
- }
67
- function useCustomer() {
68
- const { account } = useAuth();
69
- const res = useResource(null, () => account.getProfile(), [account]);
70
- const update = useCallback(async (patch) => {
71
- await account.updateProfile(patch);
72
- await res.refetch();
73
- }, [account, res]);
74
- return { ...res, update };
75
- }
76
- function useAddresses() {
77
- const { account } = useAuth();
78
- const res = useResource([], () => account.listAddresses(), [account]);
79
- const after = async (p) => {
80
- await p;
81
- await res.refetch();
82
- };
83
- return {
84
- ...res,
85
- create: (input) => after(account.createAddress(input)),
86
- update: (id, patch) => after(account.updateAddress(id, patch)),
87
- remove: (id) => after(account.deleteAddress(id))
88
- };
89
- }
90
- function useSavedCards() {
91
- const { account } = useAuth();
92
- const res = useResource([], () => account.listPaymentMethods(), [account]);
93
- const after = async (p) => {
94
- await p;
95
- await res.refetch();
96
- };
97
- return {
98
- ...res,
99
- setDefault: (id) => after(account.setDefaultPaymentMethod(id)),
100
- remove: (id) => after(account.deletePaymentMethod(id))
101
- };
102
- }
103
- function useOrders(page) {
104
- const { account } = useAuth();
105
- return useResource([], () => account.listOrders(page), [account, page?.cursor, page?.limit]);
106
- }
107
- function useInvoices(page) {
108
- const { account } = useAuth();
109
- return useResource([], () => account.listInvoices(page), [account, page?.cursor, page?.limit]);
110
- }
111
- function useSubscriptions(page) {
112
- const { account } = useAuth();
113
- const res = useResource(
114
- [],
115
- () => account.listSubscriptions(page),
116
- [account, page?.cursor, page?.limit]
117
- );
118
- const after = async (p) => {
119
- await p;
120
- await res.refetch();
121
- };
122
- return {
123
- ...res,
124
- cancel: (id, opts) => after(account.cancelSubscription(id, opts)),
125
- pause: (id) => after(account.pauseSubscription(id)),
126
- resume: (id) => after(account.resumeSubscription(id))
127
- };
128
- }
18
+ memoryStorage,
19
+ useAuth,
20
+ useAuthContext
21
+ } from "../chunk-SZ427BQ3.js";
129
22
  export {
130
23
  ThrottleAuthError,
131
24
  ThrottleAuthProvider,
@@ -137,7 +30,9 @@ export {
137
30
  useAuth,
138
31
  useAuthContext,
139
32
  useCustomer,
33
+ useInvoice,
140
34
  useInvoices,
35
+ useOrder,
141
36
  useOrders,
142
37
  useSavedCards,
143
38
  useSubscriptions
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/react/hooks.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\nimport { ThrottleAuthError } from '../errors';\nimport type { Address, AddressInput, Customer, Invoice, Order, PaymentMethod, ProfilePatch, Subscription } from '../types';\nimport type { Page } from '../account';\nimport { useAuth } from './context';\n\nexport interface Resource<T> {\n data: T;\n isLoading: boolean;\n error: ThrottleAuthError | null;\n refetch(): Promise<void>;\n}\n\nfunction asError(err: unknown): ThrottleAuthError {\n if (err instanceof ThrottleAuthError) return err;\n const anyErr = err as any;\n return new ThrottleAuthError({\n code: anyErr?.code ?? 'request_failed',\n message: anyErr?.message ?? String(err),\n statusCode: anyErr?.statusCode ?? 0,\n });\n}\n\n/**\n * One fetch-on-auth-change primitive behind every resource hook. `emailVerified`\n * is a dependency on purpose: verifying lifts the claim cutoff, and lists that\n * were legitimately empty a moment ago are not empty any more.\n */\nfunction useResource<T>(empty: T, load: () => Promise<T>, deps: unknown[]): Resource<T> {\n const { status, emailVerified } = useAuth();\n const [data, setData] = useState<T>(empty);\n const [isLoading, setIsLoading] = useState(status === 'loading');\n const [error, setError] = useState<ThrottleAuthError | null>(null);\n const gen = useRef(0);\n const alive = useRef(true);\n\n useEffect(() => {\n // Set on mount, not only cleared on unmount: React StrictMode mounts,\n // unmounts and remounts in development, and a ref that is only ever set\n // to false would silently discard every response for the rest of the\n // component's life.\n alive.current = true;\n return () => { alive.current = false; gen.current++; };\n }, []);\n\n const refetch = useCallback(async () => {\n const mine = ++gen.current;\n setIsLoading(true);\n try {\n const next = await load();\n if (!alive.current || gen.current !== mine) return;\n setData(next);\n setError(null);\n } catch (err) {\n if (!alive.current || gen.current !== mine) return;\n setError(asError(err));\n } finally {\n if (alive.current && gen.current === mine) setIsLoading(false);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, deps);\n\n useEffect(() => {\n if (status !== 'authenticated') {\n gen.current++; // abandon anything in flight\n setData(empty);\n setError(null);\n setIsLoading(status === 'loading');\n return;\n }\n void refetch();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [status, emailVerified, refetch]);\n\n return { data, isLoading, error, refetch };\n}\n\nexport function useCustomer(): Resource<Customer | null> & { update(patch: ProfilePatch): Promise<void> } {\n const { account } = useAuth();\n const res = useResource<Customer | null>(null, () => account.getProfile(), [account]);\n const update = useCallback(async (patch: ProfilePatch) => {\n await account.updateProfile(patch);\n await res.refetch();\n }, [account, res]);\n return { ...res, update };\n}\n\nexport function useAddresses(): Resource<Address[]> & {\n create(input: AddressInput): Promise<void>;\n update(id: string, patch: Partial<AddressInput>): Promise<void>;\n remove(id: string): Promise<void>;\n} {\n const { account } = useAuth();\n const res = useResource<Address[]>([], () => account.listAddresses(), [account]);\n const after = async (p: Promise<unknown>) => { await p; await res.refetch(); };\n return {\n ...res,\n create: (input) => after(account.createAddress(input)),\n update: (id, patch) => after(account.updateAddress(id, patch)),\n remove: (id) => after(account.deleteAddress(id)),\n };\n}\n\nexport function useSavedCards(): Resource<PaymentMethod[]> & {\n setDefault(id: string): Promise<void>;\n remove(id: string): Promise<void>;\n} {\n const { account } = useAuth();\n const res = useResource<PaymentMethod[]>([], () => account.listPaymentMethods(), [account]);\n const after = async (p: Promise<unknown>) => { await p; await res.refetch(); };\n return {\n ...res,\n setDefault: (id) => after(account.setDefaultPaymentMethod(id)),\n remove: (id) => after(account.deletePaymentMethod(id)),\n };\n}\n\nexport function useOrders(page?: Page): Resource<Order[]> {\n const { account } = useAuth();\n return useResource<Order[]>([], () => account.listOrders(page), [account, page?.cursor, page?.limit]);\n}\n\nexport function useInvoices(page?: Page): Resource<Invoice[]> {\n const { account } = useAuth();\n return useResource<Invoice[]>([], () => account.listInvoices(page), [account, page?.cursor, page?.limit]);\n}\n\nexport function useSubscriptions(page?: Page): Resource<Subscription[]> & {\n cancel(id: string, opts?: { atPeriodEnd?: boolean }): Promise<void>;\n pause(id: string): Promise<void>;\n resume(id: string): Promise<void>;\n} {\n const { account } = useAuth();\n const res = useResource<Subscription[]>([], () => account.listSubscriptions(page),\n [account, page?.cursor, page?.limit]);\n const after = async (p: Promise<unknown>) => { await p; await res.refetch(); };\n return {\n ...res,\n cancel: (id, opts) => after(account.cancelSubscription(id, opts)),\n pause: (id) => after(account.pauseSubscription(id)),\n resume: (id) => after(account.resumeSubscription(id)),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}