@usethrottle/subscriptions 1.5.1 → 2.0.1
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/dist/{chunk-O7VSJ72M.js → chunk-C4MXEOJ3.js} +20 -2
- package/dist/chunk-C4MXEOJ3.js.map +1 -0
- package/dist/{errors-DPLUVIMf.d.cts → errors-1V2z7X4H.d.cts} +29 -6
- package/dist/{errors-DPLUVIMf.d.ts → errors-1V2z7X4H.d.ts} +29 -6
- package/dist/index.cjs +98 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +77 -5
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +19 -1
- 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 +1 -1
- package/package.json +4 -3
- package/dist/chunk-O7VSJ72M.js.map +0 -1
|
@@ -19,6 +19,11 @@ function normalizeSubscription(raw) {
|
|
|
19
19
|
planReference: requiredString(raw?.planReference, "subscription.planReference"),
|
|
20
20
|
planName: optionalString(raw?.planName),
|
|
21
21
|
interval: raw?.interval ?? "monthly",
|
|
22
|
+
intervalUnit: optionalString(raw?.intervalUnit) ?? null,
|
|
23
|
+
intervalCount: raw?.intervalCount == null ? null : Number(raw.intervalCount),
|
|
24
|
+
totalPayments: raw?.totalPayments == null ? null : Number(raw.totalPayments),
|
|
25
|
+
paymentsMade: Number(raw?.paymentsMade ?? 0),
|
|
26
|
+
completedAt: optionalIsoDateString(raw?.completedAt),
|
|
22
27
|
amount: Number(raw?.amount ?? 0),
|
|
23
28
|
currency: optionalString(raw?.currency) ?? "USD",
|
|
24
29
|
currentPeriodStart: requiredDateString(
|
|
@@ -113,6 +118,14 @@ function optionalDateString(value) {
|
|
|
113
118
|
if (typeof value === "string" && value.length > 0) return value;
|
|
114
119
|
return null;
|
|
115
120
|
}
|
|
121
|
+
function optionalIsoDateString(value) {
|
|
122
|
+
if (value instanceof Date) return value.toISOString();
|
|
123
|
+
if (typeof value === "string" && value.length > 0) {
|
|
124
|
+
const d = new Date(value);
|
|
125
|
+
return Number.isNaN(d.getTime()) ? value : d.toISOString();
|
|
126
|
+
}
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
116
129
|
function objectOrEmpty(value) {
|
|
117
130
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
118
131
|
}
|
|
@@ -170,7 +183,8 @@ var SubscriptionsClient = class {
|
|
|
170
183
|
code: json.error?.code ?? "unknown_error",
|
|
171
184
|
message: json.error?.message ?? `HTTP ${res.status}`,
|
|
172
185
|
statusCode: res.status,
|
|
173
|
-
details: json.error?.details
|
|
186
|
+
details: json.error?.details,
|
|
187
|
+
responseHeaders: res.headers
|
|
174
188
|
});
|
|
175
189
|
}
|
|
176
190
|
return json;
|
|
@@ -186,6 +200,9 @@ var SubscriptionsClient = class {
|
|
|
186
200
|
planReference: input.planReference,
|
|
187
201
|
planName: input.planName,
|
|
188
202
|
interval: input.interval,
|
|
203
|
+
intervalUnit: input.intervalUnit,
|
|
204
|
+
intervalCount: input.intervalCount,
|
|
205
|
+
totalPayments: input.totalPayments,
|
|
189
206
|
amount: input.amount,
|
|
190
207
|
currency: input.currency,
|
|
191
208
|
currentPeriodStart: toIso(input.currentPeriodStart),
|
|
@@ -202,6 +219,7 @@ var SubscriptionsClient = class {
|
|
|
202
219
|
setQuery(query, "externalCustomerId", params.externalCustomerId);
|
|
203
220
|
setQuery(query, "status", params.status);
|
|
204
221
|
setQuery(query, "interval", params.interval);
|
|
222
|
+
setQuery(query, "installment", params.installment);
|
|
205
223
|
setQuery(query, "q", params.q);
|
|
206
224
|
setQuery(query, "cursor", params.cursor);
|
|
207
225
|
setQuery(query, "limit", params.limit);
|
|
@@ -338,4 +356,4 @@ export {
|
|
|
338
356
|
SubscriptionsClient,
|
|
339
357
|
createSubscriptionsClient
|
|
340
358
|
};
|
|
341
|
-
//# sourceMappingURL=chunk-
|
|
359
|
+
//# sourceMappingURL=chunk-C4MXEOJ3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/normalize.ts","../src/client.ts"],"sourcesContent":["import { ThrottleError, type ThrottleErrorArgs } from '@usethrottle/errors';\n\n/**\n * Thrown on a non-2xx response from the Throttle Subscriptions API.\n *\n * Extends the shared {@link ThrottleError} so a single\n * `catch (e) { if (e instanceof ThrottleError) … }` covers errors from every\n * Throttle SDK. `instanceof ThrottleSubscriptionsError` keeps working.\n */\nexport class ThrottleSubscriptionsError extends ThrottleError {\n constructor(args: {\n code: string;\n message: string;\n statusCode: number;\n details?: unknown;\n responseHeaders?: ThrottleErrorArgs['responseHeaders'];\n }) {\n super(args);\n this.name = 'ThrottleSubscriptionsError';\n }\n}\n\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\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 workspaceId: optionalString(raw?.workspaceId),\n applicationId: optionalString(raw?.applicationId),\n customerId: requiredString(raw?.customerId, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(raw?.planReference, 'subscription.planReference'),\n planName: optionalString(raw?.planName),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n intervalUnit: (optionalString(raw?.intervalUnit) as Subscription['intervalUnit']) ?? null,\n intervalCount: raw?.intervalCount == null ? null : Number(raw.intervalCount),\n totalPayments: raw?.totalPayments == null ? null : Number(raw.totalPayments),\n paymentsMade: Number(raw?.paymentsMade ?? 0),\n completedAt: optionalIsoDateString(raw?.completedAt),\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? false),\n failureCount: Number(raw?.failureCount ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt),\n pausedAt: optionalDateString(raw?.pausedAt),\n cancelledAt: optionalDateString(raw?.cancelledAt),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt) ?? 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),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName),\n lastName: optionalString(raw?.lastName),\n phone: optionalString(raw?.phone),\n company: optionalString(raw?.company),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt) ?? 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),\n cardBrand: optionalString(raw?.cardBrand),\n cardLastFour: optionalString(raw?.cardLastFour),\n isDefault: Boolean(raw?.isDefault ?? false),\n isActive: Boolean(raw?.isActive ?? true),\n createdAt: optionalDateString(raw?.createdAt) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt) ?? undefined,\n };\n}\n\nexport function normalizeCheckoutSession(raw: any): CheckoutSession {\n const sessionId = raw?.sessionId ?? raw?.id;\n return {\n ...withoutUnderscoreKeys(raw),\n id: optionalString(raw?.id) ?? undefined,\n sessionId: requiredString(sessionId, 'checkoutSession.sessionId'),\n checkoutUrl: optionalString(raw?.checkoutUrl) ?? undefined,\n embedToken: optionalString(raw?.embedToken) ?? undefined,\n expiresAt: optionalDateString(raw?.expiresAt) ?? 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 ?? 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\n/**\n * Like `optionalDateString`, but always reserializes to a full ISO string\n * (with milliseconds) rather than passing a raw string through unchanged.\n * `completedAt` is a fresh field with no legacy raw-string callers to stay\n * compatible with, so it normalizes cleanly instead of echoing whatever the\n * API sent.\n */\nfunction optionalIsoDateString(value: unknown): string | null {\n if (value instanceof Date) return value.toISOString();\n if (typeof value === 'string' && value.length > 0) {\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? value : d.toISOString();\n }\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\nfunction withoutUnderscoreKeys(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).filter(([key]) => !key.includes('_')),\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 SubscriptionInvoiceRefund,\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 responseHeaders: res.headers,\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 applicationId: input.applicationId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n intervalUnit: input.intervalUnit,\n intervalCount: input.intervalCount,\n totalPayments: input.totalPayments,\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 orderId: input.orderId,\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, 'installment', params.installment);\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(\n id: string,\n input: { atPeriodEnd?: boolean; refund?: 'none' | 'prorated' | 'last_cycle' } = {},\n ): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false, refund: input.refund ?? 'none' },\n );\n return normalizeSubscription(data);\n }\n\n /**\n * Refund one billing cycle.\n *\n * `intent` has no default: refunding money and ending the subscription are\n * separate decisions, and guessing either way is wrong often enough that the\n * API requires the caller to say which one they mean.\n */\n async refundInvoice(\n id: string,\n invoiceId: string,\n input: { intent: 'money_only' | 'refund_and_cancel'; amount?: number; reason?: string },\n ): Promise<SubscriptionInvoiceRefund> {\n return this.request<SubscriptionInvoiceRefund>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/invoices/${encodeURIComponent(invoiceId)}/refund`,\n input,\n );\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 paymentMethodId: 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":["ThrottleError"]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
-
import { ThrottleError } from '@usethrottle/errors';
|
|
2
|
+
import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
|
|
3
3
|
|
|
4
|
-
type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing';
|
|
5
|
-
type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly';
|
|
4
|
+
type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing' | 'unpaid' | 'completed';
|
|
5
|
+
type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'custom';
|
|
6
|
+
type SubscriptionIntervalUnit = 'hour' | 'day' | 'week' | 'month';
|
|
6
7
|
type SubscriptionSort = 'asc' | 'desc';
|
|
7
8
|
interface Subscription {
|
|
8
9
|
id: string;
|
|
@@ -13,6 +14,15 @@ interface Subscription {
|
|
|
13
14
|
planReference: string;
|
|
14
15
|
planName?: string | null;
|
|
15
16
|
interval: SubscriptionInterval;
|
|
17
|
+
/** The cadence as "every intervalCount intervalUnit". Named intervals carry their shorthand (monthly → month, 1). */
|
|
18
|
+
intervalUnit: SubscriptionIntervalUnit | null;
|
|
19
|
+
intervalCount: number | null;
|
|
20
|
+
/** Installment plans only: the fixed number of payments. null for an ongoing subscription. */
|
|
21
|
+
totalPayments: number | null;
|
|
22
|
+
/** Installment plans only: payments counted so far, charges and waived periods alike. */
|
|
23
|
+
paymentsMade: number;
|
|
24
|
+
/** When the final installment succeeded. Set only on `completed`. */
|
|
25
|
+
completedAt: string | null;
|
|
16
26
|
amount: number;
|
|
17
27
|
currency: string;
|
|
18
28
|
currentPeriodStart: string;
|
|
@@ -85,6 +95,8 @@ interface ListSubscriptionsParams {
|
|
|
85
95
|
sort?: SubscriptionSort;
|
|
86
96
|
createdAfter?: string | Date;
|
|
87
97
|
createdBefore?: string | Date;
|
|
98
|
+
/** true: only installment plans; false: only ongoing subscriptions. */
|
|
99
|
+
installment?: boolean;
|
|
88
100
|
}
|
|
89
101
|
interface CreateSubscriptionInput {
|
|
90
102
|
applicationId?: string;
|
|
@@ -92,7 +104,12 @@ interface CreateSubscriptionInput {
|
|
|
92
104
|
externalCustomerId?: string;
|
|
93
105
|
planReference: string;
|
|
94
106
|
planName?: string;
|
|
95
|
-
interval
|
|
107
|
+
interval?: SubscriptionInterval;
|
|
108
|
+
/** Any cadence from 1 hour to 1 year. Send with intervalCount instead of, or with, `interval`. */
|
|
109
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
110
|
+
intervalCount?: number;
|
|
111
|
+
/** Makes this an installment plan of exactly this many payments (2–60). No trial; set once. */
|
|
112
|
+
totalPayments?: number;
|
|
96
113
|
amount: number;
|
|
97
114
|
currency?: string;
|
|
98
115
|
currentPeriodStart: string | Date;
|
|
@@ -111,6 +128,8 @@ interface UpdateSubscriptionInput {
|
|
|
111
128
|
planReference?: string;
|
|
112
129
|
planName?: string;
|
|
113
130
|
interval?: SubscriptionInterval;
|
|
131
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
132
|
+
intervalCount?: number;
|
|
114
133
|
amount?: number;
|
|
115
134
|
metadata?: Record<string, unknown>;
|
|
116
135
|
}
|
|
@@ -124,7 +143,10 @@ interface ChangePlanInput extends UpdateSubscriptionInput {
|
|
|
124
143
|
}
|
|
125
144
|
interface RecurringIntent {
|
|
126
145
|
plan: string;
|
|
127
|
-
interval
|
|
146
|
+
interval?: SubscriptionInterval;
|
|
147
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
148
|
+
intervalCount?: number;
|
|
149
|
+
totalPayments?: number;
|
|
128
150
|
amount?: number;
|
|
129
151
|
trialDays?: number;
|
|
130
152
|
planName?: string;
|
|
@@ -330,7 +352,8 @@ declare class ThrottleSubscriptionsError extends ThrottleError {
|
|
|
330
352
|
message: string;
|
|
331
353
|
statusCode: number;
|
|
332
354
|
details?: unknown;
|
|
355
|
+
responseHeaders?: ThrottleErrorArgs['responseHeaders'];
|
|
333
356
|
});
|
|
334
357
|
}
|
|
335
358
|
|
|
336
|
-
export {
|
|
359
|
+
export { type TrialEligibilityResult as A, createSubscriptionsClient as B, 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 Subscription as S, type ThrottleEnvelope as T, type UpdateSubscriptionInput as U, type ChangePlanInput as a, type CheckoutCollectInput as b, type CheckoutCustomerInput as c, type CheckoutSession as d, type CreateCheckoutSessionInput as e, type CreateSubscriptionInput as f, type Customer as g, type CustomerPaymentMethod as h, type Pagination as i, type QueryState as j, type SubscriptionFetcher as k, type SubscriptionInterval as l, type SubscriptionIntervalUnit as m, type SubscriptionInvoiceRefund as n, type SubscriptionProviderProps as o, type SubscriptionSort as p, type SubscriptionStatus as q, type SubscriptionStatusBadgeProps as r, type SubscriptionTaxAddress as s, SubscriptionsClient as t, type SubscriptionsClientContract as u, type SubscriptionsClientOptions as v, ThrottleSubscriptionsError as w, type TrialCountdownProps as x, type TrialEligibilityInput as y, type TrialEligibilityReason as z };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
-
import { ThrottleError } from '@usethrottle/errors';
|
|
2
|
+
import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
|
|
3
3
|
|
|
4
|
-
type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing';
|
|
5
|
-
type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly';
|
|
4
|
+
type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing' | 'unpaid' | 'completed';
|
|
5
|
+
type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'custom';
|
|
6
|
+
type SubscriptionIntervalUnit = 'hour' | 'day' | 'week' | 'month';
|
|
6
7
|
type SubscriptionSort = 'asc' | 'desc';
|
|
7
8
|
interface Subscription {
|
|
8
9
|
id: string;
|
|
@@ -13,6 +14,15 @@ interface Subscription {
|
|
|
13
14
|
planReference: string;
|
|
14
15
|
planName?: string | null;
|
|
15
16
|
interval: SubscriptionInterval;
|
|
17
|
+
/** The cadence as "every intervalCount intervalUnit". Named intervals carry their shorthand (monthly → month, 1). */
|
|
18
|
+
intervalUnit: SubscriptionIntervalUnit | null;
|
|
19
|
+
intervalCount: number | null;
|
|
20
|
+
/** Installment plans only: the fixed number of payments. null for an ongoing subscription. */
|
|
21
|
+
totalPayments: number | null;
|
|
22
|
+
/** Installment plans only: payments counted so far, charges and waived periods alike. */
|
|
23
|
+
paymentsMade: number;
|
|
24
|
+
/** When the final installment succeeded. Set only on `completed`. */
|
|
25
|
+
completedAt: string | null;
|
|
16
26
|
amount: number;
|
|
17
27
|
currency: string;
|
|
18
28
|
currentPeriodStart: string;
|
|
@@ -85,6 +95,8 @@ interface ListSubscriptionsParams {
|
|
|
85
95
|
sort?: SubscriptionSort;
|
|
86
96
|
createdAfter?: string | Date;
|
|
87
97
|
createdBefore?: string | Date;
|
|
98
|
+
/** true: only installment plans; false: only ongoing subscriptions. */
|
|
99
|
+
installment?: boolean;
|
|
88
100
|
}
|
|
89
101
|
interface CreateSubscriptionInput {
|
|
90
102
|
applicationId?: string;
|
|
@@ -92,7 +104,12 @@ interface CreateSubscriptionInput {
|
|
|
92
104
|
externalCustomerId?: string;
|
|
93
105
|
planReference: string;
|
|
94
106
|
planName?: string;
|
|
95
|
-
interval
|
|
107
|
+
interval?: SubscriptionInterval;
|
|
108
|
+
/** Any cadence from 1 hour to 1 year. Send with intervalCount instead of, or with, `interval`. */
|
|
109
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
110
|
+
intervalCount?: number;
|
|
111
|
+
/** Makes this an installment plan of exactly this many payments (2–60). No trial; set once. */
|
|
112
|
+
totalPayments?: number;
|
|
96
113
|
amount: number;
|
|
97
114
|
currency?: string;
|
|
98
115
|
currentPeriodStart: string | Date;
|
|
@@ -111,6 +128,8 @@ interface UpdateSubscriptionInput {
|
|
|
111
128
|
planReference?: string;
|
|
112
129
|
planName?: string;
|
|
113
130
|
interval?: SubscriptionInterval;
|
|
131
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
132
|
+
intervalCount?: number;
|
|
114
133
|
amount?: number;
|
|
115
134
|
metadata?: Record<string, unknown>;
|
|
116
135
|
}
|
|
@@ -124,7 +143,10 @@ interface ChangePlanInput extends UpdateSubscriptionInput {
|
|
|
124
143
|
}
|
|
125
144
|
interface RecurringIntent {
|
|
126
145
|
plan: string;
|
|
127
|
-
interval
|
|
146
|
+
interval?: SubscriptionInterval;
|
|
147
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
148
|
+
intervalCount?: number;
|
|
149
|
+
totalPayments?: number;
|
|
128
150
|
amount?: number;
|
|
129
151
|
trialDays?: number;
|
|
130
152
|
planName?: string;
|
|
@@ -330,7 +352,8 @@ declare class ThrottleSubscriptionsError extends ThrottleError {
|
|
|
330
352
|
message: string;
|
|
331
353
|
statusCode: number;
|
|
332
354
|
details?: unknown;
|
|
355
|
+
responseHeaders?: ThrottleErrorArgs['responseHeaders'];
|
|
333
356
|
});
|
|
334
357
|
}
|
|
335
358
|
|
|
336
|
-
export {
|
|
359
|
+
export { type TrialEligibilityResult as A, createSubscriptionsClient as B, 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 Subscription as S, type ThrottleEnvelope as T, type UpdateSubscriptionInput as U, type ChangePlanInput as a, type CheckoutCollectInput as b, type CheckoutCustomerInput as c, type CheckoutSession as d, type CreateCheckoutSessionInput as e, type CreateSubscriptionInput as f, type Customer as g, type CustomerPaymentMethod as h, type Pagination as i, type QueryState as j, type SubscriptionFetcher as k, type SubscriptionInterval as l, type SubscriptionIntervalUnit as m, type SubscriptionInvoiceRefund as n, type SubscriptionProviderProps as o, type SubscriptionSort as p, type SubscriptionStatus as q, type SubscriptionStatusBadgeProps as r, type SubscriptionTaxAddress as s, SubscriptionsClient as t, type SubscriptionsClientContract as u, type SubscriptionsClientOptions as v, ThrottleSubscriptionsError as w, type TrialCountdownProps as x, type TrialEligibilityInput as y, type TrialEligibilityReason as z };
|
package/dist/index.cjs
CHANGED
|
@@ -28,12 +28,15 @@ __export(index_exports, {
|
|
|
28
28
|
ThrottleError: () => import_errors2.ThrottleError,
|
|
29
29
|
ThrottleSubscriptionsError: () => ThrottleSubscriptionsError,
|
|
30
30
|
TrialCountdown: () => TrialCountdown,
|
|
31
|
+
cadenceLabel: () => cadenceLabel2,
|
|
32
|
+
cadenceNoun: () => cadenceNoun2,
|
|
31
33
|
canCancelSubscription: () => canCancelSubscription,
|
|
32
34
|
canPauseSubscription: () => canPauseSubscription,
|
|
33
35
|
canResumeSubscription: () => canResumeSubscription,
|
|
34
36
|
createSubscriptionFetcher: () => createSubscriptionFetcher,
|
|
35
37
|
createSubscriptionsClient: () => createSubscriptionsClient,
|
|
36
38
|
daysUntil: () => daysUntil,
|
|
39
|
+
installmentProgress: () => installmentProgress2,
|
|
37
40
|
isSubscriptionPastDue: () => isSubscriptionPastDue,
|
|
38
41
|
isSubscriptionTrialing: () => isSubscriptionTrialing,
|
|
39
42
|
isTerminalSubscription: () => isTerminalSubscription,
|
|
@@ -76,6 +79,11 @@ function normalizeSubscription(raw) {
|
|
|
76
79
|
planReference: requiredString(raw?.planReference, "subscription.planReference"),
|
|
77
80
|
planName: optionalString(raw?.planName),
|
|
78
81
|
interval: raw?.interval ?? "monthly",
|
|
82
|
+
intervalUnit: optionalString(raw?.intervalUnit) ?? null,
|
|
83
|
+
intervalCount: raw?.intervalCount == null ? null : Number(raw.intervalCount),
|
|
84
|
+
totalPayments: raw?.totalPayments == null ? null : Number(raw.totalPayments),
|
|
85
|
+
paymentsMade: Number(raw?.paymentsMade ?? 0),
|
|
86
|
+
completedAt: optionalIsoDateString(raw?.completedAt),
|
|
79
87
|
amount: Number(raw?.amount ?? 0),
|
|
80
88
|
currency: optionalString(raw?.currency) ?? "USD",
|
|
81
89
|
currentPeriodStart: requiredDateString(
|
|
@@ -170,6 +178,14 @@ function optionalDateString(value) {
|
|
|
170
178
|
if (typeof value === "string" && value.length > 0) return value;
|
|
171
179
|
return null;
|
|
172
180
|
}
|
|
181
|
+
function optionalIsoDateString(value) {
|
|
182
|
+
if (value instanceof Date) return value.toISOString();
|
|
183
|
+
if (typeof value === "string" && value.length > 0) {
|
|
184
|
+
const d = new Date(value);
|
|
185
|
+
return Number.isNaN(d.getTime()) ? value : d.toISOString();
|
|
186
|
+
}
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
173
189
|
function objectOrEmpty(value) {
|
|
174
190
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
175
191
|
}
|
|
@@ -227,7 +243,8 @@ var SubscriptionsClient = class {
|
|
|
227
243
|
code: json.error?.code ?? "unknown_error",
|
|
228
244
|
message: json.error?.message ?? `HTTP ${res.status}`,
|
|
229
245
|
statusCode: res.status,
|
|
230
|
-
details: json.error?.details
|
|
246
|
+
details: json.error?.details,
|
|
247
|
+
responseHeaders: res.headers
|
|
231
248
|
});
|
|
232
249
|
}
|
|
233
250
|
return json;
|
|
@@ -243,6 +260,9 @@ var SubscriptionsClient = class {
|
|
|
243
260
|
planReference: input.planReference,
|
|
244
261
|
planName: input.planName,
|
|
245
262
|
interval: input.interval,
|
|
263
|
+
intervalUnit: input.intervalUnit,
|
|
264
|
+
intervalCount: input.intervalCount,
|
|
265
|
+
totalPayments: input.totalPayments,
|
|
246
266
|
amount: input.amount,
|
|
247
267
|
currency: input.currency,
|
|
248
268
|
currentPeriodStart: toIso(input.currentPeriodStart),
|
|
@@ -259,6 +279,7 @@ var SubscriptionsClient = class {
|
|
|
259
279
|
setQuery(query, "externalCustomerId", params.externalCustomerId);
|
|
260
280
|
setQuery(query, "status", params.status);
|
|
261
281
|
setQuery(query, "interval", params.interval);
|
|
282
|
+
setQuery(query, "installment", params.installment);
|
|
262
283
|
setQuery(query, "q", params.q);
|
|
263
284
|
setQuery(query, "cursor", params.cursor);
|
|
264
285
|
setQuery(query, "limit", params.limit);
|
|
@@ -616,9 +637,65 @@ function useStableValue(value) {
|
|
|
616
637
|
return (0, import_react2.useMemo)(() => value, [key]);
|
|
617
638
|
}
|
|
618
639
|
|
|
640
|
+
// ../core-cadence/src/cadence.ts
|
|
641
|
+
var INTERVAL_UNITS = ["hour", "day", "week", "month"];
|
|
642
|
+
var NAMED_INTERVALS = ["weekly", "biweekly", "monthly", "quarterly", "yearly"];
|
|
643
|
+
var INTERVAL_VALUES = [...NAMED_INTERVALS, "custom"];
|
|
644
|
+
var HOUR_MS = 36e5;
|
|
645
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
646
|
+
var WEEK_MS = 7 * DAY_MS;
|
|
647
|
+
function isNamedInterval(value) {
|
|
648
|
+
return typeof value === "string" && NAMED_INTERVALS.includes(value);
|
|
649
|
+
}
|
|
650
|
+
function isIntervalUnit(value) {
|
|
651
|
+
return typeof value === "string" && INTERVAL_UNITS.includes(value);
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
// ../core-cadence/src/installments.ts
|
|
655
|
+
function installmentProgress(sub) {
|
|
656
|
+
if (sub.totalPayments == null) return null;
|
|
657
|
+
const paymentsMade = Math.min(sub.paymentsMade ?? 0, sub.totalPayments);
|
|
658
|
+
const remainingPayments = sub.totalPayments - paymentsMade;
|
|
659
|
+
return {
|
|
660
|
+
paymentsMade,
|
|
661
|
+
totalPayments: sub.totalPayments,
|
|
662
|
+
remainingPayments,
|
|
663
|
+
remainingCents: remainingPayments * sub.amount * (sub.quantity ?? 1)
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// ../core-cadence/src/labels.ts
|
|
668
|
+
var NAMED_NOUN = {
|
|
669
|
+
weekly: "week",
|
|
670
|
+
biweekly: "2 weeks",
|
|
671
|
+
monthly: "month",
|
|
672
|
+
quarterly: "quarter",
|
|
673
|
+
yearly: "year"
|
|
674
|
+
};
|
|
675
|
+
var NAMED_LABEL = {
|
|
676
|
+
weekly: "Weekly",
|
|
677
|
+
biweekly: "Biweekly",
|
|
678
|
+
monthly: "Monthly",
|
|
679
|
+
quarterly: "Quarterly",
|
|
680
|
+
yearly: "Yearly"
|
|
681
|
+
};
|
|
682
|
+
function cadenceNoun(cadence) {
|
|
683
|
+
if (isNamedInterval(cadence.interval)) return NAMED_NOUN[cadence.interval];
|
|
684
|
+
if (isIntervalUnit(cadence.intervalUnit) && cadence.intervalCount != null) {
|
|
685
|
+
return cadence.intervalCount === 1 ? cadence.intervalUnit : `${cadence.intervalCount} ${cadence.intervalUnit}s`;
|
|
686
|
+
}
|
|
687
|
+
return cadence.interval;
|
|
688
|
+
}
|
|
689
|
+
function cadenceLabel(cadence) {
|
|
690
|
+
if (isNamedInterval(cadence.interval)) return NAMED_LABEL[cadence.interval];
|
|
691
|
+
if (isIntervalUnit(cadence.intervalUnit) && cadence.intervalCount != null) return `Every ${cadenceNoun(cadence)}`;
|
|
692
|
+
return cadence.interval;
|
|
693
|
+
}
|
|
694
|
+
|
|
619
695
|
// src/helpers.ts
|
|
620
696
|
function isTerminalSubscription(status) {
|
|
621
|
-
|
|
697
|
+
const s = getStatus(status);
|
|
698
|
+
return s === "cancelled" || s === "completed";
|
|
622
699
|
}
|
|
623
700
|
function canPauseSubscription(status) {
|
|
624
701
|
return getStatus(status) === "active";
|
|
@@ -627,7 +704,7 @@ function canResumeSubscription(status) {
|
|
|
627
704
|
return getStatus(status) === "paused";
|
|
628
705
|
}
|
|
629
706
|
function canCancelSubscription(status) {
|
|
630
|
-
return
|
|
707
|
+
return !isTerminalSubscription(status);
|
|
631
708
|
}
|
|
632
709
|
function isSubscriptionPastDue(status) {
|
|
633
710
|
return getStatus(status) === "past_due";
|
|
@@ -644,6 +721,15 @@ function daysUntil(date, now = /* @__PURE__ */ new Date()) {
|
|
|
644
721
|
function getStatus(input) {
|
|
645
722
|
return typeof input === "string" ? input : input.status;
|
|
646
723
|
}
|
|
724
|
+
function cadenceNoun2(cadence) {
|
|
725
|
+
return cadenceNoun(cadence);
|
|
726
|
+
}
|
|
727
|
+
function cadenceLabel2(cadence) {
|
|
728
|
+
return cadenceLabel(cadence);
|
|
729
|
+
}
|
|
730
|
+
function installmentProgress2(sub) {
|
|
731
|
+
return installmentProgress(sub);
|
|
732
|
+
}
|
|
647
733
|
|
|
648
734
|
// src/components.tsx
|
|
649
735
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -652,14 +738,18 @@ var STATUS_LABELS = {
|
|
|
652
738
|
paused: "Paused",
|
|
653
739
|
cancelled: "Cancelled",
|
|
654
740
|
past_due: "Past due",
|
|
655
|
-
trialing: "Trialing"
|
|
741
|
+
trialing: "Trialing",
|
|
742
|
+
unpaid: "Unpaid",
|
|
743
|
+
completed: "Paid in full"
|
|
656
744
|
};
|
|
657
745
|
var STATUS_STYLES = {
|
|
658
746
|
active: { color: "#035c4f", background: "#dff8ef", borderColor: "#a8e8d2" },
|
|
659
747
|
paused: { color: "#735c00", background: "#fff4ca", borderColor: "#f3d46b" },
|
|
660
748
|
cancelled: { color: "#6c2632", background: "#ffe1e7", borderColor: "#f4a9b8" },
|
|
661
749
|
past_due: { color: "#7a2d00", background: "#ffe8d6", borderColor: "#f5b47f" },
|
|
662
|
-
trialing: { color: "#124c73", background: "#dff1ff", borderColor: "#9ed3fb" }
|
|
750
|
+
trialing: { color: "#124c73", background: "#dff1ff", borderColor: "#9ed3fb" },
|
|
751
|
+
unpaid: { color: "#7a2d00", background: "#ffe8d6", borderColor: "#f5b47f" },
|
|
752
|
+
completed: { color: "#035c4f", background: "#dff8ef", borderColor: "#a8e8d2" }
|
|
663
753
|
};
|
|
664
754
|
function SubscriptionStatusBadge({
|
|
665
755
|
status,
|
|
@@ -761,12 +851,15 @@ function DunningBanner({
|
|
|
761
851
|
ThrottleError,
|
|
762
852
|
ThrottleSubscriptionsError,
|
|
763
853
|
TrialCountdown,
|
|
854
|
+
cadenceLabel,
|
|
855
|
+
cadenceNoun,
|
|
764
856
|
canCancelSubscription,
|
|
765
857
|
canPauseSubscription,
|
|
766
858
|
canResumeSubscription,
|
|
767
859
|
createSubscriptionFetcher,
|
|
768
860
|
createSubscriptionsClient,
|
|
769
861
|
daysUntil,
|
|
862
|
+
installmentProgress,
|
|
770
863
|
isSubscriptionPastDue,
|
|
771
864
|
isSubscriptionTrialing,
|
|
772
865
|
isTerminalSubscription,
|