hevy-shared 1.0.962 → 1.0.964

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.
Files changed (86) hide show
  1. package/README.md +17 -2
  2. package/built/API/APIClient.d.ts +157 -0
  3. package/built/API/APIClient.js +381 -0
  4. package/built/API/index.d.ts +2 -0
  5. package/built/API/index.js +18 -0
  6. package/built/API/types.d.ts +38 -0
  7. package/built/API/types.js +18 -0
  8. package/built/adjustEventTokens.d.ts +16 -0
  9. package/built/adjustEventTokens.js +18 -0
  10. package/built/adminPermissions.d.ts +4 -0
  11. package/built/adminPermissions.js +22 -0
  12. package/built/async.d.ts +50 -0
  13. package/built/async.js +170 -0
  14. package/built/chat.d.ts +25 -23
  15. package/built/coachPlans.d.ts +2 -1
  16. package/built/coachPlans.js +2 -2
  17. package/built/cue.d.ts +12 -0
  18. package/built/cue.js +22 -0
  19. package/built/exerciseLocaleUtils.d.ts +17 -0
  20. package/built/exerciseLocaleUtils.js +62 -0
  21. package/built/filterExercises.d.ts +19 -3
  22. package/built/filterExercises.js +72 -60
  23. package/built/hevyTrainer.d.ts +250 -0
  24. package/built/hevyTrainer.js +676 -0
  25. package/built/index.d.ts +1217 -304
  26. package/built/index.js +268 -75
  27. package/built/muscleHeatmaps.d.ts +31 -0
  28. package/built/muscleHeatmaps.js +68 -0
  29. package/built/muscleSplits.d.ts +36 -0
  30. package/built/muscleSplits.js +100 -0
  31. package/built/normalizedWorkoutUtils.d.ts +88 -0
  32. package/built/normalizedWorkoutUtils.js +112 -0
  33. package/built/notifications.d.ts +215 -0
  34. package/built/notifications.js +9 -0
  35. package/built/routineUtils.d.ts +14 -0
  36. package/built/routineUtils.js +186 -0
  37. package/built/setIndicatorUtils.d.ts +4 -3
  38. package/built/setIndicatorUtils.js +15 -1
  39. package/built/tests/async.test.d.ts +1 -0
  40. package/built/tests/async.test.js +49 -0
  41. package/built/tests/hevyTrainer.test.d.ts +1 -0
  42. package/built/tests/hevyTrainer.test.js +1199 -0
  43. package/built/tests/muscleSplit.test.d.ts +1 -0
  44. package/built/tests/muscleSplit.test.js +153 -0
  45. package/built/tests/routineUtils.test.d.ts +1 -0
  46. package/built/tests/routineUtils.test.js +745 -0
  47. package/built/tests/testUtils.d.ts +85 -0
  48. package/built/tests/testUtils.js +319 -0
  49. package/built/tests/utils.test.js +748 -0
  50. package/built/tests/workoutVolume.test.js +165 -49
  51. package/built/translations/index.d.ts +2 -0
  52. package/built/translations/index.js +18 -0
  53. package/built/translations/translationUtils.d.ts +2 -0
  54. package/built/translations/translationUtils.js +61 -0
  55. package/built/translations/types.d.ts +8 -0
  56. package/built/translations/types.js +20 -0
  57. package/built/typeUtils.d.ts +70 -0
  58. package/built/typeUtils.js +55 -0
  59. package/built/units.d.ts +14 -7
  60. package/built/units.js +24 -14
  61. package/built/utils.d.ts +192 -5
  62. package/built/utils.js +598 -85
  63. package/built/websocket.d.ts +14 -2
  64. package/built/workoutVolume.d.ts +24 -5
  65. package/built/workoutVolume.js +25 -34
  66. package/package.json +30 -9
  67. package/.eslintignore +0 -2
  68. package/.eslintrc +0 -21
  69. package/.github/workflows/ci.yml +0 -15
  70. package/.github/workflows/npm-publish.yml +0 -59
  71. package/.github/workflows/pr-auto-assign.yml +0 -15
  72. package/.prettierrc.js +0 -5
  73. package/jest.config.js +0 -4
  74. package/src/chat.ts +0 -130
  75. package/src/coachPlans.ts +0 -57
  76. package/src/constants.ts +0 -14
  77. package/src/filterExercises.ts +0 -222
  78. package/src/index.ts +0 -1576
  79. package/src/setIndicatorUtils.ts +0 -137
  80. package/src/tests/utils.test.ts +0 -156
  81. package/src/tests/workoutVolume.test.ts +0 -93
  82. package/src/units.ts +0 -41
  83. package/src/utils.ts +0 -516
  84. package/src/websocket.ts +0 -36
  85. package/src/workoutVolume.ts +0 -175
  86. package/tsconfig.json +0 -70
