@kaiord/fit 4.7.2 → 4.8.1

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/dist/index.js CHANGED
@@ -1,15 +1,8 @@
1
- import { sportSchema, durationTypeSchema, createConsoleLogger, createFitParsingError, fileTypeSchema, workoutSchema, isRepetitionBlock, convertLengthToMeters, subSportSchema, lengthUnitSchema, FIT_TO_SWIM_STROKE, equipmentSchema, targetTypeSchema, targetUnitSchema, intensitySchema } from '@kaiord/core';
1
+ import { sportSchema, durationTypeSchema, createConsoleLogger, createFitParsingError, fileTypeSchema, workoutSchema, isRepetitionBlock, convertLengthToMeters, subSportSchema, lengthUnitSchema, equipmentSchema, targetTypeSchema, FIT_TO_SWIM_STROKE, targetUnitSchema, intensitySchema } from '@kaiord/core';
2
2
  import { Stream, Decoder, Encoder, Profile } from '@garmin/fitsdk';
3
3
  import { z } from 'zod';
4
4
 
5
5
  // src/index.ts
6
-
7
- // src/adapters/shared/message-numbers.ts
8
- var FIT_MESSAGE_NUMBERS = {
9
- FILE_ID: 0,
10
- WORKOUT: 26,
11
- WORKOUT_STEP: 27
12
- };
13
6
  z.enum([
14
7
  "device",
15
8
  "settings",
@@ -283,49 +276,6 @@ var fitDurationTypeSchema = z.enum([
283
276
  "repeatUntilPowerGreaterThan",
284
277
  "open"
285
278
  ]);
286
- var fitTargetTypeSchema = z.enum([
287
- "power",
288
- "heartRate",
289
- "cadence",
290
- "speed",
291
- "swimStroke",
292
- "open"
293
- ]);
294
- var fitEquipmentSchema = z.enum([
295
- "none",
296
- "swimFins",
297
- "swimKickboard",
298
- "swimPaddles",
299
- "swimPullBuoy",
300
- "swimSnorkel"
301
- ]);
302
-
303
- // src/adapters/equipment/equipment.mapper.ts
304
- var FIT_TO_KRD_EQUIPMENT_MAP = {
305
- none: "none",
306
- swimFins: "swim_fins",
307
- swimKickboard: "swim_kickboard",
308
- swimPaddles: "swim_paddles",
309
- swimPullBuoy: "swim_pull_buoy",
310
- swimSnorkel: "swim_snorkel"
311
- };
312
- var KRD_TO_FIT_EQUIPMENT_MAP = Object.fromEntries(
313
- Object.entries(FIT_TO_KRD_EQUIPMENT_MAP).map(([fit, krd]) => [krd, fit])
314
- );
315
- var mapEquipmentToKrd = (fitEquipment) => {
316
- const result = fitEquipmentSchema.safeParse(fitEquipment);
317
- if (!result.success) {
318
- return equipmentSchema.enum.none;
319
- }
320
- return FIT_TO_KRD_EQUIPMENT_MAP[result.data] || equipmentSchema.enum.none;
321
- };
322
- var mapEquipmentToFit = (krdEquipment) => {
323
- const result = equipmentSchema.safeParse(krdEquipment);
324
- if (!result.success) {
325
- return fitEquipmentSchema.enum.none;
326
- }
327
- return KRD_TO_FIT_EQUIPMENT_MAP[result.data] || fitEquipmentSchema.enum.none;
328
- };
329
279
  var convertConditionalDuration = (duration, message) => {
330
280
  if (duration.type === durationTypeSchema.enum.heart_rate_less_than) {
331
281
  message.durationType = fitDurationTypeSchema.enum.hrLessThan;
@@ -421,6 +371,16 @@ var convertDuration = (step, message) => {
421
371
  if (convertRepeatHrPowerDuration(duration, message)) return;
422
372
  message.durationType = fitDurationTypeSchema.enum.open;
423
373
  };
374
+ var fitTargetTypeSchema = z.enum([
375
+ "power",
376
+ "heartRate",
377
+ "cadence",
378
+ "speed",
379
+ "swimStroke",
380
+ "open"
381
+ ]);
382
+
383
+ // src/adapters/krd-to-fit/krd-to-fit-target-cadence.mapper.ts
424
384
  var convertCadenceTarget = (step, message) => {
425
385
  message.targetType = fitTargetTypeSchema.enum.cadence;
426
386
  if (step.target.type !== targetTypeSchema.enum.cadence) return;
@@ -508,6 +468,41 @@ var convertTarget = (step, message) => {
508
468
  convertStrokeTarget(step, message);
509
469
  }
510
470
  };
471
+ var fitEquipmentSchema = z.enum([
472
+ "none",
473
+ "swimFins",
474
+ "swimKickboard",
475
+ "swimPaddles",
476
+ "swimPullBuoy",
477
+ "swimSnorkel"
478
+ ]);
479
+
480
+ // src/adapters/equipment/equipment.mapper.ts
481
+ var FIT_TO_KRD_EQUIPMENT_MAP = {
482
+ none: "none",
483
+ swimFins: "swim_fins",
484
+ swimKickboard: "swim_kickboard",
485
+ swimPaddles: "swim_paddles",
486
+ swimPullBuoy: "swim_pull_buoy",
487
+ swimSnorkel: "swim_snorkel"
488
+ };
489
+ var KRD_TO_FIT_EQUIPMENT_MAP = Object.fromEntries(
490
+ Object.entries(FIT_TO_KRD_EQUIPMENT_MAP).map(([fit, krd]) => [krd, fit])
491
+ );
492
+ var mapEquipmentToKrd = (fitEquipment) => {
493
+ const result = fitEquipmentSchema.safeParse(fitEquipment);
494
+ if (!result.success) {
495
+ return equipmentSchema.enum.none;
496
+ }
497
+ return FIT_TO_KRD_EQUIPMENT_MAP[result.data] || equipmentSchema.enum.none;
498
+ };
499
+ var mapEquipmentToFit = (krdEquipment) => {
500
+ const result = equipmentSchema.safeParse(krdEquipment);
501
+ if (!result.success) {
502
+ return fitEquipmentSchema.enum.none;
503
+ }
504
+ return KRD_TO_FIT_EQUIPMENT_MAP[result.data] || fitEquipmentSchema.enum.none;
505
+ };
511
506
 
512
507
  // src/adapters/krd-to-fit/krd-to-fit-step.mapper.ts
513
508
  var FIT_NOTES_MAX_LENGTH = 256;
@@ -554,6 +549,13 @@ var convertNotes = (notes, stepIndex, behavior, logger) => {
554
549
  return notes.substring(0, FIT_NOTES_MAX_LENGTH);
555
550
  };
556
551
 
552
+ // src/adapters/shared/message-numbers.ts
553
+ var FIT_MESSAGE_NUMBERS = {
554
+ FILE_ID: 0,
555
+ WORKOUT: 26,
556
+ WORKOUT_STEP: 27
557
+ };
558
+
557
559
  // src/adapters/krd-to-fit/krd-to-fit-workout.mapper.ts
558
560
  var convertWorkoutSteps = (workout, logger, options = {}) => {
559
561
  logger.debug("Converting workout steps", { stepCount: workout.steps.length });
@@ -664,72 +666,6 @@ var validateCoordinates = (latSemicircles, lonSemicircles) => {
664
666
  const degreesLon = semicirclesToDegrees(lonSemicircles);
665
667
  return degreesLat >= -90 && degreesLat <= 90 && degreesLon >= -180 && degreesLon <= 180;
666
668
  };
667
- var fitMessageKeySchema = z.enum([
668
- "fileIdMesgs",
669
- "workoutMesgs",
670
- "workoutStepMesgs",
671
- "sessionMesgs",
672
- "recordMesgs",
673
- "eventMesgs",
674
- "lapMesgs"
675
- ]);
676
- var fitEventSchema = z.enum([
677
- "timer",
678
- "workout",
679
- "workoutStep",
680
- "powerDown",
681
- "powerUp",
682
- "offCourse",
683
- "session",
684
- "lap",
685
- "coursePoint",
686
- "battery",
687
- "virtualPartnerPace",
688
- "hrHighAlert",
689
- "hrLowAlert",
690
- "speedHighAlert",
691
- "speedLowAlert",
692
- "cadHighAlert",
693
- "cadLowAlert",
694
- "powerHighAlert",
695
- "powerLowAlert",
696
- "recoveryHr",
697
- "batteryLow",
698
- "timeDurationAlert",
699
- "distanceDurationAlert",
700
- "calorieDurationAlert",
701
- "activity",
702
- "fitnessEquipment",
703
- "length",
704
- "userMarker",
705
- "sportPoint",
706
- "calibration",
707
- "frontGearChange",
708
- "rearGearChange",
709
- "riderPositionChange",
710
- "elevHighAlert",
711
- "elevLowAlert"
712
- ]);
713
- var fitEventTypeSchema = z.enum([
714
- "start",
715
- "stop",
716
- "consecutiveDepreciated",
717
- "marker",
718
- "stopAll",
719
- "beginDepreciated",
720
- "endDepreciated",
721
- "endAllDepreciated",
722
- "stopDisable",
723
- "stopDisableAll"
724
- ]);
725
- var fitEventMessageSchema = z.object({
726
- timestamp: z.number(),
727
- event: fitEventSchema,
728
- eventType: fitEventTypeSchema,
729
- eventGroup: z.number().optional(),
730
- data: z.number().optional(),
731
- data16: z.number().optional()
732
- });
733
669
 
734
670
  // src/adapters/event/event-type-maps.ts
735
671
  var FIT_EVENT_TO_KRD_TYPE = {
@@ -793,6 +729,63 @@ var mapFitEventToKrd = (fit) => ({
793
729
  eventGroup: fit.eventGroup,
794
730
  data: fit.data
795
731
  });
732
+ var fitEventSchema = z.enum([
733
+ "timer",
734
+ "workout",
735
+ "workoutStep",
736
+ "powerDown",
737
+ "powerUp",
738
+ "offCourse",
739
+ "session",
740
+ "lap",
741
+ "coursePoint",
742
+ "battery",
743
+ "virtualPartnerPace",
744
+ "hrHighAlert",
745
+ "hrLowAlert",
746
+ "speedHighAlert",
747
+ "speedLowAlert",
748
+ "cadHighAlert",
749
+ "cadLowAlert",
750
+ "powerHighAlert",
751
+ "powerLowAlert",
752
+ "recoveryHr",
753
+ "batteryLow",
754
+ "timeDurationAlert",
755
+ "distanceDurationAlert",
756
+ "calorieDurationAlert",
757
+ "activity",
758
+ "fitnessEquipment",
759
+ "length",
760
+ "userMarker",
761
+ "sportPoint",
762
+ "calibration",
763
+ "frontGearChange",
764
+ "rearGearChange",
765
+ "riderPositionChange",
766
+ "elevHighAlert",
767
+ "elevLowAlert"
768
+ ]);
769
+ var fitEventTypeSchema = z.enum([
770
+ "start",
771
+ "stop",
772
+ "consecutiveDepreciated",
773
+ "marker",
774
+ "stopAll",
775
+ "beginDepreciated",
776
+ "endDepreciated",
777
+ "endAllDepreciated",
778
+ "stopDisable",
779
+ "stopDisableAll"
780
+ ]);
781
+ var fitEventMessageSchema = z.object({
782
+ timestamp: z.number(),
783
+ event: fitEventSchema,
784
+ eventType: fitEventTypeSchema,
785
+ eventGroup: z.number().optional(),
786
+ data: z.number().optional(),
787
+ data16: z.number().optional()
788
+ });
796
789
 
797
790
  // src/adapters/event/fit-to-krd-event.converter.ts
798
791
  var convertFitToKrdEvent = (data) => {
@@ -802,6 +795,15 @@ var convertFitToKrdEvent = (data) => {
802
795
  var convertFitToKrdEvents = (events) => {
803
796
  return events.map(convertFitToKrdEvent);
804
797
  };
798
+ var fitMessageKeySchema = z.enum([
799
+ "fileIdMesgs",
800
+ "workoutMesgs",
801
+ "workoutStepMesgs",
802
+ "sessionMesgs",
803
+ "recordMesgs",
804
+ "eventMesgs",
805
+ "lapMesgs"
806
+ ]);
805
807
 
806
808
  // src/adapters/extensions/extensions.extractor.ts
807
809
  var extractFitExtensions = (messages, logger) => {
@@ -869,6 +871,64 @@ var buildExtensions = (unknownMessages, developerFields, logger) => {
869
871
  }
870
872
  return extensions;
871
873
  };
874
+
875
+ // src/adapters/lap/lap-trigger.mapper.ts
876
+ var mapFitLapTriggerToKrd = (fit) => {
877
+ switch (fit) {
878
+ case "manual":
879
+ return "manual";
880
+ case "time":
881
+ return "time";
882
+ case "distance":
883
+ return "distance";
884
+ case "positionStart":
885
+ case "positionLap":
886
+ case "positionWaypoint":
887
+ case "positionMarked":
888
+ return "position";
889
+ case "sessionEnd":
890
+ return "session_end";
891
+ case "fitnessEquipment":
892
+ return "fitness_equipment";
893
+ }
894
+ };
895
+
896
+ // src/adapters/lap/lap.mapper.ts
897
+ var mapFitLapToKrd = (fit) => ({
898
+ // Timing - convert ms to seconds
899
+ startTime: new Date(fit.startTime * 1e3).toISOString(),
900
+ totalElapsedTime: fit.totalElapsedTime / 1e3,
901
+ totalTimerTime: fit.totalTimerTime / 1e3,
902
+ // Distance
903
+ totalDistance: fit.totalDistance,
904
+ // Heart rate
905
+ avgHeartRate: fit.avgHeartRate,
906
+ maxHeartRate: fit.maxHeartRate,
907
+ // Cadence
908
+ avgCadence: fit.avgCadence,
909
+ maxCadence: fit.maxCadence,
910
+ // Power
911
+ avgPower: fit.avgPower,
912
+ maxPower: fit.maxPower,
913
+ normalizedPower: fit.normalizedPower,
914
+ // Speed - prefer enhanced values
915
+ avgSpeed: fit.enhancedAvgSpeed ?? fit.avgSpeed,
916
+ maxSpeed: fit.enhancedMaxSpeed ?? fit.maxSpeed,
917
+ // Elevation
918
+ totalAscent: fit.totalAscent,
919
+ totalDescent: fit.totalDescent,
920
+ // Calories
921
+ totalCalories: fit.totalCalories,
922
+ // Classification
923
+ trigger: fit.lapTrigger ? mapFitLapTriggerToKrd(fit.lapTrigger) : void 0,
924
+ sport: fit.sport,
925
+ subSport: fit.subSport ? mapSubSportToKrd(fit.subSport) : void 0,
926
+ // Workout reference
927
+ workoutStepIndex: fit.wktStepIndex,
928
+ // Swimming
929
+ numLengths: fit.numLengths,
930
+ swimStroke: fit.swimStroke !== void 0 ? FIT_TO_SWIM_STROKE[fit.swimStroke] : void 0
931
+ });
872
932
  var fitLapTriggerSchema = z.enum([
873
933
  "manual",
874
934
  "time",
@@ -929,64 +989,6 @@ var fitLapSchema = z.object({
929
989
  wktStepIndex: z.number().optional()
930
990
  });
931
991
 
932
- // src/adapters/lap/lap-trigger.mapper.ts
933
- var mapFitLapTriggerToKrd = (fit) => {
934
- switch (fit) {
935
- case "manual":
936
- return "manual";
937
- case "time":
938
- return "time";
939
- case "distance":
940
- return "distance";
941
- case "positionStart":
942
- case "positionLap":
943
- case "positionWaypoint":
944
- case "positionMarked":
945
- return "position";
946
- case "sessionEnd":
947
- return "session_end";
948
- case "fitnessEquipment":
949
- return "fitness_equipment";
950
- }
951
- };
952
-
953
- // src/adapters/lap/lap.mapper.ts
954
- var mapFitLapToKrd = (fit) => ({
955
- // Timing - convert ms to seconds
956
- startTime: new Date(fit.startTime * 1e3).toISOString(),
957
- totalElapsedTime: fit.totalElapsedTime / 1e3,
958
- totalTimerTime: fit.totalTimerTime / 1e3,
959
- // Distance
960
- totalDistance: fit.totalDistance,
961
- // Heart rate
962
- avgHeartRate: fit.avgHeartRate,
963
- maxHeartRate: fit.maxHeartRate,
964
- // Cadence
965
- avgCadence: fit.avgCadence,
966
- maxCadence: fit.maxCadence,
967
- // Power
968
- avgPower: fit.avgPower,
969
- maxPower: fit.maxPower,
970
- normalizedPower: fit.normalizedPower,
971
- // Speed - prefer enhanced values
972
- avgSpeed: fit.enhancedAvgSpeed ?? fit.avgSpeed,
973
- maxSpeed: fit.enhancedMaxSpeed ?? fit.maxSpeed,
974
- // Elevation
975
- totalAscent: fit.totalAscent,
976
- totalDescent: fit.totalDescent,
977
- // Calories
978
- totalCalories: fit.totalCalories,
979
- // Classification
980
- trigger: fit.lapTrigger ? mapFitLapTriggerToKrd(fit.lapTrigger) : void 0,
981
- sport: fit.sport,
982
- subSport: fit.subSport ? mapSubSportToKrd(fit.subSport) : void 0,
983
- // Workout reference
984
- workoutStepIndex: fit.wktStepIndex,
985
- // Swimming
986
- numLengths: fit.numLengths,
987
- swimStroke: fit.swimStroke !== void 0 ? FIT_TO_SWIM_STROKE[fit.swimStroke] : void 0
988
- });
989
-
990
992
  // src/adapters/lap/fit-to-krd-lap.converter.ts
991
993
  var convertFitToKrdLap = (data) => {
992
994
  const fitLap = fitLapSchema.parse(data);
@@ -995,26 +997,6 @@ var convertFitToKrdLap = (data) => {
995
997
  var convertFitToKrdLaps = (laps) => {
996
998
  return laps.map(convertFitToKrdLap);
997
999
  };
998
- var fitRecordSchema = z.object({
999
- timestamp: z.number(),
1000
- positionLat: z.number().optional(),
1001
- positionLong: z.number().optional(),
1002
- altitude: z.number().optional(),
1003
- enhancedAltitude: z.number().optional(),
1004
- speed: z.number().optional(),
1005
- enhancedSpeed: z.number().optional(),
1006
- distance: z.number().optional(),
1007
- heartRate: z.number().optional(),
1008
- cadence: z.number().optional(),
1009
- fractionalCadence: z.number().optional(),
1010
- power: z.number().optional(),
1011
- temperature: z.number().optional(),
1012
- verticalOscillation: z.number().optional(),
1013
- stanceTime: z.number().optional(),
1014
- stanceTimePercent: z.number().optional(),
1015
- stepLength: z.number().optional(),
1016
- compressedTimestamp: z.number().optional()
1017
- });
1018
1000
 
1019
1001
  // src/adapters/record/record.mapper.ts
1020
1002
  var mapFitRecordToKrd = (fit) => {
@@ -1051,6 +1033,26 @@ var mapFitRecordToKrd = (fit) => {
1051
1033
  if (fit.stepLength !== void 0) record.stepLength = fit.stepLength;
1052
1034
  return record;
1053
1035
  };
1036
+ var fitRecordSchema = z.object({
1037
+ timestamp: z.number(),
1038
+ positionLat: z.number().optional(),
1039
+ positionLong: z.number().optional(),
1040
+ altitude: z.number().optional(),
1041
+ enhancedAltitude: z.number().optional(),
1042
+ speed: z.number().optional(),
1043
+ enhancedSpeed: z.number().optional(),
1044
+ distance: z.number().optional(),
1045
+ heartRate: z.number().optional(),
1046
+ cadence: z.number().optional(),
1047
+ fractionalCadence: z.number().optional(),
1048
+ power: z.number().optional(),
1049
+ temperature: z.number().optional(),
1050
+ verticalOscillation: z.number().optional(),
1051
+ stanceTime: z.number().optional(),
1052
+ stanceTimePercent: z.number().optional(),
1053
+ stepLength: z.number().optional(),
1054
+ compressedTimestamp: z.number().optional()
1055
+ });
1054
1056
 
1055
1057
  // src/adapters/record/fit-to-krd-record.converter.ts
1056
1058
  var convertFitToKrdRecord = (data) => {
@@ -1070,6 +1072,30 @@ var convertFitToKrdRecord = (data) => {
1070
1072
  var convertFitToKrdRecords = (records) => {
1071
1073
  return records.map(convertFitToKrdRecord);
1072
1074
  };
1075
+
1076
+ // src/adapters/session/session.mapper.ts
1077
+ var mapFitSessionToKrd = (fit) => ({
1078
+ startTime: new Date(fit.startTime * 1e3).toISOString(),
1079
+ totalElapsedTime: fit.totalElapsedTime / 1e3,
1080
+ totalTimerTime: fit.totalTimerTime !== void 0 ? fit.totalTimerTime / 1e3 : void 0,
1081
+ totalDistance: fit.totalDistance,
1082
+ sport: String(fit.sport),
1083
+ subSport: fit.subSport ? mapSubSportToKrd(fit.subSport) : void 0,
1084
+ avgHeartRate: fit.avgHeartRate,
1085
+ maxHeartRate: fit.maxHeartRate,
1086
+ avgCadence: fit.avgCadence,
1087
+ maxCadence: fit.maxCadence,
1088
+ avgPower: fit.avgPower,
1089
+ maxPower: fit.maxPower,
1090
+ normalizedPower: fit.normalizedPower,
1091
+ trainingStressScore: fit.trainingStressScore,
1092
+ intensityFactor: fit.intensityFactor,
1093
+ totalCalories: fit.totalCalories,
1094
+ totalAscent: fit.totalAscent,
1095
+ totalDescent: fit.totalDescent,
1096
+ avgSpeed: fit.enhancedAvgSpeed ?? fit.avgSpeed,
1097
+ maxSpeed: fit.enhancedMaxSpeed ?? fit.maxSpeed
1098
+ });
1073
1099
  var fitSessionSchema = z.object({
1074
1100
  timestamp: z.number(),
1075
1101
  startTime: z.number(),
@@ -1098,30 +1124,6 @@ var fitSessionSchema = z.object({
1098
1124
  firstLapIndex: z.number().optional()
1099
1125
  });
1100
1126
 
1101
- // src/adapters/session/session.mapper.ts
1102
- var mapFitSessionToKrd = (fit) => ({
1103
- startTime: new Date(fit.startTime * 1e3).toISOString(),
1104
- totalElapsedTime: fit.totalElapsedTime / 1e3,
1105
- totalTimerTime: fit.totalTimerTime !== void 0 ? fit.totalTimerTime / 1e3 : void 0,
1106
- totalDistance: fit.totalDistance,
1107
- sport: String(fit.sport),
1108
- subSport: fit.subSport ? mapSubSportToKrd(fit.subSport) : void 0,
1109
- avgHeartRate: fit.avgHeartRate,
1110
- maxHeartRate: fit.maxHeartRate,
1111
- avgCadence: fit.avgCadence,
1112
- maxCadence: fit.maxCadence,
1113
- avgPower: fit.avgPower,
1114
- maxPower: fit.maxPower,
1115
- normalizedPower: fit.normalizedPower,
1116
- trainingStressScore: fit.trainingStressScore,
1117
- intensityFactor: fit.intensityFactor,
1118
- totalCalories: fit.totalCalories,
1119
- totalAscent: fit.totalAscent,
1120
- totalDescent: fit.totalDescent,
1121
- avgSpeed: fit.enhancedAvgSpeed ?? fit.avgSpeed,
1122
- maxSpeed: fit.enhancedMaxSpeed ?? fit.maxSpeed
1123
- });
1124
-
1125
1127
  // src/adapters/session/fit-to-krd-session.converter.ts
1126
1128
  var convertFitToKrdSession = (data) => {
1127
1129
  const fitSession = fitSessionSchema.parse(data);
@@ -1171,6 +1173,29 @@ var mapActivityFileToKRD = (messages, logger) => {
1171
1173
  }
1172
1174
  };
1173
1175
  };
1176
+ var validateMessages = (fileId, workoutMsg, messages, logger, options = {}) => {
1177
+ const { strict = true } = options;
1178
+ if (!fileId) {
1179
+ const message = "Missing required fileId message in FIT file";
1180
+ if (strict) {
1181
+ throw createFitParsingError(message);
1182
+ }
1183
+ logger.warn(message);
1184
+ }
1185
+ if (!workoutMsg) {
1186
+ const message = "Missing required workout message in FIT file";
1187
+ if (strict) {
1188
+ throw createFitParsingError(message);
1189
+ }
1190
+ logger.warn(message);
1191
+ }
1192
+ const workoutMessages = messages[fitMessageKeySchema.enum.workoutMesgs];
1193
+ if (workoutMessages && workoutMessages.length > 1) {
1194
+ logger.warn("Multiple workout messages found, using first one", {
1195
+ count: workoutMessages.length
1196
+ });
1197
+ }
1198
+ };
1174
1199
  var DEFAULT_SPORT = sportSchema.enum.cycling;
1175
1200
  var mapSportType = (fitSport) => {
1176
1201
  if (!fitSport) {
@@ -1206,16 +1231,6 @@ var mapCreatedTimestamp = (fileId) => {
1206
1231
  }
1207
1232
  return (/* @__PURE__ */ new Date()).toISOString();
1208
1233
  };
1209
- var FIT_LENGTH_UNIT_MAP = {
1210
- 0: "meters",
1211
- 1: "yards"
1212
- };
1213
- var mapLengthUnitToKrd = (fitUnit) => {
1214
- if (fitUnit === void 0) {
1215
- return lengthUnitSchema.enum.meters;
1216
- }
1217
- return FIT_LENGTH_UNIT_MAP[fitUnit] || lengthUnitSchema.enum.meters;
1218
- };
1219
1234
  var convertTimeDuration = (data) => {
1220
1235
  if (data.durationTime !== void 0) {
1221
1236
  return {
@@ -1807,6 +1822,16 @@ var buildRepetitionBlock = (step, workoutSteps, currentIndex) => {
1807
1822
  steps: repeatedSteps
1808
1823
  };
1809
1824
  };
1825
+ var FIT_LENGTH_UNIT_MAP = {
1826
+ 0: "meters",
1827
+ 1: "yards"
1828
+ };
1829
+ var mapLengthUnitToKrd = (fitUnit) => {
1830
+ if (fitUnit === void 0) {
1831
+ return lengthUnitSchema.enum.meters;
1832
+ }
1833
+ return FIT_LENGTH_UNIT_MAP[fitUnit] || lengthUnitSchema.enum.meters;
1834
+ };
1810
1835
 
1811
1836
  // src/adapters/workout/workout.mapper.ts
1812
1837
  var mapWorkout = (workoutMsg, workoutSteps, logger) => {
@@ -1830,29 +1855,6 @@ var mapWorkout = (workoutMsg, workoutSteps, logger) => {
1830
1855
  }
1831
1856
  return workout;
1832
1857
  };
1833
- var validateMessages = (fileId, workoutMsg, messages, logger, options = {}) => {
1834
- const { strict = true } = options;
1835
- if (!fileId) {
1836
- const message = "Missing required fileId message in FIT file";
1837
- if (strict) {
1838
- throw createFitParsingError(message);
1839
- }
1840
- logger.warn(message);
1841
- }
1842
- if (!workoutMsg) {
1843
- const message = "Missing required workout message in FIT file";
1844
- if (strict) {
1845
- throw createFitParsingError(message);
1846
- }
1847
- logger.warn(message);
1848
- }
1849
- const workoutMessages = messages[fitMessageKeySchema.enum.workoutMesgs];
1850
- if (workoutMessages && workoutMessages.length > 1) {
1851
- logger.warn("Multiple workout messages found, using first one", {
1852
- count: workoutMessages.length
1853
- });
1854
- }
1855
- };
1856
1858
 
1857
1859
  // src/adapters/messages/workout.mapper.ts
1858
1860
  var KRD_VERSION2 = "1.0";