@usethrottle/subscriptions 1.0.4 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CLAUDE.md CHANGED
@@ -38,6 +38,13 @@ Direct customer-scoped browser tokens are intentionally not in v1 because the AP
38
38
  - Mutations invalidate provider queries by bumping the provider cache version. Avoid adding a heavy query dependency unless product needs become more complex.
39
39
  - Components are primitive and minimally styled. They accept `className` and `style` so merchants can bring their own design system.
40
40
 
41
+ ## Errors
42
+
43
+ `ThrottleSubscriptionsError` extends the shared `ThrottleError` from
44
+ `@usethrottle/errors` (a `dependency`, `workspace:^`); the package re-exports
45
+ `ThrottleError` + `isThrottleError`. Keep it a subclass so a single
46
+ `instanceof ThrottleError` catches errors from every Throttle SDK.
47
+
41
48
  ## Validation
42
49
 
43
50
  - `pnpm --filter @usethrottle/subscriptions typecheck`
package/README.md CHANGED
@@ -1,3 +1,8 @@
1
+ <p align="left">
2
+ <img src="https://raw.githubusercontent.com/Epic-Design-Labs/app-throttle/main/packages/brand/assets/throttle-logo.png" alt="Throttle" height="56" />
3
+ </p>
4
+
5
+
1
6
  # @usethrottle/subscriptions
2
7
 
3
8
  Production React hooks, server proxy helpers, and primitive components for Throttle subscriptions.
@@ -1,14 +1,10 @@
1
1
  // src/errors.ts
2
- var ThrottleSubscriptionsError = class extends Error {
3
- code;
4
- statusCode;
5
- details;
2
+ import { ThrottleError } from "@usethrottle/errors";
3
+ import { ThrottleError as ThrottleError2, isThrottleError } from "@usethrottle/errors";
4
+ var ThrottleSubscriptionsError = class extends ThrottleError {
6
5
  constructor(args) {
7
- super(args.message);
6
+ super(args);
8
7
  this.name = "ThrottleSubscriptionsError";
9
- this.code = args.code;
10
- this.statusCode = args.statusCode;
11
- this.details = args.details;
12
8
  }
13
9
  };
14
10
 
@@ -16,72 +12,70 @@ var ThrottleSubscriptionsError = class extends Error {
16
12
  function normalizeSubscription(raw) {
17
13
  return {
18
14
  id: requiredString(raw?.id, "subscription.id"),
19
- workspaceId: optionalString(raw?.workspaceId ?? raw?.merchant_id),
20
- applicationId: optionalString(raw?.applicationId ?? raw?.store_id),
21
- customerId: requiredString(raw?.customerId ?? raw?.customer_id, "subscription.customerId"),
15
+ workspaceId: optionalString(raw?.workspaceId),
16
+ applicationId: optionalString(raw?.applicationId),
17
+ customerId: requiredString(raw?.customerId, "subscription.customerId"),
22
18
  status: raw?.status ?? "active",
23
- planReference: requiredString(
24
- raw?.planReference ?? raw?.plan_reference,
25
- "subscription.planReference"
26
- ),
27
- planName: optionalString(raw?.planName ?? raw?.plan_name),
19
+ planReference: requiredString(raw?.planReference, "subscription.planReference"),
20
+ planName: optionalString(raw?.planName),
28
21
  interval: raw?.interval ?? "monthly",
29
22
  amount: Number(raw?.amount ?? 0),
30
23
  currency: optionalString(raw?.currency) ?? "USD",
31
24
  currentPeriodStart: requiredDateString(
32
- raw?.currentPeriodStart ?? raw?.current_period_start,
25
+ raw?.currentPeriodStart,
33
26
  "subscription.currentPeriodStart"
34
27
  ),
35
28
  currentPeriodEnd: requiredDateString(
36
- raw?.currentPeriodEnd ?? raw?.current_period_end,
29
+ raw?.currentPeriodEnd,
37
30
  "subscription.currentPeriodEnd"
38
31
  ),
39
- trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),
40
- cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),
41
- failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),
42
- lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),
43
- pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),
44
- cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),
32
+ trialEnd: optionalDateString(raw?.trialEnd),
33
+ cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? false),
34
+ failureCount: Number(raw?.failureCount ?? 0),
35
+ lastPaymentAt: optionalDateString(raw?.lastPaymentAt),
36
+ pausedAt: optionalDateString(raw?.pausedAt),
37
+ cancelledAt: optionalDateString(raw?.cancelledAt),
45
38
  metadata: objectOrEmpty(raw?.metadata),