package/built/index.js CHANGED
@@ -14,7 +14,9 @@ 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.isValidUserWorkoutMetricsType = exports.isPublicWorkout = exports.validRpeValues = exports.isRPE = exports.isExerciseType = exports.exerciseTypes = exports.isEquipmentFilter = exports.isEquipment = exports.equipmentFilters = exports.equipments = exports.isMuscleGroupFilter = exports.muscleGroupFilters = exports.isMuscleGroup = exports.muscleGroups = exports.DefaultClientConfiguration = exports.isErrorResponse = exports.isTimerVolumeOption = exports.isWeekday = exports.isBodyMeasurementUnit = exports.isDistanceUnitShort = exports.isDistanceUnit = exports.isWeightUnit = exports.isLanguage = void 0;
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
+ exports.isOAuthScope = exports.supportedScopes = exports.isSuggestedUserSource = exports.isValidUserWorkoutMetricsType = exports.isBodyMeasurementKey = exports.measurementsList = exports.isHevyTrainerRoutine = exports.isWorkoutBiometrics = void 0;
19
+ const typeUtils_1 = require("./typeUtils");
18
20
  __exportStar(require("./constants"), exports);
19
21
  __exportStar(require("./utils"), exports);
20
22
  __exportStar(require("./units"), exports);
@@ -24,23 +26,19 @@ __exportStar(require("./workoutVolume"), exports);
24
26
  __exportStar(require("./coachPlans"), exports);
25
27
  __exportStar(require("./chat"), exports);
26
28
  __exportStar(require("./websocket"), exports);
27
- const isLanguage = (x) => {
28
- return [
29
- 'en',
30
- 'es',
31
- 'de',
32
- 'fr',
33
- 'it',
34
- 'pt',
35
- 'tr',
36
- 'zh_CN',
37
- 'zh_TW',
38
- 'ru',
39
- 'ja',
40
- 'ko',
41
- ].includes(x);
42
- };
43
- exports.isLanguage = isLanguage;
29
+ __exportStar(require("./cue"), exports);
30
+ __exportStar(require("./muscleHeatmaps"), exports);
31
+ __exportStar(require("./muscleSplits"), exports);
32
+ __exportStar(require("./notifications"), exports);
33
+ __exportStar(require("./normalizedWorkoutUtils"), exports);
34
+ __exportStar(require("./routineUtils"), exports);
35
+ __exportStar(require("./typeUtils"), exports);
36
+ __exportStar(require("./async"), exports);
37
+ __exportStar(require("./adminPermissions"), exports);
38
+ __exportStar(require("./adjustEventTokens"), exports);
39
+ __exportStar(require("./hevyTrainer"), exports);
40
+ __exportStar(require("./translations"), exports);
41
+ __exportStar(require("./exerciseLocaleUtils"), exports);
44
42
  const isWeightUnit = (x) => {
45
43
  return x === 'kg' || x === 'lbs';
46
44
  };
@@ -57,61 +55,119 @@ const isBodyMeasurementUnit = (x) => {
57
55
  return x === 'cm' || x === 'in';
58
56
  };
59
57
  exports.isBodyMeasurementUnit = isBodyMeasurementUnit;
60
- const isWeekday = (x) => {
61
- return (x === 'monday' ||
62
- x === 'tuesday' ||
63
- x === 'wednesday' ||
64
- x === 'thursday' ||
65
- x === 'friday' ||
66
- x === 'saturday' ||
67
- x === 'sunday');
68
- };
58
+ /** Monday is first */
59
+ exports.orderedWeekdays = [
60
+ 'monday',
61
+ 'tuesday',
62
+ 'wednesday',
63
+ 'thursday',
64
+ 'friday',
65
+ 'saturday',
66
+ 'sunday',
67
+ ];
68
+ const isWeekday = (x) => (0, typeUtils_1.isInArray)(x, exports.orderedWeekdays);
69
69
  exports.isWeekday = isWeekday;
70
- const isTimerVolumeOption = (x) => {
71
- return x === 'off' || x === 'low' || x === 'normal' || x === 'high';
72
- };
70
+ const _timerVolumeOptions = ['off', 'low', 'normal', 'high'];
71
+ const isTimerVolumeOption = (x) => (0, typeUtils_1.isInArray)(x, _timerVolumeOptions);
73
72
  exports.isTimerVolumeOption = isTimerVolumeOption;
