@usethrottle/subscriptions 3.6.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -47,6 +47,7 @@ Direct customer-scoped browser tokens are intentionally not in v1 because the AP
47
47
  - `create()` accepts either `customerId` or `externalCustomerId`; resolve external ids to Throttle customer rows before posting to `/api/v1/subscriptions`.
48
48
  - Normalize both camelCase and snake_case response fields. Some OpenAPI schemas use snake_case while service rows currently serialize camelCase.
49
49
  - The proxy helper must pin buyer-scoped reads, customer lookups, subscription creates, and checkout-session creates to `getExternalCustomerId()`.
50
+ - **The proxy forwards on the merchant's `sk_` key, so buyer bodies are an allowlist (4.0.0), not "whatever the API accepts".** `BUYER_BODY_FIELDS` in `server.ts` is the list: cancel → `atPeriodEnd` only (forwarding `refund` let a buyer refund themselves), PATCH → `shippingAddress` only, create refused. Prices and terms pass only through the merchant's `authorizeUpdate` / `authorizeCreate` hooks. Refuse unknown fields with `403 field_not_allowed`; never drop them silently. Do not widen the list without a merchant hook in front of it.
50
51
  - Mutations invalidate provider queries by bumping the provider cache version. Avoid adding a heavy query dependency unless product needs become more complex.
51
52
  - Components are primitive and minimally styled. They accept `className` and `style` so merchants can bring their own design system.
52
53
 
