hevy-shared 1.0.841 → 1.0.843

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.
package/built/index.d.ts CHANGED
@@ -570,7 +570,7 @@ export interface UserProfile {
570
570
  mutual_followers: PreviewMutualUser[];
571
571
  }
572
572
  export interface UserWorkoutStreakCount {
573
- streak_count: number | undefined;
573
+ streak_count: number;
574
574
  }
575
575
  export interface PublicUserProfile {
576
576
  private_profile: boolean;
@@ -1864,6 +1864,3 @@ export interface FolderLinkPreviewMetadataResponse extends LinkPreviewMetadataRe
1864
1864
  username: string;
1865
1865
  routine_count: number;
1866
1866
  }
1867
- export interface StartTimeableWorkout {
1868
- start_time: number;
1869
- }
@@ -325,6 +325,139 @@ describe('utils', () => {
325
325
  expect((0, utils_1.formatDurationInput)('99:99')).toBe('99:99');
326
326
  });
327
327
  });
328
+ describe('getEstimatedExercisesDurationSeconds', () => {
329
+ const testCases = [
330
+ {
331
+ exercises: [
332
+ {
333
+ exercise_type: 'duration',
334
+ rest_seconds: 10,
335
+ sets: [{ duration_seconds: 50, indicator: 'normal' }],
336
+ },
337
+ ],
338
+ expectedDuration: 50 + 10,
339
+ },
340
+ {
341
+ exercises: [
342
+ {
343
+ exercise_type: 'floors_duration',
344
+ rest_seconds: 10,
345
+ sets: [{ duration_seconds: 0, indicator: 'normal' }],
346
+ },
347
+ ],
348
+ expectedDuration: 10,
349
+ },
350
+ {
351
+ exercises: [
352
+ {
353
+ exercise_type: 'weight_duration',
354
+ rest_seconds: null,
355
+ sets: [{ duration_seconds: 30, indicator: 'normal' }],
356
+ },
357
+ ],
358
+ expectedDuration: 30 + utils_1.ESTIMATED_REST_TIMER_DURATION,
359
+ },
360
+ {
361
+ exercises: [
362
+ {
363
+ exercise_type: 'distance_duration',
364
+ rest_seconds: 120,
365
+ sets: [{ duration_seconds: 40, indicator: 'normal' }],
366
+ },
367
+ ],
368
+ expectedDuration: 40 + 120,
369
+ },
370
+ {
371
+ exercises: [
372
+ {
373
+ exercise_type: 'weight_duration',
374
+ rest_seconds: 120,
375
+ sets: [{ duration_seconds: null, indicator: 'normal' }],
376
+ },
377
+ ],
378
+ expectedDuration: 120 + utils_1.ESTIMATED_SET_DURATION,
379
+ },
380
+ {
381
+ exercises: [
382
+ {
383
+ exercise_type: 'duration',
384
+ rest_seconds: 0,
385
+ sets: [{ duration_seconds: null, indicator: 'normal' }],
386
+ },
387
+ ],
388
+ expectedDuration: utils_1.ESTIMATED_SET_DURATION,
389
+ },
390
+ {
391
+ exercises: [
392
+ {
393
+ exercise_type: 'reps_only',
394
+ rest_seconds: 180,
395
+ sets: [{ duration_seconds: null, indicator: 'normal' }],
396
+ },
397
+ {
398
+ exercise_type: 'reps_only',
399
+ rest_seconds: 180,
400
+ sets: [
401
+ {
402
+ duration_seconds: 0,
403
+ indicator: 'normal',
404
+ },
405
+ {
406
+ duration_seconds: 0,
407
+ indicator: 'normal',
408
+ },
409
+ {
410
+ duration_seconds: 0,
411
+ indicator: 'normal',
412
+ },
413
+ {
414
+ duration_seconds: 0,
415
+ indicator: 'normal',
416
+ },
417
+ ],
418
+ },
419
+ ],
420
+ expectedDuration: (180 + utils_1.ESTIMATED_SET_DURATION) * 5,
421
+ },
422
+ {
423
+ exercises: [
424
+ {
425
+ exercise_type: 'reps_only',
426
+ rest_seconds: null,
427
+ sets: [{ duration_seconds: null, indicator: 'normal' }],
428
+ },
429
+ {
430
+ exercise_type: 'reps_only',
431
+ rest_seconds: null,
432
+ sets: [
433
+ {
434
+ duration_seconds: 0,
435
+ indicator: 'normal',
436
+ },
437
+ {
438
+ duration_seconds: 0,
439
+ indicator: 'dropset',
440
+ },
441
+ {
442
+ duration_seconds: 0,
443
+ indicator: 'normal',
444
+ },
445
+ {
446
+ duration_seconds: 0,
447
+ indicator: 'dropset',
448
+ },
449
+ ],
450
+ },
451
+ ],
452
+ expectedDuration: utils_1.ESTIMATED_REST_TIMER_DURATION * 3 + 5 * utils_1.ESTIMATED_SET_DURATION,
453
+ },
454
+ ];
455
+ testCases.forEach((testCase) => {
456
+ it(`getEstimatedExercisesDurationSeconds`, () => {
457
+ expect((0, utils_1.getEstimatedExercisesDurationSeconds)(testCase)).toBe(testCase.expectedDuration);
458
+ });
459
+ });
460
+ });
328
461
  describe('splitAtUsernamesAndLinks', () => {
329
462
  it('Takes a string and returns an array of FormatAtText', () => {
330
463
  const inputOutputs = [
package/built/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Dayjs } from 'dayjs';
2
- import { BaseExerciseTemplate, FormatAtText, Result, StartTimeableWorkout, StrengthLevel, UserExerciseSet, Weekday } from '.';
2
+ import { BaseExerciseTemplate, ExerciseType, FormatAtText, Result, SetType, StrengthLevel, UserExerciseSet, UserFacingSetIndicator, Weekday } from '.';
3
3
  /**
4
4
  * Doesn't matter what you throw in the function it'll
5
5
  * always return a number. Non number values will return
@@ -176,14 +176,19 @@ export interface TotalSetCountWorkout {
176
176
  */
177
177
  export declare const userExerciseSetWeight: (set: UserExerciseSet, exerciseStore: BaseExerciseTemplate[], hundredPercentBodyweightExercise: boolean) => number;
178
178
  export declare const workoutSetCount: (w: TotalSetCountWorkout) => number;
179
+ export declare const UserFacingIndicatorToSetIndicator: (indicator: UserFacingSetIndicator) => SetType;
179
180
  interface GetEstimatedExercisesDuration {
180
181
  exercises: {
181
182
  rest_seconds: number | null;
183
+ exercise_type: ExerciseType;
182
184
  sets: {
183
185
  duration_seconds?: number | null;
186
+ indicator: SetType;
184
187
  }[];
185
188
  }[];
186
189
  }
190
+ export declare const ESTIMATED_SET_DURATION = 45;
191
+ export declare const ESTIMATED_REST_TIMER_DURATION = 90;
187
192
  export declare const getEstimatedExercisesDurationSeconds: ({ exercises, }: GetEstimatedExercisesDuration) => number;
188
193
  export declare const oneRepMaxPercentageMap: {
189
194
  [s: number]: number;
@@ -237,7 +242,9 @@ export declare const splitAtUsernamesAndLinks: (text: string) => FormatAtText[];
237
242
  export declare const validateYoutubeUrl: (url: string) => boolean;
238
243
  export declare const getYoutubeVideoId: (url: string) => string | undefined;
239
244
  /**@param workouts must be sorted descending by start_time */
240
- export declare const calculateCurrentWeekStreak: (workouts: StartTimeableWorkout[], firstWeekday: Weekday, untilUnix?: number) => number;
245
+ export declare const calculateCurrentWeekStreak: (workouts: {
246
+ start_time: number;
247
+ }[], firstWeekday: Weekday, untilUnix?: number) => number;
241
248
  export declare const startOfWeek: (d: Dayjs, firstDayOfWeek: Weekday) => Dayjs;
242
249
  export declare const weekdayNumberMap: {
243
250
  [key in Weekday]: number;
package/built/utils.js CHANGED
@@ -3,7 +3,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.weekdayNumberMap = exports.startOfWeek = exports.calculateCurrentWeekStreak = exports.getYoutubeVideoId = exports.validateYoutubeUrl = exports.splitAtUsernamesAndLinks = exports.isVersionAGreaterOrEqualToVersionB = exports.generateUserGroupValue = exports.generateUserGroup = exports.isBaseExerciseTemplate = exports.getStrengthLevelFromPercentile = exports.numberToLocaleString = exports.numberWithCommas = exports.setVolume = exports.oneRepMax = exports.oneRepMaxPercentageMap = exports.getEstimatedExercisesDurationSeconds = exports.workoutSetCount = exports.userExerciseSetWeight = exports.workoutDistanceMeters = exports.workoutReps = exports.workoutDurationSeconds = exports.removeAccents = exports.getClosestDataPointAroundTargetDate = exports.getClosestDataPointBeforeTargetDate = exports.findMapped = exports.stringToNumber = exports.forceStringToNumber = exports.formatDurationInput = exports.isValidFormattedTime = exports.isWholeNumber = exports.isNumber = exports.isValidUuid = exports.isValidPhoneNumber = exports.isValidWebUrl = exports.URL_REGEX = exports.isValidEmail = exports.secondsToWordFormatMinutes = exports.secondsToWordFormat = exports.secondsToClockFormat = exports.secondsToClockParts = exports.isValidUsername = exports.roundToWholeNumber = exports.roundToOneDecimal = exports.roundToTwoDecimal = exports.divide = exports.clampNumber = exports.num = void 0;
6
+ exports.startOfWeek = exports.calculateCurrentWeekStreak = exports.getYoutubeVideoId = exports.validateYoutubeUrl = exports.splitAtUsernamesAndLinks = exports.isVersionAGreaterOrEqualToVersionB = exports.generateUserGroupValue = exports.generateUserGroup = exports.isBaseExerciseTemplate = exports.getStrengthLevelFromPercentile = exports.numberToLocaleString = exports.numberWithCommas = exports.setVolume = exports.oneRepMax = exports.oneRepMaxPercentageMap = exports.getEstimatedExercisesDurationSeconds = exports.ESTIMATED_REST_TIMER_DURATION = exports.ESTIMATED_SET_DURATION = exports.UserFacingIndicatorToSetIndicator = exports.workoutSetCount = exports.userExerciseSetWeight = exports.workoutDistanceMeters = exports.workoutReps = exports.workoutDurationSeconds = exports.removeAccents = exports.getClosestDataPointAroundTargetDate = exports.getClosestDataPointBeforeTargetDate = exports.findMapped = exports.stringToNumber = exports.forceStringToNumber = exports.formatDurationInput = exports.isValidFormattedTime = exports.isWholeNumber = exports.isNumber = exports.isValidUuid = exports.isValidPhoneNumber = exports.isValidWebUrl = exports.URL_REGEX = exports.isValidEmail = exports.secondsToWordFormatMinutes = exports.secondsToWordFormat = exports.secondsToClockFormat = exports.secondsToClockParts = exports.isValidUsername = exports.roundToWholeNumber = exports.roundToOneDecimal = exports.roundToTwoDecimal = exports.divide = exports.clampNumber = exports.num = void 0;
7
+ exports.weekdayNumberMap = void 0;
7
8
  const dayjs_1 = __importDefault(require("dayjs"));
8
9
  /**
9
10
  * Doesn't matter what you throw in the function it'll
@@ -448,18 +449,45 @@ const workoutSetCount = (w) => {
448
449
  }, 0);
449
450
  };
450
451
  exports.workoutSetCount = workoutSetCount;
451
- const ESTIMATED_SET_DURATION = 45;
452
- const ESTIMATED_REST_TIMER_DURATION = 90;
452
+ const UserFacingIndicatorToSetIndicator = (indicator) => {
453
+ switch (indicator) {
454
+ case 'dropset':
455
+ return 'dropset';
456
+ case 'warmup':
457
+ return 'warmup';
458
+ case 'failure':
459
+ return 'failure';
460
+ default:
461
+ return 'normal';
462
+ }
463
+ };
464
+ exports.UserFacingIndicatorToSetIndicator = UserFacingIndicatorToSetIndicator;
465
+ exports.ESTIMATED_SET_DURATION = 45;
466
+ exports.ESTIMATED_REST_TIMER_DURATION = 90;
467
+ const isDurationExercise = (type) => {
468
+ return (type === 'duration' ||
469
+ type === 'weight_duration' ||
470
+ type === 'distance_duration' ||
471
+ type === 'floors_duration' ||
472
+ type === 'steps_duration');
473
+ };
453
474
  const getEstimatedExercisesDurationSeconds = ({ exercises, }) => {
454
475
  const totalSeconds = exercises.reduce((exercisesTotal, exercise) => {
455
476
  var _a;
456
- const restPerSet = (_a = exercise.rest_seconds) !== null && _a !== void 0 ? _a : ESTIMATED_REST_TIMER_DURATION;
457
- const exerciseTotal = exercise.sets.reduce((setTotal, set) => {
477
+ const restPerSet = (_a = exercise.rest_seconds) !== null && _a !== void 0 ? _a : exports.ESTIMATED_REST_TIMER_DURATION;
478
+ const setsTotal = exercise.sets.reduce((setTotal, set) => {
458
479
  var _a;
459
- const duration = (_a = set.duration_seconds) !== null && _a !== void 0 ? _a : ESTIMATED_SET_DURATION;
480
+ // Sometimes we get 0 values for duration on exercises that aren't duration.
481
+ // Added this check to prevent having a estimated duration of 0 for these.
482
+ const duration = isDurationExercise(exercise.exercise_type)
483
+ ? (_a = set.duration_seconds) !== null && _a !== void 0 ? _a : exports.ESTIMATED_SET_DURATION
484
+ : exports.ESTIMATED_SET_DURATION;
485
+ // if it is a dropset, we don't add the rest time
486
+ if (set.indicator === 'dropset')
487
+ return setTotal + duration;
460
488
  return setTotal + duration + restPerSet;
461
489
  }, 0);
462
- return exercisesTotal + exerciseTotal;
490
+ return exercisesTotal + setsTotal;
463
491
  }, 0);
464
492
  return totalSeconds;
465
493
  };
@@ -720,6 +748,7 @@ const calculateCurrentWeekStreak = (workouts, firstWeekday, untilUnix = (0, dayj
720
748
  }
721
749
  i += 1;
722
750
  }
751
+ // check if the current week has any workouts
723
752
  weekStart = (0, exports.startOfWeek)(dayjs_1.default.unix(untilUnix), firstWeekday);
724
753
  weekEnd = weekStart.add(1, 'week');
725
754
  if (workouts.find(({ start_time }) => start_time >= weekStart.unix() && start_time <= weekEnd.unix())) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hevy-shared",
3
- "version": "1.0.841",
3
+ "version": "1.0.843",
4
4
  "description": "",
5
5
  "main": "built/index.js",
6
6
  "types": "built/index.d.ts",