73
+ const _livePRVolumeOption = ['off', 'low', 'normal', 'high'];
74
+ const isLivePRVolumeOption = (x) => (0, typeUtils_1.isInArray)(x, _livePRVolumeOption);
75
+ exports.isLivePRVolumeOption = isLivePRVolumeOption;
74
76
  const isErrorResponse = (x) => {
75
77
  return typeof (x === null || x === void 0 ? void 0 : x.error) === 'string';
76
78
  };
77
79
  exports.isErrorResponse = isErrorResponse;
80
+ const _coachRoles = ['member', 'admin', 'owner'];
81
+ const isCoachRole = (role) => (0, typeUtils_1.isInArray)(role, _coachRoles);
82
+ exports.isCoachRole = isCoachRole;
83
+ const parseClientAuthTokenResponse = (data) => typeof data === 'object' &&
84
+ !!data &&
85
+ typeof data.access_token === 'string' &&
86
+ data.access_token.length > 0 &&
87
+ typeof data.refresh_token === 'string' &&
88
+ data.refresh_token.length > 0 &&
89
+ typeof data.expires_at === 'string' &&
90
+ data.expires_at.length > 0 &&
91
+ !!new Date(data.expires_at).valueOf()
92
+ ? {
93
+ access_token: data.access_token,
94
+ refresh_token: data.refresh_token,
95
+ expires_at: new Date(data.expires_at),
96
+ }
97
+ : null;
98
+ exports.parseClientAuthTokenResponse = parseClientAuthTokenResponse;
78
99
  exports.DefaultClientConfiguration = {
79
100
  is_chat_enabled: false,
101
+ are_notifications_enabled: true,
80
102
  };
