@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 +7 -0
- package/README.md +5 -0
- package/dist/{chunk-YNHK6SPQ.js → chunk-SVK2EVJ4.js} +48 -46
- package/dist/chunk-SVK2EVJ4.js.map +1 -0
- package/dist/{errors-DPfsiLtM.d.cts → errors-BR8lr8_6.d.cts} +11 -6
- package/dist/{errors-DPfsiLtM.d.ts → errors-BR8lr8_6.d.ts} +11 -6
- package/dist/index.cjs +49 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +45 -49
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +3 -2
- package/dist/server.d.ts +3 -2
- package/dist/server.js +1 -5
- package/dist/server.js.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-YNHK6SPQ.js.map +0 -1
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
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
|
|
20
|
-
applicationId: optionalString(raw?.applicationId
|
|
21
|
-
customerId: requiredString(raw?.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
|
-
|
|
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
|
|
25
|
+
raw?.currentPeriodStart,
|
|
33
26
|
"subscription.currentPeriodStart"
|
|
34
27
|
),
|
|
35
28
|
currentPeriodEnd: requiredDateString(
|
|
36
|
-
raw?.currentPeriodEnd
|
|
29
|
+
raw?.currentPeriodEnd,
|
|
37
30
|
"subscription.currentPeriodEnd"
|
|
38
31
|
),
|
|
39
|
-
trialEnd: optionalDateString(raw?.trialEnd
|
|
40
|
-
cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ??
|
|
41
|
-
failureCount: Number(raw?.failureCount ??
|
|
42
|
-
lastPaymentAt: optionalDateString(raw?.lastPaymentAt
|
|
43
|
-
pausedAt: optionalDateString(raw?.pausedAt
|
|
44
|
-
cancelledAt: optionalDateString(raw?.cancelledAt
|
|
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
|
|
47
|
-
updatedAt: optionalDateString(raw?.updatedAt
|
|
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
|
|
47
|
+
externalId: optionalString(raw?.externalId),
|
|
55
48
|
email: optionalString(raw?.email),
|
|
56
|
-
firstName: optionalString(raw?.firstName
|
|
57
|
-
lastName: optionalString(raw?.lastName
|
|
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
|
|
61
|
-
updatedAt: optionalDateString(raw?.updatedAt
|
|
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
|
|
69
|
-
cardBrand: optionalString(raw?.cardBrand
|
|
70
|
-
cardLastFour: optionalString(raw?.cardLastFour
|
|
71
|
-
isDefault: Boolean(raw?.isDefault ??
|
|
72
|
-
|
|
73
|
-
|
|
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?.
|
|
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 ??
|
|
83
|
-
embedToken: optionalString(raw?.embedToken ??
|
|
84
|
-
expiresAt: optionalDateString(raw?.expiresAt
|
|
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 ??
|
|
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
|
-
|
|
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-
|
|
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
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
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
|
|
58
|
-
|
|
59
|
-
|
|
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
|
|
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
|
|
75
|
-
applicationId: optionalString(raw?.applicationId
|
|
76
|
-
customerId: requiredString(raw?.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
|
-
|
|
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
|
|
82
|
+
raw?.currentPeriodStart,
|
|
88
83
|
"subscription.currentPeriodStart"
|
|
89
84
|
),
|
|
90
85
|
currentPeriodEnd: requiredDateString(
|
|
91
|
-
raw?.currentPeriodEnd
|
|
86
|
+
raw?.currentPeriodEnd,
|
|
92
87
|
"subscription.currentPeriodEnd"
|
|
93
88
|
),
|
|
94
|
-
trialEnd: optionalDateString(raw?.trialEnd
|
|
95
|
-
cancelAtPeriodEnd: Boolean(raw?.cancelAtPeriodEnd ??
|
|
96
|
-
failureCount: Number(raw?.failureCount ??
|
|
97
|
-
lastPaymentAt: optionalDateString(raw?.lastPaymentAt
|
|
98
|
-
pausedAt: optionalDateString(raw?.pausedAt
|
|
99
|
-
cancelledAt: optionalDateString(raw?.cancelledAt
|
|
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
|
|
102
|
-
updatedAt: optionalDateString(raw?.updatedAt
|
|
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
|
|
104
|
+
externalId: optionalString(raw?.externalId),
|
|
110
105
|
email: optionalString(raw?.email),
|
|
111
|
-
firstName: optionalString(raw?.firstName
|
|
112
|
-
lastName: optionalString(raw?.lastName
|
|
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
|
|
116
|
-
updatedAt: optionalDateString(raw?.updatedAt
|
|
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
|
|
124
|
-
cardBrand: optionalString(raw?.cardBrand
|
|
125
|
-
cardLastFour: optionalString(raw?.cardLastFour
|
|
126
|
-
isDefault: Boolean(raw?.isDefault ??
|
|
127
|
-
|
|
128
|
-
|
|
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?.
|
|
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 ??
|
|
138
|
-
embedToken: optionalString(raw?.embedToken ??
|
|
139
|
-
expiresAt: optionalDateString(raw?.expiresAt
|
|
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 ??
|
|
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
|
-
|
|
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,
|