hevy-shared 1.0.876 → 1.0.877

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.
@@ -699,4 +699,76 @@ describe('utils', () => {
699
699
  expect((0, utils_1.calculateCurrentWeekStreak)(workouts, firstWeekday, untilUnix)).toBe(0);
700
700
  });
701
701
  });
702
+ describe('formatSetValue', () => {
703
+ const baseParams = {
704
+ set: {
705
+ weight_kg: 100,
706
+ reps: 10,
707
+ duration_seconds: 90,
708
+ distance_meters: 1500,
709
+ custom_metric: 15,
710
+ },
711
+ units: {
712
+ weight: 'kg',
713
+ distance: 'kilometers',
714
+ },
715
+ labels: {
716
+ weight: 'kg',
717
+ distance: ' km',
718
+ shortDistance: ' m',
719
+ steps: 'Steps',
720
+ floors: 'Floors',
721
+ },
722
+ };
723
+ it('formats weight and reps for weight-based exercises', () => {
724
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'weight_reps' }))).toBe('100 kg x 10');
725
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'bodyweight_reps' }))).toBe('100 kg x 10');
726
+ });
727
+ it('formats assisted bodyweight reps with negative weight', () => {
728
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'bodyweight_assisted_reps', set: Object.assign(Object.assign({}, baseParams.set), { weight_kg: 15, reps: 8 }) }))).toBe('-15 kg x 8');
729
+ });
730
+ it('formats reps-only exercises', () => {
731
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'reps_only' }))).toBe('10');
732
+ });
733
+ it('formats distance with duration', () => {
734
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'distance_duration' }))).toBe('1.5 km - 1min 30s');
735
+ });
736
+ it('formats duration-only exercises', () => {
737
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'duration' }))).toBe('1min 30s');
738
+ });
739
+ it('formats short distance with weight', () => {
740
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'short_distance_weight', set: Object.assign(Object.assign({}, baseParams.set), { distance_meters: 250 }) }))).toBe('100 kg - 250 m');
741
+ });
742
+ it('handles null reps as zero', () => {
743
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'weight_reps', set: Object.assign(Object.assign({}, baseParams.set), { reps: null }) }))).toBe('100 kg x 0');
744
+ });
745
+ it('formats weight with duration', () => {
746
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'weight_duration' }))).toBe('100 kg - 1min 30s');
747
+ });
748
+ it('formats floors with duration', () => {
749
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'floors_duration' }))).toBe('15 Floors - 1min 30s');
750
+ });
751
+ it('formats steps with duration', () => {
752
+ expect((0, utils_1.formatSetValue)(Object.assign(Object.assign({}, baseParams), { exerciseType: 'steps_duration' }))).toBe('15 Steps - 1min 30s');
753
+ });
754
+ });
755
+ describe('distance', () => {
756
+ it('converts meters to kilometers and rounds to two decimals', () => {
757
+ expect((0, utils_1.distance)(1555, 'kilometers')).toBe(1.56);
758
+ });
759
+ it('converts meters to miles and rounds to two decimals', () => {
760
+ expect((0, utils_1.distance)(1000, 'miles')).toBe(0.62);
761
+ });
762
+ });
763
+ describe('exerciseWeight', () => {
764
+ it('returns rounded kg values for metric units', () => {
765
+ expect((0, utils_1.exerciseWeight)(10.555, 'kg')).toBe(10.56);
766
+ });
767
+ it('converts kg to lbs and rounds to two decimals', () => {
768
+ expect((0, utils_1.exerciseWeight)(100, 'lbs')).toBe(220.46);
769
+ });
770
+ it('rounds lbs values to two decimals', () => {
771
+ expect((0, utils_1.exerciseWeight)(4.535, 'lbs')).toBe(10.0);
772
+ });
773
+ });
702
774
  });
package/built/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Dayjs } from 'dayjs';
2
- import { BaseExerciseTemplate, ExerciseInstructionsStep, ExerciseType, FormatAtText, Result, SetType, StrengthLevel, UserExerciseSet, UserFacingSetIndicator, Weekday } from '.';
2
+ import { BaseExerciseTemplate, DistanceUnit, ExerciseInstructionsStep, ExerciseType, FormatAtText, Result, SetType, StrengthLevel, UserExerciseSet, UserFacingSetIndicator, Weekday, WeightUnit } 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
@@ -249,5 +249,29 @@ export declare const startOfWeek: (d: Dayjs, firstDayOfWeek: Weekday) => Dayjs;
249
249
  export declare const weekdayNumberMap: {
250
250
  [key in Weekday]: number;
251
251
  };
252
+ export declare const distance: (value: number, distanceUnit: DistanceUnit) => number;
253
+ export declare const exerciseWeight: (value: number, weightUnit: WeightUnit) => number;
254
+ interface getSetValueParams {
255
+ exerciseType: ExerciseType;
256
+ set: {
257
+ weight_kg: number | null;
258
+ reps: number | null;
259
+ duration_seconds: number | null;
260
+ distance_meters: number | null;
261
+ custom_metric: number | null;
262
+ };
263
+ units: {
264
+ weight: WeightUnit;
265
+ distance: DistanceUnit;
266
+ };
267
+ labels: {
268
+ weight: string;
269
+ distance: string;
270
+ shortDistance: string;
271
+ steps: string;
272
+ floors: string;
273
+ };
274
+ }
275
+ export declare const formatSetValue: ({ exerciseType, set, units, labels, }: getSetValueParams) => string;
252
276
  export declare const rawInstructionsToIndexedSteps: (rawInstructions: string) => ExerciseInstructionsStep[];
