trackswap 0.0.1 → 0.0.2

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.
Files changed (78) hide show
  1. package/dist/FIT/base.d.ts +91 -0
  2. package/dist/FIT/base.js +101 -0
  3. package/dist/FIT/crc.d.ts +1 -0
  4. package/dist/FIT/crc.js +16 -0
  5. package/dist/FIT/decoder.d.ts +83 -0
  6. package/dist/FIT/decoder.js +323 -0
  7. package/dist/FIT/encoder.d.ts +142 -0
  8. package/dist/FIT/encoder.js +445 -0
  9. package/dist/FIT/index.d.ts +12 -0
  10. package/dist/FIT/index.js +13 -0
  11. package/dist/FIT/mesg.d.ts +40 -0
  12. package/dist/FIT/mesg.js +208 -0
  13. package/dist/FIT/middleware.d.ts +48 -0
  14. package/dist/FIT/middleware.js +206 -0
  15. package/dist/FIT/plugins.d.ts +26 -0
  16. package/dist/FIT/plugins.js +104 -0
  17. package/dist/FIT/processor.d.ts +58 -0
  18. package/dist/FIT/processor.js +170 -0
  19. package/dist/FIT/types/course_point.d.ts +56 -0
  20. package/dist/FIT/types/course_point.js +58 -0
  21. package/dist/FIT/types/event.d.ts +49 -0
  22. package/dist/FIT/types/event.js +50 -0
  23. package/dist/FIT/types/event_type.d.ts +18 -0
  24. package/dist/FIT/types/event_type.js +19 -0
  25. package/dist/FIT/types/file.d.ts +23 -0
  26. package/dist/FIT/types/file.js +24 -0
  27. package/dist/FIT/types/index.d.ts +119 -0
  28. package/dist/FIT/types/index.js +297 -0
  29. package/dist/FIT/types/mesg_num.d.ts +105 -0
  30. package/dist/FIT/types/mesg_num.js +106 -0
  31. package/dist/FIT/types/sport.d.ts +47 -0
  32. package/dist/FIT/types/sport.js +48 -0
  33. package/dist/FIT/types.d.ts +231 -0
  34. package/dist/FIT/types.js +1 -0
  35. package/dist/FIT/util.d.ts +1 -0
  36. package/dist/FIT/util.js +7 -0
  37. package/dist/GPX/base.d.ts +43 -67
  38. package/dist/GPX/base.js +40 -67
  39. package/dist/GPX/converters.d.ts +12 -36
  40. package/dist/GPX/converters.js +11 -103
  41. package/dist/GPX/decoder.d.ts +5 -5
  42. package/dist/GPX/decoder.js +6 -0
  43. package/dist/GPX/encoder.d.ts +4 -0
  44. package/dist/GPX/encoder.js +3 -0
  45. package/dist/GPX/index.d.ts +1 -1
  46. package/dist/GPX/index.js +1 -1
  47. package/dist/GPX/middleware.d.ts +27 -0
  48. package/dist/GPX/middleware.js +93 -0
  49. package/dist/GPX/processor.d.ts +1 -1
  50. package/dist/GPX/processor.js +12 -11
  51. package/dist/GPX/types.d.ts +2 -3
  52. package/dist/TCX/base.d.ts +52 -0
  53. package/dist/TCX/base.js +62 -0
  54. package/dist/TCX/converters.d.ts +75 -0
  55. package/dist/TCX/converters.js +333 -0
  56. package/dist/TCX/decoder.d.ts +87 -0
  57. package/dist/TCX/decoder.js +350 -0
  58. package/dist/TCX/encoder.d.ts +150 -0
  59. package/dist/TCX/encoder.js +513 -0
  60. package/dist/TCX/index.d.ts +10 -0
  61. package/dist/TCX/index.js +9 -0
  62. package/dist/TCX/middleware.d.ts +27 -0
  63. package/dist/TCX/middleware.js +93 -0
  64. package/dist/TCX/processor.d.ts +48 -0
  65. package/dist/TCX/processor.js +197 -0
  66. package/dist/TCX/types.d.ts +203 -0
  67. package/dist/TCX/types.js +1 -0
  68. package/dist/core/base.d.ts +119 -0
  69. package/dist/core/base.js +138 -0
  70. package/dist/core/decoder.d.ts +66 -0
  71. package/dist/core/decoder.js +90 -0
  72. package/dist/core/index.d.ts +2 -0
  73. package/dist/core/index.js +4 -0
  74. package/dist/core/processor.d.ts +69 -0
  75. package/dist/core/processor.js +265 -0
  76. package/dist/core/xml-utils.d.ts +41 -0
  77. package/dist/core/xml-utils.js +140 -0
  78. package/package.json +8 -5
