···26262727### Step 1 — Generate the exercise map template
28282929-Reads your CSV and outputs an `exercise-map.ts` file listing every unique exercise name:
2929+Reads your CSV and outputs `exercise-map.ts` listing every unique exercise name:
30303131```sh
3232deno task generate-map
3333```
34343535-### Step 2 — Get your Hevy exercise template IDs
3535+### Step 2 — Generate the Hevy exercise list
36363737-Fetches all exercise templates from your Hevy account and prints them as mappable key/value pairs:
3737+Fetches all exercise templates from your Hevy account and writes `HEVY_EXERCISES.ts`, a typed constant with ALL_CAPS keys mapping to Hevy template IDs:
38383939```sh
4040-deno task get-templates
4040+deno task generate-template-list
4141+```
4242+4343+This produces entries like:
4444+4545+```ts
4646+export const HEVY_EXERCISES: Record<string, string> = {
4747+ RUNNING: "abc123-...",
4848+ DUMBBELL_ROW: "def456-...",
4949+ // ...
5050+};
4151```
42524353### Step 3 — Fill in the exercise map
44544545-Open `exercise-map.ts` and paste in the Hevy template ID for each exercise. Any exercise left as an empty string will be skipped during import.
5555+Open `exercise-map.ts` and set each value to the matching `HEVY_EXERCISES` constant. Use your editor's autocomplete to browse available keys:
46564757```ts
5858+import { HEVY_EXERCISES } from './HEVY_EXERCISES.ts';
5959+4860export const EXERCISE_MAP: Record<string, string> = {
4949- "Running": "abc123",
5050- "Dumbbell Row": "def456",
6161+ "Running": HEVY_EXERCISES.RUNNING,
6262+ "Dumbbell Row": HEVY_EXERCISES.DUMBBELL_ROW,
5163 // ...
5264};
5365```
6666+6767+Any exercise left as `""` will be skipped during import.
54685569### Step 4 — Run the import
5670···5872deno task import
5973```
60746161-Workouts are sent one day at a time with a 1.5-second delay between requests to respect Hevy's rate limits. Exercises not found in the map are skipped with a warning.
7575+Workouts are sent one day at a time with a 1.5-second delay between requests to respect Hevy's rate limits.
62766377## Files
6478···6882| `.env.sample` | Template for `.env` |
6983| `config.ts` | Loads env vars, CSV path, API base URL |
7084| `generate-map.ts` | Generates `exercise-map.ts` from the CSV |
7171-| `get-templates.ts` | Lists Hevy exercise templates and their IDs |
8585+| `generate-template-list.ts` | Fetches Hevy templates and writes `HEVY_EXERCISES.ts` |
8686+| `HEVY_EXERCISES.ts` | Generated — ALL_CAPS constants mapping to Hevy template IDs |
7287| `exercise-map.ts` | Maps Fitbod exercise names → Hevy template IDs |
7388| `import.ts` | Main import script |
7489| `WorkoutExport.csv` | Your Fitbod data export (not committed) |
+1-1
deno.json
···11{
22 "tasks": {
33 "generate-map": "deno run --allow-read --allow-write generate-map.ts",
44- "get-templates": "deno run --allow-read --allow-net get-templates.ts",
44+ "generate-template-list": "deno run --allow-read --allow-write --allow-net generate-template-list.ts",
55 "import": "deno run --allow-read --allow-net import.ts"
66 }
77}
+9-7
exercise-map.ts
···11// exercise-map.ts
22-// Replace the empty strings with your actual Hevy exercise_template_ids from get-templates.ts
22+// Run generate-template-list.ts first, then fill in each value using HEVY_EXERCISES.KEY
33+// e.g. "Running": H.RUNNING
44+import { HEVY_EXERCISES as H } from './HEVY_EXERCISES.ts';
3546export const EXERCISE_MAP: Record<string, string> = {
55- "Running": "",
66- "Rowing": "",
77- "Dumbbell Row": "",
88- "Dumbbell Bicep Curl": "",
99- "Dumbbell Skullcrusher": "",
1010- "Dumbbell Fly": "",
77+ "Running": H.RUNNING,
88+ "Rowing": H.ROWING,
99+ "Dumbbell Row": H.DUMBBELL_ROW,
1010+ "Dumbbell Bicep Curl": H.DUMBBELL_BICEP_CURL,
1111+ "Dumbbell Skullcrusher": H.DUMBBELL_SKULLCRUSHER,
1212+ "Dumbbell Fly": H.DUMBBELL_FLY,
1113 "Dumbbell Incline Bench Press": "",
1214 "Bench Dip": "",
1315 "Dumbbell Goblet Squat": "",
+3-1
generate-map.ts
···3434 }
35353636 let fileContent = `// exercise-map.ts\n`;
3737- fileContent += `// Replace the empty strings with your actual Hevy exercise_template_ids from get-templates.ts\n\n`;
3737+ fileContent += `// Run generate-template-list.ts first, then fill in each value using HEVY_EXERCISES.KEY\n`;
3838+ fileContent += `// e.g. "Running": HEVY_EXERCISES.RUNNING\n`;
3939+ fileContent += `import { HEVY_EXERCISES } from './HEVY_EXERCISES.ts';\n\n`;
3840 fileContent += `export const EXERCISE_MAP: Record<string, string> = {\n`;
39414042 for (const ex of uniqueExercises) {