package/README.md CHANGED
@@ -86,9 +86,28 @@ const handler = createSubscriptionProxyHandler({
86
86
  export { handler as GET, handler as POST, handler as PATCH };
87
87
  ```
88
88
 
89
- 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.
89
+ 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 reading one subscription (404 otherwise) or forwarding a mutation.
90
90
  Payment-method reads are pinned to the authenticated buyer's Throttle customer row.
91
91
 
92
+ Because it forwards on your secret key, it also limits what a buyer may send (4.0.0):
93
+
94
+ | Request | A buyer may send | Otherwise |
95
+ | --- | --- | --- |
96
+ | `POST …/cancel` | `atPeriodEnd` | `403 field_not_allowed` (a `refund` is never forwarded) |
97
+ | `POST …/pause`, `…/resume` | nothing | `403 field_not_allowed` |
98
+ | `PATCH …/payment-method` | `paymentMethodId` | `403 field_not_allowed` |
99
+ | `PATCH /api/v1/subscriptions/{id}` | `shippingAddress` | `403 field_not_allowed`, unless `authorizeUpdate` returns true |
100
+ | `POST /api/v1/subscriptions` | — | `403 create_not_allowed`, unless `authorizeCreate` returns true |
101
+
102
+ ```ts
103
+ const handler = createSubscriptionProxyHandler({
104
+ apiKey: process.env.THROTTLE_SECRET_KEY!,
105
+ getExternalCustomerId: async () => (await auth())?.id ?? null,
106
+ // Only if buyers change plans in your portal: check the price yourself.
107
+ authorizeUpdate: ({ body }) => isCatalogPrice(body.planReference, body.amount),
108
+ });
109
+ ```
110
+
92
111
  ## Server-side API client
93
112
 
94
113
  You can also use the client directly from backend code:
@@ -114,6 +133,13 @@ await subscriptions.setPaymentMethod('sub_123', 'pm_456');
114
133
  subscription per checkout; omit it when the cart's lines carry `recurring`
115
134
  (`@usethrottle/cart`), and each such line becomes its own subscription.
116
135
 
136
+ ## Money
137
+
138
+ Amounts are integers in the subscription's minor unit. Show them with
139
+ `formatMoney(sub.amount, sub.currency)`: this package re-exports
140
+ `@usethrottle/money` as `money` and `formatMoney` by name, plus the
141
+ `CurrencyCode` and `MoneyValue` types.
142
+
117
143
  ## Boundaries
118
144
 
119
145
  - Customer-scoped browser tokens are not part of v1. Use the proxy helper.
@@ -29,7 +29,8 @@ function normalizeSubscription(raw) {
29
29
  nextPaymentAmount: raw?.nextPaymentAmount == null ? null : Number(raw.nextPaymentAmount),
30
30
  amount: Number(raw?.amount ?? 0),
31
31
  quantity: Number(raw?.quantity ?? 1),
32
- currency: optionalString(raw?.currency) ?? "USD",
32
+ // No USD fallback (MC2-R35): a subscription without a currency is a broken response.
33
+ currency: requiredString(raw?.currency, "subscription.currency"),
33
34
  currentPeriodStart: requiredDateString(
34
35
  raw?.currentPeriodStart,
35
36
  "subscription.currentPeriodStart"
@@ -46,7 +47,10 @@ function normalizeSubscription(raw) {
46
47
  cancelledAt: optionalDateString(raw?.cancelledAt),
47
48
  metadata: objectOrEmpty(raw?.metadata),
48
49
  paymentMethodId: optionalString(raw?.paymentMethodId),
49
- renewalIssue: normalizeRenewalIssue(raw?.renewalIssue),
50
+ deliveryMethod: raw?.deliveryMethod === "shipment" ? "shipment" : "access_grant",
51
+ shippingAddress: raw?.shippingAddress && typeof raw.shippingAddress === "object" ? raw.shippingAddress : null,
52
+ // `currency` above has already been checked.
53
+ renewalIssue: normalizeRenewalIssue(raw?.renewalIssue, raw.currency),
50
54
  proration: raw?.proration ? {
51
55
  creditCents: raw.proration.creditCents,
52
56
  chargedCents: raw.proration.chargedCents,
@@ -69,7 +73,7 @@ function normalizePaymentSchedule(raw) {
69
73
  dueAt: optionalDateString(r?.dueAt)
70
74
  }));
71
75
  }
72
- function normalizeRenewalIssue(raw) {
76
+ function normalizeRenewalIssue(raw, subscriptionCurrency) {
73
77
  if (!raw || typeof raw !== "object") return null;
74
78
  return {
75
79
  kind: raw.kind,
@@ -82,7 +86,7 @@ function normalizeRenewalIssue(raw) {
82
86
  charge: raw.charge ? {
83
87
  transactionId: optionalString(raw.charge.transactionId),
84
88
  amount: Number(raw.charge.amount ?? 0),
85
- currency: optionalString(raw.charge.currency) ?? "USD",
89
+ currency: optionalString(raw.charge.currency) || subscriptionCurrency,
86
90
  periodStart: optionalString(raw.charge.periodStart) ?? void 0
87
91
  } : null
88
92
  };
@@ -518,4 +522,4 @@ export {
518
522
  SubscriptionsClient,
519
523
  createSubscriptionsClient
520
524
  };
521
- //# sourceMappingURL=chunk-QDARSRCR.js.map
525
+ //# sourceMappingURL=chunk-GK6QY63F.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 // No USD fallback (MC2-R35): a subscription without a currency is a broken response.\n currency: requiredString(raw?.currency, 'subscription.currency'),\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 paymentMethodId: optionalString(raw?.paymentMethodId),\n deliveryMethod: raw?.deliveryMethod === 'shipment' ? 'shipment' : 'access_grant',\n shippingAddress:\n raw?.shippingAddress && typeof raw.shippingAddress === 'object' ? raw.shippingAddress : null,\n // `currency` above has already been checked.\n renewalIssue: normalizeRenewalIssue(raw?.renewalIssue, raw.currency),\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, subscriptionCurrency: string): 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) || subscriptionCurrency,\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 allowZeroAmount: input.allowZeroAmount,\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 allowZeroAmount: body.allowZeroAmount,\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 * Set the saved card this one subscription renews on. Only this\n * subscription moves: the customer's default card and their other\n * subscriptions stay as they are. Nothing is charged now; the next renewal\n * (or dunning retry) charges the new card. Mirrors\n * `PATCH /api/v1/subscriptions/{id}/payment-method`.\n */\n async setPaymentMethod(id: string, paymentMethodId: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/payment-method`,\n { paymentMethodId },\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":";AAAA,SAAS,qBAA6C;AAsBtD,SAAS,iBAAAA,gBAAe,uBAAuB;AAbxC,IAAM,6BAAN,cAAyC,cAAc;AAAA,EAC5D,YAAY,MAMT;AACD,UAAM,IAAI;AACV,SAAK,OAAO;AAAA,EACd;AACF;;;ACNO,SAAS,sBAAsB,KAAwB;AAC5D,SAAO;AAAA,IACL,IAAI,eAAe,KAAK,IAAI,iBAAiB;AAAA,IAC7C,aAAa,eAAe,KAAK,WAAW;AAAA,IAC5C,eAAe,eAAe,KAAK,aAAa;AAAA,IAChD,YAAY,eAAe,KAAK,YAAY,yBAAyB;AAAA,IACrE,QAAS,KAAK,UAAU;AAAA,IACxB,eAAe,eAAe,KAAK,eAAe,4BAA4B;AAAA,IAC9E,UAAU,eAAe,KAAK,QAAQ;AAAA,IACtC,UAAW,KAAK,YAAY;AAAA,IAC5B,cAAe,eAAe,KAAK,YAAY,KAAsC;AAAA,IACrF,eAAe,KAAK,iBAAiB,OAAO,OAAO,OAAO,IAAI,aAAa;AAAA,IAC3E,eAAe,KAAK,iBAAiB,OAAO,OAAO,OAAO,IAAI,aAAa;AAAA,IAC3E,cAAc,OAAO,KAAK,gBAAgB,CAAC;AAAA,IAC3C,aAAa,sBAAsB,KAAK,WAAW;AAAA,IACnD,iBAAiB,yBAAyB,KAAK,eAAe;AAAA,IAC9D,eAAe,KAAK,iBAAiB,OAAO,OAAO,OAAO,IAAI,aAAa;AAAA,IAC3E,mBAAmB,KAAK,qBAAqB,OAAO,OAAO,OAAO,IAAI,iBAAiB;AAAA,IACvF,QAAQ,OAAO,KAAK,UAAU,CAAC;AAAA,IAC/B,UAAU,OAAO,KAAK,YAAY,CAAC;AAAA;AAAA,IAEnC,UAAU,eAAe,KAAK,UAAU,uBAAuB;AAAA,IAC/D,oBAAoB;AAAA,MAClB,KAAK;AAAA,MACL;AAAA,IACF;AAAA,IACA,kBAAkB;AAAA,MAChB,KAAK;AAAA,MACL;AAAA,IACF;AAAA,IACA,UAAU,mBAAmB,KAAK,QAAQ;AAAA,IAC1C,mBAAmB,QAAQ,KAAK,qBAAqB,KAAK;AAAA,IAC1D,cAAc,OAAO,KAAK,gBAAgB,CAAC;AAAA,IAC3C,eAAe,mBAAmB,KAAK,aAAa;AAAA,IACpD,UAAU,mBAAmB,KAAK,QAAQ;AAAA,IAC1C,aAAa,mBAAmB,KAAK,WAAW;AAAA,IAChD,UAAU,cAAc,KAAK,QAAQ;AAAA,IACrC,iBAAiB,eAAe,KAAK,eAAe;AAAA,IACpD,gBAAgB,KAAK,mBAAmB,aAAa,aAAa;AAAA,IAClE,iBACE,KAAK,mBAAmB,OAAO,IAAI,oBAAoB,WAAW,IAAI,kBAAkB;AAAA;AAAA,IAE1F,cAAc,sBAAsB,KAAK,cAAc,IAAI,QAAQ;AAAA,IACnE,WAAW,KAAK,YACZ;AAAA,MACE,aAAa,IAAI,UAAU;AAAA,MAC3B,cAAc,IAAI,UAAU;AAAA,MAC5B,YAAY,IAAI,UAAU;AAAA,IAC5B,IACA;AAAA,IACJ,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,IACjD,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,EACnD;AACF;AAEA,SAAS,yBAAyB,KAA2C;AAC3E,MAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO;AAChC,SAAO,IAAI,IAAI,CAAC,OAAY;AAAA,IAC1B,OAAO,OAAO,GAAG,SAAS,CAAC;AAAA,IAC3B,QAAQ,OAAO,GAAG,UAAU,CAAC;AAAA,IAC7B,UAAU,OAAO,GAAG,YAAY,CAAC;AAAA,IACjC,KAAK,OAAO,GAAG,OAAO,CAAC;AAAA,IACvB,cAAe,eAAe,GAAG,YAAY,KAAyC;AAAA,IACtF,eAAe,GAAG,iBAAiB,OAAO,OAAO,OAAO,EAAE,aAAa;AAAA,IACvE,QAAQ,GAAG;AAAA,IACX,OAAO,mBAAmB,GAAG,KAAK;AAAA,EACpC,EAAE;AACJ;AAEA,SAAS,sBAAsB,KAAU,sBAA+D;AACtG,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO;AAC5C,SAAO;AAAA,IACL,MAAM,IAAI;AAAA,IACV,QAAQ,IAAI;AAAA,IACZ,OAAO,OAAO,IAAI,SAAS,CAAC;AAAA,IAC5B,SAAS,eAAe,IAAI,OAAO,KAAK;AAAA,IACxC,QAAQ,eAAe,IAAI,QAAQ,kCAAkC;AAAA,IACrE,SAAS,IAAI,WAAW;AAAA,IACxB,WAAW,mBAAmB,IAAI,SAAS;AAAA,IAC3C,QAAQ,IAAI,SACR;AAAA,MACE,eAAe,eAAe,IAAI,OAAO,aAAa;AAAA,MACtD,QAAQ,OAAO,IAAI,OAAO,UAAU,CAAC;AAAA,MACrC,UAAU,eAAe,IAAI,OAAO,QAAQ,KAAK;AAAA,MACjD,aAAa,eAAe,IAAI,OAAO,WAAW,KAAK;AAAA,IACzD,IACA;AAAA,EACN;AACF;AAEO,SAAS,mBAAmB,KAAiC;AAClE,SAAO;AAAA,IACL,IAAI,eAAe,KAAK,IAAI,cAAc;AAAA,IAC1C,gBAAgB,eAAe,KAAK,gBAAgB,0BAA0B;AAAA,IAC9E,MAAM,KAAK,QAAQ;AAAA,IACnB,WAAW,OAAO,KAAK,aAAa,CAAC;AAAA,IACrC,gBAAgB,OAAO,KAAK,kBAAkB,CAAC;AAAA,IAC/C,YAAY,OAAO,KAAK,cAAc,CAAC;AAAA,IACvC,aAAa,mBAAmB,KAAK,aAAa,uBAAuB;AAAA,IACzE,WAAW,mBAAmB,KAAK,WAAW,qBAAqB;AAAA,IACnE,WAAW,mBAAmB,KAAK,WAAW,qBAAqB;AAAA,EACrE;AACF;AAEO,SAAS,kBAAkB,KAA2B;AAC3D,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO;AAAA,IACL,IAAI,eAAe,KAAK,IAAI,aAAa;AAAA,IACzC,YAAY,eAAe,KAAK,UAAU;AAAA,IAC1C,OAAO,eAAe,KAAK,KAAK;AAAA,IAChC,WAAW,eAAe,KAAK,SAAS;AAAA,IACxC,UAAU,eAAe,KAAK,QAAQ;AAAA,IACtC,OAAO,eAAe,KAAK,KAAK;AAAA,IAChC,SAAS,eAAe,KAAK,OAAO;AAAA,IACpC,UAAU,cAAc,KAAK,QAAQ;AAAA,IACrC,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,IACjD,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,EACnD;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,UAAU;AAAA,IAC1C,WAAW,eAAe,KAAK,SAAS;AAAA,IACxC,cAAc,eAAe,KAAK,YAAY;AAAA,IAC9C,WAAW,QAAQ,KAAK,aAAa,KAAK;AAAA,IAC1C,UAAU,QAAQ,KAAK,YAAY,IAAI;AAAA,IACvC,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,IACjD,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,EACnD;AACF;AAEO,SAAS,yBAAyB,KAA2B;AAClE,QAAM,YAAY,KAAK,aAAa,KAAK;AACzC,SAAO;AAAA,IACL,GAAG,sBAAsB,GAAG;AAAA,IAC5B,IAAI,eAAe,KAAK,EAAE,KAAK;AAAA,IAC/B,WAAW,eAAe,WAAW,2BAA2B;AAAA,IAChE,aAAa,eAAe,KAAK,WAAW,KAAK;AAAA,IACjD,YAAY,eAAe,KAAK,UAAU,KAAK;AAAA,IAC/C,WAAW,mBAAmB,KAAK,SAAS,KAAK;AAAA,EACnD;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,KAAK;AAAA,EACvC;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;AASA,SAAS,sBAAsB,OAA+B;AAC5D,MAAI,iBAAiB,KAAM,QAAO,MAAM,YAAY;AACpD,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAAG;AACjD,UAAM,IAAI,IAAI,KAAK,KAAK;AACxB,WAAO,OAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,QAAQ,EAAE,YAAY;AAAA,EAC3D;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAyC;AAC9D,SAAO,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IAC5D,QACD,CAAC;AACP;AAEA,SAAS,sBAAsB,OAAyC;AACtE,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACzE,SAAO,OAAO;AAAA,IACZ,OAAO,QAAQ,KAAgC,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,SAAS,GAAG,CAAC;AAAA,EACvF;AACF;;;AClMO,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,UACrB,iBAAiB,IAAI;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,eAAe,MAAM;AAAA,MACrB;AAAA,MACA,eAAe,MAAM;AAAA,MACrB,UAAU,MAAM;AAAA,MAChB,UAAU,MAAM;AAAA,MAChB,cAAc,MAAM;AAAA,MACpB,eAAe,MAAM;AAAA,MACrB,eAAe,MAAM;AAAA,MACrB,QAAQ,MAAM;AAAA,MACd,iBAAiB,MAAM;AAAA,MACvB,UAAU,MAAM;AAAA,MAChB,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,MAC7B,SAAS,MAAM;AAAA,IACjB,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,eAAe,OAAO,WAAW;AACjD,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,MAAM,WAAW,OAA+C;AAC9D,UAAM,EAAE,IAAI,GAAG,KAAK,IAAI;AACxB,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C;AAAA,QACE,eAAe,KAAK;AAAA,QACpB,UAAU,KAAK;AAAA,QACf,UAAU,KAAK;AAAA,QACf,cAAc,KAAK;AAAA,QACnB,eAAe,KAAK;AAAA,QACpB,QAAQ,KAAK;AAAA,QACb,iBAAiB,KAAK;AAAA,QACtB,WAAW,KAAK;AAAA,MAClB;AAAA,IACF;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,eAAe,IAAY,OAAmD;AAClF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C,EAAE,UAAU,MAAM,UAAU,WAAW,MAAM,UAAU;AAAA,IACzD;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,YAAY,IAAmC;AACnD,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,IACjD;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,IAAY,OAAgD;AAC5E,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C,EAAE,QAAQ,MAAM,OAAO;AAAA,IACzB;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBAAiB,IAAY,iBAAgD;AACjF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C,EAAE,gBAAgB;AAAA,IACpB;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,IAAY,OAAyD;AACrF,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C,EAAE,MAAM,MAAM,MAAM,WAAW,MAAM,WAAW,gBAAgB,MAAM,eAAe;AAAA,IACvF;AACA,WAAO,mBAAmB,IAAI;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAU,IAA8C;AAC5D,UAAM,WAAW,MAAM,KAAK;AAAA,MAC1B;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,IACjD;AAIA,UAAM,QAAS,SAA8C,SAAS,CAAC;AACvE,WAAO,MAAM,IAAI,kBAAkB;AAAA,EACrC;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,OACJ,IACA,QAAgF,CAAC,GAC1D;AACvB,UAAM,OAAO,MAAM,KAAK;AAAA,MACtB;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC;AAAA,MAC/C,EAAE,aAAa,MAAM,eAAe,OAAO,QAAQ,MAAM,UAAU,OAAO;AAAA,IAC5E;AACA,WAAO,sBAAsB,IAAI;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,cACJ,IACA,WACA,OACoC;AACpC,WAAO,KAAK;AAAA,MACV;AAAA,MACA,yBAAyB,mBAAmB,EAAE,CAAC,aAAa,mBAAmB,SAAS,CAAC;AAAA,MACzF;AAAA,IACF;AAAA,EACF;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,iBAAiB,MAAM;AAAA,IACzB,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;","names":["ThrottleError"]}
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
+ import { CurrencyCode } from '@usethrottle/money';
2
3
  import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
3
4
 
4
5
  type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing' | 'unpaid' | 'completed';
@@ -42,7 +43,7 @@ interface Subscription {
42
43
  amount: number;
43
44
  /** #688 — number of seats. Per-seat price is `amount`; the period charge is `amount × quantity`. Defaults to 1. */
44
45
  quantity: number;
45
- currency: string;
46
+ currency: CurrencyCode;
46
47
  currentPeriodStart: string;
47
48
  currentPeriodEnd: string;
48
49
  trialEnd?: string | null;
@@ -60,6 +61,13 @@ interface Subscription {
60
61
  taxAddressSnapshot?: SubscriptionTaxAddress | null;
61
62
  /** `checkout` when captured at signup, `manual` once a merchant edited it. */
62
63
  taxAddressSource?: 'checkout' | 'manual' | null;
64
+ /**
65
+ * `shipment` = a physical subscription: every renewal creates an order that
66
+ * owes a box and ships to `shippingAddress`. `access_grant` = nothing ships.
67
+ */
68
+ deliveryMethod?: SubscriptionDeliveryMethod;
69
+ /** Where a physical subscription ships; null when nothing ships. */
70
+ shippingAddress?: SubscriptionShippingAddress | null;
63
71
  /**
64
72
  * The saved card this subscription renews on (the card used at checkout);
65
73
  * null = the customer's default card. A charge that cannot use it falls back
@@ -93,7 +101,8 @@ interface SubscriptionRenewalIssue {
93
101
  charge?: {
94
102
  transactionId: string | null;
95
103
  amount: number;
96
- currency: string;
104
+ /** The subscription's currency when the API did not name one. */
105
+ currency: CurrencyCode;
97
106
  periodStart?: string;
98
107
  } | null;
99
108
  }
@@ -110,6 +119,14 @@ interface SubscriptionTaxAddress {
110
119
  postalCode?: string | null;
111
120
  countryCode?: string | null;
112
121
  }
122
+ type SubscriptionDeliveryMethod = 'access_grant' | 'shipment';
123
+ /** A physical subscription's ship-to. `addressLine1`, `city` and `countryCode` are required on write. */
124
+ interface SubscriptionShippingAddress extends SubscriptionTaxAddress {
125
+ firstName?: string | null;
126
+ lastName?: string | null;
127
+ company?: string | null;
128
+ phone?: string | null;
129
+ }
113
130
  interface Customer {
114
131
  id: string;
115
132
  externalId?: string | null;
@@ -202,6 +219,9 @@ interface CreateSubscriptionInput {
202
219
  * stamped by Throttle and need nothing here.
203
220
  */
204
221
  orderId?: string;
222
+ /** `shipment` makes a physical subscription; `shippingAddress` is then required. */
223
+ deliveryMethod?: SubscriptionDeliveryMethod;
224
+ shippingAddress?: SubscriptionShippingAddress;
205
225
  }
206
226
  interface UpdateSubscriptionInput {
207
227
  planReference?: string;
@@ -216,6 +236,11 @@ interface UpdateSubscriptionInput {
216
236
  * `400 invalid_amount`. Applies to this request only; it is not stored.
217
237
  */
218
238
  allowZeroAmount?: boolean;
239
+ /**
240
+ * Where a physical subscription ships, from the next renewal. A subscription
241
+ * that does not ship answers `422 subscription_not_physical`.
242
+ */
243
+ shippingAddress?: SubscriptionShippingAddress;
219
244
  metadata?: Record<string, unknown>;
220
245
  }
221
246
  interface CancelSubscriptionInput {
@@ -553,4 +578,4 @@ declare class ThrottleSubscriptionsError extends ThrottleError {
553
578
  });
554
579
  }
555
580
 
556
- 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 };
581
+ export { type SubscriptionUsageItem as A, SubscriptionsClient as B, type CancelSubscriptionInput as C, type DunningBannerProps as D, type SubscriptionsClientContract as E, type SubscriptionsClientOptions as F, ThrottleSubscriptionsError as G, type TrialCountdownProps as H, type TrialEligibilityInput as I, type TrialEligibilityReason as J, type TrialEligibilityResult as K, type ListSubscriptionsParams as L, type MutationState as M, createSubscriptionsClient as N, 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 SubscriptionDeliveryMethod as m, type SubscriptionFetcher as n, type SubscriptionInterval as o, type SubscriptionIntervalUnit as p, type SubscriptionInvoiceRefund as q, type SubscriptionPaymentScheduleRow as r, type SubscriptionProration as s, type SubscriptionProviderProps as t, type SubscriptionRenewalIssue as u, type SubscriptionShippingAddress as v, type SubscriptionSort as w, type SubscriptionStatus as x, type SubscriptionStatusBadgeProps as y, type SubscriptionTaxAddress as z };
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
+ import { CurrencyCode } from '@usethrottle/money';
2
3
  import { ThrottleError, ThrottleErrorArgs } from '@usethrottle/errors';
3
4
 
4
5
  type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing' | 'unpaid' | 'completed';
@@ -42,7 +43,7 @@ interface Subscription {
42
43
  amount: number;
43
44
  /** #688 — number of seats. Per-seat price is `amount`; the period charge is `amount × quantity`. Defaults to 1. */
44
45
  quantity: number;
45
- currency: string;
46
+ currency: CurrencyCode;
46
47
  currentPeriodStart: string;
47
48
  currentPeriodEnd: string;
48
49
  trialEnd?: string | null;
@@ -60,6 +61,13 @@ interface Subscription {
60
61
  taxAddressSnapshot?: SubscriptionTaxAddress | null;
61
62
  /** `checkout` when captured at signup, `manual` once a merchant edited it. */
62
63
  taxAddressSource?: 'checkout' | 'manual' | null;
64
+ /**
65
+ * `shipment` = a physical subscription: every renewal creates an order that
66
+ * owes a box and ships to `shippingAddress`. `access_grant` = nothing ships.
67
+ */
68
+ deliveryMethod?: SubscriptionDeliveryMethod;
69
+ /** Where a physical subscription ships; null when nothing ships. */
70
+ shippingAddress?: SubscriptionShippingAddress | null;
63
71
  /**
64
72
  * The saved card this subscription renews on (the card used at checkout);
65
73
  * null = the customer's default card. A charge that cannot use it falls back
@@ -93,7 +101,8 @@ interface SubscriptionRenewalIssue {
93
101
  charge?: {
94
102
  transactionId: string | null;
95
103
  amount: number;
96
- currency: string;
104
+ /** The subscription's currency when the API did not name one. */
105
+ currency: CurrencyCode;
97
106
  periodStart?: string;
98
107
  } | null;
99
108
  }
@@ -110,6 +119,14 @@ interface SubscriptionTaxAddress {
110
119
  postalCode?: string | null;
111
120
  countryCode?: string | null;
112
121
  }
122
+ type SubscriptionDeliveryMethod = 'access_grant' | 'shipment';
123
+ /** A physical subscription's ship-to. `addressLine1`, `city` and `countryCode` are required on write. */
124
+ interface SubscriptionShippingAddress extends SubscriptionTaxAddress {
125
+ firstName?: string | null;
126
+ lastName?: string | null;
127
+ company?: string | null;
128
+ phone?: string | null;
129
+ }
113
130
  interface Customer {
114
131
  id: string;
115
132
  externalId?: string | null;
@@ -202,6 +219,9 @@ interface CreateSubscriptionInput {
202
219
  * stamped by Throttle and need nothing here.
203
220
  */
204
221
  orderId?: string;
222
+ /** `shipment` makes a physical subscription; `shippingAddress` is then required. */
223
+ deliveryMethod?: SubscriptionDeliveryMethod;
224
+ shippingAddress?: SubscriptionShippingAddress;
205
225
  }
206
226
  interface UpdateSubscriptionInput {
207
227
  planReference?: string;
@@ -216,6 +236,11 @@ interface UpdateSubscriptionInput {
216
236
  * `400 invalid_amount`. Applies to this request only; it is not stored.
217
237
  */
218
238
  allowZeroAmount?: boolean;
239
+ /**
240
+ * Where a physical subscription ships, from the next renewal. A subscription
241
+ * that does not ship answers `422 subscription_not_physical`.
242
+ */
243
+ shippingAddress?: SubscriptionShippingAddress;
219
244
  metadata?: Record<string, unknown>;
220
245
  }
221
246
  interface CancelSubscriptionInput {
@@ -553,4 +578,4 @@ declare class ThrottleSubscriptionsError extends ThrottleError {
553
578
  });
554
579
  }
555
580
 
556
- 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 };
581
+ export { type SubscriptionUsageItem as A, SubscriptionsClient as B, type CancelSubscriptionInput as C, type DunningBannerProps as D, type SubscriptionsClientContract as E, type SubscriptionsClientOptions as F, ThrottleSubscriptionsError as G, type TrialCountdownProps as H, type TrialEligibilityInput as I, type TrialEligibilityReason as J, type TrialEligibilityResult as K, type ListSubscriptionsParams as L, type MutationState as M, createSubscriptionsClient as N, 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 SubscriptionDeliveryMethod as m, type SubscriptionFetcher as n, type SubscriptionInterval as o, type SubscriptionIntervalUnit as p, type SubscriptionInvoiceRefund as q, type SubscriptionPaymentScheduleRow as r, type SubscriptionProration as s, type SubscriptionProviderProps as t, type SubscriptionRenewalIssue as u, type SubscriptionShippingAddress as v, type SubscriptionSort as w, type SubscriptionStatus as x, type SubscriptionStatusBadgeProps as y, type SubscriptionTaxAddress as z };
package/dist/index.cjs CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,11 +17,20 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.tsx
21
31
  var index_exports = {};
22
32
  __export(index_exports, {
33
+ CURRENCIES: () => import_money.CURRENCIES,
23
34
  DunningBanner: () => DunningBanner,
24
35
  SubscriptionProvider: () => SubscriptionProvider,
25
36
  SubscriptionProviderWithClient: () => SubscriptionProviderWithClient,
@@ -28,6 +39,7 @@ __export(index_exports, {
28
39
  ThrottleError: () => import_errors2.ThrottleError,
29
40
  ThrottleSubscriptionsError: () => ThrottleSubscriptionsError,
30
41
  TrialCountdown: () => TrialCountdown,
42
+ UnknownCurrencyError: () => import_money.UnknownCurrencyError,
31
43
  cadenceLabel: () => cadenceLabel2,
32
44
  cadenceNoun: () => cadenceNoun2,
33
45
  canCancelSubscription: () => canCancelSubscription,
@@ -35,12 +47,21 @@ __export(index_exports, {
35
47
  canResumeSubscription: () => canResumeSubscription,
36
48
  createSubscriptionFetcher: () => createSubscriptionFetcher,
37
49
  createSubscriptionsClient: () => createSubscriptionsClient,
50
+ currencySymbol: () => import_money.currencySymbol,
38
51
  daysUntil: () => daysUntil,
52
+ formatMoney: () => import_money.formatMoney,
39
53
  installmentProgress: () => installmentProgress2,
54
+ isKnownCurrency: () => import_money.isKnownCurrency,
40
55
  isSubscriptionPastDue: () => isSubscriptionPastDue,
41
56
  isSubscriptionTrialing: () => isSubscriptionTrialing,
42
57
  isTerminalSubscription: () => isTerminalSubscription,
43
58
  isThrottleError: () => import_errors2.isThrottleError,
59
+ minorUnitsOf: () => import_money.minorUnitsOf,
60
+ money: () => money,
61
+ moneyValue: () => import_money.moneyValue,
62
+ parseMoney: () => import_money.parseMoney,
63
+ toDecimalString: () => import_money.toDecimalString,
64
+ toMinor: () => import_money.toMinor,
44
65
  useCancelSubscription: () => useCancelSubscription,
45
66
  useChangePlan: () => useChangePlan,
46
67
  useCreateCheckoutSession: () => useCreateCheckoutSession,
@@ -89,7 +110,8 @@ function normalizeSubscription(raw) {
89
110
  nextPaymentAmount: raw?.nextPaymentAmount == null ? null : Number(raw.nextPaymentAmount),
90
111
  amount: Number(raw?.amount ?? 0),
91
112
  quantity: Number(raw?.quantity ?? 1),
92
- currency: optionalString(raw?.currency) ?? "USD",
113
+ // No USD fallback (MC2-R35): a subscription without a currency is a broken response.
114
+ currency: requiredString(raw?.currency, "subscription.currency"),
93
115
  currentPeriodStart: requiredDateString(
94
116
  raw?.currentPeriodStart,
95
117
  "subscription.currentPeriodStart"
@@ -106,7 +128,10 @@ function normalizeSubscription(raw) {
106
128
  cancelledAt: optionalDateString(raw?.cancelledAt),
107
129
  metadata: objectOrEmpty(raw?.metadata),
108
130
  paymentMethodId: optionalString(raw?.paymentMethodId),
109
- renewalIssue: normalizeRenewalIssue(raw?.renewalIssue),
131
+ deliveryMethod: raw?.deliveryMethod === "shipment" ? "shipment" : "access_grant",
132
+ shippingAddress: raw?.shippingAddress && typeof raw.shippingAddress === "object" ? raw.shippingAddress : null,
133
+ // `currency` above has already been checked.
134
+ renewalIssue: normalizeRenewalIssue(raw?.renewalIssue, raw.currency),
110
135
  proration: raw?.proration ? {
111
136
  creditCents: raw.proration.creditCents,
112
137
  chargedCents: raw.proration.chargedCents,
@@ -129,7 +154,7 @@ function normalizePaymentSchedule(raw) {
129
154
  dueAt: optionalDateString(r?.dueAt)
130
155
  }));
131
156
  }
132
- function normalizeRenewalIssue(raw) {
157
+ function normalizeRenewalIssue(raw, subscriptionCurrency) {
133
158
  if (!raw || typeof raw !== "object") return null;
134
159
  return {
135
160
  kind: raw.kind,
@@ -142,7 +167,7 @@ function normalizeRenewalIssue(raw) {
142
167
  charge: raw.charge ? {
143
168
  transactionId: optionalString(raw.charge.transactionId),
144
169
  amount: Number(raw.charge.amount ?? 0),
145
- currency: optionalString(raw.charge.currency) ?? "USD",
170
+ currency: optionalString(raw.charge.currency) || subscriptionCurrency,
146
171
  periodStart: optionalString(raw.charge.periodStart) ?? void 0
147
172
  } : null
148
173
  };
@@ -1003,8 +1028,13 @@ function DunningBanner({
1003
1028
  }
1004
1029
  );
1005
1030
  }
1031
+
1032
+ // src/index.tsx
1033
+ var money = __toESM(require("@usethrottle/money"), 1);
1034
+ var import_money = require("@usethrottle/money");
1006
1035
  // Annotate the CommonJS export names for ESM import in node:
1007
1036
  0 && (module.exports = {
1037
+ CURRENCIES,
1008
1038
  DunningBanner,
1009
1039
  SubscriptionProvider,
1010
1040
  SubscriptionProviderWithClient,
@@ -1013,6 +1043,7 @@ function DunningBanner({
1013
1043
  ThrottleError,
1014
1044
  ThrottleSubscriptionsError,
1015
1045
  TrialCountdown,
1046
+ UnknownCurrencyError,
1016
1047
  cadenceLabel,
1017
1048
  cadenceNoun,
1018
1049
  canCancelSubscription,
@@ -1020,12 +1051,21 @@ function DunningBanner({
1020
1051
  canResumeSubscription,
1021
1052
  createSubscriptionFetcher,
1022
1053
  createSubscriptionsClient,
1054
+ currencySymbol,
1023
1055
  daysUntil,
1056
+ formatMoney,
1024
1057
  installmentProgress,
1058
+ isKnownCurrency,
1025
1059
  isSubscriptionPastDue,
1026
1060
  isSubscriptionTrialing,
1027
1061
  isTerminalSubscription,
1028
1062
  isThrottleError,
1063
+ minorUnitsOf,
1064
+ money,
1065
+ moneyValue,
1066
+ parseMoney,
1067
+ toDecimalString,
1068
+ toMinor,
1029
1069
  useCancelSubscription,
1030
1070
  useChangePlan,
1031
1071
  useCreateCheckoutSession,