@usethrottle/subscriptions 3.2.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-YQLHMNZH.js → chunk-XXR5PITK.js} +18 -1
- package/dist/chunk-XXR5PITK.js.map +1 -0
- package/dist/{errors-BCOtLFs2.d.cts → errors-BaFuPdr3.d.cts} +35 -3
- package/dist/{errors-BCOtLFs2.d.ts → errors-BaFuPdr3.d.ts} +35 -3
- package/dist/index.cjs +24 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +8 -8
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +29 -8
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3 -2
- package/dist/server.d.ts +3 -2
- package/dist/server.js +13 -9
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-YQLHMNZH.js.map +0 -1
|
@@ -24,6 +24,9 @@ function normalizeSubscription(raw) {
|
|
|
24
24
|
totalPayments: raw?.totalPayments == null ? null : Number(raw.totalPayments),
|
|
25
25
|
paymentsMade: Number(raw?.paymentsMade ?? 0),
|
|
26
26
|
completedAt: optionalIsoDateString(raw?.completedAt),
|
|
27
|
+
paymentSchedule: normalizePaymentSchedule(raw?.paymentSchedule),
|
|
28
|
+
scheduleTotal: raw?.scheduleTotal == null ? null : Number(raw.scheduleTotal),
|
|
29
|
+
nextPaymentAmount: raw?.nextPaymentAmount == null ? null : Number(raw.nextPaymentAmount),
|
|
27
30
|
amount: Number(raw?.amount ?? 0),
|
|
28
31
|
quantity: Number(raw?.quantity ?? 1),
|
|
29
32
|
currency: optionalString(raw?.currency) ?? "USD",
|
|
@@ -52,6 +55,19 @@ function normalizeSubscription(raw) {
|
|
|
52
55
|
updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
|
|
53
56
|
};
|
|
54
57
|
}
|
|
58
|
+
function normalizePaymentSchedule(raw) {
|
|
59
|
+
if (!Array.isArray(raw)) return null;
|
|
60
|
+
return raw.map((r) => ({
|
|
61
|
+
index: Number(r?.index ?? 0),
|
|
62
|
+
amount: Number(r?.amount ?? 0),
|
|
63
|
+
discount: Number(r?.discount ?? 0),
|
|
64
|
+
net: Number(r?.net ?? 0),
|
|
65
|
+
intervalUnit: optionalString(r?.intervalUnit) ?? null,
|
|
66
|
+
intervalCount: r?.intervalCount == null ? null : Number(r.intervalCount),
|
|
67
|
+
status: r?.status,
|
|
68
|
+
dueAt: optionalDateString(r?.dueAt)
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
55
71
|
function normalizeRenewalIssue(raw) {
|
|
56
72
|
if (!raw || typeof raw !== "object") return null;
|
|
57
73
|
return {
|
|
@@ -242,6 +258,7 @@ var SubscriptionsClient = class {
|
|
|
242
258
|
intervalCount: input.intervalCount,
|
|
243
259
|
totalPayments: input.totalPayments,
|
|
244
260
|
amount: input.amount,
|
|
261
|
+
schedule: input.schedule,
|
|
245
262
|
currency: input.currency,
|
|
246
263
|
currentPeriodStart: toIso(input.currentPeriodStart),
|
|
247
264
|
currentPeriodEnd: toIso(input.currentPeriodEnd),
|
|
@@ -483,4 +500,4 @@ export {
|
|
|
483
500
|
SubscriptionsClient,
|
|
484
501
|
createSubscriptionsClient
|
|
485
502
|
};
|
|
486
|
-
//# sourceMappingURL=chunk-
|
|
503
|
+
//# sourceMappingURL=chunk-XXR5PITK.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 SubscriptionIntervalUnit,\n SubscriptionRenewalIssue,\n SubscriptionStatus,\n SubscriptionUsageItem,\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 paymentSchedule: normalizePaymentSchedule(raw?.paymentSchedule),\n scheduleTotal: raw?.scheduleTotal == null ? null : Number(raw.scheduleTotal),\n nextPaymentAmount: raw?.nextPaymentAmount == null ? null : Number(raw.nextPaymentAmount),\n amount: Number(raw?.amount ?? 0),\n quantity: Number(raw?.quantity ?? 1),\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 renewalIssue: normalizeRenewalIssue(raw?.renewalIssue),\n proration: raw?.proration\n ? {\n creditCents: raw.proration.creditCents,\n chargedCents: raw.proration.chargedCents,\n fullAmount: raw.proration.fullAmount,\n }\n : undefined,\n createdAt: optionalDateString(raw?.createdAt) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt) ?? undefined,\n };\n}\n\nfunction normalizePaymentSchedule(raw: any): Subscription['paymentSchedule'] {\n if (!Array.isArray(raw)) return null;\n return raw.map((r: any) => ({\n index: Number(r?.index ?? 0),\n amount: Number(r?.amount ?? 0),\n discount: Number(r?.discount ?? 0),\n net: Number(r?.net ?? 0),\n intervalUnit: (optionalString(r?.intervalUnit) as SubscriptionIntervalUnit | null) ?? null,\n intervalCount: r?.intervalCount == null ? null : Number(r.intervalCount),\n status: r?.status as 'paid' | 'due' | 'upcoming',\n dueAt: optionalDateString(r?.dueAt),\n }));\n}\n\nfunction normalizeRenewalIssue(raw: any): SubscriptionRenewalIssue | null {\n if (!raw || typeof raw !== 'object') return null;\n return {\n kind: raw.kind,\n reason: raw.reason,\n count: Number(raw.count ?? 0),\n firstAt: optionalString(raw.firstAt) ?? undefined,\n lastAt: requiredString(raw.lastAt, 'subscription.renewalIssue.lastAt'),\n message: raw.message ?? '',\n alertedAt: optionalDateString(raw.alertedAt),\n charge: raw.charge\n ? {\n transactionId: optionalString(raw.charge.transactionId),\n amount: Number(raw.charge.amount ?? 0),\n currency: optionalString(raw.charge.currency) ?? 'USD',\n periodStart: optionalString(raw.charge.periodStart) ?? undefined,\n }\n : null,\n };\n}\n\nexport function normalizeUsageItem(raw: any): SubscriptionUsageItem {\n return {\n id: requiredString(raw?.id, 'usageItem.id'),\n subscriptionId: requiredString(raw?.subscriptionId, 'usageItem.subscriptionId'),\n kind: raw?.kind ?? '',\n unitCount: Number(raw?.unitCount ?? 0),\n unitPriceCents: Number(raw?.unitPriceCents ?? 0),\n totalCents: Number(raw?.totalCents ?? 0),\n periodStart: requiredDateString(raw?.periodStart, 'usageItem.periodStart'),\n periodEnd: requiredDateString(raw?.periodEnd, 'usageItem.periodEnd'),\n createdAt: requiredDateString(raw?.createdAt, 'usageItem.createdAt'),\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 normalizeUsageItem,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n ChangeQuantityInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n RecordUsageInput,\n Subscription,\n SubscriptionInvoiceRefund,\n SubscriptionUsageItem,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n WaivePeriodInput,\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 schedule: input.schedule,\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 /**\n * A term-only edit: rename the plan, correct the cadence or the amount on\n * the row — no proration, no charge, no period reset. Mirrors\n * `PATCH /api/v1/subscriptions/{id}`. This is what `changePlan()` did\n * before 3.0.0; use `changePlan()` now for an actual plan change.\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 /**\n * A real plan change: prorated and charged immediately when\n * `effective: 'now'`, or scheduled for period end with no charge today.\n * Mirrors `POST /api/v1/subscriptions/{id}/change-plan`. The resolved\n * subscription carries `proration` when the server computed one.\n *\n * This is NOT the old `changePlan()` (a PATCH-style term edit with no\n * proration and no charge) — use `update()` for that.\n */\n async changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/change-plan`,\n {\n planReference: body.planReference,\n planName: body.planName,\n interval: body.interval,\n intervalUnit: body.intervalUnit,\n intervalCount: body.intervalCount,\n amount: body.amount,\n effective: body.effective,\n },\n );\n return normalizeSubscription(data);\n }\n\n /**\n * Change the seat quantity: prorated and charged immediately when\n * `effective: 'now'`, or scheduled for period end with no charge today.\n * Mirrors `POST /api/v1/subscriptions/{id}/change-quantity`.\n */\n async changeQuantity(id: string, input: ChangeQuantityInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/change-quantity`,\n { quantity: input.quantity, effective: input.effective },\n );\n return normalizeSubscription(data);\n }\n\n /**\n * Charge a past-due subscription's card again now, instead of waiting for\n * the next scheduled dunning retry. Mirrors\n * `POST /api/v1/subscriptions/{id}/retry-charge`.\n */\n async retryCharge(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/retry-charge`,\n );\n return normalizeSubscription(data);\n }\n\n /**\n * Forgive the current past-due period — the merchant is not collecting it.\n * Mirrors `POST /api/v1/subscriptions/{id}/waive-period`.\n */\n async waivePeriod(id: string, input: WaivePeriodInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/waive-period`,\n { reason: input.reason },\n );\n return normalizeSubscription(data);\n }\n\n /**\n * Record (upsert) a usage item for the subscription's current billing\n * period. Mirrors `POST /api/v1/subscriptions/{id}/usage`.\n */\n async recordUsage(id: string, input: RecordUsageInput): Promise<SubscriptionUsageItem> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/usage`,\n { kind: input.kind, unitCount: input.unitCount, unitPriceCents: input.unitPriceCents },\n );\n return normalizeUsageItem(data);\n }\n\n /**\n * List usage items recorded for the subscription's current billing period.\n * Mirrors `GET /api/v1/subscriptions/{id}/usage`.\n */\n async listUsage(id: string): Promise<SubscriptionUsageItem[]> {\n const envelope = await this.requestEnvelope<{ items?: unknown[] }>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/usage`,\n );\n // This route answers `{ items: [...] }`, not the usual `{ data, meta }`\n // envelope, so `request()`'s data-unwrap would just hand back the whole\n // body — read `items` off the raw envelope instead.\n const items = (envelope as unknown as { items?: unknown[] }).items ?? [];\n return items.map(normalizeUsageItem);\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"]}
|
|
@@ -5,6 +5,16 @@ type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'tria
|
|
|
5
5
|
type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'custom';
|
|
6
6
|
type SubscriptionIntervalUnit = 'hour' | 'day' | 'week' | 'month';
|
|
7
7
|
type SubscriptionSort = 'asc' | 'desc';
|
|
8
|
+
interface SubscriptionPaymentScheduleRow {
|
|
9
|
+
index: number;
|
|
10
|
+
amount: number;
|
|
11
|
+
discount: number;
|
|
12
|
+
net: number;
|
|
13
|
+
intervalUnit: SubscriptionIntervalUnit | null;
|
|
14
|
+
intervalCount: number | null;
|
|
15
|
+
status: 'paid' | 'due' | 'upcoming';
|
|
16
|
+
dueAt: string | null;
|
|
17
|
+
}
|
|
8
18
|
interface Subscription {
|
|
9
19
|
id: string;
|
|
10
20
|
workspaceId?: string | null;
|
|
@@ -23,6 +33,12 @@ interface Subscription {
|
|
|
23
33
|
paymentsMade: number;
|
|
24
34
|
/** When the final installment succeeded. Set only on `completed`. */
|
|
25
35
|
completedAt: string | null;
|
|
36
|
+
/** Installment plans only: every payment in order (equal plans synthesized). dueAt is an estimate. */
|
|
37
|
+
paymentSchedule?: SubscriptionPaymentScheduleRow[] | null;
|
|
38
|
+
/** Installment plans only: the sum of every payment's net amount. */
|
|
39
|
+
scheduleTotal?: number | null;
|
|
40
|
+
/** Installment plans only: what the next payment will charge. null once complete. */
|
|
41
|
+
nextPaymentAmount?: number | null;
|
|
26
42
|
amount: number;
|
|
27
43
|
/** #688 — number of seats. Per-seat price is `amount`; the period charge is `amount × quantity`. Defaults to 1. */
|
|
28
44
|
quantity: number;
|
|
@@ -145,10 +161,26 @@ interface CreateSubscriptionInput {
|
|
|
145
161
|
intervalCount?: number;
|
|
146
162
|
/** Makes this an installment plan of exactly this many payments (2–60). No trial; set once. */
|
|
147
163
|
totalPayments?: number;
|
|
148
|
-
amount
|
|
164
|
+
/** Required unless `schedule` is sent (the first payment's amount is then taken from the schedule). */
|
|
165
|
+
amount?: number;
|
|
149
166
|
currency?: string;
|
|
150
167
|
currentPeriodStart: string | Date;
|
|
151
|
-
|
|
168
|
+
/** Optional when `schedule` is sent; the first period end is derived from the schedule's first gap. */
|
|
169
|
+
currentPeriodEnd?: string | Date;
|
|
170
|
+
/**
|
|
171
|
+
* Custom installment schedule: 2-60 payments that differ in amount and in the
|
|
172
|
+
* gap before each one. Row 0 has no gap; later rows may carry `intervalUnit`
|
|
173
|
+
* (hour 1-8760, day 1-365, week 1-52, month 1-12) and `intervalCount`.
|
|
174
|
+
* Amounts are positive integers in minor units. The row count is the number
|
|
175
|
+
* of payments. `interval`, `intervalUnit`, `intervalCount`, `totalPayments`
|
|
176
|
+
* and `trialEnd` must be OMITTED with a schedule: the API rejects them
|
|
177
|
+
* whatever their value.
|
|
178
|
+
*/
|
|
179
|
+
schedule?: Array<{
|
|
180
|
+
amount: number;
|
|
181
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
182
|
+
intervalCount?: number;
|
|
183
|
+
}>;
|
|
152
184
|
trialEnd?: string | Date;
|
|
153
185
|
metadata?: Record<string, unknown>;
|
|
154
186
|
/**
|
|
@@ -486,4 +518,4 @@ declare class ThrottleSubscriptionsError extends ThrottleError {
|
|
|
486
518
|
});
|
|
487
519
|
}
|
|
488
520
|
|
|
489
|
-
export { type
|
|
521
|
+
export { type SubscriptionsClientContract as A, type SubscriptionsClientOptions as B, type CancelSubscriptionInput as C, type DunningBannerProps as D, ThrottleSubscriptionsError as E, type TrialCountdownProps as F, type TrialEligibilityInput as G, type TrialEligibilityReason as H, type TrialEligibilityResult as I, createSubscriptionsClient as J, type ListSubscriptionsParams as L, type MutationState as M, type PaginatedSubscriptions as P, type QueryOptions as Q, type RecordUsageInput as R, type Subscription as S, type ThrottleEnvelope as T, type UpdateSubscriptionInput as U, type WaivePeriodInput as W, type ChangePlanInput as a, type ChangeQuantityInput as b, type CheckoutCollectInput as c, type CheckoutCustomerInput as d, type CheckoutSession as e, type CreateCheckoutSessionInput as f, type CreateSubscriptionInput as g, type Customer as h, type CustomerPaymentMethod as i, type Pagination as j, type QueryState as k, type RecurringIntent as l, type SubscriptionFetcher as m, type SubscriptionInterval as n, type SubscriptionIntervalUnit as o, type SubscriptionInvoiceRefund as p, type SubscriptionPaymentScheduleRow as q, type SubscriptionProration as r, type SubscriptionProviderProps as s, type SubscriptionRenewalIssue as t, type SubscriptionSort as u, type SubscriptionStatus as v, type SubscriptionStatusBadgeProps as w, type SubscriptionTaxAddress as x, type SubscriptionUsageItem as y, SubscriptionsClient as z };
|
|
@@ -5,6 +5,16 @@ type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'tria
|
|
|
5
5
|
type SubscriptionInterval = 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly' | 'custom';
|
|
6
6
|
type SubscriptionIntervalUnit = 'hour' | 'day' | 'week' | 'month';
|
|
7
7
|
type SubscriptionSort = 'asc' | 'desc';
|
|
8
|
+
interface SubscriptionPaymentScheduleRow {
|
|
9
|
+
index: number;
|
|
10
|
+
amount: number;
|
|
11
|
+
discount: number;
|
|
12
|
+
net: number;
|
|
13
|
+
intervalUnit: SubscriptionIntervalUnit | null;
|
|
14
|
+
intervalCount: number | null;
|
|
15
|
+
status: 'paid' | 'due' | 'upcoming';
|
|
16
|
+
dueAt: string | null;
|
|
17
|
+
}
|
|
8
18
|
interface Subscription {
|
|
9
19
|
id: string;
|
|
10
20
|
workspaceId?: string | null;
|
|
@@ -23,6 +33,12 @@ interface Subscription {
|
|
|
23
33
|
paymentsMade: number;
|
|
24
34
|
/** When the final installment succeeded. Set only on `completed`. */
|
|
25
35
|
completedAt: string | null;
|
|
36
|
+
/** Installment plans only: every payment in order (equal plans synthesized). dueAt is an estimate. */
|
|
37
|
+
paymentSchedule?: SubscriptionPaymentScheduleRow[] | null;
|
|
38
|
+
/** Installment plans only: the sum of every payment's net amount. */
|
|
39
|
+
scheduleTotal?: number | null;
|
|
40
|
+
/** Installment plans only: what the next payment will charge. null once complete. */
|
|
41
|
+
nextPaymentAmount?: number | null;
|
|
26
42
|
amount: number;
|
|
27
43
|
/** #688 — number of seats. Per-seat price is `amount`; the period charge is `amount × quantity`. Defaults to 1. */
|
|
28
44
|
quantity: number;
|
|
@@ -145,10 +161,26 @@ interface CreateSubscriptionInput {
|
|
|
145
161
|
intervalCount?: number;
|
|
146
162
|
/** Makes this an installment plan of exactly this many payments (2–60). No trial; set once. */
|
|
147
163
|
totalPayments?: number;
|
|
148
|
-
amount
|
|
164
|
+
/** Required unless `schedule` is sent (the first payment's amount is then taken from the schedule). */
|
|
165
|
+
amount?: number;
|
|
149
166
|
currency?: string;
|
|
150
167
|
currentPeriodStart: string | Date;
|
|
151
|
-
|
|
168
|
+
/** Optional when `schedule` is sent; the first period end is derived from the schedule's first gap. */
|
|
169
|
+
currentPeriodEnd?: string | Date;
|
|
170
|
+
/**
|
|
171
|
+
* Custom installment schedule: 2-60 payments that differ in amount and in the
|
|
172
|
+
* gap before each one. Row 0 has no gap; later rows may carry `intervalUnit`
|
|
173
|
+
* (hour 1-8760, day 1-365, week 1-52, month 1-12) and `intervalCount`.
|
|
174
|
+
* Amounts are positive integers in minor units. The row count is the number
|
|
175
|
+
* of payments. `interval`, `intervalUnit`, `intervalCount`, `totalPayments`
|
|
176
|
+
* and `trialEnd` must be OMITTED with a schedule: the API rejects them
|
|
177
|
+
* whatever their value.
|
|
178
|
+
*/
|
|
179
|
+
schedule?: Array<{
|
|
180
|
+
amount: number;
|
|
181
|
+
intervalUnit?: SubscriptionIntervalUnit;
|
|
182
|
+
intervalCount?: number;
|
|
183
|
+
}>;
|
|
152
184
|
trialEnd?: string | Date;
|
|
153
185
|
metadata?: Record<string, unknown>;
|
|
154
186
|
/**
|
|
@@ -486,4 +518,4 @@ declare class ThrottleSubscriptionsError extends ThrottleError {
|
|
|
486
518
|
});
|
|
487
519
|
}
|
|
488
520
|
|
|
489
|
-
export { type
|
|
521
|
+
export { type SubscriptionsClientContract as A, type SubscriptionsClientOptions as B, type CancelSubscriptionInput as C, type DunningBannerProps as D, ThrottleSubscriptionsError as E, type TrialCountdownProps as F, type TrialEligibilityInput as G, type TrialEligibilityReason as H, type TrialEligibilityResult as I, createSubscriptionsClient as J, type ListSubscriptionsParams as L, type MutationState as M, type PaginatedSubscriptions as P, type QueryOptions as Q, type RecordUsageInput as R, type Subscription as S, type ThrottleEnvelope as T, type UpdateSubscriptionInput as U, type WaivePeriodInput as W, type ChangePlanInput as a, type ChangeQuantityInput as b, type CheckoutCollectInput as c, type CheckoutCustomerInput as d, type CheckoutSession as e, type CreateCheckoutSessionInput as f, type CreateSubscriptionInput as g, type Customer as h, type CustomerPaymentMethod as i, type Pagination as j, type QueryState as k, type RecurringIntent as l, type SubscriptionFetcher as m, type SubscriptionInterval as n, type SubscriptionIntervalUnit as o, type SubscriptionInvoiceRefund as p, type SubscriptionPaymentScheduleRow as q, type SubscriptionProration as r, type SubscriptionProviderProps as s, type SubscriptionRenewalIssue as t, type SubscriptionSort as u, type SubscriptionStatus as v, type SubscriptionStatusBadgeProps as w, type SubscriptionTaxAddress as x, type SubscriptionUsageItem as y, SubscriptionsClient as z };
|
package/dist/index.cjs
CHANGED
|
@@ -84,6 +84,9 @@ function normalizeSubscription(raw) {
|
|
|
84
84
|
totalPayments: raw?.totalPayments == null ? null : Number(raw.totalPayments),
|
|
85
85
|
paymentsMade: Number(raw?.paymentsMade ?? 0),
|
|
86
86
|
completedAt: optionalIsoDateString(raw?.completedAt),
|
|
87
|
+
paymentSchedule: normalizePaymentSchedule(raw?.paymentSchedule),
|
|
88
|
+
scheduleTotal: raw?.scheduleTotal == null ? null : Number(raw.scheduleTotal),
|
|
89
|
+
nextPaymentAmount: raw?.nextPaymentAmount == null ? null : Number(raw.nextPaymentAmount),
|
|
87
90
|
amount: Number(raw?.amount ?? 0),
|
|
88
91
|
quantity: Number(raw?.quantity ?? 1),
|
|
89
92
|
currency: optionalString(raw?.currency) ?? "USD",
|
|
@@ -112,6 +115,19 @@ function normalizeSubscription(raw) {
|
|
|
112
115
|
updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
|
|
113
116
|
};
|
|
114
117
|
}
|
|
118
|
+
function normalizePaymentSchedule(raw) {
|
|
119
|
+
if (!Array.isArray(raw)) return null;
|
|
120
|
+
return raw.map((r) => ({
|
|
121
|
+
index: Number(r?.index ?? 0),
|
|
122
|
+
amount: Number(r?.amount ?? 0),
|
|
123
|
+
discount: Number(r?.discount ?? 0),
|
|
124
|
+
net: Number(r?.net ?? 0),
|
|
125
|
+
intervalUnit: optionalString(r?.intervalUnit) ?? null,
|
|
126
|
+
intervalCount: r?.intervalCount == null ? null : Number(r.intervalCount),
|
|
127
|
+
status: r?.status,
|
|
128
|
+
dueAt: optionalDateString(r?.dueAt)
|
|
129
|
+
}));
|
|
130
|
+
}
|
|
115
131
|
function normalizeRenewalIssue(raw) {
|
|
116
132
|
if (!raw || typeof raw !== "object") return null;
|
|
117
133
|
return {
|
|
@@ -302,6 +318,7 @@ var SubscriptionsClient = class {
|
|
|
302
318
|
intervalCount: input.intervalCount,
|
|
303
319
|
totalPayments: input.totalPayments,
|
|
304
320
|
amount: input.amount,
|
|
321
|
+
schedule: input.schedule,
|
|
305
322
|
currency: input.currency,
|
|
306
323
|
currentPeriodStart: toIso(input.currentPeriodStart),
|
|
307
324
|
currentPeriodEnd: toIso(input.currentPeriodEnd),
|
|
@@ -783,12 +800,9 @@ function installmentProgress(sub) {
|
|
|
783
800
|
if (sub.totalPayments == null) return null;
|
|
784
801
|
const paymentsMade = Math.min(sub.paymentsMade ?? 0, sub.totalPayments);
|
|
785
802
|
const remainingPayments = sub.totalPayments - paymentsMade;
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
remainingPayments,
|
|
790
|
-
remainingCents: remainingPayments * sub.amount * (sub.quantity ?? 1)
|
|
791
|
-
};
|
|
803
|
+
const quantity = sub.quantity ?? 1;
|
|
804
|
+
const remainingCents = sub.scheduleRows && sub.scheduleRows.length > 0 ? sub.scheduleRows.slice(paymentsMade).reduce((s, r) => s + r.unitAmount * quantity - r.discount, 0) : remainingPayments * sub.amount * quantity;
|
|
805
|
+
return { paymentsMade, totalPayments: sub.totalPayments, remainingPayments, remainingCents };
|
|
792
806
|
}
|
|
793
807
|
|
|
794
808
|
// ../core-cadence/src/labels.ts
|
|
@@ -855,7 +869,10 @@ function cadenceLabel2(cadence) {
|
|
|
855
869
|
return cadenceLabel(cadence);
|
|
856
870
|
}
|
|
857
871
|
function installmentProgress2(sub) {
|
|
858
|
-
|
|
872
|
+
const progress = installmentProgress(sub);
|
|
873
|
+
if (!progress || !sub.paymentSchedule || sub.paymentSchedule.length === 0) return progress;
|
|
874
|
+
const remainingCents = sub.paymentSchedule.filter((r) => r.status !== "paid").reduce((sum, r) => sum + r.net, 0);
|
|
875
|
+
return { ...progress, remainingCents };
|
|
859
876
|
}
|
|
860
877
|
|
|
861
878
|
// src/components.tsx
|