hevy-shared 1.0.924 → 1.0.926

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.
@@ -25,6 +25,7 @@ export interface ExerciseSelectionCriteria {
25
25
  level: TrainingLevel;
26
26
  goal: TrainingGoal;
27
27
  muscleGroup: MuscleGroup;
28
+ frequency: WeeklyTrainingFrequency;
28
29
  }
29
30
  export interface ExerciseSelectionContext {
30
31
  programUsedExerciseIds?: Set<string>;
@@ -195,7 +196,7 @@ export interface TrainerProgramResult {
195
196
  export interface TrainerProgramError {
196
197
  success: false;
197
198
  errors: ExercisePrescriptionError[];
198
- partialProgram?: TrainerProgram;
199
+ partialProgram: TrainerProgram;
199
200
  }
200
201
  export type TrainerProgramAttempt = TrainerProgramResult | TrainerProgramError;
201
202
  /**
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateProgram = exports.pickExerciseForPrescription = exports.getPrioritySortedExercises = exports.isEquipmentCompatible = exports.normalizeExerciseCategory = exports.getTrainerRestTimerSeconds = exports.getTrainerRepRange = exports.getTrainerSetCount = exports.programSplits = exports.frequencyMap = exports.routineNames = exports.defaultDurationPerFrequency = exports.hevyTrainerExerciseCategories = exports.granularEquipmentsToTrainerEquipments = exports.trainerEquipmentToGranularEquipments = exports.granularEquipmentDefaults = exports.trainerGymTypes = exports.workoutDurationOptions = void 0;
4
4
  const _1 = require(".");
5
- const MAX_BARBELL_EXERCISES_PER_ROUTINE = 2;
6
5
  exports.workoutDurationOptions = [40, 60, 80];
7
6
  exports.trainerGymTypes = [
8
7
  'home_gym',
@@ -71,6 +70,7 @@ exports.granularEquipmentDefaults = {
71
70
  'stair_machine',
72
71
  'air_bike',
73
72
  'suspension_band',
73
+ 'resistance_band',
74
74
  'battle_rope',
75
75
  'rings',
76
76
  'jump_rope',
@@ -278,16 +278,32 @@ const isEquipmentCompatible = (exercise, userSelectedGranularEquipments) => {
278
278
  return exercise.granular_equipments.every((granularEquipment) => allowedEquipments.includes(granularEquipment));
279
279
  };
280
280
  exports.isEquipmentCompatible = isEquipmentCompatible;
281
+ const MAX_BARBELL_EXERCISES_FOR_ONCE_PER_WEEK = 3;
281
282
  /**
282
- * Checks if the routine barbell exercise limit is exceeded
283
- *
284
- * - We allow up to 2 barbell exercises per routine
285
- * - Unless the user ONLY has barbell as an allowed equipment
283
+ * - If frequency is 1 and the candidate exercise is a barbell exercise
284
+ * - Then allow at most `MAX_BARBELL_EXERCISES_FOR_ONCE_PER_WEEK` barbell exercises
285
+ * - Only enforce the cap when the user has at least one "barbell substitute" equipment available
286
+ * (otherwise we allow barbell exercises to avoid running out of viable options)
286
287
  */
287
- const isBarbellLimitExceeded = (exercise, routineBarbellExerciseCount, allowedEquipments) => {
288
- return (exercise.equipment_category === 'barbell' &&
289
- routineBarbellExerciseCount >= MAX_BARBELL_EXERCISES_PER_ROUTINE &&
290
- allowedEquipments.length > 1);
288
+ const isBarbellExerciseAllowed = (exercise, routineBarbellExerciseCount, userEquipments, frequency) => {
289
+ const isCandidateBarbell = exercise.equipment_category === 'barbell';
290
+ const isOncePerWeek = frequency === 1;
291
+ if (!isCandidateBarbell || !isOncePerWeek)
292
+ return true;
293
+ const isAtOrOverLimit = routineBarbellExerciseCount >= MAX_BARBELL_EXERCISES_FOR_ONCE_PER_WEEK;
294
+ if (!isAtOrOverLimit)
295
+ return true;
296
+ const barbellSubstitutes = [
297
+ 'dumbbell',
298
+ 'dual_cable_machine',
299
+ 'single_cable_machine',
300
+ 'smith_machine',
301
+ 'plate_machines',
302
+ 'stack_machines',
303
+ ];
304
+ const hasAnySubstitute = barbellSubstitutes.some((substitute) => userEquipments.includes(substitute));
305
+ // If the user has substitutes, enforce the cap; otherwise allow barbell to avoid dead-ends.
306
+ return !hasAnySubstitute;
291
307
  };
292
308
  const isExerciseUsed = (exercise, context) => {
293
309
  var _a, _b, _c;
@@ -297,9 +313,29 @@ const isExerciseUsed = (exercise, context) => {
297
313
  false);
298
314
  };
299
315
  const isolationExerciseAlternatives = {
316
+ /**
317
+ * - B74A95BB (Kneeling Push Up)
318
+ * - 392887AA (Push Up)
319
+ * - 39C99849 (Incline Push Ups)
320
+ * - 982734D4 (Plate Press)
321
+ */
300
322
  chest: ['B74A95BB', '392887AA', '39C99849', '982734D4'],
323
+ /**
324
+ * - 6575F52D (Diamond Push Up)
325
+ * - CD6DC8E5 (Bench Dip)
326
+ */
301
327
  triceps: ['6575F52D', 'CD6DC8E5'],
328
+ /**
329
+ * - 32HKJ34K (Walking Lunge)
330
+ * - A733CC5B (Walking Lunge (Dumbbell))
331
+ * - 9694DA61 (Squat (Bodyweight))
332
+ */
302
333
  quadriceps: ['32HKJ34K', 'A733CC5B', '9694DA61'],
334
+ /**
335
+ * - F6948F17 (Frog Pumps (Dumbbell))
336
+ * - 487B3755 (Single Leg Hip Thrust)
337
+ * - CDA23948 (Glute Bridge)
338
+ */
303
339
  hamstrings: ['F6948F17', '487B3755', 'CDA23948'],
304
340
  glutes: [],
305
341
  lats: [],
@@ -378,7 +414,7 @@ const isExerciseMatch = (exercise, criteria) => {
378
414
  const levelMatch = (_b = (_a = exercise.level) === null || _a === void 0 ? void 0 : _a.includes(criteria.level)) !== null && _b !== void 0 ? _b : false;
379
415
  const goalMatch = (_d = (_c = exercise.goal) === null || _c === void 0 ? void 0 : _c.includes(criteria.goal)) !== null && _d !== void 0 ? _d : false;
380
416
  const equipmentMatch = (0, exports.isEquipmentCompatible)(exercise, criteria.equipments);
381
- const barbellLimitOk = !isBarbellLimitExceeded(exercise, criteria.routineBarbellExerciseCount, criteria.equipments);
417
+ const barbellLimitOk = isBarbellExerciseAllowed(exercise, criteria.routineBarbellExerciseCount, criteria.equipments, criteria.frequency);
382
418
  return (categoryMatch && levelMatch && goalMatch && equipmentMatch && barbellLimitOk);
383
419
  };
384
420
  /**
@@ -500,6 +536,7 @@ const generateProgram = (params) => {
500
536
  const exercise = (0, exports.pickExerciseForPrescription)({
501
537
  sortedExercises,
502
538
  criteria: {
539
+ frequency: selectedDays,
503
540
  exerciseCategory: exercisePrescription.category,
504
541
  equipments: selectedEquipments,
505
542
  muscleGroup,
@@ -559,7 +596,7 @@ const generateProgram = (params) => {
559
596
  return {
560
597
  success: false,
561
598
  errors: allErrors,
562
- partialProgram: program.routines.length > 0 ? program : undefined,
599
+ partialProgram: program,
563
600
  };
564
601
  }
565
602
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hevy-shared",
3
- "version": "1.0.924",
3
+ "version": "1.0.926",
4
4
  "description": "",
5
5
  "main": "built/index.js",
6
6
  "types": "built/index.d.ts",