UNPKG

trainingpeaks-sdk

Version:
98 lines (97 loc) 4.21 kB
import { ValidationError } from '../../domain/errors/domain-errors.js'; import { WorkoutValidationError } from '../../domain/errors/workout-errors.js'; export const calculateWorkoutDuration = (structure) => { return structure.structure.reduce((sum, element) => { return sum + element.length.value; }, 0); }; export const createWorkout = (id, name, date, duration, description, distance, activityType, structure, fileContent, fileName) => { if (!id || id.trim().length === 0) { throw new ValidationError('Workout ID cannot be empty', 'id'); } if (!name || name.trim().length === 0) { throw new ValidationError('Workout name cannot be empty', 'name'); } if (name.trim().length > 200) { throw new ValidationError('Workout name cannot exceed 200 characters', 'name'); } if (duration < 0) { throw new ValidationError('Workout duration cannot be negative', 'duration'); } if (!isFinite(duration)) { throw new ValidationError('Workout duration must be a finite number', 'duration'); } if (distance !== undefined && (distance < 0 || !isFinite(distance))) { throw new ValidationError('Workout distance must be a non-negative finite number', 'distance'); } if (description && description.length > 1000) { throw new ValidationError('Workout description cannot exceed 1000 characters', 'description'); } if (activityType && activityType.trim().length > 50) { throw new ValidationError('Activity type cannot exceed 50 characters', 'activityType'); } if (fileName && fileName.trim().length > 255) { throw new ValidationError('File name cannot exceed 255 characters', 'fileName'); } const now = new Date(); return { id: id.trim(), name: name.trim(), description: description?.trim() || '', date, duration, distance, activityType: activityType?.trim(), structure, fileContent, fileName: fileName?.trim(), createdAt: now, updatedAt: now, }; }; export const createStructuredWorkout = (id, name, date, structure, description, activityType) => { if (!structure) { throw new WorkoutValidationError('Workout structure is required for structured workout'); } if (!structure.structure || structure.structure.length === 0) { throw new WorkoutValidationError('Workout structure must contain at least one element'); } const totalDuration = calculateWorkoutDuration(structure); return createWorkout(id, name, date, totalDuration, description, undefined, activityType, structure); }; export const updateWorkout = (workout, updates) => { if (updates.name !== undefined && (!updates.name || updates.name.trim().length === 0)) { throw new ValidationError('Workout name cannot be empty', 'name'); } if (updates.name && updates.name.trim().length > 200) { throw new ValidationError('Workout name cannot exceed 200 characters', 'name'); } if (updates.description && updates.description.length > 1000) { throw new ValidationError('Workout description cannot exceed 1000 characters', 'description'); } if (updates.distance !== undefined && (updates.distance < 0 || !isFinite(updates.distance))) { throw new ValidationError('Workout distance must be a non-negative finite number', 'distance'); } if (updates.activityType && updates.activityType.trim().length > 50) { throw new ValidationError('Activity type cannot exceed 50 characters', 'activityType'); } return { ...workout, ...updates, name: updates.name?.trim() || workout.name, description: updates.description?.trim() ?? workout.description, activityType: updates.activityType?.trim() ?? workout.activityType, updatedAt: new Date(), }; }; export const isStructuredWorkout = (workout) => { return Boolean(workout.structure && workout.structure.structure.length > 0); }; export const getWorkoutDistance = (workout) => { if (workout.distance !== undefined) { return workout.distance; } return undefined; };