253
277
  export {};
package/built/utils.js CHANGED
@@ -4,8 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
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.rawInstructionsToIndexedSteps = exports.weekdayNumberMap = void 0;
7
+ exports.rawInstructionsToIndexedSteps = exports.formatSetValue = exports.exerciseWeight = exports.distance = exports.weekdayNumberMap = void 0;
8
8
  const dayjs_1 = __importDefault(require("dayjs"));
9
+ const _1 = require(".");
9
10
  /**
10
11
  * Doesn't matter what you throw in the function it'll
11
12
  * always return a number. Non number values will return
@@ -775,6 +776,64 @@ exports.weekdayNumberMap = {
775
776
  friday: 5,
776
777
  saturday: 6,
777
778
  };
779
+ const distance = (value, distanceUnit) => {
780
+ if (distanceUnit === 'miles') {
781
+ const unrounded = (0, _1.exactMetersToMiles)(value);
782
+ return (0, exports.roundToTwoDecimal)(unrounded);
783
+ }
784
+ return (0, exports.roundToTwoDecimal)(value / 1000);
785
+ };
786
+ exports.distance = distance;
787
+ const exerciseWeight = (value, weightUnit) => {
788
+ if (weightUnit === 'lbs') {
789
+ return (0, exports.roundToTwoDecimal)((0, _1.exactKgtoLbs)(value));
790
+ }
791
+ return (0, exports.roundToTwoDecimal)(value);
792
+ };
793
+ exports.exerciseWeight = exerciseWeight;
794
+ const formatSetValue = ({ exerciseType, set, units, labels, }) => {
795
+ var _a, _b, _c;
796
+ switch (exerciseType) {
797
+ case 'weight_reps':
798
+ case 'bodyweight_reps': {
799
+ const weight = `${(0, exports.exerciseWeight)(set.weight_kg || 0, units.weight)} ${labels.weight}`;
800
+ const reps = `${(_a = set.reps) !== null && _a !== void 0 ? _a : 0}`;
801
+ return `${weight} x ${reps}`;
802
+ }
803
+ case 'bodyweight_assisted_reps': {
804
+ const weight = `-${(0, exports.exerciseWeight)(set.weight_kg || 0, units.weight)} ${labels.weight}`;
805
+ const reps = `${(_b = set.reps) !== null && _b !== void 0 ? _b : 0}`;
806
+ return `${weight} x ${reps}`;
807
+ }
808
+ case 'reps_only':
809
+ return `${(_c = set.reps) !== null && _c !== void 0 ? _c : 0}`;
810
+ case 'distance_duration': {
811
+ const distanceValue = `${(0, exports.distance)(set.distance_meters || 0, units.distance)}${labels.distance}`;
812
+ const duration = `${(0, exports.secondsToWordFormat)(Number(set.duration_seconds))}`;
813
+ return `${distanceValue} - ${duration}`;
814
+ }
815
+ case 'duration':
816
+ return (0, exports.secondsToWordFormat)(Number(set.duration_seconds));
817
+ case 'short_distance_weight': {
818
+ const weight = `${(0, exports.exerciseWeight)(set.weight_kg || 0, units.weight)} ${labels.weight}`;
819
+ const shortDistance = (0, exports.roundToTwoDecimal)(set.distance_meters || 0);
820
+ return `${weight} - ${shortDistance}${labels.shortDistance}`;
821
+ }
822
+ case 'weight_duration': {
823
+ const weight = `${(0, exports.exerciseWeight)(set.weight_kg || 0, units.weight)} ${labels.weight}`;
824
+ const duration = `${(0, exports.secondsToWordFormat)(Number(set.duration_seconds))}`;
825
+ return `${weight} - ${duration}`;
826
+ }
827
+ case 'floors_duration':
828
+ return `${set.custom_metric ? (0, exports.roundToWholeNumber)(set.custom_metric) : 0} ${labels.floors} - ${(0, exports.secondsToWordFormat)(Number(set.duration_seconds))}`;
829
+ case 'steps_duration':
830
+ return `${set.custom_metric ? (0, exports.roundToWholeNumber)(set.custom_metric) : 0} ${labels.steps} - ${(0, exports.secondsToWordFormat)(Number(set.duration_seconds))}`;
831
+ default:
832
+ (0, _1.exhaustiveTypeCheck)(exerciseType);
833
+ return '';
834
+ }
835
+ };
836
+ exports.formatSetValue = formatSetValue;
778
837
  const rawInstructionsToIndexedSteps = (rawInstructions) => {
779
838
  const instructionsByLine = rawInstructions
780
839
  .split('\n')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hevy-shared",
3
- "version": "1.0.876",
3
+ "version": "1.0.877",
4
4
  "description": "",
5
5
  "main": "built/index.js",
6
6
  "types": "built/index.d.ts",