81
- exports.muscleGroups = [
82
- 'abdominals',
83
- 'abductors',
84
- 'adductors',
85
- 'biceps',
86
- 'lower_back',
87
- 'upper_back',
88
- 'cardio',
89
- 'chest',
103
+ const _supportedProStores = [
104
+ 'app_store',
105
+ 'play_store',
106
+ 'stripe',
107
+ 'hevy-gift',
108
+ 'gympass',
109
+ 'paddle',
110
+ 'hevy-coach',
111
+ ];
112
+ exports.coreMuscles = ['abdominals'];
113
+ exports.shoulderMuscles = ['shoulders'];
114
+ exports.armMuscles = ['biceps', 'triceps', 'forearms'];
115
+ exports.legMuscles = [
116
+ 'quadriceps',
117
+ 'hamstrings',
90
118
  'calves',
91
- 'forearms',
92
119
  'glutes',
93
- 'hamstrings',
120
+ 'abductors',
121
+ 'adductors',
122
+ ];
123
+ exports.backMuscles = [
94
124
  'lats',
95
- 'quadriceps',
96
- 'shoulders',
97
- 'triceps',
125
+ 'upper_back',
98
126
  'traps',
127
+ 'lower_back',
128
+ ];
129
+ exports.chestMuscles = ['chest'];
130
+ exports.miscellaneousMuscles = [
131
+ 'cardio',
99
132
  'neck',
100
133
  'full_body',
101
134
  'other',
102
135
  ];
103
- const isMuscleGroup = (x) => {
104
- return exports.muscleGroups.includes(x);
105
- };
106
- exports.isMuscleGroup = isMuscleGroup;
107
- exports.muscleGroupFilters = [
108
- 'all_muscles',
109
- ...exports.muscleGroups,
136
+ exports.simplifiedMuscleGroups = [
137
+ 'core',
138
+ 'shoulders',
139
+ 'arms',
140
+ 'legs',
141
+ 'back',
142
+ 'chest',
110
143
  ];
111
- const isMuscleGroupFilter = (x) => {
112
- return exports.muscleGroupFilters.includes(x);
113
- };
144
+ const isSimplifiedMuscleGroup = (x) => (0, typeUtils_1.isInArray)(x, exports.simplifiedMuscleGroups);
145
+ exports.isSimplifiedMuscleGroup = isSimplifiedMuscleGroup;
146
+ exports.muscleGroups = [
147
+ ...exports.coreMuscles,
148
+ ...exports.shoulderMuscles,
149
+ ...exports.armMuscles,
150
+ ...exports.legMuscles,
151
+ ...exports.backMuscles,
152
+ ...exports.chestMuscles,
153
+ ...exports.miscellaneousMuscles,
154
+ ];
155
+ const isMuscleGroup = (x) => (0, typeUtils_1.isInArray)(x, exports.muscleGroups);
156
+ exports.isMuscleGroup = isMuscleGroup;
157
+ exports.muscleGroupFilters = ['all_muscles', ...exports.muscleGroups];
158
+ const isMuscleGroupFilter = (x) => (0, typeUtils_1.isInArray)(x, exports.muscleGroupFilters);
114
159
  exports.isMuscleGroupFilter = isMuscleGroupFilter;
160
+ exports.simplifiedMuscleGroupToMuscleGroups = {
161
+ chest: exports.chestMuscles,
162
+ shoulders: exports.shoulderMuscles,
163
+ back: exports.backMuscles,
164
+ arms: exports.armMuscles,
165
+ legs: exports.legMuscles,
166
+ core: exports.coreMuscles,
167
+ };
168
+ /**
169
+ * Equipment
170
+ */
115
171
  exports.equipments = [
116
172
  'none',
117
173
  'barbell',
@@ -123,24 +179,23 @@ exports.equipments = [
123
179
  'suspension',
124
180
  'other',
125
181
  ];
126
- exports.equipmentFilters = [
127
- 'all_equipment',
128
- ...exports.equipments,
129
- ];
130
- const isEquipment = (x) => {
131
- return exports.equipments.includes(x);
132
- };
182
+ const isEquipment = (x) => (0, typeUtils_1.isInArray)(x, exports.equipments);
133
183
  exports.isEquipment = isEquipment;
134
- const isEquipmentFilter = (x) => {
135
- return exports.equipmentFilters.includes(x);
136
- };
184
+ exports.equipmentFilters = ['all_equipment', ...exports.equipments];
185
+ const isEquipmentFilter = (x) => (0, typeUtils_1.isInArray)(x, exports.equipmentFilters);
137
186
  exports.isEquipmentFilter = isEquipmentFilter;
138
- exports.exerciseTypes = [
187
+ exports.exerciseRepTypes = [
139
188
  'weight_reps',
140
189
  'reps_only',
141
- 'bodyweight_reps',
190
+ 'bodyweight_reps', // This is actually used for weighted bodyweight exercises (eg weighted pull ups)
142
191
  'bodyweight_assisted_reps',
192
+ ];
193
+ const isExerciseRepType = (x) => (0, typeUtils_1.isInArray)(x, exports.exerciseRepTypes);
194
+ exports.isExerciseRepType = isExerciseRepType;
195
+ exports.exerciseTypes = [
196
+ ...exports.exerciseRepTypes,
143
197
  'duration',
198
+ 'weight_duration',
144
199
  'distance_duration',
145
200
  /**
146
201
  * Note on short_distance_weight exercises. The UI makes it look like we support yards and meters
@@ -153,21 +208,159 @@ exports.exerciseTypes = [
153
208
  * from yards<->meters.
154
209
  */
155
210
  'short_distance_weight',
211
+ /**
212
+ * At the time of writing, the only exercise that uses these types are Stair Machine (Floors)
213
+ * and Stair Machine (Steps) respectively.
214
+ */
215
+ 'floors_duration',
216
+ 'steps_duration',
156
217
  ];
157
- const isExerciseType = (x) => {
158
- return typeof x === 'string' && exports.exerciseTypes.includes(x);
159
- };
218
+ const isExerciseType = (x) => (0, typeUtils_1.isInArray)(x, exports.exerciseTypes);
160
219
  exports.isExerciseType = isExerciseType;
161
- const isRPE = (x) => {
162
- return exports.validRpeValues.includes(x);
163
- };
164
- exports.isRPE = isRPE;
220
+ exports.customExericseTypes = exports.exerciseTypes.filter((type) => type !== 'floors_duration' && type !== 'steps_duration');
221
+ const isCustomExerciseType = (x) => (0, typeUtils_1.isInArray)(x, exports.customExericseTypes);
222
+ exports.isCustomExerciseType = isCustomExerciseType;
223
+ // Hevy Trainer related types
224
+ exports.trainingGoals = ['strength', 'build_muscle', 'fat_loss'];
225
+ exports.trainingLevels = ['beginner', 'intermediate', 'advanced'];
226
+ exports.exerciseCategories = [
227
+ 'isolation',
228
+ 'compound',
229
+ 'assistance-compound',
230
+ ];
231
+ exports.restTimerLengths = ['short', 'medium', 'long'];
232
+ exports.hevyTrainerProgramEquipments = [
233
+ 'barbell',
234
+ 'dumbbell',
235
+ 'machine',
236
+ ];
237
+ exports.granularEquipments = [
238
+ 'barbell',
239
+ 'dumbbell',
240
+ 'kettlebell',
241
+ 'plate',
242
+ 'medicine_ball',
243
+ 'ez_bar',
244
+ 'landmine',
245
+ 'trap_bar',
246
+ 'pullup_bar',
247
+ 'dip_bar',
248
+ 'squat_rack',
249
+ 'flat_bench',
250
+ 'adjustable_bench',
251
+ 'dual_cable_machine',
252
+ 'single_cable_machine',
253
+ 'lat_pulldown_cable',
254
+ 'leg_press_machine',
255
+ 'smith_machine',
256
+ 't_bar',
257
+ 'plate_machines',
258
+ 'stack_machines',
259
+ 'treadmill',
260
+ 'elliptical_trainer',
261
+ 'rowing_machine',
262
+ 'spinning',
263
+ 'stair_machine',
264
+ 'air_bike',
265
+ 'suspension_band',
266
+ 'resistance_band',
267
+ 'battle_rope',
268
+ 'rings',
269
+ 'jump_rope',
270
+ ];
271
+ const isGranularEquipment = (x) => (0, typeUtils_1.isInArray)(x, exports.granularEquipments);
272
+ exports.isGranularEquipment = isGranularEquipment;
273
+ exports.weeklyTrainingFrequencies = [1, 2, 3, 4, 5, 6];
274
+ // Workouts
275
+ const _setPersonalRecordTypes = [
276
+ 'best_weight',
277
+ 'best_reps',
278
+ 'best_volume',
279
+ 'best_1rm',
280
+ 'best_duration',
281
+ 'best_distance',
282
+ 'most_floors',
283
+ 'most_steps',
284
+ ];
285
+ const isSetPersonalRecordType = (x) => (0, typeUtils_1.isInArray)(x, _setPersonalRecordTypes);
286
+ exports.isSetPersonalRecordType = isSetPersonalRecordType;
165
287
  exports.validRpeValues = [6, 7, 7.5, 8, 8.5, 9, 9.5, 10];
288
+ const isRPE = (x) => (0, typeUtils_1.isInArray)(x, exports.validRpeValues);
289
+ exports.isRPE = isRPE;
290
+ const _setTypes = ['warmup', 'normal', 'failure', 'dropset'];
291
+ const isSetType = (x) => (0, typeUtils_1.isInArray)(x, _setTypes);
292
+ exports.isSetType = isSetType;
166
293
  const isPublicWorkout = (x) => {
167
294
  return x.type === 'public';
168
295
  };
169
296
  exports.isPublicWorkout = isPublicWorkout;
170
- const isValidUserWorkoutMetricsType = (x) => {
171
- return typeof x === 'string' && ['duration', 'reps'].includes(x);
297
+ const isHeartRateSamples = (x) => {
298
+ if (!x || !Array.isArray(x))
299
+ return false;
300
+ for (const sample of x) {
301
+ if (typeof sample.timestamp_ms !== 'number' ||
302
+ typeof sample.bpm !== 'number') {
303
+ return false;
304
+ }
305
+ }
306
+ return true;
307
+ };
308
+ exports.isHeartRateSamples = isHeartRateSamples;
309
+ const isWorkoutBiometrics = (x) => {
310
+ if (!x)
311
+ return false;
312
+ const maybeCalories = x.total_calories;
313
+ const maybeHeartRateSamples = x.heart_rate_samples;
314
+ const caloriesAreValid = maybeCalories === undefined ||
315
+ (typeof maybeCalories === 'number' && maybeCalories >= 0);
316
+ const heartSamplesAreValid = maybeHeartRateSamples === undefined ||
317
+ (0, exports.isHeartRateSamples)(maybeHeartRateSamples);
318
+ return caloriesAreValid && heartSamplesAreValid;
172
319
  };
320
+ exports.isWorkoutBiometrics = isWorkoutBiometrics;
321
+ const isHevyTrainerRoutine = (routine) => routine.hevy_trainer_program_id !== null;
322
+ exports.isHevyTrainerRoutine = isHevyTrainerRoutine;
323
+ exports.measurementsList = [
324
+ 'weight_kg',
325
+ 'lean_mass_kg',
326
+ 'fat_percent',
327
+ 'neck_cm',
328
+ 'shoulder_cm',
329
+ 'chest_cm',
330
+ 'left_bicep_cm',
331
+ 'right_bicep_cm',
332
+ 'left_forearm_cm',
333
+ 'right_forearm_cm',
334
+ 'abdomen',
335
+ 'waist',
336
+ 'hips',
337
+ 'left_thigh',
338
+ 'right_thigh',
339
+ 'left_calf',
340
+ 'right_calf',
341
+ ];
342
+ const isBodyMeasurementKey = (key) => (0, typeUtils_1.isInArray)(key, exports.measurementsList);
343
+ exports.isBodyMeasurementKey = isBodyMeasurementKey;
344
+ const _validUserWorkoutMetricsTypes = ['duration', 'reps'];
345
+ const isValidUserWorkoutMetricsType = (x) => (0, typeUtils_1.isInArray)(x, _validUserWorkoutMetricsTypes);
173
346
  exports.isValidUserWorkoutMetricsType = isValidUserWorkoutMetricsType;
347
+ const _suggestedUserSources = [
348
+ 'popular',
349
+ 'local',
350
+ 'contact',
351
+ 'mutual_follows',
352
+ 'follows_you',
353
+ 'featured',
354
+ 'hyper_local',
355
+ ];
356
+ const isSuggestedUserSource = (source) => (0, typeUtils_1.isInArray)(source, _suggestedUserSources);
357
+ exports.isSuggestedUserSource = isSuggestedUserSource;
358
+ exports.supportedScopes = [
359
+ 'read-workout',
360
+ 'modify-workout',
361
+ 'read-routine',
362
+ 'modify-routine',
363
+ 'unrestricted',
364
+ ];
365
+ const isOAuthScope = (x) => (0, typeUtils_1.isInArray)(x, exports.supportedScopes);
366
+ exports.isOAuthScope = isOAuthScope;
@@ -0,0 +1,31 @@
1
+ import { MuscleGroup } from '.';
2
+ import { Lookup } from './typeUtils';
3
+ declare const _muscleHeatmapKeys: readonly ["abdominals", "shoulders", "chest", "lower_back", "biceps", "triceps", "upper_back", "quadriceps", "calves", "lats", "hamstrings", "glutes", "abductors", "adductors", "traps", "forearms", "neck"];
4
+ export type MuscleHeatmapKey = Lookup<typeof _muscleHeatmapKeys>;
5
+ export declare const isMuscleHeatmapKey: (x: string) => x is MuscleHeatmapKey;
6
+ export type MuscleHeatmapData = {
7
+ [key in MuscleHeatmapKey]?: number;
8
+ };
9
+ /**
10
+ * Calculates muscle group opacity from exercise data: primary muscle groups are 1.0, secondary are 0.5
11
+ */
12
+ export declare const getMuscleHeatmapDataForExercises: (exercises: ({
13
+ muscle_group: MuscleGroup;
14
+ other_muscles: MuscleGroup[];
15
+ } | undefined)[]) => MuscleHeatmapData;
16
+ /**
17
+ *
18
+ * @param workoutsOrRoutines An array of objects with an array of exercises
19
+ * @param getExerciseTemplateWithId A function that returns an ExerciseTemplate (or undefined) given an ID
20
+ * @returns MuscleHeatmapData with a value that represents how much a muscle group was used in the workouts or routines:
21
+ * A primary muscle counts as 1.0 per workout/routine, and a secondary muscle counts as 0.5 per workout/routine
22
+ */
23
+ export declare const getMuscleHeatmapDataForWorkoutsOrRoutines: ({ workoutsOrRoutines, }: {
24
+ workoutsOrRoutines: {
25
+ exercises: {
26
+ muscle_group: MuscleGroup;
27
+ other_muscles: MuscleGroup[];
28
+ }[];
29
+ }[];
30
+ }) => MuscleHeatmapData;
31
+ export {};
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMuscleHeatmapDataForWorkoutsOrRoutines = exports.getMuscleHeatmapDataForExercises = exports.isMuscleHeatmapKey = void 0;
4
+ const typeUtils_1 = require("./typeUtils");
5
+ const _muscleHeatmapKeys = [
6
+ 'abdominals',
7
+ 'shoulders',
8
+ 'chest',
9
+ 'lower_back',
10
+ 'biceps',
11
+ 'triceps',
12
+ 'upper_back',
13
+ 'quadriceps',
14
+ 'calves',
15
+ 'lats',
16
+ 'hamstrings',
17
+ 'glutes',
18
+ 'abductors',
19
+ 'adductors',
20
+ 'traps',
21
+ 'forearms',
22
+ 'neck',
23
+ ];
24
+ const isMuscleHeatmapKey = (x) => (0, typeUtils_1.isInArray)(x, _muscleHeatmapKeys);
25
+ exports.isMuscleHeatmapKey = isMuscleHeatmapKey;
26
+ /**
27
+ * Calculates muscle group opacity from exercise data: primary muscle groups are 1.0, secondary are 0.5
28
+ */
29
+ const getMuscleHeatmapDataForExercises = (exercises) => {
30
+ var _a;
31
+ // initialise all keys to 0
32
+ const data = _muscleHeatmapKeys.reduce((prev, curr) => (Object.assign(Object.assign({}, prev), { [curr]: 0 })), {});
33
+ for (const e of exercises) {
34
+ if (!e)
35
+ continue;
36
+ if ((0, exports.isMuscleHeatmapKey)(e.muscle_group)) {
37
+ data[e.muscle_group] = 1;
38
+ }
39
+ for (const m of e.other_muscles) {
40
+ if ((0, exports.isMuscleHeatmapKey)(m)) {
41
+ data[m] = Math.max((_a = data[m]) !== null && _a !== void 0 ? _a : 0, 0.5);
42
+ }
43
+ }
44
+ }
45
+ return data;
46
+ };
47
+ exports.getMuscleHeatmapDataForExercises = getMuscleHeatmapDataForExercises;
48
+ /**
49
+ *
50
+ * @param workoutsOrRoutines An array of objects with an array of exercises
51
+ * @param getExerciseTemplateWithId A function that returns an ExerciseTemplate (or undefined) given an ID
52
+ * @returns MuscleHeatmapData with a value that represents how much a muscle group was used in the workouts or routines:
53
+ * A primary muscle counts as 1.0 per workout/routine, and a secondary muscle counts as 0.5 per workout/routine
54
+ */
55
+ const getMuscleHeatmapDataForWorkoutsOrRoutines = ({ workoutsOrRoutines, }) => {
56
+ // initialise all keys to 0
57
+ const data = _muscleHeatmapKeys.reduce((prev, curr) => (Object.assign(Object.assign({}, prev), { [curr]: 0 })), {});
58
+ workoutsOrRoutines.forEach((workoutOrRoutine) => {
59
+ const muscleData = (0, exports.getMuscleHeatmapDataForExercises)(workoutOrRoutine.exercises);
60
+ Object.keys(muscleData).forEach((muscle) => {
61
+ data[muscle] =
62
+ (data[muscle] || 0) +
63
+ (muscleData[muscle] || 0);
64
+ });
65
+ });
66
+ return data;
67
+ };
68
+ exports.getMuscleHeatmapDataForWorkoutsOrRoutines = getMuscleHeatmapDataForWorkoutsOrRoutines;
@@ -0,0 +1,36 @@
1
+ import { MuscleGroup, SetType, SimplifiedMuscleGroup } from '.';
2
+ interface SetCountableSet {
3
+ indicator: SetType;
4
+ }
5
+ interface SetCountableExercise {
6
+ muscle_group: MuscleGroup;
7
+ other_muscles: MuscleGroup[];
8
+ sets: SetCountableSet[];
9
+ }
10
+ export interface SetCountableWorkoutOrRoutine {
11
+ exercises: SetCountableExercise[];
12
+ }
13
+ export declare const calculateSetContributionsForSimplifiedMuscleGroups: ({ muscle_group, other_muscles, }: {
14
+ muscle_group: MuscleGroup;
15
+ other_muscles: MuscleGroup[];
16
+ }) => {
17
+ core: number;
18
+ shoulders: number;
19
+ arms: number;
20
+ legs: number;
21
+ back: number;
22
+ chest: number;
23
+ };
24
+ export declare const calculateSimplifiedMuscleSplit: ({ workoutsOrRoutines, includeWarmupSets, }: {
25
+ workoutsOrRoutines: SetCountableWorkoutOrRoutine[];
26
+ includeWarmupSets: boolean;
27
+ }) => Record<SimplifiedMuscleGroup, number>;
28
+ export declare const calculateSetContributionsForMuscleGroups: ({ muscleGroup, otherMuscles, }: {
29
+ muscleGroup: MuscleGroup;
30
+ otherMuscles: MuscleGroup[];
31
+ }) => Record<MuscleGroup, number>;
32
+ export declare const calculateSetCountPerMuscleGroups: ({ workoutsOrRoutines, includeWarmupSets, }: {
33
+ workoutsOrRoutines: SetCountableWorkoutOrRoutine[];
34
+ includeWarmupSets: boolean;
35
+ }) => Record<MuscleGroup, number>;
36
+ export {};
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.calculateSetCountPerMuscleGroups = exports.calculateSetContributionsForMuscleGroups = exports.calculateSimplifiedMuscleSplit = exports.calculateSetContributionsForSimplifiedMuscleGroups = void 0;
7
+ const intersection_1 = __importDefault(require("lodash/intersection"));
8
+ const _1 = require(".");
9
+ const calculateSetContributionsForSimplifiedMuscleGroups = ({ muscle_group, other_muscles, }) => {
10
+ const getContribution = (mg) => {
11
+ if (mg.includes(muscle_group)) {
12
+ return 1;
13
+ }
14
+ else if ((0, intersection_1.default)(mg, other_muscles).length) {
15
+ return 0.5;
16
+ }
17
+ else if (muscle_group === 'full_body') {
18
+ return 1 / 6;
19
+ }
20
+ return 0;
21
+ };
22
+ return {
23
+ core: getContribution(_1.coreMuscles),
24
+ shoulders: getContribution(_1.shoulderMuscles),
25
+ arms: getContribution(_1.armMuscles),
26
+ legs: getContribution(_1.legMuscles),
27
+ back: getContribution(_1.backMuscles),
28
+ chest: getContribution(_1.chestMuscles),
29
+ };
30
+ };
31
+ exports.calculateSetContributionsForSimplifiedMuscleGroups = calculateSetContributionsForSimplifiedMuscleGroups;
32
+ const calculateSimplifiedMuscleSplit = ({ workoutsOrRoutines, includeWarmupSets, }) => {
33
+ const totals = {
34
+ core: 0,
35
+ shoulders: 0,
36
+ arms: 0,
37
+ legs: 0,
38
+ back: 0,
39
+ chest: 0,
40
+ };
41
+ for (const workoutOrRoutine of workoutsOrRoutines) {
42
+ for (const exercise of workoutOrRoutine.exercises) {
43
+ const trimmedSets = includeWarmupSets
44
+ ? exercise.sets
45
+ : exercise.sets.filter((s) => s.indicator !== 'warmup');
46
+ const setCount = trimmedSets.length;
47
+ const contributions = (0, exports.calculateSetContributionsForSimplifiedMuscleGroups)({
48
+ muscle_group: exercise.muscle_group,
49
+ other_muscles: exercise.other_muscles,
50
+ });
51
+ totals.core += contributions.core * setCount;
52
+ totals.shoulders += contributions.shoulders * setCount;
53
+ totals.arms += contributions.arms * setCount;
54
+ totals.legs += contributions.legs * setCount;
55
+ totals.back += contributions.back * setCount;
56
+ totals.chest += contributions.chest * setCount;
57
+ }
58
+ }
59
+ return totals;
60
+ };
61
+ exports.calculateSimplifiedMuscleSplit = calculateSimplifiedMuscleSplit;
62
+ const calculateSetContributionsForMuscleGroups = ({ muscleGroup, otherMuscles, }) => {
63
+ const getContribution = (mg) => {
64
+ if (mg === muscleGroup) {
65
+ return 1;
66
+ }
67
+ else if (otherMuscles.includes(mg)) {
68
+ return 0.5;
69
+ }
70
+ return 0;
71
+ };
72
+ return _1.muscleGroups.reduce((acc, mg) => {
73
+ acc[mg] = getContribution(mg);
74
+ return acc;
75
+ }, {});
76
+ };
77
+ exports.calculateSetContributionsForMuscleGroups = calculateSetContributionsForMuscleGroups;
78
+ const calculateSetCountPerMuscleGroups = ({ workoutsOrRoutines, includeWarmupSets, }) => {
79
+ const totals = _1.muscleGroups.reduce((acc, muscleGroup) => {
80
+ acc[muscleGroup] = 0;
81
+ return acc;
82
+ }, {});
83
+ for (const workoutOrRoutine of workoutsOrRoutines) {
84
+ for (const exercise of workoutOrRoutine.exercises) {
85
+ const trimmedSets = includeWarmupSets
86
+ ? exercise.sets
87
+ : exercise.sets.filter((s) => s.indicator !== 'warmup');
88
+ const setCount = trimmedSets.length;
89
+ const contributions = (0, exports.calculateSetContributionsForMuscleGroups)({
90
+ muscleGroup: exercise.muscle_group,
91
+ otherMuscles: exercise.other_muscles,
92
+ });
93
+ for (const muscleGroup of _1.muscleGroups) {
94
+ totals[muscleGroup] += contributions[muscleGroup] * setCount;
95
+ }
96
+ }
97
+ }
98
+ return totals;
99
+ };
100
+ exports.calculateSetCountPerMuscleGroups = calculateSetCountPerMuscleGroups;