@workoutx/sdk 0.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/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +148 -0
- package/dist/index.cjs +610 -0
- package/dist/index.d.cts +442 -0
- package/dist/index.d.ts +442 -0
- package/dist/index.js +573 -0
- package/package.json +59 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
type QueryValue = string | number | boolean | undefined | null;
|
|
2
|
+
type Query = Record<string, QueryValue>;
|
|
3
|
+
interface HttpConfig {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
/** API key for exercises/gifs/workout/supplements (sent as X-WorkoutX-Key). */
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
/** Bearer token for the body-scan endpoints. */
|
|
8
|
+
getBearer?: () => Promise<string | undefined> | string | undefined;
|
|
9
|
+
/** Per-request timeout in ms. Default 30000. */
|
|
10
|
+
timeout: number;
|
|
11
|
+
/** Max retries for transient failures (429 / 5xx / network). Default 2. */
|
|
12
|
+
maxRetries: number;
|
|
13
|
+
/** Extra headers merged into every request. */
|
|
14
|
+
defaultHeaders: Record<string, string>;
|
|
15
|
+
fetch: typeof fetch;
|
|
16
|
+
}
|
|
17
|
+
interface RequestOptions {
|
|
18
|
+
method?: "GET" | "POST" | "DELETE" | "PUT" | "PATCH";
|
|
19
|
+
query?: Query;
|
|
20
|
+
body?: unknown;
|
|
21
|
+
/** Which credential to attach. "key" = X-WorkoutX-Key, "bearer" = Authorization. */
|
|
22
|
+
auth?: "key" | "bearer";
|
|
23
|
+
/** Override the default Accept/return handling to get raw bytes. */
|
|
24
|
+
raw?: boolean;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
|
+
}
|
|
27
|
+
declare class HttpClient {
|
|
28
|
+
private readonly cfg;
|
|
29
|
+
constructor(cfg: HttpConfig);
|
|
30
|
+
request<T>(path: string, opts?: RequestOptions): Promise<T>;
|
|
31
|
+
private resolveBearer;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Shared types for the WorkoutX SDK.
|
|
36
|
+
*
|
|
37
|
+
* These mirror the shapes returned by the WorkoutX API
|
|
38
|
+
* (https://api.workoutxapp.com). Fields that depend on the caller's plan
|
|
39
|
+
* (e.g. extended metadata only available on paid tiers) are marked optional.
|
|
40
|
+
*/
|
|
41
|
+
/** Firestore-style timestamp returned by the API. */
|
|
42
|
+
interface ApiTimestamp {
|
|
43
|
+
_seconds: number;
|
|
44
|
+
_nanoseconds: number;
|
|
45
|
+
}
|
|
46
|
+
/** A single exercise record. */
|
|
47
|
+
interface Exercise {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
bodyPart: string;
|
|
51
|
+
equipment: string;
|
|
52
|
+
target: string;
|
|
53
|
+
secondaryMuscles: string[];
|
|
54
|
+
instructions: string[];
|
|
55
|
+
gifUrl?: string;
|
|
56
|
+
createdAt?: ApiTimestamp;
|
|
57
|
+
updatedAt?: ApiTimestamp;
|
|
58
|
+
/** Plan-gated / computed fields may also appear depending on the endpoint. */
|
|
59
|
+
[key: string]: unknown;
|
|
60
|
+
}
|
|
61
|
+
/** Standard paginated list envelope used by exercise list endpoints. */
|
|
62
|
+
interface PaginatedList<T> {
|
|
63
|
+
total: number;
|
|
64
|
+
count: number;
|
|
65
|
+
data: T[];
|
|
66
|
+
}
|
|
67
|
+
/** Common pagination params accepted by list endpoints. */
|
|
68
|
+
interface PageParams {
|
|
69
|
+
limit?: number;
|
|
70
|
+
offset?: number;
|
|
71
|
+
}
|
|
72
|
+
/** Query params for {@link ExercisesResource.search}. */
|
|
73
|
+
interface SearchParams extends PageParams {
|
|
74
|
+
name?: string;
|
|
75
|
+
bodyPart?: string;
|
|
76
|
+
target?: string;
|
|
77
|
+
equipment?: string;
|
|
78
|
+
secondaryMuscle?: string;
|
|
79
|
+
/** Ultra-gated filters — only effective on plans that allow them. */
|
|
80
|
+
jointFocus?: string;
|
|
81
|
+
intensityLevel?: string;
|
|
82
|
+
movementTag?: string;
|
|
83
|
+
}
|
|
84
|
+
/** Query params for {@link ExercisesResource.alternatives}. */
|
|
85
|
+
interface AlternativesParams extends PageParams {
|
|
86
|
+
/** Prefer alternatives using this equipment. */
|
|
87
|
+
equipment?: string;
|
|
88
|
+
/** Exclude alternatives using this equipment. */
|
|
89
|
+
excludeEquipment?: string;
|
|
90
|
+
}
|
|
91
|
+
/** Result of an exercise calorie estimate. */
|
|
92
|
+
interface CalorieEstimate {
|
|
93
|
+
id: string;
|
|
94
|
+
name: string;
|
|
95
|
+
[key: string]: unknown;
|
|
96
|
+
}
|
|
97
|
+
/** A supplement record. */
|
|
98
|
+
interface Supplement {
|
|
99
|
+
id: string;
|
|
100
|
+
name: string;
|
|
101
|
+
[key: string]: unknown;
|
|
102
|
+
}
|
|
103
|
+
/** Params for {@link WorkoutResource.generate}. */
|
|
104
|
+
interface WorkoutGenerateParams {
|
|
105
|
+
goal?: string;
|
|
106
|
+
days?: number;
|
|
107
|
+
equipment?: string;
|
|
108
|
+
level?: string;
|
|
109
|
+
[key: string]: unknown;
|
|
110
|
+
}
|
|
111
|
+
/** Params for {@link WorkoutResource.program}. */
|
|
112
|
+
interface WorkoutProgramParams {
|
|
113
|
+
goal?: string;
|
|
114
|
+
weeks?: number;
|
|
115
|
+
daysPerWeek?: number;
|
|
116
|
+
[key: string]: unknown;
|
|
117
|
+
}
|
|
118
|
+
/** Generic JSON object response for endpoints with flexible shapes. */
|
|
119
|
+
type JsonObject = Record<string, unknown>;
|
|
120
|
+
|
|
121
|
+
/** Access to `/v1/exercises/*`. Authenticated with the API key. */
|
|
122
|
+
declare class ExercisesResource {
|
|
123
|
+
private readonly http;
|
|
124
|
+
constructor(http: HttpClient);
|
|
125
|
+
/** List exercises (paginated). */
|
|
126
|
+
list(params?: PageParams): Promise<PaginatedList<Exercise>>;
|
|
127
|
+
/**
|
|
128
|
+
* Look up a single exercise by its exact numeric ID (e.g. "0001").
|
|
129
|
+
*
|
|
130
|
+
* Note: IDs are not sequential — there are gaps. To resolve a human name
|
|
131
|
+
* like "lunges", use {@link byName} instead. See {@link find} for a helper
|
|
132
|
+
* that tries an ID first and falls back to a name search.
|
|
133
|
+
*/
|
|
134
|
+
get(id: string): Promise<Exercise>;
|
|
135
|
+
/** Find exercises whose name contains the given text. */
|
|
136
|
+
byName(name: string, params?: PageParams): Promise<Exercise[]>;
|
|
137
|
+
/** Filter exercises by body part (e.g. "back"). */
|
|
138
|
+
byBodyPart(bodyPart: string, params?: PageParams): Promise<PaginatedList<Exercise>>;
|
|
139
|
+
/** Filter exercises by target muscle (e.g. "abs"). */
|
|
140
|
+
byTarget(target: string, params?: PageParams): Promise<PaginatedList<Exercise>>;
|
|
141
|
+
/** Filter exercises by equipment (e.g. "barbell"). */
|
|
142
|
+
byEquipment(equipment: string, params?: PageParams): Promise<PaginatedList<Exercise>>;
|
|
143
|
+
/** Multi-filter search (plan-gated: requires the `multiFilter` feature). */
|
|
144
|
+
search(params?: SearchParams): Promise<PaginatedList<Exercise>>;
|
|
145
|
+
/** Exercises similar to the given exercise ID. */
|
|
146
|
+
similar(id: string, params?: PageParams): Promise<PaginatedList<Exercise>>;
|
|
147
|
+
/** Alternatives that hit the same target with different equipment. */
|
|
148
|
+
alternatives(id: string, params?: AlternativesParams): Promise<PaginatedList<Exercise>>;
|
|
149
|
+
/** Estimated calories burned for an exercise. */
|
|
150
|
+
calories(id: string, params?: JsonObject): Promise<CalorieEstimate>;
|
|
151
|
+
/** Dataset changelog (plan-gated: requires the `datasetSync` feature). */
|
|
152
|
+
changes(params?: JsonObject): Promise<JsonObject>;
|
|
153
|
+
/** List of all body parts. */
|
|
154
|
+
bodyPartList(): Promise<string[]>;
|
|
155
|
+
/** List of all target muscles. */
|
|
156
|
+
targetList(): Promise<string[]>;
|
|
157
|
+
/** List of all equipment types. */
|
|
158
|
+
equipmentList(): Promise<string[]>;
|
|
159
|
+
/** List of all secondary muscles. */
|
|
160
|
+
secondaryMuscleList(): Promise<string[]>;
|
|
161
|
+
/**
|
|
162
|
+
* Convenience resolver: treat `idOrName` as an ID first, and if that 404s,
|
|
163
|
+
* fall back to a name search and return the first match. Saves callers from
|
|
164
|
+
* the common "/v1/exercises/lunges → 404" mistake.
|
|
165
|
+
*
|
|
166
|
+
* Returns `null` when neither an ID nor a name match is found.
|
|
167
|
+
*/
|
|
168
|
+
find(idOrName: string): Promise<Exercise | null>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Access to `/v1/gifs/*`. Authenticated with the API key. */
|
|
172
|
+
declare class GifsResource {
|
|
173
|
+
private readonly http;
|
|
174
|
+
constructor(http: HttpClient);
|
|
175
|
+
/**
|
|
176
|
+
* Fetch an exercise GIF as raw bytes.
|
|
177
|
+
*
|
|
178
|
+
* Accepts both "0001" and "0001.gif". On the free plan the API serves a
|
|
179
|
+
* watermarked variant; paid plans get the original. Returns the binary
|
|
180
|
+
* payload — wrap it in `Blob`/`Buffer` as needed.
|
|
181
|
+
*/
|
|
182
|
+
get(filename: string): Promise<ArrayBuffer>;
|
|
183
|
+
/**
|
|
184
|
+
* Build the direct GIF URL (no request made). Useful for `<img src>`.
|
|
185
|
+
* The API key still needs to be supplied — by default via the `api-key`
|
|
186
|
+
* query param, which works for `<img>` tags that can't set headers.
|
|
187
|
+
*/
|
|
188
|
+
url(filename: string, opts: {
|
|
189
|
+
baseUrl: string;
|
|
190
|
+
apiKey?: string;
|
|
191
|
+
}): string;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Access to `/v1/workout/*`. Authenticated with the API key. */
|
|
195
|
+
declare class WorkoutResource {
|
|
196
|
+
private readonly http;
|
|
197
|
+
constructor(http: HttpClient);
|
|
198
|
+
/** Generate a single workout (plan-gated: requires `workoutGenerator`). */
|
|
199
|
+
generate(params?: WorkoutGenerateParams): Promise<JsonObject>;
|
|
200
|
+
/** Generate a multi-week program (plan-gated: requires `workoutPrograms`). */
|
|
201
|
+
program(params?: WorkoutProgramParams): Promise<JsonObject>;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Access to `/v1/supplements/*`. Authenticated with the API key. */
|
|
205
|
+
declare class SupplementsResource {
|
|
206
|
+
private readonly http;
|
|
207
|
+
constructor(http: HttpClient);
|
|
208
|
+
/** List supplements (paginated). */
|
|
209
|
+
list(params?: PageParams): Promise<JsonObject>;
|
|
210
|
+
/** Available supplement filters. */
|
|
211
|
+
filters(): Promise<JsonObject>;
|
|
212
|
+
/** Build a recommended stack (plan-gated: requires `supplementStacks`). */
|
|
213
|
+
stack(params?: JsonObject): Promise<JsonObject>;
|
|
214
|
+
/** Supplements recommended for a given exercise. */
|
|
215
|
+
forExercise(exerciseId: string): Promise<JsonObject>;
|
|
216
|
+
/** Get a single supplement by ID. */
|
|
217
|
+
get(id: string): Promise<Supplement>;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Access to the Body Scan product (`/v1/scan/*`).
|
|
222
|
+
*
|
|
223
|
+
* Unlike the exercise endpoints (API key), these require a logged-in user's
|
|
224
|
+
* Bearer token. Supply it via the client's `scan` option — either a ready
|
|
225
|
+
* `token`, or `email`/`password` for automatic login on first use.
|
|
226
|
+
*/
|
|
227
|
+
declare class ScanResource {
|
|
228
|
+
private readonly http;
|
|
229
|
+
constructor(http: HttpClient);
|
|
230
|
+
/** Body-scan credit balance + usage stats for the current user. */
|
|
231
|
+
credits(): Promise<JsonObject>;
|
|
232
|
+
/** Current user's body-scan profile. */
|
|
233
|
+
me(): Promise<JsonObject>;
|
|
234
|
+
/** Paginated scan history. */
|
|
235
|
+
history(params?: PageParams): Promise<JsonObject>;
|
|
236
|
+
/** List the user's body-scan API keys. */
|
|
237
|
+
listKeys(): Promise<JsonObject[]>;
|
|
238
|
+
/** Create a body-scan API key. */
|
|
239
|
+
createKey(name: string): Promise<JsonObject>;
|
|
240
|
+
/** Delete a body-scan API key by ID. */
|
|
241
|
+
deleteKey(id: string): Promise<JsonObject>;
|
|
242
|
+
/** Create a Stripe checkout session for a credit pack. */
|
|
243
|
+
checkout(body?: JsonObject): Promise<JsonObject>;
|
|
244
|
+
/** Public list of available credit packs (no auth required). */
|
|
245
|
+
packs(): Promise<JsonObject>;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Result of {@link AuthResource.login}. */
|
|
249
|
+
interface AuthLoginResult extends JsonObject {
|
|
250
|
+
token: string;
|
|
251
|
+
user: JsonObject;
|
|
252
|
+
apiKeys: JsonObject[];
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Account, API-key, and webhook management (`/v1/auth/*`).
|
|
256
|
+
*
|
|
257
|
+
* `register`, `login`, `forgotPassword`, `resetPassword`, `verifyEmail`, and
|
|
258
|
+
* `resendVerification` are public — no token needed. Everything else
|
|
259
|
+
* requires the Bearer token returned by `login` (see {@link WorkoutX.setScanToken}
|
|
260
|
+
* or pass `scan: { email, password }` to the client for automatic login).
|
|
261
|
+
*
|
|
262
|
+
* Google OAuth (`/v1/auth/google`) is a browser-redirect flow and is not
|
|
263
|
+
* wrapped here — it only makes sense from a web app, not an SDK call.
|
|
264
|
+
*/
|
|
265
|
+
declare class AuthResource {
|
|
266
|
+
private readonly http;
|
|
267
|
+
private readonly onLogin?;
|
|
268
|
+
constructor(http: HttpClient, onLogin?: ((token: string) => void) | undefined);
|
|
269
|
+
/** Create a new account. Sends a verification email; no token is issued yet. */
|
|
270
|
+
register(params: {
|
|
271
|
+
email: string;
|
|
272
|
+
password: string;
|
|
273
|
+
name?: string;
|
|
274
|
+
}): Promise<JsonObject>;
|
|
275
|
+
/** Log in and receive a Bearer token (also used by `scan.*`). */
|
|
276
|
+
login(email: string, password: string): Promise<AuthLoginResult>;
|
|
277
|
+
/** Get the current user's profile. */
|
|
278
|
+
me(): Promise<JsonObject>;
|
|
279
|
+
/** Update the current user's display name. */
|
|
280
|
+
updateMe(name: string): Promise<JsonObject>;
|
|
281
|
+
/** Change the current user's password. */
|
|
282
|
+
changePassword(currentPassword: string, newPassword: string): Promise<JsonObject>;
|
|
283
|
+
/** List the current user's API keys (exercises/gifs/workout/supplements product). */
|
|
284
|
+
listKeys(): Promise<JsonObject[]>;
|
|
285
|
+
/** Create a new API key. */
|
|
286
|
+
createKey(name?: string): Promise<JsonObject>;
|
|
287
|
+
/** Delete an API key by ID. */
|
|
288
|
+
deleteKey(id: string): Promise<JsonObject>;
|
|
289
|
+
/** Change the plan assigned to an API key. */
|
|
290
|
+
updateKeyPlan(id: string, planId: string): Promise<JsonObject>;
|
|
291
|
+
/** Usage statistics for the current user (optionally filtered to one API key). */
|
|
292
|
+
usage(params?: {
|
|
293
|
+
days?: number;
|
|
294
|
+
apiKey?: string;
|
|
295
|
+
}): Promise<JsonObject>;
|
|
296
|
+
/** Request a password-reset email. Always succeeds (no email enumeration). */
|
|
297
|
+
forgotPassword(email: string): Promise<JsonObject>;
|
|
298
|
+
/** Complete a password reset using the token emailed by `forgotPassword`. */
|
|
299
|
+
resetPassword(token: string, password: string): Promise<JsonObject>;
|
|
300
|
+
/** Verify an email address using the token from the verification email. */
|
|
301
|
+
verifyEmail(token: string): Promise<JsonObject>;
|
|
302
|
+
/** Resend the verification email. Always succeeds (no email enumeration). */
|
|
303
|
+
resendVerification(email: string): Promise<JsonObject>;
|
|
304
|
+
/** Get the current user's registered webhook URL. */
|
|
305
|
+
getWebhook(): Promise<{
|
|
306
|
+
webhookUrl: string | null;
|
|
307
|
+
}>;
|
|
308
|
+
/** Set (or clear, with `null`) the webhook URL. */
|
|
309
|
+
setWebhook(webhookUrl: string | null): Promise<JsonObject>;
|
|
310
|
+
/** Send a test event to the registered webhook URL. */
|
|
311
|
+
testWebhook(): Promise<JsonObject>;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Subscription billing (`/v1/billing/*`). All methods require the Bearer
|
|
316
|
+
* token from {@link AuthResource.login} (same token used by `scan.*`).
|
|
317
|
+
*
|
|
318
|
+
* `POST /v1/billing/webhook` (Stripe's server-to-server callback) is
|
|
319
|
+
* intentionally not wrapped here — it requires the raw request body and
|
|
320
|
+
* Stripe-Signature header from an actual HTTP server, not a client SDK call.
|
|
321
|
+
*/
|
|
322
|
+
declare class BillingResource {
|
|
323
|
+
private readonly http;
|
|
324
|
+
constructor(http: HttpClient);
|
|
325
|
+
/** Current subscription status, plan, and renewal date for the logged-in user. */
|
|
326
|
+
status(): Promise<JsonObject>;
|
|
327
|
+
/** Create a Stripe Checkout session for upgrading to a paid plan. */
|
|
328
|
+
checkout(planId: "basic" | "pro" | "ultra", billingCycle?: "monthly" | "yearly"): Promise<{
|
|
329
|
+
url: string;
|
|
330
|
+
}>;
|
|
331
|
+
/** Open the Stripe Customer Portal for the logged-in user to manage/cancel their subscription. */
|
|
332
|
+
portal(): Promise<{
|
|
333
|
+
url: string;
|
|
334
|
+
}>;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
declare const DEFAULT_BASE_URL = "https://api.workoutxapp.com";
|
|
338
|
+
/** Credentials for the Body Scan product. */
|
|
339
|
+
type ScanAuth =
|
|
340
|
+
/** A ready-to-use JWT from a prior login. */
|
|
341
|
+
{
|
|
342
|
+
token: string;
|
|
343
|
+
}
|
|
344
|
+
/** Credentials used to log in automatically on first scan call. */
|
|
345
|
+
| {
|
|
346
|
+
email: string;
|
|
347
|
+
password: string;
|
|
348
|
+
};
|
|
349
|
+
interface WorkoutXOptions {
|
|
350
|
+
/**
|
|
351
|
+
* API key (starts with `wx_`) for exercises, gifs, workout, supplements.
|
|
352
|
+
* Required unless you only use public endpoints (e.g. `scan.packs`).
|
|
353
|
+
*/
|
|
354
|
+
apiKey?: string;
|
|
355
|
+
/** Credentials for the Body Scan product. Omit if you don't use `scan`. */
|
|
356
|
+
scan?: ScanAuth;
|
|
357
|
+
/** Override the API base URL. Defaults to https://api.workoutxapp.com */
|
|
358
|
+
baseUrl?: string;
|
|
359
|
+
/** Per-request timeout in ms. Default 30000. */
|
|
360
|
+
timeout?: number;
|
|
361
|
+
/** Max retries on transient errors (429/5xx/network). Default 2. */
|
|
362
|
+
maxRetries?: number;
|
|
363
|
+
/** Extra headers added to every request. */
|
|
364
|
+
headers?: Record<string, string>;
|
|
365
|
+
/** Custom fetch implementation (defaults to global fetch). */
|
|
366
|
+
fetch?: typeof fetch;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* The WorkoutX API client. One instance covers both products:
|
|
370
|
+
*
|
|
371
|
+
* ```ts
|
|
372
|
+
* const wx = new WorkoutX({ apiKey: "wx_...", scan: { token: "eyJ..." } });
|
|
373
|
+
* await wx.exercises.byName("lunges");
|
|
374
|
+
* await wx.scan.credits();
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
declare class WorkoutX {
|
|
378
|
+
readonly exercises: ExercisesResource;
|
|
379
|
+
readonly gifs: GifsResource;
|
|
380
|
+
readonly workout: WorkoutResource;
|
|
381
|
+
readonly supplements: SupplementsResource;
|
|
382
|
+
readonly scan: ScanResource;
|
|
383
|
+
readonly auth: AuthResource;
|
|
384
|
+
readonly billing: BillingResource;
|
|
385
|
+
private readonly http;
|
|
386
|
+
private readonly baseUrl;
|
|
387
|
+
private readonly apiKey?;
|
|
388
|
+
private cachedToken?;
|
|
389
|
+
private loginInFlight?;
|
|
390
|
+
private readonly scanAuth?;
|
|
391
|
+
constructor(opts?: WorkoutXOptions);
|
|
392
|
+
/** Build a direct GIF URL with the API key baked into the query string. */
|
|
393
|
+
gifUrl(filename: string): string;
|
|
394
|
+
/** Manually set/replace the body-scan Bearer token. */
|
|
395
|
+
setScanToken(token: string): void;
|
|
396
|
+
/** Resolve a Bearer token, logging in with email/password if needed. */
|
|
397
|
+
private getBearerToken;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Error raised for any non-2xx response from the WorkoutX API.
|
|
402
|
+
*
|
|
403
|
+
* The original parsed body (when JSON) is preserved on `.body`, and common
|
|
404
|
+
* fields the API returns (`error`, `message`, `tip`, `docs`) are surfaced
|
|
405
|
+
* directly so callers don't have to dig.
|
|
406
|
+
*/
|
|
407
|
+
declare class WorkoutXError extends Error {
|
|
408
|
+
/** HTTP status code (e.g. 401, 404, 429, 503). */
|
|
409
|
+
readonly status: number;
|
|
410
|
+
/** Short error label from the API body, e.g. "Not Found". */
|
|
411
|
+
readonly code?: string;
|
|
412
|
+
/** Hint the API sometimes returns to help fix the request. */
|
|
413
|
+
readonly tip?: string;
|
|
414
|
+
/** Docs URL the API sometimes returns. */
|
|
415
|
+
readonly docs?: string;
|
|
416
|
+
/** Raw parsed response body (object when JSON, string otherwise). */
|
|
417
|
+
readonly body: unknown;
|
|
418
|
+
/** The request path that failed, e.g. "/v1/exercises/lunges". */
|
|
419
|
+
readonly path: string;
|
|
420
|
+
constructor(args: {
|
|
421
|
+
status: number;
|
|
422
|
+
path: string;
|
|
423
|
+
body: unknown;
|
|
424
|
+
message: string;
|
|
425
|
+
code?: string;
|
|
426
|
+
tip?: string;
|
|
427
|
+
docs?: string;
|
|
428
|
+
});
|
|
429
|
+
/** True for 429 (rate limit / quota). */
|
|
430
|
+
get isRateLimited(): boolean;
|
|
431
|
+
/** True for 401/403 (auth/plan problems). */
|
|
432
|
+
get isAuthError(): boolean;
|
|
433
|
+
/** True for 404. */
|
|
434
|
+
get isNotFound(): boolean;
|
|
435
|
+
}
|
|
436
|
+
/** Raised when a network/transport failure prevents getting any response. */
|
|
437
|
+
declare class WorkoutXConnectionError extends Error {
|
|
438
|
+
readonly cause?: unknown;
|
|
439
|
+
constructor(message: string, cause?: unknown);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export { type AlternativesParams, type ApiTimestamp, type AuthLoginResult, AuthResource, BillingResource, type CalorieEstimate, DEFAULT_BASE_URL, type Exercise, ExercisesResource, GifsResource, type JsonObject, type PageParams, type PaginatedList, type ScanAuth, ScanResource, type SearchParams, type Supplement, SupplementsResource, type WorkoutGenerateParams, type WorkoutProgramParams, WorkoutResource, WorkoutX, WorkoutXConnectionError, WorkoutXError, type WorkoutXOptions };
|