UNPKG

hevy-mcp

Version:

A Model Context Protocol (MCP) server implementation that interfaces with the Hevy fitness tracking app and its API.

1,451 lines (1,436 loc) 76.7 kB
#!/usr/bin/env node // Generated with tsup // https://github.com/egoist/tsup // src/index.ts import "@dotenvx/dotenvx/config"; import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; // src/tools/folders.ts import { z } from "zod"; // src/utils/formatters.ts function formatWorkout(workout) { return { id: workout.id, date: workout.createdAt, name: workout.title, description: workout.description, duration: calculateDuration(workout.startTime || "", workout.endTime || ""), exercises: workout.exercises?.map((exercise) => { return { name: exercise.title, notes: exercise.notes, sets: exercise.sets?.map((set) => ({ type: set.type, weight: set.weightKg, reps: set.reps, distance: set.distanceMeters, duration: set.durationSeconds, rpe: set.rpe, customMetric: set.customMetric })) }; }) }; } function formatRoutine(routine) { return { id: routine.id, title: routine.title, folderId: routine.folderId, createdAt: routine.createdAt, updatedAt: routine.updatedAt, exercises: routine.exercises?.map((exercise) => { return { name: exercise.title, index: exercise.index, exerciseTemplateId: exercise.exerciseTemplateId, notes: exercise.notes, supersetId: exercise.supersetsId, sets: exercise.sets?.map((set) => ({ index: set.index, type: set.type, weight: set.weightKg, reps: set.reps, distance: set.distanceMeters, duration: set.durationSeconds, customMetric: set.customMetric })) }; }) }; } function formatRoutineFolder(folder) { return { id: folder.id, title: folder.title, createdAt: folder.createdAt, updatedAt: folder.updatedAt }; } function calculateDuration(startTime, endTime) { if (!startTime || !endTime) return "Unknown duration"; const start = new Date(startTime); const end = new Date(endTime); const durationMs = end.getTime() - start.getTime(); const hours = Math.floor(durationMs / (1e3 * 60 * 60)); const minutes = Math.floor(durationMs % (1e3 * 60 * 60) / (1e3 * 60)); const seconds = Math.floor(durationMs % (1e3 * 60) / 1e3); return `${hours}h ${minutes}m ${seconds}s`; } function formatExerciseTemplate(template) { return { id: template.id, title: template.title, type: template.type, primaryMuscleGroup: template.primaryMuscleGroup, secondaryMuscleGroups: template.secondaryMuscleGroups, isCustom: template.isCustom }; } // src/tools/folders.ts function registerFolderTools(server2, hevyClient2) { server2.tool( "get-routine-folders", "Get a paginated list of routine folders available on the account. Returns folder details including ID, title, index (order position), and creation/update timestamps. Useful for organizing routines into categories.", { page: z.coerce.number().int().gte(1).default(1), pageSize: z.coerce.number().int().gte(1).lte(10).default(5) }, async ({ page, pageSize }) => { try { const data = await hevyClient2.v1.routine_folders.get({ queryParameters: { page, pageSize } }); const folders = data?.routineFolders?.map((folder) => formatRoutineFolder(folder)) || []; return { content: [ { type: "text", text: JSON.stringify(folders, null, 2) } ] }; } catch (error) { console.error("Error fetching routine folders:", error); return { content: [ { type: "text", text: `Error fetching routine folders: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "get-routine-folder", "Get complete details of a specific routine folder by ID. Returns all folder information including title, index (order position), and creation/update timestamps.", { folderId: z.coerce.number().int() }, async ({ folderId }) => { try { const data = await hevyClient2.v1.routine_folders.byFolderId(folderId.toString()).get(); if (!data) { return { content: [ { type: "text", text: `Routine folder with ID ${folderId} not found` } ] }; } const folder = formatRoutineFolder(data); return { content: [ { type: "text", text: JSON.stringify(folder, null, 2) } ] }; } catch (error) { console.error(`Error fetching routine folder ${folderId}:`, error); return { content: [ { type: "text", text: `Error fetching routine folder: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "create-routine-folder", "Create a new routine folder in your Hevy account. The folder will be created at index 0, and all other folders will have their indexes incremented. Returns the complete folder details upon successful creation including the newly assigned folder ID.", { title: z.string().min(1) }, async ({ title }) => { try { const data = await hevyClient2.v1.routine_folders.post({ routineFolder: { title } }); if (!data) { return { content: [ { type: "text", text: "Failed to create routine folder" } ] }; } const folder = formatRoutineFolder(data); return { content: [ { type: "text", text: `Routine folder created successfully: ${JSON.stringify(folder, null, 2)}` } ] }; } catch (error) { console.error("Error creating routine folder:", error); return { content: [ { type: "text", text: `Error creating routine folder: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); } // src/tools/routines.ts import { z as z2 } from "zod"; function registerRoutineTools(server2, hevyClient2) { server2.tool( "get-routines", "Get a paginated list of routines. Returns routine details including title, creation date, folder assignment, and exercise configurations. Results include both default and custom routines.", { page: z2.coerce.number().int().gte(1).default(1), pageSize: z2.coerce.number().int().gte(1).lte(10).default(5) }, async ({ page, pageSize }) => { try { const data = await hevyClient2.v1.routines.get({ queryParameters: { page, pageSize } }); const routines = data?.routines?.map((routine) => formatRoutine(routine)) || []; return { content: [ { type: "text", text: JSON.stringify(routines, null, 2) } ] }; } catch (error) { console.error("Error fetching routines:", error); return { content: [ { type: "text", text: `Error fetching routines: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "get-routine", "Get complete details of a specific routine by ID. Returns all routine information including title, notes, assigned folder, and detailed exercise data with set configurations.", { routineId: z2.string().min(1) }, async ({ routineId }) => { try { const data = await hevyClient2.v1.routines.byRoutineId(routineId).put({ routine: { title: "" // We're providing a minimal body as required by the API } }); if (!data) { return { content: [ { type: "text", text: `Routine with ID ${routineId} not found` } ] }; } const routine = formatRoutine(data); return { content: [ { type: "text", text: JSON.stringify(routine, null, 2) } ] }; } catch (error) { console.error(`Error fetching routine ${routineId}:`, error); return { content: [ { type: "text", text: `Error fetching routine: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "create-routine", "Create a new workout routine in your Hevy account. Requires title and at least one exercise with sets. Optionally assign to a specific folder. Returns the complete routine details upon successful creation including the newly assigned routine ID.", { title: z2.string().min(1), folderId: z2.coerce.number().nullable().optional(), notes: z2.string().optional(), exercises: z2.array( z2.object({ exerciseTemplateId: z2.string().min(1), supersetId: z2.coerce.number().nullable().optional(), restSeconds: z2.coerce.number().int().min(0).optional(), notes: z2.string().optional(), sets: z2.array( z2.object({ type: z2.enum(["warmup", "normal", "failure", "dropset"]).default("normal"), weightKg: z2.coerce.number().optional(), reps: z2.coerce.number().int().optional(), distanceMeters: z2.coerce.number().int().optional(), durationSeconds: z2.coerce.number().int().optional(), customMetric: z2.coerce.number().optional() }) ) }) ) }, async ({ title, folderId, notes, exercises }) => { try { const data = await hevyClient2.v1.routines.post({ routine: { title, folderId: folderId || null, notes: notes || "", exercises: exercises.map((exercise) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, restSeconds: exercise.restSeconds || null, notes: exercise.notes || null, sets: exercise.sets.map((set) => ({ type: set.type, weightKg: set.weightKg || null, reps: set.reps || null, distanceMeters: set.distanceMeters || null, durationSeconds: set.durationSeconds || null, customMetric: set.customMetric || null })) })) } }); if (!data) { return { content: [ { type: "text", text: "Failed to create routine" } ] }; } const routine = formatRoutine(data); return { content: [ { type: "text", text: `Routine created successfully: ${JSON.stringify(routine, null, 2)}` } ] }; } catch (error) { console.error("Error creating routine:", error); return { content: [ { type: "text", text: `Error creating routine: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "update-routine", "Update an existing workout routine by ID. You can modify the title, notes, and exercise data. Returns the updated routine with all changes applied. Note that you cannot change the folder assignment through this method.", { routineId: z2.string().min(1), title: z2.string().min(1), notes: z2.string().optional(), exercises: z2.array( z2.object({ exerciseTemplateId: z2.string().min(1), supersetId: z2.coerce.number().nullable().optional(), restSeconds: z2.coerce.number().int().min(0).optional(), notes: z2.string().optional(), sets: z2.array( z2.object({ type: z2.enum(["warmup", "normal", "failure", "dropset"]).default("normal"), weightKg: z2.coerce.number().optional(), reps: z2.coerce.number().int().optional(), distanceMeters: z2.coerce.number().int().optional(), durationSeconds: z2.coerce.number().int().optional(), customMetric: z2.coerce.number().optional() }) ) }) ) }, async ({ routineId, title, notes, exercises }) => { try { const data = await hevyClient2.v1.routines.byRoutineId(routineId).put({ routine: { title, notes: notes || null, exercises: exercises.map((exercise) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, restSeconds: exercise.restSeconds || null, notes: exercise.notes || null, sets: exercise.sets.map((set) => ({ type: set.type, weightKg: set.weightKg || null, reps: set.reps || null, distanceMeters: set.distanceMeters || null, durationSeconds: set.durationSeconds || null, customMetric: set.customMetric || null })) })) } }); if (!data) { return { content: [ { type: "text", text: `Failed to update routine with ID ${routineId}` } ] }; } const routine = formatRoutine(data); return { content: [ { type: "text", text: `Routine updated successfully: ${JSON.stringify(routine, null, 2)}` } ] }; } catch (error) { console.error(`Error updating routine ${routineId}:`, error); return { content: [ { type: "text", text: `Error updating routine: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); } // src/tools/templates.ts import { z as z3 } from "zod"; function registerTemplateTools(server2, hevyClient2) { server2.tool( "get-exercise-templates", "Get a paginated list of exercise templates available on the account. Returns both default and custom exercise templates with details including title, type, primary muscle group, and secondary muscle groups. Supports up to 100 templates per page.", { page: z3.coerce.number().int().gte(1).default(1), pageSize: z3.coerce.number().int().gte(1).lte(100).default(20) }, async ({ page, pageSize }) => { try { const data = await hevyClient2.v1.exercise_templates.get({ queryParameters: { page, pageSize } }); const templates = data?.exerciseTemplates?.map( (template) => formatExerciseTemplate(template) ) || []; return { content: [ { type: "text", text: JSON.stringify(templates, null, 2) } ] }; } catch (error) { console.error("Error fetching exercise templates:", error); return { content: [ { type: "text", text: `Error fetching exercise templates: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "get-exercise-template", "Get complete details of a specific exercise template by ID. Returns all template information including title, type, primary muscle group, secondary muscle groups, and whether it's a custom exercise.", { exerciseTemplateId: z3.string().min(1) }, async ({ exerciseTemplateId }) => { try { const data = await hevyClient2.v1.exercise_templates.byExerciseTemplateId(exerciseTemplateId).get(); if (!data) { return { content: [ { type: "text", text: `Exercise template with ID ${exerciseTemplateId} not found` } ] }; } const template = formatExerciseTemplate(data); return { content: [ { type: "text", text: JSON.stringify(template, null, 2) } ] }; } catch (error) { console.error( `Error fetching exercise template ${exerciseTemplateId}:`, error ); return { content: [ { type: "text", text: `Error fetching exercise template: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); } // src/tools/workouts.ts import { z as z4 } from "zod"; function registerWorkoutTools(server2, hevyClient2) { server2.tool( "get-workouts", "Get a paginated list of workouts. Returns workout details including title, description, start/end times, and exercises performed. Results are ordered from newest to oldest.", { page: z4.coerce.number().gte(1).default(1), pageSize: z4.coerce.number().int().gte(1).lte(10).default(5) }, async ({ page, pageSize }, extra) => { try { const data = await hevyClient2.v1.workouts.get({ queryParameters: { page, pageSize } }); const workouts = data?.workouts?.map((workout) => formatWorkout(workout)) || []; return { content: [ { type: "text", text: JSON.stringify(workouts, null, 2) } ] }; } catch (error) { console.error("Error fetching workouts:", error); return { content: [ { type: "text", text: `Error fetching workouts: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "get-workout", "Get complete details of a specific workout by ID. Returns all workout information including title, description, start/end times, and detailed exercise data.", { workoutId: z4.string().min(1) }, async ({ workoutId }, extra) => { try { const data = await hevyClient2.v1.workouts.byWorkoutId(workoutId).get(); if (!data) { return { content: [ { type: "text", text: `Workout with ID ${workoutId} not found` } ] }; } const workout = formatWorkout(data); return { content: [ { type: "text", text: JSON.stringify(workout, null, 2) } ] }; } catch (error) { console.error(`Error fetching workout ${workoutId}:`, error); return { content: [ { type: "text", text: `Error fetching workout: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "get-workout-count", "Get the total number of workouts on the account. Useful for pagination or statistics.", {}, async (_, extra) => { try { const data = await hevyClient2.v1.workouts.count.get(); return { content: [ { type: "text", text: `Total workouts: ${data ? data.workoutCount || 0 : 0}` } ] }; } catch (error) { console.error("Error fetching workout count:", error); return { content: [ { type: "text", text: `Error fetching workout count: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "get-workout-events", "Retrieve a paged list of workout events (updates or deletes) since a given date. Events are ordered from newest to oldest. The intention is to allow clients to keep their local cache of workouts up to date without having to fetch the entire list of workouts.", { page: z4.coerce.number().int().gte(1).default(1), pageSize: z4.coerce.number().int().gte(1).lte(10).default(5), since: z4.string().default("1970-01-01T00:00:00Z") }, async ({ page, pageSize, since }, extra) => { try { const data = await hevyClient2.v1.workouts.events.get({ queryParameters: { page, pageSize, since } }); return { content: [ { type: "text", text: JSON.stringify(data?.events || [], null, 2) } ] }; } catch (error) { console.error("Error fetching workout events:", error); return { content: [ { type: "text", text: `Error fetching workout events: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "create-workout", "Create a new workout in your Hevy account. Requires title, start/end times, and at least one exercise with sets. Returns the complete workout details upon successful creation including the newly assigned workout ID.", { title: z4.string().min(1), description: z4.string().optional().nullable(), startTime: z4.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), endTime: z4.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), isPrivate: z4.boolean().default(false), exercises: z4.array( z4.object({ exerciseTemplateId: z4.string().min(1), supersetId: z4.coerce.number().nullable().optional(), notes: z4.string().optional().nullable(), sets: z4.array( z4.object({ type: z4.enum(["warmup", "normal", "failure", "dropset"]).default("normal"), weightKg: z4.coerce.number().optional().nullable(), reps: z4.coerce.number().int().optional().nullable(), distanceMeters: z4.coerce.number().int().optional().nullable(), durationSeconds: z4.coerce.number().int().optional().nullable(), rpe: z4.coerce.number().optional().nullable(), customMetric: z4.coerce.number().optional().nullable() }) ) }) ) }, async ({ title, description, startTime, endTime, isPrivate, exercises }, extra) => { try { const requestBody = { workout: { title, description: description || null, startTime, endTime, isPrivate, exercises: exercises.map((exercise) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, notes: exercise.notes || null, sets: exercise.sets.map((set) => ({ type: set.type, weightKg: set.weightKg || null, reps: set.reps || null, distanceMeters: set.distanceMeters || null, durationSeconds: set.durationSeconds || null, rpe: set.rpe || null, customMetric: set.customMetric || null })) })) } }; const data = await hevyClient2.v1.workouts.post(requestBody); if (!data) { return { content: [ { type: "text", text: "Failed to create workout" } ] }; } const workout = formatWorkout(data); return { content: [ { type: "text", text: `Workout created successfully: ${JSON.stringify(workout, null, 2)}` } ] }; } catch (error) { console.error("Error creating workout:", error); return { content: [ { type: "text", text: `Error creating workout: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); server2.tool( "update-workout", "Update an existing workout by ID. You can modify the title, description, start/end times, privacy setting, and exercise data. Returns the updated workout with all changes applied.", { workoutId: z4.string().min(1), title: z4.string().min(1), description: z4.string().optional().nullable(), startTime: z4.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), endTime: z4.string().regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/), isPrivate: z4.boolean().default(false), exercises: z4.array( z4.object({ exerciseTemplateId: z4.string().min(1), supersetId: z4.coerce.number().nullable().optional(), notes: z4.string().optional().nullable(), sets: z4.array( z4.object({ type: z4.enum(["warmup", "normal", "failure", "dropset"]).default("normal"), weightKg: z4.coerce.number().optional().nullable(), reps: z4.coerce.number().int().optional().nullable(), distanceMeters: z4.coerce.number().int().optional().nullable(), durationSeconds: z4.coerce.number().int().optional().nullable(), rpe: z4.coerce.number().optional().nullable(), customMetric: z4.coerce.number().optional().nullable() }) ) }) ) }, async ({ workoutId, title, description, startTime, endTime, isPrivate, exercises }, extra) => { try { const requestBody = { workout: { title, description: description || null, startTime, endTime, isPrivate, exercises: exercises.map((exercise) => ({ exerciseTemplateId: exercise.exerciseTemplateId, supersetId: exercise.supersetId || null, notes: exercise.notes || null, sets: exercise.sets.map((set) => ({ type: set.type, weightKg: set.weightKg || null, reps: set.reps || null, distanceMeters: set.distanceMeters || null, durationSeconds: set.durationSeconds || null, rpe: set.rpe || null, customMetric: set.customMetric || null })) })) } }; const data = await hevyClient2.v1.workouts.byWorkoutId(workoutId).put(requestBody); if (!data) { return { content: [ { type: "text", text: `Failed to update workout with ID ${workoutId}` } ] }; } const workout = formatWorkout(data); return { content: [ { type: "text", text: `Workout updated successfully: ${JSON.stringify(workout, null, 2)}` } ] }; } catch (error) { console.error(`Error updating workout ${workoutId}:`, error); return { content: [ { type: "text", text: `Error updating workout: ${error instanceof Error ? error.message : String(error)}` } ], isError: true }; } } ); } // src/utils/hevyClient.ts import { ApiKeyAuthenticationProvider, ApiKeyLocation } from "@microsoft/kiota-abstractions"; import { FetchRequestAdapter } from "@microsoft/kiota-http-fetchlibrary"; // src/generated/client/models/index.ts function createDeletedWorkoutFromDiscriminatorValue(parseNode) { return deserializeIntoDeletedWorkout; } function createExerciseTemplateFromDiscriminatorValue(parseNode) { return deserializeIntoExerciseTemplate; } function createPaginatedWorkoutEventsFromDiscriminatorValue(parseNode) { return deserializeIntoPaginatedWorkoutEvents; } function createRoutine_exercises_setsFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine_exercises_sets; } function createRoutine_exercisesFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine_exercises; } function createRoutineFolderFromDiscriminatorValue(parseNode) { return deserializeIntoRoutineFolder; } function createRoutineFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine; } function createUpdatedWorkoutFromDiscriminatorValue(parseNode) { return deserializeIntoUpdatedWorkout; } function createWorkout_exercises_setsFromDiscriminatorValue(parseNode) { return deserializeIntoWorkout_exercises_sets; } function createWorkout_exercisesFromDiscriminatorValue(parseNode) { return deserializeIntoWorkout_exercises; } function createWorkoutFromDiscriminatorValue(parseNode) { return deserializeIntoWorkout; } function deserializeIntoDeletedWorkout(deletedWorkout = {}) { return { "deleted_at": (n) => { deletedWorkout.deletedAt = n.getStringValue(); }, "id": (n) => { deletedWorkout.id = n.getStringValue(); }, "type": (n) => { deletedWorkout.type = n.getStringValue(); } }; } function deserializeIntoExerciseTemplate(exerciseTemplate = {}) { return { "id": (n) => { exerciseTemplate.id = n.getStringValue(); }, "is_custom": (n) => { exerciseTemplate.isCustom = n.getBooleanValue(); }, "primary_muscle_group": (n) => { exerciseTemplate.primaryMuscleGroup = n.getStringValue(); }, "secondary_muscle_groups": (n) => { exerciseTemplate.secondaryMuscleGroups = n.getCollectionOfPrimitiveValues(); }, "title": (n) => { exerciseTemplate.title = n.getStringValue(); }, "type": (n) => { exerciseTemplate.type = n.getStringValue(); } }; } function deserializeIntoPaginatedWorkoutEvents(paginatedWorkoutEvents = {}) { return { "events": (n) => { paginatedWorkoutEvents.events = n.getCollectionOfObjectValues(createDeletedWorkoutFromDiscriminatorValue) ?? n.getCollectionOfObjectValues(createUpdatedWorkoutFromDiscriminatorValue); }, "page": (n) => { paginatedWorkoutEvents.page = n.getNumberValue(); }, "page_count": (n) => { paginatedWorkoutEvents.pageCount = n.getNumberValue(); } }; } function deserializeIntoRoutine(routine = {}) { return { "created_at": (n) => { routine.createdAt = n.getStringValue(); }, "exercises": (n) => { routine.exercises = n.getCollectionOfObjectValues(createRoutine_exercisesFromDiscriminatorValue); }, "folder_id": (n) => { routine.folderId = n.getNumberValue(); }, "id": (n) => { routine.id = n.getStringValue(); }, "title": (n) => { routine.title = n.getStringValue(); }, "updated_at": (n) => { routine.updatedAt = n.getStringValue(); } }; } function deserializeIntoRoutine_exercises(routine_exercises = {}) { return { "exercise_template_id": (n) => { routine_exercises.exerciseTemplateId = n.getStringValue(); }, "index": (n) => { routine_exercises.index = n.getNumberValue(); }, "notes": (n) => { routine_exercises.notes = n.getStringValue(); }, "sets": (n) => { routine_exercises.sets = n.getCollectionOfObjectValues(createRoutine_exercises_setsFromDiscriminatorValue); }, "supersets_id": (n) => { routine_exercises.supersetsId = n.getNumberValue(); }, "title": (n) => { routine_exercises.title = n.getStringValue(); } }; } function deserializeIntoRoutine_exercises_sets(routine_exercises_sets = {}) { return { "custom_metric": (n) => { routine_exercises_sets.customMetric = n.getNumberValue(); }, "distance_meters": (n) => { routine_exercises_sets.distanceMeters = n.getNumberValue(); }, "duration_seconds": (n) => { routine_exercises_sets.durationSeconds = n.getNumberValue(); }, "index": (n) => { routine_exercises_sets.index = n.getNumberValue(); }, "reps": (n) => { routine_exercises_sets.reps = n.getNumberValue(); }, "rpe": (n) => { routine_exercises_sets.rpe = n.getNumberValue(); }, "type": (n) => { routine_exercises_sets.type = n.getStringValue(); }, "weight_kg": (n) => { routine_exercises_sets.weightKg = n.getNumberValue(); } }; } function deserializeIntoRoutineFolder(routineFolder = {}) { return { "created_at": (n) => { routineFolder.createdAt = n.getStringValue(); }, "id": (n) => { routineFolder.id = n.getNumberValue(); }, "index": (n) => { routineFolder.index = n.getNumberValue(); }, "title": (n) => { routineFolder.title = n.getStringValue(); }, "updated_at": (n) => { routineFolder.updatedAt = n.getStringValue(); } }; } function deserializeIntoUpdatedWorkout(updatedWorkout = {}) { return { "type": (n) => { updatedWorkout.type = n.getStringValue(); }, "workout": (n) => { updatedWorkout.workout = n.getObjectValue(createWorkoutFromDiscriminatorValue); } }; } function deserializeIntoWorkout(workout = {}) { return { "created_at": (n) => { workout.createdAt = n.getStringValue(); }, "description": (n) => { workout.description = n.getStringValue(); }, "end_time": (n) => { workout.endTime = n.getNumberValue(); }, "exercises": (n) => { workout.exercises = n.getCollectionOfObjectValues(createWorkout_exercisesFromDiscriminatorValue); }, "id": (n) => { workout.id = n.getStringValue(); }, "start_time": (n) => { workout.startTime = n.getNumberValue(); }, "title": (n) => { workout.title = n.getStringValue(); }, "updated_at": (n) => { workout.updatedAt = n.getStringValue(); } }; } function deserializeIntoWorkout_exercises(workout_exercises = {}) { return { "exercise_template_id": (n) => { workout_exercises.exerciseTemplateId = n.getStringValue(); }, "index": (n) => { workout_exercises.index = n.getNumberValue(); }, "notes": (n) => { workout_exercises.notes = n.getStringValue(); }, "sets": (n) => { workout_exercises.sets = n.getCollectionOfObjectValues(createWorkout_exercises_setsFromDiscriminatorValue); }, "supersets_id": (n) => { workout_exercises.supersetsId = n.getNumberValue(); }, "title": (n) => { workout_exercises.title = n.getStringValue(); } }; } function deserializeIntoWorkout_exercises_sets(workout_exercises_sets = {}) { return { "custom_metric": (n) => { workout_exercises_sets.customMetric = n.getNumberValue(); }, "distance_meters": (n) => { workout_exercises_sets.distanceMeters = n.getNumberValue(); }, "duration_seconds": (n) => { workout_exercises_sets.durationSeconds = n.getNumberValue(); }, "index": (n) => { workout_exercises_sets.index = n.getNumberValue(); }, "reps": (n) => { workout_exercises_sets.reps = n.getNumberValue(); }, "rpe": (n) => { workout_exercises_sets.rpe = n.getNumberValue(); }, "type": (n) => { workout_exercises_sets.type = n.getStringValue(); }, "weight_kg": (n) => { workout_exercises_sets.weightKg = n.getNumberValue(); } }; } function serializePostRoutineFolderRequestBody(writer, postRoutineFolderRequestBody = {}) { if (postRoutineFolderRequestBody) { writer.writeObjectValue("routine_folder", postRoutineFolderRequestBody.routineFolder, serializePostRoutineFolderRequestBody_routine_folder); writer.writeAdditionalData(postRoutineFolderRequestBody.additionalData); } } function serializePostRoutineFolderRequestBody_routine_folder(writer, postRoutineFolderRequestBody_routine_folder = {}) { if (postRoutineFolderRequestBody_routine_folder) { writer.writeStringValue("title", postRoutineFolderRequestBody_routine_folder.title); writer.writeAdditionalData(postRoutineFolderRequestBody_routine_folder.additionalData); } } function serializePostRoutinesRequestBody(writer, postRoutinesRequestBody = {}) { if (postRoutinesRequestBody) { writer.writeObjectValue("routine", postRoutinesRequestBody.routine, serializePostRoutinesRequestBody_routine); writer.writeAdditionalData(postRoutinesRequestBody.additionalData); } } function serializePostRoutinesRequestBody_routine(writer, postRoutinesRequestBody_routine = {}) { if (postRoutinesRequestBody_routine) { writer.writeCollectionOfObjectValues("exercises", postRoutinesRequestBody_routine.exercises, serializePostRoutinesRequestExercise); writer.writeNumberValue("folder_id", postRoutinesRequestBody_routine.folderId); writer.writeStringValue("notes", postRoutinesRequestBody_routine.notes); writer.writeStringValue("title", postRoutinesRequestBody_routine.title); writer.writeAdditionalData(postRoutinesRequestBody_routine.additionalData); } } function serializePostRoutinesRequestExercise(writer, postRoutinesRequestExercise = {}) { if (postRoutinesRequestExercise) { writer.writeStringValue("exercise_template_id", postRoutinesRequestExercise.exerciseTemplateId); writer.writeStringValue("notes", postRoutinesRequestExercise.notes); writer.writeNumberValue("rest_seconds", postRoutinesRequestExercise.restSeconds); writer.writeCollectionOfObjectValues("sets", postRoutinesRequestExercise.sets, serializePostRoutinesRequestSet); writer.writeNumberValue("superset_id", postRoutinesRequestExercise.supersetId); writer.writeAdditionalData(postRoutinesRequestExercise.additionalData); } } function serializePostRoutinesRequestSet(writer, postRoutinesRequestSet = {}) { if (postRoutinesRequestSet) { writer.writeNumberValue("custom_metric", postRoutinesRequestSet.customMetric); writer.writeNumberValue("distance_meters", postRoutinesRequestSet.distanceMeters); writer.writeNumberValue("duration_seconds", postRoutinesRequestSet.durationSeconds); writer.writeNumberValue("reps", postRoutinesRequestSet.reps); writer.writeEnumValue("type", postRoutinesRequestSet.type); writer.writeNumberValue("weight_kg", postRoutinesRequestSet.weightKg); writer.writeAdditionalData(postRoutinesRequestSet.additionalData); } } function serializePostWorkoutsRequestBody(writer, postWorkoutsRequestBody = {}) { if (postWorkoutsRequestBody) { writer.writeObjectValue("workout", postWorkoutsRequestBody.workout, serializePostWorkoutsRequestBody_workout); writer.writeAdditionalData(postWorkoutsRequestBody.additionalData); } } function serializePostWorkoutsRequestBody_workout(writer, postWorkoutsRequestBody_workout = {}) { if (postWorkoutsRequestBody_workout) { writer.writeStringValue("description", postWorkoutsRequestBody_workout.description); writer.writeStringValue("end_time", postWorkoutsRequestBody_workout.endTime); writer.writeCollectionOfObjectValues("exercises", postWorkoutsRequestBody_workout.exercises, serializePostWorkoutsRequestExercise); writer.writeBooleanValue("is_private", postWorkoutsRequestBody_workout.isPrivate); writer.writeStringValue("start_time", postWorkoutsRequestBody_workout.startTime); writer.writeStringValue("title", postWorkoutsRequestBody_workout.title); writer.writeAdditionalData(postWorkoutsRequestBody_workout.additionalData); } } function serializePostWorkoutsRequestExercise(writer, postWorkoutsRequestExercise = {}) { if (postWorkoutsRequestExercise) { writer.writeStringValue("exercise_template_id", postWorkoutsRequestExercise.exerciseTemplateId); writer.writeStringValue("notes", postWorkoutsRequestExercise.notes); writer.writeCollectionOfObjectValues("sets", postWorkoutsRequestExercise.sets, serializePostWorkoutsRequestSet); writer.writeNumberValue("superset_id", postWorkoutsRequestExercise.supersetId); writer.writeAdditionalData(postWorkoutsRequestExercise.additionalData); } } function serializePostWorkoutsRequestSet(writer, postWorkoutsRequestSet = {}) { if (postWorkoutsRequestSet) { writer.writeNumberValue("custom_metric", postWorkoutsRequestSet.customMetric); writer.writeNumberValue("distance_meters", postWorkoutsRequestSet.distanceMeters); writer.writeNumberValue("duration_seconds", postWorkoutsRequestSet.durationSeconds); writer.writeNumberValue("reps", postWorkoutsRequestSet.reps); writer.writeNumberValue("rpe", postWorkoutsRequestSet.rpe); writer.writeEnumValue("type", postWorkoutsRequestSet.type); writer.writeNumberValue("weight_kg", postWorkoutsRequestSet.weightKg); writer.writeAdditionalData(postWorkoutsRequestSet.additionalData); } } function serializePutRoutinesRequestBody(writer, putRoutinesRequestBody = {}) { if (putRoutinesRequestBody) { writer.writeObjectValue("routine", putRoutinesRequestBody.routine, serializePutRoutinesRequestBody_routine); writer.writeAdditionalData(putRoutinesRequestBody.additionalData); } } function serializePutRoutinesRequestBody_routine(writer, putRoutinesRequestBody_routine = {}) { if (putRoutinesRequestBody_routine) { writer.writeCollectionOfObjectValues("exercises", putRoutinesRequestBody_routine.exercises, serializePutRoutinesRequestExercise); writer.writeStringValue("notes", putRoutinesRequestBody_routine.notes); writer.writeStringValue("title", putRoutinesRequestBody_routine.title); writer.writeAdditionalData(putRoutinesRequestBody_routine.additionalData); } } function serializePutRoutinesRequestExercise(writer, putRoutinesRequestExercise = {}) { if (putRoutinesRequestExercise) { writer.writeStringValue("exercise_template_id", putRoutinesRequestExercise.exerciseTemplateId); writer.writeStringValue("notes", putRoutinesRequestExercise.notes); writer.writeNumberValue("rest_seconds", putRoutinesRequestExercise.restSeconds); writer.writeCollectionOfObjectValues("sets", putRoutinesRequestExercise.sets, serializePutRoutinesRequestSet); writer.writeNumberValue("superset_id", putRoutinesRequestExercise.supersetId); writer.writeAdditionalData(putRoutinesRequestExercise.additionalData); } } function serializePutRoutinesRequestSet(writer, putRoutinesRequestSet = {}) { if (putRoutinesRequestSet) { writer.writeNumberValue("custom_metric", putRoutinesRequestSet.customMetric); writer.writeNumberValue("distance_meters", putRoutinesRequestSet.distanceMeters); writer.writeNumberValue("duration_seconds", putRoutinesRequestSet.durationSeconds); writer.writeNumberValue("reps", putRoutinesRequestSet.reps); writer.writeEnumValue("type", putRoutinesRequestSet.type); writer.writeNumberValue("weight_kg", putRoutinesRequestSet.weightKg); writer.writeAdditionalData(putRoutinesRequestSet.additionalData); } } // src/generated/client/v1/exercise_templates/item/index.ts var WithExerciseTemplateItemRequestBuilderUriTemplate = "{+baseurl}/v1/exercise_templates/{exerciseTemplateId}"; var WithExerciseTemplateItemRequestBuilderRequestsMetadata = { get: { uriTemplate: WithExerciseTemplateItemRequestBuilderUriTemplate, responseBodyContentType: "application/json", adapterMethodName: "send", responseBodyFactory: createExerciseTemplateFromDiscriminatorValue } }; // src/generated/client/v1/exercise_templates/index.ts function createExercise_templatesGetResponseFromDiscriminatorValue(parseNode) { return deserializeIntoExercise_templatesGetResponse; } function deserializeIntoExercise_templatesGetResponse(exercise_templatesGetResponse = {}) { return { "exercise_templates": (n) => { exercise_templatesGetResponse.exerciseTemplates = n.getCollectionOfObjectValues(createExerciseTemplateFromDiscriminatorValue); }, "page": (n) => { exercise_templatesGetResponse.page = n.getNumberValue(); }, "page_count": (n) => { exercise_templatesGetResponse.pageCount = n.getNumberValue(); } }; } var Exercise_templatesRequestBuilderUriTemplate = "{+baseurl}/v1/exercise_templates{?page*,pageSize*}"; var Exercise_templatesRequestBuilderNavigationMetadata = { byExerciseTemplateId: { requestsMetadata: WithExerciseTemplateItemRequestBuilderRequestsMetadata, pathParametersMappings: ["exerciseTemplateId"] } }; var Exercise_templatesRequestBuilderRequestsMetadata = { get: { uriTemplate: Exercise_templatesRequestBuilderUriTemplate, responseBodyContentType: "application/json", adapterMethodName: "send", responseBodyFactory: createExercise_templatesGetResponseFromDiscriminatorValue } }; // src/generated/client/v1/routine_folders/item/index.ts var WithFolderItemRequestBuilderUriTemplate = "{+baseurl}/v1/routine_folders/{folderId}"; var WithFolderItemRequestBuilderRequestsMetadata = { get: { uriTemplate: WithFolderItemRequestBuilderUriTemplate, responseBodyContentType: "application/json", adapterMethodName: "send", responseBodyFactory: createRoutineFolderFromDiscriminatorValue } }; // src/generated/client/v1/routine_folders/index.ts function createRoutine_foldersGetResponseFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine_foldersGetResponse; } function createRoutineFolder400ErrorFromDiscriminatorValue(parseNode) { return deserializeIntoRoutineFolder400Error; } function deserializeIntoRoutine_foldersGetResponse(routine_foldersGetResponse = {}) { return { "page": (n) => { routine_foldersGetResponse.page = n.getNumberValue(); }, "page_count": (n) => { routine_foldersGetResponse.pageCount = n.getNumberValue(); }, "routine_folders": (n) => { routine_foldersGetResponse.routineFolders = n.getCollectionOfObjectValues(createRoutineFolderFromDiscriminatorValue); } }; } function deserializeIntoRoutineFolder400Error(routineFolder400Error = {}) { return { "error": (n) => { routineFolder400Error.errorEscaped = n.getStringValue(); } }; } var Routine_foldersRequestBuilderUriTemplate = "{+baseurl}/v1/routine_folders{?page*,pageSize*}"; var Routine_foldersRequestBuilderNavigationMetadata = { byFolderId: { requestsMetadata: WithFolderItemRequestBuilderRequestsMetadata, pathParametersMappings: ["folderId"] } }; var Routine_foldersRequestBuilderRequestsMetadata = { get: { uriTemplate: Routine_foldersRequestBuilderUriTemplate, responseBodyContentType: "application/json", adapterMethodName: "send", responseBodyFactory: createRoutine_foldersGetResponseFromDiscriminatorValue }, post: { uriTemplate: Routine_foldersRequestBuilderUriTemplate, responseBodyContentType: "application/json", errorMappings: { 400: createRoutineFolder400ErrorFromDiscriminatorValue }, adapterMethodName: "send", responseBodyFactory: createRoutineFolderFromDiscriminatorValue, requestBodyContentType: "application/json", requestBodySerializer: serializePostRoutineFolderRequestBody, requestInformationContentSetMethod: "setContentFromParsable" } }; // src/generated/client/v1/routines/item/index.ts function createRoutine400ErrorFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine400Error; } function createRoutine404ErrorFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine404Error; } function deserializeIntoRoutine400Error(routine400Error = {}) { return { "error": (n) => { routine400Error.errorEscaped = n.getStringValue(); } }; } function deserializeIntoRoutine404Error(routine404Error = {}) { return { "error": (n) => { routine404Error.errorEscaped = n.getStringValue(); } }; } var WithRoutineItemRequestBuilderUriTemplate = "{+baseurl}/v1/routines/{routineId}"; var WithRoutineItemRequestBuilderRequestsMetadata = { put: { uriTemplate: WithRoutineItemRequestBuilderUriTemplate, responseBodyContentType: "application/json", errorMappings: { 400: createRoutine400ErrorFromDiscriminatorValue, 404: createRoutine404ErrorFromDiscriminatorValue }, adapterMethodName: "send", responseBodyFactory: createRoutineFromDiscriminatorValue, requestBodyContentType: "application/json", requestBodySerializer: serializePutRoutinesRequestBody, requestInformationContentSetMethod: "setContentFromParsable" } }; // src/generated/client/v1/routines/index.ts function createRoutine400ErrorFromDiscriminatorValue2(parseNode) { return deserializeIntoRoutine400Error2; } function createRoutine403ErrorFromDiscriminatorValue(parseNode) { return deserializeIntoRoutine