46
- createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
47
- updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
39
+ createdAt: optionalDateString(raw?.createdAt) ?? void 0,
40
+ updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
48
41
  };
49
42
  }
50
43
  function normalizeCustomer(raw) {
51
44
  if (!raw) return null;
52
45
  return {
53
46
  id: requiredString(raw?.id, "customer.id"),
54
- externalId: optionalString(raw?.externalId ?? raw?.external_id),
47
+ externalId: optionalString(raw?.externalId),
55
48
  email: optionalString(raw?.email),
56
- firstName: optionalString(raw?.firstName ?? raw?.first_name),
57
- lastName: optionalString(raw?.lastName ?? raw?.last_name),
49
+ firstName: optionalString(raw?.firstName),
50
+ lastName: optionalString(raw?.lastName),
58
51
  phone: optionalString(raw?.phone),
59
52
  metadata: objectOrEmpty(raw?.metadata),
60
- createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
61
- updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
53
+ createdAt: optionalDateString(raw?.createdAt) ?? void 0,
54
+ updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
62
55
  };
63
56
  }
64
57
  function normalizeCustomerPaymentMethod(raw) {
65
58
  return {
66
59
  id: requiredString(raw?.id, "paymentMethod.id"),
67
60
  processor: optionalString(raw?.processor),
68
- methodType: optionalString(raw?.methodType ?? raw?.method_type),
69
- cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),
70
- cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),
71
- isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),
72
- createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
73
- updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
61
+ methodType: optionalString(raw?.methodType),
62
+ cardBrand: optionalString(raw?.cardBrand),
63
+ cardLastFour: optionalString(raw?.cardLastFour),
64
+ isDefault: Boolean(raw?.isDefault ?? false),
65
+ isActive: Boolean(raw?.isActive ?? true),
66
+ createdAt: optionalDateString(raw?.createdAt) ?? void 0,
67
+ updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
74
68
  };
75
69
  }
76
70
  function normalizeCheckoutSession(raw) {
77
- const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
71
+ const sessionId = raw?.sessionId ?? raw?.id;
78
72
  return {
79
- ...raw,
80
- id: optionalString(raw?.id),
73
+ ...withoutUnderscoreKeys(raw),
74
+ id: optionalString(raw?.id) ?? void 0,
81
75
  sessionId: requiredString(sessionId, "checkoutSession.sessionId"),
82
- checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),
83
- embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),
84
- expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? void 0
76
+ checkoutUrl: optionalString(raw?.checkoutUrl) ?? void 0,
77
+ embedToken: optionalString(raw?.embedToken) ?? void 0,
78
+ expiresAt: optionalDateString(raw?.expiresAt) ?? void 0
85
79
  };
86
80
  }
87
81
  function normalizeTrialEligibility(raw) {
@@ -94,7 +88,7 @@ function normalizePagination(raw) {
94
88
  if (!raw) return void 0;
95
89
  return {
96
90
  cursor: raw.cursor ?? null,
97
- hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false)
91
+ hasMore: Boolean(raw.hasMore ?? false)
98
92
  };
99
93
  }
