@kaiord/tcx 4.0.0 → 4.3.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/README.md +1 -1
- package/dist/index.d.ts +20 -9
- package/dist/index.js +13 -11
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@kaiord/tcx)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
-
TCX format adapter for Kaiord
|
|
6
|
+
TCX format adapter for the Kaiord health & fitness data framework. Provides reading, writing, and XSD validation of Garmin Training Center XML files.
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
import { Logger,
|
|
1
|
+
import { Logger, TextReader, TextWriter } from '@kaiord/core';
|
|
2
2
|
|
|
3
|
-
type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
type TcxValidationResult = {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
errors: Array<{
|
|
6
|
+
path: string;
|
|
7
|
+
message: string;
|
|
8
|
+
}>;
|
|
7
9
|
};
|
|
8
|
-
|
|
10
|
+
type TcxValidator = (xmlString: string) => Promise<TcxValidationResult>;
|
|
9
11
|
|
|
10
|
-
declare const createFastXmlTcxReader: (logger: Logger) =>
|
|
11
|
-
declare const createFastXmlTcxWriter: (logger: Logger, validator: TcxValidator) =>
|
|
12
|
+
declare const createFastXmlTcxReader: (logger: Logger) => TextReader;
|
|
13
|
+
declare const createFastXmlTcxWriter: (logger: Logger, validator: TcxValidator) => TextWriter;
|
|
12
14
|
|
|
13
15
|
declare const createXsdTcxValidator: (logger: Logger) => TcxValidator;
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
/**
|
|
18
|
+
* @kaiord/tcx - TCX format adapter for Kaiord
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
declare const createTcxReader: (logger?: Logger) => TextReader;
|
|
22
|
+
declare const createTcxWriter: (logger?: Logger) => TextWriter;
|
|
23
|
+
declare const tcxReader: TextReader;
|
|
24
|
+
declare const tcxWriter: TextWriter;
|
|
25
|
+
|
|
26
|
+
export { type TcxValidationResult, type TcxValidator, createFastXmlTcxReader, createFastXmlTcxWriter, createTcxReader, createTcxWriter, createXsdTcxValidator, tcxReader, tcxWriter };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { createTcxParsingError, createTcxValidationError
|
|
1
|
+
import { createConsoleLogger, createTcxParsingError, createTcxValidationError } from '@kaiord/core';
|
|
2
2
|
import { XMLParser, XMLBuilder, XMLValidator } from 'fast-xml-parser';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
|
-
// src/
|
|
5
|
+
// src/index.ts
|
|
6
6
|
|
|
7
7
|
// src/adapters/workout/metadata-extractor.ts
|
|
8
8
|
var extractKaiordMetadata = (trainingCenterDatabase, workout) => {
|
|
@@ -707,17 +707,19 @@ var createXsdTcxValidator = (logger) => async (xmlString) => {
|
|
|
707
707
|
}
|
|
708
708
|
};
|
|
709
709
|
|
|
710
|
-
// src/
|
|
711
|
-
var
|
|
710
|
+
// src/index.ts
|
|
711
|
+
var createTcxReader = (logger) => {
|
|
712
712
|
const log = logger || createConsoleLogger();
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
713
|
+
return createFastXmlTcxReader(log);
|
|
714
|
+
};
|
|
715
|
+
var createTcxWriter = (logger) => {
|
|
716
|
+
const log = logger || createConsoleLogger();
|
|
717
|
+
const validator = createXsdTcxValidator(log);
|
|
718
|
+
return createFastXmlTcxWriter(log, validator);
|
|
719
719
|
};
|
|
720
|
+
var tcxReader = createTcxReader();
|
|
721
|
+
var tcxWriter = createTcxWriter();
|
|
720
722
|
|
|
721
|
-
export { createFastXmlTcxReader, createFastXmlTcxWriter,
|
|
723
|
+
export { createFastXmlTcxReader, createFastXmlTcxWriter, createTcxReader, createTcxWriter, createXsdTcxValidator, tcxReader, tcxWriter };
|
|
722
724
|
//# sourceMappingURL=index.js.map
|
|
723
725
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/workout/metadata-extractor.ts","../src/adapters/schemas/tcx-sport.ts","../src/adapters/duration/duration-kaiord-restorer.ts","../src/adapters/duration/duration-standard-converter.ts","../src/adapters/duration/duration.mapper.ts","../src/adapters/target/tcx-to-krd.mapper.ts","../src/adapters/workout/step-helpers.ts","../src/adapters/workout/step.converter.ts","../src/adapters/workout/workout.converter.ts","../src/adapters/workout/krd.converter.ts","../src/adapters/workout/metadata-builder.ts","../src/adapters/workout/duration-to-tcx-encoder.ts","../src/adapters/workout/target-to-tcx.converter.ts","../src/adapters/workout/step-to-tcx.converter.ts","../src/adapters/workout/tcx.converter.ts","../src/adapters/fast-xml-parser.ts","../src/adapters/xsd-validator.ts","../src/providers.ts"],"names":["createTcxParsingError","convertKRDToTcx"],"mappings":"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","file":"index.js","sourcesContent":["import type { KRD } from \"@kaiord/core\";\nimport type { Workout } from \"@kaiord/core\";\n\nexport const extractKaiordMetadata = (\n trainingCenterDatabase: Record<string, unknown>,\n workout: Workout\n): KRD[\"metadata\"] => {\n const metadata: KRD[\"metadata\"] = {\n created:\n (trainingCenterDatabase[\"@_kaiord:timeCreated\"] as string | undefined) ||\n new Date().toISOString(),\n sport: workout.sport,\n subSport: workout.subSport,\n };\n\n if (trainingCenterDatabase[\"@_kaiord:manufacturer\"]) {\n metadata.manufacturer = trainingCenterDatabase[\n \"@_kaiord:manufacturer\"\n ] as string;\n }\n if (trainingCenterDatabase[\"@_kaiord:product\"]) {\n metadata.product = trainingCenterDatabase[\"@_kaiord:product\"] as string;\n }\n if (trainingCenterDatabase[\"@_kaiord:serialNumber\"]) {\n const serialNumber = trainingCenterDatabase[\"@_kaiord:serialNumber\"];\n // Convert to string if it's a number (XML parser may parse as number)\n metadata.serialNumber =\n typeof serialNumber === \"number\"\n ? String(serialNumber)\n : (serialNumber as string);\n }\n\n return metadata;\n};\n","import { z } from \"zod\";\nimport type { Sport } from \"@kaiord/core\";\n\nexport const tcxSportSchema = z.enum([\"Running\", \"Biking\", \"Other\"]);\n\nexport type TcxSport = z.infer<typeof tcxSportSchema>;\n\nexport const TCX_TO_KRD_SPORT: Record<TcxSport, Sport> = {\n Running: \"running\",\n Biking: \"cycling\",\n Other: \"generic\",\n};\n\nexport const KRD_TO_TCX_SPORT: Record<Sport, TcxSport> = {\n running: \"Running\",\n cycling: \"Biking\",\n swimming: \"Other\",\n generic: \"Other\",\n};\n","import type { Duration } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\n\nconst restoreHeartRateLessThan = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const bpm = tcxDuration[\"@_kaiord:originalDurationBpm\"] as number | undefined;\n if (typeof bpm === \"number\") {\n logger.debug(\"Restoring heart_rate_less_than from kaiord attributes\", {\n bpm,\n });\n return { type: \"heart_rate_less_than\", bpm };\n }\n return null;\n};\n\nconst restorePowerLessThan = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const watts = tcxDuration[\"@_kaiord:originalDurationWatts\"] as\n | number\n | undefined;\n if (typeof watts === \"number\") {\n logger.debug(\"Restoring power_less_than from kaiord attributes\", {\n watts,\n });\n return { type: \"power_less_than\", watts };\n }\n return null;\n};\n\nconst restorePowerGreaterThan = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const watts = tcxDuration[\"@_kaiord:originalDurationWatts\"] as\n | number\n | undefined;\n if (typeof watts === \"number\") {\n logger.debug(\"Restoring power_greater_than from kaiord attributes\", {\n watts,\n });\n return { type: \"power_greater_than\", watts };\n }\n return null;\n};\n\nconst restoreCalories = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const calories = tcxDuration[\"@_kaiord:originalDurationCalories\"] as\n | number\n | undefined;\n if (typeof calories === \"number\") {\n logger.debug(\"Restoring calories from kaiord attributes\", {\n calories,\n });\n return { type: \"calories\", calories };\n }\n return null;\n};\n\nexport const restoreKaiordDuration = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const originalDurationType = tcxDuration[\"@_kaiord:originalDurationType\"] as\n | string\n | undefined;\n\n if (originalDurationType === \"heart_rate_less_than\") {\n return restoreHeartRateLessThan(tcxDuration, logger);\n }\n\n if (originalDurationType === \"power_less_than\") {\n return restorePowerLessThan(tcxDuration, logger);\n }\n\n if (originalDurationType === \"power_greater_than\") {\n return restorePowerGreaterThan(tcxDuration, logger);\n }\n\n if (originalDurationType === \"calories\") {\n return restoreCalories(tcxDuration, logger);\n }\n\n return null;\n};\n","import type { Duration } from \"@kaiord/core\";\n\nexport const convertStandardTcxDuration = (\n tcxDuration: Record<string, unknown>\n): Duration | null => {\n const durationType = tcxDuration[\"@_xsi:type\"] as string | undefined;\n\n if (durationType === \"Time_t\") {\n const seconds = tcxDuration.Seconds as number | undefined;\n if (typeof seconds === \"number\" && seconds > 0) {\n return { type: \"time\", seconds };\n }\n }\n\n if (durationType === \"Distance_t\") {\n const meters = tcxDuration.Meters as number | undefined;\n if (typeof meters === \"number\" && meters > 0) {\n return { type: \"distance\", meters };\n }\n }\n\n if (durationType === \"LapButton_t\") {\n return { type: \"open\" };\n }\n\n return null;\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { tcxDurationTypeSchema } from \"../schemas/tcx-duration\";\nimport { restoreKaiordDuration } from \"./duration-kaiord-restorer\";\nimport { convertStandardTcxDuration } from \"./duration-standard-converter\";\n\nexport type TcxDurationData = {\n durationType?: string;\n seconds?: number;\n meters?: number;\n};\n\nexport const mapTcxDuration = (data: TcxDurationData): Duration => {\n const result = tcxDurationTypeSchema.safeParse(data.durationType);\n\n if (!result.success) {\n return { type: durationTypeSchema.enum.open };\n }\n\n // Time duration\n if (\n result.data === tcxDurationTypeSchema.enum.Time &&\n data.seconds !== undefined\n ) {\n return {\n type: durationTypeSchema.enum.time,\n seconds: data.seconds,\n };\n }\n\n // Distance duration\n if (\n result.data === tcxDurationTypeSchema.enum.Distance &&\n data.meters !== undefined\n ) {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data.meters,\n };\n }\n\n // LapButton duration\n if (result.data === tcxDurationTypeSchema.enum.LapButton) {\n return {\n type: durationTypeSchema.enum.open,\n };\n }\n\n // Default to open for unsupported types (HeartRateAbove, HeartRateBelow, CaloriesBurned)\n // These will be handled by the converter and stored in extensions\n return { type: durationTypeSchema.enum.open };\n};\n\nexport const convertTcxDuration = (\n tcxDuration: Record<string, unknown> | undefined,\n logger: Logger\n): Duration | null => {\n if (!tcxDuration) {\n return null;\n }\n\n // First check for kaiord attributes to restore advanced duration types\n const kaiordDuration = restoreKaiordDuration(tcxDuration, logger);\n if (kaiordDuration) {\n return kaiordDuration;\n }\n\n // Then check for standard TCX duration types\n const standardDuration = convertStandardTcxDuration(tcxDuration);\n if (standardDuration) {\n return standardDuration;\n }\n\n const durationType = tcxDuration[\"@_xsi:type\"] as string | undefined;\n logger.warn(\"Unsupported duration type\", { durationType });\n return null;\n};\n\n// KRD → TCX duration mappers\n\nexport type TcxDurationElement = Record<string, unknown>;\n\nexport const mapTimeDurationToTcx = (seconds: number): TcxDurationElement => {\n return {\n \"@_xsi:type\": \"Time_t\",\n Seconds: seconds,\n };\n};\n\nexport const mapDistanceDurationToTcx = (\n meters: number\n): TcxDurationElement => {\n return {\n \"@_xsi:type\": \"Distance_t\",\n Meters: meters,\n };\n};\n\nexport const mapOpenDurationToTcx = (): TcxDurationElement => {\n return {\n \"@_xsi:type\": \"LapButton_t\",\n };\n};\n","import type { Target } from \"@kaiord/core\";\nimport { targetTypeSchema, type TargetType } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { tcxTargetTypeSchema } from \"../schemas/tcx-target\";\n\nexport const mapTargetType = (\n tcxTargetType: string | undefined\n): TargetType => {\n if (tcxTargetType === tcxTargetTypeSchema.enum.HeartRate)\n return targetTypeSchema.enum.heart_rate;\n if (tcxTargetType === tcxTargetTypeSchema.enum.Speed)\n return targetTypeSchema.enum.pace;\n if (tcxTargetType === tcxTargetTypeSchema.enum.Cadence)\n return targetTypeSchema.enum.cadence;\n if (tcxTargetType === tcxTargetTypeSchema.enum.None)\n return targetTypeSchema.enum.open;\n return targetTypeSchema.enum.open;\n};\n\nconst convertHeartRateTarget = (\n heartRateZone: Record<string, unknown> | undefined\n): Target | null => {\n if (!heartRateZone) return null;\n\n const zoneType = heartRateZone[\"@_xsi:type\"] as string | undefined;\n\n if (zoneType === \"PredefinedHeartRateZone_t\") {\n const zoneNumber = heartRateZone.Number as number | undefined;\n if (typeof zoneNumber === \"number\") {\n return {\n type: \"heart_rate\",\n value: { unit: \"zone\", value: zoneNumber },\n };\n }\n }\n\n if (zoneType === \"CustomHeartRateZone_t\") {\n const low = heartRateZone.Low as number | undefined;\n const high = heartRateZone.High as number | undefined;\n if (typeof low === \"number\" && typeof high === \"number\") {\n return {\n type: \"heart_rate\",\n value: { unit: \"range\", min: low, max: high },\n };\n }\n }\n\n return null;\n};\n\nexport const convertTcxTarget = (\n tcxTarget: Record<string, unknown> | undefined,\n logger: Logger\n): Target | null => {\n if (!tcxTarget) {\n return { type: \"open\" };\n }\n\n const targetType = tcxTarget[\"@_xsi:type\"] as string | undefined;\n\n if (targetType === \"None_t\") {\n return { type: \"open\" };\n }\n\n if (targetType === \"HeartRate_t\") {\n const heartRateZone = tcxTarget.HeartRateZone as\n | Record<string, unknown>\n | undefined;\n const result = convertHeartRateTarget(heartRateZone);\n if (result) return result;\n }\n\n logger.warn(\"Unsupported target type\", { targetType });\n return { type: \"open\" };\n};\n","import type { Logger } from \"@kaiord/core\";\n\nexport const extractIntensity = (\n tcxStep: Record<string, unknown>\n): \"warmup\" | \"active\" | \"cooldown\" | \"rest\" | undefined => {\n const raw = tcxStep.Intensity as string | undefined;\n const value = raw?.toLowerCase();\n\n switch (value) {\n case \"warmup\":\n case \"active\":\n case \"cooldown\":\n case \"rest\":\n return value;\n case \"resting\":\n return \"rest\";\n default:\n return undefined;\n }\n};\n\nexport const extractPowerFromExtensions = (\n extensions: Record<string, unknown>,\n logger: Logger\n): number | undefined => {\n if (extensions.TPX) {\n const tpx = extensions.TPX as Record<string, unknown>;\n if (typeof tpx.Watts === \"number\") {\n logger.debug(\"Found power data in TCX extensions\", {\n watts: tpx.Watts,\n });\n return tpx.Watts;\n }\n }\n\n if (extensions.Power && typeof extensions.Power === \"number\") {\n logger.debug(\"Found power data in TCX extensions\", {\n watts: extensions.Power,\n });\n return extensions.Power;\n }\n\n return undefined;\n};\n\nexport const extractExtensions = (\n tcxStep: Record<string, unknown>,\n logger: Logger\n): Record<string, unknown> | undefined => {\n const extensions = tcxStep.Extensions as Record<string, unknown> | undefined;\n if (!extensions) {\n return undefined;\n }\n\n logger.debug(\"Extracting TCX extensions from step\");\n return { ...extensions };\n};\n","import type { Duration } from \"@kaiord/core\";\nimport type { Target } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertTcxDuration } from \"../duration/duration.mapper\";\nimport { convertTcxTarget } from \"../target/target.mapper\";\nimport {\n extractExtensions,\n extractIntensity,\n extractPowerFromExtensions,\n} from \"./step-helpers\";\n\nconst convertTargetWithExtensions = (\n tcxStep: Record<string, unknown>,\n extensions: Record<string, unknown> | undefined,\n logger: Logger\n): Target | null => {\n const target = convertTcxTarget(\n tcxStep.Target as Record<string, unknown> | undefined,\n logger\n );\n if (!target) return null;\n\n if (target.type === \"open\" && extensions) {\n const powerWatts = extractPowerFromExtensions(extensions, logger);\n if (powerWatts !== undefined) {\n logger.debug(\"Converting open target to power target from extensions\", {\n watts: powerWatts,\n });\n return {\n type: \"power\",\n value: {\n unit: \"watts\",\n value: powerWatts,\n },\n };\n }\n }\n\n return target;\n};\n\nconst buildWorkoutStep = (\n stepIndex: number,\n name: string | undefined,\n duration: Duration,\n target: Target,\n tcxStep: Record<string, unknown>,\n extensions: Record<string, unknown> | undefined\n): WorkoutStep => {\n const step: WorkoutStep = {\n stepIndex,\n name,\n durationType: duration.type,\n duration,\n targetType: target.type,\n target,\n intensity: extractIntensity(tcxStep),\n };\n\n return extensions ? { ...step, extensions: { tcx: extensions } } : step;\n};\n\nexport const convertTcxStep = (\n tcxStep: Record<string, unknown>,\n stepIndex: number,\n logger: Logger\n): WorkoutStep | null => {\n logger.debug(\"Converting TCX step\", { stepIndex });\n\n const stepType = tcxStep[\"@_xsi:type\"] as string | undefined;\n if (stepType === \"Repeat_t\") {\n logger.warn(\"Repetition blocks not yet supported\", { stepIndex });\n return null;\n }\n\n const duration = convertTcxDuration(\n tcxStep.Duration as Record<string, unknown> | undefined,\n logger\n );\n if (!duration) {\n logger.warn(\"Step has no valid duration, skipping\", { stepIndex });\n return null;\n }\n\n const extensions = extractExtensions(tcxStep, logger);\n const target = convertTargetWithExtensions(tcxStep, extensions, logger);\n if (!target) {\n logger.warn(\"Step has no valid target, skipping\", { stepIndex });\n return null;\n }\n\n return buildWorkoutStep(\n stepIndex,\n tcxStep.Name as string | undefined,\n duration,\n target,\n tcxStep,\n extensions\n );\n};\n","import type { Workout, WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { TCX_TO_KRD_SPORT, tcxSportSchema } from \"../schemas/tcx-sport\";\nimport { convertTcxStep } from \"./step.converter\";\n\nconst extractWorkoutExtensions = (\n tcxWorkout: Record<string, unknown>,\n logger: Logger\n): Record<string, unknown> | undefined => {\n const extensions = tcxWorkout.Extensions as\n | Record<string, unknown>\n | undefined;\n if (!extensions) {\n return undefined;\n }\n\n logger.debug(\"Extracting TCX extensions from workout\");\n\n // Store the raw TCX extensions for round-trip preservation\n return { ...extensions };\n};\n\nconst convertSteps = (\n tcxSteps: unknown,\n logger: Logger\n): Array<WorkoutStep> => {\n const steps: Array<WorkoutStep> = [];\n\n if (!tcxSteps) return steps;\n\n const stepArray = Array.isArray(tcxSteps) ? tcxSteps : [tcxSteps];\n let stepIndex = 0;\n\n for (const tcxStep of stepArray) {\n const step = convertTcxStep(\n tcxStep as Record<string, unknown>,\n stepIndex,\n logger\n );\n if (step) {\n steps.push(step);\n stepIndex++;\n }\n }\n\n return steps;\n};\n\nexport const convertTcxWorkout = (\n tcxWorkout: Record<string, unknown>,\n logger: Logger\n): Workout => {\n logger.debug(\"Converting TCX workout\");\n\n const sportAttr = tcxWorkout[\"@_Sport\"] as string | undefined;\n const sportResult = tcxSportSchema.safeParse(sportAttr);\n const sport = sportResult.success\n ? TCX_TO_KRD_SPORT[sportResult.data]\n : \"generic\";\n\n const name = tcxWorkout.Name as string | undefined;\n const steps = convertSteps(tcxWorkout.Step, logger);\n const extensions = extractWorkoutExtensions(tcxWorkout, logger);\n\n const workout: Workout = {\n name,\n sport,\n steps,\n };\n\n if (extensions) {\n return {\n ...workout,\n extensions: {\n tcx: extensions,\n },\n };\n }\n\n return workout;\n};\n","import type { KRD } from \"@kaiord/core\";\nimport { createTcxParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { extractKaiordMetadata } from \"./metadata-extractor\";\nimport { convertTcxWorkout } from \"./workout.converter\";\n\nconst extractTcxExtensions = (\n trainingCenterDatabase: Record<string, unknown>,\n logger: Logger\n): Record<string, unknown> | undefined => {\n const extensions = trainingCenterDatabase.Extensions as\n | Record<string, unknown>\n | undefined;\n if (!extensions) {\n return undefined;\n }\n\n logger.debug(\"Extracting TCX extensions from TrainingCenterDatabase\");\n\n // Store the raw TCX extensions for round-trip preservation\n return { ...extensions };\n};\n\nconst extractWorkoutData = (\n trainingCenterDatabase: Record<string, unknown>\n): Record<string, unknown> => {\n const workouts = trainingCenterDatabase.Workouts as\n | Record<string, unknown>\n | undefined;\n\n if (!workouts) {\n throw createTcxParsingError(\"No workouts found in TCX file\");\n }\n\n const workoutArray = Array.isArray(workouts.Workout)\n ? workouts.Workout\n : [workouts.Workout];\n\n if (workoutArray.length === 0) {\n throw createTcxParsingError(\"No workout data found in TCX file\");\n }\n\n return workoutArray[0] as Record<string, unknown>;\n};\n\nexport const convertTcxToKRD = (\n tcxData: Record<string, unknown>,\n logger: Logger\n): KRD => {\n logger.debug(\"Converting TCX to KRD\");\n\n const trainingCenterDatabase = tcxData.TrainingCenterDatabase as Record<\n string,\n unknown\n >;\n\n const tcxWorkout = extractWorkoutData(trainingCenterDatabase);\n const workout = convertTcxWorkout(tcxWorkout, logger);\n const tcxExtensions = extractTcxExtensions(trainingCenterDatabase, logger);\n const metadata = extractKaiordMetadata(trainingCenterDatabase, workout);\n\n const krd: KRD = {\n version: \"1.0\",\n type: \"structured_workout\",\n metadata,\n extensions: {\n structured_workout: workout,\n ...(tcxExtensions && { tcx: tcxExtensions }),\n },\n };\n\n logger.debug(\"TCX to KRD conversion complete\");\n return krd;\n};\n","import type { KRD } from \"@kaiord/core\";\n\nexport const addKaiordMetadata = (\n trainingCenterDatabase: Record<string, unknown>,\n krd: KRD\n): void => {\n if (krd.metadata.created) {\n trainingCenterDatabase[\"@_kaiord:timeCreated\"] = krd.metadata.created;\n }\n if (krd.metadata.manufacturer) {\n trainingCenterDatabase[\"@_kaiord:manufacturer\"] = krd.metadata.manufacturer;\n }\n if (krd.metadata.product) {\n trainingCenterDatabase[\"@_kaiord:product\"] = krd.metadata.product;\n }\n if (krd.metadata.serialNumber) {\n trainingCenterDatabase[\"@_kaiord:serialNumber\"] = krd.metadata.serialNumber;\n }\n};\n","import type { Duration } from \"@kaiord/core\";\n\nconst addKaiordAttributes = (\n tcxDuration: Record<string, unknown>,\n duration: Duration\n): void => {\n if (duration.type === \"heart_rate_less_than\" && duration.bpm !== undefined) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"heart_rate_less_than\";\n tcxDuration[\"@_kaiord:originalDurationBpm\"] = duration.bpm;\n } else if (\n duration.type === \"power_less_than\" &&\n duration.watts !== undefined\n ) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"power_less_than\";\n tcxDuration[\"@_kaiord:originalDurationWatts\"] = duration.watts;\n } else if (\n duration.type === \"power_greater_than\" &&\n duration.watts !== undefined\n ) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"power_greater_than\";\n tcxDuration[\"@_kaiord:originalDurationWatts\"] = duration.watts;\n } else if (duration.type === \"calories\" && duration.calories !== undefined) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"calories\";\n tcxDuration[\"@_kaiord:originalDurationCalories\"] = duration.calories;\n }\n};\n\nexport const convertDurationToTcx = (step: {\n duration: Duration;\n}): Record<string, unknown> => {\n const duration = step.duration;\n\n // Standard TCX duration types\n if (duration.type === \"time\") {\n return {\n \"@_xsi:type\": \"Time_t\",\n Seconds: duration.seconds,\n };\n }\n\n if (duration.type === \"distance\") {\n return {\n \"@_xsi:type\": \"Distance_t\",\n Meters: duration.meters,\n };\n }\n\n // For advanced duration types not natively supported by TCX,\n // use LapButton_t and preserve original type in kaiord attributes\n const tcxDuration: Record<string, unknown> = {\n \"@_xsi:type\": \"LapButton_t\",\n };\n\n addKaiordAttributes(tcxDuration, duration);\n\n return tcxDuration;\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\n\nexport const convertHeartRateToTcx = (value: {\n unit: string;\n value?: number;\n min?: number;\n max?: number;\n}): Record<string, unknown> => {\n if (value.unit === \"zone\") {\n return {\n \"@_xsi:type\": \"HeartRate_t\",\n HeartRateZone: {\n \"@_xsi:type\": \"PredefinedHeartRateZone_t\",\n Number: value.value,\n },\n };\n }\n\n if (value.unit === \"bpm\" || value.unit === \"range\") {\n const min = \"min\" in value ? value.min : value.value;\n const max = \"max\" in value ? value.max : value.value;\n return {\n \"@_xsi:type\": \"HeartRate_t\",\n HeartRateZone: {\n \"@_xsi:type\": \"CustomHeartRateZone_t\",\n Low: min,\n High: max,\n },\n };\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n\nexport const convertPaceToTcx = (value: {\n unit: string;\n value?: number;\n min?: number;\n max?: number;\n}): Record<string, unknown> => {\n if (value.unit === \"meters_per_second\" || value.unit === \"range\") {\n const min = \"min\" in value ? value.min : value.value;\n const max = \"max\" in value ? value.max : value.value;\n return {\n \"@_xsi:type\": \"Speed_t\",\n SpeedZone: {\n \"@_xsi:type\": \"CustomSpeedZone_t\",\n LowInMetersPerSecond: min,\n HighInMetersPerSecond: max,\n },\n };\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n\nexport const convertCadenceToTcx = (value: {\n unit: string;\n value?: number;\n min?: number;\n max?: number;\n}): Record<string, unknown> => {\n if (value.unit === \"rpm\" || value.unit === \"range\") {\n const min = \"min\" in value ? value.min : value.value;\n const max = \"max\" in value ? value.max : value.value;\n return {\n \"@_xsi:type\": \"Cadence_t\",\n CadenceZone: {\n \"@_xsi:type\": \"CustomCadenceZone_t\",\n Low: min,\n High: max,\n },\n };\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n\nexport const convertTargetToTcx = (\n step: WorkoutStep\n): Record<string, unknown> => {\n if (step.target.type === \"open\") {\n return { \"@_xsi:type\": \"None_t\" };\n }\n\n if (step.target.type === \"heart_rate\") {\n const value = step.target.value;\n if (value && \"unit\" in value) {\n return convertHeartRateToTcx(value);\n }\n }\n\n if (step.target.type === \"pace\") {\n const value = step.target.value;\n if (value && \"unit\" in value) {\n return convertPaceToTcx(value);\n }\n }\n\n if (step.target.type === \"cadence\") {\n const value = step.target.value;\n if (value && \"unit\" in value) {\n return convertCadenceToTcx(value);\n }\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertDurationToTcx } from \"./duration-to-tcx-encoder\";\nimport { convertTargetToTcx } from \"./target-to-tcx.converter\";\n\nconst capitalizeFirst = (str: string): string => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\nconst addPowerExtensions = (\n step: WorkoutStep,\n tcxStep: Record<string, unknown>,\n logger: Logger\n): void => {\n if (step.target.type === \"power\") {\n logger.debug(\"Encoding power target to TCX extensions\", {\n stepIndex: step.stepIndex,\n });\n const powerValue = step.target.value;\n if (powerValue && \"unit\" in powerValue && powerValue.unit === \"watts\") {\n tcxStep.Extensions = {\n TPX: {\n \"@_xmlns\": \"http://www.garmin.com/xmlschemas/ActivityExtension/v2\",\n Watts: powerValue.value,\n },\n };\n }\n }\n};\n\nexport const convertStepToTcx = (\n step: WorkoutStep,\n index: number,\n logger: Logger\n): Record<string, unknown> => {\n logger.debug(\"Converting step to TCX\", { stepIndex: step.stepIndex });\n\n const tcxStep: Record<string, unknown> = {\n \"@_xsi:type\": \"Step_t\",\n StepId: index + 1,\n };\n\n if (step.name) {\n tcxStep.Name = step.name;\n }\n\n tcxStep.Duration = convertDurationToTcx(step);\n\n if (step.intensity) {\n tcxStep.Intensity = capitalizeFirst(step.intensity);\n }\n\n tcxStep.Target = convertTargetToTcx(step);\n\n if (step.extensions?.tcx) {\n logger.debug(\"Restoring step-level TCX extensions\", {\n stepIndex: step.stepIndex,\n });\n tcxStep.Extensions = step.extensions.tcx;\n } else {\n addPowerExtensions(step, tcxStep, logger);\n }\n\n return tcxStep;\n};\n","import type { KRD } from \"@kaiord/core\";\nimport type { Workout, WorkoutStep } from \"@kaiord/core\";\nimport { createTcxParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { KRD_TO_TCX_SPORT } from \"../schemas/tcx-sport\";\nimport { addKaiordMetadata } from \"./metadata-builder\";\nimport { convertStepToTcx } from \"./step-to-tcx.converter\";\n\nconst buildTcxWorkout = (\n workout: Workout,\n logger: Logger\n): Record<string, unknown> => {\n const tcxSport =\n KRD_TO_TCX_SPORT[workout.sport as keyof typeof KRD_TO_TCX_SPORT] || \"Other\";\n\n const tcxSteps = workout.steps.map((step, index) =>\n convertStepToTcx(step as WorkoutStep, index, logger)\n );\n\n const tcxWorkout: Record<string, unknown> = {\n \"@_Sport\": tcxSport,\n Name: workout.name,\n Step: tcxSteps,\n };\n\n if (workout.extensions?.tcx) {\n logger.debug(\"Restoring workout-level TCX extensions\");\n tcxWorkout.Extensions = workout.extensions.tcx;\n }\n\n return tcxWorkout;\n};\n\nconst buildTrainingCenterDatabase = (\n tcxWorkout: Record<string, unknown>,\n krd: KRD,\n logger: Logger\n): Record<string, unknown> => {\n const trainingCenterDatabase: Record<string, unknown> = {\n \"@_xmlns\": \"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2\",\n \"@_xmlns:xsi\": \"http://www.w3.org/2001/XMLSchema-instance\",\n \"@_xmlns:kaiord\": \"http://kaiord.dev/tcx-extensions/1.0\",\n Workouts: {\n Workout: tcxWorkout,\n },\n };\n\n addKaiordMetadata(trainingCenterDatabase, krd);\n\n if (krd.extensions?.tcx) {\n logger.debug(\"Restoring TrainingCenterDatabase-level TCX extensions\");\n trainingCenterDatabase.Extensions = krd.extensions.tcx;\n }\n\n return trainingCenterDatabase;\n};\n\nexport const convertKRDToTcx = (krd: KRD, logger: Logger): unknown => {\n logger.debug(\"Converting KRD to TCX structure\");\n\n if (!krd.extensions?.structured_workout) {\n throw createTcxParsingError(\n \"KRD does not contain workout data in extensions\"\n );\n }\n\n const workout = krd.extensions.structured_workout as Workout;\n const tcxWorkout = buildTcxWorkout(workout, logger);\n const trainingCenterDatabase = buildTrainingCenterDatabase(\n tcxWorkout,\n krd,\n logger\n );\n\n return {\n TrainingCenterDatabase: trainingCenterDatabase,\n };\n};\n","import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport type { KRD } from \"@kaiord/core\";\nimport { createTcxParsingError, createTcxValidationError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport type { TcxReader } from \"@kaiord/core\";\nimport type { TcxValidator } from \"@kaiord/core\";\nimport type { TcxWriter } from \"@kaiord/core\";\nimport { convertTcxToKRD } from \"./workout/krd.converter\";\nimport { convertKRDToTcx as convertKRDToTcxStructure } from \"./workout/tcx.converter\";\n\nexport const createFastXmlTcxReader =\n (logger: Logger): TcxReader =>\n async (xmlString: string): Promise<KRD> => {\n logger.debug(\"Parsing TCX file\", { xmlLength: xmlString.length });\n\n let tcxData: unknown;\n try {\n const parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: true,\n });\n\n tcxData = parser.parse(xmlString);\n } catch (error) {\n logger.error(\"Failed to parse TCX XML\", { error });\n throw createTcxParsingError(\"Failed to parse TCX file\", error);\n }\n\n if (\n !tcxData ||\n typeof tcxData !== \"object\" ||\n !(\"TrainingCenterDatabase\" in tcxData)\n ) {\n const error = createTcxParsingError(\n \"Invalid TCX format: missing TrainingCenterDatabase element\"\n );\n logger.error(\"Invalid TCX structure\", { error });\n throw error;\n }\n\n logger.info(\"TCX file parsed successfully\");\n\n return convertTcxToKRD(tcxData, logger);\n };\n\nexport const createFastXmlTcxWriter =\n (logger: Logger, validator: TcxValidator): TcxWriter =>\n async (krd: KRD): Promise<string> => {\n logger.debug(\"Encoding KRD to TCX\");\n\n let tcxData: unknown;\n try {\n tcxData = convertKRDToTcx(krd, logger);\n } catch (error) {\n logger.error(\"Failed to convert KRD to TCX structure\", { error });\n throw createTcxParsingError(\"Failed to convert KRD to TCX\", error);\n }\n\n let xmlString: string;\n try {\n const builder = new XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n format: true,\n indentBy: \" \",\n });\n\n xmlString = builder.build(tcxData);\n } catch (error) {\n logger.error(\"Failed to build TCX XML\", { error });\n throw createTcxParsingError(\"Failed to build TCX XML\", error);\n }\n\n logger.debug(\"Validating generated TCX against XSD\");\n\n const validationResult = await validator(xmlString);\n if (!validationResult.valid) {\n logger.error(\"Generated TCX does not conform to XSD schema\", {\n errors: validationResult.errors,\n });\n throw createTcxValidationError(\n \"Generated TCX file does not conform to XSD schema\",\n validationResult.errors.map((err) => ({\n field: err.path,\n message: err.message,\n }))\n );\n }\n\n logger.info(\"KRD encoded to TCX successfully\");\n return xmlString;\n };\n\nconst convertKRDToTcx = (krd: KRD, logger: Logger): unknown => {\n return convertKRDToTcxStructure(krd, logger);\n};\n","import { XMLValidator } from \"fast-xml-parser\";\nimport type { Logger } from \"@kaiord/core\";\nimport type { TcxValidationResult, TcxValidator } from \"@kaiord/core\";\n\nexport const createXsdTcxValidator =\n (logger: Logger): TcxValidator =>\n async (xmlString: string): Promise<TcxValidationResult> => {\n try {\n logger.debug(\"Validating TCX XML structure\");\n\n // Validate XML structure using fast-xml-parser\n const xmlValidation = XMLValidator.validate(xmlString, {\n allowBooleanAttributes: true,\n });\n\n if (xmlValidation !== true) {\n logger.warn(\"TCX XML validation failed\", {\n error: xmlValidation.err,\n });\n\n return {\n valid: false,\n errors: [\n {\n path: `line ${xmlValidation.err.line}`,\n message: `XML validation failed: ${xmlValidation.err.msg}`,\n },\n ],\n };\n }\n\n logger.info(\"TCX XML structure is valid\");\n return { valid: true, errors: [] };\n } catch (error) {\n logger.error(\"TCX validation failed\", { error });\n\n return {\n valid: false,\n errors: [\n {\n path: \"root\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n ],\n };\n }\n };\n","import type { Logger, TcxReader, TcxValidator, TcxWriter } from \"@kaiord/core\";\nimport { createConsoleLogger } from \"@kaiord/core\";\nimport {\n createFastXmlTcxReader,\n createFastXmlTcxWriter,\n} from \"./adapters/fast-xml-parser\";\nimport { createXsdTcxValidator } from \"./adapters/xsd-validator\";\n\nexport type TcxProviders = {\n tcxReader: TcxReader;\n tcxWriter: TcxWriter;\n tcxValidator: TcxValidator;\n};\n\nexport const createTcxProviders = (logger?: Logger): TcxProviders => {\n const log = logger || createConsoleLogger();\n const tcxValidator = createXsdTcxValidator(log);\n\n return {\n tcxReader: createFastXmlTcxReader(log),\n tcxWriter: createFastXmlTcxWriter(log, tcxValidator),\n tcxValidator,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/workout/metadata-extractor.ts","../src/adapters/schemas/tcx-sport.ts","../src/adapters/duration/duration-kaiord-restorer.ts","../src/adapters/duration/duration-standard-converter.ts","../src/adapters/duration/duration.mapper.ts","../src/adapters/target/tcx-to-krd.mapper.ts","../src/adapters/workout/step-helpers.ts","../src/adapters/workout/step.converter.ts","../src/adapters/workout/workout.converter.ts","../src/adapters/workout/krd.converter.ts","../src/adapters/workout/metadata-builder.ts","../src/adapters/workout/duration-to-tcx-encoder.ts","../src/adapters/workout/target-to-tcx.converter.ts","../src/adapters/workout/step-to-tcx.converter.ts","../src/adapters/workout/tcx.converter.ts","../src/adapters/fast-xml-parser.ts","../src/adapters/xsd-validator.ts","../src/index.ts"],"names":["createTcxParsingError","convertKRDToTcx"],"mappings":"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","file":"index.js","sourcesContent":["import type { KRD } from \"@kaiord/core\";\nimport type { Workout } from \"@kaiord/core\";\n\nexport const extractKaiordMetadata = (\n trainingCenterDatabase: Record<string, unknown>,\n workout: Workout\n): KRD[\"metadata\"] => {\n const metadata: KRD[\"metadata\"] = {\n created:\n (trainingCenterDatabase[\"@_kaiord:timeCreated\"] as string | undefined) ||\n new Date().toISOString(),\n sport: workout.sport,\n subSport: workout.subSport,\n };\n\n if (trainingCenterDatabase[\"@_kaiord:manufacturer\"]) {\n metadata.manufacturer = trainingCenterDatabase[\n \"@_kaiord:manufacturer\"\n ] as string;\n }\n if (trainingCenterDatabase[\"@_kaiord:product\"]) {\n metadata.product = trainingCenterDatabase[\"@_kaiord:product\"] as string;\n }\n if (trainingCenterDatabase[\"@_kaiord:serialNumber\"]) {\n const serialNumber = trainingCenterDatabase[\"@_kaiord:serialNumber\"];\n // Convert to string if it's a number (XML parser may parse as number)\n metadata.serialNumber =\n typeof serialNumber === \"number\"\n ? String(serialNumber)\n : (serialNumber as string);\n }\n\n return metadata;\n};\n","import { z } from \"zod\";\nimport type { Sport } from \"@kaiord/core\";\n\nexport const tcxSportSchema = z.enum([\"Running\", \"Biking\", \"Other\"]);\n\nexport type TcxSport = z.infer<typeof tcxSportSchema>;\n\nexport const TCX_TO_KRD_SPORT: Record<TcxSport, Sport> = {\n Running: \"running\",\n Biking: \"cycling\",\n Other: \"generic\",\n};\n\nexport const KRD_TO_TCX_SPORT: Record<Sport, TcxSport> = {\n running: \"Running\",\n cycling: \"Biking\",\n swimming: \"Other\",\n generic: \"Other\",\n};\n","import type { Duration } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\n\nconst restoreHeartRateLessThan = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const bpm = tcxDuration[\"@_kaiord:originalDurationBpm\"] as number | undefined;\n if (typeof bpm === \"number\") {\n logger.debug(\"Restoring heart_rate_less_than from kaiord attributes\", {\n bpm,\n });\n return { type: \"heart_rate_less_than\", bpm };\n }\n return null;\n};\n\nconst restorePowerLessThan = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const watts = tcxDuration[\"@_kaiord:originalDurationWatts\"] as\n | number\n | undefined;\n if (typeof watts === \"number\") {\n logger.debug(\"Restoring power_less_than from kaiord attributes\", {\n watts,\n });\n return { type: \"power_less_than\", watts };\n }\n return null;\n};\n\nconst restorePowerGreaterThan = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const watts = tcxDuration[\"@_kaiord:originalDurationWatts\"] as\n | number\n | undefined;\n if (typeof watts === \"number\") {\n logger.debug(\"Restoring power_greater_than from kaiord attributes\", {\n watts,\n });\n return { type: \"power_greater_than\", watts };\n }\n return null;\n};\n\nconst restoreCalories = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const calories = tcxDuration[\"@_kaiord:originalDurationCalories\"] as\n | number\n | undefined;\n if (typeof calories === \"number\") {\n logger.debug(\"Restoring calories from kaiord attributes\", {\n calories,\n });\n return { type: \"calories\", calories };\n }\n return null;\n};\n\nexport const restoreKaiordDuration = (\n tcxDuration: Record<string, unknown>,\n logger: Logger\n): Duration | null => {\n const originalDurationType = tcxDuration[\"@_kaiord:originalDurationType\"] as\n | string\n | undefined;\n\n if (originalDurationType === \"heart_rate_less_than\") {\n return restoreHeartRateLessThan(tcxDuration, logger);\n }\n\n if (originalDurationType === \"power_less_than\") {\n return restorePowerLessThan(tcxDuration, logger);\n }\n\n if (originalDurationType === \"power_greater_than\") {\n return restorePowerGreaterThan(tcxDuration, logger);\n }\n\n if (originalDurationType === \"calories\") {\n return restoreCalories(tcxDuration, logger);\n }\n\n return null;\n};\n","import type { Duration } from \"@kaiord/core\";\n\nexport const convertStandardTcxDuration = (\n tcxDuration: Record<string, unknown>\n): Duration | null => {\n const durationType = tcxDuration[\"@_xsi:type\"] as string | undefined;\n\n if (durationType === \"Time_t\") {\n const seconds = tcxDuration.Seconds as number | undefined;\n if (typeof seconds === \"number\" && seconds > 0) {\n return { type: \"time\", seconds };\n }\n }\n\n if (durationType === \"Distance_t\") {\n const meters = tcxDuration.Meters as number | undefined;\n if (typeof meters === \"number\" && meters > 0) {\n return { type: \"distance\", meters };\n }\n }\n\n if (durationType === \"LapButton_t\") {\n return { type: \"open\" };\n }\n\n return null;\n};\n","import { durationTypeSchema, type Duration } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { tcxDurationTypeSchema } from \"../schemas/tcx-duration\";\nimport { restoreKaiordDuration } from \"./duration-kaiord-restorer\";\nimport { convertStandardTcxDuration } from \"./duration-standard-converter\";\n\nexport type TcxDurationData = {\n durationType?: string;\n seconds?: number;\n meters?: number;\n};\n\nexport const mapTcxDuration = (data: TcxDurationData): Duration => {\n const result = tcxDurationTypeSchema.safeParse(data.durationType);\n\n if (!result.success) {\n return { type: durationTypeSchema.enum.open };\n }\n\n // Time duration\n if (\n result.data === tcxDurationTypeSchema.enum.Time &&\n data.seconds !== undefined\n ) {\n return {\n type: durationTypeSchema.enum.time,\n seconds: data.seconds,\n };\n }\n\n // Distance duration\n if (\n result.data === tcxDurationTypeSchema.enum.Distance &&\n data.meters !== undefined\n ) {\n return {\n type: durationTypeSchema.enum.distance,\n meters: data.meters,\n };\n }\n\n // LapButton duration\n if (result.data === tcxDurationTypeSchema.enum.LapButton) {\n return {\n type: durationTypeSchema.enum.open,\n };\n }\n\n // Default to open for unsupported types (HeartRateAbove, HeartRateBelow, CaloriesBurned)\n // These will be handled by the converter and stored in extensions\n return { type: durationTypeSchema.enum.open };\n};\n\nexport const convertTcxDuration = (\n tcxDuration: Record<string, unknown> | undefined,\n logger: Logger\n): Duration | null => {\n if (!tcxDuration) {\n return null;\n }\n\n // First check for kaiord attributes to restore advanced duration types\n const kaiordDuration = restoreKaiordDuration(tcxDuration, logger);\n if (kaiordDuration) {\n return kaiordDuration;\n }\n\n // Then check for standard TCX duration types\n const standardDuration = convertStandardTcxDuration(tcxDuration);\n if (standardDuration) {\n return standardDuration;\n }\n\n const durationType = tcxDuration[\"@_xsi:type\"] as string | undefined;\n logger.warn(\"Unsupported duration type\", { durationType });\n return null;\n};\n\n// KRD → TCX duration mappers\n\nexport type TcxDurationElement = Record<string, unknown>;\n\nexport const mapTimeDurationToTcx = (seconds: number): TcxDurationElement => {\n return {\n \"@_xsi:type\": \"Time_t\",\n Seconds: seconds,\n };\n};\n\nexport const mapDistanceDurationToTcx = (\n meters: number\n): TcxDurationElement => {\n return {\n \"@_xsi:type\": \"Distance_t\",\n Meters: meters,\n };\n};\n\nexport const mapOpenDurationToTcx = (): TcxDurationElement => {\n return {\n \"@_xsi:type\": \"LapButton_t\",\n };\n};\n","import type { Target } from \"@kaiord/core\";\nimport { targetTypeSchema, type TargetType } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { tcxTargetTypeSchema } from \"../schemas/tcx-target\";\n\nexport const mapTargetType = (\n tcxTargetType: string | undefined\n): TargetType => {\n if (tcxTargetType === tcxTargetTypeSchema.enum.HeartRate)\n return targetTypeSchema.enum.heart_rate;\n if (tcxTargetType === tcxTargetTypeSchema.enum.Speed)\n return targetTypeSchema.enum.pace;\n if (tcxTargetType === tcxTargetTypeSchema.enum.Cadence)\n return targetTypeSchema.enum.cadence;\n if (tcxTargetType === tcxTargetTypeSchema.enum.None)\n return targetTypeSchema.enum.open;\n return targetTypeSchema.enum.open;\n};\n\nconst convertHeartRateTarget = (\n heartRateZone: Record<string, unknown> | undefined\n): Target | null => {\n if (!heartRateZone) return null;\n\n const zoneType = heartRateZone[\"@_xsi:type\"] as string | undefined;\n\n if (zoneType === \"PredefinedHeartRateZone_t\") {\n const zoneNumber = heartRateZone.Number as number | undefined;\n if (typeof zoneNumber === \"number\") {\n return {\n type: \"heart_rate\",\n value: { unit: \"zone\", value: zoneNumber },\n };\n }\n }\n\n if (zoneType === \"CustomHeartRateZone_t\") {\n const low = heartRateZone.Low as number | undefined;\n const high = heartRateZone.High as number | undefined;\n if (typeof low === \"number\" && typeof high === \"number\") {\n return {\n type: \"heart_rate\",\n value: { unit: \"range\", min: low, max: high },\n };\n }\n }\n\n return null;\n};\n\nexport const convertTcxTarget = (\n tcxTarget: Record<string, unknown> | undefined,\n logger: Logger\n): Target | null => {\n if (!tcxTarget) {\n return { type: \"open\" };\n }\n\n const targetType = tcxTarget[\"@_xsi:type\"] as string | undefined;\n\n if (targetType === \"None_t\") {\n return { type: \"open\" };\n }\n\n if (targetType === \"HeartRate_t\") {\n const heartRateZone = tcxTarget.HeartRateZone as\n | Record<string, unknown>\n | undefined;\n const result = convertHeartRateTarget(heartRateZone);\n if (result) return result;\n }\n\n logger.warn(\"Unsupported target type\", { targetType });\n return { type: \"open\" };\n};\n","import type { Logger } from \"@kaiord/core\";\n\nexport const extractIntensity = (\n tcxStep: Record<string, unknown>\n): \"warmup\" | \"active\" | \"cooldown\" | \"rest\" | undefined => {\n const raw = tcxStep.Intensity as string | undefined;\n const value = raw?.toLowerCase();\n\n switch (value) {\n case \"warmup\":\n case \"active\":\n case \"cooldown\":\n case \"rest\":\n return value;\n case \"resting\":\n return \"rest\";\n default:\n return undefined;\n }\n};\n\nexport const extractPowerFromExtensions = (\n extensions: Record<string, unknown>,\n logger: Logger\n): number | undefined => {\n if (extensions.TPX) {\n const tpx = extensions.TPX as Record<string, unknown>;\n if (typeof tpx.Watts === \"number\") {\n logger.debug(\"Found power data in TCX extensions\", {\n watts: tpx.Watts,\n });\n return tpx.Watts;\n }\n }\n\n if (extensions.Power && typeof extensions.Power === \"number\") {\n logger.debug(\"Found power data in TCX extensions\", {\n watts: extensions.Power,\n });\n return extensions.Power;\n }\n\n return undefined;\n};\n\nexport const extractExtensions = (\n tcxStep: Record<string, unknown>,\n logger: Logger\n): Record<string, unknown> | undefined => {\n const extensions = tcxStep.Extensions as Record<string, unknown> | undefined;\n if (!extensions) {\n return undefined;\n }\n\n logger.debug(\"Extracting TCX extensions from step\");\n return { ...extensions };\n};\n","import type { Duration } from \"@kaiord/core\";\nimport type { Target } from \"@kaiord/core\";\nimport type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertTcxDuration } from \"../duration/duration.mapper\";\nimport { convertTcxTarget } from \"../target/target.mapper\";\nimport {\n extractExtensions,\n extractIntensity,\n extractPowerFromExtensions,\n} from \"./step-helpers\";\n\nconst convertTargetWithExtensions = (\n tcxStep: Record<string, unknown>,\n extensions: Record<string, unknown> | undefined,\n logger: Logger\n): Target | null => {\n const target = convertTcxTarget(\n tcxStep.Target as Record<string, unknown> | undefined,\n logger\n );\n if (!target) return null;\n\n if (target.type === \"open\" && extensions) {\n const powerWatts = extractPowerFromExtensions(extensions, logger);\n if (powerWatts !== undefined) {\n logger.debug(\"Converting open target to power target from extensions\", {\n watts: powerWatts,\n });\n return {\n type: \"power\",\n value: {\n unit: \"watts\",\n value: powerWatts,\n },\n };\n }\n }\n\n return target;\n};\n\nconst buildWorkoutStep = (\n stepIndex: number,\n name: string | undefined,\n duration: Duration,\n target: Target,\n tcxStep: Record<string, unknown>,\n extensions: Record<string, unknown> | undefined\n): WorkoutStep => {\n const step: WorkoutStep = {\n stepIndex,\n name,\n durationType: duration.type,\n duration,\n targetType: target.type,\n target,\n intensity: extractIntensity(tcxStep),\n };\n\n return extensions ? { ...step, extensions: { tcx: extensions } } : step;\n};\n\nexport const convertTcxStep = (\n tcxStep: Record<string, unknown>,\n stepIndex: number,\n logger: Logger\n): WorkoutStep | null => {\n logger.debug(\"Converting TCX step\", { stepIndex });\n\n const stepType = tcxStep[\"@_xsi:type\"] as string | undefined;\n if (stepType === \"Repeat_t\") {\n logger.warn(\"Repetition blocks not yet supported\", { stepIndex });\n return null;\n }\n\n const duration = convertTcxDuration(\n tcxStep.Duration as Record<string, unknown> | undefined,\n logger\n );\n if (!duration) {\n logger.warn(\"Step has no valid duration, skipping\", { stepIndex });\n return null;\n }\n\n const extensions = extractExtensions(tcxStep, logger);\n const target = convertTargetWithExtensions(tcxStep, extensions, logger);\n if (!target) {\n logger.warn(\"Step has no valid target, skipping\", { stepIndex });\n return null;\n }\n\n return buildWorkoutStep(\n stepIndex,\n tcxStep.Name as string | undefined,\n duration,\n target,\n tcxStep,\n extensions\n );\n};\n","import type { Workout, WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { TCX_TO_KRD_SPORT, tcxSportSchema } from \"../schemas/tcx-sport\";\nimport { convertTcxStep } from \"./step.converter\";\n\nconst extractWorkoutExtensions = (\n tcxWorkout: Record<string, unknown>,\n logger: Logger\n): Record<string, unknown> | undefined => {\n const extensions = tcxWorkout.Extensions as\n | Record<string, unknown>\n | undefined;\n if (!extensions) {\n return undefined;\n }\n\n logger.debug(\"Extracting TCX extensions from workout\");\n\n // Store the raw TCX extensions for round-trip preservation\n return { ...extensions };\n};\n\nconst convertSteps = (\n tcxSteps: unknown,\n logger: Logger\n): Array<WorkoutStep> => {\n const steps: Array<WorkoutStep> = [];\n\n if (!tcxSteps) return steps;\n\n const stepArray = Array.isArray(tcxSteps) ? tcxSteps : [tcxSteps];\n let stepIndex = 0;\n\n for (const tcxStep of stepArray) {\n const step = convertTcxStep(\n tcxStep as Record<string, unknown>,\n stepIndex,\n logger\n );\n if (step) {\n steps.push(step);\n stepIndex++;\n }\n }\n\n return steps;\n};\n\nexport const convertTcxWorkout = (\n tcxWorkout: Record<string, unknown>,\n logger: Logger\n): Workout => {\n logger.debug(\"Converting TCX workout\");\n\n const sportAttr = tcxWorkout[\"@_Sport\"] as string | undefined;\n const sportResult = tcxSportSchema.safeParse(sportAttr);\n const sport = sportResult.success\n ? TCX_TO_KRD_SPORT[sportResult.data]\n : \"generic\";\n\n const name = tcxWorkout.Name as string | undefined;\n const steps = convertSteps(tcxWorkout.Step, logger);\n const extensions = extractWorkoutExtensions(tcxWorkout, logger);\n\n const workout: Workout = {\n name,\n sport,\n steps,\n };\n\n if (extensions) {\n return {\n ...workout,\n extensions: {\n tcx: extensions,\n },\n };\n }\n\n return workout;\n};\n","import type { KRD } from \"@kaiord/core\";\nimport { createTcxParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { extractKaiordMetadata } from \"./metadata-extractor\";\nimport { convertTcxWorkout } from \"./workout.converter\";\n\nconst extractTcxExtensions = (\n trainingCenterDatabase: Record<string, unknown>,\n logger: Logger\n): Record<string, unknown> | undefined => {\n const extensions = trainingCenterDatabase.Extensions as\n | Record<string, unknown>\n | undefined;\n if (!extensions) {\n return undefined;\n }\n\n logger.debug(\"Extracting TCX extensions from TrainingCenterDatabase\");\n\n // Store the raw TCX extensions for round-trip preservation\n return { ...extensions };\n};\n\nconst extractWorkoutData = (\n trainingCenterDatabase: Record<string, unknown>\n): Record<string, unknown> => {\n const workouts = trainingCenterDatabase.Workouts as\n | Record<string, unknown>\n | undefined;\n\n if (!workouts) {\n throw createTcxParsingError(\"No workouts found in TCX file\");\n }\n\n const workoutArray = Array.isArray(workouts.Workout)\n ? workouts.Workout\n : [workouts.Workout];\n\n if (workoutArray.length === 0) {\n throw createTcxParsingError(\"No workout data found in TCX file\");\n }\n\n return workoutArray[0] as Record<string, unknown>;\n};\n\nexport const convertTcxToKRD = (\n tcxData: Record<string, unknown>,\n logger: Logger\n): KRD => {\n logger.debug(\"Converting TCX to KRD\");\n\n const trainingCenterDatabase = tcxData.TrainingCenterDatabase as Record<\n string,\n unknown\n >;\n\n const tcxWorkout = extractWorkoutData(trainingCenterDatabase);\n const workout = convertTcxWorkout(tcxWorkout, logger);\n const tcxExtensions = extractTcxExtensions(trainingCenterDatabase, logger);\n const metadata = extractKaiordMetadata(trainingCenterDatabase, workout);\n\n const krd: KRD = {\n version: \"1.0\",\n type: \"structured_workout\",\n metadata,\n extensions: {\n structured_workout: workout,\n ...(tcxExtensions && { tcx: tcxExtensions }),\n },\n };\n\n logger.debug(\"TCX to KRD conversion complete\");\n return krd;\n};\n","import type { KRD } from \"@kaiord/core\";\n\nexport const addKaiordMetadata = (\n trainingCenterDatabase: Record<string, unknown>,\n krd: KRD\n): void => {\n if (krd.metadata.created) {\n trainingCenterDatabase[\"@_kaiord:timeCreated\"] = krd.metadata.created;\n }\n if (krd.metadata.manufacturer) {\n trainingCenterDatabase[\"@_kaiord:manufacturer\"] = krd.metadata.manufacturer;\n }\n if (krd.metadata.product) {\n trainingCenterDatabase[\"@_kaiord:product\"] = krd.metadata.product;\n }\n if (krd.metadata.serialNumber) {\n trainingCenterDatabase[\"@_kaiord:serialNumber\"] = krd.metadata.serialNumber;\n }\n};\n","import type { Duration } from \"@kaiord/core\";\n\nconst addKaiordAttributes = (\n tcxDuration: Record<string, unknown>,\n duration: Duration\n): void => {\n if (duration.type === \"heart_rate_less_than\" && duration.bpm !== undefined) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"heart_rate_less_than\";\n tcxDuration[\"@_kaiord:originalDurationBpm\"] = duration.bpm;\n } else if (\n duration.type === \"power_less_than\" &&\n duration.watts !== undefined\n ) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"power_less_than\";\n tcxDuration[\"@_kaiord:originalDurationWatts\"] = duration.watts;\n } else if (\n duration.type === \"power_greater_than\" &&\n duration.watts !== undefined\n ) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"power_greater_than\";\n tcxDuration[\"@_kaiord:originalDurationWatts\"] = duration.watts;\n } else if (duration.type === \"calories\" && duration.calories !== undefined) {\n tcxDuration[\"@_kaiord:originalDurationType\"] = \"calories\";\n tcxDuration[\"@_kaiord:originalDurationCalories\"] = duration.calories;\n }\n};\n\nexport const convertDurationToTcx = (step: {\n duration: Duration;\n}): Record<string, unknown> => {\n const duration = step.duration;\n\n // Standard TCX duration types\n if (duration.type === \"time\") {\n return {\n \"@_xsi:type\": \"Time_t\",\n Seconds: duration.seconds,\n };\n }\n\n if (duration.type === \"distance\") {\n return {\n \"@_xsi:type\": \"Distance_t\",\n Meters: duration.meters,\n };\n }\n\n // For advanced duration types not natively supported by TCX,\n // use LapButton_t and preserve original type in kaiord attributes\n const tcxDuration: Record<string, unknown> = {\n \"@_xsi:type\": \"LapButton_t\",\n };\n\n addKaiordAttributes(tcxDuration, duration);\n\n return tcxDuration;\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\n\nexport const convertHeartRateToTcx = (value: {\n unit: string;\n value?: number;\n min?: number;\n max?: number;\n}): Record<string, unknown> => {\n if (value.unit === \"zone\") {\n return {\n \"@_xsi:type\": \"HeartRate_t\",\n HeartRateZone: {\n \"@_xsi:type\": \"PredefinedHeartRateZone_t\",\n Number: value.value,\n },\n };\n }\n\n if (value.unit === \"bpm\" || value.unit === \"range\") {\n const min = \"min\" in value ? value.min : value.value;\n const max = \"max\" in value ? value.max : value.value;\n return {\n \"@_xsi:type\": \"HeartRate_t\",\n HeartRateZone: {\n \"@_xsi:type\": \"CustomHeartRateZone_t\",\n Low: min,\n High: max,\n },\n };\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n\nexport const convertPaceToTcx = (value: {\n unit: string;\n value?: number;\n min?: number;\n max?: number;\n}): Record<string, unknown> => {\n if (value.unit === \"meters_per_second\" || value.unit === \"range\") {\n const min = \"min\" in value ? value.min : value.value;\n const max = \"max\" in value ? value.max : value.value;\n return {\n \"@_xsi:type\": \"Speed_t\",\n SpeedZone: {\n \"@_xsi:type\": \"CustomSpeedZone_t\",\n LowInMetersPerSecond: min,\n HighInMetersPerSecond: max,\n },\n };\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n\nexport const convertCadenceToTcx = (value: {\n unit: string;\n value?: number;\n min?: number;\n max?: number;\n}): Record<string, unknown> => {\n if (value.unit === \"rpm\" || value.unit === \"range\") {\n const min = \"min\" in value ? value.min : value.value;\n const max = \"max\" in value ? value.max : value.value;\n return {\n \"@_xsi:type\": \"Cadence_t\",\n CadenceZone: {\n \"@_xsi:type\": \"CustomCadenceZone_t\",\n Low: min,\n High: max,\n },\n };\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n\nexport const convertTargetToTcx = (\n step: WorkoutStep\n): Record<string, unknown> => {\n if (step.target.type === \"open\") {\n return { \"@_xsi:type\": \"None_t\" };\n }\n\n if (step.target.type === \"heart_rate\") {\n const value = step.target.value;\n if (value && \"unit\" in value) {\n return convertHeartRateToTcx(value);\n }\n }\n\n if (step.target.type === \"pace\") {\n const value = step.target.value;\n if (value && \"unit\" in value) {\n return convertPaceToTcx(value);\n }\n }\n\n if (step.target.type === \"cadence\") {\n const value = step.target.value;\n if (value && \"unit\" in value) {\n return convertCadenceToTcx(value);\n }\n }\n\n return { \"@_xsi:type\": \"None_t\" };\n};\n","import type { WorkoutStep } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { convertDurationToTcx } from \"./duration-to-tcx-encoder\";\nimport { convertTargetToTcx } from \"./target-to-tcx.converter\";\n\nconst capitalizeFirst = (str: string): string => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n};\n\nconst addPowerExtensions = (\n step: WorkoutStep,\n tcxStep: Record<string, unknown>,\n logger: Logger\n): void => {\n if (step.target.type === \"power\") {\n logger.debug(\"Encoding power target to TCX extensions\", {\n stepIndex: step.stepIndex,\n });\n const powerValue = step.target.value;\n if (powerValue && \"unit\" in powerValue && powerValue.unit === \"watts\") {\n tcxStep.Extensions = {\n TPX: {\n \"@_xmlns\": \"http://www.garmin.com/xmlschemas/ActivityExtension/v2\",\n Watts: powerValue.value,\n },\n };\n }\n }\n};\n\nexport const convertStepToTcx = (\n step: WorkoutStep,\n index: number,\n logger: Logger\n): Record<string, unknown> => {\n logger.debug(\"Converting step to TCX\", { stepIndex: step.stepIndex });\n\n const tcxStep: Record<string, unknown> = {\n \"@_xsi:type\": \"Step_t\",\n StepId: index + 1,\n };\n\n if (step.name) {\n tcxStep.Name = step.name;\n }\n\n tcxStep.Duration = convertDurationToTcx(step);\n\n if (step.intensity) {\n tcxStep.Intensity = capitalizeFirst(step.intensity);\n }\n\n tcxStep.Target = convertTargetToTcx(step);\n\n if (step.extensions?.tcx) {\n logger.debug(\"Restoring step-level TCX extensions\", {\n stepIndex: step.stepIndex,\n });\n tcxStep.Extensions = step.extensions.tcx;\n } else {\n addPowerExtensions(step, tcxStep, logger);\n }\n\n return tcxStep;\n};\n","import type { KRD } from \"@kaiord/core\";\nimport type { Workout, WorkoutStep } from \"@kaiord/core\";\nimport { createTcxParsingError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport { KRD_TO_TCX_SPORT } from \"../schemas/tcx-sport\";\nimport { addKaiordMetadata } from \"./metadata-builder\";\nimport { convertStepToTcx } from \"./step-to-tcx.converter\";\n\nconst buildTcxWorkout = (\n workout: Workout,\n logger: Logger\n): Record<string, unknown> => {\n const tcxSport =\n KRD_TO_TCX_SPORT[workout.sport as keyof typeof KRD_TO_TCX_SPORT] || \"Other\";\n\n const tcxSteps = workout.steps.map((step, index) =>\n convertStepToTcx(step as WorkoutStep, index, logger)\n );\n\n const tcxWorkout: Record<string, unknown> = {\n \"@_Sport\": tcxSport,\n Name: workout.name,\n Step: tcxSteps,\n };\n\n if (workout.extensions?.tcx) {\n logger.debug(\"Restoring workout-level TCX extensions\");\n tcxWorkout.Extensions = workout.extensions.tcx;\n }\n\n return tcxWorkout;\n};\n\nconst buildTrainingCenterDatabase = (\n tcxWorkout: Record<string, unknown>,\n krd: KRD,\n logger: Logger\n): Record<string, unknown> => {\n const trainingCenterDatabase: Record<string, unknown> = {\n \"@_xmlns\": \"http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2\",\n \"@_xmlns:xsi\": \"http://www.w3.org/2001/XMLSchema-instance\",\n \"@_xmlns:kaiord\": \"http://kaiord.dev/tcx-extensions/1.0\",\n Workouts: {\n Workout: tcxWorkout,\n },\n };\n\n addKaiordMetadata(trainingCenterDatabase, krd);\n\n if (krd.extensions?.tcx) {\n logger.debug(\"Restoring TrainingCenterDatabase-level TCX extensions\");\n trainingCenterDatabase.Extensions = krd.extensions.tcx;\n }\n\n return trainingCenterDatabase;\n};\n\nexport const convertKRDToTcx = (krd: KRD, logger: Logger): unknown => {\n logger.debug(\"Converting KRD to TCX structure\");\n\n if (!krd.extensions?.structured_workout) {\n throw createTcxParsingError(\n \"KRD does not contain workout data in extensions\"\n );\n }\n\n const workout = krd.extensions.structured_workout as Workout;\n const tcxWorkout = buildTcxWorkout(workout, logger);\n const trainingCenterDatabase = buildTrainingCenterDatabase(\n tcxWorkout,\n krd,\n logger\n );\n\n return {\n TrainingCenterDatabase: trainingCenterDatabase,\n };\n};\n","import { XMLBuilder, XMLParser } from \"fast-xml-parser\";\nimport type { KRD, TextReader, TextWriter } from \"@kaiord/core\";\nimport { createTcxParsingError, createTcxValidationError } from \"@kaiord/core\";\nimport type { Logger } from \"@kaiord/core\";\nimport type { TcxValidator } from \"../types\";\nimport { convertTcxToKRD } from \"./workout/krd.converter\";\nimport { convertKRDToTcx as convertKRDToTcxStructure } from \"./workout/tcx.converter\";\n\nexport const createFastXmlTcxReader =\n (logger: Logger): TextReader =>\n async (xmlString: string): Promise<KRD> => {\n logger.debug(\"Parsing TCX file\", { xmlLength: xmlString.length });\n\n let tcxData: unknown;\n try {\n const parser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n parseAttributeValue: true,\n });\n\n tcxData = parser.parse(xmlString);\n } catch (error) {\n logger.error(\"Failed to parse TCX XML\", { error });\n throw createTcxParsingError(\"Failed to parse TCX file\", error);\n }\n\n if (\n !tcxData ||\n typeof tcxData !== \"object\" ||\n !(\"TrainingCenterDatabase\" in tcxData)\n ) {\n const error = createTcxParsingError(\n \"Invalid TCX format: missing TrainingCenterDatabase element\"\n );\n logger.error(\"Invalid TCX structure\", { error });\n throw error;\n }\n\n logger.info(\"TCX file parsed successfully\");\n\n return convertTcxToKRD(tcxData, logger);\n };\n\nexport const createFastXmlTcxWriter =\n (logger: Logger, validator: TcxValidator): TextWriter =>\n async (krd: KRD): Promise<string> => {\n logger.debug(\"Encoding KRD to TCX\");\n\n let tcxData: unknown;\n try {\n tcxData = convertKRDToTcx(krd, logger);\n } catch (error) {\n logger.error(\"Failed to convert KRD to TCX structure\", { error });\n throw createTcxParsingError(\"Failed to convert KRD to TCX\", error);\n }\n\n let xmlString: string;\n try {\n const builder = new XMLBuilder({\n ignoreAttributes: false,\n attributeNamePrefix: \"@_\",\n format: true,\n indentBy: \" \",\n });\n\n xmlString = builder.build(tcxData);\n } catch (error) {\n logger.error(\"Failed to build TCX XML\", { error });\n throw createTcxParsingError(\"Failed to build TCX XML\", error);\n }\n\n logger.debug(\"Validating generated TCX against XSD\");\n\n const validationResult = await validator(xmlString);\n if (!validationResult.valid) {\n logger.error(\"Generated TCX does not conform to XSD schema\", {\n errors: validationResult.errors,\n });\n throw createTcxValidationError(\n \"Generated TCX file does not conform to XSD schema\",\n validationResult.errors.map((err) => ({\n field: err.path,\n message: err.message,\n }))\n );\n }\n\n logger.info(\"KRD encoded to TCX successfully\");\n return xmlString;\n };\n\nconst convertKRDToTcx = (krd: KRD, logger: Logger): unknown => {\n return convertKRDToTcxStructure(krd, logger);\n};\n","import { XMLValidator } from \"fast-xml-parser\";\nimport type { Logger } from \"@kaiord/core\";\nimport type { TcxValidationResult, TcxValidator } from \"../types\";\n\nexport const createXsdTcxValidator =\n (logger: Logger): TcxValidator =>\n async (xmlString: string): Promise<TcxValidationResult> => {\n try {\n logger.debug(\"Validating TCX XML structure\");\n\n // Validate XML structure using fast-xml-parser\n const xmlValidation = XMLValidator.validate(xmlString, {\n allowBooleanAttributes: true,\n });\n\n if (xmlValidation !== true) {\n logger.warn(\"TCX XML validation failed\", {\n error: xmlValidation.err,\n });\n\n return {\n valid: false,\n errors: [\n {\n path: `line ${xmlValidation.err.line}`,\n message: `XML validation failed: ${xmlValidation.err.msg}`,\n },\n ],\n };\n }\n\n logger.info(\"TCX XML structure is valid\");\n return { valid: true, errors: [] };\n } catch (error) {\n logger.error(\"TCX validation failed\", { error });\n\n return {\n valid: false,\n errors: [\n {\n path: \"root\",\n message: error instanceof Error ? error.message : \"Unknown error\",\n },\n ],\n };\n }\n };\n","/**\n * @kaiord/tcx - TCX format adapter for Kaiord\n */\n\nimport type { Logger, TextReader, TextWriter } from \"@kaiord/core\";\nimport { createConsoleLogger } from \"@kaiord/core\";\nimport {\n createFastXmlTcxReader,\n createFastXmlTcxWriter,\n} from \"./adapters/fast-xml-parser\";\nimport { createXsdTcxValidator } from \"./adapters/xsd-validator\";\n\nexport const createTcxReader = (logger?: Logger): TextReader => {\n const log = logger || createConsoleLogger();\n return createFastXmlTcxReader(log);\n};\n\nexport const createTcxWriter = (logger?: Logger): TextWriter => {\n const log = logger || createConsoleLogger();\n const validator = createXsdTcxValidator(log);\n return createFastXmlTcxWriter(log, validator);\n};\n\nexport const tcxReader: TextReader = createTcxReader();\nexport const tcxWriter: TextWriter = createTcxWriter();\n\nexport { createFastXmlTcxReader, createFastXmlTcxWriter };\nexport { createXsdTcxValidator };\nexport type { TcxValidator, TcxValidationResult } from \"./types\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kaiord/tcx",
|
|
3
|
-
"version": "4.
|
|
4
|
-
"description": "TCX format adapter for Kaiord
|
|
3
|
+
"version": "4.3.0",
|
|
4
|
+
"description": "TCX format adapter for the Kaiord health & fitness data framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"fast-xml-parser": "^5.3.4",
|
|
20
|
-
"zod": "^
|
|
21
|
-
"@kaiord/core": "^4.
|
|
20
|
+
"zod": "^4.0.0",
|
|
21
|
+
"@kaiord/core": "^4.3.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@types/node": "^24.0.0",
|