hevy-shared 1.0.906 → 1.0.908

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.
@@ -1,16 +1,20 @@
1
- import { WeeklyTrainingFrequency, TrainingGoal, TrainingLevel, Equipment, SimplifiedMuscleGroup, MuscleGroup, LibraryExercise, ExerciseCategory } from '.';
1
+ import { WeeklyTrainingFrequency, TrainingGoal, TrainingLevel, SimplifiedMuscleGroup, MuscleGroup, LibraryExercise, ExerciseCategory, GranularEquipment } from '.';
2
2
  export type HevyTrainerExerciseCategory = typeof hevyTrainerExerciseCategories[number];
3
3
  export type HevyTrainerRoutineName = typeof routineNames[number];
4
- export type HevyTrainerProgramEquipment = Extract<Equipment, 'barbell' | 'dumbbell' | 'machine'>;
5
- export declare const hevyTrainerExerciseCategories: readonly ["compound", "isolation"];
6
- export type WorkoutDurationMinutes = typeof workoutDurationOptions[number];
7
4
  export declare const workoutDurationOptions: readonly [40, 60, 80];
5
+ export type WorkoutDurationMinutes = typeof workoutDurationOptions[number];
6
+ export declare const trainerGymTypes: readonly ["home_gym", "garage_gym", "commercial_gym", "full_gym"];
7
+ export type TrainerGymType = typeof trainerGymTypes[number];
8
+ export declare const granularEquipmentDefaults: {
9
+ [key in TrainerGymType]: GranularEquipment[];
10
+ };
11
+ export declare const hevyTrainerExerciseCategories: readonly ["compound", "isolation"];
8
12
  export declare const defaultDurationPerFrequency: Record<WeeklyTrainingFrequency, WorkoutDurationMinutes>;
9
13
  export declare const routineNames: readonly ["full_body_1", "full_body_2_a", "full_body_2_b", "full_body_3_a", "full_body_3_b", "full_body_3_c", "upper_1_a", "lower_1_a", "upper_1_b", "lower_1_b", "push_1", "pull_1", "legs_1", "upper_2", "lower_2", "push_2_a", "pull_2_a", "legs_2_a", "push_2_b", "pull_2_b", "legs_2_b"];
10
14
  export type exerciseId = string;
