@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/CHANGELOG.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here. This project adheres
|
|
4
|
+
to [Semantic Versioning](https://semver.org/).
|
|
5
|
+
|
|
6
|
+
## 0.1.0
|
|
7
|
+
|
|
8
|
+
Initial release.
|
|
9
|
+
|
|
10
|
+
- Exercises: `list`, `get`, `byName`, `byBodyPart`, `byTarget`, `byEquipment`,
|
|
11
|
+
`search`, `similar`, `alternatives`, `calories`, `changes`, `find`, and the
|
|
12
|
+
`bodyPartList` / `targetList` / `equipmentList` / `secondaryMuscleList` lookups.
|
|
13
|
+
- GIFs: raw byte fetch and direct URL builder.
|
|
14
|
+
- Workout generator and supplement endpoints.
|
|
15
|
+
- Body Scan: credits, profile, history, key management, checkout, public packs.
|
|
16
|
+
- Account (`auth`): register, login, profile, API-key management, password
|
|
17
|
+
reset, email verification, usage stats, and webhook configuration.
|
|
18
|
+
- Billing: subscription status, Stripe Checkout, and customer portal.
|
|
19
|
+
- Automatic retry with backoff on transient failures (429/5xx/network),
|
|
20
|
+
honoring `Retry-After`.
|
|
21
|
+
- Shared Bearer token: a successful `auth.login()` is cached for later
|
|
22
|
+
`scan` / `billing` calls.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 WorkoutX
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# @workoutx/sdk
|
|
2
|
+
|
|
3
|
+
Official TypeScript/JavaScript SDK for the [WorkoutX API](https://workoutxapp.com).
|
|
4
|
+
One client covers **both** products:
|
|
5
|
+
|
|
6
|
+
- **Exercises** — exercises, GIFs, workout generator, supplements (API-key auth)
|
|
7
|
+
- **Body Scan** — credits, history, keys, checkout (logged-in user / Bearer auth)
|
|
8
|
+
- **Account & Billing** — register/login, API-key management, password reset, webhooks, subscription checkout (Bearer auth)
|
|
9
|
+
|
|
10
|
+
Works in Node.js 18+ and modern browsers. Zero runtime dependencies (uses native `fetch`).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install @workoutx/sdk
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
import { WorkoutX } from "@workoutx/sdk";
|
|
22
|
+
|
|
23
|
+
const wx = new WorkoutX({
|
|
24
|
+
apiKey: "wx_your_key_here", // exercises / gifs / workout / supplements
|
|
25
|
+
scan: { token: "eyJ..." }, // body scan (optional)
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Exercises
|
|
29
|
+
const page = await wx.exercises.list({ limit: 20 });
|
|
30
|
+
const byId = await wx.exercises.get("0001");
|
|
31
|
+
const lunges = await wx.exercises.byName("lunges"); // ← name lookup
|
|
32
|
+
const similar = await wx.exercises.similar("0001");
|
|
33
|
+
const alts = await wx.exercises.alternatives("0001", { equipment: "dumbbell" });
|
|
34
|
+
|
|
35
|
+
// GIFs (binary)
|
|
36
|
+
const bytes = await wx.gifs.get("0001"); // ArrayBuffer
|
|
37
|
+
const src = wx.gifUrl("0001"); // for <img src>
|
|
38
|
+
|
|
39
|
+
// Workout & supplements
|
|
40
|
+
const workout = await wx.workout.generate({ goal: "hypertrophy", days: 4 });
|
|
41
|
+
const stack = await wx.supplements.stack({ goal: "cut" });
|
|
42
|
+
|
|
43
|
+
// Body Scan
|
|
44
|
+
const credits = await wx.scan.credits();
|
|
45
|
+
const history = await wx.scan.history({ limit: 10 });
|
|
46
|
+
|
|
47
|
+
// Account & billing
|
|
48
|
+
const { token } = await wx.auth.login("user@example.com", "•••"); // token cached for scan/auth/billing
|
|
49
|
+
const me = await wx.auth.me();
|
|
50
|
+
const keys = await wx.auth.listKeys();
|
|
51
|
+
const sub = await wx.billing.status();
|
|
52
|
+
const checkout = await wx.billing.checkout("pro", "yearly"); // → { url } to redirect to Stripe
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Authentication
|
|
56
|
+
|
|
57
|
+
The two products use different credentials — the SDK handles both transparently.
|
|
58
|
+
|
|
59
|
+
| Product | Endpoints | Credential |
|
|
60
|
+
|---------|-----------|------------|
|
|
61
|
+
| Exercises | `exercises`, `gifs`, `workout`, `supplements` | `apiKey` (`wx_...`) → `X-WorkoutX-Key` header |
|
|
62
|
+
| Body Scan | `scan.*` | Bearer JWT |
|
|
63
|
+
|
|
64
|
+
For Body Scan you can either pass a ready token or let the SDK log in for you:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// Option A — you already have a token
|
|
68
|
+
new WorkoutX({ apiKey, scan: { token: "eyJ..." } });
|
|
69
|
+
|
|
70
|
+
// Option B — auto-login on first scan call, then cache the token
|
|
71
|
+
new WorkoutX({ apiKey, scan: { email: "user@example.com", password: "•••" } });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
You can also set/replace the token later:
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
wx.setScanToken("eyJ...");
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Avoiding the "name as ID" 404
|
|
81
|
+
|
|
82
|
+
`exercises.get(id)` expects an exact numeric ID (IDs have gaps and are **not**
|
|
83
|
+
sequential). Passing a human name like `"lunges"` returns 404. Use `byName`, or
|
|
84
|
+
the convenience resolver that tries an ID first then falls back to a name search:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
const ex = await wx.exercises.find("lunges"); // Exercise | null
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Error handling
|
|
91
|
+
|
|
92
|
+
Every non-2xx response throws a `WorkoutXError` with structured fields:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
import { WorkoutXError } from "@workoutx/sdk";
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await wx.exercises.get("not-a-real-id");
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (err instanceof WorkoutXError) {
|
|
101
|
+
err.status; // 404
|
|
102
|
+
err.code; // "Not Found"
|
|
103
|
+
err.message; // human-readable
|
|
104
|
+
err.tip; // hint from the API, when present
|
|
105
|
+
err.isNotFound; // boolean helpers: isAuthError, isRateLimited, isNotFound
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Transient failures (HTTP 429 and 5xx, plus network errors) are retried
|
|
111
|
+
automatically with exponential backoff, honoring the `Retry-After` header.
|
|
112
|
+
|
|
113
|
+
## Options
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
new WorkoutX({
|
|
117
|
+
apiKey,
|
|
118
|
+
scan,
|
|
119
|
+
baseUrl: "https://api.workoutxapp.com", // default
|
|
120
|
+
timeout: 30_000, // ms, default 30s
|
|
121
|
+
maxRetries: 2, // default 2
|
|
122
|
+
headers: { "X-Trace": "abc" }, // extra headers on every request
|
|
123
|
+
fetch: customFetch, // custom fetch impl (optional)
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## API surface
|
|
128
|
+
|
|
129
|
+
- `wx.exercises` — `list`, `get`, `byName`, `byBodyPart`, `byTarget`, `byEquipment`, `search`, `similar`, `alternatives`, `calories`, `changes`, `find`, `bodyPartList`, `targetList`, `equipmentList`, `secondaryMuscleList`
|
|
130
|
+
- `wx.gifs` — `get`, `url`
|
|
131
|
+
- `wx.workout` — `generate`, `program`
|
|
132
|
+
- `wx.supplements` — `list`, `filters`, `stack`, `forExercise`, `get`
|
|
133
|
+
- `wx.scan` — `credits`, `me`, `history`, `listKeys`, `createKey`, `deleteKey`, `checkout`, `packs`
|
|
134
|
+
- `wx.auth` — `register`, `login`, `me`, `updateMe`, `changePassword`, `listKeys`, `createKey`, `deleteKey`, `updateKeyPlan`, `usage`, `forgotPassword`, `resetPassword`, `verifyEmail`, `resendVerification`, `getWebhook`, `setWebhook`, `testWebhook`
|
|
135
|
+
- `wx.billing` — `status`, `checkout`, `portal`
|
|
136
|
+
|
|
137
|
+
> `auth`, `billing`, and `scan` use the same Bearer token. A successful
|
|
138
|
+
> `auth.login()` caches it, so subsequent `scan.*` / `billing.*` calls work
|
|
139
|
+
> without re-supplying credentials. Google OAuth (`/v1/auth/google`) is a
|
|
140
|
+
> browser-redirect flow and is intentionally not wrapped in the SDK.
|
|
141
|
+
|
|
142
|
+
> Some endpoints are plan-gated (e.g. `search`, `workout.generate`,
|
|
143
|
+
> `supplements.stack`). Calling them on a plan without the feature returns a
|
|
144
|
+
> `WorkoutXError` with a `403`/upgrade message.
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|