hevy-shared 1.0.940 → 1.0.942
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/hevyTrainer.d.ts +3 -7
- package/built/hevyTrainer.js +5 -41
- package/built/index.d.ts +0 -4
- package/built/index.js +2 -3
- package/built/tests/utils.test.js +52 -0
- package/built/utils.d.ts +10 -0
- package/built/utils.js +39 -2
- package/package.json +1 -1
package/built/hevyTrainer.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { WeeklyTrainingFrequency, TrainingGoal, TrainingLevel, SimplifiedMuscleGroup, MuscleGroup, LibraryExercise, ExerciseCategory, GranularEquipment, HevyTrainerProgramEquipment
|
|
1
|
+
import { WeeklyTrainingFrequency, TrainingGoal, TrainingLevel, SimplifiedMuscleGroup, MuscleGroup, LibraryExercise, ExerciseCategory, GranularEquipment, HevyTrainerProgramEquipment } from '.';
|
|
2
2
|
export type HevyTrainerExerciseCategory = typeof hevyTrainerExerciseCategories[number];
|
|
3
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
|
-
export declare const trainingGoalLengths: readonly ["strength_short", "strength_default", "strength_long", "build_muscle_short", "build_muscle_default", "build_muscle_long", "fat_loss_short", "fat_loss_default", "fat_loss_long"];
|
|
7
|
-
export type TrainingGoalLength = typeof trainingGoalLengths[number];
|
|
8
6
|
export declare const trainerGymTypes: readonly ["home_gym", "garage_gym", "commercial_gym", "full_gym"];
|
|
9
7
|
export type TrainerGymType = typeof trainerGymTypes[number];
|
|
10
8
|
export declare const granularEquipmentDefaults: {
|
|
@@ -47,7 +45,6 @@ export interface ProgramGenerationParams<T extends HevyTrainerLibraryExercise> {
|
|
|
47
45
|
selectedLevel: TrainingLevel;
|
|
48
46
|
selectedEquipments: GranularEquipment[];
|
|
49
47
|
selectedWorkoutDurationMinutes?: WorkoutDurationMinutes;
|
|
50
|
-
selectedRestTimerLength: RestTimerLength;
|
|
51
48
|
exerciseStore: T[];
|
|
52
49
|
focusMuscle?: SimplifiedMuscleGroup;
|
|
53
50
|
excludedExerciseIds?: Set<string>;
|
|
@@ -75,7 +72,7 @@ export type RestTimersPerCategory = {
|
|
|
75
72
|
[key in HevyTrainerExerciseCategory]: number;
|
|
76
73
|
};
|
|
77
74
|
export type RestTimers = {
|
|
78
|
-
[key in
|
|
75
|
+
[key in TrainingGoal]: RestTimersPerCategory;
|
|
79
76
|
};
|
|
80
77
|
export type ExercisePriorities = {
|
|
81
78
|
[key in MuscleGroup]: exerciseId[];
|
|
@@ -138,8 +135,7 @@ export interface TrainerProgram {
|
|
|
138
135
|
}
|
|
139
136
|
export declare const getTrainerSetCount: (trainerAlgorithmSettings: TrainerAlgorithmSettings, goal: TrainingGoal, frequency: WeeklyTrainingFrequency) => number;
|
|
140
137
|
export declare const getTrainerRepRange: (trainerAlgorithmSettings: TrainerAlgorithmSettings, goal: TrainingGoal, exerciseCategory: HevyTrainerExerciseCategory) => RepRange;
|
|
141
|
-
export declare const getTrainerRestTimerSeconds: (trainerAlgorithmSettings: TrainerAlgorithmSettings,
|
|
142
|
-
export declare const getRestTimerLength: (goal: TrainingGoal, length: RestTimerLength) => TrainingGoalLength;
|
|
138
|
+
export declare const getTrainerRestTimerSeconds: (trainerAlgorithmSettings: TrainerAlgorithmSettings, goal: TrainingGoal, exerciseCategory: HevyTrainerExerciseCategory) => number;
|
|
143
139
|
/**
|
|
144
140
|
* Normalizes the exercise category to a HevyTrainerExerciseCategory
|
|
145
141
|
* - Treat custom exercises and exercises with no category as `compound`
|
package/built/hevyTrainer.js
CHANGED
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.generateProgram = exports.pickExerciseForPrescription = exports.getPrioritySortedExercises = exports.isEquipmentCompatible = exports.normalizeExerciseCategory = exports.
|
|
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
5
|
exports.workoutDurationOptions = [40, 60, 80];
|
|
6
|
-
exports.trainingGoalLengths = [
|
|
7
|
-
'strength_short',
|
|
8
|
-
'strength_default',
|
|
9
|
-
'strength_long',
|
|
10
|
-
'build_muscle_short',
|
|
11
|
-
'build_muscle_default',
|
|
12
|
-
'build_muscle_long',
|
|
13
|
-
'fat_loss_short',
|
|
14
|
-
'fat_loss_default',
|
|
15
|
-
'fat_loss_long',
|
|
16
|
-
];
|
|
17
6
|
exports.trainerGymTypes = [
|
|
18
7
|
'home_gym',
|
|
19
8
|
'garage_gym',
|
|
@@ -214,35 +203,10 @@ const getTrainerRepRange = (trainerAlgorithmSettings, goal, exerciseCategory) =>
|
|
|
214
203
|
return trainerAlgorithmSettings.rep_ranges[goal][exerciseCategory];
|
|
215
204
|
};
|
|
216
205
|
exports.getTrainerRepRange = getTrainerRepRange;
|
|
217
|
-
const getTrainerRestTimerSeconds = (trainerAlgorithmSettings,
|
|
218
|
-
return trainerAlgorithmSettings.rest_timers[
|
|
206
|
+
const getTrainerRestTimerSeconds = (trainerAlgorithmSettings, goal, exerciseCategory) => {
|
|
207
|
+
return trainerAlgorithmSettings.rest_timers[goal][exerciseCategory];
|
|
219
208
|
};
|
|
220
209
|
exports.getTrainerRestTimerSeconds = getTrainerRestTimerSeconds;
|
|
221
|
-
const getRestTimerLength = (goal, length) => {
|
|
222
|
-
switch (goal) {
|
|
223
|
-
case 'strength':
|
|
224
|
-
return length === 'short'
|
|
225
|
-
? 'strength_short'
|
|
226
|
-
: length === 'default'
|
|
227
|
-
? 'strength_default'
|
|
228
|
-
: 'strength_long';
|
|
229
|
-
case 'build_muscle':
|
|
230
|
-
return length === 'short'
|
|
231
|
-
? 'build_muscle_short'
|
|
232
|
-
: length === 'default'
|
|
233
|
-
? 'build_muscle_default'
|
|
234
|
-
: 'build_muscle_long';
|
|
235
|
-
case 'fat_loss':
|
|
236
|
-
return length === 'short'
|
|
237
|
-
? 'fat_loss_short'
|
|
238
|
-
: length === 'default'
|
|
239
|
-
? 'fat_loss_default'
|
|
240
|
-
: 'fat_loss_long';
|
|
241
|
-
default:
|
|
242
|
-
return 'strength_default';
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
exports.getRestTimerLength = getRestTimerLength;
|
|
246
210
|
/**
|
|
247
211
|
* Normalizes the exercise category to a HevyTrainerExerciseCategory
|
|
248
212
|
* - Treat custom exercises and exercises with no category as `compound`
|
|
@@ -534,7 +498,7 @@ exports.pickExerciseForPrescription = pickExerciseForPrescription;
|
|
|
534
498
|
*/
|
|
535
499
|
const generateProgram = (params) => {
|
|
536
500
|
var _a;
|
|
537
|
-
const { trainerAlgorithmSettings, selectedDays, selectedGoal, selectedLevel, selectedEquipments, selectedWorkoutDurationMinutes,
|
|
501
|
+
const { trainerAlgorithmSettings, selectedDays, selectedGoal, selectedLevel, selectedEquipments, selectedWorkoutDurationMinutes, exerciseStore, focusMuscle, excludedExerciseIds, } = params;
|
|
538
502
|
const routines = exports.programSplits[selectedDays];
|
|
539
503
|
const program = {
|
|
540
504
|
name: selectedDays,
|
|
@@ -601,7 +565,7 @@ const generateProgram = (params) => {
|
|
|
601
565
|
sets: (0, exports.getTrainerSetCount)(trainerAlgorithmSettings, selectedGoal, selectedDays),
|
|
602
566
|
repRangeStart: repRange.rep_range_start,
|
|
603
567
|
repRangeEnd: repRange.rep_range_end,
|
|
604
|
-
restTimerSeconds: (0, exports.getTrainerRestTimerSeconds)(trainerAlgorithmSettings,
|
|
568
|
+
restTimerSeconds: (0, exports.getTrainerRestTimerSeconds)(trainerAlgorithmSettings, selectedGoal, exercisePrescription.category),
|
|
605
569
|
warmupSetCount: exercisePrescription.warmup_set_count,
|
|
606
570
|
notes: (_a = trainerAlgorithmSettings.exercise_notes[exercise.id]) !== null && _a !== void 0 ? _a : '',
|
|
607
571
|
});
|
package/built/index.d.ts
CHANGED
|
@@ -640,11 +640,9 @@ export declare const isCustomExerciseType: (x: any) => x is CustomExerciseType;
|
|
|
640
640
|
export declare const trainingGoals: readonly ["strength", "build_muscle", "fat_loss"];
|
|
641
641
|
export declare const trainingLevels: readonly ["beginner", "intermediate", "advanced"];
|
|
642
642
|
export declare const exerciseCategories: readonly ["isolation", "compound", "assistance-compound"];
|
|
643
|
-
export declare const restTimerLengths: readonly ["short", "default", "long"];
|
|
644
643
|
export type TrainingGoal = Lookup<typeof trainingGoals>;
|
|
645
644
|
export type TrainingLevel = Lookup<typeof trainingLevels>;
|
|
646
645
|
export type ExerciseCategory = Lookup<typeof exerciseCategories>;
|
|
647
|
-
export type RestTimerLength = typeof restTimerLengths[number];
|
|
648
646
|
export type HevyTrainerProgramEquipment = Extract<Equipment, 'barbell' | 'dumbbell' | 'machine'>;
|
|
649
647
|
export declare const hevyTrainerProgramEquipments: readonly ["barbell", "dumbbell", "machine"];
|
|
650
648
|
export declare const granularEquipments: readonly ["barbell", "dumbbell", "kettlebell", "plate", "medicine_ball", "ez_bar", "landmine", "trap_bar", "pullup_bar", "dip_bar", "squat_rack", "flat_bench", "adjustable_bench", "dual_cable_machine", "single_cable_machine", "lat_pulldown_cable", "leg_press_machine", "smith_machine", "t_bar", "plate_machines", "stack_machines", "treadmill", "elliptical_trainer", "rowing_machine", "spinning", "stair_machine", "air_bike", "suspension_band", "resistance_band", "battle_rope", "rings", "jump_rope"];
|
|
@@ -1261,7 +1259,6 @@ export interface HevyTrainerProgram {
|
|
|
1261
1259
|
focus_muscle?: SimplifiedMuscleGroup;
|
|
1262
1260
|
next_workout_index: number;
|
|
1263
1261
|
workout_duration_minutes?: WorkoutDurationMinutes;
|
|
1264
|
-
rest_timer_length: RestTimerLength;
|
|
1265
1262
|
}
|
|
1266
1263
|
export interface PostHevyTrainerProgramRequestBody {
|
|
1267
1264
|
program: {
|
|
@@ -1287,7 +1284,6 @@ export interface UpdateHevyTrainerProgramRequestBody {
|
|
|
1287
1284
|
focus_muscle?: SimplifiedMuscleGroup;
|
|
1288
1285
|
next_workout_index?: number;
|
|
1289
1286
|
workout_duration_minutes?: WorkoutDurationMinutes;
|
|
1290
|
-
rest_timer_length?: RestTimerLength;
|
|
1291
1287
|
routines: {
|
|
1292
1288
|
id: string;
|
|
1293
1289
|
title: string;
|
package/built/index.js
CHANGED
|
@@ -14,8 +14,8 @@ 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.isPublicWorkout = exports.isSetType = exports.isRPE = exports.validRpeValues = exports.isSetPersonalRecordType = exports.supportedInstructionsLanguages = exports.weeklyTrainingFrequencies = exports.isGranularEquipment = exports.granularEquipments = exports.hevyTrainerProgramEquipments = exports.
|
|
18
|
-
exports.isOAuthScope = exports.supportedScopes = exports.isSuggestedUserSource = exports.isValidUserWorkoutMetricsType = exports.isBodyMeasurementKey = exports.measurementsList = exports.isHevyTrainerRoutine = exports.isWorkoutBiometrics =
|
|
17
|
+
exports.isHeartRateSamples = exports.isPublicWorkout = exports.isSetType = exports.isRPE = exports.validRpeValues = exports.isSetPersonalRecordType = exports.supportedInstructionsLanguages = exports.weeklyTrainingFrequencies = exports.isGranularEquipment = exports.granularEquipments = exports.hevyTrainerProgramEquipments = 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
19
|
const typeUtils_1 = require("./typeUtils");
|
|
20
20
|
__exportStar(require("./constants"), exports);
|
|
21
21
|
__exportStar(require("./utils"), exports);
|
|
@@ -227,7 +227,6 @@ exports.exerciseCategories = [
|
|
|
227
227
|
'compound',
|
|
228
228
|
'assistance-compound',
|
|
229
229
|
];
|
|
230
|
-
exports.restTimerLengths = ['short', 'default', 'long'];
|
|
231
230
|
exports.hevyTrainerProgramEquipments = [
|
|
232
231
|
'barbell',
|
|
233
232
|
'dumbbell',
|
|
@@ -210,6 +210,58 @@ describe('utils', () => {
|
|
|
210
210
|
expect((0, utils_1.findMapped)([], () => undefined)).toBeUndefined();
|
|
211
211
|
});
|
|
212
212
|
});
|
|
213
|
+
describe('toFragmentedJSON', () => {
|
|
214
|
+
it('converts any array into an array of JSON chunks with a maximum given length', () => {
|
|
215
|
+
expect((0, utils_1.toFragmentedJSON)([
|
|
216
|
+
{ value: 'AAAAAAAAAAAAAAAA' },
|
|
217
|
+
{ value: 'BBBBBBBBBBBBBBBBBBBBB' },
|
|
218
|
+
{ value: 'CCCCCCCCCCCCCCCC' },
|
|
219
|
+
], 64)).toEqual([
|
|
220
|
+
JSON.stringify([
|
|
221
|
+
{ value: 'AAAAAAAAAAAAAAAA' },
|
|
222
|
+
{ value: 'BBBBBBBBBBBBBBBBBBBBB' },
|
|
223
|
+
]),
|
|
224
|
+
JSON.stringify([{ value: 'CCCCCCCCCCCCCCCC' }]),
|
|
225
|
+
]);
|
|
226
|
+
expect((0, utils_1.toFragmentedJSON)([
|
|
227
|
+
{ value: 'AAAAAAAAAAAAAAAA' },
|
|
228
|
+
{ value: 'BBBBBBBBBBBBBBBBBBBBB' },
|
|
229
|
+
{ value: 'CCCCCCCCCCCCCCCC' },
|
|
230
|
+
], 35)).toEqual([
|
|
231
|
+
JSON.stringify([{ value: 'AAAAAAAAAAAAAAAA' }]),
|
|
232
|
+
JSON.stringify([{ value: 'BBBBBBBBBBBBBBBBBBBBB' }]),
|
|
233
|
+
JSON.stringify([{ value: 'CCCCCCCCCCCCCCCC' }]),
|
|
234
|
+
]);
|
|
235
|
+
expect(() => (0, utils_1.toFragmentedJSON)([
|
|
236
|
+
{ value: 'AAAAAAAAAAAAAAAA' },
|
|
237
|
+
{ value: 'BBBBBBBBBBBBBBBBBBBBB' },
|
|
238
|
+
{ value: 'CCCCCCCCCCCCCCCC' },
|
|
239
|
+
], 34)).toThrow();
|
|
240
|
+
expect((0, utils_1.toFragmentedJSON)(['A', 'B', 'C'], 15)).toEqual([
|
|
241
|
+
JSON.stringify(['A', 'B', 'C']),
|
|
242
|
+
]);
|
|
243
|
+
expect((0, utils_1.toFragmentedJSON)(['A', 'B', 'C'], 10)).toEqual([
|
|
244
|
+
JSON.stringify(['A', 'B']),
|
|
245
|
+
JSON.stringify(['C']),
|
|
246
|
+
]);
|
|
247
|
+
expect((0, utils_1.toFragmentedJSON)(['A', 'B', 'C'], 5)).toEqual([
|
|
248
|
+
JSON.stringify(['A']),
|
|
249
|
+
JSON.stringify(['B']),
|
|
250
|
+
JSON.stringify(['C']),
|
|
251
|
+
]);
|
|
252
|
+
expect(() => (0, utils_1.toFragmentedJSON)(['A', 'B', 'C'], 1)).toThrow();
|
|
253
|
+
expect(() => (0, utils_1.toFragmentedJSON)(['A', 'B', 'C'], 0)).toThrow();
|
|
254
|
+
expect((0, utils_1.toFragmentedJSON)([], 1)).toEqual([]);
|
|
255
|
+
expect((0, utils_1.toFragmentedJSON)([], 0)).toEqual([]);
|
|
256
|
+
});
|
|
257
|
+
it('returns an empty array for an empty input array', () => {
|
|
258
|
+
expect((0, utils_1.toFragmentedJSON)(['blah'], 100)).toEqual([
|
|
259
|
+
JSON.stringify(['blah']),
|
|
260
|
+
]);
|
|
261
|
+
expect((0, utils_1.toFragmentedJSON)([], 100)).toEqual([]);
|
|
262
|
+
expect((0, utils_1.toFragmentedJSON)([], 100)).not.toEqual([JSON.stringify([])]);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
213
265
|
describe('getClosestDataPointBeforeTargetDate', () => {
|
|
214
266
|
it('gets the closest data point before a target date, if such a data point exists, using a function to extract the date from the data points', () => {
|
|
215
267
|
var _a, _b, _c, _d;
|
package/built/utils.d.ts
CHANGED
|
@@ -90,6 +90,16 @@ export declare const stringToNumber: (value?: string) => number | undefined;
|
|
|
90
90
|
* such value was produced. Equivalent to `firstNotNullOfOrNull` in Kotlin.
|
|
91
91
|
*/
|
|
92
92
|
export declare const findMapped: <T, R>(array: T[], transform: (element: T) => R) => R | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* converts any array into an array of JSON chunks with a maximum given length
|
|
95
|
+
* @param data an array of objects or primitives to be split into chunks
|
|
96
|
+
* @param maxLength maximum length of any single returned JSON string
|
|
97
|
+
* @returns an array of JSON strings, each one no longer than `maxLength`
|
|
98
|
+
* @throws an error if fragmentation is impossible due to input data structure
|
|
99
|
+
*/
|
|
100
|
+
export declare const toFragmentedJSON: <T>(data: T[], maxLength: number, options?: {
|
|
101
|
+
lengthIn: "utf8bytes" | "characters";
|
|
102
|
+
}) => string[];
|
|
93
103
|
/**
|
|
94
104
|
* Finds the closest data point that occurs before or at the target date using binary search.
|
|
95
105
|
* Assumes input array is sorted by date in ascending order.
|
package/built/utils.js
CHANGED
|
@@ -3,8 +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.
|
|
7
|
-
exports.rawInstructionsToIndexedSteps = exports.formatSetValue = exports.exerciseWeight = exports.distance = exports.weekdayNumberMap = void 0;
|
|
6
|
+
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.toFragmentedJSON = 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.formatSetValue = exports.exerciseWeight = exports.distance = exports.weekdayNumberMap = exports.startOfWeek = void 0;
|
|
8
8
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
9
9
|
const _1 = require(".");
|
|
10
10
|
/**
|
|
@@ -298,6 +298,43 @@ const findMapped = (array, transform) => {
|
|
|
298
298
|
}
|
|
299
299
|
};
|
|
300
300
|
exports.findMapped = findMapped;
|
|
301
|
+
/**
|
|
302
|
+
* converts any array into an array of JSON chunks with a maximum given length
|
|
303
|
+
* @param data an array of objects or primitives to be split into chunks
|
|
304
|
+
* @param maxLength maximum length of any single returned JSON string
|
|
305
|
+
* @returns an array of JSON strings, each one no longer than `maxLength`
|
|
306
|
+
* @throws an error if fragmentation is impossible due to input data structure
|
|
307
|
+
*/
|
|
308
|
+
const toFragmentedJSON = (data, maxLength, options = { lengthIn: 'utf8bytes' }) => {
|
|
309
|
+
const outputArray = [];
|
|
310
|
+
const recurse = (left, right) => {
|
|
311
|
+
if (left === right)
|
|
312
|
+
return;
|
|
313
|
+
// slice the array and convert it to JSON
|
|
314
|
+
const sliceJson = JSON.stringify(data.slice(left, right));
|
|
315
|
+
const length = options.lengthIn === 'characters'
|
|
316
|
+
? sliceJson.length
|
|
317
|
+
: Buffer.byteLength(sliceJson, 'utf8');
|
|
318
|
+
if (length <= maxLength) {
|
|
319
|
+
// the size is good, push the chunk to the output array
|
|
320
|
+
outputArray.push(sliceJson);
|
|
321
|
+
}
|
|
322
|
+
else if (right > left + 1) {
|
|
323
|
+
// there are at least 2 elements in the current slice
|
|
324
|
+
const middle = Math.ceil((left + right) / 2);
|
|
325
|
+
recurse(left, middle);
|
|
326
|
+
recurse(middle, right);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
// we can't subdivide any further but the string is still too long
|
|
330
|
+
throw new Error(`couldn't subdivide element`);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
outputArray.length = 0;
|
|
334
|
+
recurse(0, data.length);
|
|
335
|
+
return outputArray;
|
|
336
|
+
};
|
|
337
|
+
exports.toFragmentedJSON = toFragmentedJSON;
|
|
301
338
|
/**
|
|
302
339
|
* Finds the closest data point that occurs before or at the target date using binary search.
|
|
303
340
|
* Assumes input array is sorted by date in ascending order.
|