11
15
  export interface ExerciseSelectionCriteria {
12
16
  exerciseCategory: HevyTrainerExerciseCategory | 'all';
13
- equipments: HevyTrainerProgramEquipment[];
17
+ granularEquipments: GranularEquipment[];
14
18
  routineBarbellExerciseCount: number;
15
19
  level: TrainingLevel;
16
20
  goal: TrainingGoal;
@@ -32,7 +36,7 @@ export interface ProgramGenerationParams<T extends HevyTrainerLibraryExercise> {
32
36
  selectedDays: WeeklyTrainingFrequency;
33
37
  selectedGoal: TrainingGoal;
34
38
  selectedLevel: TrainingLevel;
35
- selectedEquipments: HevyTrainerProgramEquipment[];
39
+ selectedGranularEquipments: GranularEquipment[];
36
40
  selectedWorkoutDurationMinutes?: WorkoutDurationMinutes;
37
41
  exerciseStore: T[];
38
42
  focusMuscle?: SimplifiedMuscleGroup;
@@ -150,7 +154,7 @@ export declare const getPrioritySortedExercises: <T extends HevyTrainerLibraryEx
150
154
  * Selects the best exercise for a given prescription using a multi-pass strategy
151
155
  */
152
156
  export declare const pickExerciseForPrescription: <T extends HevyTrainerLibraryExercise>(params: ExerciseSelectionParams<T>) => T | undefined;
153
- export type HevyTrainerLibraryExercise = Pick<LibraryExercise, 'id' | 'title' | 'priority' | 'muscle_group' | 'other_muscles' | 'exercise_type' | 'equipment_category' | 'category' | 'level' | 'goal'>;
157
+ export type HevyTrainerLibraryExercise = Pick<LibraryExercise, 'id' | 'title' | 'priority' | 'muscle_group' | 'other_muscles' | 'exercise_type' | 'equipment_category' | 'category' | 'level' | 'goal' | 'granular_equipments'>;
154
158
  export interface ExercisePrescriptionError {
155
159
  type: 'exercise_not_found';
156
160
  prescription: ExercisePrescription;
@@ -158,7 +162,7 @@ export interface ExercisePrescriptionError {
158
162
  context: {
159
163
  goal: TrainingGoal;
160
164
  level: TrainingLevel;
161
- equipments: HevyTrainerProgramEquipment[];
165
+ granularEquipments: GranularEquipment[];
162
166
  focusMuscle?: SimplifiedMuscleGroup;
163
167
  };
164
168
  }
@@ -1,10 +1,82 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateProgram = exports.pickExerciseForPrescription = exports.getPrioritySortedExercises = exports.normalizeExerciseCategory = exports.getTrainerRestTimerSeconds = exports.getTrainerRepRange = exports.getTrainerSetCount = exports.programSplits = exports.frequencyMap = exports.routineNames = exports.defaultDurationPerFrequency = exports.workoutDurationOptions = exports.hevyTrainerExerciseCategories = void 0;
3
+ exports.generateProgram = exports.pickExerciseForPrescription = exports.getPrioritySortedExercises = exports.normalizeExerciseCategory = exports.getTrainerRestTimerSeconds = exports.getTrainerRepRange = exports.getTrainerSetCount = exports.programSplits = exports.frequencyMap = exports.routineNames = exports.defaultDurationPerFrequency = exports.hevyTrainerExerciseCategories = exports.granularEquipmentDefaults = exports.trainerGymTypes = exports.workoutDurationOptions = void 0;
4
4
  const _1 = require(".");
5
5
  const MAX_BARBELL_EXERCISES_PER_ROUTINE = 2;
6
- exports.hevyTrainerExerciseCategories = ['compound', 'isolation'];
7
6
  exports.workoutDurationOptions = [40, 60, 80];
7
+ exports.trainerGymTypes = [
8
+ 'home_gym',
9
+ 'garage_gym',
10
+ 'commercial_gym',
11
+ 'full_gym',
12
+ ];
13
+ exports.granularEquipmentDefaults = {
14
+ home_gym: ['dumbbell', 'pullup_bar', 'adjustable_bench'],
15
+ garage_gym: [
16
+ 'dumbbell',
17
+ 'kettlebell',
18
+ 'barbell',
19
+ 'plate',
20
+ 'pullup_bar',
21
+ 'dip_bar',
22
+ 'squat_rack',
23
+ 'adjustable_bench',
24
+ 'spinning',
25
+ ],
26
+ commercial_gym: [
27
+ 'dumbbell',
28
+ 'barbell',
29
+ 'plate',
30
+ 'ez_bar',
31
+ 'pullup_bar',
32
+ 'dip_bar',
33
+ 'squat_rack',
34
+ 'adjustable_bench',
35
+ 'single_cable_machine',
36
+ 'lat_pulldown_cable',
37
+ 'leg_press_machine',
38
+ 'smith_machine',
39
+ 'stack_machines',
40
+ 'treadmill',
41
+ 'elliptical_trainer',
42
+ 'spinning',
43
+ ],
44
+ // All equipment is available in a full gym
45
+ full_gym: [
46
+ 'barbell',
47
+ 'dumbbell',
48
+ 'kettlebell',
49
+ 'plate',
50
+ 'medicine_ball',
51
+ 'ez_bar',
52
+ 'landmine',
53
+ 'trap_bar',
54
+ 'pullup_bar',
55
+ 'dip_bar',
56
+ 'squat_rack',
57
+ 'flat_bench',
58
+ 'adjustable_bench',
59
+ 'dual_cable_machine',
60
+ 'single_cable_machine',
61
+ 'lat_pulldown_cable',
62
+ 'leg_press_machine',
63
+ 'smith_machine',
64
+ 't_bar',
65
+ 'plate_machines',
66
+ 'stack_machines',
67
+ 'treadmill',
68
+ 'elliptical_trainer',
69
+ 'rowing_machine',
70
+ 'spinning',
71
+ 'stair_machine',
72
+ 'air_bike',
73
+ 'suspension_band',
74
+ 'battle_rope',
75
+ 'rings',
76
+ 'rope',
77
+ ],
78
+ };
79
+ exports.hevyTrainerExerciseCategories = ['compound', 'isolation'];
8
80
  // These are the values that Philip decided for the default duration per frequency
9
81
  exports.defaultDurationPerFrequency = {
10
82
  1: 80,
@@ -120,18 +192,17 @@ const isFocusMuscleExtraExerciseAllowed = (templateName, focusMuscle) => {
120
192
  }
121
193
  };
122
194
  /**
123
- * Checks if an exercise is compatible with the user's equipments
195
+ * Checks if an exercise is compatible with the user's selected granular equipments
124
196
  *
125
- * - We enable plate exercises where users have barbell as an equipment
126
- * - None and other equipment categories are also always allowed
127
- * - Otherwise, the exercise is only allowed if the user has that equipment
197
+ * - If the exercise has no granular equipments, it is compatible no matter what the user has selected
198
+ * - Otherwise, the exercise is only allowed if the user has all the granular equipments
128
199
  */
129
- const isEquipmentCompatible = (exercise, allowedEquipments) => {
130
- return (allowedEquipments.includes(exercise.equipment_category) ||
131
- exercise.equipment_category === 'none' ||
132
- exercise.equipment_category === 'other' ||
133
- (exercise.equipment_category === 'plate' &&
134
- allowedEquipments.includes('barbell')));
200
+ const isEquipmentCompatible = (exercise, userSelectedGranularEquipments) => {
201
+ if (!exercise.granular_equipments ||
202
+ exercise.granular_equipments.length === 0) {
203
+ return true;
204
+ }
205
+ return exercise.granular_equipments.every((granularEquipment) => userSelectedGranularEquipments.includes(granularEquipment));
135
206
  };
136
207
  /**
137
208
  * Checks if the routine barbell exercise limit is exceeded
@@ -232,8 +303,8 @@ const isExerciseMatch = (exercise, criteria) => {
232
303
  criteria.exerciseCategory === 'compound');
233
304
  const levelMatch = (_b = (_a = exercise.level) === null || _a === void 0 ? void 0 : _a.includes(criteria.level)) !== null && _b !== void 0 ? _b : false;
234
305
  const goalMatch = (_d = (_c = exercise.goal) === null || _c === void 0 ? void 0 : _c.includes(criteria.goal)) !== null && _d !== void 0 ? _d : false;
235
- const equipmentMatch = isEquipmentCompatible(exercise, criteria.equipments);
236
- const barbellLimitOk = !isBarbellLimitExceeded(exercise, criteria.routineBarbellExerciseCount, criteria.equipments);
306
+ const equipmentMatch = isEquipmentCompatible(exercise, criteria.granularEquipments);
307
+ const barbellLimitOk = !isBarbellLimitExceeded(exercise, criteria.routineBarbellExerciseCount, criteria.granularEquipments);
237
308
  return (categoryMatch && levelMatch && goalMatch && equipmentMatch && barbellLimitOk);
238
309
  };
239
310
  /**
@@ -243,7 +314,7 @@ const isAlternativeIsolationExerciseMatch = (exercise, criteria) => {
243
314
  var _a, _b;
244
315
  const isIsolationCategory = criteria.exerciseCategory === 'isolation';
245
316
  const isAlternativeExercise = isolationExerciseAlternatives[criteria.muscleGroup].includes(exercise.id);
246
- const equipmentMatch = isEquipmentCompatible(exercise, criteria.equipments);
317
+ const equipmentMatch = isEquipmentCompatible(exercise, criteria.granularEquipments);
247
318
  const levelMatch = (_b = (_a = exercise.level) === null || _a === void 0 ? void 0 : _a.includes(criteria.level)) !== null && _b !== void 0 ? _b : false;
248
319
  return (isIsolationCategory && isAlternativeExercise && equipmentMatch && levelMatch);
249
320
  };
@@ -317,7 +388,7 @@ exports.pickExerciseForPrescription = pickExerciseForPrescription;
317
388
  */
318
389
  const generateProgram = (params) => {
319
390
  var _a;
320
- const { trainerAlgorithmSettings, selectedDays, selectedGoal, selectedLevel, selectedEquipments, selectedWorkoutDurationMinutes, exerciseStore, focusMuscle, excludedExerciseIds, } = params;
391
+ const { trainerAlgorithmSettings, selectedDays, selectedGoal, selectedLevel, selectedGranularEquipments, selectedWorkoutDurationMinutes, exerciseStore, focusMuscle, excludedExerciseIds, } = params;
321
392
  const routines = exports.programSplits[selectedDays];
322
393
  const program = {
323
394
  name: selectedDays,
@@ -356,7 +427,7 @@ const generateProgram = (params) => {
356
427
  sortedExercises,
357
428
  criteria: {
358
429
  exerciseCategory: exercisePrescription.category,
359
- equipments: selectedEquipments,
430
+ granularEquipments: selectedGranularEquipments,
360
431
  muscleGroup,
361
432
  routineBarbellExerciseCount,
362
433
  level: selectedLevel,
@@ -397,7 +468,7 @@ const generateProgram = (params) => {
397
468
  context: {
398
469
  goal: selectedGoal,
399
470
  level: selectedLevel,
400
- equipments: selectedEquipments,
471
+ granularEquipments: selectedGranularEquipments,
401
472
  focusMuscle,
402
473
  },
403
474
  });
package/built/index.d.ts CHANGED
@@ -647,6 +647,9 @@ export type TrainingLevel = Lookup<typeof trainingLevels>;
647
647
  export type ExerciseCategory = Lookup<typeof exerciseCategories>;
648
648
  export type HevyTrainerProgramEquipment = Extract<Equipment, 'barbell' | 'dumbbell' | 'machine'>;
649
649
  export declare const hevyTrainerProgramEquipments: readonly ["barbell", "dumbbell", "machine"];
650
+ export declare const granularEquipments: readonly ["barbell", "dumbbell", "kettlebell", "plate", "medicine_ball", "ez_bar", "landmine", "trap_bar", "pullup_bar", "dip_bar", "squat_rack", "flat_bench", "adjustable_bench", "dual_cable_machine", "single_cable_machine", "lat_pulldown_cable", "leg_press_machine", "smith_machine", "t_bar", "plate_machines", "stack_machines", "treadmill", "elliptical_trainer", "rowing_machine", "spinning", "stair_machine", "air_bike", "suspension_band", "battle_rope", "rings", "rope"];
651
+ export type GranularEquipment = Lookup<typeof granularEquipments>;
652
+ export declare const isGranularEquipment: (x: string) => x is GranularEquipment;
650
653
  export declare const weeklyTrainingFrequencies: readonly [1, 2, 3, 4, 5, 6];
651
654
  export type WeeklyTrainingFrequency = Lookup<typeof weeklyTrainingFrequencies>;
652
655
  /**
@@ -698,6 +701,7 @@ export interface LibraryExercise extends BaseExerciseTemplate {
698
701
  goal: TrainingGoal[] | undefined;
699
702
  level: TrainingLevel[] | undefined;
700
703
  category: ExerciseCategory | undefined;
704
+ granular_equipments: GranularEquipment[] | undefined;
701
705
  url_female?: string;
702
706
  thumbnail_url_female?: string;
703
707
  }
@@ -1251,7 +1255,9 @@ export interface HevyTrainerProgram {
1251
1255
  title: string;
1252
1256
  level: TrainingLevel;
1253
1257
  goal: TrainingGoal;
1258
+ /** @deprecated Use granular_equipments instead */
1254
1259
  equipments: HevyTrainerProgramEquipment[];
1260
+ granular_equipments: GranularEquipment[];
1255
1261
  weekly_frequency: WeeklyTrainingFrequency;
1256
1262
  routines: HevyTrainerRoutine[];
1257
1263
  focus_muscle?: SimplifiedMuscleGroup;
@@ -1263,7 +1269,9 @@ export interface PostHevyTrainerProgramRequestBody {
1263
1269
  title: string;
1264
1270
  level: TrainingLevel;
1265
1271
  goal: TrainingGoal;
1272
+ /** @deprecated Use granular_equipments instead */
1266
1273
  equipments: HevyTrainerProgramEquipment[];
1274
+ granular_equipments: GranularEquipment[];
1267
1275
  weekly_frequency: WeeklyTrainingFrequency;
1268
1276
  focus_muscle?: SimplifiedMuscleGroup;
1269
1277
  routines: RoutineUpdate[];
@@ -1277,7 +1285,9 @@ export interface UpdateHevyTrainerProgramRequestBody {
1277
1285
  title: string;
1278
1286
  level: TrainingLevel;
1279
1287
  goal: TrainingGoal;
1288
+ /** @deprecated Use granular_equipments instead */
1280
1289
  equipments: HevyTrainerProgramEquipment[];
1290
+ granular_equipments: GranularEquipment[];
1281
1291
  weekly_frequency: WeeklyTrainingFrequency;
1282
1292
  focus_muscle?: SimplifiedMuscleGroup;
1283
1293
  next_workout_index?: number;
@@ -1915,10 +1925,6 @@ export interface ExerciseHistoryWorkout {
1915
1925
  export declare const supportedScopes: readonly ["read-workout", "modify-workout", "read-routine", "modify-routine", "unrestricted"];
1916
1926
  export type OAuthScope = Lookup<typeof supportedScopes>;
1917
1927
  export declare const isOAuthScope: (x: string) => x is OAuthScope;
1918
- export interface MuscleGroupSetCount {
1919
- muscleGroup: MuscleGroup;
1920
- sets: number;
1921
- }
1922
1928
  export interface WorkoutsWithMediaBackofficeResponse {
1923
1929
  username: string;
1924
1930
  workouts: {
package/built/index.js CHANGED
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.isHevyTrainerRoutine = exports.isWorkoutBiometrics = exports.isHeartRateSamples = exports.isPublicWorkout = exports.isSetType = exports.isRPE = exports.validRpeValues = exports.isSetPersonalRecordType = exports.supportedInstructionsLanguages = exports.weeklyTrainingFrequencies = exports.hevyTrainerProgramEquipments = exports.exerciseCategories = exports.trainingLevels = exports.trainingGoals = exports.isCustomExerciseType = exports.customExericseTypes = exports.isExerciseType = exports.exerciseTypes = exports.isExerciseRepType = exports.exerciseRepTypes = exports.isEquipmentFilter = exports.equipmentFilters = exports.isEquipment = exports.equipments = exports.simplifiedMuscleGroupToMuscleGroups = exports.isMuscleGroupFilter = exports.muscleGroupFilters = exports.isMuscleGroup = exports.muscleGroups = exports.isSimplifiedMuscleGroup = exports.simplifiedMuscleGroups = exports.miscellaneousMuscles = exports.chestMuscles = exports.backMuscles = exports.legMuscles = exports.armMuscles = exports.shoulderMuscles = exports.coreMuscles = exports.DefaultClientConfiguration = exports.parseClientAuthTokenResponse = exports.isCoachRole = exports.isErrorResponse = exports.isLivePRVolumeOption = exports.isTimerVolumeOption = exports.isWeekday = exports.orderedWeekdays = exports.isBodyMeasurementUnit = exports.isDistanceUnitShort = exports.isDistanceUnit = exports.isWeightUnit = void 0;
18
- exports.isOAuthScope = exports.supportedScopes = exports.isSuggestedUserSource = exports.isValidUserWorkoutMetricsType = exports.isBodyMeasurementKey = exports.measurementsList = void 0;
17
+ exports.isHeartRateSamples = exports.isPublicWorkout = exports.isSetType = exports.isRPE = exports.validRpeValues = exports.isSetPersonalRecordType = exports.supportedInstructionsLanguages = exports.weeklyTrainingFrequencies = exports.isGranularEquipment = exports.granularEquipments = exports.hevyTrainerProgramEquipments = exports.exerciseCategories = exports.trainingLevels = exports.trainingGoals = exports.isCustomExerciseType = exports.customExericseTypes = exports.isExerciseType = exports.exerciseTypes = exports.isExerciseRepType = exports.exerciseRepTypes = exports.isEquipmentFilter = exports.equipmentFilters = exports.isEquipment = exports.equipments = exports.simplifiedMuscleGroupToMuscleGroups = exports.isMuscleGroupFilter = exports.muscleGroupFilters = exports.isMuscleGroup = exports.muscleGroups = exports.isSimplifiedMuscleGroup = exports.simplifiedMuscleGroups = exports.miscellaneousMuscles = exports.chestMuscles = exports.backMuscles = exports.legMuscles = exports.armMuscles = exports.shoulderMuscles = exports.coreMuscles = exports.DefaultClientConfiguration = exports.parseClientAuthTokenResponse = exports.isCoachRole = exports.isErrorResponse = exports.isLivePRVolumeOption = exports.isTimerVolumeOption = exports.isWeekday = exports.orderedWeekdays = exports.isBodyMeasurementUnit = exports.isDistanceUnitShort = exports.isDistanceUnit = exports.isWeightUnit = void 0;
18
+ exports.isOAuthScope = exports.supportedScopes = exports.isSuggestedUserSource = exports.isValidUserWorkoutMetricsType = exports.isBodyMeasurementKey = exports.measurementsList = exports.isHevyTrainerRoutine = exports.isWorkoutBiometrics = void 0;
19
19
  const typeUtils_1 = require("./typeUtils");
20
20
  __exportStar(require("./constants"), exports);
21
21
  __exportStar(require("./utils"), exports);
@@ -232,6 +232,41 @@ exports.hevyTrainerProgramEquipments = [
232
232
  'dumbbell',
233
233
  'machine',
234
234
  ];
235
+ exports.granularEquipments = [
236
+ 'barbell',
237
+ 'dumbbell',
238
+ 'kettlebell',
239
+ 'plate',
240
+ 'medicine_ball',
241
+ 'ez_bar',
242
+ 'landmine',
243
+ 'trap_bar',
244
+ 'pullup_bar',
245
+ 'dip_bar',
246
+ 'squat_rack',
247
+ 'flat_bench',
248
+ 'adjustable_bench',
249
+ 'dual_cable_machine',
250
+ 'single_cable_machine',
251
+ 'lat_pulldown_cable',
252
+ 'leg_press_machine',
253
+ 'smith_machine',
254
+ 't_bar',
255
+ 'plate_machines',
256
+ 'stack_machines',
257
+ 'treadmill',
258
+ 'elliptical_trainer',
259
+ 'rowing_machine',
260
+ 'spinning',
261
+ 'stair_machine',
262
+ 'air_bike',
263
+ 'suspension_band',
264
+ 'battle_rope',
265
+ 'rings',
266
+ 'rope',
267
+ ];
268
+ const isGranularEquipment = (x) => (0, typeUtils_1.isInArray)(x, exports.granularEquipments);
269
+ exports.isGranularEquipment = isGranularEquipment;
235
270
  exports.weeklyTrainingFrequencies = [1, 2, 3, 4, 5, 6];
236
271
  exports.supportedInstructionsLanguages = [
237
272
  'en',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hevy-shared",
3
- "version": "1.0.906",
3
+ "version": "1.0.908",
4
4
  "description": "",
5
5
  "main": "built/index.js",
6
6
  "types": "built/index.d.ts",