UNPKG

trainingpeaks-sdk

Version:
163 lines (162 loc) 6.57 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAggregateSummary = exports.isAggregateConsistent = exports.getAggregateDuration = exports.removeWorkoutFile = exports.addWorkoutFile = exports.removeWorkoutStructure = exports.updateWorkoutStructure = exports.updateWorkoutAggregate = exports.createWorkoutAggregate = void 0; const domain_errors_1 = require("../../domain/errors/domain-errors.js"); const workout_errors_1 = require("../../domain/errors/workout-errors.js"); const workout_1 = require("./workout.js"); const createWorkoutAggregate = (id, name, date, duration, description, distance, activityType, structure, fileContent, fileName) => { let workout; if (structure) { validateWorkoutStructure(structure); const calculatedDuration = (0, workout_1.calculateWorkoutDuration)(structure); if (Math.abs(duration - calculatedDuration) > 1) { throw new workout_errors_1.WorkoutValidationError(`Provided duration (${duration}s) does not match calculated duration (${calculatedDuration}s)`); } workout = (0, workout_1.createStructuredWorkout)(id, name, date, structure, description, activityType); } else { workout = (0, workout_1.createWorkout)(id, name, date, duration, description, distance, activityType, structure, fileContent, fileName); } return { workout, structure, }; }; exports.createWorkoutAggregate = createWorkoutAggregate; const updateWorkoutAggregate = (aggregate, updates) => { const updatedWorkout = (0, workout_1.updateWorkout)(aggregate.workout, updates); return { ...aggregate, workout: updatedWorkout, }; }; exports.updateWorkoutAggregate = updateWorkoutAggregate; const updateWorkoutStructure = (aggregate, newStructure) => { validateWorkoutStructure(newStructure); const newDuration = (0, workout_1.calculateWorkoutDuration)(newStructure); const updatedWorkout = { ...aggregate.workout, structure: newStructure, duration: newDuration, updatedAt: new Date(), }; return { workout: updatedWorkout, structure: newStructure, }; }; exports.updateWorkoutStructure = updateWorkoutStructure; const removeWorkoutStructure = (aggregate, newDuration) => { if (newDuration < 0 || !isFinite(newDuration)) { throw new domain_errors_1.ValidationError('Duration must be a non-negative finite number', 'duration'); } const updatedWorkout = { ...aggregate.workout, structure: undefined, duration: newDuration, updatedAt: new Date(), }; return { workout: updatedWorkout, structure: undefined, }; }; exports.removeWorkoutStructure = removeWorkoutStructure; const addWorkoutFile = (aggregate, fileContent, fileName) => { if (!fileContent || !fileName) { throw new domain_errors_1.ValidationError('File content and name are required'); } if (fileName.trim().length > 255) { throw new domain_errors_1.ValidationError('File name cannot exceed 255 characters', 'fileName'); } const updatedWorkout = { ...aggregate.workout, fileContent, fileName: fileName.trim(), updatedAt: new Date(), }; return { ...aggregate, workout: updatedWorkout, }; }; exports.addWorkoutFile = addWorkoutFile; const removeWorkoutFile = (aggregate) => { const updatedWorkout = { ...aggregate.workout, fileContent: undefined, fileName: undefined, updatedAt: new Date(), }; return { ...aggregate, workout: updatedWorkout, }; }; exports.removeWorkoutFile = removeWorkoutFile; const getAggregateDuration = (aggregate) => { if (aggregate.structure) { return (0, workout_1.calculateWorkoutDuration)(aggregate.structure); } return aggregate.workout.duration; }; exports.getAggregateDuration = getAggregateDuration; const isAggregateConsistent = (aggregate) => { try { if (aggregate.structure) { const calculatedDuration = (0, workout_1.calculateWorkoutDuration)(aggregate.structure); const durationDiff = Math.abs(aggregate.workout.duration - calculatedDuration); if (durationDiff > 1) { return false; } validateWorkoutStructure(aggregate.structure); } if (aggregate.workout.fileContent && !aggregate.workout.fileName) { return false; } if (!aggregate.workout.fileContent && aggregate.workout.fileName) { return false; } return true; } catch { return false; } }; exports.isAggregateConsistent = isAggregateConsistent; const getAggregateSummary = (aggregate) => { const { workout, structure } = aggregate; return { id: workout.id, name: workout.name, date: workout.date, duration: (0, exports.getAggregateDuration)(aggregate), distance: workout.distance, activityType: workout.activityType, isStructured: Boolean(structure), hasFile: Boolean(workout.fileContent), structureElementCount: structure?.structure.length || 0, isConsistent: (0, exports.isAggregateConsistent)(aggregate), }; }; exports.getAggregateSummary = getAggregateSummary; const validateWorkoutStructure = (structure) => { if (!structure.structure || structure.structure.length === 0) { throw new workout_errors_1.WorkoutStructureError('Workout structure must contain at least one element'); } for (let i = 0; i < structure.structure.length - 1; i++) { const current = structure.structure[i]; const next = structure.structure[i + 1]; if (current && next && current.end > next.begin) { throw new workout_errors_1.WorkoutStructureError(`Structure elements overlap: element ${i} ends after element ${i + 1} begins`, { elementIndex: i, nextElementIndex: i + 1 }); } } structure.structure.forEach((element, index) => { if (!element.steps || element.steps.length === 0) { throw new workout_errors_1.WorkoutStructureError(`Structure element ${index} must have at least one step`, { elementIndex: index }); } if (element.end <= element.begin) { throw new workout_errors_1.WorkoutStructureError(`Structure element ${index} end time must be greater than begin time`, { elementIndex: index, begin: element.begin, end: element.end }); } }); };