hevy-shared 1.0.971 → 1.0.972

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,6 +1,6 @@
1
1
  import { WeeklyTrainingFrequency, TrainingGoal, TrainingLevel, SimplifiedMuscleGroup, MuscleGroup, LibraryExercise, ExerciseCategory, GranularEquipment, HevyTrainerProgramEquipment, RestTimerLength } from '.';
2
2
  export type HevyTrainerExerciseCategory = typeof hevyTrainerExerciseCategories[number];
3
- export type TrainerWorkoutTemplateName = typeof workoutTemplateNames[number];
3
+ export type HevyTrainerRoutineName = typeof routineNames[number];
4
4
  export declare const workoutDurationOptions: readonly [40, 60, 80];
5
5
  export type WorkoutDurationMinutes = typeof workoutDurationOptions[number];
6
6
  export declare const trainerGymTypes: readonly ["home_gym", "garage_gym", "commercial_gym", "full_gym"];
@@ -16,14 +16,14 @@ export declare const trainerEquipmentToGranularEquipments: (equipments: HevyTrai
16
16
  export declare const granularEquipmentsToTrainerEquipments: (granularEquipments: GranularEquipment[]) => HevyTrainerProgramEquipment[];
17
17
  export declare const hevyTrainerExerciseCategories: readonly ["compound", "isolation"];
18
18
  export declare const defaultDurationPerFrequency: Record<WeeklyTrainingFrequency, WorkoutDurationMinutes>;
19
- export declare const workoutTemplateNames: 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"];
19
+ 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"];
20
20
  export type exerciseId = string;
21
21
  export interface ExerciseSelectionCriteria {
22
22
  exerciseCategory: HevyTrainerExerciseCategory | 'all';
23
23
  equipments: GranularEquipment[];
24
24
  routineBarbellExerciseCount: number;
25
25
  level: TrainingLevel;
26
- goal: TrainingGoal;
26
+ goal: TrainingGoal | 'all';
27
27
  muscleGroup: MuscleGroup;
28
28
  frequency: WeeklyTrainingFrequency;
29
29
  }
@@ -59,6 +59,7 @@ export interface ProgramGenerationParams<T extends HevyTrainerLibraryExercise> {
59
59
  exerciseStore: T[];
60
60
  focusMuscle?: SimplifiedMuscleGroup;
61
61
  excludedExerciseIds?: Set<string>;
62
+ cardio: undefined | 'beginning' | 'end';
62
63
  /**
63
64
  * When enabled, includes exercise selection trace breadcrumbs in the result
64
65
  * for debugging. Intended for troubleshooting on backoffice; keep off in
@@ -67,7 +68,7 @@ export interface ProgramGenerationParams<T extends HevyTrainerLibraryExercise> {
67
68
  debugExerciseSelectionTrace?: boolean;
68
69
  }
69
70
  export interface ProgramExerciseSelectionTraceRecord {
70
- routine: TrainerWorkoutTemplateName;
71
+ routine: HevyTrainerRoutineName;
71
72
  prescriptionIndex: number;
72
73
  prescription: ExercisePrescription;
73
74
  resolvedMuscleGroup: MuscleGroup;
@@ -80,7 +81,7 @@ export type TrainerProgramAttemptWithTraces = TrainerProgramAttempt & {
80
81
  };
81
82
  export type FrequencyString = 'one_day' | 'two_days' | 'three_days' | 'four_days' | 'five_days' | 'six_days';
82
83
  export declare const frequencyMap: Record<WeeklyTrainingFrequency, FrequencyString>;
83
- export declare const programSplits: Record<WeeklyTrainingFrequency, TrainerWorkoutTemplateName[]>;
84
+ export declare const programSplits: Record<WeeklyTrainingFrequency, HevyTrainerRoutineName[]>;
84
85
  export type SetsPerGoal = {
85
86
  [key in TrainingGoal]: number;
86
87
  };
@@ -126,7 +127,7 @@ export interface WorkoutTemplate {
126
127
  notes?: string;
127
128
  }
128
129
  export type Templates = {
129
- [key in TrainerWorkoutTemplateName]: WorkoutTemplate;
130
+ [key in HevyTrainerRoutineName]: WorkoutTemplate;
130
131
  };
131
132
  export interface BackofficeTrainerPreset {
132
133
  id?: number;
@@ -157,7 +158,7 @@ export interface TrainerProgramExercise {
157
158
  notes?: string;
158
159
  }
159
160
  export interface TrainerProgramRoutine {
160
- name: TrainerWorkoutTemplateName;
161
+ name: HevyTrainerRoutineName;
161
162
  exercises: TrainerProgramExercise[];
162
163
  notes?: string;
163
164
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPrioritySortedExercises = exports.isEquipmentCompatible = exports.normalizeExerciseCategory = exports.getTrainerRestTimerSeconds = exports.getTrainerRepRange = exports.getTrainerSetCount = exports.programSplits = exports.frequencyMap = exports.workoutTemplateNames = exports.defaultDurationPerFrequency = exports.hevyTrainerExerciseCategories = exports.granularEquipmentsToTrainerEquipments = exports.trainerEquipmentToGranularEquipments = exports.granularEquipmentDefaults = exports.trainerGymTypes = exports.workoutDurationOptions = void 0;
3
+ 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
  exports.pickExerciseForPrescription = pickExerciseForPrescription;
5
5
  exports.generateProgram = generateProgram;
6
6
  const _1 = require(".");
@@ -152,7 +152,7 @@ exports.defaultDurationPerFrequency = {
152
152
  5: 40,
153
153
  6: 40,
154
154
  };
155
- exports.workoutTemplateNames = [
155
+ exports.routineNames = [
156
156
  // Full body 1x
157
157
  'full_body_1',
158
158
  // Full body 2x
@@ -414,7 +414,7 @@ const isExerciseMatch = (exercise, criteria) => {
414
414
  (exercise.category === 'assistance-compound' &&
415
415
  criteria.exerciseCategory === 'compound');
416
416
  const levelMatch = (_b = (_a = exercise.level) === null || _a === void 0 ? void 0 : _a.includes(criteria.level)) !== null && _b !== void 0 ? _b : false;
417
- const goalMatch = (_d = (_c = exercise.goal) === null || _c === void 0 ? void 0 : _c.includes(criteria.goal)) !== null && _d !== void 0 ? _d : false;
417
+ const goalMatch = (_d = (criteria.goal === 'all' || ((_c = exercise.goal) === null || _c === void 0 ? void 0 : _c.includes(criteria.goal)))) !== null && _d !== void 0 ? _d : false;
418
418
  const equipmentMatch = (0, exports.isEquipmentCompatible)(exercise, criteria.equipments);
419
419
  const barbellLimitOk = isBarbellExerciseAllowed(exercise, criteria.routineBarbellExerciseCount, criteria.equipments, criteria.frequency);
420
420
  return (categoryMatch && levelMatch && goalMatch && equipmentMatch && barbellLimitOk);
@@ -433,7 +433,8 @@ const isAlternativeIsolationExerciseMatch = (exercise, criteria) => {
433
433
  /**
434
434
  * Finds an exercise that matches the criteria and is not already used
435
435
  */
436
- const findMatchingExercise = (exercises, criteria, context) => {
436
+ const findMatchingExercise = (exercises, //TODO: muscle group exercises
437
+ criteria, context) => {
437
438
  return exercises.find((exercise) => {
438
439
  const matchesCriteria = isExerciseMatch(exercise, criteria);
439
440
  const isNotUsed = !isExerciseUsed(exercise, context);
@@ -537,13 +538,14 @@ function pickExerciseForPrescription(params) {
537
538
  }
538
539
  function generateProgram(params) {
539
540
  var _a, _b;
540
- const { trainerAlgorithmSettings, frequency, goal, level, equipments, workoutDurationMinutes, restTimerLength, exerciseStore, focusMuscle, excludedExerciseIds, debugExerciseSelectionTrace, } = params;
541
+ const { trainerAlgorithmSettings, frequency, goal, level, equipments, workoutDurationMinutes, restTimerLength, exerciseStore, focusMuscle, excludedExerciseIds, debugExerciseSelectionTrace, cardio, } = params;
541
542
  const exerciseSelectionTraces = [];
542
543
  const routines = exports.programSplits[frequency];
543
544
  const program = {
544
545
  name: frequency,
545
546
  routines: [],
546
547
  };
548
+ // TODO: Rename sortedExercises to sortedExercisesByMuscleGroup or something similar
547
549
  const sortedExercises = (0, exports.getPrioritySortedExercises)(trainerAlgorithmSettings.exercise_priorities, exerciseStore);
548
550
  const programUsedExerciseIds = new Set();
549
551
  let programFocusMuscleExerciseCount = 0;
@@ -651,6 +653,90 @@ function generateProgram(params) {
651
653
  });
652
654
  }
653
655
  }
656
+ if (cardio) {
657
+ const cardioExercises = sortedExercises['cardio'];
658
+ const cardioExercise = findMatchingExercise(cardioExercises, {
659
+ frequency,
660
+ exerciseCategory: 'all',
661
+ equipments,
662
+ muscleGroup: 'cardio',
663
+ routineBarbellExerciseCount,
664
+ level,
665
+ goal: 'all',
666
+ }, {
667
+ programUsedExerciseIds,
668
+ routineUsedExerciseIds,
669
+ excludedExerciseIds,
670
+ });
671
+ // TODO change the interface to include cardio
672
+ if (cardioExercise) {
673
+ if (cardio === 'beginning') {
674
+ routineExercises.unshift({
675
+ exerciseTemplate: cardioExercise,
676
+ muscleGroup: 'cardio',
677
+ category: 'compound',
678
+ sets: 1,
679
+ repRangeStart: 0,
680
+ repRangeEnd: 0,
681
+ restTimerSeconds: 0,
682
+ });
683
+ exerciseSelectionTraces.unshift({
684
+ routine,
685
+ prescriptionIndex: 0,
686
+ prescription: { muscle_group: 'cardio', category: 'compound' },
687
+ resolvedMuscleGroup: 'cardio',
688
+ criteria: {
689
+ frequency,
690
+ exerciseCategory: 'all',
691
+ equipments,
692
+ muscleGroup: 'cardio',
693
+ routineBarbellExerciseCount,
694
+ level,
695
+ goal: 'all',
696
+ },
697
+ selectedExerciseId: cardioExercise.id,
698
+ trace: {
699
+ entries: [],
700
+ selectedPass: 1,
701
+ },
702
+ });
703
+ }
704
+ else {
705
+ routineExercises.push({
706
+ exerciseTemplate: cardioExercise,
707
+ muscleGroup: 'cardio',
708
+ category: 'compound',
709
+ sets: 1,
710
+ repRangeStart: 0,
711
+ repRangeEnd: 0,
712
+ restTimerSeconds: 0,
713
+ });
714
+ // todo: handle debug traces with the exercises
715
+ exerciseSelectionTraces.push({
716
+ routine,
717
+ prescriptionIndex: routineExercises.length,
718
+ prescription: { muscle_group: 'cardio', category: 'compound' },
719
+ resolvedMuscleGroup: 'cardio',
720
+ criteria: {
721
+ frequency,
722
+ exerciseCategory: 'all',
723
+ equipments,
724
+ muscleGroup: 'cardio',
725
+ routineBarbellExerciseCount,
726
+ level,
727
+ goal: 'all',
728
+ },
729
+ selectedExerciseId: cardioExercise.id,
730
+ trace: {
731
+ entries: [],
732
+ selectedPass: 1,
733
+ },
734
+ });
735
+ }
736
+ programUsedExerciseIds.add(cardioExercise.id);
737
+ routineUsedExerciseIds.add(cardioExercise.id);
738
+ }
739
+ }
654
740
  program.routines.push({
655
741
  name: routine,
656
742
  notes: routineTemplate.notes,
package/built/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { InstructionsLanguage } from './exerciseLocaleUtils';
2
- import { TrainerWorkoutTemplateName, WorkoutDurationMinutes } from './hevyTrainer';
2
+ import { WorkoutDurationMinutes } from './hevyTrainer';
3
+ import { postEmailBackofficeSchema } from './schemas';
3
4
  import { Language } from './translations';
4
5
  import { Lookup } from './typeUtils';
6
+ import { z } from 'zod';
7
+ export * from './schemas';
5
8
  export * from './constants';
6
9
  export * from './utils';
7
10
  export * from './units';
@@ -881,7 +884,6 @@ export interface Workout {
881
884
  biometrics?: WorkoutBiometrics;
882
885
  is_biometrics_public: boolean;
883
886
  trainer_program_id: string | undefined;
884
- trainer_workout_template_id: string | undefined;
885
887
  }
886
888
  export interface CustomExerciseImage {
887
889
  type: 'image';
@@ -961,7 +963,6 @@ export interface PostWorkoutRequestWorkout {
961
963
  biometrics?: WorkoutBiometrics;
962
964
  is_biometrics_public: boolean;
963
965
  trainer_program_id: string | undefined;
964
- trainer_workout_template_id: string | undefined;
965
966
  }
966
967
  export declare const isHeartRateSamples: (x: any) => x is HeartRateSample[];
967
968
  export declare const isWorkoutBiometrics: (x: any) => x is WorkoutBiometrics;
@@ -1250,88 +1251,6 @@ export interface GetTeamInviteResponse {
1250
1251
  export interface OutstandingInvitesForCoachTeamResponse {
1251
1252
  invites: CoachTeamInvite[];
1252
1253
  }
1253
- export interface TrainerWorkoutTemplateExercise {
1254
- id: string;
1255
- exercise_template_id: string;
1256
- index: number;
1257
- set_count: number;
1258
- warmup_set_count: number;
1259
- rep_range?: RepRange;
1260
- rest_seconds: number;
1261
- }
1262
- export interface TrainerWorkoutTemplate {
1263
- id: string;
1264
- hevy_trainer_program_id: string;
1265
- index: number;
1266
- name: TrainerWorkoutTemplateName;
1267
- exercises: TrainerWorkoutTemplateExercise[];
1268
- }
1269
- export interface TrainerProgramV3 {
1270
- id: string;
1271
- schema_version: 'v3';
1272
- created_at: string;
1273
- updated_at: string;
1274
- level: TrainingLevel;
1275
- goal: TrainingGoal;
1276
- equipments: GranularEquipment[];
1277
- weekly_frequency: WeeklyTrainingFrequency;
1278
- templates: TrainerWorkoutTemplate[];
1279
- focus_muscle?: SimplifiedMuscleGroup;
1280
- next_workout_index: number;
1281
- workout_duration_minutes: WorkoutDurationMinutes;
1282
- rest_timer_length: RestTimerLength;
1283
- }
1284
- export interface PostTrainerProgramV3RequestBody {
1285
- program: {
1286
- title: string;
1287
- level: TrainingLevel;
1288
- goal: TrainingGoal;
1289
- equipments: GranularEquipment[];
1290
- weekly_frequency: WeeklyTrainingFrequency;
1291
- focus_muscle?: SimplifiedMuscleGroup;
1292
- next_workout_index?: number;
1293
- workout_duration_minutes: WorkoutDurationMinutes;
1294
- rest_timer_length: RestTimerLength;
1295
- templates: {
1296
- index: number;
1297
- name: TrainerWorkoutTemplateName;
1298
- exercises: {
1299
- exercise_template_id: string;
1300
- index: number;
1301
- set_count: number;
1302
- warmup_set_count: number;
1303
- rep_range?: RepRange;
1304
- rest_seconds: number;
1305
- }[];
1306
- }[];
1307
- };
1308
- }
1309
- export interface UpdateTrainerProgramV3RequestBody {
1310
- program: {
1311
- programId: string;
1312
- level: TrainingLevel;
1313
- goal: TrainingGoal;
1314
- equipments: GranularEquipment[];
1315
- weekly_frequency: WeeklyTrainingFrequency;
1316
- focus_muscle?: SimplifiedMuscleGroup;
1317
- next_workout_index?: number;
1318
- workout_duration_minutes: WorkoutDurationMinutes;
1319
- rest_timer_length: RestTimerLength;
1320
- templates: {
1321
- id: string;
1322
- index: number;
1323
- name: TrainerWorkoutTemplateName;
1324
- exercises: {
1325
- exercise_template_id: string;
1326
- index: number;
1327
- set_count: number;
1328
- warmup_set_count: number;
1329
- rep_range?: RepRange;
1330
- rest_seconds: number;
1331
- }[];
1332
- }[];
1333
- };
1334
- }
1335
1254
  export interface HevyTrainerProgram {
1336
1255
  id: string;
1337
1256
  created_at: string;
@@ -2071,6 +1990,7 @@ export interface GetAccountsByEmailResponse {
2071
1990
  wellhub_email: string | null;
2072
1991
  }[];
2073
1992
  }
1993
+ export type PostEmailBackofficeRequest = z.infer<typeof postEmailBackofficeSchema>;
2074
1994
  export interface UserReportSummaryBackoffice {
2075
1995
  reported_by: string;
2076
1996
  reported_at: string;
package/built/index.js CHANGED
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.isHeartRateSamples = exports.isPublicWorkout = exports.isSetType = exports.isRPE = exports.validRpeValues = exports.isSetPersonalRecordType = exports.weeklyTrainingFrequencies = exports.isGranularEquipment = exports.granularEquipments = exports.hevyTrainerProgramEquipments = exports.restTimerLengths = 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
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
+ __exportStar(require("./schemas"), exports);
20
21
  __exportStar(require("./constants"), exports);
21
22
  __exportStar(require("./utils"), exports);
22
23
  __exportStar(require("./units"), exports);
@@ -36,7 +36,6 @@ export interface NormalizedWorkout {
36
36
  clientId: string;
37
37
  biometrics?: WorkoutBiometrics;
38
38
  trainerProgramId: string | undefined;
39
- trainerWorkoutTemplateId?: string;
40
39
  }
41
40
  export interface NormalizedSet {
42
41
  index: number;
@@ -0,0 +1,14 @@
1
+ import { z } from 'zod';
2
+ export declare const postEmailBackofficeSchema: z.ZodObject<{
3
+ toUserId: z.ZodString;
4
+ subject: z.ZodString;
5
+ message: z.ZodString;
6
+ }, "strip", z.ZodTypeAny, {
7
+ message: string;
8
+ toUserId: string;
9
+ subject: string;
10
+ }, {
11
+ message: string;
12
+ toUserId: string;
13
+ subject: string;
14
+ }>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.postEmailBackofficeSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.postEmailBackofficeSchema = zod_1.z.object({
6
+ toUserId: zod_1.z.string(),
7
+ subject: zod_1.z.string(),
8
+ message: zod_1.z.string(),
9
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hevy-shared",
3
- "version": "1.0.971",
3
+ "version": "1.0.972",
4
4
  "description": "",
5
5
  "main": "built/index.js",
6
6
  "types": "built/index.d.ts",
@@ -51,6 +51,7 @@
51
51
  },
52
52
  "dependencies": {
53
53
  "dayjs": "^1.11.19",
54
- "lodash": "^4.17.21"
54
+ "lodash": "^4.17.21",
55
+ "zod": "3.24.3"
55
56
  }
56
57
  }
@@ -1 +0,0 @@
1
- export {};