@kaiord/fit 4.0.0
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/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1954 -0
- package/dist/index.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/shared/message-numbers.ts","../src/adapters/schemas/fit-file-type.ts","../src/adapters/shared/type-guards.ts","../src/adapters/schemas/fit-sub-sport.ts","../src/adapters/sub-sport/sub-sport.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-metadata.mapper.ts","../src/adapters/schemas/fit-duration.ts","../src/adapters/schemas/fit-target.ts","../src/adapters/schemas/fit-equipment.ts","../src/adapters/equipment/equipment.mapper.ts","../src/adapters/krd-to-fit/duration-converters/conditional.ts","../src/adapters/krd-to-fit/duration-converters/repeat.ts","../src/adapters/krd-to-fit/duration-converters/repeat-hr-power.ts","../src/adapters/krd-to-fit/duration-converters/simple.ts","../src/adapters/krd-to-fit/krd-to-fit-duration.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-target-cadence.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-target-heart-rate.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-target-pace.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-target-power.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-target-stroke.converter.ts","../src/adapters/krd-to-fit/krd-to-fit-target.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-step.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit-workout.mapper.ts","../src/adapters/krd-to-fit/krd-to-fit.converter.ts","../src/adapters/shared/coordinate.converter.ts","../src/adapters/schemas/fit-message-keys.ts","../src/adapters/schemas/fit-event.ts","../src/adapters/event/event-type-maps.ts","../src/adapters/event/event.mapper.ts","../src/adapters/event/fit-to-krd-event.converter.ts","../src/adapters/extensions/extensions.extractor.ts","../src/adapters/schemas/fit-lap-trigger.ts","../src/adapters/schemas/fit-sport.ts","../src/adapters/schemas/fit-lap.ts","../src/adapters/lap/lap-trigger.mapper.ts","../src/adapters/lap/lap.mapper.ts","../src/adapters/lap/fit-to-krd-lap.converter.ts","../src/adapters/schemas/fit-record.ts","../src/adapters/record/record.mapper.ts","../src/adapters/record/fit-to-krd-record.converter.ts","../src/adapters/schemas/fit-session.ts","../src/adapters/session/session.mapper.ts","../src/adapters/session/fit-to-krd-session.converter.ts","../src/adapters/messages/activity.mapper.ts","../src/adapters/metadata/metadata.mapper.ts","../src/adapters/length-unit/length-unit.mapper.ts","../src/adapters/duration/duration-converters.ts","../src/adapters/duration/repeat-duration-converters.ts","../src/adapters/duration/duration.converter.ts","../src/adapters/duration/duration.mapper.ts","../src/adapters/target/target-cadence.converter.ts","../src/adapters/target/target-heart-rate.converter.ts","../src/adapters/target/target-pace.converter.ts","../src/adapters/target/power-helpers.ts","../src/adapters/target/target-power.converter.ts","../src/adapters/target/target-stroke.converter.ts","../src/adapters/target/target.converter.ts","../src/adapters/target/target.mapper.ts","../src/adapters/workout/step.mapper.ts","../src/adapters/workout/repetition.builder.ts","../src/adapters/workout/workout.mapper.ts","../src/adapters/messages/messages.validator.ts","../src/adapters/messages/workout.mapper.ts","../src/adapters/messages/messages.mapper.ts","../src/adapters/garmin-fitsdk.ts","../src/providers.ts"],"names":["z","durationTypeSchema","targetTypeSchema","targetUnitSchema","createFitParsingError","convertCadenceTarget","convertHeartRateTarget","convertPaceTarget","convertPowerTarget","KRD_VERSION","fileTypeSchema"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * FIT Message Numbers from Garmin FIT SDK Profile\n * Source: @garmin/fitsdk Profile.MesgNum\n */\n\nexport const FIT_MESSAGE_NUMBERS = {\n FILE_ID: 0,\n WORKOUT: 26,\n WORKOUT_STEP: 27,\n} as const;\n","import { z } from \"zod\";\n\n/**\n * FIT file type enum schema\n *\n * Defines the type of data contained in the FIT file.\n * Used in FILE_ID message to identify file purpose.\n *\n * @see https://developer.garmin.com/fit/file-types/\n */\nexport const fitFileTypeSchema = z.enum([\n \"device\",\n \"settings\",\n \"sport\",\n \"activity\",\n \"workout\",\n \"course\",\n \"schedules\",\n \"weight\",\n \"totals\",\n \"goals\",\n \"bloodPressure\",\n \"monitoringA\",\n \"activitySummary\",\n \"monitoringDaily\",\n \"monitoringB\",\n \"segment\",\n \"segmentList\",\n \"exdConfiguration\",\n]);\n\n/**\n * TypeScript type for FIT file type\n */\nexport type FitFileType = z.infer<typeof fitFileTypeSchema>;\n\n/**\n * Bidirectional mapping: FIT file type → numeric value\n *\n * Maps string file type to FIT protocol numeric values.\n */\nexport const FIT_FILE_TYPE_TO_NUMBER: Record<FitFileType, number> = {\n device: 1,\n settings: 2,\n sport: 3,\n activity: 4,\n workout: 5,\n course: 6,\n schedules: 7,\n weight: 9,\n totals: 10,\n goals: 11,\n bloodPressure: 14,\n monitoringA: 15,\n activitySummary: 20,\n monitoringDaily: 28,\n monitoringB: 32,\n segment: 34,\n segmentList: 35,\n exdConfiguration: 40,\n};\n\n/**\n * Bidirectional mapping: numeric value → FIT file type\n *\n * Maps FIT protocol numeric values to string file type.\n */\nexport const NUMBER_TO_FIT_FILE_TYPE: Record<number, FitFileType> = {\n 1: \"device\",\n 2: \"settings\",\n 3: \"sport\",\n 4: \"activity\",\n 5: \"workout\",\n 6: \"course\",\n 7: \"schedules\",\n 9: \"weight\",\n 10: \"totals\",\n 11: \"goals\",\n 14: \"bloodPressure\",\n 15: \"monitoringA\",\n 20: \"activitySummary\",\n 28: \"monitoringDaily\",\n 32: \"monitoringB\",\n 34: \"segment\",\n 35: \"segmentList\",\n 40: \"exdConfiguration\",\n};\n","import { sportSchema } from \"@kaiord/core\";\nimport type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\n\n/**\n * Type guard to check if a step is a RepetitionBlock\n */\nexport const isRepetitionBlock = (\n step: WorkoutStep | RepetitionBlock\n): step is RepetitionBlock => {\n return \"repeatCount\" in step;\n};\n\n/**\n * Default values for FIT file generation and mapping\n */\nexport const DEFAULT_MANUFACTURER = \"development\" as const;\nexport const DEFAULT_SPORT = sportSchema.enum.cycling;\n\n/**\n * Maps FIT sport type to KRD sport type\n * Returns DEFAULT_SPORT if fitSport is undefined\n */\nexport const mapSportType = (fitSport: string | undefined): string => {\n if (!fitSport) {\n return DEFAULT_SPORT;\n }\n return fitSport.toLowerCase();\n};\n","import { z } from \"zod\";\n\nexport const fitSubSportSchema = z.enum([\n \"generic\",\n \"treadmill\",\n \"street\",\n \"trail\",\n \"track\",\n \"spin\",\n \"indoorCycling\",\n \"road\",\n \"mountain\",\n \"downhill\",\n \"recumbent\",\n \"cyclocross\",\n \"handCycling\",\n \"trackCycling\",\n \"indoorRowing\",\n \"elliptical\",\n \"stairClimbing\",\n \"lapSwimming\",\n \"openWater\",\n \"flexibilityTraining\",\n \"strengthTraining\",\n \"warmUp\",\n \"match\",\n \"exercise\",\n \"challenge\",\n \"indoorSkiing\",\n \"cardioTraining\",\n \"indoorWalking\",\n \"eBikeFitness\",\n \"bmx\",\n \"casualWalking\",\n \"speedWalking\",\n \"bikeToRunTransition\",\n \"runToBikeTransition\",\n \"swimToBikeTransition\",\n \"atv\",\n \"motocross\",\n \"backcountry\",\n \"resort\",\n \"rcDrone\",\n \"wingsuit\",\n \"whitewater\",\n \"skateSkiing\",\n \"yoga\",\n \"pilates\",\n \"indoorRunning\",\n \"gravelCycling\",\n \"eBikeMountain\",\n \"commuting\",\n \"mixedSurface\",\n \"navigate\",\n \"trackMe\",\n \"map\",\n \"singleGasDiving\",\n \"multiGasDiving\",\n \"gaugeDiving\",\n \"apneaDiving\",\n \"apneaHunting\",\n \"virtualActivity\",\n \"obstacle\",\n \"all\",\n]);\n\nexport type FitSubSport = z.infer<typeof fitSubSportSchema>;\n","import { subSportSchema, type SubSport } from \"@kaiord/core\";\nimport { fitSubSportSchema, type FitSubSport } from \"../schemas/fit-sub-sport\";\n\nconst FIT_TO_KRD_SUB_SPORT_MAP: Record<FitSubSport, SubSport> = {\n generic: \"generic\",\n treadmill: \"treadmill\",\n street: \"street\",\n trail: \"trail\",\n track: \"track\",\n spin: \"spin\",\n indoorCycling: \"indoor_cycling\",\n road: \"road\",\n mountain: \"mountain\",\n downhill: \"downhill\",\n recumbent: \"recumbent\",\n cyclocross: \"cyclocross\",\n handCycling: \"hand_cycling\",\n trackCycling: \"track_cycling\",\n indoorRowing: \"indoor_rowing\",\n elliptical: \"elliptical\",\n stairClimbing: \"stair_climbing\",\n lapSwimming: \"lap_swimming\",\n openWater: \"open_water\",\n flexibilityTraining: \"flexibility_training\",\n strengthTraining: \"strength_training\",\n warmUp: \"warm_up\",\n match: \"match\",\n exercise: \"exercise\",\n challenge: \"challenge\",\n indoorSkiing: \"indoor_skiing\",\n cardioTraining: \"cardio_training\",\n indoorWalking: \"indoor_walking\",\n eBikeFitness: \"e_bike_fitness\",\n bmx: \"bmx\",\n casualWalking: \"casual_walking\",\n speedWalking: \"speed_walking\",\n bikeToRunTransition: \"bike_to_run_transition\",\n runToBikeTransition: \"run_to_bike_transition\",\n swimToBikeTransition: \"swim_to_bike_transition\",\n atv: \"atv\",\n motocross: \"motocross\",\n backcountry: \"backcountry\",\n resort: \"resort\",\n rcDrone: \"rc_drone\",\n wingsuit: \"wingsuit\",\n whitewater: \"whitewater\",\n skateSkiing: \"skate_skiing\",\n yoga: \"yoga\",\n pilates: \"pilates\",\n indoorRunning: \"indoor_running\",\n gravelCycling: \"gravel_cycling\",\n eBikeMountain: \"e_bike_mountain\",\n commuting: \"commuting\",\n mixedSurface: \"mixed_surface\",\n navigate: \"navigate\",\n trackMe: \"track_me\",\n map: \"map\",\n singleGasDiving: \"single_gas_diving\",\n multiGasDiving: \"multi_gas_diving\",\n gaugeDiving: \"gauge_diving\",\n apneaDiving: \"apnea_diving\",\n apneaHunting: \"apnea_hunting\",\n virtualActivity: \"virtual_activity\",\n obstacle: \"obstacle\",\n all: \"all\",\n};\n\nconst KRD_TO_FIT_SUB_SPORT_MAP: Record<SubSport, FitSubSport> =\n Object.fromEntries(\n Object.entries(FIT_TO_KRD_SUB_SPORT_MAP).map(([fit, krd]) => [krd, fit])\n ) as Record<SubSport, FitSubSport>;\n\nexport const mapSubSportToKrd = (fitSubSport: unknown): SubSport => {\n const result = fitSubSportSchema.safeParse(fitSubSport);\n\n if (!result.success) {\n return subSportSchema.enum.generic;\n }\n\n return FIT_TO_KRD_SUB_SPORT_MAP[result.data] || subSportSchema.enum.generic;\n};\n\nexport const mapSubSportToFit = (krdSubSport: unknown): FitSubSport => {\n const result = subSportSchema.safeParse(krdSubSport);\n\n if (!result.success) {\n return fitSubSportSchema.enum.generic;\n }\n\n return (\n KRD_TO_FIT_SUB_SPORT_MAP[result.data] || fitSubSportSchema.enum.generic\n );\n};\n","import { Profile } from \"@garmin/fitsdk\";\nimport type { KRD } from \"@kaiord/core\";\nimport type { RepetitionBlock, Workout, WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { FIT_FILE_TYPE_TO_NUMBER } from \"../schemas/fit-file-type\";\nimport { isRepetitionBlock } from \"../shared/type-guards\";\nimport { mapSubSportToFit } from \"../sub-sport/sub-sport.mapper\";\n\nconst DEFAULT_MANUFACTURER = \"garmin\";\n\n/**\n * Maps KRD manufacturer string to valid FIT Profile manufacturer enum value.\n * Uses fuzzy matching (case-insensitive, prefix matching).\n */\nconst mapManufacturer = (\n manufacturer: string | undefined,\n logger: Logger\n): string => {\n if (!manufacturer) {\n return DEFAULT_MANUFACTURER;\n }\n\n const manufacturerEnum = Profile.types.manufacturer;\n const manufacturerValues = Object.values(manufacturerEnum);\n const normalized = manufacturer.toLowerCase();\n\n const matched = manufacturerValues.find(\n (value) =>\n value.toLowerCase() === normalized ||\n value.toLowerCase().startsWith(normalized) ||\n normalized.startsWith(value.toLowerCase())\n );\n\n if (matched) return matched;\n\n logger.warn(\n `Unknown manufacturer \"${manufacturer}\", using fallback \"${DEFAULT_MANUFACTURER}\"`,\n { original: manufacturer, fallback: DEFAULT_MANUFACTURER }\n );\n return DEFAULT_MANUFACTURER;\n};\n\nexport const convertMetadataToFileId = (\n krd: KRD,\n logger: Logger\n): Record<string, unknown> => {\n logger.debug(\"Converting metadata to file_id message\");\n\n const fileType =\n krd.type === \"structured_workout\"\n ? \"workout\"\n : krd.type === \"recorded_activity\"\n ? \"activity\"\n : krd.type === \"course\"\n ? \"course\"\n : \"workout\";\n\n const fileId: Record<string, unknown> = {\n type: FIT_FILE_TYPE_TO_NUMBER[fileType] ?? FIT_FILE_TYPE_TO_NUMBER.workout,\n timeCreated: new Date(krd.metadata.created),\n manufacturer: mapManufacturer(krd.metadata.manufacturer, logger),\n };\n\n if (krd.metadata.product !== undefined) {\n const productNumber = parseInt(krd.metadata.product, 10);\n if (!isNaN(productNumber)) {\n fileId.product = productNumber;\n }\n }\n\n if (krd.metadata.serialNumber) {\n const serialNumber = parseInt(krd.metadata.serialNumber, 10);\n if (!isNaN(serialNumber)) {\n fileId.serialNumber = serialNumber;\n }\n }\n\n return fileId;\n};\n\nexport const convertWorkoutMetadata = (\n workout: Workout,\n logger: Logger\n): Record<string, unknown> => {\n logger.debug(\"Converting workout metadata\");\n\n const numValidSteps = countValidSteps(workout.steps);\n\n const workoutMesg: Record<string, unknown> = {\n wktName: workout.name,\n sport: workout.sport,\n numValidSteps,\n };\n\n if (workout.subSport !== undefined) {\n workoutMesg.subSport = mapSubSportToFit(workout.subSport);\n }\n\n if (workout.poolLength !== undefined) {\n workoutMesg.poolLength = workout.poolLength;\n workoutMesg.poolLengthUnit = 0;\n }\n\n return workoutMesg;\n};\n\nconst countValidSteps = (\n steps: Array<WorkoutStep | RepetitionBlock>\n): number => {\n let count = 0;\n for (const step of steps) {\n if (isRepetitionBlock(step)) {\n count += step.steps.length + 1;\n } else {\n count += 1;\n }\n }\n return count;\n};\n","import { z } from \"zod\";\n\nexport const fitDurationTypeSchema = z.enum([\n \"time\",\n \"distance\",\n \"repeatUntilStepsCmplt\",\n \"repeatUntilHrGreaterThan\",\n \"hrLessThan\",\n \"hrGreaterThan\",\n \"calories\",\n \"powerLessThan\",\n \"powerGreaterThan\",\n \"repeatUntilTime\",\n \"repeatUntilDistance\",\n \"repeatUntilCalories\",\n \"repeatUntilHrLessThan\",\n \"repeatUntilPowerLessThan\",\n \"repeatUntilPowerGreaterThan\",\n \"open\",\n]);\n\nexport type FitDurationType = z.infer<typeof fitDurationTypeSchema>;\n","import { z } from \"zod\";\n\nexport const fitTargetTypeSchema = z.enum([\n \"power\",\n \"heartRate\",\n \"cadence\",\n \"speed\",\n \"swimStroke\",\n \"open\",\n]);\n\nexport type FitTargetType = z.infer<typeof fitTargetTypeSchema>;\n","import { z } from \"zod\";\n\nexport const fitEquipmentSchema = z.enum([\n \"none\",\n \"swimFins\",\n \"swimKickboard\",\n \"swimPaddles\",\n \"swimPullBuoy\",\n \"swimSnorkel\",\n]);\n\nexport type FitEquipment = z.infer<typeof fitEquipmentSchema>;\n","import { equipmentSchema, type Equipment } from \"@kaiord/core\";\nimport {\n fitEquipmentSchema,\n type FitEquipment,\n} from \"../schemas/fit-equipment\";\n\nconst FIT_TO_KRD_EQUIPMENT_MAP: Record<FitEquipment, Equipment> = {\n none: \"none\",\n swimFins: \"swim_fins\",\n swimKickboard: \"swim_kickboard\",\n swimPaddles: \"swim_paddles\",\n swimPullBuoy: \"swim_pull_buoy\",\n swimSnorkel: \"swim_snorkel\",\n};\n\nconst KRD_TO_FIT_EQUIPMENT_MAP: Record<Equipment, FitEquipment> =\n Object.fromEntries(\n Object.entries(FIT_TO_KRD_EQUIPMENT_MAP).map(([fit, krd]) => [krd, fit])\n ) as Record<Equipment, FitEquipment>;\n\nexport const mapEquipmentToKrd = (fitEquipment: unknown): Equipment => {\n const result = fitEquipmentSchema.safeParse(fitEquipment);\n\n if (!result.success) {\n return equipmentSchema.enum.none;\n }\n\n return FIT_TO_KRD_EQUIPMENT_MAP[result.data] || equipmentSchema.enum.none;\n};\n\nexport const mapEquipmentToFit = (krdEquipment: unknown): FitEquipment => {\n const result = equipmentSchema.safeParse(krdEquipment);\n\n if (!result.success) {\n return fitEquipmentSchema.enum.none;\n }\n\n return KRD_TO_FIT_EQUIPMENT_MAP[result.data] || fitEquipmentSchema.enum.none;\n};\n","import type { Duration } from \"@kaiord/core\";\nimport { durationTypeSchema } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../../schemas/fit-duration\";\n\nexport const convertConditionalDuration = (\n duration: Duration,\n message: Record<string, unknown>\n): boolean => {\n if (duration.type === durationTypeSchema.enum.heart_rate_less_than) {\n message.durationType = fitDurationTypeSchema.enum.hrLessThan;\n message.durationHr = duration.bpm;\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.power_less_than) {\n message.durationType = fitDurationTypeSchema.enum.powerLessThan;\n message.durationPower = duration.watts;\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.power_greater_than) {\n message.durationType = fitDurationTypeSchema.enum.powerGreaterThan;\n message.durationPower = duration.watts;\n return true;\n }\n\n return false;\n};\n","import type { Duration } from \"@kaiord/core\";\nimport { durationTypeSchema } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../../schemas/fit-duration\";\n\nexport const convertRepeatDuration = (\n duration: Duration,\n message: Record<string, unknown>\n): boolean => {\n if (duration.type === durationTypeSchema.enum.repeat_until_time) {\n message.durationType = fitDurationTypeSchema.enum.repeatUntilTime;\n message.durationTime = duration.seconds;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.repeat_until_distance) {\n message.durationType = fitDurationTypeSchema.enum.repeatUntilDistance;\n message.durationDistance = duration.meters;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.repeat_until_calories) {\n message.durationType = fitDurationTypeSchema.enum.repeatUntilCalories;\n message.durationCalories = duration.calories;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n return false;\n};\n","import type { Duration } from \"@kaiord/core\";\nimport { durationTypeSchema } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../../schemas/fit-duration\";\n\nexport const convertRepeatHrPowerDuration = (\n duration: Duration,\n message: Record<string, unknown>\n): boolean => {\n if (\n duration.type ===\n durationTypeSchema.enum.repeat_until_heart_rate_greater_than\n ) {\n message.durationType = fitDurationTypeSchema.enum.repeatUntilHrGreaterThan;\n message.durationHr = duration.bpm;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n if (\n duration.type === durationTypeSchema.enum.repeat_until_heart_rate_less_than\n ) {\n message.durationType = fitDurationTypeSchema.enum.repeatUntilHrLessThan;\n message.durationHr = duration.bpm;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.repeat_until_power_less_than) {\n message.durationType = fitDurationTypeSchema.enum.repeatUntilPowerLessThan;\n message.durationPower = duration.watts;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n if (\n duration.type === durationTypeSchema.enum.repeat_until_power_greater_than\n ) {\n message.durationType =\n fitDurationTypeSchema.enum.repeatUntilPowerGreaterThan;\n message.durationPower = duration.watts;\n message.durationStep = duration.repeatFrom;\n return true;\n }\n\n return false;\n};\n","import type { Duration } from \"@kaiord/core\";\nimport { durationTypeSchema } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../../schemas/fit-duration\";\n\nexport const convertSimpleDuration = (\n duration: Duration,\n message: Record<string, unknown>\n): boolean => {\n if (duration.type === durationTypeSchema.enum.time) {\n message.durationType = fitDurationTypeSchema.enum.time;\n message.durationTime = duration.seconds;\n message.durationValue = duration.seconds * 1000; // durationValue is in milliseconds\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.distance) {\n message.durationType = fitDurationTypeSchema.enum.distance;\n message.durationDistance = duration.meters;\n return true;\n }\n\n if (duration.type === durationTypeSchema.enum.calories) {\n message.durationType = fitDurationTypeSchema.enum.calories;\n message.durationCalories = duration.calories;\n return true;\n }\n\n return false;\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../schemas/fit-duration\";\nimport { convertConditionalDuration } from \"./duration-converters/conditional\";\nimport { convertRepeatDuration } from \"./duration-converters/repeat\";\nimport { convertRepeatHrPowerDuration } from \"./duration-converters/repeat-hr-power\";\nimport { convertSimpleDuration } from \"./duration-converters/simple\";\n\nexport const convertDuration = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n const { duration } = step;\n\n if (convertSimpleDuration(duration, message)) return;\n if (convertConditionalDuration(duration, message)) return;\n if (convertRepeatDuration(duration, message)) return;\n if (convertRepeatHrPowerDuration(duration, message)) return;\n\n message.durationType = fitDurationTypeSchema.enum.open;\n};\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\n\nexport const convertCadenceTarget = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n message.targetType = fitTargetTypeSchema.enum.cadence;\n if (step.target.type !== targetTypeSchema.enum.cadence) return;\n\n const value = step.target.value;\n if (value.unit === targetUnitSchema.enum.range) {\n message.targetValue = 0;\n message.customTargetCadenceLow = value.min;\n message.customTargetCadenceHigh = value.max;\n } else {\n message.targetValue = 0;\n message.customTargetCadenceLow = value.value;\n message.customTargetCadenceHigh = value.value;\n }\n};\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\n\nexport const convertHeartRateTarget = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n message.targetType = fitTargetTypeSchema.enum.heartRate;\n if (step.target.type !== targetTypeSchema.enum.heart_rate) return;\n\n const value = step.target.value;\n if (value.unit === targetUnitSchema.enum.zone) {\n message.targetHrZone = value.value;\n } else if (value.unit === targetUnitSchema.enum.range) {\n message.targetValue = 0;\n message.customTargetHeartRateLow = value.min;\n message.customTargetHeartRateHigh = value.max;\n } else if (value.unit === targetUnitSchema.enum.bpm) {\n // Garmin encoding: Absolute bpm needs +100 offset\n message.targetValue = value.value + 100;\n } else if (value.unit === targetUnitSchema.enum.percent_max) {\n // Garmin encoding: Percentage max HR has no offset\n message.targetValue = value.value;\n }\n};\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\n\nexport const convertPaceTarget = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n message.targetType = fitTargetTypeSchema.enum.speed;\n if (step.target.type !== targetTypeSchema.enum.pace) return;\n\n const value = step.target.value;\n if (value.unit === targetUnitSchema.enum.zone) {\n message.targetSpeedZone = value.value;\n } else if (value.unit === targetUnitSchema.enum.range) {\n message.targetValue = 0;\n message.customTargetSpeedLow = value.min;\n message.customTargetSpeedHigh = value.max;\n } else {\n message.targetValue = 0;\n message.customTargetSpeedLow = value.value;\n message.customTargetSpeedHigh = value.value;\n }\n};\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\n\nexport const convertPowerTarget = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n message.targetType = fitTargetTypeSchema.enum.power;\n if (step.target.type !== targetTypeSchema.enum.power) return;\n\n const value = step.target.value;\n if (value.unit === targetUnitSchema.enum.zone) {\n message.targetPowerZone = value.value;\n } else if (value.unit === targetUnitSchema.enum.range) {\n message.targetValue = 0;\n message.customTargetPowerLow = value.min;\n message.customTargetPowerHigh = value.max;\n } else if (value.unit === targetUnitSchema.enum.watts) {\n // Garmin encoding: Absolute watts need +1000 offset\n message.targetValue = value.value + 1000;\n } else if (value.unit === targetUnitSchema.enum.percent_ftp) {\n // Garmin encoding: Percentage FTP has no offset\n message.targetValue = value.value;\n }\n};\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\n\n/**\n * Converts KRD stroke_type target to FIT swimStroke target.\n *\n * The stroke value is already a FIT-compatible number (0-5):\n * 0 = freestyle, 1 = backstroke, 2 = breaststroke, 3 = butterfly, 4 = drill, 5 = mixed/IM\n */\nexport const convertStrokeTarget = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n message.targetType = fitTargetTypeSchema.enum.swimStroke;\n if (step.target.type !== targetTypeSchema.enum.stroke_type) return;\n\n // Zod discriminated union guarantees value exists when type is stroke_type\n const strokeValue = step.target.value as { unit: string; value: number };\n\n message.targetValue = strokeValue.value;\n};\n","import { targetTypeSchema } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\nimport { convertCadenceTarget } from \"./krd-to-fit-target-cadence.mapper\";\nimport { convertHeartRateTarget } from \"./krd-to-fit-target-heart-rate.mapper\";\nimport { convertPaceTarget } from \"./krd-to-fit-target-pace.mapper\";\nimport { convertPowerTarget } from \"./krd-to-fit-target-power.mapper\";\nimport { convertStrokeTarget } from \"./krd-to-fit-target-stroke.converter\";\n\nexport const convertTarget = (\n step: WorkoutStep,\n message: Record<string, unknown>\n): void => {\n if (step.target.type === targetTypeSchema.enum.open) {\n message.targetType = fitTargetTypeSchema.enum.open;\n return;\n }\n\n if (step.target.type === targetTypeSchema.enum.power) {\n convertPowerTarget(step, message);\n } else if (step.target.type === targetTypeSchema.enum.heart_rate) {\n convertHeartRateTarget(step, message);\n } else if (step.target.type === targetTypeSchema.enum.cadence) {\n convertCadenceTarget(step, message);\n } else if (step.target.type === targetTypeSchema.enum.pace) {\n convertPaceTarget(step, message);\n } else if (step.target.type === targetTypeSchema.enum.stroke_type) {\n convertStrokeTarget(step, message);\n }\n};\n","import { createFitParsingError } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { mapEquipmentToFit } from \"../equipment/equipment.mapper\";\nimport { convertDuration } from \"./krd-to-fit-duration.mapper\";\nimport { convertTarget } from \"./krd-to-fit-target.mapper\";\n\n/** FIT protocol maximum length for notes field */\nconst FIT_NOTES_MAX_LENGTH = 256;\n\nexport type TruncationBehavior = \"truncate\" | \"error\";\n\nexport type ConvertWorkoutStepOptions = {\n /** How to handle notes exceeding 256 characters. Default: \"truncate\" */\n notesTruncation?: TruncationBehavior;\n};\n\n/**\n * Converts a KRD workout step to a FIT workout step message.\n */\nexport const convertWorkoutStep = (\n step: WorkoutStep,\n messageIndex: number,\n logger: Logger,\n options: ConvertWorkoutStepOptions = {}\n): Record<string, unknown> => {\n const { notesTruncation = \"truncate\" } = options;\n\n logger.debug(\"Converting workout step\", { stepIndex: step.stepIndex });\n\n const workoutStepMesg: Record<string, unknown> = {\n messageIndex,\n };\n\n if (step.name) {\n workoutStepMesg.wktStepName = step.name;\n }\n\n if (step.intensity) {\n workoutStepMesg.intensity = step.intensity;\n }\n\n if (step.notes !== undefined) {\n workoutStepMesg.notes = convertNotes(\n step.notes,\n step.stepIndex,\n notesTruncation,\n logger\n );\n }\n\n if (step.equipment !== undefined) {\n workoutStepMesg.equipment = mapEquipmentToFit(step.equipment);\n }\n\n convertDuration(step, workoutStepMesg);\n convertTarget(step, workoutStepMesg);\n\n return workoutStepMesg;\n};\n\nconst convertNotes = (\n notes: string,\n stepIndex: number,\n behavior: TruncationBehavior,\n logger: Logger\n): string => {\n if (notes.length <= FIT_NOTES_MAX_LENGTH) {\n return notes;\n }\n\n if (behavior === \"error\") {\n throw createFitParsingError(\n `Notes exceed ${FIT_NOTES_MAX_LENGTH} characters at step ${stepIndex} ` +\n `(length: ${notes.length}). Use notesTruncation: \"truncate\" to auto-truncate.`\n );\n }\n\n logger.warn(\n `Notes truncated from ${notes.length} to ${FIT_NOTES_MAX_LENGTH} characters`,\n { stepIndex, originalLength: notes.length }\n );\n return notes.substring(0, FIT_NOTES_MAX_LENGTH);\n};\n","import type { RepetitionBlock, Workout } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../schemas/fit-duration\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\nimport { FIT_MESSAGE_NUMBERS } from \"../shared/message-numbers\";\nimport { isRepetitionBlock } from \"../shared/type-guards\";\nimport {\n convertWorkoutStep,\n type ConvertWorkoutStepOptions,\n} from \"./krd-to-fit-step.mapper\";\n\nexport type ConvertWorkoutStepsOptions = ConvertWorkoutStepOptions;\n\nexport const convertWorkoutSteps = (\n workout: Workout,\n logger: Logger,\n options: ConvertWorkoutStepsOptions = {}\n): Array<unknown> => {\n logger.debug(\"Converting workout steps\", { stepCount: workout.steps.length });\n\n const messages: Array<unknown> = [];\n let messageIndex = 0;\n\n for (const step of workout.steps) {\n if (isRepetitionBlock(step)) {\n const repetitionMessages = convertRepetitionBlock(\n step,\n messageIndex,\n logger,\n options\n );\n messages.push(...repetitionMessages);\n messageIndex += repetitionMessages.length;\n } else {\n const stepMessage = convertWorkoutStep(\n step,\n messageIndex,\n logger,\n options\n );\n messages.push(stepMessage);\n messageIndex += 1;\n }\n }\n\n return messages;\n};\n\nconst convertRepetitionBlock = (\n block: RepetitionBlock,\n startIndex: number,\n logger: Logger,\n options: ConvertWorkoutStepsOptions\n): Array<unknown> => {\n logger.debug(\"Converting repetition block\", {\n repeatCount: block.repeatCount,\n stepCount: block.steps.length,\n });\n\n const messages: Array<unknown> = [];\n let messageIndex = startIndex;\n\n for (const step of block.steps) {\n const stepMessage = convertWorkoutStep(step, messageIndex, logger, options);\n messages.push(stepMessage);\n messageIndex += 1;\n }\n\n const repeatMessage: Record<string, unknown> = {\n mesgNum: FIT_MESSAGE_NUMBERS.WORKOUT_STEP,\n messageIndex,\n durationType: fitDurationTypeSchema.enum.repeatUntilStepsCmplt,\n durationStep: startIndex,\n repeatSteps: block.repeatCount,\n targetType: fitTargetTypeSchema.enum.open,\n };\n messages.push(repeatMessage);\n\n return messages;\n};\n","import type { KRD } from \"@kaiord/core\";\nimport { workoutSchema, type Workout } from \"@kaiord/core\";\nimport { createFitParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { FIT_MESSAGE_NUMBERS } from \"../shared/message-numbers\";\nimport {\n convertMetadataToFileId,\n convertWorkoutMetadata,\n} from \"./krd-to-fit-metadata.mapper\";\nimport { convertWorkoutSteps } from \"./krd-to-fit-workout.mapper\";\n\n/**\n * Safely converts unknown to Record<string, unknown>.\n * Returns empty object if value is not a valid object.\n */\nconst toRecord = (value: unknown): Record<string, unknown> => {\n if (typeof value === \"object\" && value !== null) {\n return value as Record<string, unknown>;\n }\n return {};\n};\n\n/**\n * Extracts and validates workout data from KRD extensions.\n * Throws if workout is missing or invalid.\n */\nconst extractWorkout = (krd: KRD, logger: Logger): Workout => {\n const rawWorkout = krd.extensions?.structured_workout;\n if (!rawWorkout) {\n throw createFitParsingError(\"KRD missing workout data in extensions\");\n }\n\n const result = workoutSchema.safeParse(rawWorkout);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => `${i.path.join(\".\")}: ${i.message}`)\n .join(\"; \");\n logger.error(\"Invalid workout data in KRD extensions\", { issues });\n throw createFitParsingError(`Invalid workout data: ${issues}`);\n }\n\n return result.data;\n};\n\nexport const convertKRDToMessages = (\n krd: KRD,\n logger: Logger\n): Array<unknown> => {\n logger.debug(\"Converting KRD to FIT messages\");\n\n const messages: Array<unknown> = [];\n\n const fileIdMessage = convertMetadataToFileId(krd, logger);\n messages.push({\n mesgNum: FIT_MESSAGE_NUMBERS.FILE_ID,\n ...fileIdMessage,\n });\n\n const workout = extractWorkout(krd, logger);\n\n const workoutMessage = convertWorkoutMetadata(workout, logger);\n messages.push({\n mesgNum: FIT_MESSAGE_NUMBERS.WORKOUT,\n ...workoutMessage,\n });\n\n const workoutStepMessages = convertWorkoutSteps(workout, logger);\n for (const stepMessage of workoutStepMessages) {\n messages.push({\n mesgNum: FIT_MESSAGE_NUMBERS.WORKOUT_STEP,\n ...toRecord(stepMessage),\n });\n }\n\n logger.debug(\"Converted KRD to FIT messages\", {\n messageCount: messages.length,\n });\n\n return messages;\n};\n","/**\n * Coordinate conversion utilities for FIT ↔ KRD.\n *\n * FIT uses semicircles for coordinates (signed 32-bit integer).\n * KRD uses degrees (-90 to 90 for lat, -180 to 180 for lon).\n */\n\nconst SEMICIRCLES_TO_DEGREES = 180 / Math.pow(2, 31);\nconst DEGREES_TO_SEMICIRCLES = Math.pow(2, 31) / 180;\n\n/**\n * Converts FIT semicircles to degrees.\n * @param semicircles - Coordinate in semicircles (signed 32-bit integer)\n * @returns Coordinate in degrees\n */\nexport const semicirclesToDegrees = (semicircles: number): number =>\n semicircles * SEMICIRCLES_TO_DEGREES;\n\n/**\n * Converts degrees to FIT semicircles.\n * @param degrees - Coordinate in degrees\n * @returns Coordinate in semicircles (rounded to integer)\n */\nexport const degreesToSemicircles = (degrees: number): number =>\n Math.round(degrees * DEGREES_TO_SEMICIRCLES);\n\n/**\n * Validates that coordinates are within valid ranges.\n * Handles edge cases: NaN, Infinity.\n *\n * @param latSemicircles - Latitude in semicircles\n * @param lonSemicircles - Longitude in semicircles\n * @returns true if coordinates are valid\n */\nexport const validateCoordinates = (\n latSemicircles: number,\n lonSemicircles: number\n): boolean => {\n if (!Number.isFinite(latSemicircles) || !Number.isFinite(lonSemicircles)) {\n return false;\n }\n\n const degreesLat = semicirclesToDegrees(latSemicircles);\n const degreesLon = semicirclesToDegrees(lonSemicircles);\n\n return (\n degreesLat >= -90 &&\n degreesLat <= 90 &&\n degreesLon >= -180 &&\n degreesLon <= 180\n );\n};\n","import { z } from \"zod\";\n\nexport const fitMessageKeySchema = z.enum([\n \"fileIdMesgs\",\n \"workoutMesgs\",\n \"workoutStepMesgs\",\n \"sessionMesgs\",\n \"recordMesgs\",\n \"eventMesgs\",\n \"lapMesgs\",\n]);\n\nexport type FitMessageKey = z.infer<typeof fitMessageKeySchema>;\n","import { z } from \"zod\";\n\n/**\n * FIT event types (what kind of event occurred).\n */\nexport const fitEventSchema = z.enum([\n \"timer\",\n \"workout\",\n \"workoutStep\",\n \"powerDown\",\n \"powerUp\",\n \"offCourse\",\n \"session\",\n \"lap\",\n \"coursePoint\",\n \"battery\",\n \"virtualPartnerPace\",\n \"hrHighAlert\",\n \"hrLowAlert\",\n \"speedHighAlert\",\n \"speedLowAlert\",\n \"cadHighAlert\",\n \"cadLowAlert\",\n \"powerHighAlert\",\n \"powerLowAlert\",\n \"recoveryHr\",\n \"batteryLow\",\n \"timeDurationAlert\",\n \"distanceDurationAlert\",\n \"calorieDurationAlert\",\n \"activity\",\n \"fitnessEquipment\",\n \"length\",\n \"userMarker\",\n \"sportPoint\",\n \"calibration\",\n \"frontGearChange\",\n \"rearGearChange\",\n \"riderPositionChange\",\n \"elevHighAlert\",\n \"elevLowAlert\",\n]);\n\nexport type FitEvent = z.infer<typeof fitEventSchema>;\n\n/**\n * FIT event type (start, stop, marker, etc.).\n */\nexport const fitEventTypeSchema = z.enum([\n \"start\",\n \"stop\",\n \"consecutiveDepreciated\",\n \"marker\",\n \"stopAll\",\n \"beginDepreciated\",\n \"endDepreciated\",\n \"endAllDepreciated\",\n \"stopDisable\",\n \"stopDisableAll\",\n]);\n\nexport type FitEventType = z.infer<typeof fitEventTypeSchema>;\n\n/**\n * FIT EVENT message schema (Message ID: 21).\n *\n * Captures workout events like start, stop, pause, markers.\n */\nexport const fitEventMessageSchema = z.object({\n timestamp: z.number(),\n event: fitEventSchema,\n eventType: fitEventTypeSchema,\n eventGroup: z.number().optional(),\n data: z.number().optional(),\n data16: z.number().optional(),\n});\n\nexport type FitEventMessage = z.infer<typeof fitEventMessageSchema>;\n","import type { KRDEvent } from \"@kaiord/core\";\nimport type { FitEvent, FitEventType } from \"../schemas/fit-event\";\n\nexport const FIT_EVENT_TO_KRD_TYPE: Record<FitEvent, KRDEvent[\"eventType\"]> = {\n timer: \"event_timer\",\n workout: \"event_start\",\n workoutStep: \"event_workout_step_change\",\n powerDown: \"event_stop\",\n powerUp: \"event_start\",\n offCourse: \"event_marker\",\n session: \"event_session_start\",\n lap: \"event_lap\",\n coursePoint: \"event_marker\",\n battery: \"event_marker\",\n virtualPartnerPace: \"event_marker\",\n hrHighAlert: \"event_marker\",\n hrLowAlert: \"event_marker\",\n speedHighAlert: \"event_marker\",\n speedLowAlert: \"event_marker\",\n cadHighAlert: \"event_marker\",\n cadLowAlert: \"event_marker\",\n powerHighAlert: \"event_marker\",\n powerLowAlert: \"event_marker\",\n recoveryHr: \"event_marker\",\n batteryLow: \"event_marker\",\n timeDurationAlert: \"event_marker\",\n distanceDurationAlert: \"event_marker\",\n calorieDurationAlert: \"event_marker\",\n activity: \"event_activity_start\",\n fitnessEquipment: \"event_marker\",\n length: \"event_lap\",\n userMarker: \"event_marker\",\n sportPoint: \"event_marker\",\n calibration: \"event_marker\",\n frontGearChange: \"event_marker\",\n rearGearChange: \"event_marker\",\n riderPositionChange: \"event_marker\",\n elevHighAlert: \"event_marker\",\n elevLowAlert: \"event_marker\",\n};\n\nexport const KRD_TYPE_TO_FIT_EVENT: Record<KRDEvent[\"eventType\"], FitEvent> = {\n event_start: \"timer\",\n event_stop: \"timer\",\n event_pause: \"timer\",\n event_resume: \"timer\",\n event_lap: \"lap\",\n event_marker: \"userMarker\",\n event_timer: \"timer\",\n event_workout_step_change: \"workoutStep\",\n event_session_start: \"session\",\n event_activity_start: \"activity\",\n};\n\nexport const KRD_TYPE_TO_FIT_EVENT_TYPE: Record<\n KRDEvent[\"eventType\"],\n FitEventType\n> = {\n event_start: \"start\",\n event_stop: \"stop\",\n event_pause: \"stopDisable\",\n event_resume: \"start\",\n event_lap: \"marker\",\n event_marker: \"marker\",\n event_timer: \"start\",\n event_workout_step_change: \"marker\",\n event_session_start: \"start\",\n event_activity_start: \"start\",\n};\n","import type { KRDEvent } from \"@kaiord/core\";\nimport type {\n FitEvent,\n FitEventMessage,\n FitEventType,\n} from \"../schemas/fit-event\";\nimport {\n FIT_EVENT_TO_KRD_TYPE,\n KRD_TYPE_TO_FIT_EVENT,\n KRD_TYPE_TO_FIT_EVENT_TYPE,\n} from \"./event-type-maps\";\n\nconst mapEventTypeToKrd = (\n fitEvent: FitEvent,\n fitEventType: FitEventType\n): KRDEvent[\"eventType\"] => {\n if (fitEvent === \"timer\") {\n switch (fitEventType) {\n case \"start\":\n return \"event_start\";\n case \"stop\":\n return \"event_stop\";\n case \"stopDisable\":\n case \"stopDisableAll\":\n return \"event_pause\";\n default:\n return \"event_timer\";\n }\n }\n return FIT_EVENT_TO_KRD_TYPE[fitEvent] ?? \"event_marker\";\n};\n\n/** Maps FIT EVENT to KRD event. */\nexport const mapFitEventToKrd = (fit: FitEventMessage): KRDEvent => ({\n timestamp: new Date(fit.timestamp * 1000).toISOString(),\n eventType: mapEventTypeToKrd(fit.event, fit.eventType),\n eventGroup: fit.eventGroup,\n data: fit.data,\n});\n\n/** Maps KRD event to FIT EVENT. */\nexport const mapKrdEventToFit = (krd: KRDEvent): Partial<FitEventMessage> => ({\n timestamp: Math.floor(new Date(krd.timestamp).getTime() / 1000),\n event: KRD_TYPE_TO_FIT_EVENT[krd.eventType] ?? \"userMarker\",\n eventType: KRD_TYPE_TO_FIT_EVENT_TYPE[krd.eventType] ?? \"marker\",\n eventGroup: krd.eventGroup,\n data: krd.data,\n});\n","import type { KRDEvent } from \"@kaiord/core\";\nimport {\n fitEventMessageSchema,\n type FitEventMessage,\n} from \"../schemas/fit-event\";\nimport { mapFitEventToKrd } from \"./event.mapper\";\n\n/**\n * Converts a FIT EVENT message to KRD event format.\n *\n * @param data - Raw FIT EVENT message data\n * @returns KRD event object\n * @throws Error if FIT data is invalid\n */\nexport const convertFitToKrdEvent = (\n data: Record<string, unknown>\n): KRDEvent => {\n const fitEvent = fitEventMessageSchema.parse(data) as FitEventMessage;\n return mapFitEventToKrd(fitEvent);\n};\n\n/**\n * Batch converts FIT EVENT messages to KRD events.\n *\n * @param events - Array of raw FIT EVENT message data\n * @returns Array of KRD event objects\n */\nexport const convertFitToKrdEvents = (\n events: Record<string, unknown>[]\n): KRDEvent[] => {\n return events.map(convertFitToKrdEvent);\n};\n","import type { Logger } from \"@kaiord/core\";\nimport { fitMessageKeySchema } from \"../schemas/fit-message-keys\";\nimport type { FitMessages } from \"../shared/types\";\n\nexport const extractFitExtensions = (\n messages: FitMessages,\n logger: Logger\n): Record<string, unknown> => {\n logger.debug(\"Extracting FIT extensions\");\n\n const unknownMessages = extractUnknownMessages(messages, logger);\n const developerFields = extractAllDeveloperFields(messages);\n\n return buildExtensions(unknownMessages, developerFields, logger);\n};\n\nconst extractUnknownMessages = (\n messages: FitMessages,\n logger: Logger\n): Record<string, Array<Record<string, unknown>>> => {\n const knownMessageKeys = new Set<string>([\n fitMessageKeySchema.enum.fileIdMesgs,\n fitMessageKeySchema.enum.workoutMesgs,\n fitMessageKeySchema.enum.workoutStepMesgs,\n ]);\n\n const unknownMessages: Record<string, Array<Record<string, unknown>>> = {};\n\n for (const [key, value] of Object.entries(messages)) {\n if (!knownMessageKeys.has(key) && value && Array.isArray(value)) {\n logger.debug(\"Found unknown message type\", { messageType: key });\n unknownMessages[key] = value;\n }\n }\n\n return unknownMessages;\n};\n\nconst extractAllDeveloperFields = (\n messages: FitMessages\n): Array<Record<string, unknown>> => {\n const developerFields: Array<Record<string, unknown>> = [];\n\n for (const value of Object.values(messages)) {\n if (value && Array.isArray(value)) {\n for (const message of value) {\n if (message && typeof message === \"object\") {\n const devFields = extractDeveloperFields(message);\n if (devFields.length > 0) {\n developerFields.push(...devFields);\n }\n }\n }\n }\n }\n\n return developerFields;\n};\n\nconst extractDeveloperFields = (\n message: Record<string, unknown>\n): Array<Record<string, unknown>> => {\n const devFields: Array<Record<string, unknown>> = [];\n\n for (const [key, value] of Object.entries(message)) {\n if (key.startsWith(\"developer_\") || key.includes(\"DeveloperField\")) {\n devFields.push({\n fieldName: key,\n value,\n });\n }\n }\n\n return devFields;\n};\n\nconst buildExtensions = (\n unknownMessages: Record<string, Array<Record<string, unknown>>>,\n developerFields: Array<Record<string, unknown>>,\n logger: Logger\n): Record<string, unknown> => {\n const extensions: Record<string, unknown> = {};\n\n if (developerFields.length > 0) {\n logger.info(\"Preserved developer fields\", {\n count: developerFields.length,\n });\n extensions.developerFields = developerFields;\n }\n\n if (Object.keys(unknownMessages).length > 0) {\n logger.info(\"Preserved unknown message types\", {\n types: Object.keys(unknownMessages),\n });\n extensions.unknownMessages = unknownMessages;\n }\n\n return extensions;\n};\n","import { z } from \"zod\";\n\n/**\n * FIT lap trigger types (what caused the lap to be recorded).\n */\nexport const fitLapTriggerSchema = z.enum([\n \"manual\",\n \"time\",\n \"distance\",\n \"positionStart\",\n \"positionLap\",\n \"positionWaypoint\",\n \"positionMarked\",\n \"sessionEnd\",\n \"fitnessEquipment\",\n]);\n\nexport type FitLapTrigger = z.infer<typeof fitLapTriggerSchema>;\n","import { z } from \"zod\";\n\nexport const fitSportSchema = z.enum([\n \"cycling\",\n \"running\",\n \"swimming\",\n \"generic\",\n]);\n\nexport type FitSport = z.infer<typeof fitSportSchema>;\n","import { z } from \"zod\";\nimport { fitLapTriggerSchema } from \"./fit-lap-trigger\";\nimport { fitSportSchema } from \"./fit-sport\";\nimport { fitSubSportSchema } from \"./fit-sub-sport\";\n\n/**\n * FIT LAP message schema (Message ID: 19).\n *\n * Contains per-lap/interval statistics for structured workouts.\n */\nexport const fitLapSchema = z.object({\n // Identifiers\n messageIndex: z.number().optional(),\n timestamp: z.number(),\n\n // Timing\n startTime: z.number(),\n totalElapsedTime: z.number(),\n totalTimerTime: z.number(),\n\n // Distance\n totalDistance: z.number().optional(),\n\n // Speed (enhanced values preferred when available)\n avgSpeed: z.number().optional(),\n maxSpeed: z.number().optional(),\n enhancedAvgSpeed: z.number().optional(),\n enhancedMaxSpeed: z.number().optional(),\n\n // Heart rate\n avgHeartRate: z.number().optional(),\n maxHeartRate: z.number().optional(),\n\n // Cadence\n avgCadence: z.number().optional(),\n maxCadence: z.number().optional(),\n\n // Power\n avgPower: z.number().optional(),\n maxPower: z.number().optional(),\n normalizedPower: z.number().optional(),\n\n // Elevation\n totalAscent: z.number().optional(),\n totalDescent: z.number().optional(),\n\n // Calories\n totalCalories: z.number().optional(),\n\n // Classification\n lapTrigger: fitLapTriggerSchema.optional(),\n sport: fitSportSchema.optional(),\n subSport: fitSubSportSchema.optional(),\n\n // Swimming\n numLengths: z.number().optional(),\n swimStroke: z.number().optional(),\n\n // Workout reference\n wktStepIndex: z.number().optional(),\n});\n\nexport type FitLap = z.infer<typeof fitLapSchema>;\n","import type { KRDLapTrigger } from \"@kaiord/core\";\nimport type { FitLapTrigger } from \"../schemas/fit-lap-trigger\";\n\n/**\n * Maps FIT lap trigger to KRD lap trigger.\n * Position-based triggers are consolidated into \"position\".\n */\nexport const mapFitLapTriggerToKrd = (fit: FitLapTrigger): KRDLapTrigger => {\n switch (fit) {\n case \"manual\":\n return \"manual\";\n case \"time\":\n return \"time\";\n case \"distance\":\n return \"distance\";\n case \"positionStart\":\n case \"positionLap\":\n case \"positionWaypoint\":\n case \"positionMarked\":\n return \"position\";\n case \"sessionEnd\":\n return \"session_end\";\n case \"fitnessEquipment\":\n return \"fitness_equipment\";\n }\n};\n\n/**\n * Maps KRD lap trigger to FIT lap trigger.\n * Position defaults to positionLap.\n */\nexport const mapKrdLapTriggerToFit = (krd: KRDLapTrigger): FitLapTrigger => {\n switch (krd) {\n case \"manual\":\n return \"manual\";\n case \"time\":\n return \"time\";\n case \"distance\":\n return \"distance\";\n case \"position\":\n return \"positionLap\";\n case \"session_end\":\n return \"sessionEnd\";\n case \"fitness_equipment\":\n return \"fitnessEquipment\";\n }\n};\n","import type { KRDLap } from \"@kaiord/core\";\nimport { FIT_TO_SWIM_STROKE, SWIM_STROKE_TO_FIT } from \"@kaiord/core\";\nimport type { FitLap } from \"../schemas/fit-lap\";\nimport { mapSubSportToFit, mapSubSportToKrd } from \"../sub-sport/sub-sport\";\nimport {\n mapFitLapTriggerToKrd,\n mapKrdLapTriggerToFit,\n} from \"./lap-trigger.mapper\";\n\n/**\n * Maps FIT LAP fields to KRD lap fields.\n * Thin translation layer - no complex logic.\n */\nexport const mapFitLapToKrd = (fit: FitLap): KRDLap => ({\n // Timing - convert ms to seconds\n startTime: new Date(fit.startTime * 1000).toISOString(),\n totalElapsedTime: fit.totalElapsedTime / 1000,\n totalTimerTime: fit.totalTimerTime / 1000,\n\n // Distance\n totalDistance: fit.totalDistance,\n\n // Heart rate\n avgHeartRate: fit.avgHeartRate,\n maxHeartRate: fit.maxHeartRate,\n\n // Cadence\n avgCadence: fit.avgCadence,\n maxCadence: fit.maxCadence,\n\n // Power\n avgPower: fit.avgPower,\n maxPower: fit.maxPower,\n normalizedPower: fit.normalizedPower,\n\n // Speed - prefer enhanced values\n avgSpeed: fit.enhancedAvgSpeed ?? fit.avgSpeed,\n maxSpeed: fit.enhancedMaxSpeed ?? fit.maxSpeed,\n\n // Elevation\n totalAscent: fit.totalAscent,\n totalDescent: fit.totalDescent,\n\n // Calories\n totalCalories: fit.totalCalories,\n\n // Classification\n trigger: fit.lapTrigger ? mapFitLapTriggerToKrd(fit.lapTrigger) : undefined,\n sport: fit.sport,\n subSport: fit.subSport ? mapSubSportToKrd(fit.subSport) : undefined,\n\n // Workout reference\n workoutStepIndex: fit.wktStepIndex,\n\n // Swimming\n numLengths: fit.numLengths,\n swimStroke:\n fit.swimStroke !== undefined\n ? FIT_TO_SWIM_STROKE[fit.swimStroke]\n : undefined,\n});\n\n/**\n * Maps KRD lap fields to FIT LAP fields.\n * Thin translation layer - no complex logic.\n */\nexport const mapKrdLapToFit = (krd: KRDLap): Partial<FitLap> => {\n const startTimeSeconds = Math.floor(new Date(krd.startTime).getTime() / 1000);\n const elapsedTimeMs = krd.totalElapsedTime * 1000;\n // Preserve zero totalTimerTime, default to elapsed time if undefined\n const timerTimeMs =\n krd.totalTimerTime !== undefined\n ? krd.totalTimerTime * 1000\n : elapsedTimeMs;\n\n return {\n // Timing\n timestamp: startTimeSeconds + Math.floor(krd.totalElapsedTime),\n startTime: startTimeSeconds,\n totalElapsedTime: elapsedTimeMs,\n totalTimerTime: timerTimeMs,\n\n // Distance\n totalDistance: krd.totalDistance,\n\n // Heart rate\n avgHeartRate: krd.avgHeartRate,\n maxHeartRate: krd.maxHeartRate,\n\n // Cadence\n avgCadence: krd.avgCadence,\n maxCadence: krd.maxCadence,\n\n // Power\n avgPower: krd.avgPower,\n maxPower: krd.maxPower,\n normalizedPower: krd.normalizedPower,\n\n // Speed\n avgSpeed: krd.avgSpeed,\n maxSpeed: krd.maxSpeed,\n\n // Elevation\n totalAscent: krd.totalAscent,\n totalDescent: krd.totalDescent,\n\n // Calories\n totalCalories: krd.totalCalories,\n\n // Classification\n lapTrigger: krd.trigger ? mapKrdLapTriggerToFit(krd.trigger) : undefined,\n sport: krd.sport,\n subSport: krd.subSport ? mapSubSportToFit(krd.subSport) : undefined,\n\n // Workout reference\n wktStepIndex: krd.workoutStepIndex,\n\n // Swimming\n numLengths: krd.numLengths,\n swimStroke:\n krd.swimStroke !== undefined\n ? SWIM_STROKE_TO_FIT[krd.swimStroke]\n : undefined,\n };\n};\n","import type { KRDLap } from \"@kaiord/core\";\nimport type { FitLap } from \"../schemas/fit-lap\";\nimport { fitLapSchema } from \"../schemas/fit-lap\";\nimport { mapFitLapToKrd } from \"./lap.mapper\";\n\n/**\n * Converts a FIT LAP message to KRD lap format.\n *\n * @param data - Raw FIT LAP message data\n * @returns KRD lap object\n * @throws Error if FIT data is invalid\n */\nexport const convertFitToKrdLap = (data: Record<string, unknown>): KRDLap => {\n const fitLap = fitLapSchema.parse(data) as FitLap;\n return mapFitLapToKrd(fitLap);\n};\n\n/**\n * Batch converts FIT LAP messages to KRD laps.\n *\n * @param laps - Array of raw FIT LAP message data\n * @returns Array of KRD lap objects\n */\nexport const convertFitToKrdLaps = (\n laps: Record<string, unknown>[]\n): KRDLap[] => {\n return laps.map(convertFitToKrdLap);\n};\n","import { z } from \"zod\";\n\n/**\n * FIT RECORD message schema (Message ID: 20).\n *\n * Contains time-series data points (typically 1 per second).\n * Coordinates are in semicircles (signed 32-bit integer).\n */\nexport const fitRecordSchema = z.object({\n timestamp: z.number(),\n positionLat: z.number().optional(),\n positionLong: z.number().optional(),\n altitude: z.number().optional(),\n enhancedAltitude: z.number().optional(),\n speed: z.number().optional(),\n enhancedSpeed: z.number().optional(),\n distance: z.number().optional(),\n heartRate: z.number().optional(),\n cadence: z.number().optional(),\n fractionalCadence: z.number().optional(),\n power: z.number().optional(),\n temperature: z.number().optional(),\n verticalOscillation: z.number().optional(),\n stanceTime: z.number().optional(),\n stanceTimePercent: z.number().optional(),\n stepLength: z.number().optional(),\n compressedTimestamp: z.number().optional(),\n});\n\nexport type FitRecord = z.infer<typeof fitRecordSchema>;\n","import type { KRDRecord } from \"@kaiord/core\";\nimport type { FitRecord } from \"../schemas/fit-record\";\nimport {\n degreesToSemicircles,\n semicirclesToDegrees,\n} from \"../shared/coordinate.converter\";\n\n/**\n * Maps FIT RECORD fields to KRD record fields.\n * Thin translation layer - no complex logic.\n */\nexport const mapFitRecordToKrd = (fit: FitRecord): KRDRecord => {\n const record: KRDRecord = {\n timestamp: new Date(fit.timestamp * 1000).toISOString(),\n };\n\n // Position - convert semicircles to degrees\n if (fit.positionLat !== undefined && fit.positionLong !== undefined) {\n record.position = {\n lat: semicirclesToDegrees(fit.positionLat),\n lon: semicirclesToDegrees(fit.positionLong),\n };\n }\n\n // Altitude - prefer enhanced\n if (fit.enhancedAltitude !== undefined) {\n record.altitude = fit.enhancedAltitude;\n } else if (fit.altitude !== undefined) {\n record.altitude = fit.altitude;\n }\n\n // Speed - prefer enhanced\n if (fit.enhancedSpeed !== undefined) {\n record.speed = fit.enhancedSpeed;\n } else if (fit.speed !== undefined) {\n record.speed = fit.speed;\n }\n\n // Direct mappings\n if (fit.distance !== undefined) record.distance = fit.distance;\n if (fit.heartRate !== undefined) record.heartRate = fit.heartRate;\n if (fit.power !== undefined) record.power = fit.power;\n if (fit.temperature !== undefined) record.temperature = fit.temperature;\n\n // Cadence - combine fractional\n if (fit.cadence !== undefined) {\n record.cadence = fit.cadence + (fit.fractionalCadence ?? 0);\n }\n\n // Running dynamics\n if (fit.verticalOscillation !== undefined) {\n record.verticalOscillation = fit.verticalOscillation;\n }\n if (fit.stanceTime !== undefined) record.stanceTime = fit.stanceTime;\n if (fit.stepLength !== undefined) record.stepLength = fit.stepLength;\n\n return record;\n};\n\n/**\n * Maps KRD record fields to FIT RECORD fields.\n * Thin translation layer - no complex logic.\n */\nexport const mapKrdRecordToFit = (krd: KRDRecord): Partial<FitRecord> => {\n const fit: Partial<FitRecord> = {\n timestamp: Math.floor(new Date(krd.timestamp).getTime() / 1000),\n };\n\n // Position - convert degrees to semicircles\n if (krd.position) {\n fit.positionLat = degreesToSemicircles(krd.position.lat);\n fit.positionLong = degreesToSemicircles(krd.position.lon);\n }\n\n // Direct mappings\n if (krd.altitude !== undefined) fit.altitude = krd.altitude;\n if (krd.speed !== undefined) fit.speed = krd.speed;\n if (krd.distance !== undefined) fit.distance = krd.distance;\n if (krd.heartRate !== undefined) fit.heartRate = krd.heartRate;\n if (krd.cadence !== undefined) {\n fit.cadence = Math.floor(krd.cadence);\n const fractional = krd.cadence - Math.floor(krd.cadence);\n if (fractional > 0) {\n fit.fractionalCadence = fractional;\n }\n }\n if (krd.power !== undefined) fit.power = krd.power;\n if (krd.temperature !== undefined) fit.temperature = krd.temperature;\n\n // Running dynamics\n if (krd.verticalOscillation !== undefined) {\n fit.verticalOscillation = krd.verticalOscillation;\n }\n if (krd.stanceTime !== undefined) fit.stanceTime = krd.stanceTime;\n if (krd.stepLength !== undefined) fit.stepLength = krd.stepLength;\n\n return fit;\n};\n","import type { KRDRecord } from \"@kaiord/core\";\nimport { fitRecordSchema, type FitRecord } from \"../schemas/fit-record\";\nimport { validateCoordinates } from \"../shared/coordinate.converter\";\nimport { mapFitRecordToKrd } from \"./record.mapper\";\n\n/**\n * Converts a FIT RECORD message to KRD record format.\n *\n * @param data - Raw FIT RECORD message data\n * @returns KRD record object\n * @throws Error if FIT data is invalid or coordinates out of range\n */\nexport const convertFitToKrdRecord = (\n data: Record<string, unknown>\n): KRDRecord => {\n const fitRecord = fitRecordSchema.parse(data) as FitRecord;\n\n // Validate coordinates if present - both must be present or neither\n const hasLat = fitRecord.positionLat !== undefined;\n const hasLon = fitRecord.positionLong !== undefined;\n\n if (hasLat !== hasLon) {\n throw new Error(\"Partial coordinates: both lat and lon must be present\");\n }\n\n if (hasLat && hasLon) {\n if (!validateCoordinates(fitRecord.positionLat!, fitRecord.positionLong!)) {\n throw new Error(\"Invalid coordinates: out of range\");\n }\n }\n\n return mapFitRecordToKrd(fitRecord);\n};\n\n/**\n * Batch converts FIT RECORD messages to KRD records.\n * Optimized for processing large numbers of records.\n *\n * @param records - Array of raw FIT RECORD message data\n * @returns Array of KRD record objects\n */\nexport const convertFitToKrdRecords = (\n records: Record<string, unknown>[]\n): KRDRecord[] => {\n return records.map(convertFitToKrdRecord);\n};\n","import { z } from \"zod\";\nimport { fitSportSchema } from \"./fit-sport\";\nimport { fitSubSportSchema } from \"./fit-sub-sport\";\n\n/**\n * FIT SESSION message schema (Message ID: 18).\n *\n * Contains aggregate statistics for the entire workout/activity.\n */\nexport const fitSessionSchema = z.object({\n timestamp: z.number(),\n startTime: z.number(),\n totalElapsedTime: z.number(),\n totalTimerTime: z.number(),\n totalDistance: z.number().optional(),\n totalCalories: z.number().optional(),\n avgSpeed: z.number().optional(),\n maxSpeed: z.number().optional(),\n enhancedAvgSpeed: z.number().optional(),\n enhancedMaxSpeed: z.number().optional(),\n avgHeartRate: z.number().optional(),\n maxHeartRate: z.number().optional(),\n avgCadence: z.number().optional(),\n maxCadence: z.number().optional(),\n avgPower: z.number().optional(),\n maxPower: z.number().optional(),\n normalizedPower: z.number().optional(),\n trainingStressScore: z.number().optional(),\n intensityFactor: z.number().optional(),\n totalAscent: z.number().optional(),\n totalDescent: z.number().optional(),\n sport: fitSportSchema,\n subSport: fitSubSportSchema.optional(),\n numLaps: z.number().optional(),\n firstLapIndex: z.number().optional(),\n});\n\nexport type FitSession = z.infer<typeof fitSessionSchema>;\n","import type { KRDSession } from \"@kaiord/core\";\nimport type { FitSession } from \"../schemas/fit-session\";\nimport { mapSubSportToFit, mapSubSportToKrd } from \"../sub-sport/sub-sport\";\n\n/**\n * Maps FIT SESSION fields to KRD session fields.\n * Thin translation layer - no complex logic.\n */\nexport const mapFitSessionToKrd = (fit: FitSession): KRDSession => ({\n startTime: new Date(fit.startTime * 1000).toISOString(),\n totalElapsedTime: fit.totalElapsedTime / 1000,\n totalTimerTime:\n fit.totalTimerTime !== undefined ? fit.totalTimerTime / 1000 : undefined,\n totalDistance: fit.totalDistance,\n sport: String(fit.sport),\n subSport: fit.subSport ? mapSubSportToKrd(fit.subSport) : undefined,\n avgHeartRate: fit.avgHeartRate,\n maxHeartRate: fit.maxHeartRate,\n avgCadence: fit.avgCadence,\n maxCadence: fit.maxCadence,\n avgPower: fit.avgPower,\n maxPower: fit.maxPower,\n normalizedPower: fit.normalizedPower,\n trainingStressScore: fit.trainingStressScore,\n intensityFactor: fit.intensityFactor,\n totalCalories: fit.totalCalories,\n totalAscent: fit.totalAscent,\n totalDescent: fit.totalDescent,\n avgSpeed: fit.enhancedAvgSpeed ?? fit.avgSpeed,\n maxSpeed: fit.enhancedMaxSpeed ?? fit.maxSpeed,\n});\n\n/**\n * Maps KRD session fields to FIT SESSION fields.\n * Thin translation layer - no complex logic.\n */\nexport const mapKrdSessionToFit = (krd: KRDSession): Partial<FitSession> => {\n const startTimeSeconds = Math.floor(new Date(krd.startTime).getTime() / 1000);\n const elapsedTimeMs = krd.totalElapsedTime * 1000;\n // Preserve zero totalTimerTime, default to elapsed time if undefined\n const timerTimeMs =\n krd.totalTimerTime !== undefined\n ? krd.totalTimerTime * 1000\n : elapsedTimeMs;\n\n return {\n timestamp: startTimeSeconds + Math.floor(krd.totalElapsedTime),\n startTime: startTimeSeconds,\n totalElapsedTime: elapsedTimeMs,\n totalTimerTime: timerTimeMs,\n totalDistance: krd.totalDistance,\n sport: krd.sport as FitSession[\"sport\"],\n subSport: krd.subSport ? mapSubSportToFit(krd.subSport) : undefined,\n avgHeartRate: krd.avgHeartRate,\n maxHeartRate: krd.maxHeartRate,\n avgCadence: krd.avgCadence,\n maxCadence: krd.maxCadence,\n avgPower: krd.avgPower,\n maxPower: krd.maxPower,\n normalizedPower: krd.normalizedPower,\n trainingStressScore: krd.trainingStressScore,\n intensityFactor: krd.intensityFactor,\n totalCalories: krd.totalCalories,\n totalAscent: krd.totalAscent,\n totalDescent: krd.totalDescent,\n avgSpeed: krd.avgSpeed,\n maxSpeed: krd.maxSpeed,\n };\n};\n","import type { KRDSession } from \"@kaiord/core\";\nimport { fitSessionSchema, type FitSession } from \"../schemas/fit-session\";\nimport { mapFitSessionToKrd } from \"./session.mapper\";\n\n/**\n * Converts a FIT SESSION message to KRD session format.\n *\n * @param data - Raw FIT SESSION message data\n * @returns KRD session object\n * @throws Error if FIT data is invalid\n */\nexport const convertFitToKrdSession = (\n data: Record<string, unknown>\n): KRDSession => {\n const fitSession = fitSessionSchema.parse(data) as FitSession;\n return mapFitSessionToKrd(fitSession);\n};\n","import { fileTypeSchema } from \"@kaiord/core\";\nimport type { KRD } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertFitToKrdEvents } from \"../event\";\nimport { extractFitExtensions } from \"../extensions/extensions.extractor\";\nimport { convertFitToKrdLaps } from \"../lap\";\nimport { convertFitToKrdRecords } from \"../record\";\nimport { fitMessageKeySchema } from \"../schemas/fit-message-keys\";\nimport { convertFitToKrdSession } from \"../session\";\nimport type { FitMessages } from \"../shared/types\";\n\nconst KRD_VERSION = \"1.0\" as const;\n\n/**\n * Converts FIT timeCreated to ISO string, handling Date objects and numbers\n */\nconst convertTimeCreated = (timeCreated: unknown): string => {\n if (timeCreated instanceof Date) return timeCreated.toISOString();\n if (typeof timeCreated === \"number\")\n return new Date(timeCreated * 1000).toISOString();\n return new Date().toISOString();\n};\n\n/**\n * Maps activity file to KRD format.\n */\nexport const mapActivityFileToKRD = (\n messages: FitMessages,\n logger: Logger\n): KRD => {\n const fileId = messages[fitMessageKeySchema.enum.fileIdMesgs]?.[0];\n const sessionMsgs = messages[fitMessageKeySchema.enum.sessionMesgs] || [];\n const recordMsgs = messages[fitMessageKeySchema.enum.recordMesgs] || [];\n const eventMsgs = messages[fitMessageKeySchema.enum.eventMesgs] || [];\n const lapMsgs = messages[fitMessageKeySchema.enum.lapMesgs] || [];\n\n logger.debug(\"Mapping activity file\", {\n sessions: sessionMsgs.length,\n records: recordMsgs.length,\n events: eventMsgs.length,\n laps: lapMsgs.length,\n });\n\n const session =\n sessionMsgs.length > 0 ? convertFitToKrdSession(sessionMsgs[0]) : undefined;\n const records = convertFitToKrdRecords(recordMsgs);\n const events = convertFitToKrdEvents(eventMsgs);\n const laps = convertFitToKrdLaps(lapMsgs);\n const fitExtensions = extractFitExtensions(messages, logger);\n\n const created = convertTimeCreated(fileId?.timeCreated);\n\n return {\n version: KRD_VERSION,\n type: fileTypeSchema.enum.recorded_activity,\n metadata: {\n created,\n sport: session?.sport ?? \"other\",\n subSport: session?.subSport,\n },\n sessions: session ? [session] : undefined,\n laps: laps.length > 0 ? laps : undefined,\n records: records.length > 0 ? records : undefined,\n events: events.length > 0 ? events : undefined,\n extensions: {\n fit: fitExtensions,\n },\n };\n};\n","import type { KRDMetadata } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { mapSportType } from \"../shared/type-guards\";\nimport type { FitFileId, FitWorkoutMessage } from \"../shared/types\";\nexport const mapMetadata = (\n fileId: FitFileId | undefined,\n workoutMsg: FitWorkoutMessage | undefined,\n logger: Logger\n): KRDMetadata => {\n logger.debug(\"Mapping metadata from FIT messages\");\n\n const sport = mapSportType(workoutMsg?.sport);\n const created = mapCreatedTimestamp(fileId);\n\n return {\n created,\n manufacturer: fileId?.manufacturer,\n product: fileId?.garminProduct || fileId?.product?.toString(),\n serialNumber: fileId?.serialNumber?.toString(),\n sport,\n };\n};\n\nconst mapCreatedTimestamp = (fileId: FitFileId | undefined): string => {\n if (!fileId?.timeCreated) {\n return new Date().toISOString();\n }\n\n if (typeof fileId.timeCreated === \"string\") {\n return fileId.timeCreated;\n }\n\n if (fileId.timeCreated instanceof Date) {\n return fileId.timeCreated.toISOString();\n }\n\n return new Date().toISOString();\n};\n","import { lengthUnitSchema, type LengthUnit } from \"@kaiord/core\";\n\nconst FIT_LENGTH_UNIT_MAP: Record<number, LengthUnit> = {\n 0: \"meters\",\n 1: \"yards\",\n};\n\nexport const mapLengthUnitToKrd = (fitUnit: number | undefined): LengthUnit => {\n if (fitUnit === undefined) {\n return lengthUnitSchema.enum.meters;\n }\n\n return FIT_LENGTH_UNIT_MAP[fitUnit] || lengthUnitSchema.enum.meters;\n};\n\nexport const mapLengthUnitToFit = (krdUnit: LengthUnit): number => {\n if (krdUnit === lengthUnitSchema.enum.yards) {\n return 1;\n }\n\n return 0;\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\nimport type { FitDurationData } from \"./duration.converter\";\n\nexport const convertTimeDuration = (data: FitDurationData): Duration | null => {\n if (data.durationTime !== undefined) {\n return {\n type: durationTypeSchema.enum.time,\n seconds: data.durationTime,\n };\n }\n return null;\n};\n\nexport const convertDistanceDuration = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationDistance !== undefined) {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data.durationDistance,\n };\n }\n return null;\n};\n\nexport const convertHeartRateLessThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationHr !== undefined) {\n return {\n type: durationTypeSchema.enum.heart_rate_less_than,\n bpm: data.durationHr,\n };\n }\n return null;\n};\n\nexport const convertHeartRateGreaterThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.repeatHr !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_heart_rate_greater_than,\n bpm: data.repeatHr,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n\nexport const convertCaloriesDuration = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationCalories !== undefined) {\n return {\n type: durationTypeSchema.enum.calories,\n calories: data.durationCalories,\n };\n }\n return null;\n};\n\nexport const convertPowerLessThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationPower !== undefined) {\n return {\n type: durationTypeSchema.enum.power_less_than,\n watts: data.durationPower,\n };\n }\n return null;\n};\n\nexport const convertPowerGreaterThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationPower !== undefined) {\n return {\n type: durationTypeSchema.enum.power_greater_than,\n watts: data.durationPower,\n };\n }\n return null;\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\nimport type { FitDurationData } from \"./duration.converter\";\n\nexport const convertRepeatUntilTime = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationTime !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_time,\n seconds: data.durationTime,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n\nexport const convertRepeatUntilDistance = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationDistance !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_distance,\n meters: data.durationDistance,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n\nexport const convertRepeatUntilCalories = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationCalories !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_calories,\n calories: data.durationCalories,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n\nexport const convertRepeatUntilHrLessThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationHr !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_heart_rate_less_than,\n bpm: data.durationHr,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n\nexport const convertRepeatUntilPowerLessThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationPower !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_power_less_than,\n watts: data.durationPower,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n\nexport const convertRepeatUntilPowerGreaterThan = (\n data: FitDurationData\n): Duration | null => {\n if (data.durationPower !== undefined && data.durationStep !== undefined) {\n return {\n type: durationTypeSchema.enum.repeat_until_power_greater_than,\n watts: data.durationPower,\n repeatFrom: data.durationStep,\n };\n }\n return null;\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../schemas/fit-duration\";\nimport {\n convertCaloriesDuration,\n convertDistanceDuration,\n convertHeartRateGreaterThan,\n convertHeartRateLessThan,\n convertPowerGreaterThan,\n convertPowerLessThan,\n convertTimeDuration,\n} from \"./duration-converters\";\nimport {\n convertRepeatUntilCalories,\n convertRepeatUntilDistance,\n convertRepeatUntilHrLessThan,\n convertRepeatUntilPowerGreaterThan,\n convertRepeatUntilPowerLessThan,\n convertRepeatUntilTime,\n} from \"./repeat-duration-converters\";\n\nexport type FitDurationData = {\n durationType?: string;\n durationTime?: number;\n durationDistance?: number;\n durationHr?: number;\n durationStep?: number;\n repeatHr?: number;\n durationCalories?: number;\n durationPower?: number;\n};\n\nconst DURATION_CONVERTERS: Record<\n string,\n (data: FitDurationData) => Duration | null\n> = {\n [fitDurationTypeSchema.enum.time]: convertTimeDuration,\n [fitDurationTypeSchema.enum.distance]: convertDistanceDuration,\n [fitDurationTypeSchema.enum.hrLessThan]: convertHeartRateLessThan,\n [fitDurationTypeSchema.enum.repeatUntilHrGreaterThan]:\n convertHeartRateGreaterThan,\n [fitDurationTypeSchema.enum.calories]: convertCaloriesDuration,\n [fitDurationTypeSchema.enum.powerLessThan]: convertPowerLessThan,\n [fitDurationTypeSchema.enum.powerGreaterThan]: convertPowerGreaterThan,\n [fitDurationTypeSchema.enum.repeatUntilTime]: convertRepeatUntilTime,\n [fitDurationTypeSchema.enum.repeatUntilDistance]: convertRepeatUntilDistance,\n [fitDurationTypeSchema.enum.repeatUntilCalories]: convertRepeatUntilCalories,\n [fitDurationTypeSchema.enum.repeatUntilHrLessThan]:\n convertRepeatUntilHrLessThan,\n [fitDurationTypeSchema.enum.repeatUntilPowerLessThan]:\n convertRepeatUntilPowerLessThan,\n [fitDurationTypeSchema.enum.repeatUntilPowerGreaterThan]:\n convertRepeatUntilPowerGreaterThan,\n};\n\nexport const convertFitDuration = (data: FitDurationData): Duration => {\n const result = fitDurationTypeSchema.safeParse(data.durationType);\n\n if (!result.success) {\n return { type: durationTypeSchema.enum.open };\n }\n\n const converter = DURATION_CONVERTERS[result.data];\n if (converter) {\n return converter(data) || { type: durationTypeSchema.enum.open };\n }\n\n return { type: durationTypeSchema.enum.open };\n};\n","import {\n durationTypeSchema,\n type Duration,\n type DurationType,\n} from \"@kaiord/core\";\nimport { convertFitDuration } from \"../duration/duration.converter\";\nimport { fitDurationTypeSchema } from \"../schemas/fit-duration\";\nimport type { FitWorkoutStep } from \"../shared/types\";\n\nexport const mapDuration = (step: FitWorkoutStep): Duration => {\n return convertFitDuration(step);\n};\n\nexport const mapDurationType = (\n fitDurationType: string | undefined\n): DurationType => {\n if (fitDurationType === fitDurationTypeSchema.enum.time)\n return durationTypeSchema.enum.time;\n if (fitDurationType === fitDurationTypeSchema.enum.distance)\n return durationTypeSchema.enum.distance;\n if (fitDurationType === fitDurationTypeSchema.enum.hrLessThan)\n return durationTypeSchema.enum.heart_rate_less_than;\n if (fitDurationType === fitDurationTypeSchema.enum.repeatUntilHrGreaterThan)\n return durationTypeSchema.enum.repeat_until_heart_rate_greater_than;\n if (fitDurationType === fitDurationTypeSchema.enum.calories)\n return durationTypeSchema.enum.calories;\n if (fitDurationType === fitDurationTypeSchema.enum.powerLessThan)\n return durationTypeSchema.enum.power_less_than;\n if (fitDurationType === fitDurationTypeSchema.enum.powerGreaterThan)\n return durationTypeSchema.enum.power_greater_than;\n if (fitDurationType === fitDurationTypeSchema.enum.repeatUntilTime)\n return durationTypeSchema.enum.repeat_until_time;\n if (fitDurationType === fitDurationTypeSchema.enum.repeatUntilDistance)\n return durationTypeSchema.enum.repeat_until_distance;\n if (fitDurationType === fitDurationTypeSchema.enum.repeatUntilCalories)\n return durationTypeSchema.enum.repeat_until_calories;\n if (fitDurationType === fitDurationTypeSchema.enum.repeatUntilHrLessThan)\n return durationTypeSchema.enum.repeat_until_heart_rate_less_than;\n if (fitDurationType === fitDurationTypeSchema.enum.repeatUntilPowerLessThan)\n return durationTypeSchema.enum.repeat_until_power_less_than;\n if (\n fitDurationType === fitDurationTypeSchema.enum.repeatUntilPowerGreaterThan\n )\n return durationTypeSchema.enum.repeat_until_power_greater_than;\n return durationTypeSchema.enum.open;\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { FitTargetData } from \"./target.types\";\n\nexport const convertCadenceTarget = (data: FitTargetData): Target => {\n const rangeTarget = buildCadenceRangeTarget(data);\n if (rangeTarget) return rangeTarget;\n\n const zoneTarget = buildCadenceZoneTarget(data);\n if (zoneTarget) return zoneTarget;\n\n const valueTarget = buildCadenceValueTarget(data);\n if (valueTarget) return valueTarget;\n\n return { type: targetTypeSchema.enum.open };\n};\n\nconst buildCadenceRangeTarget = (data: FitTargetData): Target | null => {\n if (\n data.customTargetCadenceLow !== undefined &&\n data.customTargetCadenceHigh !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.cadence,\n value: {\n unit: targetUnitSchema.enum.range,\n min: data.customTargetCadenceLow,\n max: data.customTargetCadenceHigh,\n },\n };\n }\n\n if (\n data.customTargetValueLow !== undefined &&\n data.customTargetValueHigh !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.cadence,\n value: {\n unit: targetUnitSchema.enum.range,\n min: data.customTargetValueLow,\n max: data.customTargetValueHigh,\n },\n };\n }\n\n return null;\n};\n\nconst buildCadenceZoneTarget = (data: FitTargetData): Target | null => {\n if (data.targetCadenceZone !== undefined) {\n return {\n type: targetTypeSchema.enum.cadence,\n value: {\n unit: targetUnitSchema.enum.rpm,\n value: data.targetCadenceZone,\n },\n };\n }\n return null;\n};\n\nconst buildCadenceValueTarget = (data: FitTargetData): Target | null => {\n if (data.targetValue !== undefined) {\n return {\n type: targetTypeSchema.enum.cadence,\n value: {\n unit: targetUnitSchema.enum.rpm,\n value: data.targetValue,\n },\n };\n }\n return null;\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { FitTargetData } from \"./target.types\";\n\nexport const convertHeartRateTarget = (data: FitTargetData): Target => {\n const rangeTarget = buildHeartRateRangeTarget(data);\n if (rangeTarget) return rangeTarget;\n\n const zoneTarget = buildHeartRateZoneTarget(data);\n if (zoneTarget) return zoneTarget;\n\n if (data.targetValue !== undefined) {\n return convertHeartRateValue(data.targetValue);\n }\n\n return { type: targetTypeSchema.enum.open };\n};\n\nconst buildHeartRateRangeTarget = (data: FitTargetData): Target | null => {\n if (\n data.customTargetHeartRateLow !== undefined &&\n data.customTargetHeartRateHigh !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: targetUnitSchema.enum.range,\n min: data.customTargetHeartRateLow,\n max: data.customTargetHeartRateHigh,\n },\n };\n }\n\n if (\n data.customTargetValueLow !== undefined &&\n data.customTargetValueHigh !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: targetUnitSchema.enum.range,\n min: data.customTargetValueLow,\n max: data.customTargetValueHigh,\n },\n };\n }\n\n return null;\n};\n\nconst buildHeartRateZoneTarget = (data: FitTargetData): Target | null => {\n if (data.targetHrZone !== undefined) {\n // Validate zone is in valid range (1-5)\n // If not, treat as BPM value instead\n if (data.targetHrZone >= 1 && data.targetHrZone <= 5) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: targetUnitSchema.enum.zone,\n value: data.targetHrZone,\n },\n };\n }\n // Invalid zone value, treat as BPM\n return convertHeartRateValue(data.targetHrZone);\n }\n return null;\n};\n\nconst convertHeartRateValue = (value: number): Target => {\n // Garmin FIT encoding:\n // - Values > 100: Absolute bpm (offset by 100)\n // - Values 0-100: Percentage of max HR\n if (value > 100) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: targetUnitSchema.enum.bpm,\n value: value - 100,\n },\n };\n }\n\n if (value > 0) {\n return {\n type: targetTypeSchema.enum.heart_rate,\n value: {\n unit: targetUnitSchema.enum.percent_max,\n value,\n },\n };\n }\n\n return { type: targetTypeSchema.enum.open };\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { FitTargetData } from \"./target.types\";\n\nexport const convertPaceTarget = (data: FitTargetData): Target => {\n const rangeTarget = buildPaceRangeTarget(data);\n if (rangeTarget) return rangeTarget;\n\n const zoneTarget = buildPaceZoneTarget(data);\n if (zoneTarget) return zoneTarget;\n\n const valueTarget = buildPaceValueTarget(data);\n if (valueTarget) return valueTarget;\n\n return { type: targetTypeSchema.enum.open };\n};\n\nconst buildPaceRangeTarget = (data: FitTargetData): Target | null => {\n if (\n data.customTargetSpeedLow !== undefined &&\n data.customTargetSpeedHigh !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.pace,\n value: {\n unit: targetUnitSchema.enum.range,\n min: data.customTargetSpeedLow,\n max: data.customTargetSpeedHigh,\n },\n };\n }\n\n if (\n data.customTargetValueLow !== undefined &&\n data.customTargetValueHigh !== undefined\n ) {\n return {\n type: targetTypeSchema.enum.pace,\n value: {\n unit: targetUnitSchema.enum.range,\n min: data.customTargetValueLow,\n max: data.customTargetValueHigh,\n },\n };\n }\n\n return null;\n};\n\nconst buildPaceZoneTarget = (data: FitTargetData): Target | null => {\n if (data.targetSpeedZone !== undefined) {\n return {\n type: targetTypeSchema.enum.pace,\n value: {\n unit: targetUnitSchema.enum.zone,\n value: data.targetSpeedZone,\n },\n };\n }\n return null;\n};\n\nconst buildPaceValueTarget = (data: FitTargetData): Target | null => {\n if (data.targetValue !== undefined) {\n return {\n type: targetTypeSchema.enum.pace,\n value: {\n unit: targetUnitSchema.enum.mps,\n value: data.targetValue,\n },\n };\n }\n return null;\n};\n","/**\n * Interprets a workoutPower value from FIT SDK\n * - Values 0-999: Percentage of FTP (direct)\n * - Values >= 1000: Absolute watts (value - 1000)\n */\nexport const interpretWorkoutPower = (\n value: number\n): { type: \"watts\" | \"percentage\"; value: number } => {\n if (value >= 1000) {\n return {\n type: \"watts\",\n value: value - 1000,\n };\n }\n return {\n type: \"percentage\",\n value,\n };\n};\n\n/**\n * Convert a single power value to KRD target\n * Garmin FIT encoding:\n * - Values > 1000: Absolute watts (offset by 1000)\n * - Values 0-1000: Percentage of FTP\n */\nexport const convertPowerValue = (value: number) => {\n if (value > 1000) {\n return {\n unit: \"watts\" as const,\n value: value - 1000,\n };\n }\n\n if (value > 0) {\n return {\n unit: \"percent_ftp\" as const,\n value,\n };\n }\n\n return null;\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport { convertPowerValue, interpretWorkoutPower } from \"./power-helpers\";\nimport type { FitTargetData } from \"./target.types\";\n\nexport const convertPowerTarget = (data: FitTargetData): Target => {\n const rangeTarget = buildPowerRangeTarget(data);\n if (rangeTarget) return rangeTarget;\n\n const zoneTarget = buildPowerZoneTarget(data);\n if (zoneTarget) return zoneTarget;\n\n if (data.targetValue !== undefined) {\n const powerValue = convertPowerValue(data.targetValue);\n if (powerValue) {\n return {\n type: targetTypeSchema.enum.power,\n value: powerValue,\n };\n }\n }\n\n return { type: targetTypeSchema.enum.open };\n};\n\nconst buildPowerRangeTarget = (data: FitTargetData): Target | null => {\n if (\n data.customTargetPowerLow !== undefined &&\n data.customTargetPowerHigh !== undefined\n ) {\n const minValue = interpretWorkoutPower(data.customTargetPowerLow);\n const maxValue = interpretWorkoutPower(data.customTargetPowerHigh);\n\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: targetUnitSchema.enum.range,\n min: minValue.value,\n max: maxValue.value,\n },\n };\n }\n\n if (\n data.customTargetValueLow !== undefined &&\n data.customTargetValueHigh !== undefined\n ) {\n const minValue = interpretWorkoutPower(data.customTargetValueLow);\n const maxValue = interpretWorkoutPower(data.customTargetValueHigh);\n\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: targetUnitSchema.enum.range,\n min: minValue.value,\n max: maxValue.value,\n },\n };\n }\n\n return null;\n};\n\nconst buildPowerZoneTarget = (data: FitTargetData): Target | null => {\n if (data.targetPowerZone !== undefined) {\n return {\n type: targetTypeSchema.enum.power,\n value: {\n unit: targetUnitSchema.enum.zone,\n value: data.targetPowerZone,\n },\n };\n }\n return null;\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport { targetUnitSchema } from \"@kaiord/core\";\nimport type { FitTargetData } from \"./target.types\";\n\nexport const convertStrokeTypeTarget = (data: FitTargetData): Target => {\n if (data.targetSwimStroke !== undefined) {\n return {\n type: targetTypeSchema.enum.stroke_type,\n value: {\n unit: targetUnitSchema.enum.swim_stroke,\n value: data.targetSwimStroke,\n },\n };\n }\n\n return { type: targetTypeSchema.enum.open };\n};\n","import { targetTypeSchema, type Target } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\nimport { convertCadenceTarget } from \"./target-cadence.converter\";\nimport { convertHeartRateTarget } from \"./target-heart-rate.converter\";\nimport { convertPaceTarget } from \"./target-pace.converter\";\nimport { convertPowerTarget } from \"./target-power.converter\";\nimport { convertStrokeTypeTarget } from \"./target-stroke.converter\";\nimport type { FitTargetData } from \"./target.types\";\n\nexport type { FitTargetData };\n\nexport const convertFitTarget = (data: FitTargetData): Target => {\n if (data.targetType === fitTargetTypeSchema.enum.power) {\n return convertPowerTarget(data);\n }\n\n if (data.targetType === fitTargetTypeSchema.enum.heartRate) {\n return convertHeartRateTarget(data);\n }\n\n if (data.targetType === fitTargetTypeSchema.enum.cadence) {\n return convertCadenceTarget(data);\n }\n\n if (data.targetType === fitTargetTypeSchema.enum.speed) {\n return convertPaceTarget(data);\n }\n\n if (data.targetType === fitTargetTypeSchema.enum.swimStroke) {\n return convertStrokeTypeTarget(data);\n }\n\n return { type: targetTypeSchema.enum.open };\n};\n","import { targetTypeSchema, type Target, type TargetType } from \"@kaiord/core\";\nimport { fitTargetTypeSchema } from \"../schemas/fit-target\";\nimport type { FitWorkoutStep } from \"../shared/types\";\nimport { convertFitTarget } from \"./target.converter\";\n\nexport const mapTarget = (step: FitWorkoutStep): Target => {\n return convertFitTarget(step);\n};\n\nexport const mapTargetType = (\n fitTargetType: string | undefined\n): TargetType => {\n if (fitTargetType === fitTargetTypeSchema.enum.power)\n return targetTypeSchema.enum.power;\n if (fitTargetType === fitTargetTypeSchema.enum.heartRate)\n return targetTypeSchema.enum.heart_rate;\n if (fitTargetType === fitTargetTypeSchema.enum.cadence)\n return targetTypeSchema.enum.cadence;\n if (fitTargetType === fitTargetTypeSchema.enum.speed)\n return targetTypeSchema.enum.pace;\n if (fitTargetType === fitTargetTypeSchema.enum.swimStroke)\n return targetTypeSchema.enum.stroke_type;\n return targetTypeSchema.enum.open;\n};\n","import { intensitySchema, type Intensity } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport { mapDuration, mapDurationType } from \"../duration/duration.mapper\";\nimport { mapEquipmentToKrd } from \"../equipment/equipment.mapper\";\nimport type { FitWorkoutStep } from \"../shared/types\";\nimport { mapTarget, mapTargetType } from \"../target/target.mapper\";\n\nexport const mapStep = (step: FitWorkoutStep, index: number): WorkoutStep => {\n const duration = mapDuration(step);\n const target = mapTarget(step);\n\n const workoutStep: WorkoutStep = {\n stepIndex: step.messageIndex ?? index,\n name: step.wktStepName,\n durationType: mapDurationType(step.durationType),\n duration,\n targetType: mapTargetType(step.targetType),\n target,\n intensity: mapIntensity(step.intensity),\n };\n\n if (step.notes !== undefined) {\n workoutStep.notes = step.notes;\n }\n\n if (step.equipment !== undefined) {\n workoutStep.equipment = mapEquipmentToKrd(step.equipment);\n }\n\n return workoutStep;\n};\n\nconst mapIntensity = (intensity: string | undefined): Intensity | undefined => {\n if (!intensity) return undefined;\n\n const normalized = intensity.toLowerCase();\n const validIntensities = intensitySchema.options;\n\n if (validIntensities.includes(normalized as Intensity)) {\n return normalized as Intensity;\n }\n\n return undefined;\n};\n","import type { RepetitionBlock, WorkoutStep } from \"@kaiord/core\";\nimport { fitDurationTypeSchema } from \"../schemas/fit-duration\";\nimport type { FitWorkoutStep } from \"../shared/types\";\nimport { mapStep } from \"./step.mapper\";\n\nexport const findRepetitionStepIndices = (\n workoutSteps: Array<FitWorkoutStep>\n): Set<number> => {\n const indices = new Set<number>();\n\n for (let i = 0; i < workoutSteps.length; i++) {\n const step = workoutSteps[i];\n if (\n step.durationType === fitDurationTypeSchema.enum.repeatUntilStepsCmplt\n ) {\n const startIndex = (step.durationStep || 0) as number;\n for (let j = startIndex; j < i; j++) {\n indices.add(j);\n }\n }\n }\n\n return indices;\n};\n\nexport const buildWorkoutSteps = (\n workoutSteps: Array<FitWorkoutStep>,\n repetitionStepIndices: Set<number>\n): Array<WorkoutStep | RepetitionBlock> => {\n const steps = [];\n\n for (let i = 0; i < workoutSteps.length; i++) {\n const step = workoutSteps[i];\n\n if (\n step.durationType === fitDurationTypeSchema.enum.repeatUntilStepsCmplt &&\n step.repeatSteps\n ) {\n const repetitionBlock = buildRepetitionBlock(step, workoutSteps, i);\n steps.push(repetitionBlock);\n } else if (!repetitionStepIndices.has(i)) {\n steps.push(mapStep(step, i));\n }\n }\n\n return steps;\n};\n\nexport const buildRepetitionBlock = (\n step: FitWorkoutStep,\n workoutSteps: Array<FitWorkoutStep>,\n currentIndex: number\n): RepetitionBlock => {\n const repeatCount = step.repeatSteps!;\n const startIndex = (step.durationStep || 0) as number;\n const repeatedSteps = [];\n\n for (let j = startIndex; j < currentIndex; j++) {\n repeatedSteps.push(mapStep(workoutSteps[j], j));\n }\n\n return {\n repeatCount,\n steps: repeatedSteps,\n };\n};\n","import { convertLengthToMeters } from \"@kaiord/core\";\nimport type { Workout } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { mapLengthUnitToKrd } from \"../length-unit/length-unit.mapper\";\nimport { mapSportType } from \"../shared/type-guards\";\nimport type { FitWorkoutMessage, FitWorkoutStep } from \"../shared/types\";\nimport { mapSubSportToKrd } from \"../sub-sport/sub-sport.mapper\";\nimport {\n buildWorkoutSteps,\n findRepetitionStepIndices,\n} from \"./repetition.builder\";\n\nexport const mapWorkout = (\n workoutMsg: FitWorkoutMessage | undefined,\n workoutSteps: Array<FitWorkoutStep>,\n logger: Logger\n): Workout => {\n logger.debug(\"Mapping workout steps\", {\n stepCount: workoutSteps.length,\n });\n\n const repetitionStepIndices = findRepetitionStepIndices(workoutSteps);\n const steps = buildWorkoutSteps(workoutSteps, repetitionStepIndices);\n\n const workout: Workout = {\n name: workoutMsg?.wktName,\n sport: mapSportType(workoutMsg?.sport),\n steps,\n };\n\n if (workoutMsg?.subSport !== undefined) {\n workout.subSport = mapSubSportToKrd(workoutMsg.subSport);\n }\n\n if (workoutMsg?.poolLength !== undefined) {\n const unit = mapLengthUnitToKrd(workoutMsg.poolLengthUnit);\n workout.poolLength = convertLengthToMeters(workoutMsg.poolLength, unit);\n workout.poolLengthUnit = \"meters\";\n }\n\n return workout;\n};\n","import { createFitParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { fitMessageKeySchema } from \"../schemas/fit-message-keys\";\nimport type { FitMessages } from \"../shared/types\";\n\nexport type ValidateMessagesOptions = {\n /** If true, throw on missing critical messages. Default: true */\n strict?: boolean;\n};\n\n/**\n * Validates required FIT messages are present.\n * In strict mode (default), throws on missing fileId or workout messages.\n */\nexport const validateMessages = (\n fileId: unknown,\n workoutMsg: unknown,\n messages: FitMessages,\n logger: Logger,\n options: ValidateMessagesOptions = {}\n): void => {\n const { strict = true } = options;\n\n if (!fileId) {\n const message = \"Missing required fileId message in FIT file\";\n if (strict) {\n throw createFitParsingError(message);\n }\n logger.warn(message);\n }\n\n if (!workoutMsg) {\n const message = \"Missing required workout message in FIT file\";\n if (strict) {\n throw createFitParsingError(message);\n }\n logger.warn(message);\n }\n\n const workoutMessages = messages[fitMessageKeySchema.enum.workoutMesgs];\n if (workoutMessages && workoutMessages.length > 1) {\n logger.warn(\"Multiple workout messages found, using first one\", {\n count: workoutMessages.length,\n });\n }\n};\n","import { fileTypeSchema } from \"@kaiord/core\";\nimport type { KRD } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { extractFitExtensions } from \"../extensions/extensions.extractor\";\nimport { mapMetadata } from \"../metadata/metadata.mapper\";\nimport { fitMessageKeySchema } from \"../schemas/fit-message-keys\";\nimport type { FitMessages } from \"../shared/types\";\nimport { mapWorkout } from \"../workout/workout.mapper\";\nimport { validateMessages } from \"./messages.validator\";\n\nconst KRD_VERSION = \"1.0\" as const;\n\n/**\n * Maps workout file to KRD format.\n */\nexport const mapWorkoutFileToKRD = (\n messages: FitMessages,\n logger: Logger\n): KRD => {\n const fileId = messages[fitMessageKeySchema.enum.fileIdMesgs]?.[0];\n const workoutMsg = messages[fitMessageKeySchema.enum.workoutMesgs]?.[0];\n const workoutSteps =\n messages[fitMessageKeySchema.enum.workoutStepMesgs] || [];\n\n validateMessages(fileId, workoutMsg, messages, logger);\n\n const metadata = mapMetadata(fileId, workoutMsg, logger);\n const workout = mapWorkout(workoutMsg, workoutSteps, logger);\n const fitExtensions = extractFitExtensions(messages, logger);\n\n return {\n version: KRD_VERSION,\n type: fileTypeSchema.enum.structured_workout,\n metadata,\n extensions: { structured_workout: workout, fit: fitExtensions },\n };\n};\n","import { fileTypeSchema, type FileType } from \"@kaiord/core\";\nimport type { KRD } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { createCourseMessages } from \"../course\";\nimport { convertKRDToMessages } from \"../krd-to-fit/krd-to-fit.converter\";\nimport { fitMessageKeySchema } from \"../schemas/fit-message-keys\";\nimport { FIT_MESSAGE_NUMBERS } from \"../shared/message-numbers\";\nimport type { FitMessages } from \"../shared/types\";\nimport { createActivityMessages } from \"./activity-messages.creator\";\nimport { mapActivityFileToKRD } from \"./activity.mapper\";\nimport { mapWorkoutFileToKRD } from \"./workout.mapper\";\n\n/**\n * Detects file type from FIT messages.\n */\nconst detectFileType = (messages: FitMessages): FileType => {\n const workoutMsgs = messages[fitMessageKeySchema.enum.workoutMesgs];\n if (workoutMsgs && workoutMsgs.length > 0)\n return fileTypeSchema.enum.structured_workout;\n\n const sessionMsgs = messages[fitMessageKeySchema.enum.sessionMesgs];\n const recordMsgs = messages[fitMessageKeySchema.enum.recordMesgs];\n if (\n (sessionMsgs && sessionMsgs.length > 0) ||\n (recordMsgs && recordMsgs.length > 0)\n ) {\n return fileTypeSchema.enum.recorded_activity;\n }\n\n return fileTypeSchema.enum.structured_workout;\n};\n\nexport const mapMessagesToKRD = (\n messages: FitMessages,\n logger: Logger\n): KRD => {\n logger.debug(\"Mapping FIT messages to KRD\", {\n messageCount: Object.keys(messages).length,\n });\n\n const fileType = detectFileType(messages);\n logger.debug(\"Detected file type\", { fileType });\n\n switch (fileType) {\n case fileTypeSchema.enum.recorded_activity:\n return mapActivityFileToKRD(messages, logger);\n case fileTypeSchema.enum.structured_workout:\n default:\n return mapWorkoutFileToKRD(messages, logger);\n }\n};\n\n/**\n * Creates FIT messages from KRD format with file type routing.\n *\n * Routes to the appropriate message creation function based on the\n * file type specified in KRD metadata. Supports workout, activity,\n * and course file types.\n */\nexport const createFitMessages = (\n krd: KRD,\n logger: Logger\n): Record<string, unknown[]> => {\n const fileType = krd.type;\n logger.debug(\"Creating FIT messages from KRD\", { fileType });\n\n switch (fileType) {\n case \"structured_workout\": {\n // Workout files use array-based format from convertKRDToMessages\n // Group messages by type for compatibility with record-based format\n const messages = convertKRDToMessages(krd, logger);\n const result: Record<string, unknown[]> = {};\n\n for (const msg of messages) {\n const message = msg as { mesgNum?: number };\n if (message.mesgNum === FIT_MESSAGE_NUMBERS.FILE_ID) {\n result[fitMessageKeySchema.enum.fileIdMesgs] = [\n ...(result[fitMessageKeySchema.enum.fileIdMesgs] || []),\n message,\n ];\n } else if (message.mesgNum === FIT_MESSAGE_NUMBERS.WORKOUT) {\n result[fitMessageKeySchema.enum.workoutMesgs] = [\n ...(result[fitMessageKeySchema.enum.workoutMesgs] || []),\n message,\n ];\n } else if (message.mesgNum === FIT_MESSAGE_NUMBERS.WORKOUT_STEP) {\n result[fitMessageKeySchema.enum.workoutStepMesgs] = [\n ...(result[fitMessageKeySchema.enum.workoutStepMesgs] || []),\n message,\n ];\n }\n }\n\n return result;\n }\n case \"recorded_activity\":\n return createActivityMessages(krd, logger);\n case \"course\":\n return createCourseMessages(krd, logger);\n default:\n throw new Error(`Unsupported FIT file type: ${fileType}`);\n }\n};\n","/**\n * Garmin FIT SDK Adapter - converts FIT workout files to KRD format\n * References: https://developer.garmin.com/fit/file-types/workout/\n */\n\nimport { Decoder, Encoder, Stream } from \"@garmin/fitsdk\";\nimport type { KRD } from \"@kaiord/core\";\nimport { createFitParsingError } from \"@kaiord/core\";\nimport type { FitReader } from \"@kaiord/core\";\nimport type { FitWriter } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertKRDToMessages } from \"./krd-to-fit/krd-to-fit.converter\";\nimport { mapMessagesToKRD } from \"./messages/messages.mapper\";\nimport type { FitMessages } from \"./shared/types\";\n\nexport const createGarminFitSdkReader =\n (logger: Logger): FitReader =>\n async (buffer: Uint8Array): Promise<KRD> => {\n try {\n logger.debug(\"Parsing FIT file\", { bufferSize: buffer.length });\n\n if (buffer.length === 0) {\n logger.error(\"Empty FIT buffer\");\n throw createFitParsingError(\"Cannot parse empty FIT buffer\");\n }\n\n const stream = Stream.fromByteArray(Array.from(buffer));\n const decoder = new Decoder(stream);\n const { messages, errors } = decoder.read();\n\n if (errors.length > 0) {\n logger.error(\"FIT parsing errors detected\", { errors });\n throw createFitParsingError(`FIT parsing errors: ${errors.join(\", \")}`);\n }\n\n logger.info(\"FIT file parsed successfully\");\n return mapMessagesToKRD(messages as FitMessages, logger);\n } catch (error) {\n if (error instanceof Error && error.name === \"FitParsingError\") {\n throw error;\n }\n logger.error(\"Failed to parse FIT file\", { error });\n throw createFitParsingError(\"Failed to parse FIT file\", error);\n }\n };\n\nexport const createGarminFitSdkWriter =\n (logger: Logger): FitWriter =>\n async (krd: KRD): Promise<Uint8Array> => {\n try {\n logger.debug(\"Encoding KRD to FIT\");\n\n const encoder = new Encoder();\n const messages = convertKRDToMessages(krd, logger);\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n try {\n logger.debug(`Writing message ${i + 1}/${messages.length}`, {\n mesgNum: (message as { mesgNum?: number }).mesgNum,\n });\n encoder.writeMesg(message);\n } catch (error) {\n logger.error(`Failed to write message ${i + 1}`, {\n message: JSON.stringify(message, null, 2),\n error,\n });\n throw error;\n }\n }\n\n const buffer = encoder.close();\n logger.info(\"KRD encoded to FIT successfully\");\n return new Uint8Array(buffer);\n } catch (error) {\n if (error instanceof Error && error.name === \"FitParsingError\") {\n throw error;\n }\n logger.error(\"Failed to write FIT file\", { error });\n throw createFitParsingError(\"Failed to write FIT file\", error);\n }\n };\n","import type { FitReader, FitWriter, Logger } from \"@kaiord/core\";\nimport { createConsoleLogger } from \"@kaiord/core\";\nimport {\n createGarminFitSdkReader,\n createGarminFitSdkWriter,\n} from \"./adapters/garmin-fitsdk\";\n\nexport type FitProviders = {\n fitReader: FitReader;\n fitWriter: FitWriter;\n};\n\nexport const createFitProviders = (logger?: Logger): FitProviders => {\n const log = logger || createConsoleLogger();\n\n return {\n fitReader: createGarminFitSdkReader(log),\n fitWriter: createGarminFitSdkWriter(log),\n };\n};\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kaiord/fit",
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"description": "FIT format adapter for Kaiord workout data conversion",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@garmin/fitsdk": "^21.141.0",
|
|
20
|
+
"zod": "^3.22.4",
|
|
21
|
+
"@kaiord/core": "^4.1.0"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@faker-js/faker": "^10.1.0",
|
|
25
|
+
"@types/node": "^24.0.0",
|
|
26
|
+
"@types/rosie": "^0.0.45",
|
|
27
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
28
|
+
"rosie": "^2.1.1",
|
|
29
|
+
"tsup": "^8.5.1",
|
|
30
|
+
"tsx": "^4.7.0",
|
|
31
|
+
"typescript": "^5.3.3",
|
|
32
|
+
"vitest": "^4.0.18"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/pablo-albaladejo/kaiord.git",
|
|
37
|
+
"directory": "packages/fit"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://www.npmjs.com/package/@kaiord/fit",
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/pablo-albaladejo/kaiord/issues"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"keywords": [
|
|
47
|
+
"kaiord",
|
|
48
|
+
"fit",
|
|
49
|
+
"garmin",
|
|
50
|
+
"workout",
|
|
51
|
+
"converter",
|
|
52
|
+
"fitness"
|
|
53
|
+
],
|
|
54
|
+
"author": "Kaiord Contributors",
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "tsup",
|
|
58
|
+
"test": "vitest --run",
|
|
59
|
+
"test:watch": "vitest",
|
|
60
|
+
"lint": "tsc --noEmit && eslint . && prettier --check src",
|
|
61
|
+
"lint:fix": "eslint . --fix && prettier --write src",
|
|
62
|
+
"clean": "rm -rf dist"
|
|
63
|
+
}
|
|
64
|
+
}
|