100
94
  function toIso(value) {
@@ -121,6 +115,12 @@ function optionalDateString(value) {
121
115
  function objectOrEmpty(value) {
122
116
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
123
117
  }
118
+ function withoutUnderscoreKeys(value) {
119
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
120
+ return Object.fromEntries(
121
+ Object.entries(value).filter(([key]) => !key.includes("_"))
122
+ );
123
+ }
124
124
 
125
125
  // src/client.ts
126
126
  var SubscriptionsClient = class {
@@ -260,7 +260,7 @@ var SubscriptionsClient = class {
260
260
  }
261
261
  async checkTrialEligibility(input) {
262
262
  const data = await this.request("POST", "/api/v1/subscriptions/eligibility-check", {
263
- payment_method_id: input.paymentMethodId
263
+ paymentMethodId: input.paymentMethodId
264
264
  });
265
265
  return normalizeTrialEligibility(data);
266
266
  }
@@ -317,7 +317,9 @@ function setQuery(query, key, value) {
317
317
 
318
318
  export {
319
319
  ThrottleSubscriptionsError,
320
+ ThrottleError2 as ThrottleError,
321
+ isThrottleError,
320
322
  SubscriptionsClient,
321
323
  createSubscriptionsClient
322
324
  };
323
- //# sourceMappingURL=chunk-YNHK6SPQ.js.map
325
+ //# sourceMappingURL=chunk-SVK2EVJ4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/normalize.ts","../src/client.ts"],"sourcesContent":["import { ThrottleError } 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: { code: string; message: string; statusCode: number; details?: unknown }) {\n super(args);\n this.name = 'ThrottleSubscriptionsError';\n }\n}\n\nexport { ThrottleError, isThrottleError } from '@usethrottle/errors';\n","import type {\n CheckoutSession,\n Customer,\n CustomerPaymentMethod,\n Pagination,\n Subscription,\n SubscriptionInterval,\n SubscriptionStatus,\n TrialEligibilityResult,\n} from './types';\n\nexport function normalizeSubscription(raw: any): Subscription {\n return {\n id: requiredString(raw?.id, 'subscription.id'),\n workspaceId: optionalString(raw?.workspaceId),\n applicationId: optionalString(raw?.applicationId),\n customerId: requiredString(raw?.customerId, 'subscription.customerId'),\n status: (raw?.status ?? 'active') as SubscriptionStatus,\n planReference: requiredString(raw?.planReference, 'subscription.planReference'),\n planName: optionalString(raw?.planName),\n interval: (raw?.interval ?? 'monthly') as SubscriptionInterval,\n amount: Number(raw?.amount ?? 0),\n currency: optionalString(raw?.currency) ?? 'USD',\n currentPeriodStart: requiredDateString(\n raw?.currentPeriodStart,\n 'subscription.currentPeriodStart',\n ),\n currentPeriodEnd: requiredDateString(\n raw?.currentPeriodEnd,\n 'subscription.currentPeriodEnd',\n ),\n trialEnd: optionalDateString(raw?.trialEnd),\n cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? false),\n failureCount: Number(raw?.failureCount ?? 0),\n lastPaymentAt: optionalDateString(raw?.lastPaymentAt),\n pausedAt: optionalDateString(raw?.pausedAt),\n cancelledAt: optionalDateString(raw?.cancelledAt),\n metadata: objectOrEmpty(raw?.metadata),\n createdAt: optionalDateString(raw?.createdAt) ?? undefined,\n updatedAt: optionalDateString(raw?.updatedAt) ?? undefined,\n };\n}\n\nexport function normalizeCustomer(raw: any): Customer | null {\n if (!raw) return null;\n return {\n id: requiredString(raw?.id, 'customer.id'),\n externalId: optionalString(raw?.externalId),\n email: optionalString(raw?.email),\n firstName: optionalString(raw?.firstName),\n lastName: optionalString(raw?.lastName),\n phone: optionalString(raw?.phone),\n 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\nfunction objectOrEmpty(value: unknown): Record<string, unknown> {\n return value && typeof value === 'object' && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : {};\n}\n\nfunction withoutUnderscoreKeys(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {};\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).filter(([key]) => !key.includes('_')),\n );\n}\n","import { ThrottleSubscriptionsError } from './errors';\nimport {\n normalizeCheckoutSession,\n normalizeCustomer,\n normalizeCustomerPaymentMethod,\n normalizePagination,\n normalizeSubscription,\n normalizeTrialEligibility,\n toIso,\n} from './normalize';\nimport type {\n ChangePlanInput,\n CheckoutSession,\n CreateCheckoutSessionInput,\n CreateSubscriptionInput,\n Customer,\n CustomerPaymentMethod,\n ListSubscriptionsParams,\n PaginatedSubscriptions,\n Subscription,\n SubscriptionsClientContract,\n SubscriptionsClientOptions,\n ThrottleEnvelope,\n TrialEligibilityInput,\n TrialEligibilityResult,\n UpdateSubscriptionInput,\n} from './types';\n\nexport class SubscriptionsClient implements SubscriptionsClientContract {\n private readonly apiKey?: string;\n private readonly baseUrl: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n private readonly fetcher?: SubscriptionsClientOptions['fetcher'];\n private readonly timeoutMs: number;\n\n constructor(opts: SubscriptionsClientOptions = {}) {\n const fetchImpl = opts.fetch ?? globalThis.fetch;\n if (!fetchImpl) throw new Error('SubscriptionsClient: fetch is required');\n if (!opts.apiKey && !opts.fetcher) {\n throw new Error('SubscriptionsClient: apiKey or fetcher is required');\n }\n\n this.apiKey = opts.apiKey;\n this.baseUrl = (opts.baseUrl ?? 'https://api.usethrottle.dev').replace(/\\/+$/, '');\n this.fetchImpl = fetchImpl;\n this.fetcher = opts.fetcher;\n this.timeoutMs = opts.timeoutMs ?? 30_000;\n }\n\n async request<T = unknown>(method: string, path: string, body?: unknown): Promise<T> {\n const envelope = await this.requestEnvelope<T>(method, path, body);\n if (Object.prototype.hasOwnProperty.call(envelope, 'data')) {\n return envelope.data as T;\n }\n return envelope as T;\n }\n\n async requestEnvelope<T = unknown>(\n method: string,\n path: string,\n body?: unknown,\n ): Promise<ThrottleEnvelope<T>> {\n const ctrl = new AbortController();\n const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);\n\n try {\n const init: RequestInit = {\n method,\n headers: {\n 'content-type': 'application/json',\n ...(this.apiKey ? { 'x-api-key': this.apiKey } : {}),\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n signal: ctrl.signal,\n };\n\n const res = this.fetcher\n ? await this.fetcher(path, init)\n : await this.fetchImpl(toAbsoluteUrl(this.baseUrl, path), init);\n\n if (res.status === 204) return { data: undefined as T };\n\n const json = (await res.json().catch(() => ({}))) as ThrottleEnvelope<T>;\n if (!res.ok) {\n throw new ThrottleSubscriptionsError({\n code: json.error?.code ?? 'unknown_error',\n message: json.error?.message ?? `HTTP ${res.status}`,\n statusCode: res.status,\n details: json.error?.details,\n });\n }\n return json;\n } finally {\n clearTimeout(timer);\n }\n }\n\n async create(input: CreateSubscriptionInput): Promise<Subscription> {\n const customerId = await this.resolveCustomerId(input.customerId, input.externalCustomerId);\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions', {\n applicationId: input.applicationId,\n customerId,\n planReference: input.planReference,\n planName: input.planName,\n interval: input.interval,\n amount: input.amount,\n currency: input.currency,\n currentPeriodStart: toIso(input.currentPeriodStart),\n currentPeriodEnd: toIso(input.currentPeriodEnd),\n trialEnd: toIso(input.trialEnd),\n metadata: input.metadata ?? {},\n });\n return normalizeSubscription(data);\n }\n\n async list(params: ListSubscriptionsParams = {}): Promise<PaginatedSubscriptions> {\n const query = new URLSearchParams();\n setQuery(query, 'customerId', params.customerId);\n setQuery(query, 'externalCustomerId', params.externalCustomerId);\n setQuery(query, 'status', params.status);\n setQuery(query, 'interval', params.interval);\n setQuery(query, 'q', params.q);\n setQuery(query, 'cursor', params.cursor);\n setQuery(query, 'limit', params.limit);\n setQuery(query, 'sort', params.sort);\n setQuery(query, 'createdAfter', toIso(params.createdAfter));\n setQuery(query, 'createdBefore', toIso(params.createdBefore));\n\n const suffix = query.toString() ? `?${query}` : '';\n const envelope = await this.requestEnvelope<unknown[]>('GET', `/api/v1/subscriptions${suffix}`);\n return {\n data: (envelope.data ?? []).map(normalizeSubscription),\n pagination: normalizePagination(envelope.meta?.pagination),\n };\n }\n\n async get(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n );\n return normalizeSubscription(data);\n }\n\n async update(id: string, input: UpdateSubscriptionInput): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'PATCH',\n `/api/v1/subscriptions/${encodeURIComponent(id)}`,\n input,\n );\n return normalizeSubscription(data);\n }\n\n changePlan(input: ChangePlanInput): Promise<Subscription> {\n const { id, ...body } = input;\n return this.update(id, body);\n }\n\n async pause(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/pause`,\n );\n return normalizeSubscription(data);\n }\n\n async resume(id: string): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/resume`,\n );\n return normalizeSubscription(data);\n }\n\n async cancel(id: string, input: { atPeriodEnd?: boolean } = {}): Promise<Subscription> {\n const data = await this.request<unknown>(\n 'POST',\n `/api/v1/subscriptions/${encodeURIComponent(id)}/cancel`,\n { atPeriodEnd: input.atPeriodEnd ?? false },\n );\n return normalizeSubscription(data);\n }\n\n async createCheckoutSession(input: CreateCheckoutSessionInput): Promise<CheckoutSession> {\n const data = await this.request<unknown>('POST', '/api/v1/checkout/sessions', input);\n return normalizeCheckoutSession(data);\n }\n\n async checkTrialEligibility(input: TrialEligibilityInput): Promise<TrialEligibilityResult> {\n const data = await this.request<unknown>('POST', '/api/v1/subscriptions/eligibility-check', {\n paymentMethodId: input.paymentMethodId,\n });\n return normalizeTrialEligibility(data);\n }\n\n async getCustomerByExternalId(externalId: string): Promise<Customer | null> {\n try {\n const data = await this.request<unknown>(\n 'GET',\n `/api/v1/customers/by-external/${encodeURIComponent(externalId)}`,\n );\n return normalizeCustomer(data);\n } catch (err) {\n if (err instanceof ThrottleSubscriptionsError && err.statusCode === 404) return null;\n throw err;\n }\n }\n\n async listCustomerPaymentMethods(customerId: string): Promise<CustomerPaymentMethod[]> {\n const data = await this.request<unknown[]>(\n 'GET',\n `/api/v1/customers/${encodeURIComponent(customerId)}/payment-methods`,\n );\n return (data ?? []).map(normalizeCustomerPaymentMethod);\n }\n\n private async resolveCustomerId(\n customerId?: string,\n externalCustomerId?: string,\n ): Promise<string> {\n if (customerId) return customerId;\n if (!externalCustomerId) {\n throw new ThrottleSubscriptionsError({\n code: 'invalid_request',\n message: 'customerId or externalCustomerId is required',\n statusCode: 400,\n });\n }\n\n const customer = await this.getCustomerByExternalId(externalCustomerId);\n if (!customer) {\n throw new ThrottleSubscriptionsError({\n code: 'customer_not_found',\n message: 'Customer not found',\n statusCode: 404,\n });\n }\n return customer.id;\n }\n}\n\nexport function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient {\n return new SubscriptionsClient(opts);\n}\n\nfunction toAbsoluteUrl(baseUrl: string, path: string): string {\n if (/^https?:\\/\\//i.test(path)) return path;\n return `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;\n}\n\nfunction setQuery(query: URLSearchParams, key: string, value: unknown): void {\n if (value === undefined || value === null || value === '') return;\n query.set(key, String(value));\n}\n"],"mappings":"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","names":["ThrottleError"]}
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
+ import { ThrottleError } from '@usethrottle/errors';
2
3
 
3
4
  type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing';
4
5
  type SubscriptionInterval = 'weekly' | 'monthly' | 'quarterly' | 'yearly';
@@ -44,6 +45,7 @@ interface CustomerPaymentMethod {
44
45
  cardBrand?: string | null;
45
46
  cardLastFour?: string | null;
46
47
  isDefault?: boolean;
48
+ isActive?: boolean;
47
49
  createdAt?: string;
48
50
  updatedAt?: string;
49
51
  }
@@ -151,10 +153,9 @@ interface TrialEligibilityResult {
151
153
  interface ThrottleEnvelope<T> {
152
154
  data?: T;
153
155
  meta?: {
154
- request_id?: string;
156
+ requestId?: string;
155
157
  pagination?: {
156
158
  cursor?: string | null;
157
- has_more?: boolean;
158
159
  hasMore?: boolean;
159
160
  };
160
161
  [key: string]: unknown;
@@ -268,10 +269,14 @@ declare class SubscriptionsClient implements SubscriptionsClientContract {
268
269
  }
269
270
  declare function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient;
270
271
 
271
- declare class ThrottleSubscriptionsError extends Error {
272
- readonly code: string;
273
- readonly statusCode: number;
274
- readonly details?: unknown;
272
+ /**
273
+ * Thrown on a non-2xx response from the Throttle Subscriptions API.
274
+ *
275
+ * Extends the shared {@link ThrottleError} so a single
276
+ * `catch (e) { if (e instanceof ThrottleError) … }` covers errors from every
277
+ * Throttle SDK. `instanceof ThrottleSubscriptionsError` keeps working.
278
+ */
279
+ declare class ThrottleSubscriptionsError extends ThrottleError {
275
280
  constructor(args: {
276
281
  code: string;
277
282
  message: string;
@@ -1,4 +1,5 @@
1
1
  import { CSSProperties, ReactNode } from 'react';
2
+ import { ThrottleError } from '@usethrottle/errors';
2
3
 
3
4
  type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'past_due' | 'trialing';
4
5
  type SubscriptionInterval = 'weekly' | 'monthly' | 'quarterly' | 'yearly';
@@ -44,6 +45,7 @@ interface CustomerPaymentMethod {
44
45
  cardBrand?: string | null;
45
46
  cardLastFour?: string | null;
46
47
  isDefault?: boolean;
48
+ isActive?: boolean;
47
49
  createdAt?: string;
48
50
  updatedAt?: string;
49
51
  }
@@ -151,10 +153,9 @@ interface TrialEligibilityResult {
151
153
  interface ThrottleEnvelope<T> {
152
154
  data?: T;
153
155
  meta?: {
154
- request_id?: string;
156
+ requestId?: string;
155
157
  pagination?: {
156
158
  cursor?: string | null;
157
- has_more?: boolean;
158
159
  hasMore?: boolean;
159
160
  };
160
161
  [key: string]: unknown;
@@ -268,10 +269,14 @@ declare class SubscriptionsClient implements SubscriptionsClientContract {
268
269
  }
269
270
  declare function createSubscriptionsClient(opts: SubscriptionsClientOptions): SubscriptionsClient;
270
271
 
271
- declare class ThrottleSubscriptionsError extends Error {
272
- readonly code: string;
273
- readonly statusCode: number;
274
- readonly details?: unknown;
272
+ /**
273
+ * Thrown on a non-2xx response from the Throttle Subscriptions API.
274
+ *
275
+ * Extends the shared {@link ThrottleError} so a single
276
+ * `catch (e) { if (e instanceof ThrottleError) … }` covers errors from every
277
+ * Throttle SDK. `instanceof ThrottleSubscriptionsError` keeps working.
278
+ */
279
+ declare class ThrottleSubscriptionsError extends ThrottleError {
275
280
  constructor(args: {
276
281
  code: string;
277
282
  message: string;
package/dist/index.cjs CHANGED
@@ -25,6 +25,7 @@ __export(index_exports, {
25
25
  SubscriptionProviderWithClient: () => SubscriptionProviderWithClient,
26
26
  SubscriptionStatusBadge: () => SubscriptionStatusBadge,
27
27
  SubscriptionsClient: () => SubscriptionsClient,
28
+ ThrottleError: () => import_errors2.ThrottleError,
28
29
  ThrottleSubscriptionsError: () => ThrottleSubscriptionsError,
29
30
  TrialCountdown: () => TrialCountdown,
30
31
  canCancelSubscription: () => canCancelSubscription,
@@ -36,6 +37,7 @@ __export(index_exports, {
36
37
  isSubscriptionPastDue: () => isSubscriptionPastDue,
37
38
  isSubscriptionTrialing: () => isSubscriptionTrialing,
38
39
  isTerminalSubscription: () => isTerminalSubscription,
40
+ isThrottleError: () => import_errors2.isThrottleError,
39
41
  useCancelSubscription: () => useCancelSubscription,
40
42
  useChangePlan: () => useChangePlan,
41
43
  useCreateCheckoutSession: () => useCreateCheckoutSession,
@@ -54,16 +56,12 @@ __export(index_exports, {
54
56
  module.exports = __toCommonJS(index_exports);
55
57
 
56
58
  // src/errors.ts
57
- var ThrottleSubscriptionsError = class extends Error {
58
- code;
59
- statusCode;
60
- details;
59
+ var import_errors = require("@usethrottle/errors");
60
+ var import_errors2 = require("@usethrottle/errors");
61
+ var ThrottleSubscriptionsError = class extends import_errors.ThrottleError {
61
62
  constructor(args) {
62
- super(args.message);
63
+ super(args);
63
64
  this.name = "ThrottleSubscriptionsError";
64
- this.code = args.code;
65
- this.statusCode = args.statusCode;
66
- this.details = args.details;
67
65
  }
68
66
  };
69
67
 
@@ -71,72 +69,70 @@ var ThrottleSubscriptionsError = class extends Error {
71
69
  function normalizeSubscription(raw) {
72
70
  return {
73
71
  id: requiredString(raw?.id, "subscription.id"),
74
- workspaceId: optionalString(raw?.workspaceId ?? raw?.merchant_id),
75
- applicationId: optionalString(raw?.applicationId ?? raw?.store_id),
76
- customerId: requiredString(raw?.customerId ?? raw?.customer_id, "subscription.customerId"),
72
+ workspaceId: optionalString(raw?.workspaceId),
73
+ applicationId: optionalString(raw?.applicationId),
74
+ customerId: requiredString(raw?.customerId, "subscription.customerId"),
77
75
  status: raw?.status ?? "active",
78
- planReference: requiredString(
79
- raw?.planReference ?? raw?.plan_reference,
80
- "subscription.planReference"
81
- ),
82
- planName: optionalString(raw?.planName ?? raw?.plan_name),
76
+ planReference: requiredString(raw?.planReference, "subscription.planReference"),
77
+ planName: optionalString(raw?.planName),
83
78
  interval: raw?.interval ?? "monthly",
84
79
  amount: Number(raw?.amount ?? 0),
85
80
  currency: optionalString(raw?.currency) ?? "USD",
86
81
  currentPeriodStart: requiredDateString(
87
- raw?.currentPeriodStart ?? raw?.current_period_start,
82
+ raw?.currentPeriodStart,
88
83
  "subscription.currentPeriodStart"
89
84
  ),
90
85
  currentPeriodEnd: requiredDateString(
91
- raw?.currentPeriodEnd ?? raw?.current_period_end,
86
+ raw?.currentPeriodEnd,
92
87
  "subscription.currentPeriodEnd"
93
88
  ),
94
- trialEnd: optionalDateString(raw?.trialEnd ?? raw?.trial_end),
95
- cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? raw?.cancel_at_period_end ?? false),
96
- failureCount: Number(raw?.failureCount ?? raw?.failure_count ?? 0),
97
- lastPaymentAt: optionalDateString(raw?.lastPaymentAt ?? raw?.last_payment_at),
98
- pausedAt: optionalDateString(raw?.pausedAt ?? raw?.paused_at),
99
- cancelledAt: optionalDateString(raw?.cancelledAt ?? raw?.cancelled_at),
89
+ trialEnd: optionalDateString(raw?.trialEnd),
90
+ cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ?? false),
91
+ failureCount: Number(raw?.failureCount ?? 0),
92
+ lastPaymentAt: optionalDateString(raw?.lastPaymentAt),
93
+ pausedAt: optionalDateString(raw?.pausedAt),
94
+ cancelledAt: optionalDateString(raw?.cancelledAt),
100
95
  metadata: objectOrEmpty(raw?.metadata),
101
- createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
102
- updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
96
+ createdAt: optionalDateString(raw?.createdAt) ?? void 0,
97
+ updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
103
98
  };
104
99
  }
105
100
  function normalizeCustomer(raw) {
106
101
  if (!raw) return null;
107
102
  return {
108
103
  id: requiredString(raw?.id, "customer.id"),
109
- externalId: optionalString(raw?.externalId ?? raw?.external_id),
104
+ externalId: optionalString(raw?.externalId),
110
105
  email: optionalString(raw?.email),
111
- firstName: optionalString(raw?.firstName ?? raw?.first_name),
112
- lastName: optionalString(raw?.lastName ?? raw?.last_name),
106
+ firstName: optionalString(raw?.firstName),
107
+ lastName: optionalString(raw?.lastName),
113
108
  phone: optionalString(raw?.phone),
114
109
  metadata: objectOrEmpty(raw?.metadata),
115
- createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
116
- updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
110
+ createdAt: optionalDateString(raw?.createdAt) ?? void 0,
111
+ updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
117
112
  };
118
113
  }
119
114
  function normalizeCustomerPaymentMethod(raw) {
120
115
  return {
121
116
  id: requiredString(raw?.id, "paymentMethod.id"),
122
117
  processor: optionalString(raw?.processor),
123
- methodType: optionalString(raw?.methodType ?? raw?.method_type),
124
- cardBrand: optionalString(raw?.cardBrand ?? raw?.card_brand),
125
- cardLastFour: optionalString(raw?.cardLastFour ?? raw?.card_last_four),
126
- isDefault: Boolean(raw?.isDefault ?? raw?.is_default ?? false),
127
- createdAt: optionalDateString(raw?.createdAt ?? raw?.created_at) ?? void 0,
128
- updatedAt: optionalDateString(raw?.updatedAt ?? raw?.updated_at) ?? void 0
118
+ methodType: optionalString(raw?.methodType),
119
+ cardBrand: optionalString(raw?.cardBrand),
120
+ cardLastFour: optionalString(raw?.cardLastFour),
121
+ isDefault: Boolean(raw?.isDefault ?? false),
122
+ isActive: Boolean(raw?.isActive ?? true),
123
+ createdAt: optionalDateString(raw?.createdAt) ?? void 0,
124
+ updatedAt: optionalDateString(raw?.updatedAt) ?? void 0
129
125
  };
130
126
  }
131
127
  function normalizeCheckoutSession(raw) {
132
- const sessionId = raw?.sessionId ?? raw?.session_id ?? raw?.id;
128
+ const sessionId = raw?.sessionId ?? raw?.id;
133
129
  return {
134
- ...raw,
135
- id: optionalString(raw?.id),
130
+ ...withoutUnderscoreKeys(raw),
131
+ id: optionalString(raw?.id) ?? void 0,
136
132
  sessionId: requiredString(sessionId, "checkoutSession.sessionId"),
137
- checkoutUrl: optionalString(raw?.checkoutUrl ?? raw?.checkout_url),
138
- embedToken: optionalString(raw?.embedToken ?? raw?.embed_token),
139
- expiresAt: optionalDateString(raw?.expiresAt ?? raw?.expires_at) ?? void 0
133
+ checkoutUrl: optionalString(raw?.checkoutUrl) ?? void 0,
134
+ embedToken: optionalString(raw?.embedToken) ?? void 0,
135
+ expiresAt: optionalDateString(raw?.expiresAt) ?? void 0
140
136
  };
141
137
  }
142
138
  function normalizeTrialEligibility(raw) {
@@ -149,7 +145,7 @@ function normalizePagination(raw) {
149
145
  if (!raw) return void 0;
150
146
  return {
151
147
  cursor: raw.cursor ?? null,
152
- hasMore: Boolean(raw.hasMore ?? raw.has_more ?? false)
148
+ hasMore: Boolean(raw.hasMore ?? false)
153
149
  };
154
150
  }
155
151
  function toIso(value) {
@@ -176,6 +172,12 @@ function optionalDateString(value) {
176
172
  function objectOrEmpty(value) {
177
173
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
178
174
  }
175
+ function withoutUnderscoreKeys(value) {
176
+ if (!value || typeof value !== "object" || Array.isArray(value)) return {};
177
+ return Object.fromEntries(
178
+ Object.entries(value).filter(([key]) => !key.includes("_"))
179
+ );
180
+ }
179
181
 
180
182
  // src/client.ts
181
183
  var SubscriptionsClient = class {
@@ -315,7 +317,7 @@ var SubscriptionsClient = class {
315
317
  }
316
318
  async checkTrialEligibility(input) {
317
319
  const data = await this.request("POST", "/api/v1/subscriptions/eligibility-check", {
318
- payment_method_id: input.paymentMethodId
320
+ paymentMethodId: input.paymentMethodId
319
321
  });
320
322
  return normalizeTrialEligibility(data);
321
323
  }
@@ -740,6 +742,7 @@ function DunningBanner({
740
742
  SubscriptionProviderWithClient,
741
743
  SubscriptionStatusBadge,
742
744
  SubscriptionsClient,
745
+ ThrottleError,
743
746
  ThrottleSubscriptionsError,
744
747
  TrialCountdown,
745
748
  canCancelSubscription,
@@ -751,6 +754,7 @@ function DunningBanner({
751
754
  isSubscriptionPastDue,
752
755
  isSubscriptionTrialing,
753
756
  isTerminalSubscription,
757
+ isThrottleError,
754
758
  useCancelSubscription,
755
759
  useChangePlan,
756
760
  useCreateCheckoutSession,