@@ -1,9 +1,9 @@
1
- import { BaseConverter, BaseMiddleware } from "./base.js";
1
+ import { BaseGPXConverter } from "./base.js";
2
2
  // ============ 核心转换器 ============
3
3
  /**
4
4
  * WPT转换器
5
5
  */
6
- export class WptConverter extends BaseConverter {
6
+ export class WptConverter extends BaseGPXConverter {
7
7
  constructor() {
8
8
  super(...arguments);
9
9
  this.name = "wpt-converter";
@@ -67,7 +67,7 @@ export class WptConverter extends BaseConverter {
67
67
  /**
68
68
  * Route转换器
69
69
  */
70
- export class RteConverter extends BaseConverter {
70
+ export class RteConverter extends BaseGPXConverter {
71
71
  constructor() {
72
72
  super(...arguments);
73
73
  this.name = "rte-converter";
@@ -114,7 +114,7 @@ export class RteConverter extends BaseConverter {
114
114
  /**
115
115
  * Track转换器
116
116
  */
117
- export class TrkConverter extends BaseConverter {
117
+ export class TrkConverter extends BaseGPXConverter {
118
118
  constructor() {
119
119
  super(...arguments);
120
120
  this.name = "trk-converter";
@@ -161,7 +161,7 @@ export class TrkConverter extends BaseConverter {
161
161
  /**
162
162
  * Track Segment转换器
163
163
  */
164
- export class TrksegConverter extends BaseConverter {
164
+ export class TrksegConverter extends BaseGPXConverter {
165
165
  constructor() {
166
166
  super(...arguments);
167
167
  this.name = "trkseg-converter";
@@ -190,7 +190,7 @@ export class TrksegConverter extends BaseConverter {
190
190
  /**
191
191
  * Link转换器
192
192
  */
193
- export class LinkConverter extends BaseConverter {
193
+ export class LinkConverter extends BaseGPXConverter {
194
194
  constructor() {
195
195
  super(...arguments);
196
196
  this.name = "link-converter";
@@ -211,7 +211,7 @@ export class LinkConverter extends BaseConverter {
211
211
  /**
212
212
  * Metadata转换器
213
213
  */
214
- export class MetadataConverter extends BaseConverter {
214
+ export class MetadataConverter extends BaseGPXConverter {
215
215
  constructor() {
216
216
  super(...arguments);
217
217
  this.name = "metadata-converter";
@@ -263,7 +263,7 @@ export class MetadataConverter extends BaseConverter {
263
263
  /**
264
264
  * Person转换器
265
265
  */
266
- export class PersonConverter extends BaseConverter {
266
+ export class PersonConverter extends BaseGPXConverter {
267
267
  constructor() {
268
268
  super(...arguments);
269
269
  this.name = "person-converter";
@@ -294,7 +294,7 @@ export class PersonConverter extends BaseConverter {
294
294
  /**
295
295
  * Email转换器
296
296
  */
297
- export class EmailConverter extends BaseConverter {
297
+ export class EmailConverter extends BaseGPXConverter {
298
298
  constructor() {
299
299
  super(...arguments);
300
300
  this.name = "email-converter";
@@ -312,7 +312,7 @@ export class EmailConverter extends BaseConverter {
312
312
  /**
313
313
  * Copyright转换器
314
314
  */
315
- export class CopyrightConverter extends BaseConverter {
315
+ export class CopyrightConverter extends BaseGPXConverter {
316
316
  constructor() {
317
317
  super(...arguments);
318
318
  this.name = "copyright-converter";
@@ -333,7 +333,7 @@ export class CopyrightConverter extends BaseConverter {
333
333
  /**
334
334
  * Bounds转换器
335
335
  */
336
- export class BoundsConverter extends BaseConverter {
336
+ export class BoundsConverter extends BaseGPXConverter {
337
337
  constructor() {
338
338
  super(...arguments);
339
339
  this.name = "bounds-converter";
@@ -350,95 +350,3 @@ export class BoundsConverter extends BaseConverter {
350
350
  return bounds;
351
351
  }
352
352
  }
353
- // ============ 示例中间件 ============
354
- /**
355
- * 性能监控中间件
356
- */
357
- export class PerformanceMiddleware extends BaseMiddleware {
358
- constructor() {
359
- super(...arguments);
360
- this.name = "performance-middleware";
361
- this.description = "监控解析性能";
362
- }
363
- async onTokenize(tokens, context) {
364
- console.log(`Token化完成,生成了 ${tokens.length} 个token`);
365
- return tokens;
366
- }
367
- async onAstGenerate(ast, context) {
368
- const nodeCount = this.countNodes(ast);
369
- console.log(`AST生成完成,包含 ${nodeCount} 个节点`);
370
- return ast;
371
- }
372
- async onComplete(result, context) {
373
- const performance = context.metadata.get("performance");
374
- console.log("解析性能统计:", performance);
375
- return result;
376
- }
377
- countNodes(ast) {
378
- let count = 1;
379
- if (ast.children) {
380
- for (const child of ast.children) {
381
- count += this.countNodes(child);
382
- }
383
- }
384
- return count;
385
- }
386
- }
387
- /**
388
- * 验证中间件
389
- */
390
- export class ValidationMiddleware extends BaseMiddleware {
391
- constructor() {
392
- super(...arguments);
393
- this.name = "validation-middleware";
394
- this.description = "验证GPX数据的完整性";
395
- }
396
- async onComplete(result, context) {
397
- const errors = this.validateGPX(result);
398
- if (errors.length > 0) {
399
- console.warn("GPX验证发现问题:", errors);
400
- context.metadata.set("validation-errors", errors);
401
- }
402
- else {
403
- console.log("GPX验证通过");
404
- }
405
- return result;
406
- }
407
- validateGPX(gpx) {
408
- const errors = [];
409
- if (!gpx.version) {
410
- errors.push("缺少GPX版本信息");
411
- }
412
- if (!gpx.creator) {
413
- errors.push("缺少GPX创建者信息");
414
- }
415
- // 验证轨迹点
416
- if (gpx.trk) {
417
- for (const track of gpx.trk) {
418
- if (track.trkseg) {
419
- for (const segment of track.trkseg) {
420
- if (segment.trkpt) {
421
- for (const point of segment.trkpt) {
422
- if (typeof point.lat !== "number" ||
423
- typeof point.lon !== "number") {
424
- errors.push("轨迹点坐标无效");
425
- }
426
- }
427
- }
428
- }
429
- }
430
- }
431
- }
432
- return errors;
433
- }
434
- }
435
- // ============ 默认转换器注册函数 ============
436
- /**
437
- * 注册所有默认中间件
438
- */
439
- export async function registerDefaultMiddlewares(decoder) {
440
- const middlewares = [new PerformanceMiddleware(), new ValidationMiddleware()];
441
- for (const middleware of middlewares) {
442
- await decoder.registerMiddleware(middleware);
443
- }
444
- }
@@ -1,5 +1,5 @@
1
1
  import { ExtensionsType, TokenAST } from "../types.js";
2
- import { IConverterPlugin, IMiddlewarePlugin } from "./base.js";
2
+ import { IGPXConverterPlugin, IGPXMiddlewarePlugin } from "./base.js";
3
3
  import { GPX11Type } from "./types.js";
4
4
  /**
5
5
  * GPX解码器主类
@@ -27,19 +27,19 @@ export declare class GPXDecoder {
27
27
  /**
28
28
  * 注册转换器插件
29
29
  */
30
- registerConverter(plugin: IConverterPlugin): Promise<void>;
30
+ registerConverter(plugin: IGPXConverterPlugin): Promise<void>;
31
31
  /**
32
32
  * 注册中间件插件 - 真正的扩展点
33
33
  */
34
- registerMiddleware(plugin: IMiddlewarePlugin): Promise<void>;
34
+ registerMiddleware(plugin: IGPXMiddlewarePlugin): Promise<void>;
35
35
  /**
36
36
  * 获取转换器(返回优先级最高的)
37
37
  */
38
- getConverter(tag: string): IConverterPlugin | undefined;
38
+ getConverter(tag: string): IGPXConverterPlugin | undefined;
39
39
  /**
40
40
  * 获取指定标签的所有转换器(按优先级排序)
41
41
  */
42
- getAllConverters(tag: string): IConverterPlugin[];
42
+ getAllConverters(tag: string): IGPXConverterPlugin[];
43
43
  /**
44
44
  * 移除转换器
45
45
  */
@@ -292,6 +292,12 @@ export class GPXDecoder {
292
292
  return {
293
293
  metadata: new Map(),
294
294
  errors: [],
295
+ warnings: [],
296
+ stats: {
297
+ startTime: Date.now(),
298
+ processedTokens: 0,
299
+ convertedElements: 0,
300
+ },
295
301
  performance: {
296
302
  startTime: Date.now(),
297
303
  },
@@ -148,3 +148,7 @@ export declare class GPXEncoder {
148
148
  */
149
149
  encoder(node: GPX11Type): Promise<Buffer>;
150
150
  }
151
+ declare const _default: {
152
+ GPXEncoder: typeof GPXEncoder;
153
+ };
154
+ export default _default;
@@ -508,3 +508,6 @@ export class GPXEncoder {
508
508
  return this.encode(node);
509
509
  }
510
510
  }
511
+ export default {
512
+ GPXEncoder,
513
+ };
@@ -1,6 +1,6 @@
1
1
  import { GPXDecoder } from "./decoder.js";
2
2
  import { GPXEncoder } from "./encoder.js";
3
- import { registerDefaultMiddlewares } from "./converters.js";
3
+ import { registerDefaultMiddlewares } from "./middleware.js";
4
4
  import { PipelineStage } from "./processor.js";
5
5
  export { GPXDecoder, GPXEncoder, registerDefaultMiddlewares, PipelineStage };
6
6
  declare const _default: {
package/dist/GPX/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { GPXDecoder } from "./decoder.js";
2
2
  import { GPXEncoder } from "./encoder.js";
3
- import { registerDefaultMiddlewares } from "./converters.js";
3
+ import { registerDefaultMiddlewares } from "./middleware.js";
4
4
  import { PipelineStage } from "./processor.js";
5
5
  export { GPXDecoder, GPXEncoder, registerDefaultMiddlewares, PipelineStage };
6
6
  export default {
@@ -0,0 +1,27 @@
1
+ import { Token, TokenAST } from "../types";
2
+ import { BaseGPXMiddleware } from "./base";
3
+ import { DecoderContext } from "./types";
4
+ /**
5
+ * 性能监控中间件
6
+ */
7
+ export declare class PerformanceMiddleware extends BaseGPXMiddleware {
8
+ name: string;
9
+ description: string;
10
+ onTokenize(tokens: Token[], context: DecoderContext): Promise<Token[]>;
11
+ onAstGenerate(ast: TokenAST, context: DecoderContext): Promise<TokenAST>;
12
+ onComplete(result: any, context: DecoderContext): Promise<any>;
13
+ private countNodes;
14
+ }
15
+ /**
16
+ * 验证中间件
17
+ */
18
+ export declare class ValidationMiddleware extends BaseGPXMiddleware {
19
+ name: string;
20
+ description: string;
21
+ onComplete(result: any, context: DecoderContext): Promise<any>;
22
+ private validateGPX;
23
+ }
24
+ /**
25
+ * 注册所有默认中间件
26
+ */
27
+ export declare function registerDefaultMiddlewares(decoder: any): Promise<void>;
@@ -0,0 +1,93 @@
1
+ import { BaseGPXMiddleware } from "./base";
2
+ // ============ 示例中间件 ============
3
+ /**
4
+ * 性能监控中间件
5
+ */
6
+ export class PerformanceMiddleware extends BaseGPXMiddleware {
7
+ constructor() {
8
+ super(...arguments);
9
+ this.name = "performance-middleware";
10
+ this.description = "监控解析性能";
11
+ }
12
+ async onTokenize(tokens, context) {
13
+ console.log(`Token化完成,生成了 ${tokens.length} 个token`);
14
+ return tokens;
15
+ }
16
+ async onAstGenerate(ast, context) {
17
+ const nodeCount = this.countNodes(ast);
18
+ console.log(`AST生成完成,包含 ${nodeCount} 个节点`);
19
+ return ast;
20
+ }
21
+ async onComplete(result, context) {
22
+ const performance = context.metadata.get("performance");
23
+ console.log("解析性能统计:", performance);
24
+ return result;
25
+ }
26
+ countNodes(ast) {
27
+ let count = 1;
28
+ if (ast.children) {
29
+ for (const child of ast.children) {
30
+ count += this.countNodes(child);
31
+ }
32
+ }
33
+ return count;
34
+ }
35
+ }
36
+ /**
37
+ * 验证中间件
38
+ */
39
+ export class ValidationMiddleware extends BaseGPXMiddleware {
40
+ constructor() {
41
+ super(...arguments);
42
+ this.name = "validation-middleware";
43
+ this.description = "验证GPX数据的完整性";
44
+ }
45
+ async onComplete(result, context) {
46
+ const errors = this.validateGPX(result);
47
+ if (errors.length > 0) {
48
+ console.warn("GPX验证发现问题:", errors);
49
+ context.metadata.set("validation-errors", errors);
50
+ }
51
+ else {
52
+ console.log("GPX验证通过");
53
+ }
54
+ return result;
55
+ }
56
+ validateGPX(gpx) {
57
+ const errors = [];
58
+ if (!gpx.version) {
59
+ errors.push("缺少GPX版本信息");
60
+ }
61
+ if (!gpx.creator) {
62
+ errors.push("缺少GPX创建者信息");
63
+ }
64
+ // 验证轨迹点
65
+ if (gpx.trk) {
66
+ for (const track of gpx.trk) {
67
+ if (track.trkseg) {
68
+ for (const segment of track.trkseg) {
69
+ if (segment.trkpt) {
70
+ for (const point of segment.trkpt) {
71
+ if (typeof point.lat !== "number" ||
72
+ typeof point.lon !== "number") {
73
+ errors.push("轨迹点坐标无效");
74
+ }
75
+ }
76
+ }
77
+ }
78
+ }
79
+ }
80
+ }
81
+ return errors;
82
+ }
83
+ }
84
+ // ============ 默认转换器注册函数 ============
85
+ /**
86
+ * 注册所有默认中间件
87
+ */
88
+ export async function registerDefaultMiddlewares(decoder) {
89
+ const middlewares = [new PerformanceMiddleware(), new ValidationMiddleware()];
90
+ for (const middleware of middlewares) {
91
+ await decoder.registerMiddleware(middleware);
92
+ }
93
+ }
@@ -16,7 +16,7 @@ export interface IPipelineProcessor {
16
16
  process(context: DecoderContext): Promise<DecoderContext>;
17
17
  }
18
18
  /**
19
- * Tokenize处理器
19
+ * Tokenize处理器, 将xml转为 token
20
20
  */
21
21
  export declare class TokenizeProcessor implements IPipelineProcessor {
22
22
  stage: PipelineStage;
@@ -10,7 +10,7 @@ export var PipelineStage;
10
10
  PipelineStage["COMPLETE"] = "complete";
11
11
  })(PipelineStage || (PipelineStage = {}));
12
12
  /**
13
- * Tokenize处理器
13
+ * Tokenize处理器, 将xml转为 token
14
14
  */
15
15
  export class TokenizeProcessor {
16
16
  constructor() {
@@ -122,18 +122,19 @@ export class ConvertProcessor {
122
122
  // 处理子节点
123
123
  context.ast.children?.forEach((child) => {
124
124
  const converter = this.getConverter(child.tag);
125
- if (converter) {
126
- try {
127
- const result = converter.convert(child, context);
128
- if (result) {
129
- this.assignResult(gpx, child.tag, result);
130
- }
131
- }
132
- catch (error) {
133
- context.errors.push(error);
134
- console.error(`转换器 ${converter.name} 处理标签 ${child.tag} 时出错:`, error);
125
+ if (!converter) {
126
+ console.error(`标签 ${child.tag} 未找到对应的 converter`);
127
+ }
128
+ try {
129
+ const result = converter.convert(child, context);
130
+ if (result) {
131
+ this.assignResult(gpx, child.tag, result);
135
132
  }
136
133
  }
134
+ catch (error) {
135
+ context.errors.push(error);
136
+ console.error(`转换器 ${converter.name} 处理标签 ${child.tag} 时出错:`, error);
137
+ }
137
138
  });
138
139
  context.result = gpx;
139
140
  context.performance.convertTime = Date.now() - startTime;
@@ -1,4 +1,5 @@
1
1
  import { DegreesType, ExtensionsType, LatitudeType, LongitudeType, Token, TokenAST } from "../types.js";
2
+ import { IProcessingContext } from "../core/base.js";
2
3
  /**
3
4
  * Two lat/lon pairs defining the extent of an element.
4
5
  */
@@ -211,14 +212,12 @@ export interface TrksegType {
211
212
  trkpt?: WptType[];
212
213
  extensions?: ExtensionsType;
213
214
  }
214
- export interface DecoderContext {
215
+ export interface DecoderContext extends IProcessingContext {
215
216
  rawData?: Buffer;
216
217
  xmlContent?: string;
217
218
  tokens?: Token[];
218
219
  ast?: TokenAST;
219
220
  result?: GPX11Type;
220
- metadata: Map<string, any>;
221
- errors: Error[];
222
221
  performance: {
223
222
  startTime: number;
224
223
  tokenizeTime?: number;
@@ -0,0 +1,52 @@
1
+ import { IPlugin, IConverterPlugin, IMiddlewarePlugin, BaseConverter, BaseMiddleware } from "../core/base.js";
2
+ import { TCXContext, TCXFileType } from "./types.js";
3
+ /**
4
+ * TCX 插件接口(继承通用插件接口)
5
+ */
6
+ export interface ITCXPlugin extends IPlugin<TCXContext> {
7
+ }
8
+ /**
9
+ * TCX 转换器插件接口(继承通用转换器接口)
10
+ */
11
+ export interface ITCXConverterPlugin extends IConverterPlugin<TCXContext> {
12
+ }
13
+ /**
14
+ * TCX 中间件插件接口(继承通用中间件接口)
15
+ */
16
+ export interface ITCXMiddlewarePlugin extends IMiddlewarePlugin<TCXContext, TCXFileType> {
17
+ }
18
+ /**
19
+ * TCX 基础转换器抽象类(继承通用基础转换器)
20
+ */
21
+ export declare abstract class BaseTCXConverter extends BaseConverter<TCXContext> implements ITCXConverterPlugin {
22
+ /**
23
+ * 解析 TCX 心率值
24
+ */
25
+ protected parseHeartRate(value: string | number | undefined): number | undefined;
26
+ /**
27
+ * 解析 TCX 时间格式(ISO 8601)
28
+ */
29
+ protected parseTCXTime(value: string | undefined): Date | undefined;
30
+ /**
31
+ * 解析 TCX 距离值(米)
32
+ */
33
+ protected parseDistance(value: string | number | undefined): number | undefined;
34
+ /**
35
+ * 解析 TCX 速度值(m/s)
36
+ */
37
+ protected parseSpeed(value: string | number | undefined): number | undefined;
38
+ /**
39
+ * 解析 TCX 海拔值(米)
40
+ */
41
+ protected parseAltitude(value: string | number | undefined): number | undefined;
42
+ /**
43
+ * 解析 TCX 坐标值(纬度/经度)
44
+ */
45
+ protected parseCoordinate(value: string | number | undefined): number | undefined;
46
+ }
47
+ /**
48
+ * TCX 基础中间件抽象类(继承通用基础中间件)
49
+ */
50
+ export declare abstract class BaseTCXMiddleware extends BaseMiddleware<TCXContext, TCXFileType> implements ITCXMiddlewarePlugin {
51
+ onError(error: Error, context: TCXContext): Promise<void>;
52
+ }
@@ -0,0 +1,62 @@
1
+ import { BaseConverter, BaseMiddleware, } from "../core/base.js";
2
+ // ============ TCX 特定基础类 ============
3
+ /**
4
+ * TCX 基础转换器抽象类(继承通用基础转换器)
5
+ */
6
+ export class BaseTCXConverter extends BaseConverter {
7
+ // TCX 特定的工具方法可以在这里添加
8
+ /**
9
+ * 解析 TCX 心率值
10
+ */
11
+ parseHeartRate(value) {
12
+ const hr = this.parseFloat(value);
13
+ return hr > 0 && hr < 300 ? hr : undefined; // 合理的心率范围
14
+ }
15
+ /**
16
+ * 解析 TCX 时间格式(ISO 8601)
17
+ */
18
+ parseTCXTime(value) {
19
+ if (!value)
20
+ return undefined;
21
+ // TCX 使用 ISO 8601 格式
22
+ const date = new Date(value);
23
+ return isNaN(date.getTime()) ? undefined : date;
24
+ }
25
+ /**
26
+ * 解析 TCX 距离值(米)
27
+ */
28
+ parseDistance(value) {
29
+ const distance = this.parseFloat(value);
30
+ return distance >= 0 ? distance : undefined;
31
+ }
32
+ /**
33
+ * 解析 TCX 速度值(m/s)
34
+ */
35
+ parseSpeed(value) {
36
+ const speed = this.parseFloat(value);
37
+ return speed >= 0 ? speed : undefined;
38
+ }
39
+ /**
40
+ * 解析 TCX 海拔值(米)
41
+ */
42
+ parseAltitude(value) {
43
+ return this.parseFloat(value);
44
+ }
45
+ /**
46
+ * 解析 TCX 坐标值(纬度/经度)
47
+ */
48
+ parseCoordinate(value) {
49
+ const coord = this.parseFloat(value);
50
+ return coord !== 0 ? coord : undefined;
51
+ }
52
+ }
53
+ /**
54
+ * TCX 基础中间件抽象类(继承通用基础中间件)
55
+ */
56
+ export class BaseTCXMiddleware extends BaseMiddleware {
57
+ // TCX 特定的中间件逻辑可以在这里添加
58
+ async onError(error, context) {
59
+ console.error(`TCX中间件 ${this.name} 处理错误:`, error);
60
+ context.warnings.push(`中间件 ${this.name} 错误: ${error.message}`);
61
+ }
62
+ }
@@ -0,0 +1,75 @@
1
+ import { TokenAST } from "../types.js";
2
+ import { BaseTCXConverter } from "./base.js";
3
+ import { TCXContext, ActivityType, ActivityLapType, TrackType, TrackpointType, PositionType, ActivityListType, MultiSportSessionType, AbstractSourceType } from "./types.js";
4
+ /**
5
+ * 位置转换器
6
+ */
7
+ export declare class PositionConverter extends BaseTCXConverter {
8
+ name: string;
9
+ supportedTags: string[];
10
+ convert(ast: TokenAST, context: TCXContext): PositionType | undefined;
11
+ }
12
+ /**
13
+ * 轨迹点转换器
14
+ */
15
+ export declare class TrackpointConverter extends BaseTCXConverter {
16
+ name: string;
17
+ supportedTags: string[];
18
+ convert(ast: TokenAST, context: TCXContext): TrackpointType | undefined;
19
+ protected convertExtensions(extensionsAST: TokenAST): any;
20
+ protected convertExtensionContent(extension: TokenAST): any;
21
+ }
22
+ /**
23
+ * 轨迹转换器
24
+ */
25
+ export declare class TrackConverter extends BaseTCXConverter {
26
+ name: string;
27
+ supportedTags: string[];
28
+ convert(ast: TokenAST, context: TCXContext): TrackType | undefined;
29
+ }
30
+ /**
31
+ * 活动圈数转换器
32
+ */
33
+ export declare class ActivityLapConverter extends BaseTCXConverter {
34
+ name: string;
35
+ supportedTags: string[];
36
+ convert(ast: TokenAST, context: TCXContext): ActivityLapType | undefined;
37
+ protected convertExtensions(extensionsAST: TokenAST): any;
38
+ protected convertExtensionContent(extension: TokenAST): any;
39
+ }
40
+ /**
41
+ * 活动转换器
42
+ */
43
+ export declare class ActivityConverter extends BaseTCXConverter {
44
+ name: string;
45
+ supportedTags: string[];
46
+ convert(ast: TokenAST, context: TCXContext): ActivityType | undefined;
47
+ private convertTraining;
48
+ private convertCreator;
49
+ protected convertExtensions(extensionsAST: TokenAST): any;
50
+ protected convertExtensionContent(extension: TokenAST): any;
51
+ }
52
+ /**
53
+ * 活动列表转换器
54
+ */
55
+ export declare class ActivityListConverter extends BaseTCXConverter {
56
+ name: string;
57
+ supportedTags: string[];
58
+ convert(ast: TokenAST, context: TCXContext): ActivityListType | undefined;
59
+ }
60
+ /**
61
+ * 多运动会话转换器
62
+ */
63
+ export declare class MultiSportSessionConverter extends BaseTCXConverter {
64
+ name: string;
65
+ supportedTags: string[];
66
+ convert(ast: TokenAST, context: TCXContext): MultiSportSessionType | undefined;
67
+ }
68
+ /**
69
+ * 抽象来源转换器
70
+ */
71
+ export declare class AbstractSourceConverter extends BaseTCXConverter {
72
+ name: string;
73
+ supportedTags: string[];
74
+ convert(ast: TokenAST, context: TCXContext): AbstractSourceType | undefined;
75
+ }