@usethrottle/subscriptions 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/{chunk-CRI67SGE.js → chunk-SXTIX2Y2.js} +20 -1
- package/dist/chunk-SXTIX2Y2.js.map +1 -0
- package/dist/{errors-DfWfeSji.d.cts → errors-CZVUZzk3.d.cts} +13 -1
- package/dist/{errors-DfWfeSji.d.ts → errors-CZVUZzk3.d.ts} +13 -1
- package/dist/index.cjs +30 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +33 -0
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +15 -1
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-CRI67SGE.js.map +0 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ npm install @usethrottle/subscriptions @usethrottle/checkout-react
|
|
|
11
11
|
- Subscription lifecycle reads and mutations: list, get, create, update, change plan, pause, resume, cancel.
|
|
12
12
|
- Recurring checkout-session creation for subscribe flows.
|
|
13
13
|
- Trial eligibility checks for trial-fraud protection.
|
|
14
|
+
- Customer payment-method reads for subscription confirmation and buyer portals.
|
|
14
15
|
- Buyer-portal proxy helpers so browser code never sees an `sk_*` key.
|
|
15
16
|
- Primitive UI components for status, trial countdowns, and past-due dunning.
|
|
16
17
|
|
|
@@ -81,6 +82,7 @@ export { handler as GET, handler as POST, handler as PATCH };
|
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
The helper allowlists subscription, customer-by-external, trial eligibility, and checkout-session paths. It pins subscription list reads, customer lookups, direct subscription creates, and checkout-session creates to the authenticated buyer's `externalCustomerId`, and verifies ownership before forwarding subscription mutations.
|
|
85
|
+
Payment-method reads are pinned to the authenticated buyer's Throttle customer row.
|
|
84
86
|
|
|
85
87
|
## Server-side API client
|
|
86
88
|
|
|
@@ -94,6 +96,7 @@ const subscriptions = createSubscriptionsClient({
|
|
|
94
96
|
});
|
|
95
97
|
|
|
96
98
|
await subscriptions.cancel('sub_123', { atPeriodEnd: true });
|
|
99
|
+
await subscriptions.listCustomerPaymentMethods('cus_123');
|
|
97
100
|
```
|
|
98
101
|
|
|
99
102
|
`create()` accepts either a Throttle `customerId` or your own `externalCustomerId`. When you pass `externalCustomerId`, the client resolves the Throttle customer row before calling the subscription create endpoint.
|
|
@@ -61,6 +61,18 @@ function normalizeCustomer(raw) {
|
|
|
61
61
|
updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
|
|
62
62
|
};
|
|
63
63
|
}
|
|
64
|
+
function normalizeCustomerPaymentMethod(raw) {
|
|
65
|
+
return {
|
|
66
|
+
id: requiredString(raw?.id, "paymentMethod.id"),
|
|
67
|
+
processor: optionalString(raw?.processor),
|
|
68
|
+
methodType: optionalString(raw?.methodType ?? raw?.method_type),
|
|
69
|
+
cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),
|
|
70
|
+
cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),
|
|
71
|
+
isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),
|
|
72
|
+
createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
|
|
73
|
+
updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
|
|
74
|
+
};
|
|
75
|
+
}
|
|
64
76
|
function normalizeCheckoutSession(raw) {
|
|
65
77
|
const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
|
|
66
78
|
return {
|
|
@@ -264,6 +276,13 @@ var SubscriptionsClient = class {
|
|
|
264
276
|
throw err;
|
|
265
277
|
}
|
|
266
278
|
}
|
|
279
|
+
async listCustomerPaymentMethods(customerId) {
|
|
280
|
+
const data = await this.request(
|
|
281
|
+
"GET",
|
|
282
|
+
`/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`
|
|
283
|
+
);
|
|
284
|
+
return (data ?? []).map(normalizeCustomerPaymentMethod);
|
|
285
|
+
}
|
|
267
286
|
async resolveCustomerId(customerId, externalCustomerId) {
|
|
268
287
|
if (customerId) return customerId;
|
|
269
288
|
if (!externalCustomerId) {
|
|
@@ -301,4 +320,4 @@ export {
|
|
|
301
320
|
SubscriptionsClient,
|
|
302
321
|
createSubscriptionsClient
|
|
303
322
|
};
|
|
304
|
-
//# sourceMappingURL=chunk-
|
|
323
|
+
//# sourceMappingURL=chunk-SXTIX2Y2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/normalize.ts","../src/client.ts"],"sourcesContent":["export class ThrottleSubscriptionsError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args.message);\n this.name = 'ThrottleSubscriptionsError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n }\n}\n","import type {\n CheckoutSession,\n Customer,\n CustomerPaymentMethod,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n merchantId: optionalString(raw?.merchantId ?? raw?.merchant_id),\n storeId: optionalString(raw?.storeId ?? raw?.store_id),\n customerId: requiredString(raw?.customerId ?? raw?.customer_id, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(\n raw?.planReference ?? raw?.plan_reference,\n 'subscription.planReference',\n ),\n planName: optionalString(raw?.planName ?? raw?.plan_name),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart ?? raw?.current_period_start,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd ?? raw?.current_period_end,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),\n failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),\n pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),\n cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId ?? raw?.external_id),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName ?? raw?.first_name),\n lastName: optionalString(raw?.lastName ?? raw?.last_name),\n phone: optionalString(raw?.phone),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomerPaymentMethod(raw: any): CustomerPaymentMethod {\n return {\n id: requiredString(raw?.id, 'paymentMethod.id'),\n processor: optionalString(raw?.processor),\n methodType: optionalString(raw?.methodType ?? raw?.method_type),\n cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),\n cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),\n isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),\n expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nexport function normalizeTrialEligibility(raw: any): TrialEligibilityResult {\n return {\n eligible: Boolean(raw?.eligible),\n reason: raw?.reason,\n };\n}\n\nexport function normalizePagination(raw: any): Pagination | undefined {\n if (!raw) return undefined;\n return {\n cursor: raw.cursor ?? null,\n hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false),\n };\n}\n\nexport function toIso(value: string | Date | undefined): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction requiredDateString(value: unknown, label: string): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return null;\n}\n\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizeCustomerPaymentMethod,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n storeId: input.storeId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n payment_method_id: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n async listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`,\n );\n return (data ?? []).map(normalizeCustomerPaymentMethod);\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n"],"mappings":"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","names":[]}
|
|
@@ -37,6 +37,16 @@ interface Customer {
|
|
|
37
37
|
createdAt?: string;
|
|
38
38
|
updatedAt?: string;
|
|
39
39
|
}
|
|
40
|
+
interface CustomerPaymentMethod {
|
|
41
|
+
id: string;
|
|
42
|
+
processor?: string | null;
|
|
43
|
+
methodType?: string | null;
|
|
44
|
+
cardBrand?: string | null;
|
|
45
|
+
cardLastFour?: string | null;
|
|
46
|
+
isDefault?: boolean;
|
|
47
|
+
createdAt?: string;
|
|
48
|
+
updatedAt?: string;
|
|
49
|
+
}
|
|
40
50
|
interface Pagination {
|
|
41
51
|
cursor: string | null;
|
|
42
52
|
hasMore: boolean;
|
|
@@ -228,6 +238,7 @@ interface SubscriptionsClientContract {
|
|
|
228
238
|
createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession>;
|
|
229
239
|
checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult>;
|
|
230
240
|
getCustomerByExternalId(externalId: string): Promise<Customer | null>;
|
|
241
|
+
listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]>;
|
|
231
242
|
}
|
|
232
243
|
|
|
233
244
|
declare class SubscriptionsClient implements SubscriptionsClientContract {
|
|
@@ -252,6 +263,7 @@ declare class SubscriptionsClient implements SubscriptionsClientContract {
|
|
|
252
263
|
createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession>;
|
|
253
264
|
checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult>;
|
|
254
265
|
getCustomerByExternalId(externalId: string): Promise<Customer | null>;
|
|
266
|
+
listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]>;
|
|
255
267
|
private resolveCustomerId;
|
|
256
268
|
}
|
|
257
269
|
declare function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient;
|
|
@@ -268,4 +280,4 @@ declare class ThrottleSubscriptionsError extends Error {
|
|
|
268
280
|
});
|
|
269
281
|
}
|
|
270
282
|
|
|
271
|
-
export { type CancelSubscriptionInput as C, type DunningBannerProps as D, type ListSubscriptionsParams as L, type MutationState as M, type PaginatedSubscriptions as P, type QueryOptions as Q, type RecurringIntent as R, type SubscriptionProviderProps as S, type TrialEligibilityResult as T, type UpdateSubscriptionInput as U, type SubscriptionsClientContract as a, type SubscriptionFetcher as b, type Subscription as c, type ChangePlanInput as d, type CheckoutSession as e, type CreateCheckoutSessionInput as f, type CreateSubscriptionInput as g, type Customer as h, type QueryState as i, type
|
|
283
|
+
export { type CancelSubscriptionInput as C, type DunningBannerProps as D, type ListSubscriptionsParams as L, type MutationState as M, type PaginatedSubscriptions as P, type QueryOptions as Q, type RecurringIntent as R, type SubscriptionProviderProps as S, type TrialEligibilityResult as T, type UpdateSubscriptionInput as U, type SubscriptionsClientContract as a, type SubscriptionFetcher as b, type Subscription as c, type ChangePlanInput as d, type CheckoutSession as e, type CreateCheckoutSessionInput as f, type CreateSubscriptionInput as g, type Customer as h, type QueryState as i, type CustomerPaymentMethod as j, type TrialEligibilityInput as k, type SubscriptionStatusBadgeProps as l, type TrialCountdownProps as m, type SubscriptionStatus as n, type CheckoutCollectInput as o, type CheckoutCustomerInput as p, type Pagination as q, type SubscriptionInterval as r, type SubscriptionSort as s, SubscriptionsClient as t, type SubscriptionsClientOptions as u, type ThrottleEnvelope as v, ThrottleSubscriptionsError as w, type TrialEligibilityReason as x, createSubscriptionsClient as y };
|
|
@@ -37,6 +37,16 @@ interface Customer {
|
|
|
37
37
|
createdAt?: string;
|
|
38
38
|
updatedAt?: string;
|
|
39
39
|
}
|
|
40
|
+
interface CustomerPaymentMethod {
|
|
41
|
+
id: string;
|
|
42
|
+
processor?: string | null;
|
|
43
|
+
methodType?: string | null;
|
|
44
|
+
cardBrand?: string | null;
|
|
45
|
+
cardLastFour?: string | null;
|
|
46
|
+
isDefault?: boolean;
|
|
47
|
+
createdAt?: string;
|
|
48
|
+
updatedAt?: string;
|
|
49
|
+
}
|
|
40
50
|
interface Pagination {
|
|
41
51
|
cursor: string | null;
|
|
42
52
|
hasMore: boolean;
|
|
@@ -228,6 +238,7 @@ interface SubscriptionsClientContract {
|
|
|
228
238
|
createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession>;
|
|
229
239
|
checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult>;
|
|
230
240
|
getCustomerByExternalId(externalId: string): Promise<Customer | null>;
|
|
241
|
+
listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]>;
|
|
231
242
|
}
|
|
232
243
|
|
|
233
244
|
declare class SubscriptionsClient implements SubscriptionsClientContract {
|
|
@@ -252,6 +263,7 @@ declare class SubscriptionsClient implements SubscriptionsClientContract {
|
|
|
252
263
|
createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession>;
|
|
253
264
|
checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult>;
|
|
254
265
|
getCustomerByExternalId(externalId: string): Promise<Customer | null>;
|
|
266
|
+
listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]>;
|
|
255
267
|
private resolveCustomerId;
|
|
256
268
|
}
|
|
257
269
|
declare function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient;
|
|
@@ -268,4 +280,4 @@ declare class ThrottleSubscriptionsError extends Error {
|
|
|
268
280
|
});
|
|
269
281
|
}
|
|
270
282
|
|
|
271
|
-
export { type CancelSubscriptionInput as C, type DunningBannerProps as D, type ListSubscriptionsParams as L, type MutationState as M, type PaginatedSubscriptions as P, type QueryOptions as Q, type RecurringIntent as R, type SubscriptionProviderProps as S, type TrialEligibilityResult as T, type UpdateSubscriptionInput as U, type SubscriptionsClientContract as a, type SubscriptionFetcher as b, type Subscription as c, type ChangePlanInput as d, type CheckoutSession as e, type CreateCheckoutSessionInput as f, type CreateSubscriptionInput as g, type Customer as h, type QueryState as i, type
|
|
283
|
+
export { type CancelSubscriptionInput as C, type DunningBannerProps as D, type ListSubscriptionsParams as L, type MutationState as M, type PaginatedSubscriptions as P, type QueryOptions as Q, type RecurringIntent as R, type SubscriptionProviderProps as S, type TrialEligibilityResult as T, type UpdateSubscriptionInput as U, type SubscriptionsClientContract as a, type SubscriptionFetcher as b, type Subscription as c, type ChangePlanInput as d, type CheckoutSession as e, type CreateCheckoutSessionInput as f, type CreateSubscriptionInput as g, type Customer as h, type QueryState as i, type CustomerPaymentMethod as j, type TrialEligibilityInput as k, type SubscriptionStatusBadgeProps as l, type TrialCountdownProps as m, type SubscriptionStatus as n, type CheckoutCollectInput as o, type CheckoutCustomerInput as p, type Pagination as q, type SubscriptionInterval as r, type SubscriptionSort as s, SubscriptionsClient as t, type SubscriptionsClientOptions as u, type ThrottleEnvelope as v, ThrottleSubscriptionsError as w, type TrialEligibilityReason as x, createSubscriptionsClient as y };
|
package/dist/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(index_exports, {
|
|
|
41
41
|
useCreateCheckoutSession: () => useCreateCheckoutSession,
|
|
42
42
|
useCreateSubscription: () => useCreateSubscription,
|
|
43
43
|
useCustomerByExternalId: () => useCustomerByExternalId,
|
|
44
|
+
useCustomerPaymentMethods: () => useCustomerPaymentMethods,
|
|
44
45
|
usePauseSubscription: () => usePauseSubscription,
|
|
45
46
|
useResumeSubscription: () => useResumeSubscription,
|
|
46
47
|
useSubscription: () => useSubscription,
|
|
@@ -115,6 +116,18 @@ function normalizeCustomer(raw) {
|
|
|
115
116
|
updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
|
|
116
117
|
};
|
|
117
118
|
}
|
|
119
|
+
function normalizeCustomerPaymentMethod(raw) {
|
|
120
|
+
return {
|
|
121
|
+
id: requiredString(raw?.id, "paymentMethod.id"),
|
|
122
|
+
processor: optionalString(raw?.processor),
|
|
123
|
+
methodType: optionalString(raw?.methodType ?? raw?.method_type),
|
|
124
|
+
cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),
|
|
125
|
+
cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),
|
|
126
|
+
isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),
|
|
127
|
+
createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
|
|
128
|
+
updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
|
|
129
|
+
};
|
|
130
|
+
}
|
|
118
131
|
function normalizeCheckoutSession(raw) {
|
|
119
132
|
const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
|
|
120
133
|
return {
|
|
@@ -318,6 +331,13 @@ var SubscriptionsClient = class {
|
|
|
318
331
|
throw err;
|
|
319
332
|
}
|
|
320
333
|
}
|
|
334
|
+
async listCustomerPaymentMethods(customerId) {
|
|
335
|
+
const data = await this.request(
|
|
336
|
+
"GET",
|
|
337
|
+
`/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`
|
|
338
|
+
);
|
|
339
|
+
return (data ?? []).map(normalizeCustomerPaymentMethod);
|
|
340
|
+
}
|
|
321
341
|
async resolveCustomerId(customerId, externalCustomerId) {
|
|
322
342
|
if (customerId) return customerId;
|
|
323
343
|
if (!externalCustomerId) {
|
|
@@ -440,6 +460,15 @@ function useCustomerByExternalId(externalId, options = {}) {
|
|
|
440
460
|
{ ...options, enabled: options.enabled ?? Boolean(externalId) }
|
|
441
461
|
);
|
|
442
462
|
}
|
|
463
|
+
function useCustomerPaymentMethods(customerId, options = {}) {
|
|
464
|
+
const client = useSubscriptionClient();
|
|
465
|
+
const cacheVersion = useSubscriptionCacheVersion();
|
|
466
|
+
return useAsyncQuery(
|
|
467
|
+
() => customerId ? client.listCustomerPaymentMethods(customerId) : Promise.resolve(null),
|
|
468
|
+
[client, customerId, cacheVersion],
|
|
469
|
+
{ ...options, enabled: options.enabled ?? Boolean(customerId) }
|
|
470
|
+
);
|
|
471
|
+
}
|
|
443
472
|
function useTrialEligibility() {
|
|
444
473
|
const client = useSubscriptionClient();
|
|
445
474
|
return useAsyncMutation((input) => client.checkTrialEligibility(input));
|
|
@@ -727,6 +756,7 @@ function DunningBanner({
|
|
|
727
756
|
useCreateCheckoutSession,
|
|
728
757
|
useCreateSubscription,
|
|
729
758
|
useCustomerByExternalId,
|
|
759
|
+
useCustomerPaymentMethods,
|
|
730
760
|
usePauseSubscription,
|
|
731
761
|
useResumeSubscription,
|
|
732
762
|
useSubscription,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.tsx","../src/errors.ts","../src/normalize.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/helpers.ts","../src/components.tsx"],"sourcesContent":["export { SubscriptionsClient, createSubscriptionsClient } from './client';\nexport { ThrottleSubscriptionsError } from './errors';\nexport {\n SubscriptionProvider,\n SubscriptionProviderWithClient,\n createSubscriptionFetcher,\n useSubscriptionClient,\n useSubscriptionInvalidation,\n} from './provider';\nexport {\n useCancelSubscription,\n useChangePlan,\n useCreateCheckoutSession,\n useCreateSubscription,\n useCustomerByExternalId,\n usePauseSubscription,\n useResumeSubscription,\n useSubscription,\n useSubscriptions,\n useTrialEligibility,\n useUpdateSubscription,\n} from './hooks';\nexport { DunningBanner, SubscriptionStatusBadge, TrialCountdown } from './components';\nexport {\n canCancelSubscription,\n canPauseSubscription,\n canResumeSubscription,\n daysUntil,\n isSubscriptionPastDue,\n isSubscriptionTrialing,\n isTerminalSubscription,\n} from './helpers';\nexport type * from './types';\n","export class ThrottleSubscriptionsError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args.message);\n this.name = 'ThrottleSubscriptionsError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n }\n}\n","import type {\n CheckoutSession,\n Customer,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n merchantId: optionalString(raw?.merchantId ?? raw?.merchant_id),\n storeId: optionalString(raw?.storeId ?? raw?.store_id),\n customerId: requiredString(raw?.customerId ?? raw?.customer_id, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(\n raw?.planReference ?? raw?.plan_reference,\n 'subscription.planReference',\n ),\n planName: optionalString(raw?.planName ?? raw?.plan_name),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart ?? raw?.current_period_start,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd ?? raw?.current_period_end,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),\n failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),\n pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),\n cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId ?? raw?.external_id),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName ?? raw?.first_name),\n lastName: optionalString(raw?.lastName ?? raw?.last_name),\n phone: optionalString(raw?.phone),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),\n expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nexport function normalizeTrialEligibility(raw: any): TrialEligibilityResult {\n return {\n eligible: Boolean(raw?.eligible),\n reason: raw?.reason,\n };\n}\n\nexport function normalizePagination(raw: any): Pagination | undefined {\n if (!raw) return undefined;\n return {\n cursor: raw.cursor ?? null,\n hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false),\n };\n}\n\nexport function toIso(value: string | Date | undefined): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction requiredDateString(value: unknown, label: string): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return null;\n}\n\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n storeId: input.storeId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n payment_method_id: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n","import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { SubscriptionsClient } from './client';\nimport type {\n SubscriptionFetcher,\n SubscriptionProviderProps,\n SubscriptionsClientContract,\n} from './types';\n\ninterface SubscriptionContextValue {\n client: SubscriptionsClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst SubscriptionContext = createContext<SubscriptionContextValue | null>(null);\n\nexport function SubscriptionProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: SubscriptionProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new SubscriptionsClient({\n fetcher: fetcher ?? createSubscriptionFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n\nexport function useSubscriptionClient(): SubscriptionsClientContract {\n return useSubscriptionContext().client;\n}\n\nexport function useSubscriptionInvalidation(): () => void {\n return useSubscriptionContext().invalidate;\n}\n\nexport function useSubscriptionCacheVersion(): number {\n return useSubscriptionContext().cacheVersion;\n}\n\nexport function createSubscriptionFetcher(basePath: string): SubscriptionFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useSubscriptionContext(): SubscriptionContextValue {\n const ctx = useContext(SubscriptionContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/subscriptions hooks must be used inside <SubscriptionProvider />',\n );\n }\n return ctx;\n}\n\nexport function SubscriptionProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: SubscriptionsClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSubscriptionCacheVersion,\n useSubscriptionClient,\n useSubscriptionInvalidation,\n} from './provider';\nimport type {\n CancelSubscriptionInput,\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n ListSubscriptionsParams,\n MutationState,\n PaginatedSubscriptions,\n QueryOptions,\n QueryState,\n Subscription,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport function useSubscriptions(\n params: ListSubscriptionsParams = {},\n options: QueryOptions<PaginatedSubscriptions> = {},\n): QueryState<PaginatedSubscriptions> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n const stableParams = useStableValue(params);\n return useAsyncQuery(\n () => client.list(stableParams),\n [client, stableParams, cacheVersion],\n options,\n );\n}\n\nexport function useSubscription(\n id: string | null | undefined,\n options: QueryOptions<Subscription> = {},\n): QueryState<Subscription> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useCustomerByExternalId(\n externalId: string | null | undefined,\n options: QueryOptions<Customer> = {},\n): QueryState<Customer> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (externalId ? client.getCustomerByExternalId(externalId) : Promise.resolve(null)),\n [client, externalId, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(externalId) },\n );\n}\n\nexport function useTrialEligibility(): MutationState<\n TrialEligibilityResult,\n TrialEligibilityInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.checkTrialEligibility(input));\n}\n\nexport function useCreateSubscription(): MutationState<Subscription, CreateSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.create(input), invalidate);\n}\n\nexport function useUpdateSubscription(): MutationState<\n Subscription,\n { id: string; data: UpdateSubscriptionInput }\n> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(({ id, data }) => client.update(id, data), invalidate);\n}\n\nexport function useChangePlan(): MutationState<Subscription, ChangePlanInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.changePlan(input), invalidate);\n}\n\nexport function useCancelSubscription(): MutationState<Subscription, CancelSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(\n (input) => client.cancel(input.id, { atPeriodEnd: input.atPeriodEnd }),\n invalidate,\n );\n}\n\nexport function usePauseSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.pause(input.id), invalidate);\n}\n\nexport function useResumeSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.resume(input.id), invalidate);\n}\n\nexport function useCreateCheckoutSession(): MutationState<\n CheckoutSession,\n CreateCheckoutSessionInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.createCheckoutSession(input));\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useAsyncMutation<TData, TVariables>(\n action: (variables: TVariables) => Promise<TData>,\n onSuccess?: () => void,\n): MutationState<TData, TVariables> {\n const [data, setData] = useState<TData | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [isPending, setIsPending] = useState(false);\n\n const mutateAsync = useCallback(\n async (variables: TVariables) => {\n setIsPending(true);\n setError(null);\n try {\n const next = await action(variables);\n setData(next);\n onSuccess?.();\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsPending(false);\n }\n },\n [action, onSuccess],\n );\n\n const mutate = useCallback(\n (variables: TVariables) => {\n void mutateAsync(variables).catch(() => undefined);\n },\n [mutateAsync],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsPending(false);\n }, []);\n\n return { data, error, isPending, mutate, mutateAsync, reset };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n","import type { Subscription, SubscriptionStatus } from './types';\n\nexport function isTerminalSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'cancelled';\n}\n\nexport function canPauseSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'active';\n}\n\nexport function canResumeSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'paused';\n}\n\nexport function canCancelSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) !== 'cancelled';\n}\n\nexport function isSubscriptionPastDue(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'past_due';\n}\n\nexport function isSubscriptionTrialing(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'trialing';\n}\n\nexport function daysUntil(date: string | Date, now = new Date()): number {\n const end = date instanceof Date ? date : new Date(date);\n const ms = end.getTime() - now.getTime();\n if (!Number.isFinite(ms)) return 0;\n return Math.max(0, Math.ceil(ms / 86_400_000));\n}\n\nfunction getStatus(input: SubscriptionStatus | Subscription): SubscriptionStatus {\n return typeof input === 'string' ? input : input.status;\n}\n","import type { CSSProperties } from 'react';\nimport { daysUntil } from './helpers';\nimport type {\n DunningBannerProps,\n SubscriptionStatus,\n SubscriptionStatusBadgeProps,\n TrialCountdownProps,\n} from './types';\n\nconst STATUS_LABELS: Record<SubscriptionStatus, string> = {\n active: 'Active',\n paused: 'Paused',\n cancelled: 'Cancelled',\n past_due: 'Past due',\n trialing: 'Trialing',\n};\n\nconst STATUS_STYLES: Record<SubscriptionStatus, CSSProperties> = {\n active: { color: '#035c4f', background: '#dff8ef', borderColor: '#a8e8d2' },\n paused: { color: '#735c00', background: '#fff4ca', borderColor: '#f3d46b' },\n cancelled: { color: '#6c2632', background: '#ffe1e7', borderColor: '#f4a9b8' },\n past_due: { color: '#7a2d00', background: '#ffe8d6', borderColor: '#f5b47f' },\n trialing: { color: '#124c73', background: '#dff1ff', borderColor: '#9ed3fb' },\n};\n\nexport function SubscriptionStatusBadge({\n status,\n className,\n style,\n labels,\n}: SubscriptionStatusBadgeProps) {\n return (\n <span\n className={className}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n border: '1px solid',\n borderRadius: 999,\n padding: '2px 8px',\n fontSize: 12,\n fontWeight: 700,\n lineHeight: 1.6,\n whiteSpace: 'nowrap',\n ...STATUS_STYLES[status],\n ...style,\n }}\n >\n {labels?.[status] ?? STATUS_LABELS[status]}\n </span>\n );\n}\n\nexport function TrialCountdown({\n endDate,\n now,\n className,\n style,\n expiredLabel = 'Trial ended',\n prefix = 'Trial ends in',\n}: TrialCountdownProps) {\n const days = daysUntil(endDate, now);\n const label = days <= 0 ? expiredLabel : `${prefix} ${days} ${days === 1 ? 'day' : 'days'}`;\n\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nexport function DunningBanner({\n subscription,\n onUpdateCard,\n title = 'Payment needs attention',\n message,\n actionLabel = 'Update card',\n className,\n style,\n}: DunningBannerProps) {\n if (subscription.status !== 'past_due') return null;\n const fallbackMessage =\n subscription.failureCount > 0\n ? `We could not renew this subscription after ${subscription.failureCount} failed payment attempt${\n subscription.failureCount === 1 ? '' : 's'\n }.`\n : 'We could not renew this subscription with the saved payment method.';\n\n return (\n <div\n role=\"status\"\n className={className}\n style={{\n border: '1px solid #f5b47f',\n borderRadius: 8,\n background: '#fff7ed',\n color: '#7a2d00',\n padding: 16,\n display: 'grid',\n gap: 10,\n ...style,\n }}\n >\n <strong>{title}</strong>\n <span>{message ?? fallbackMessage}</span>\n {onUpdateCard ? (\n <button\n type=\"button\"\n onClick={onUpdateCard}\n style={{\n width: 'fit-content',\n border: '1px solid #7a2d00',\n borderRadius: 6,\n background: '#7a2d00',\n color: '#fff',\n padding: '8px 12px',\n fontWeight: 700,\n cursor: 'pointer',\n }}\n >\n {actionLabel}\n </button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["value","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.tsx","../src/errors.ts","../src/normalize.ts","../src/client.ts","../src/provider.tsx","../src/hooks.ts","../src/helpers.ts","../src/components.tsx"],"sourcesContent":["export { SubscriptionsClient, createSubscriptionsClient } from './client';\nexport { ThrottleSubscriptionsError } from './errors';\nexport {\n SubscriptionProvider,\n SubscriptionProviderWithClient,\n createSubscriptionFetcher,\n useSubscriptionClient,\n useSubscriptionInvalidation,\n} from './provider';\nexport {\n useCancelSubscription,\n useChangePlan,\n useCreateCheckoutSession,\n useCreateSubscription,\n useCustomerByExternalId,\n useCustomerPaymentMethods,\n usePauseSubscription,\n useResumeSubscription,\n useSubscription,\n useSubscriptions,\n useTrialEligibility,\n useUpdateSubscription,\n} from './hooks';\nexport { DunningBanner, SubscriptionStatusBadge, TrialCountdown } from './components';\nexport {\n canCancelSubscription,\n canPauseSubscription,\n canResumeSubscription,\n daysUntil,\n isSubscriptionPastDue,\n isSubscriptionTrialing,\n isTerminalSubscription,\n} from './helpers';\nexport type * from './types';\n","export class ThrottleSubscriptionsError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args.message);\n this.name = 'ThrottleSubscriptionsError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n }\n}\n","import type {\n CheckoutSession,\n Customer,\n CustomerPaymentMethod,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n merchantId: optionalString(raw?.merchantId ?? raw?.merchant_id),\n storeId: optionalString(raw?.storeId ?? raw?.store_id),\n customerId: requiredString(raw?.customerId ?? raw?.customer_id, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(\n raw?.planReference ?? raw?.plan_reference,\n 'subscription.planReference',\n ),\n planName: optionalString(raw?.planName ?? raw?.plan_name),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart ?? raw?.current_period_start,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd ?? raw?.current_period_end,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),\n failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),\n pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),\n cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId ?? raw?.external_id),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName ?? raw?.first_name),\n lastName: optionalString(raw?.lastName ?? raw?.last_name),\n phone: optionalString(raw?.phone),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomerPaymentMethod(raw: any): CustomerPaymentMethod {\n return {\n id: requiredString(raw?.id, 'paymentMethod.id'),\n processor: optionalString(raw?.processor),\n methodType: optionalString(raw?.methodType ?? raw?.method_type),\n cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),\n cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),\n isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),\n expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nexport function normalizeTrialEligibility(raw: any): TrialEligibilityResult {\n return {\n eligible: Boolean(raw?.eligible),\n reason: raw?.reason,\n };\n}\n\nexport function normalizePagination(raw: any): Pagination | undefined {\n if (!raw) return undefined;\n return {\n cursor: raw.cursor ?? null,\n hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false),\n };\n}\n\nexport function toIso(value: string | Date | undefined): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction requiredDateString(value: unknown, label: string): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return null;\n}\n\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizeCustomerPaymentMethod,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n storeId: input.storeId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n payment_method_id: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n async listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`,\n );\n return (data ?? []).map(normalizeCustomerPaymentMethod);\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n","import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { SubscriptionsClient } from './client';\nimport type {\n SubscriptionFetcher,\n SubscriptionProviderProps,\n SubscriptionsClientContract,\n} from './types';\n\ninterface SubscriptionContextValue {\n client: SubscriptionsClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst SubscriptionContext = createContext<SubscriptionContextValue | null>(null);\n\nexport function SubscriptionProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: SubscriptionProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new SubscriptionsClient({\n fetcher: fetcher ?? createSubscriptionFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n\nexport function useSubscriptionClient(): SubscriptionsClientContract {\n return useSubscriptionContext().client;\n}\n\nexport function useSubscriptionInvalidation(): () => void {\n return useSubscriptionContext().invalidate;\n}\n\nexport function useSubscriptionCacheVersion(): number {\n return useSubscriptionContext().cacheVersion;\n}\n\nexport function createSubscriptionFetcher(basePath: string): SubscriptionFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useSubscriptionContext(): SubscriptionContextValue {\n const ctx = useContext(SubscriptionContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/subscriptions hooks must be used inside <SubscriptionProvider />',\n );\n }\n return ctx;\n}\n\nexport function SubscriptionProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: SubscriptionsClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSubscriptionCacheVersion,\n useSubscriptionClient,\n useSubscriptionInvalidation,\n} from './provider';\nimport type {\n CancelSubscriptionInput,\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n MutationState,\n PaginatedSubscriptions,\n QueryOptions,\n QueryState,\n Subscription,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport function useSubscriptions(\n params: ListSubscriptionsParams = {},\n options: QueryOptions<PaginatedSubscriptions> = {},\n): QueryState<PaginatedSubscriptions> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n const stableParams = useStableValue(params);\n return useAsyncQuery(\n () => client.list(stableParams),\n [client, stableParams, cacheVersion],\n options,\n );\n}\n\nexport function useSubscription(\n id: string | null | undefined,\n options: QueryOptions<Subscription> = {},\n): QueryState<Subscription> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useCustomerByExternalId(\n externalId: string | null | undefined,\n options: QueryOptions<Customer> = {},\n): QueryState<Customer> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (externalId ? client.getCustomerByExternalId(externalId) : Promise.resolve(null)),\n [client, externalId, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(externalId) },\n );\n}\n\nexport function useCustomerPaymentMethods(\n customerId: string | null | undefined,\n options: QueryOptions<CustomerPaymentMethod[]> = {},\n): QueryState<CustomerPaymentMethod[]> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (customerId ? client.listCustomerPaymentMethods(customerId) : Promise.resolve(null)),\n [client, customerId, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(customerId) },\n );\n}\n\nexport function useTrialEligibility(): MutationState<\n TrialEligibilityResult,\n TrialEligibilityInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.checkTrialEligibility(input));\n}\n\nexport function useCreateSubscription(): MutationState<Subscription, CreateSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.create(input), invalidate);\n}\n\nexport function useUpdateSubscription(): MutationState<\n Subscription,\n { id: string; data: UpdateSubscriptionInput }\n> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(({ id, data }) => client.update(id, data), invalidate);\n}\n\nexport function useChangePlan(): MutationState<Subscription, ChangePlanInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.changePlan(input), invalidate);\n}\n\nexport function useCancelSubscription(): MutationState<Subscription, CancelSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(\n (input) => client.cancel(input.id, { atPeriodEnd: input.atPeriodEnd }),\n invalidate,\n );\n}\n\nexport function usePauseSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.pause(input.id), invalidate);\n}\n\nexport function useResumeSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.resume(input.id), invalidate);\n}\n\nexport function useCreateCheckoutSession(): MutationState<\n CheckoutSession,\n CreateCheckoutSessionInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.createCheckoutSession(input));\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useAsyncMutation<TData, TVariables>(\n action: (variables: TVariables) => Promise<TData>,\n onSuccess?: () => void,\n): MutationState<TData, TVariables> {\n const [data, setData] = useState<TData | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [isPending, setIsPending] = useState(false);\n\n const mutateAsync = useCallback(\n async (variables: TVariables) => {\n setIsPending(true);\n setError(null);\n try {\n const next = await action(variables);\n setData(next);\n onSuccess?.();\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsPending(false);\n }\n },\n [action, onSuccess],\n );\n\n const mutate = useCallback(\n (variables: TVariables) => {\n void mutateAsync(variables).catch(() => undefined);\n },\n [mutateAsync],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsPending(false);\n }, []);\n\n return { data, error, isPending, mutate, mutateAsync, reset };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n","import type { Subscription, SubscriptionStatus } from './types';\n\nexport function isTerminalSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'cancelled';\n}\n\nexport function canPauseSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'active';\n}\n\nexport function canResumeSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'paused';\n}\n\nexport function canCancelSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) !== 'cancelled';\n}\n\nexport function isSubscriptionPastDue(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'past_due';\n}\n\nexport function isSubscriptionTrialing(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'trialing';\n}\n\nexport function daysUntil(date: string | Date, now = new Date()): number {\n const end = date instanceof Date ? date : new Date(date);\n const ms = end.getTime() - now.getTime();\n if (!Number.isFinite(ms)) return 0;\n return Math.max(0, Math.ceil(ms / 86_400_000));\n}\n\nfunction getStatus(input: SubscriptionStatus | Subscription): SubscriptionStatus {\n return typeof input === 'string' ? input : input.status;\n}\n","import type { CSSProperties } from 'react';\nimport { daysUntil } from './helpers';\nimport type {\n DunningBannerProps,\n SubscriptionStatus,\n SubscriptionStatusBadgeProps,\n TrialCountdownProps,\n} from './types';\n\nconst STATUS_LABELS: Record<SubscriptionStatus, string> = {\n active: 'Active',\n paused: 'Paused',\n cancelled: 'Cancelled',\n past_due: 'Past due',\n trialing: 'Trialing',\n};\n\nconst STATUS_STYLES: Record<SubscriptionStatus, CSSProperties> = {\n active: { color: '#035c4f', background: '#dff8ef', borderColor: '#a8e8d2' },\n paused: { color: '#735c00', background: '#fff4ca', borderColor: '#f3d46b' },\n cancelled: { color: '#6c2632', background: '#ffe1e7', borderColor: '#f4a9b8' },\n past_due: { color: '#7a2d00', background: '#ffe8d6', borderColor: '#f5b47f' },\n trialing: { color: '#124c73', background: '#dff1ff', borderColor: '#9ed3fb' },\n};\n\nexport function SubscriptionStatusBadge({\n status,\n className,\n style,\n labels,\n}: SubscriptionStatusBadgeProps) {\n return (\n <span\n className={className}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n border: '1px solid',\n borderRadius: 999,\n padding: '2px 8px',\n fontSize: 12,\n fontWeight: 700,\n lineHeight: 1.6,\n whiteSpace: 'nowrap',\n ...STATUS_STYLES[status],\n ...style,\n }}\n >\n {labels?.[status] ?? STATUS_LABELS[status]}\n </span>\n );\n}\n\nexport function TrialCountdown({\n endDate,\n now,\n className,\n style,\n expiredLabel = 'Trial ended',\n prefix = 'Trial ends in',\n}: TrialCountdownProps) {\n const days = daysUntil(endDate, now);\n const label = days <= 0 ? expiredLabel : `${prefix} ${days} ${days === 1 ? 'day' : 'days'}`;\n\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nexport function DunningBanner({\n subscription,\n onUpdateCard,\n title = 'Payment needs attention',\n message,\n actionLabel = 'Update card',\n className,\n style,\n}: DunningBannerProps) {\n if (subscription.status !== 'past_due') return null;\n const fallbackMessage =\n subscription.failureCount > 0\n ? `We could not renew this subscription after ${subscription.failureCount} failed payment attempt${\n subscription.failureCount === 1 ? '' : 's'\n }.`\n : 'We could not renew this subscription with the saved payment method.';\n\n return (\n <div\n role=\"status\"\n className={className}\n style={{\n border: '1px solid #f5b47f',\n borderRadius: 8,\n background: '#fff7ed',\n color: '#7a2d00',\n padding: 16,\n display: 'grid',\n gap: 10,\n ...style,\n }}\n >\n <strong>{title}</strong>\n <span>{message ?? fallbackMessage}</span>\n {onUpdateCard ? (\n <button\n type=\"button\"\n onClick={onUpdateCard}\n style={{\n width: 'fit-content',\n border: '1px solid #7a2d00',\n borderRadius: 6,\n background: '#7a2d00',\n color: '#fff',\n padding: '8px 12px',\n fontWeight: 700,\n cursor: 'pointer',\n }}\n >\n {actionLabel}\n </button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["value","import_react","import_jsx_runtime"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SubscriptionProviderProps, a as SubscriptionsClientContract, b as SubscriptionFetcher, M as MutationState, c as Subscription, C as CancelSubscriptionInput, d as ChangePlanInput, e as CheckoutSession, f as CreateCheckoutSessionInput, g as CreateSubscriptionInput, Q as QueryOptions, h as Customer, i as QueryState, L as ListSubscriptionsParams, P as PaginatedSubscriptions, T as TrialEligibilityResult,
|
|
2
|
-
export {
|
|
1
|
+
import { S as SubscriptionProviderProps, a as SubscriptionsClientContract, b as SubscriptionFetcher, M as MutationState, c as Subscription, C as CancelSubscriptionInput, d as ChangePlanInput, e as CheckoutSession, f as CreateCheckoutSessionInput, g as CreateSubscriptionInput, Q as QueryOptions, h as Customer, i as QueryState, j as CustomerPaymentMethod, L as ListSubscriptionsParams, P as PaginatedSubscriptions, T as TrialEligibilityResult, k as TrialEligibilityInput, U as UpdateSubscriptionInput, D as DunningBannerProps, l as SubscriptionStatusBadgeProps, m as TrialCountdownProps, n as SubscriptionStatus } from './errors-CZVUZzk3.cjs';
|
|
2
|
+
export { o as CheckoutCollectInput, p as CheckoutCustomerInput, q as Pagination, R as RecurringIntent, r as SubscriptionInterval, s as SubscriptionSort, t as SubscriptionsClient, u as SubscriptionsClientOptions, v as ThrottleEnvelope, w as ThrottleSubscriptionsError, x as TrialEligibilityReason, y as createSubscriptionsClient } from './errors-CZVUZzk3.cjs';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -15,6 +15,7 @@ declare function SubscriptionProviderWithClient({ children, client, }: {
|
|
|
15
15
|
declare function useSubscriptions(params?: ListSubscriptionsParams, options?: QueryOptions<PaginatedSubscriptions>): QueryState<PaginatedSubscriptions>;
|
|
16
16
|
declare function useSubscription(id: string | null | undefined, options?: QueryOptions<Subscription>): QueryState<Subscription>;
|
|
17
17
|
declare function useCustomerByExternalId(externalId: string | null | undefined, options?: QueryOptions<Customer>): QueryState<Customer>;
|
|
18
|
+
declare function useCustomerPaymentMethods(customerId: string | null | undefined, options?: QueryOptions<CustomerPaymentMethod[]>): QueryState<CustomerPaymentMethod[]>;
|
|
18
19
|
declare function useTrialEligibility(): MutationState<TrialEligibilityResult, TrialEligibilityInput>;
|
|
19
20
|
declare function useCreateSubscription(): MutationState<Subscription, CreateSubscriptionInput>;
|
|
20
21
|
declare function useUpdateSubscription(): MutationState<Subscription, {
|
|
@@ -43,4 +44,4 @@ declare function isSubscriptionPastDue(status: SubscriptionStatus | Subscription
|
|
|
43
44
|
declare function isSubscriptionTrialing(status: SubscriptionStatus | Subscription): boolean;
|
|
44
45
|
declare function daysUntil(date: string | Date, now?: Date): number;
|
|
45
46
|
|
|
46
|
-
export { CancelSubscriptionInput, ChangePlanInput, CheckoutSession, CreateCheckoutSessionInput, CreateSubscriptionInput, Customer, DunningBanner, DunningBannerProps, ListSubscriptionsParams, MutationState, PaginatedSubscriptions, QueryOptions, QueryState, Subscription, SubscriptionFetcher, SubscriptionProvider, SubscriptionProviderProps, SubscriptionProviderWithClient, SubscriptionStatus, SubscriptionStatusBadge, SubscriptionStatusBadgeProps, SubscriptionsClientContract, TrialCountdown, TrialCountdownProps, TrialEligibilityInput, TrialEligibilityResult, UpdateSubscriptionInput, canCancelSubscription, canPauseSubscription, canResumeSubscription, createSubscriptionFetcher, daysUntil, isSubscriptionPastDue, isSubscriptionTrialing, isTerminalSubscription, useCancelSubscription, useChangePlan, useCreateCheckoutSession, useCreateSubscription, useCustomerByExternalId, usePauseSubscription, useResumeSubscription, useSubscription, useSubscriptionClient, useSubscriptionInvalidation, useSubscriptions, useTrialEligibility, useUpdateSubscription };
|
|
47
|
+
export { CancelSubscriptionInput, ChangePlanInput, CheckoutSession, CreateCheckoutSessionInput, CreateSubscriptionInput, Customer, CustomerPaymentMethod, DunningBanner, DunningBannerProps, ListSubscriptionsParams, MutationState, PaginatedSubscriptions, QueryOptions, QueryState, Subscription, SubscriptionFetcher, SubscriptionProvider, SubscriptionProviderProps, SubscriptionProviderWithClient, SubscriptionStatus, SubscriptionStatusBadge, SubscriptionStatusBadgeProps, SubscriptionsClientContract, TrialCountdown, TrialCountdownProps, TrialEligibilityInput, TrialEligibilityResult, UpdateSubscriptionInput, canCancelSubscription, canPauseSubscription, canResumeSubscription, createSubscriptionFetcher, daysUntil, isSubscriptionPastDue, isSubscriptionTrialing, isTerminalSubscription, useCancelSubscription, useChangePlan, useCreateCheckoutSession, useCreateSubscription, useCustomerByExternalId, useCustomerPaymentMethods, usePauseSubscription, useResumeSubscription, useSubscription, useSubscriptionClient, useSubscriptionInvalidation, useSubscriptions, useTrialEligibility, useUpdateSubscription };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as SubscriptionProviderProps, a as SubscriptionsClientContract, b as SubscriptionFetcher, M as MutationState, c as Subscription, C as CancelSubscriptionInput, d as ChangePlanInput, e as CheckoutSession, f as CreateCheckoutSessionInput, g as CreateSubscriptionInput, Q as QueryOptions, h as Customer, i as QueryState, L as ListSubscriptionsParams, P as PaginatedSubscriptions, T as TrialEligibilityResult,
|
|
2
|
-
export {
|
|
1
|
+
import { S as SubscriptionProviderProps, a as SubscriptionsClientContract, b as SubscriptionFetcher, M as MutationState, c as Subscription, C as CancelSubscriptionInput, d as ChangePlanInput, e as CheckoutSession, f as CreateCheckoutSessionInput, g as CreateSubscriptionInput, Q as QueryOptions, h as Customer, i as QueryState, j as CustomerPaymentMethod, L as ListSubscriptionsParams, P as PaginatedSubscriptions, T as TrialEligibilityResult, k as TrialEligibilityInput, U as UpdateSubscriptionInput, D as DunningBannerProps, l as SubscriptionStatusBadgeProps, m as TrialCountdownProps, n as SubscriptionStatus } from './errors-CZVUZzk3.js';
|
|
2
|
+
export { o as CheckoutCollectInput, p as CheckoutCustomerInput, q as Pagination, R as RecurringIntent, r as SubscriptionInterval, s as SubscriptionSort, t as SubscriptionsClient, u as SubscriptionsClientOptions, v as ThrottleEnvelope, w as ThrottleSubscriptionsError, x as TrialEligibilityReason, y as createSubscriptionsClient } from './errors-CZVUZzk3.js';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -15,6 +15,7 @@ declare function SubscriptionProviderWithClient({ children, client, }: {
|
|
|
15
15
|
declare function useSubscriptions(params?: ListSubscriptionsParams, options?: QueryOptions<PaginatedSubscriptions>): QueryState<PaginatedSubscriptions>;
|
|
16
16
|
declare function useSubscription(id: string | null | undefined, options?: QueryOptions<Subscription>): QueryState<Subscription>;
|
|
17
17
|
declare function useCustomerByExternalId(externalId: string | null | undefined, options?: QueryOptions<Customer>): QueryState<Customer>;
|
|
18
|
+
declare function useCustomerPaymentMethods(customerId: string | null | undefined, options?: QueryOptions<CustomerPaymentMethod[]>): QueryState<CustomerPaymentMethod[]>;
|
|
18
19
|
declare function useTrialEligibility(): MutationState<TrialEligibilityResult, TrialEligibilityInput>;
|
|
19
20
|
declare function useCreateSubscription(): MutationState<Subscription, CreateSubscriptionInput>;
|
|
20
21
|
declare function useUpdateSubscription(): MutationState<Subscription, {
|
|
@@ -43,4 +44,4 @@ declare function isSubscriptionPastDue(status: SubscriptionStatus | Subscription
|
|
|
43
44
|
declare function isSubscriptionTrialing(status: SubscriptionStatus | Subscription): boolean;
|
|
44
45
|
declare function daysUntil(date: string | Date, now?: Date): number;
|
|
45
46
|
|
|
46
|
-
export { CancelSubscriptionInput, ChangePlanInput, CheckoutSession, CreateCheckoutSessionInput, CreateSubscriptionInput, Customer, DunningBanner, DunningBannerProps, ListSubscriptionsParams, MutationState, PaginatedSubscriptions, QueryOptions, QueryState, Subscription, SubscriptionFetcher, SubscriptionProvider, SubscriptionProviderProps, SubscriptionProviderWithClient, SubscriptionStatus, SubscriptionStatusBadge, SubscriptionStatusBadgeProps, SubscriptionsClientContract, TrialCountdown, TrialCountdownProps, TrialEligibilityInput, TrialEligibilityResult, UpdateSubscriptionInput, canCancelSubscription, canPauseSubscription, canResumeSubscription, createSubscriptionFetcher, daysUntil, isSubscriptionPastDue, isSubscriptionTrialing, isTerminalSubscription, useCancelSubscription, useChangePlan, useCreateCheckoutSession, useCreateSubscription, useCustomerByExternalId, usePauseSubscription, useResumeSubscription, useSubscription, useSubscriptionClient, useSubscriptionInvalidation, useSubscriptions, useTrialEligibility, useUpdateSubscription };
|
|
47
|
+
export { CancelSubscriptionInput, ChangePlanInput, CheckoutSession, CreateCheckoutSessionInput, CreateSubscriptionInput, Customer, CustomerPaymentMethod, DunningBanner, DunningBannerProps, ListSubscriptionsParams, MutationState, PaginatedSubscriptions, QueryOptions, QueryState, Subscription, SubscriptionFetcher, SubscriptionProvider, SubscriptionProviderProps, SubscriptionProviderWithClient, SubscriptionStatus, SubscriptionStatusBadge, SubscriptionStatusBadgeProps, SubscriptionsClientContract, TrialCountdown, TrialCountdownProps, TrialEligibilityInput, TrialEligibilityResult, UpdateSubscriptionInput, canCancelSubscription, canPauseSubscription, canResumeSubscription, createSubscriptionFetcher, daysUntil, isSubscriptionPastDue, isSubscriptionTrialing, isTerminalSubscription, useCancelSubscription, useChangePlan, useCreateCheckoutSession, useCreateSubscription, useCustomerByExternalId, useCustomerPaymentMethods, usePauseSubscription, useResumeSubscription, useSubscription, useSubscriptionClient, useSubscriptionInvalidation, useSubscriptions, useTrialEligibility, useUpdateSubscription };
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
SubscriptionsClient,
|
|
3
3
|
ThrottleSubscriptionsError,
|
|
4
4
|
createSubscriptionsClient
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SXTIX2Y2.js";
|
|
6
6
|
|
|
7
7
|
// src/provider.tsx
|
|
8
8
|
import { createContext, useContext, useMemo, useReducer } from "react";
|
|
@@ -94,6 +94,15 @@ function useCustomerByExternalId(externalId, options = {}) {
|
|
|
94
94
|
{ ...options, enabled: options.enabled ?? Boolean(externalId) }
|
|
95
95
|
);
|
|
96
96
|
}
|
|
97
|
+
function useCustomerPaymentMethods(customerId, options = {}) {
|
|
98
|
+
const client = useSubscriptionClient();
|
|
99
|
+
const cacheVersion = useSubscriptionCacheVersion();
|
|
100
|
+
return useAsyncQuery(
|
|
101
|
+
() => customerId ? client.listCustomerPaymentMethods(customerId) : Promise.resolve(null),
|
|
102
|
+
[client, customerId, cacheVersion],
|
|
103
|
+
{ ...options, enabled: options.enabled ?? Boolean(customerId) }
|
|
104
|
+
);
|
|
105
|
+
}
|
|
97
106
|
function useTrialEligibility() {
|
|
98
107
|
const client = useSubscriptionClient();
|
|
99
108
|
return useAsyncMutation((input) => client.checkTrialEligibility(input));
|
|
@@ -380,6 +389,7 @@ export {
|
|
|
380
389
|
useCreateCheckoutSession,
|
|
381
390
|
useCreateSubscription,
|
|
382
391
|
useCustomerByExternalId,
|
|
392
|
+
useCustomerPaymentMethods,
|
|
383
393
|
usePauseSubscription,
|
|
384
394
|
useResumeSubscription,
|
|
385
395
|
useSubscription,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/provider.tsx","../src/hooks.ts","../src/helpers.ts","../src/components.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { SubscriptionsClient } from './client';\nimport type {\n SubscriptionFetcher,\n SubscriptionProviderProps,\n SubscriptionsClientContract,\n} from './types';\n\ninterface SubscriptionContextValue {\n client: SubscriptionsClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst SubscriptionContext = createContext<SubscriptionContextValue | null>(null);\n\nexport function SubscriptionProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: SubscriptionProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new SubscriptionsClient({\n fetcher: fetcher ?? createSubscriptionFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n\nexport function useSubscriptionClient(): SubscriptionsClientContract {\n return useSubscriptionContext().client;\n}\n\nexport function useSubscriptionInvalidation(): () => void {\n return useSubscriptionContext().invalidate;\n}\n\nexport function useSubscriptionCacheVersion(): number {\n return useSubscriptionContext().cacheVersion;\n}\n\nexport function createSubscriptionFetcher(basePath: string): SubscriptionFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useSubscriptionContext(): SubscriptionContextValue {\n const ctx = useContext(SubscriptionContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/subscriptions hooks must be used inside <SubscriptionProvider />',\n );\n }\n return ctx;\n}\n\nexport function SubscriptionProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: SubscriptionsClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSubscriptionCacheVersion,\n useSubscriptionClient,\n useSubscriptionInvalidation,\n} from './provider';\nimport type {\n CancelSubscriptionInput,\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n ListSubscriptionsParams,\n MutationState,\n PaginatedSubscriptions,\n QueryOptions,\n QueryState,\n Subscription,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport function useSubscriptions(\n params: ListSubscriptionsParams = {},\n options: QueryOptions<PaginatedSubscriptions> = {},\n): QueryState<PaginatedSubscriptions> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n const stableParams = useStableValue(params);\n return useAsyncQuery(\n () => client.list(stableParams),\n [client, stableParams, cacheVersion],\n options,\n );\n}\n\nexport function useSubscription(\n id: string | null | undefined,\n options: QueryOptions<Subscription> = {},\n): QueryState<Subscription> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useCustomerByExternalId(\n externalId: string | null | undefined,\n options: QueryOptions<Customer> = {},\n): QueryState<Customer> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (externalId ? client.getCustomerByExternalId(externalId) : Promise.resolve(null)),\n [client, externalId, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(externalId) },\n );\n}\n\nexport function useTrialEligibility(): MutationState<\n TrialEligibilityResult,\n TrialEligibilityInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.checkTrialEligibility(input));\n}\n\nexport function useCreateSubscription(): MutationState<Subscription, CreateSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.create(input), invalidate);\n}\n\nexport function useUpdateSubscription(): MutationState<\n Subscription,\n { id: string; data: UpdateSubscriptionInput }\n> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(({ id, data }) => client.update(id, data), invalidate);\n}\n\nexport function useChangePlan(): MutationState<Subscription, ChangePlanInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.changePlan(input), invalidate);\n}\n\nexport function useCancelSubscription(): MutationState<Subscription, CancelSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(\n (input) => client.cancel(input.id, { atPeriodEnd: input.atPeriodEnd }),\n invalidate,\n );\n}\n\nexport function usePauseSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.pause(input.id), invalidate);\n}\n\nexport function useResumeSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.resume(input.id), invalidate);\n}\n\nexport function useCreateCheckoutSession(): MutationState<\n CheckoutSession,\n CreateCheckoutSessionInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.createCheckoutSession(input));\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useAsyncMutation<TData, TVariables>(\n action: (variables: TVariables) => Promise<TData>,\n onSuccess?: () => void,\n): MutationState<TData, TVariables> {\n const [data, setData] = useState<TData | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [isPending, setIsPending] = useState(false);\n\n const mutateAsync = useCallback(\n async (variables: TVariables) => {\n setIsPending(true);\n setError(null);\n try {\n const next = await action(variables);\n setData(next);\n onSuccess?.();\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsPending(false);\n }\n },\n [action, onSuccess],\n );\n\n const mutate = useCallback(\n (variables: TVariables) => {\n void mutateAsync(variables).catch(() => undefined);\n },\n [mutateAsync],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsPending(false);\n }, []);\n\n return { data, error, isPending, mutate, mutateAsync, reset };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n","import type { Subscription, SubscriptionStatus } from './types';\n\nexport function isTerminalSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'cancelled';\n}\n\nexport function canPauseSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'active';\n}\n\nexport function canResumeSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'paused';\n}\n\nexport function canCancelSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) !== 'cancelled';\n}\n\nexport function isSubscriptionPastDue(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'past_due';\n}\n\nexport function isSubscriptionTrialing(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'trialing';\n}\n\nexport function daysUntil(date: string | Date, now = new Date()): number {\n const end = date instanceof Date ? date : new Date(date);\n const ms = end.getTime() - now.getTime();\n if (!Number.isFinite(ms)) return 0;\n return Math.max(0, Math.ceil(ms / 86_400_000));\n}\n\nfunction getStatus(input: SubscriptionStatus | Subscription): SubscriptionStatus {\n return typeof input === 'string' ? input : input.status;\n}\n","import type { CSSProperties } from 'react';\nimport { daysUntil } from './helpers';\nimport type {\n DunningBannerProps,\n SubscriptionStatus,\n SubscriptionStatusBadgeProps,\n TrialCountdownProps,\n} from './types';\n\nconst STATUS_LABELS: Record<SubscriptionStatus, string> = {\n active: 'Active',\n paused: 'Paused',\n cancelled: 'Cancelled',\n past_due: 'Past due',\n trialing: 'Trialing',\n};\n\nconst STATUS_STYLES: Record<SubscriptionStatus, CSSProperties> = {\n active: { color: '#035c4f', background: '#dff8ef', borderColor: '#a8e8d2' },\n paused: { color: '#735c00', background: '#fff4ca', borderColor: '#f3d46b' },\n cancelled: { color: '#6c2632', background: '#ffe1e7', borderColor: '#f4a9b8' },\n past_due: { color: '#7a2d00', background: '#ffe8d6', borderColor: '#f5b47f' },\n trialing: { color: '#124c73', background: '#dff1ff', borderColor: '#9ed3fb' },\n};\n\nexport function SubscriptionStatusBadge({\n status,\n className,\n style,\n labels,\n}: SubscriptionStatusBadgeProps) {\n return (\n <span\n className={className}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n border: '1px solid',\n borderRadius: 999,\n padding: '2px 8px',\n fontSize: 12,\n fontWeight: 700,\n lineHeight: 1.6,\n whiteSpace: 'nowrap',\n ...STATUS_STYLES[status],\n ...style,\n }}\n >\n {labels?.[status] ?? STATUS_LABELS[status]}\n </span>\n );\n}\n\nexport function TrialCountdown({\n endDate,\n now,\n className,\n style,\n expiredLabel = 'Trial ended',\n prefix = 'Trial ends in',\n}: TrialCountdownProps) {\n const days = daysUntil(endDate, now);\n const label = days <= 0 ? expiredLabel : `${prefix} ${days} ${days === 1 ? 'day' : 'days'}`;\n\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nexport function DunningBanner({\n subscription,\n onUpdateCard,\n title = 'Payment needs attention',\n message,\n actionLabel = 'Update card',\n className,\n style,\n}: DunningBannerProps) {\n if (subscription.status !== 'past_due') return null;\n const fallbackMessage =\n subscription.failureCount > 0\n ? `We could not renew this subscription after ${subscription.failureCount} failed payment attempt${\n subscription.failureCount === 1 ? '' : 's'\n }.`\n : 'We could not renew this subscription with the saved payment method.';\n\n return (\n <div\n role=\"status\"\n className={className}\n style={{\n border: '1px solid #f5b47f',\n borderRadius: 8,\n background: '#fff7ed',\n color: '#7a2d00',\n padding: 16,\n display: 'grid',\n gap: 10,\n ...style,\n }}\n >\n <strong>{title}</strong>\n <span>{message ?? fallbackMessage}</span>\n {onUpdateCard ? (\n <button\n type=\"button\"\n onClick={onUpdateCard}\n style={{\n width: 'fit-content',\n border: '1px solid #7a2d00',\n borderRadius: 6,\n background: '#7a2d00',\n color: '#fff',\n padding: '8px 12px',\n fontWeight: 700,\n cursor: 'pointer',\n }}\n >\n {actionLabel}\n </button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["value","useCallback","useMemo","useCallback","useMemo","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/provider.tsx","../src/hooks.ts","../src/helpers.ts","../src/components.tsx"],"sourcesContent":["import { createContext, useCallback, useContext, useMemo, useReducer, type ReactNode } from 'react';\nimport { SubscriptionsClient } from './client';\nimport type {\n SubscriptionFetcher,\n SubscriptionProviderProps,\n SubscriptionsClientContract,\n} from './types';\n\ninterface SubscriptionContextValue {\n client: SubscriptionsClientContract;\n cacheVersion: number;\n invalidate: () => void;\n}\n\nconst SubscriptionContext = createContext<SubscriptionContextValue | null>(null);\n\nexport function SubscriptionProvider({\n children,\n client,\n fetcher,\n baseUrl,\n timeoutMs,\n}: SubscriptionProviderProps) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const resolvedClient = useMemo(() => {\n if (client) return client;\n return new SubscriptionsClient({\n fetcher: fetcher ?? createSubscriptionFetcher('/api/throttle'),\n baseUrl,\n timeoutMs,\n });\n }, [baseUrl, client, fetcher, timeoutMs]);\n\n const value = useMemo(\n () => ({ client: resolvedClient, cacheVersion, invalidate }),\n [cacheVersion, resolvedClient],\n );\n\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n\nexport function useSubscriptionClient(): SubscriptionsClientContract {\n return useSubscriptionContext().client;\n}\n\nexport function useSubscriptionInvalidation(): () => void {\n return useSubscriptionContext().invalidate;\n}\n\nexport function useSubscriptionCacheVersion(): number {\n return useSubscriptionContext().cacheVersion;\n}\n\nexport function createSubscriptionFetcher(basePath: string): SubscriptionFetcher {\n const cleanBase = basePath.replace(/\\/+$/, '');\n return (path, init) => {\n const cleanPath = path.startsWith('/') ? path : `/${path}`;\n return fetch(`${cleanBase}${cleanPath}`, init);\n };\n}\n\nexport function useSubscriptionContext(): SubscriptionContextValue {\n const ctx = useContext(SubscriptionContext);\n if (!ctx) {\n throw new Error(\n '@usethrottle/subscriptions hooks must be used inside <SubscriptionProvider />',\n );\n }\n return ctx;\n}\n\nexport function SubscriptionProviderWithClient({\n children,\n client,\n}: {\n children: ReactNode;\n client: SubscriptionsClientContract;\n}) {\n const [cacheVersion, invalidate] = useReducer((value: number) => value + 1, 0);\n const value = useMemo(() => ({ client, cacheVersion, invalidate }), [cacheVersion, client]);\n return <SubscriptionContext.Provider value={value}>{children}</SubscriptionContext.Provider>;\n}\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSubscriptionCacheVersion,\n useSubscriptionClient,\n useSubscriptionInvalidation,\n} from './provider';\nimport type {\n CancelSubscriptionInput,\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n MutationState,\n PaginatedSubscriptions,\n QueryOptions,\n QueryState,\n Subscription,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport function useSubscriptions(\n params: ListSubscriptionsParams = {},\n options: QueryOptions<PaginatedSubscriptions> = {},\n): QueryState<PaginatedSubscriptions> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n const stableParams = useStableValue(params);\n return useAsyncQuery(\n () => client.list(stableParams),\n [client, stableParams, cacheVersion],\n options,\n );\n}\n\nexport function useSubscription(\n id: string | null | undefined,\n options: QueryOptions<Subscription> = {},\n): QueryState<Subscription> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (id ? client.get(id) : Promise.resolve(null)),\n [client, id, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(id) },\n );\n}\n\nexport function useCustomerByExternalId(\n externalId: string | null | undefined,\n options: QueryOptions<Customer> = {},\n): QueryState<Customer> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (externalId ? client.getCustomerByExternalId(externalId) : Promise.resolve(null)),\n [client, externalId, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(externalId) },\n );\n}\n\nexport function useCustomerPaymentMethods(\n customerId: string | null | undefined,\n options: QueryOptions<CustomerPaymentMethod[]> = {},\n): QueryState<CustomerPaymentMethod[]> {\n const client = useSubscriptionClient();\n const cacheVersion = useSubscriptionCacheVersion();\n return useAsyncQuery(\n () => (customerId ? client.listCustomerPaymentMethods(customerId) : Promise.resolve(null)),\n [client, customerId, cacheVersion],\n { ...options, enabled: options.enabled ?? Boolean(customerId) },\n );\n}\n\nexport function useTrialEligibility(): MutationState<\n TrialEligibilityResult,\n TrialEligibilityInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.checkTrialEligibility(input));\n}\n\nexport function useCreateSubscription(): MutationState<Subscription, CreateSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.create(input), invalidate);\n}\n\nexport function useUpdateSubscription(): MutationState<\n Subscription,\n { id: string; data: UpdateSubscriptionInput }\n> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(({ id, data }) => client.update(id, data), invalidate);\n}\n\nexport function useChangePlan(): MutationState<Subscription, ChangePlanInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.changePlan(input), invalidate);\n}\n\nexport function useCancelSubscription(): MutationState<Subscription, CancelSubscriptionInput> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation(\n (input) => client.cancel(input.id, { atPeriodEnd: input.atPeriodEnd }),\n invalidate,\n );\n}\n\nexport function usePauseSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.pause(input.id), invalidate);\n}\n\nexport function useResumeSubscription(): MutationState<Subscription, { id: string }> {\n const client = useSubscriptionClient();\n const invalidate = useSubscriptionInvalidation();\n return useAsyncMutation((input) => client.resume(input.id), invalidate);\n}\n\nexport function useCreateCheckoutSession(): MutationState<\n CheckoutSession,\n CreateCheckoutSessionInput\n> {\n const client = useSubscriptionClient();\n return useAsyncMutation((input) => client.createCheckoutSession(input));\n}\n\nfunction useAsyncQuery<T>(\n load: () => Promise<T | null>,\n deps: readonly unknown[],\n options: QueryOptions<T>,\n): QueryState<T> {\n const enabled = options.enabled ?? true;\n const [data, setData] = useState<T | null>(options.initialData ?? null);\n const [error, setError] = useState<unknown>(null);\n const [isLoading, setIsLoading] = useState(enabled && options.initialData === undefined);\n const [isFetching, setIsFetching] = useState(false);\n const loadRef = useRef(load);\n loadRef.current = load;\n\n const refetch = useCallback(async () => {\n if (!enabled) return data;\n setIsFetching(true);\n setError(null);\n try {\n const next = await loadRef.current();\n setData(next);\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsFetching(false);\n setIsLoading(false);\n }\n }, [data, enabled]);\n\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let cancelled = false;\n setIsFetching(true);\n setError(null);\n load()\n .then((next) => {\n if (!cancelled) setData(next);\n })\n .catch((err) => {\n if (!cancelled) setError(err);\n })\n .finally(() => {\n if (!cancelled) {\n setIsLoading(false);\n setIsFetching(false);\n }\n });\n\n return () => {\n cancelled = true;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [enabled, ...deps]);\n\n return { data, error, isLoading, isFetching, refetch };\n}\n\nfunction useAsyncMutation<TData, TVariables>(\n action: (variables: TVariables) => Promise<TData>,\n onSuccess?: () => void,\n): MutationState<TData, TVariables> {\n const [data, setData] = useState<TData | null>(null);\n const [error, setError] = useState<unknown>(null);\n const [isPending, setIsPending] = useState(false);\n\n const mutateAsync = useCallback(\n async (variables: TVariables) => {\n setIsPending(true);\n setError(null);\n try {\n const next = await action(variables);\n setData(next);\n onSuccess?.();\n return next;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n setIsPending(false);\n }\n },\n [action, onSuccess],\n );\n\n const mutate = useCallback(\n (variables: TVariables) => {\n void mutateAsync(variables).catch(() => undefined);\n },\n [mutateAsync],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsPending(false);\n }, []);\n\n return { data, error, isPending, mutate, mutateAsync, reset };\n}\n\nfunction useStableValue<T>(value: T): T {\n const key = JSON.stringify(value);\n return useMemo(() => value, [key]);\n}\n","import type { Subscription, SubscriptionStatus } from './types';\n\nexport function isTerminalSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'cancelled';\n}\n\nexport function canPauseSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'active';\n}\n\nexport function canResumeSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'paused';\n}\n\nexport function canCancelSubscription(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) !== 'cancelled';\n}\n\nexport function isSubscriptionPastDue(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'past_due';\n}\n\nexport function isSubscriptionTrialing(status: SubscriptionStatus | Subscription): boolean {\n return getStatus(status) === 'trialing';\n}\n\nexport function daysUntil(date: string | Date, now = new Date()): number {\n const end = date instanceof Date ? date : new Date(date);\n const ms = end.getTime() - now.getTime();\n if (!Number.isFinite(ms)) return 0;\n return Math.max(0, Math.ceil(ms / 86_400_000));\n}\n\nfunction getStatus(input: SubscriptionStatus | Subscription): SubscriptionStatus {\n return typeof input === 'string' ? input : input.status;\n}\n","import type { CSSProperties } from 'react';\nimport { daysUntil } from './helpers';\nimport type {\n DunningBannerProps,\n SubscriptionStatus,\n SubscriptionStatusBadgeProps,\n TrialCountdownProps,\n} from './types';\n\nconst STATUS_LABELS: Record<SubscriptionStatus, string> = {\n active: 'Active',\n paused: 'Paused',\n cancelled: 'Cancelled',\n past_due: 'Past due',\n trialing: 'Trialing',\n};\n\nconst STATUS_STYLES: Record<SubscriptionStatus, CSSProperties> = {\n active: { color: '#035c4f', background: '#dff8ef', borderColor: '#a8e8d2' },\n paused: { color: '#735c00', background: '#fff4ca', borderColor: '#f3d46b' },\n cancelled: { color: '#6c2632', background: '#ffe1e7', borderColor: '#f4a9b8' },\n past_due: { color: '#7a2d00', background: '#ffe8d6', borderColor: '#f5b47f' },\n trialing: { color: '#124c73', background: '#dff1ff', borderColor: '#9ed3fb' },\n};\n\nexport function SubscriptionStatusBadge({\n status,\n className,\n style,\n labels,\n}: SubscriptionStatusBadgeProps) {\n return (\n <span\n className={className}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n border: '1px solid',\n borderRadius: 999,\n padding: '2px 8px',\n fontSize: 12,\n fontWeight: 700,\n lineHeight: 1.6,\n whiteSpace: 'nowrap',\n ...STATUS_STYLES[status],\n ...style,\n }}\n >\n {labels?.[status] ?? STATUS_LABELS[status]}\n </span>\n );\n}\n\nexport function TrialCountdown({\n endDate,\n now,\n className,\n style,\n expiredLabel = 'Trial ended',\n prefix = 'Trial ends in',\n}: TrialCountdownProps) {\n const days = daysUntil(endDate, now);\n const label = days <= 0 ? expiredLabel : `${prefix} ${days} ${days === 1 ? 'day' : 'days'}`;\n\n return (\n <span className={className} style={style}>\n {label}\n </span>\n );\n}\n\nexport function DunningBanner({\n subscription,\n onUpdateCard,\n title = 'Payment needs attention',\n message,\n actionLabel = 'Update card',\n className,\n style,\n}: DunningBannerProps) {\n if (subscription.status !== 'past_due') return null;\n const fallbackMessage =\n subscription.failureCount > 0\n ? `We could not renew this subscription after ${subscription.failureCount} failed payment attempt${\n subscription.failureCount === 1 ? '' : 's'\n }.`\n : 'We could not renew this subscription with the saved payment method.';\n\n return (\n <div\n role=\"status\"\n className={className}\n style={{\n border: '1px solid #f5b47f',\n borderRadius: 8,\n background: '#fff7ed',\n color: '#7a2d00',\n padding: 16,\n display: 'grid',\n gap: 10,\n ...style,\n }}\n >\n <strong>{title}</strong>\n <span>{message ?? fallbackMessage}</span>\n {onUpdateCard ? (\n <button\n type=\"button\"\n onClick={onUpdateCard}\n style={{\n width: 'fit-content',\n border: '1px solid #7a2d00',\n borderRadius: 6,\n background: '#7a2d00',\n color: '#fff',\n padding: '8px 12px',\n fontWeight: 700,\n cursor: 'pointer',\n }}\n >\n {actionLabel}\n </button>\n ) : null}\n </div>\n );\n}\n"],"mappings":"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","names":["value","useCallback","useMemo","useCallback","useMemo","jsx"]}
|
package/dist/server.cjs
CHANGED
|
@@ -91,6 +91,18 @@ function normalizeCustomer(raw) {
|
|
|
91
91
|
updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
|
+
function normalizeCustomerPaymentMethod(raw) {
|
|
95
|
+
return {
|
|
96
|
+
id: requiredString(raw?.id, "paymentMethod.id"),
|
|
97
|
+
processor: optionalString(raw?.processor),
|
|
98
|
+
methodType: optionalString(raw?.methodType ?? raw?.method_type),
|
|
99
|
+
cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),
|
|
100
|
+
cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),
|
|
101
|
+
isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),
|
|
102
|
+
createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
|
|
103
|
+
updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
|
|
104
|
+
};
|
|
105
|
+
}
|
|
94
106
|
function normalizeCheckoutSession(raw) {
|
|
95
107
|
const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
|
|
96
108
|
return {
|
|
@@ -294,6 +306,13 @@ var SubscriptionsClient = class {
|
|
|
294
306
|
throw err;
|
|
295
307
|
}
|
|
296
308
|
}
|
|
309
|
+
async listCustomerPaymentMethods(customerId) {
|
|
310
|
+
const data = await this.request(
|
|
311
|
+
"GET",
|
|
312
|
+
`/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`
|
|
313
|
+
);
|
|
314
|
+
return (data ?? []).map(normalizeCustomerPaymentMethod);
|
|
315
|
+
}
|
|
297
316
|
async resolveCustomerId(customerId, externalCustomerId) {
|
|
298
317
|
if (customerId) return customerId;
|
|
299
318
|
if (!externalCustomerId) {
|
|
@@ -331,6 +350,7 @@ var ALLOWED_PATHS = [
|
|
|
331
350
|
/^\/api\/v1\/subscriptions(?:\/[\w.-]+)?(?:\/(?:pause|resume|cancel))?$/,
|
|
332
351
|
/^\/api\/v1\/subscriptions\/eligibility-check$/,
|
|
333
352
|
/^\/api\/v1\/customers\/by-external\/[\w.:%-]+$/,
|
|
353
|
+
/^\/api\/v1\/customers\/[\w.-]+\/payment-methods$/,
|
|
334
354
|
/^\/api\/v1\/checkout\/sessions$/
|
|
335
355
|
];
|
|
336
356
|
function createSubscriptionProxyHandler(options) {
|
|
@@ -404,6 +424,16 @@ async function buildPinnedPathAndBody(request, path, externalCustomerId, client)
|
|
|
404
424
|
)
|
|
405
425
|
};
|
|
406
426
|
}
|
|
427
|
+
if (request.method.toUpperCase() === "GET" && isCustomerPaymentMethodsPath(path)) {
|
|
428
|
+
const customer = await client.getCustomerByExternalId(externalCustomerId);
|
|
429
|
+
if (!customer) return jsonError(404, "not_found", "Customer not found");
|
|
430
|
+
return {
|
|
431
|
+
path: withQuery(
|
|
432
|
+
`/api/v1/customers/${encodeURIComponent(customer.id)}/payment-methods`,
|
|
433
|
+
query
|
|
434
|
+
)
|
|
435
|
+
};
|
|
436
|
+
}
|
|
407
437
|
if (request.method.toUpperCase() !== "GET") {
|
|
408
438
|
const raw = await request.text();
|
|
409
439
|
if (path === "/api/v1/subscriptions" && request.method.toUpperCase() === "POST") {
|
|
@@ -469,6 +499,9 @@ function isSubscriptionMutation(path, method) {
|
|
|
469
499
|
function isCustomerByExternalPath(path) {
|
|
470
500
|
return /^\/api\/v1\/customers\/by-external\/[\w.:%-]+$/.test(path);
|
|
471
501
|
}
|
|
502
|
+
function isCustomerPaymentMethodsPath(path) {
|
|
503
|
+
return /^\/api\/v1\/customers\/[\w.-]+\/payment-methods$/.test(path);
|
|
504
|
+
}
|
|
472
505
|
function subscriptionIdFromPath(path) {
|
|
473
506
|
return path.match(/^\/api\/v1\/subscriptions\/([\w.-]+)/)?.[1] ?? null;
|
|
474
507
|
}
|
package/dist/server.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/errors.ts","../src/normalize.ts","../src/client.ts"],"sourcesContent":["import { SubscriptionsClient, createSubscriptionsClient } from './client';\nimport { ThrottleSubscriptionsError } from './errors';\nimport type { Subscription, SubscriptionsClientOptions } from './types';\n\nexport { SubscriptionsClient, createSubscriptionsClient, ThrottleSubscriptionsError };\nexport type {\n CheckoutSession,\n CreateCheckoutSessionInput,\n Customer,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n TrialEligibilityInput,\n TrialEligibilityResult,\n} from './types';\n\nexport interface SubscriptionProxyOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n getExternalCustomerId: (request: Request) => string | null | Promise<string | null>;\n authorizeMutation?: (args: {\n request: Request;\n subscription: Subscription;\n externalCustomerId: string;\n }) => boolean | Promise<boolean>;\n}\n\nexport interface SubscriptionProxyContext {\n params?: {\n path?: string[] | Promise<string[]>;\n };\n path?: string[] | string;\n}\n\nconst ALLOWED_PATHS = [\n /^\\/api\\/v1\\/subscriptions(?:\\/[\\w.-]+)?(?:\\/(?:pause|resume|cancel))?$/,\n /^\\/api\\/v1\\/subscriptions\\/eligibility-check$/,\n /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/,\n /^\\/api\\/v1\\/checkout\\/sessions$/,\n];\n\nexport function createSubscriptionProxyHandler(options: SubscriptionProxyOptions) {\n return async function subscriptionProxyHandler(\n request: Request,\n context: SubscriptionProxyContext = {},\n ): Promise<Response> {\n const path = await pathFromContext(context);\n return handleSubscriptionProxyRequest(request, path, options);\n };\n}\n\nexport async function handleSubscriptionProxyRequest(\n request: Request,\n pathParts: string[] | string,\n options: SubscriptionProxyOptions,\n): Promise<Response> {\n const externalCustomerId = await options.getExternalCustomerId(request);\n if (!externalCustomerId) return jsonError(401, 'unauthorized', 'Unauthorized');\n\n const path = normalizePath(pathParts);\n if (!ALLOWED_PATHS.some((pattern) => pattern.test(path))) {\n return jsonError(403, 'forbidden', 'Path is not allowed by the subscription proxy');\n }\n\n const method = request.method.toUpperCase();\n if (!['GET', 'POST', 'PATCH'].includes(method)) {\n return jsonError(405, 'method_not_allowed', 'Method not allowed');\n }\n\n const client = new SubscriptionsClient({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n } satisfies SubscriptionsClientOptions);\n\n if (isSubscriptionMutation(path, method)) {\n const subId = subscriptionIdFromPath(path);\n if (subId) {\n const subscription = await client.get(subId).catch((err) => {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n });\n if (!subscription) return jsonError(404, 'not_found', 'Subscription not found');\n\n const defaultAuthorized = await defaultMutationAuthorization(\n client,\n subscription,\n externalCustomerId,\n );\n const customAuthorized = options.authorizeMutation\n ? await options.authorizeMutation({ request, subscription, externalCustomerId })\n : true;\n if (!defaultAuthorized || !customAuthorized) {\n return jsonError(403, 'forbidden', 'Subscription does not belong to this buyer');\n }\n }\n }\n\n const targetPath = await buildPinnedPathAndBody(request, path, externalCustomerId, client);\n if (targetPath instanceof Response) return targetPath;\n const upstream = await fetchWithApiKey(request, targetPath.path, {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n body: targetPath.body,\n });\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: filterHeaders(upstream.headers),\n });\n}\n\nasync function buildPinnedPathAndBody(\n request: Request,\n path: string,\n externalCustomerId: string,\n client: SubscriptionsClient,\n): Promise<{ path: string; body?: string } | Response> {\n const url = new URL(request.url);\n const query = new URLSearchParams(url.search);\n\n if (request.method.toUpperCase() === 'GET' && path === '/api/v1/subscriptions') {\n query.set('externalCustomerId', externalCustomerId);\n query.delete('customerId');\n query.delete('customer_id');\n query.delete('external_customer_id');\n }\n\n if (request.method.toUpperCase() === 'GET' && isCustomerByExternalPath(path)) {\n return {\n path: withQuery(\n `/api/v1/customers/by-external/${encodeURIComponent(externalCustomerId)}`,\n query,\n ),\n };\n }\n\n if (request.method.toUpperCase() !== 'GET') {\n const raw = await request.text();\n if (path === '/api/v1/subscriptions' && request.method.toUpperCase() === 'POST') {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n if (!customer) return jsonError(404, 'not_found', 'Customer not found');\n\n const body = raw ? (JSON.parse(raw) as Record<string, any>) : {};\n body.customerId = customer.id;\n delete body.customer_id;\n delete body.externalCustomerId;\n delete body.external_customer_id;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n\n if (path === '/api/v1/checkout/sessions' && raw) {\n const body = JSON.parse(raw) as Record<string, any>;\n body.customer = {\n ...(body.customer ?? {}),\n externalCustomerId,\n };\n delete body.customer.customerId;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n return { path: withQuery(path, query), body: raw || undefined };\n }\n\n return { path: withQuery(path, query) };\n}\n\nasync function fetchWithApiKey(\n request: Request,\n path: string,\n opts: {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n body?: string;\n },\n) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('fetch is required');\n const baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n return fetchImpl(`${baseUrl}${path}`, {\n method: request.method,\n headers: {\n 'x-api-key': opts.apiKey,\n 'content-type': request.headers.get('content-type') ?? 'application/json',\n },\n body: request.method.toUpperCase() === 'GET' ? undefined : opts.body,\n });\n}\n\nasync function defaultMutationAuthorization(\n client: SubscriptionsClient,\n subscription: Subscription,\n externalCustomerId: string,\n): Promise<boolean> {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n return Boolean(customer?.id && customer.id === subscription.customerId);\n}\n\nasync function pathFromContext(context: SubscriptionProxyContext): Promise<string[] | string> {\n if (context.path) return context.path;\n const path = context.params?.path;\n if (!path) return [];\n return await path;\n}\n\nfunction normalizePath(pathParts: string[] | string): string {\n if (typeof pathParts === 'string') {\n return pathParts.startsWith('/') ? pathParts : `/${pathParts}`;\n }\n return `/${pathParts.map((part) => part.replace(/^\\/+|\\/+$/g, '')).join('/')}`;\n}\n\nfunction withQuery(path: string, query: URLSearchParams): string {\n const qs = query.toString();\n return qs ? `${path}?${qs}` : path;\n}\n\nfunction isSubscriptionMutation(path: string, method: string): boolean {\n if (path === '/api/v1/subscriptions/eligibility-check') return false;\n return method !== 'GET' && /^\\/api\\/v1\\/subscriptions\\/[\\w.-]+/.test(path);\n}\n\nfunction isCustomerByExternalPath(path: string): boolean {\n return /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/.test(path);\n}\n\nfunction subscriptionIdFromPath(path: string): string | null {\n return path.match(/^\\/api\\/v1\\/subscriptions\\/([\\w.-]+)/)?.[1] ?? null;\n}\n\nfunction filterHeaders(headers: Headers): Headers {\n const next = new Headers(headers);\n next.delete('content-encoding');\n next.delete('content-length');\n next.delete('transfer-encoding');\n return next;\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return Response.json({ error: { code, message } }, { status });\n}\n","export class ThrottleSubscriptionsError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args.message);\n this.name = 'ThrottleSubscriptionsError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n }\n}\n","import type {\n CheckoutSession,\n Customer,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n merchantId: optionalString(raw?.merchantId ?? raw?.merchant_id),\n storeId: optionalString(raw?.storeId ?? raw?.store_id),\n customerId: requiredString(raw?.customerId ?? raw?.customer_id, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(\n raw?.planReference ?? raw?.plan_reference,\n 'subscription.planReference',\n ),\n planName: optionalString(raw?.planName ?? raw?.plan_name),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart ?? raw?.current_period_start,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd ?? raw?.current_period_end,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),\n failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),\n pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),\n cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId ?? raw?.external_id),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName ?? raw?.first_name),\n lastName: optionalString(raw?.lastName ?? raw?.last_name),\n phone: optionalString(raw?.phone),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),\n expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nexport function normalizeTrialEligibility(raw: any): TrialEligibilityResult {\n return {\n eligible: Boolean(raw?.eligible),\n reason: raw?.reason,\n };\n}\n\nexport function normalizePagination(raw: any): Pagination | undefined {\n if (!raw) return undefined;\n return {\n cursor: raw.cursor ?? null,\n hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false),\n };\n}\n\nexport function toIso(value: string | Date | undefined): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction requiredDateString(value: unknown, label: string): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return null;\n}\n\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n storeId: input.storeId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n payment_method_id: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/errors.ts","../src/normalize.ts","../src/client.ts"],"sourcesContent":["import { SubscriptionsClient, createSubscriptionsClient } from './client';\nimport { ThrottleSubscriptionsError } from './errors';\nimport type { Subscription, SubscriptionsClientOptions } from './types';\n\nexport { SubscriptionsClient, createSubscriptionsClient, ThrottleSubscriptionsError };\nexport type {\n CheckoutSession,\n CreateCheckoutSessionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n TrialEligibilityInput,\n TrialEligibilityResult,\n} from './types';\n\nexport interface SubscriptionProxyOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n getExternalCustomerId: (request: Request) => string | null | Promise<string | null>;\n authorizeMutation?: (args: {\n request: Request;\n subscription: Subscription;\n externalCustomerId: string;\n }) => boolean | Promise<boolean>;\n}\n\nexport interface SubscriptionProxyContext {\n params?: {\n path?: string[] | Promise<string[]>;\n };\n path?: string[] | string;\n}\n\nconst ALLOWED_PATHS = [\n /^\\/api\\/v1\\/subscriptions(?:\\/[\\w.-]+)?(?:\\/(?:pause|resume|cancel))?$/,\n /^\\/api\\/v1\\/subscriptions\\/eligibility-check$/,\n /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/,\n /^\\/api\\/v1\\/customers\\/[\\w.-]+\\/payment-methods$/,\n /^\\/api\\/v1\\/checkout\\/sessions$/,\n];\n\nexport function createSubscriptionProxyHandler(options: SubscriptionProxyOptions) {\n return async function subscriptionProxyHandler(\n request: Request,\n context: SubscriptionProxyContext = {},\n ): Promise<Response> {\n const path = await pathFromContext(context);\n return handleSubscriptionProxyRequest(request, path, options);\n };\n}\n\nexport async function handleSubscriptionProxyRequest(\n request: Request,\n pathParts: string[] | string,\n options: SubscriptionProxyOptions,\n): Promise<Response> {\n const externalCustomerId = await options.getExternalCustomerId(request);\n if (!externalCustomerId) return jsonError(401, 'unauthorized', 'Unauthorized');\n\n const path = normalizePath(pathParts);\n if (!ALLOWED_PATHS.some((pattern) => pattern.test(path))) {\n return jsonError(403, 'forbidden', 'Path is not allowed by the subscription proxy');\n }\n\n const method = request.method.toUpperCase();\n if (!['GET', 'POST', 'PATCH'].includes(method)) {\n return jsonError(405, 'method_not_allowed', 'Method not allowed');\n }\n\n const client = new SubscriptionsClient({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n } satisfies SubscriptionsClientOptions);\n\n if (isSubscriptionMutation(path, method)) {\n const subId = subscriptionIdFromPath(path);\n if (subId) {\n const subscription = await client.get(subId).catch((err) => {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n });\n if (!subscription) return jsonError(404, 'not_found', 'Subscription not found');\n\n const defaultAuthorized = await defaultMutationAuthorization(\n client,\n subscription,\n externalCustomerId,\n );\n const customAuthorized = options.authorizeMutation\n ? await options.authorizeMutation({ request, subscription, externalCustomerId })\n : true;\n if (!defaultAuthorized || !customAuthorized) {\n return jsonError(403, 'forbidden', 'Subscription does not belong to this buyer');\n }\n }\n }\n\n const targetPath = await buildPinnedPathAndBody(request, path, externalCustomerId, client);\n if (targetPath instanceof Response) return targetPath;\n const upstream = await fetchWithApiKey(request, targetPath.path, {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n body: targetPath.body,\n });\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: filterHeaders(upstream.headers),\n });\n}\n\nasync function buildPinnedPathAndBody(\n request: Request,\n path: string,\n externalCustomerId: string,\n client: SubscriptionsClient,\n): Promise<{ path: string; body?: string } | Response> {\n const url = new URL(request.url);\n const query = new URLSearchParams(url.search);\n\n if (request.method.toUpperCase() === 'GET' && path === '/api/v1/subscriptions') {\n query.set('externalCustomerId', externalCustomerId);\n query.delete('customerId');\n query.delete('customer_id');\n query.delete('external_customer_id');\n }\n\n if (request.method.toUpperCase() === 'GET' && isCustomerByExternalPath(path)) {\n return {\n path: withQuery(\n `/api/v1/customers/by-external/${encodeURIComponent(externalCustomerId)}`,\n query,\n ),\n };\n }\n\n if (request.method.toUpperCase() === 'GET' && isCustomerPaymentMethodsPath(path)) {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n if (!customer) return jsonError(404, 'not_found', 'Customer not found');\n return {\n path: withQuery(\n `/api/v1/customers/${encodeURIComponent(customer.id)}/payment-methods`,\n query,\n ),\n };\n }\n\n if (request.method.toUpperCase() !== 'GET') {\n const raw = await request.text();\n if (path === '/api/v1/subscriptions' && request.method.toUpperCase() === 'POST') {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n if (!customer) return jsonError(404, 'not_found', 'Customer not found');\n\n const body = raw ? (JSON.parse(raw) as Record<string, any>) : {};\n body.customerId = customer.id;\n delete body.customer_id;\n delete body.externalCustomerId;\n delete body.external_customer_id;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n\n if (path === '/api/v1/checkout/sessions' && raw) {\n const body = JSON.parse(raw) as Record<string, any>;\n body.customer = {\n ...(body.customer ?? {}),\n externalCustomerId,\n };\n delete body.customer.customerId;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n return { path: withQuery(path, query), body: raw || undefined };\n }\n\n return { path: withQuery(path, query) };\n}\n\nasync function fetchWithApiKey(\n request: Request,\n path: string,\n opts: {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n body?: string;\n },\n) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('fetch is required');\n const baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n return fetchImpl(`${baseUrl}${path}`, {\n method: request.method,\n headers: {\n 'x-api-key': opts.apiKey,\n 'content-type': request.headers.get('content-type') ?? 'application/json',\n },\n body: request.method.toUpperCase() === 'GET' ? undefined : opts.body,\n });\n}\n\nasync function defaultMutationAuthorization(\n client: SubscriptionsClient,\n subscription: Subscription,\n externalCustomerId: string,\n): Promise<boolean> {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n return Boolean(customer?.id && customer.id === subscription.customerId);\n}\n\nasync function pathFromContext(context: SubscriptionProxyContext): Promise<string[] | string> {\n if (context.path) return context.path;\n const path = context.params?.path;\n if (!path) return [];\n return await path;\n}\n\nfunction normalizePath(pathParts: string[] | string): string {\n if (typeof pathParts === 'string') {\n return pathParts.startsWith('/') ? pathParts : `/${pathParts}`;\n }\n return `/${pathParts.map((part) => part.replace(/^\\/+|\\/+$/g, '')).join('/')}`;\n}\n\nfunction withQuery(path: string, query: URLSearchParams): string {\n const qs = query.toString();\n return qs ? `${path}?${qs}` : path;\n}\n\nfunction isSubscriptionMutation(path: string, method: string): boolean {\n if (path === '/api/v1/subscriptions/eligibility-check') return false;\n return method !== 'GET' && /^\\/api\\/v1\\/subscriptions\\/[\\w.-]+/.test(path);\n}\n\nfunction isCustomerByExternalPath(path: string): boolean {\n return /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/.test(path);\n}\n\nfunction isCustomerPaymentMethodsPath(path: string): boolean {\n return /^\\/api\\/v1\\/customers\\/[\\w.-]+\\/payment-methods$/.test(path);\n}\n\nfunction subscriptionIdFromPath(path: string): string | null {\n return path.match(/^\\/api\\/v1\\/subscriptions\\/([\\w.-]+)/)?.[1] ?? null;\n}\n\nfunction filterHeaders(headers: Headers): Headers {\n const next = new Headers(headers);\n next.delete('content-encoding');\n next.delete('content-length');\n next.delete('transfer-encoding');\n return next;\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return Response.json({ error: { code, message } }, { status });\n}\n","export class ThrottleSubscriptionsError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args.message);\n this.name = 'ThrottleSubscriptionsError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n }\n}\n","import type {\n CheckoutSession,\n Customer,\n CustomerPaymentMethod,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n merchantId: optionalString(raw?.merchantId ?? raw?.merchant_id),\n storeId: optionalString(raw?.storeId ?? raw?.store_id),\n customerId: requiredString(raw?.customerId ?? raw?.customer_id, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(\n raw?.planReference ?? raw?.plan_reference,\n 'subscription.planReference',\n ),\n planName: optionalString(raw?.planName ?? raw?.plan_name),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart ?? raw?.current_period_start,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd ?? raw?.current_period_end,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),\n failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),\n pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),\n cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId ?? raw?.external_id),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName ?? raw?.first_name),\n lastName: optionalString(raw?.lastName ?? raw?.last_name),\n phone: optionalString(raw?.phone),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomerPaymentMethod(raw: any): CustomerPaymentMethod {\n return {\n id: requiredString(raw?.id, 'paymentMethod.id'),\n processor: optionalString(raw?.processor),\n methodType: optionalString(raw?.methodType ?? raw?.method_type),\n cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),\n cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),\n isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),\n expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nexport function normalizeTrialEligibility(raw: any): TrialEligibilityResult {\n return {\n eligible: Boolean(raw?.eligible),\n reason: raw?.reason,\n };\n}\n\nexport function normalizePagination(raw: any): Pagination | undefined {\n if (!raw) return undefined;\n return {\n cursor: raw.cursor ?? null,\n hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false),\n };\n}\n\nexport function toIso(value: string | Date | undefined): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction requiredDateString(value: unknown, label: string): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return null;\n}\n\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizeCustomerPaymentMethod,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n storeId: input.storeId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n payment_method_id: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n async listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`,\n );\n return (data ?? []).map(normalizeCustomerPaymentMethod);\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,6BAAN,cAAyC,MAAM;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,MAAgF;AAC1F,UAAM,KAAK,OAAO;AAClB,SAAK,OAAO;AACZ,SAAK,OAAO,KAAK;AACjB,SAAK,aAAa,KAAK;AACvB,SAAK,UAAU,KAAK;AAAA,EACtB;AACF;;;ACDO,SAAS,sBAAsB,KAAwB;AAC5D,SAAO;AAAA,IACL,IAAI,eAAe,KAAK,IAAI,iBAAiB;AAAA,IAC7C,YAAY,eAAe,KAAK,cAAc,KAAK,WAAW;AAAA,IAC9D,SAAS,eAAe,KAAK,WAAW,KAAK,QAAQ;AAAA,IACrD,YAAY,eAAe,KAAK,cAAc,KAAK,aAAa,yBAAyB;AAAA,IACzF,QAAS,KAAK,UAAU;AAAA,IACxB,eAAe;AAAA,MACb,KAAK,iBAAiB,KAAK;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,UAAU,eAAe,KAAK,YAAY,KAAK,SAAS;AAAA,IACxD,UAAW,KAAK,YAAY;AAAA,IAC5B,QAAQ,OAAO,KAAK,UAAU,CAAC;AAAA,IAC/B,UAAU,eAAe,KAAK,QAAQ,KAAK;AAAA,IAC3C,oBAAoB;AAAA,MAClB,KAAK,sBAAsB,KAAK;AAAA,MAChC;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA,MAChB,KAAK,oBAAoB,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA,IACA,UAAU,mBAAmB,KAAK,YAAY,KAAK,SAAS;AAAA,IAC5D,mBAAmB,QAAQ,KAAK,qBAAqB,KAAK,wBAAwB,KAAK;AAAA,IACvF,cAAc,OAAO,KAAK,gBAAgB,KAAK,iBAAiB,CAAC;AAAA,IACjE,eAAe,mBAAmB,KAAK,iBAAiB,KAAK,eAAe;AAAA,IAC5E,UAAU,mBAAmB,KAAK,YAAY,KAAK,SAAS;AAAA,IAC5D,aAAa,mBAAmB,KAAK,eAAe,KAAK,YAAY;AAAA,IACrE,UAAU,cAAc,KAAK,QAAQ;AAAA,IACrC,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IACpE,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EACtE;AACF;AAEO,SAAS,kBAAkB,KAA2B;AAC3D,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO;AAAA,IACL,IAAI,eAAe,KAAK,IAAI,aAAa;AAAA,IACzC,YAAY,eAAe,KAAK,cAAc,KAAK,WAAW;AAAA,IAC9D,OAAO,eAAe,KAAK,KAAK;AAAA,IAChC,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU;AAAA,IAC3D,UAAU,eAAe,KAAK,YAAY,KAAK,SAAS;AAAA,IACxD,OAAO,eAAe,KAAK,KAAK;AAAA,IAChC,UAAU,cAAc,KAAK,QAAQ;AAAA,IACrC,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IACpE,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EACtE;AACF;AAEO,SAAS,+BAA+B,KAAiC;AAC9E,SAAO;AAAA,IACL,IAAI,eAAe,KAAK,IAAI,kBAAkB;AAAA,IAC9C,WAAW,eAAe,KAAK,SAAS;AAAA,IACxC,YAAY,eAAe,KAAK,cAAc,KAAK,WAAW;AAAA,IAC9D,WAAW,eAAe,KAAK,aAAa,KAAK,UAAU;AAAA,IAC3D,cAAc,eAAe,KAAK,gBAAgB,KAAK,cAAc;AAAA,IACrE,WAAW,QAAQ,KAAK,aAAa,KAAK,cAAc,KAAK;AAAA,IAC7D,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,IACpE,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EACtE;AACF;AAEO,SAAS,yBAAyB,KAA2B;AAClE,QAAM,YAAY,KAAK,aAAa,KAAK,cAAc,KAAK;AAC5D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,IAAI,eAAe,KAAK,EAAE;AAAA,IAC1B,WAAW,eAAe,WAAW,2BAA2B;AAAA,IAChE,aAAa,eAAe,KAAK,eAAe,KAAK,YAAY;AAAA,IACjE,YAAY,eAAe,KAAK,cAAc,KAAK,WAAW;AAAA,IAC9D,WAAW,mBAAmB,KAAK,aAAa,KAAK,UAAU,KAAK;AAAA,EACtE;AACF;AAEO,SAAS,0BAA0B,KAAkC;AAC1E,SAAO;AAAA,IACL,UAAU,QAAQ,KAAK,QAAQ;AAAA,IAC/B,QAAQ,KAAK;AAAA,EACf;AACF;AAEO,SAAS,oBAAoB,KAAkC;AACpE,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO;AAAA,IACL,QAAQ,IAAI,UAAU;AAAA,IACtB,SAAS,QAAQ,IAAI,WAAW,IAAI,YAAY,KAAK;AAAA,EACvD;AACF;AAEO,SAAS,MAAM,OAAsD;AAC1E,MAAI,UAAU,OAAW,QAAO;AAChC,SAAO,iBAAiB,OAAO,MAAM,YAAY,IAAI;AACvD;AAEA,SAAS,eAAe,OAAgB,OAAuB;AAC7D,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,QAAO;AAC1D,QAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAC/D;AAEA,SAAS,eAAe,OAA+B;AACrD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,mBAAmB,OAAgB,OAAuB;AACjE,MAAI,iBAAiB,KAAM,QAAO,MAAM,YAAY;AACpD,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,QAAO;AAC1D,QAAM,IAAI,MAAM,sCAAsC,KAAK,EAAE;AAC/D;AAEA,SAAS,mBAAmB,OAA+B;AACzD,MAAI,iBAAiB,KAAM,QAAO,MAAM,YAAY;AACpD,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,EAAG,QAAO;AAC1D,SAAO;AACT;AAEA,SAAS,cAAc,OAAyC;AAC9D,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC5D,QACD,CAAC;AACP;;;ACvGO,IAAM,sBAAN,MAAiE;AAAA,EACrD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,OAAmC,CAAC,GAAG;AACjD,UAAM,YAAY,KAAK,SAAS,WAAW;AAC3C,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,wCAAwC;AACxE,QAAI,CAAC,KAAK,UAAU,CAAC,KAAK,SAAS;AACjC,YAAM,IAAI,MAAM,oDAAoD;AAAA,IACtE;AAEA,SAAK,SAAS,KAAK;AACnB,SAAK,WAAW,KAAK,WAAW,+BAA+B,QAAQ,QAAQ,EAAE;AACjF,SAAK,YAAY;AACjB,SAAK,UAAU,KAAK;AACpB,SAAK,YAAY,KAAK,aAAa;AAAA,EACrC;AAAA,EAEA,MAAM,QAAqB,QAAgB,MAAc,MAA4B;AACnF,UAAM,WAAW,MAAM,KAAK,gBAAmB,QAAQ,MAAM,IAAI;AACjE,QAAI,OAAO,UAAU,eAAe,KAAK,UAAU,MAAM,GAAG;AAC1D,aAAO,SAAS;AAAA,IAClB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,gBACJ,QACA,MACA,MAC8B;AAC9B,UAAM,OAAO,IAAI,gBAAgB;AACjC,UAAM,QAAQ,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,SAAS;AAE3D,QAAI;AACF,YAAM,OAAoB;AAAA,QACxB;AAAA,QACA,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,GAAI,KAAK,SAAS,EAAE,aAAa,KAAK,OAAO,IAAI,CAAC;AAAA,QACpD;AAAA,QACA,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,QAClD,QAAQ,KAAK;AAAA,MACf;AAEA,YAAM,MAAM,KAAK,UACb,MAAM,KAAK,QAAQ,MAAM,IAAI,IAC7B,MAAM,KAAK,UAAU,cAAc,KAAK,SAAS,IAAI,GAAG,IAAI;AAEhE,UAAI,IAAI,WAAW,IAAK,QAAO,EAAE,MAAM,OAAe;AAEtD,YAAM,OAAQ,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AAC/C,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,IAAI,2BAA2B;AAAA,UACnC,MAAM,KAAK,OAAO,QAAQ;AAAA,UAC1B,SAAS,KAAK,OAAO,WAAW,QAAQ,IAAI,MAAM;AAAA,UAClD,YAAY,IAAI;AAAA,UAChB,SAAS,KAAK,OAAO;AAAA,QACvB,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,UAAE;AACA,mBAAa,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,OAAuD;AAClE,UAAM,aAAa,MAAM,KAAK,kBAAkB,MAAM,YAAY,MAAM,kBAAkB;AAC1F,UAAM,OAAO,MAAM,KAAK,QAAiB,QAAQ,yBAAyB;AAAA,MACxE,SAAS,MAAM;AAAA,MACf;AAAA,MACA,eAAe,MAAM;AAAA,MACrB,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,QAAQ,MAAM;AAAA,MACd,UAAU,MAAM;AAAA,MAChB,oBAAoB,MAAM,MAAM,kBAAkB;AAAA,MAClD,kBAAkB,MAAM,MAAM,gBAAgB;AAAA,MAC9C,UAAU,MAAM,MAAM,QAAQ;AAAA,MAC9B,UAAU,MAAM,YAAY,CAAC;AAAA,IAC/B,CAAC;AACD,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,KAAK,SAAkC,CAAC,GAAoC;AAChF,UAAM,QAAQ,IAAI,gBAAgB;AAClC,aAAS,OAAO,cAAc,OAAO,UAAU;AAC/C,aAAS,OAAO,sBAAsB,OAAO,kBAAkB;AAC/D,aAAS,OAAO,UAAU,OAAO,MAAM;AACvC,aAAS,OAAO,YAAY,OAAO,QAAQ;AAC3C,aAAS,OAAO,KAAK,OAAO,CAAC;AAC7B,aAAS,OAAO,UAAU,OAAO,MAAM;AACvC,aAAS,OAAO,SAAS,OAAO,KAAK;AACrC,aAAS,OAAO,QAAQ,OAAO,IAAI;AACnC,aAAS,OAAO,gBAAgB,MAAM,OAAO,YAAY,CAAC;AAC1D,aAAS,OAAO,iBAAiB,MAAM,OAAO,aAAa,CAAC;AAE5D,UAAM,SAAS,MAAM,SAAS,IAAI,IAAI,KAAK,KAAK;AAChD,UAAM,WAAW,MAAM,KAAK,gBAA2B,OAAO,wBAAwB,MAAM,EAAE;AAC9F,WAAO;AAAA,MACL,OAAO,SAAS,QAAQ,CAAC,GAAG,IAAI,qBAAqB;AAAA,MACrD,YAAY,oBAAoB,SAAS,MAAM,UAAU;AAAA,IAC3D;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,IAAmC;AAC3C,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,IACjD;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,OAAO,IAAY,OAAuD;AAC9E,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C;AAAA,IACF;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA,EAEA,WAAW,OAA+C;AACxD,UAAM,EAAE,IAAI,GAAG,KAAK,IAAI;AACxB,WAAO,KAAK,OAAO,IAAI,IAAI;AAAA,EAC7B;AAAA,EAEA,MAAM,MAAM,IAAmC;AAC7C,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,IACjD;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,OAAO,IAAmC;AAC9C,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,IACjD;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,OAAO,IAAY,QAAmC,CAAC,GAA0B;AACrF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C,EAAE,aAAa,MAAM,eAAe,MAAM;AAAA,IAC5C;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA,EAEA,MAAM,sBAAsB,OAA6D;AACvF,UAAM,OAAO,MAAM,KAAK,QAAiB,QAAQ,6BAA6B,KAAK;AACnF,WAAO,yBAAyB,IAAI;AAAA,EACtC;AAAA,EAEA,MAAM,sBAAsB,OAA+D;AACzF,UAAM,OAAO,MAAM,KAAK,QAAiB,QAAQ,2CAA2C;AAAA,MAC1F,mBAAmB,MAAM;AAAA,IAC3B,CAAC;AACD,WAAO,0BAA0B,IAAI;AAAA,EACvC;AAAA,EAEA,MAAM,wBAAwB,YAA8C;AAC1E,QAAI;AACF,YAAM,OAAO,MAAM,KAAK;AAAA,QACtB;AAAA,QACA,iCAAiC,mBAAmB,UAAU,CAAC;AAAA,MACjE;AACA,aAAO,kBAAkB,IAAI;AAAA,IAC/B,SAAS,KAAK;AACZ,UAAI,eAAe,8BAA8B,IAAI,eAAe,IAAK,QAAO;AAChF,YAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,MAAM,2BAA2B,YAAsD;AACrF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,qBAAqB,mBAAmB,UAAU,CAAC;AAAA,IACrD;AACA,YAAQ,QAAQ,CAAC,GAAG,IAAI,8BAA8B;AAAA,EACxD;AAAA,EAEA,MAAc,kBACZ,YACA,oBACiB;AACjB,QAAI,WAAY,QAAO;AACvB,QAAI,CAAC,oBAAoB;AACvB,YAAM,IAAI,2BAA2B;AAAA,QACnC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,MAAM,KAAK,wBAAwB,kBAAkB;AACtE,QAAI,CAAC,UAAU;AACb,YAAM,IAAI,2BAA2B;AAAA,QACnC,MAAM;AAAA,QACN,SAAS;AAAA,QACT,YAAY;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO,SAAS;AAAA,EAClB;AACF;AAEO,SAAS,0BAA0B,MAAuD;AAC/F,SAAO,IAAI,oBAAoB,IAAI;AACrC;AAEA,SAAS,cAAc,SAAiB,MAAsB;AAC5D,MAAI,gBAAgB,KAAK,IAAI,EAAG,QAAO;AACvC,SAAO,GAAG,OAAO,GAAG,KAAK,WAAW,GAAG,IAAI,OAAO,IAAI,IAAI,EAAE;AAC9D;AAEA,SAAS,SAAS,OAAwB,KAAa,OAAsB;AAC3E,MAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,GAAI;AAC3D,QAAM,IAAI,KAAK,OAAO,KAAK,CAAC;AAC9B;;;AHvNA,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,+BAA+B,SAAmC;AAChF,SAAO,eAAe,yBACpB,SACA,UAAoC,CAAC,GAClB;AACnB,UAAM,OAAO,MAAM,gBAAgB,OAAO;AAC1C,WAAO,+BAA+B,SAAS,MAAM,OAAO;AAAA,EAC9D;AACF;AAEA,eAAsB,+BACpB,SACA,WACA,SACmB;AACnB,QAAM,qBAAqB,MAAM,QAAQ,sBAAsB,OAAO;AACtE,MAAI,CAAC,mBAAoB,QAAO,UAAU,KAAK,gBAAgB,cAAc;AAE7E,QAAM,OAAO,cAAc,SAAS;AACpC,MAAI,CAAC,cAAc,KAAK,CAAC,YAAY,QAAQ,KAAK,IAAI,CAAC,GAAG;AACxD,WAAO,UAAU,KAAK,aAAa,+CAA+C;AAAA,EACpF;AAEA,QAAM,SAAS,QAAQ,OAAO,YAAY;AAC1C,MAAI,CAAC,CAAC,OAAO,QAAQ,OAAO,EAAE,SAAS,MAAM,GAAG;AAC9C,WAAO,UAAU,KAAK,sBAAsB,oBAAoB;AAAA,EAClE;AAEA,QAAM,SAAS,IAAI,oBAAoB;AAAA,IACrC,QAAQ,QAAQ;AAAA,IAChB,SAAS,QAAQ;AAAA,IACjB,OAAO,QAAQ;AAAA,EACjB,CAAsC;AAEtC,MAAI,uBAAuB,MAAM,MAAM,GAAG;AACxC,UAAM,QAAQ,uBAAuB,IAAI;AACzC,QAAI,OAAO;AACT,YAAM,eAAe,MAAM,OAAO,IAAI,KAAK,EAAE,MAAM,CAAC,QAAQ;AAC1D,YAAI,eAAe,8BAA8B,IAAI,eAAe,IAAK,QAAO;AAChF,cAAM;AAAA,MACR,CAAC;AACD,UAAI,CAAC,aAAc,QAAO,UAAU,KAAK,aAAa,wBAAwB;AAE9E,YAAM,oBAAoB,MAAM;AAAA,QAC9B;AAAA,QACA;AAAA,QACA;AAAA,MACF;AACA,YAAM,mBAAmB,QAAQ,oBAC7B,MAAM,QAAQ,kBAAkB,EAAE,SAAS,cAAc,mBAAmB,CAAC,IAC7E;AACJ,UAAI,CAAC,qBAAqB,CAAC,kBAAkB;AAC3C,eAAO,UAAU,KAAK,aAAa,4CAA4C;AAAA,MACjF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,aAAa,MAAM,uBAAuB,SAAS,MAAM,oBAAoB,MAAM;AACzF,MAAI,sBAAsB,SAAU,QAAO;AAC3C,QAAM,WAAW,MAAM,gBAAgB,SAAS,WAAW,MAAM;AAAA,IAC/D,QAAQ,QAAQ;AAAA,IAChB,SAAS,QAAQ;AAAA,IACjB,OAAO,QAAQ;AAAA,IACf,MAAM,WAAW;AAAA,EACnB,CAAC;AAED,SAAO,IAAI,SAAS,SAAS,MAAM;AAAA,IACjC,QAAQ,SAAS;AAAA,IACjB,SAAS,cAAc,SAAS,OAAO;AAAA,EACzC,CAAC;AACH;AAEA,eAAe,uBACb,SACA,MACA,oBACA,QACqD;AACrD,QAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAM,QAAQ,IAAI,gBAAgB,IAAI,MAAM;AAE5C,MAAI,QAAQ,OAAO,YAAY,MAAM,SAAS,SAAS,yBAAyB;AAC9E,UAAM,IAAI,sBAAsB,kBAAkB;AAClD,UAAM,OAAO,YAAY;AACzB,UAAM,OAAO,aAAa;AAC1B,UAAM,OAAO,sBAAsB;AAAA,EACrC;AAEA,MAAI,QAAQ,OAAO,YAAY,MAAM,SAAS,yBAAyB,IAAI,GAAG;AAC5E,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,iCAAiC,mBAAmB,kBAAkB,CAAC;AAAA,QACvE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,OAAO,YAAY,MAAM,SAAS,6BAA6B,IAAI,GAAG;AAChF,UAAM,WAAW,MAAM,OAAO,wBAAwB,kBAAkB;AACxE,QAAI,CAAC,SAAU,QAAO,UAAU,KAAK,aAAa,oBAAoB;AACtE,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,qBAAqB,mBAAmB,SAAS,EAAE,CAAC;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,OAAO,YAAY,MAAM,OAAO;AAC1C,UAAM,MAAM,MAAM,QAAQ,KAAK;AAC/B,QAAI,SAAS,2BAA2B,QAAQ,OAAO,YAAY,MAAM,QAAQ;AAC/E,YAAM,WAAW,MAAM,OAAO,wBAAwB,kBAAkB;AACxE,UAAI,CAAC,SAAU,QAAO,UAAU,KAAK,aAAa,oBAAoB;AAEtE,YAAM,OAAO,MAAO,KAAK,MAAM,GAAG,IAA4B,CAAC;AAC/D,WAAK,aAAa,SAAS;AAC3B,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,aAAO,KAAK;AACZ,aAAO,EAAE,MAAM,UAAU,MAAM,KAAK,GAAG,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,IACpE;AAEA,QAAI,SAAS,+BAA+B,KAAK;AAC/C,YAAM,OAAO,KAAK,MAAM,GAAG;AAC3B,WAAK,WAAW;AAAA,QACd,GAAI,KAAK,YAAY,CAAC;AAAA,QACtB;AAAA,MACF;AACA,aAAO,KAAK,SAAS;AACrB,aAAO,EAAE,MAAM,UAAU,MAAM,KAAK,GAAG,MAAM,KAAK,UAAU,IAAI,EAAE;AAAA,IACpE;AACA,WAAO,EAAE,MAAM,UAAU,MAAM,KAAK,GAAG,MAAM,OAAO,OAAU;AAAA,EAChE;AAEA,SAAO,EAAE,MAAM,UAAU,MAAM,KAAK,EAAE;AACxC;AAEA,eAAe,gBACb,SACA,MACA,MAMA;AACA,QAAM,YAAY,KAAK,SAAS,WAAW;AAC3C,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,mBAAmB;AACnD,QAAM,WAAW,KAAK,WAAW,+BAA+B,QAAQ,QAAQ,EAAE;AAClF,SAAO,UAAU,GAAG,OAAO,GAAG,IAAI,IAAI;AAAA,IACpC,QAAQ,QAAQ;AAAA,IAChB,SAAS;AAAA,MACP,aAAa,KAAK;AAAA,MAClB,gBAAgB,QAAQ,QAAQ,IAAI,cAAc,KAAK;AAAA,IACzD;AAAA,IACA,MAAM,QAAQ,OAAO,YAAY,MAAM,QAAQ,SAAY,KAAK;AAAA,EAClE,CAAC;AACH;AAEA,eAAe,6BACb,QACA,cACA,oBACkB;AAClB,QAAM,WAAW,MAAM,OAAO,wBAAwB,kBAAkB;AACxE,SAAO,QAAQ,UAAU,MAAM,SAAS,OAAO,aAAa,UAAU;AACxE;AAEA,eAAe,gBAAgB,SAA+D;AAC5F,MAAI,QAAQ,KAAM,QAAO,QAAQ;AACjC,QAAM,OAAO,QAAQ,QAAQ;AAC7B,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,SAAO,MAAM;AACf;AAEA,SAAS,cAAc,WAAsC;AAC3D,MAAI,OAAO,cAAc,UAAU;AACjC,WAAO,UAAU,WAAW,GAAG,IAAI,YAAY,IAAI,SAAS;AAAA,EAC9D;AACA,SAAO,IAAI,UAAU,IAAI,CAAC,SAAS,KAAK,QAAQ,cAAc,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC;AAC9E;AAEA,SAAS,UAAU,MAAc,OAAgC;AAC/D,QAAM,KAAK,MAAM,SAAS;AAC1B,SAAO,KAAK,GAAG,IAAI,IAAI,EAAE,KAAK;AAChC;AAEA,SAAS,uBAAuB,MAAc,QAAyB;AACrE,MAAI,SAAS,0CAA2C,QAAO;AAC/D,SAAO,WAAW,SAAS,qCAAqC,KAAK,IAAI;AAC3E;AAEA,SAAS,yBAAyB,MAAuB;AACvD,SAAO,iDAAiD,KAAK,IAAI;AACnE;AAEA,SAAS,6BAA6B,MAAuB;AAC3D,SAAO,mDAAmD,KAAK,IAAI;AACrE;AAEA,SAAS,uBAAuB,MAA6B;AAC3D,SAAO,KAAK,MAAM,sCAAsC,IAAI,CAAC,KAAK;AACpE;AAEA,SAAS,cAAc,SAA2B;AAChD,QAAM,OAAO,IAAI,QAAQ,OAAO;AAChC,OAAK,OAAO,kBAAkB;AAC9B,OAAK,OAAO,gBAAgB;AAC5B,OAAK,OAAO,mBAAmB;AAC/B,SAAO;AACT;AAEA,SAAS,UAAU,QAAgB,MAAc,SAA2B;AAC1E,SAAO,SAAS,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC;AAC/D;","names":[]}
|
package/dist/server.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as Subscription } from './errors-
|
|
2
|
-
export { e as CheckoutSession, f as CreateCheckoutSessionInput, h as Customer, L as ListSubscriptionsParams, P as PaginatedSubscriptions,
|
|
1
|
+
import { c as Subscription } from './errors-CZVUZzk3.cjs';
|
|
2
|
+
export { e as CheckoutSession, f as CreateCheckoutSessionInput, h as Customer, j as CustomerPaymentMethod, L as ListSubscriptionsParams, P as PaginatedSubscriptions, t as SubscriptionsClient, a as SubscriptionsClientContract, u as SubscriptionsClientOptions, w as ThrottleSubscriptionsError, k as TrialEligibilityInput, T as TrialEligibilityResult, y as createSubscriptionsClient } from './errors-CZVUZzk3.cjs';
|
|
3
3
|
import 'react';
|
|
4
4
|
|
|
5
5
|
interface SubscriptionProxyOptions {
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as Subscription } from './errors-
|
|
2
|
-
export { e as CheckoutSession, f as CreateCheckoutSessionInput, h as Customer, L as ListSubscriptionsParams, P as PaginatedSubscriptions,
|
|
1
|
+
import { c as Subscription } from './errors-CZVUZzk3.js';
|
|
2
|
+
export { e as CheckoutSession, f as CreateCheckoutSessionInput, h as Customer, j as CustomerPaymentMethod, L as ListSubscriptionsParams, P as PaginatedSubscriptions, t as SubscriptionsClient, a as SubscriptionsClientContract, u as SubscriptionsClientOptions, w as ThrottleSubscriptionsError, k as TrialEligibilityInput, T as TrialEligibilityResult, y as createSubscriptionsClient } from './errors-CZVUZzk3.js';
|
|
3
3
|
import 'react';
|
|
4
4
|
|
|
5
5
|
interface SubscriptionProxyOptions {
|
package/dist/server.js
CHANGED
|
@@ -2,13 +2,14 @@ import {
|
|
|
2
2
|
SubscriptionsClient,
|
|
3
3
|
ThrottleSubscriptionsError,
|
|
4
4
|
createSubscriptionsClient
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SXTIX2Y2.js";
|
|
6
6
|
|
|
7
7
|
// src/server.ts
|
|
8
8
|
var ALLOWED_PATHS = [
|
|
9
9
|
/^\/api\/v1\/subscriptions(?:\/[\w.-]+)?(?:\/(?:pause|resume|cancel))?$/,
|
|
10
10
|
/^\/api\/v1\/subscriptions\/eligibility-check$/,
|
|
11
11
|
/^\/api\/v1\/customers\/by-external\/[\w.:%-]+$/,
|
|
12
|
+
/^\/api\/v1\/customers\/[\w.-]+\/payment-methods$/,
|
|
12
13
|
/^\/api\/v1\/checkout\/sessions$/
|
|
13
14
|
];
|
|
14
15
|
function createSubscriptionProxyHandler(options) {
|
|
@@ -82,6 +83,16 @@ async function buildPinnedPathAndBody(request, path, externalCustomerId, client)
|
|
|
82
83
|
)
|
|
83
84
|
};
|
|
84
85
|
}
|
|
86
|
+
if (request.method.toUpperCase() === "GET" && isCustomerPaymentMethodsPath(path)) {
|
|
87
|
+
const customer = await client.getCustomerByExternalId(externalCustomerId);
|
|
88
|
+
if (!customer) return jsonError(404, "not_found", "Customer not found");
|
|
89
|
+
return {
|
|
90
|
+
path: withQuery(
|
|
91
|
+
`/api/v1/customers/${encodeURIComponent(customer.id)}/payment-methods`,
|
|
92
|
+
query
|
|
93
|
+
)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
85
96
|
if (request.method.toUpperCase() !== "GET") {
|
|
86
97
|
const raw = await request.text();
|
|
87
98
|
if (path === "/api/v1/subscriptions" && request.method.toUpperCase() === "POST") {
|
|
@@ -147,6 +158,9 @@ function isSubscriptionMutation(path, method) {
|
|
|
147
158
|
function isCustomerByExternalPath(path) {
|
|
148
159
|
return /^\/api\/v1\/customers\/by-external\/[\w.:%-]+$/.test(path);
|
|
149
160
|
}
|
|
161
|
+
function isCustomerPaymentMethodsPath(path) {
|
|
162
|
+
return /^\/api\/v1\/customers\/[\w.-]+\/payment-methods$/.test(path);
|
|
163
|
+
}
|
|
150
164
|
function subscriptionIdFromPath(path) {
|
|
151
165
|
return path.match(/^\/api\/v1\/subscriptions\/([\w.-]+)/)?.[1] ?? null;
|
|
152
166
|
}
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { SubscriptionsClient, createSubscriptionsClient } from './client';\nimport { ThrottleSubscriptionsError } from './errors';\nimport type { Subscription, SubscriptionsClientOptions } from './types';\n\nexport { SubscriptionsClient, createSubscriptionsClient, ThrottleSubscriptionsError };\nexport type {\n CheckoutSession,\n CreateCheckoutSessionInput,\n Customer,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n TrialEligibilityInput,\n TrialEligibilityResult,\n} from './types';\n\nexport interface SubscriptionProxyOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n getExternalCustomerId: (request: Request) => string | null | Promise<string | null>;\n authorizeMutation?: (args: {\n request: Request;\n subscription: Subscription;\n externalCustomerId: string;\n }) => boolean | Promise<boolean>;\n}\n\nexport interface SubscriptionProxyContext {\n params?: {\n path?: string[] | Promise<string[]>;\n };\n path?: string[] | string;\n}\n\nconst ALLOWED_PATHS = [\n /^\\/api\\/v1\\/subscriptions(?:\\/[\\w.-]+)?(?:\\/(?:pause|resume|cancel))?$/,\n /^\\/api\\/v1\\/subscriptions\\/eligibility-check$/,\n /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/,\n /^\\/api\\/v1\\/checkout\\/sessions$/,\n];\n\nexport function createSubscriptionProxyHandler(options: SubscriptionProxyOptions) {\n return async function subscriptionProxyHandler(\n request: Request,\n context: SubscriptionProxyContext = {},\n ): Promise<Response> {\n const path = await pathFromContext(context);\n return handleSubscriptionProxyRequest(request, path, options);\n };\n}\n\nexport async function handleSubscriptionProxyRequest(\n request: Request,\n pathParts: string[] | string,\n options: SubscriptionProxyOptions,\n): Promise<Response> {\n const externalCustomerId = await options.getExternalCustomerId(request);\n if (!externalCustomerId) return jsonError(401, 'unauthorized', 'Unauthorized');\n\n const path = normalizePath(pathParts);\n if (!ALLOWED_PATHS.some((pattern) => pattern.test(path))) {\n return jsonError(403, 'forbidden', 'Path is not allowed by the subscription proxy');\n }\n\n const method = request.method.toUpperCase();\n if (!['GET', 'POST', 'PATCH'].includes(method)) {\n return jsonError(405, 'method_not_allowed', 'Method not allowed');\n }\n\n const client = new SubscriptionsClient({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n } satisfies SubscriptionsClientOptions);\n\n if (isSubscriptionMutation(path, method)) {\n const subId = subscriptionIdFromPath(path);\n if (subId) {\n const subscription = await client.get(subId).catch((err) => {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n });\n if (!subscription) return jsonError(404, 'not_found', 'Subscription not found');\n\n const defaultAuthorized = await defaultMutationAuthorization(\n client,\n subscription,\n externalCustomerId,\n );\n const customAuthorized = options.authorizeMutation\n ? await options.authorizeMutation({ request, subscription, externalCustomerId })\n : true;\n if (!defaultAuthorized || !customAuthorized) {\n return jsonError(403, 'forbidden', 'Subscription does not belong to this buyer');\n }\n }\n }\n\n const targetPath = await buildPinnedPathAndBody(request, path, externalCustomerId, client);\n if (targetPath instanceof Response) return targetPath;\n const upstream = await fetchWithApiKey(request, targetPath.path, {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n body: targetPath.body,\n });\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: filterHeaders(upstream.headers),\n });\n}\n\nasync function buildPinnedPathAndBody(\n request: Request,\n path: string,\n externalCustomerId: string,\n client: SubscriptionsClient,\n): Promise<{ path: string; body?: string } | Response> {\n const url = new URL(request.url);\n const query = new URLSearchParams(url.search);\n\n if (request.method.toUpperCase() === 'GET' && path === '/api/v1/subscriptions') {\n query.set('externalCustomerId', externalCustomerId);\n query.delete('customerId');\n query.delete('customer_id');\n query.delete('external_customer_id');\n }\n\n if (request.method.toUpperCase() === 'GET' && isCustomerByExternalPath(path)) {\n return {\n path: withQuery(\n `/api/v1/customers/by-external/${encodeURIComponent(externalCustomerId)}`,\n query,\n ),\n };\n }\n\n if (request.method.toUpperCase() !== 'GET') {\n const raw = await request.text();\n if (path === '/api/v1/subscriptions' && request.method.toUpperCase() === 'POST') {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n if (!customer) return jsonError(404, 'not_found', 'Customer not found');\n\n const body = raw ? (JSON.parse(raw) as Record<string, any>) : {};\n body.customerId = customer.id;\n delete body.customer_id;\n delete body.externalCustomerId;\n delete body.external_customer_id;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n\n if (path === '/api/v1/checkout/sessions' && raw) {\n const body = JSON.parse(raw) as Record<string, any>;\n body.customer = {\n ...(body.customer ?? {}),\n externalCustomerId,\n };\n delete body.customer.customerId;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n return { path: withQuery(path, query), body: raw || undefined };\n }\n\n return { path: withQuery(path, query) };\n}\n\nasync function fetchWithApiKey(\n request: Request,\n path: string,\n opts: {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n body?: string;\n },\n) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('fetch is required');\n const baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n return fetchImpl(`${baseUrl}${path}`, {\n method: request.method,\n headers: {\n 'x-api-key': opts.apiKey,\n 'content-type': request.headers.get('content-type') ?? 'application/json',\n },\n body: request.method.toUpperCase() === 'GET' ? undefined : opts.body,\n });\n}\n\nasync function defaultMutationAuthorization(\n client: SubscriptionsClient,\n subscription: Subscription,\n externalCustomerId: string,\n): Promise<boolean> {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n return Boolean(customer?.id && customer.id === subscription.customerId);\n}\n\nasync function pathFromContext(context: SubscriptionProxyContext): Promise<string[] | string> {\n if (context.path) return context.path;\n const path = context.params?.path;\n if (!path) return [];\n return await path;\n}\n\nfunction normalizePath(pathParts: string[] | string): string {\n if (typeof pathParts === 'string') {\n return pathParts.startsWith('/') ? pathParts : `/${pathParts}`;\n }\n return `/${pathParts.map((part) => part.replace(/^\\/+|\\/+$/g, '')).join('/')}`;\n}\n\nfunction withQuery(path: string, query: URLSearchParams): string {\n const qs = query.toString();\n return qs ? `${path}?${qs}` : path;\n}\n\nfunction isSubscriptionMutation(path: string, method: string): boolean {\n if (path === '/api/v1/subscriptions/eligibility-check') return false;\n return method !== 'GET' && /^\\/api\\/v1\\/subscriptions\\/[\\w.-]+/.test(path);\n}\n\nfunction isCustomerByExternalPath(path: string): boolean {\n return /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/.test(path);\n}\n\nfunction subscriptionIdFromPath(path: string): string | null {\n return path.match(/^\\/api\\/v1\\/subscriptions\\/([\\w.-]+)/)?.[1] ?? null;\n}\n\nfunction filterHeaders(headers: Headers): Headers {\n const next = new Headers(headers);\n next.delete('content-encoding');\n next.delete('content-length');\n next.delete('transfer-encoding');\n return next;\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return Response.json({ error: { code, message } }, { status });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { SubscriptionsClient, createSubscriptionsClient } from './client';\nimport { ThrottleSubscriptionsError } from './errors';\nimport type { Subscription, SubscriptionsClientOptions } from './types';\n\nexport { SubscriptionsClient, createSubscriptionsClient, ThrottleSubscriptionsError };\nexport type {\n CheckoutSession,\n CreateCheckoutSessionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n TrialEligibilityInput,\n TrialEligibilityResult,\n} from './types';\n\nexport interface SubscriptionProxyOptions {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n getExternalCustomerId: (request: Request) => string | null | Promise<string | null>;\n authorizeMutation?: (args: {\n request: Request;\n subscription: Subscription;\n externalCustomerId: string;\n }) => boolean | Promise<boolean>;\n}\n\nexport interface SubscriptionProxyContext {\n params?: {\n path?: string[] | Promise<string[]>;\n };\n path?: string[] | string;\n}\n\nconst ALLOWED_PATHS = [\n /^\\/api\\/v1\\/subscriptions(?:\\/[\\w.-]+)?(?:\\/(?:pause|resume|cancel))?$/,\n /^\\/api\\/v1\\/subscriptions\\/eligibility-check$/,\n /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/,\n /^\\/api\\/v1\\/customers\\/[\\w.-]+\\/payment-methods$/,\n /^\\/api\\/v1\\/checkout\\/sessions$/,\n];\n\nexport function createSubscriptionProxyHandler(options: SubscriptionProxyOptions) {\n return async function subscriptionProxyHandler(\n request: Request,\n context: SubscriptionProxyContext = {},\n ): Promise<Response> {\n const path = await pathFromContext(context);\n return handleSubscriptionProxyRequest(request, path, options);\n };\n}\n\nexport async function handleSubscriptionProxyRequest(\n request: Request,\n pathParts: string[] | string,\n options: SubscriptionProxyOptions,\n): Promise<Response> {\n const externalCustomerId = await options.getExternalCustomerId(request);\n if (!externalCustomerId) return jsonError(401, 'unauthorized', 'Unauthorized');\n\n const path = normalizePath(pathParts);\n if (!ALLOWED_PATHS.some((pattern) => pattern.test(path))) {\n return jsonError(403, 'forbidden', 'Path is not allowed by the subscription proxy');\n }\n\n const method = request.method.toUpperCase();\n if (!['GET', 'POST', 'PATCH'].includes(method)) {\n return jsonError(405, 'method_not_allowed', 'Method not allowed');\n }\n\n const client = new SubscriptionsClient({\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n } satisfies SubscriptionsClientOptions);\n\n if (isSubscriptionMutation(path, method)) {\n const subId = subscriptionIdFromPath(path);\n if (subId) {\n const subscription = await client.get(subId).catch((err) => {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n });\n if (!subscription) return jsonError(404, 'not_found', 'Subscription not found');\n\n const defaultAuthorized = await defaultMutationAuthorization(\n client,\n subscription,\n externalCustomerId,\n );\n const customAuthorized = options.authorizeMutation\n ? await options.authorizeMutation({ request, subscription, externalCustomerId })\n : true;\n if (!defaultAuthorized || !customAuthorized) {\n return jsonError(403, 'forbidden', 'Subscription does not belong to this buyer');\n }\n }\n }\n\n const targetPath = await buildPinnedPathAndBody(request, path, externalCustomerId, client);\n if (targetPath instanceof Response) return targetPath;\n const upstream = await fetchWithApiKey(request, targetPath.path, {\n apiKey: options.apiKey,\n baseUrl: options.baseUrl,\n fetch: options.fetch,\n body: targetPath.body,\n });\n\n return new Response(upstream.body, {\n status: upstream.status,\n headers: filterHeaders(upstream.headers),\n });\n}\n\nasync function buildPinnedPathAndBody(\n request: Request,\n path: string,\n externalCustomerId: string,\n client: SubscriptionsClient,\n): Promise<{ path: string; body?: string } | Response> {\n const url = new URL(request.url);\n const query = new URLSearchParams(url.search);\n\n if (request.method.toUpperCase() === 'GET' && path === '/api/v1/subscriptions') {\n query.set('externalCustomerId', externalCustomerId);\n query.delete('customerId');\n query.delete('customer_id');\n query.delete('external_customer_id');\n }\n\n if (request.method.toUpperCase() === 'GET' && isCustomerByExternalPath(path)) {\n return {\n path: withQuery(\n `/api/v1/customers/by-external/${encodeURIComponent(externalCustomerId)}`,\n query,\n ),\n };\n }\n\n if (request.method.toUpperCase() === 'GET' && isCustomerPaymentMethodsPath(path)) {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n if (!customer) return jsonError(404, 'not_found', 'Customer not found');\n return {\n path: withQuery(\n `/api/v1/customers/${encodeURIComponent(customer.id)}/payment-methods`,\n query,\n ),\n };\n }\n\n if (request.method.toUpperCase() !== 'GET') {\n const raw = await request.text();\n if (path === '/api/v1/subscriptions' && request.method.toUpperCase() === 'POST') {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n if (!customer) return jsonError(404, 'not_found', 'Customer not found');\n\n const body = raw ? (JSON.parse(raw) as Record<string, any>) : {};\n body.customerId = customer.id;\n delete body.customer_id;\n delete body.externalCustomerId;\n delete body.external_customer_id;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n\n if (path === '/api/v1/checkout/sessions' && raw) {\n const body = JSON.parse(raw) as Record<string, any>;\n body.customer = {\n ...(body.customer ?? {}),\n externalCustomerId,\n };\n delete body.customer.customerId;\n return { path: withQuery(path, query), body: JSON.stringify(body) };\n }\n return { path: withQuery(path, query), body: raw || undefined };\n }\n\n return { path: withQuery(path, query) };\n}\n\nasync function fetchWithApiKey(\n request: Request,\n path: string,\n opts: {\n apiKey: string;\n baseUrl?: string;\n fetch?: typeof globalThis.fetch;\n body?: string;\n },\n) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('fetch is required');\n const baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n return fetchImpl(`${baseUrl}${path}`, {\n method: request.method,\n headers: {\n 'x-api-key': opts.apiKey,\n 'content-type': request.headers.get('content-type') ?? 'application/json',\n },\n body: request.method.toUpperCase() === 'GET' ? undefined : opts.body,\n });\n}\n\nasync function defaultMutationAuthorization(\n client: SubscriptionsClient,\n subscription: Subscription,\n externalCustomerId: string,\n): Promise<boolean> {\n const customer = await client.getCustomerByExternalId(externalCustomerId);\n return Boolean(customer?.id && customer.id === subscription.customerId);\n}\n\nasync function pathFromContext(context: SubscriptionProxyContext): Promise<string[] | string> {\n if (context.path) return context.path;\n const path = context.params?.path;\n if (!path) return [];\n return await path;\n}\n\nfunction normalizePath(pathParts: string[] | string): string {\n if (typeof pathParts === 'string') {\n return pathParts.startsWith('/') ? pathParts : `/${pathParts}`;\n }\n return `/${pathParts.map((part) => part.replace(/^\\/+|\\/+$/g, '')).join('/')}`;\n}\n\nfunction withQuery(path: string, query: URLSearchParams): string {\n const qs = query.toString();\n return qs ? `${path}?${qs}` : path;\n}\n\nfunction isSubscriptionMutation(path: string, method: string): boolean {\n if (path === '/api/v1/subscriptions/eligibility-check') return false;\n return method !== 'GET' && /^\\/api\\/v1\\/subscriptions\\/[\\w.-]+/.test(path);\n}\n\nfunction isCustomerByExternalPath(path: string): boolean {\n return /^\\/api\\/v1\\/customers\\/by-external\\/[\\w.:%-]+$/.test(path);\n}\n\nfunction isCustomerPaymentMethodsPath(path: string): boolean {\n return /^\\/api\\/v1\\/customers\\/[\\w.-]+\\/payment-methods$/.test(path);\n}\n\nfunction subscriptionIdFromPath(path: string): string | null {\n return path.match(/^\\/api\\/v1\\/subscriptions\\/([\\w.-]+)/)?.[1] ?? null;\n}\n\nfunction filterHeaders(headers: Headers): Headers {\n const next = new Headers(headers);\n next.delete('content-encoding');\n next.delete('content-length');\n next.delete('transfer-encoding');\n return next;\n}\n\nfunction jsonError(status: number, code: string, message: string): Response {\n return Response.json({ error: { code, message } }, { status });\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/normalize.ts","../src/client.ts"],"sourcesContent":["export class ThrottleSubscriptionsError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly details?: unknown;\n\n constructor(args: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args.message);\n this.name = 'ThrottleSubscriptionsError';\n this.code = args.code;\n this.statusCode = args.statusCode;\n this.details = args.details;\n }\n}\n","import type {\n CheckoutSession,\n Customer,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n merchantId: optionalString(raw?.merchantId ?? raw?.merchant_id),\n storeId: optionalString(raw?.storeId ?? raw?.store_id),\n customerId: requiredString(raw?.customerId ?? raw?.customer_id, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(\n raw?.planReference ?? raw?.plan_reference,\n 'subscription.planReference',\n ),\n planName: optionalString(raw?.planName ?? raw?.plan_name),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart ?? raw?.current_period_start,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd ?? raw?.current_period_end,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),\n failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),\n pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),\n cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId ?? raw?.external_id),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName ?? raw?.first_name),\n lastName: optionalString(raw?.lastName ?? raw?.last_name),\n phone: optionalString(raw?.phone),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;\n return {\n ...raw,\n id: optionalString(raw?.id),\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),\n embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),\n expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? undefined,\n };\n}\n\nexport function normalizeTrialEligibility(raw: any): TrialEligibilityResult {\n return {\n eligible: Boolean(raw?.eligible),\n reason: raw?.reason,\n };\n}\n\nexport function normalizePagination(raw: any): Pagination | undefined {\n if (!raw) return undefined;\n return {\n cursor: raw.cursor ?? null,\n hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false),\n };\n}\n\nexport function toIso(value: string | Date | undefined): string | undefined {\n if (value === undefined) return undefined;\n return value instanceof Date ? value.toISOString() : value;\n}\n\nfunction requiredString(value: unknown, label: string): string {\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalString(value: unknown): string | null {\n return typeof value === 'string' ? value : null;\n}\n\nfunction requiredDateString(value: unknown, label: string): string {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n throw new Error(`Invalid Throttle response: missing ${label}`);\n}\n\nfunction optionalDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) return value;\n return null;\n}\n\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n storeId: input.storeId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n payment_method_id: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n"],"mappings":"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","names":[]}
|