@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 +254 -252
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,15 +1,8 @@
|
|
|
1
|
-
import { sportSchema, durationTypeSchema, createConsoleLogger, createFitParsingError, fileTypeSchema, workoutSchema, isRepetitionBlock, convertLengthToMeters, subSportSchema, lengthUnitSchema,
|
|
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";
|