incyclist-services 1.2.2 → 1.2.3

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 (44) hide show
  1. package/lib/activities/base/api/consts.d.ts +2 -0
  2. package/lib/activities/base/api/consts.js +6 -0
  3. package/lib/activities/base/api/fitconvert.d.ts +8 -0
  4. package/lib/activities/base/api/fitconvert.js +57 -0
  5. package/lib/activities/base/api/index.d.ts +1 -0
  6. package/lib/activities/base/api/index.js +17 -0
  7. package/lib/activities/base/convert/converter.d.ts +6 -0
  8. package/lib/activities/base/convert/converter.js +28 -0
  9. package/lib/activities/base/convert/factory.d.ts +8 -0
  10. package/lib/activities/base/convert/factory.js +89 -0
  11. package/lib/activities/base/convert/fit/index.d.ts +1 -0
  12. package/lib/activities/base/convert/fit/index.js +17 -0
  13. package/lib/activities/base/convert/fit/remote-fit.d.ts +13 -0
  14. package/lib/activities/base/convert/fit/remote-fit.js +61 -0
  15. package/lib/activities/base/convert/index.d.ts +4 -0
  16. package/lib/activities/base/convert/index.js +20 -0
  17. package/lib/activities/base/convert/tcx/index.d.ts +1 -0
  18. package/lib/activities/base/convert/tcx/index.js +17 -0
  19. package/lib/activities/base/convert/tcx/tcx.d.ts +12 -0
  20. package/lib/activities/base/convert/tcx/tcx.js +87 -0
  21. package/lib/activities/base/convert/types.d.ts +7 -0
  22. package/lib/activities/base/convert/types.js +9 -0
  23. package/lib/activities/base/index.d.ts +2 -0
  24. package/lib/activities/base/index.js +2 -0
  25. package/lib/activities/base/model/index.d.ts +16 -16
  26. package/lib/activities/ride/service.d.ts +1 -3
  27. package/lib/activities/ride/service.js +14 -26
  28. package/lib/api/repository/json/index.d.ts +2 -1
  29. package/lib/api/repository/types.d.ts +1 -3
  30. package/lib/routes/base/parsers/multixml.d.ts +1 -1
  31. package/lib/routes/base/parsers/multixml.js +1 -1
  32. package/lib/routes/base/parsers/utils.d.ts +2 -1
  33. package/lib/routes/base/parsers/xml.d.ts +2 -2
  34. package/lib/routes/base/parsers/xml.js +1 -1
  35. package/lib/routes/base/utils/route.js +3 -2
  36. package/lib/routes/base/utils/xml.d.ts +3 -1
  37. package/lib/utils/formatting.d.ts +1 -0
  38. package/lib/utils/formatting.js +11 -1
  39. package/lib/utils/index.d.ts +1 -0
  40. package/lib/utils/index.js +1 -0
  41. package/lib/utils/xml.d.ts +17 -0
  42. package/lib/utils/xml.js +109 -0
  43. package/lib/workouts/base/parsers/zwo.js +1 -1
  44. package/package.json +5 -2
@@ -0,0 +1,2 @@
1
+ export declare const FITCONVERT_API = "FITCONVERT_API";
2
+ export declare const DEFAULT_FIT_API = "https://dlws.incyclist.com/api/v1/fit/convert";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_FIT_API = exports.FITCONVERT_API = void 0;
4
+ const DEFAULT_FIT_API_PROD = 'https://dlws.incyclist.com/api/v1/fit/convert';
5
+ exports.FITCONVERT_API = 'FITCONVERT_API';
6
+ exports.DEFAULT_FIT_API = DEFAULT_FIT_API_PROD;
@@ -0,0 +1,8 @@
1
+ import { AxiosInstance } from "axios";
2
+ import { FitExportActivity } from "../model";
3
+ export declare class IncyclistFitConvertApi {
4
+ protected api: AxiosInstance;
5
+ convertToFit(data: FitExportActivity): Promise<ArrayBuffer>;
6
+ protected getApi(): AxiosInstance;
7
+ protected getBaseUrl(): string;
8
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.IncyclistFitConvertApi = void 0;
13
+ const settings_1 = require("../../../settings");
14
+ const api_1 = require("../../../api");
15
+ const consts_1 = require("./consts");
16
+ const utils_1 = require("../../../utils");
17
+ class IncyclistFitConvertApi {
18
+ convertToFit(data) {
19
+ return __awaiter(this, void 0, void 0, function* () {
20
+ let url;
21
+ try {
22
+ const baseUrl = this.getBaseUrl();
23
+ const requestUrl = `${baseUrl}/activity/${data.id}`;
24
+ const response = yield this.getApi().post(requestUrl, data);
25
+ url = response.data;
26
+ }
27
+ catch (error) {
28
+ throw new Error(`convert failed: (phase convert), reason: ${error.message}`);
29
+ }
30
+ try {
31
+ const response = yield this.getApi().get(url, { responseType: 'arraybuffer' });
32
+ return response.data;
33
+ }
34
+ catch (error) {
35
+ throw new Error(`convert failed: (phase download), reason: ${error.message}`);
36
+ }
37
+ });
38
+ }
39
+ getApi() {
40
+ if (!this.api) {
41
+ this.api = api_1.ApiClient.getClient();
42
+ return this.api;
43
+ }
44
+ return this.api;
45
+ }
46
+ getBaseUrl() {
47
+ let baseUrl;
48
+ try {
49
+ baseUrl = (0, settings_1.useUserSettings)().get(consts_1.FITCONVERT_API, consts_1.DEFAULT_FIT_API);
50
+ }
51
+ catch (_a) {
52
+ baseUrl = consts_1.DEFAULT_FIT_API;
53
+ }
54
+ return (0, utils_1.trimTrailingChars)(baseUrl, '/');
55
+ }
56
+ }
57
+ exports.IncyclistFitConvertApi = IncyclistFitConvertApi;
@@ -0,0 +1 @@
1
+ export * from './fitconvert';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./fitconvert"), exports);
@@ -0,0 +1,6 @@
1
+ import { ActivityDetails } from "../model";
2
+ import { ActivityConverterFactory } from "./factory";
3
+ export declare class ActivityConverter {
4
+ static factory?: ActivityConverterFactory;
5
+ static convert(activity: ActivityDetails, format: string): Promise<unknown>;
6
+ }
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ActivityConverter = void 0;
13
+ const factory_1 = require("./factory");
14
+ const fit_1 = require("./fit");
15
+ const tcx_1 = require("./tcx");
16
+ class ActivityConverter {
17
+ static convert(activity, format) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ if (!ActivityConverter.factory) {
20
+ ActivityConverter.factory = new factory_1.ActivityConverterFactory();
21
+ ActivityConverter.factory.add('fit', new fit_1.RemoteFitConverter());
22
+ ActivityConverter.factory.add('tcx', new tcx_1.TcxConverter());
23
+ }
24
+ return yield ActivityConverter.factory.convert(activity, format);
25
+ });
26
+ }
27
+ }
28
+ exports.ActivityConverter = ActivityConverter;
@@ -0,0 +1,8 @@
1
+ import { ActivityDetails } from "../model";
2
+ import { IActivityConverter } from "./types";
3
+ export declare class ActivityConverterFactory {
4
+ protected converters: Record<string, IActivityConverter>;
5
+ constructor();
6
+ add(format: string, converter: IActivityConverter): void;
7
+ convert(activity: ActivityDetails, targetFormat: string): Promise<any>;
8
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
3
+ function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
4
+ var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
5
+ var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
6
+ var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
7
+ var _, done = false;
8
+ for (var i = decorators.length - 1; i >= 0; i--) {
9
+ var context = {};
10
+ for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
11
+ for (var p in contextIn.access) context.access[p] = contextIn.access[p];
12
+ context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
13
+ var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
14
+ if (kind === "accessor") {
15
+ if (result === void 0) continue;
16
+ if (result === null || typeof result !== "object") throw new TypeError("Object expected");
17
+ if (_ = accept(result.get)) descriptor.get = _;
18
+ if (_ = accept(result.set)) descriptor.set = _;
19
+ if (_ = accept(result.init)) initializers.unshift(_);
20
+ }
21
+ else if (_ = accept(result)) {
22
+ if (kind === "field") initializers.unshift(_);
23
+ else descriptor[key] = _;
24
+ }
25
+ }
26
+ if (target) Object.defineProperty(target, contextIn.name, descriptor);
27
+ done = true;
28
+ };
29
+ var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
30
+ var useValue = arguments.length > 2;
31
+ for (var i = 0; i < initializers.length; i++) {
32
+ value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
33
+ }
34
+ return useValue ? value : void 0;
35
+ };
36
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
37
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
38
+ return new (P || (P = Promise))(function (resolve, reject) {
39
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
40
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
41
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
42
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
43
+ });
44
+ };
45
+ var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
46
+ if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
47
+ return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.ActivityConverterFactory = void 0;
51
+ const types_1 = require("../../../base/types");
52
+ let ActivityConverterFactory = (() => {
53
+ let _classDecorators = [types_1.Singleton];
54
+ let _classDescriptor;
55
+ let _classExtraInitializers = [];
56
+ let _classThis;
57
+ var ActivityConverterFactory = _classThis = class {
58
+ constructor() {
59
+ this.converters = {};
60
+ }
61
+ add(format, converter) {
62
+ if (!format || !converter)
63
+ return;
64
+ this.converters[format.toLowerCase()] = converter;
65
+ }
66
+ convert(activity, targetFormat) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ if (!activity || !targetFormat)
69
+ throw new Error('illegal use: activity and format need to be specified');
70
+ const format = targetFormat.toLowerCase();
71
+ const converter = this.converters[format];
72
+ if (!converter)
73
+ throw new Error(`unknown format: ${targetFormat}`);
74
+ const res = yield converter.convert(activity);
75
+ return res;
76
+ });
77
+ }
78
+ };
79
+ __setFunctionName(_classThis, "ActivityConverterFactory");
80
+ (() => {
81
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
82
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
83
+ ActivityConverterFactory = _classThis = _classDescriptor.value;
84
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
85
+ __runInitializers(_classThis, _classExtraInitializers);
86
+ })();
87
+ return ActivityConverterFactory = _classThis;
88
+ })();
89
+ exports.ActivityConverterFactory = ActivityConverterFactory;
@@ -0,0 +1 @@
1
+ export * from './remote-fit';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./remote-fit"), exports);
@@ -0,0 +1,13 @@
1
+ import { EventLogger } from 'gd-eventlog';
2
+ import { IncyclistFitConvertApi } from '../../api/fitconvert';
3
+ import { ActivityDetails, ActivityLogRecord, FitExportActivity, FitLogEntry } from '../../model';
4
+ export declare class RemoteFitConverter {
5
+ protected logger: EventLogger;
6
+ protected api: IncyclistFitConvertApi;
7
+ constructor();
8
+ convert(activity: ActivityDetails): Promise<ArrayBuffer>;
9
+ protected getApi(): IncyclistFitConvertApi;
10
+ protected getFitActivity(activity: ActivityDetails): FitExportActivity;
11
+ protected mapLogToFit(log: ActivityLogRecord): FitLogEntry;
12
+ protected getUserSettings(): import("../../../../settings").UserSettingsService;
13
+ }
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RemoteFitConverter = void 0;
13
+ const gd_eventlog_1 = require("gd-eventlog");
14
+ const fitconvert_1 = require("../../api/fitconvert");
15
+ const settings_1 = require("../../../../settings");
16
+ class RemoteFitConverter {
17
+ constructor() {
18
+ this.logger = new gd_eventlog_1.EventLogger('RemoteFitExporter');
19
+ }
20
+ convert(activity) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ try {
23
+ this.logger.logEvent({ message: 'convert start', format: 'FIT' });
24
+ const content = this.getFitActivity(activity);
25
+ const data = yield this.getApi().convertToFit(content);
26
+ this.logger.logEvent({ message: 'convert success', format: 'FIT' });
27
+ return data;
28
+ }
29
+ catch (err) {
30
+ this.logger.logEvent({ message: 'convert result', format: 'FIT', result: 'error', reason: err.message });
31
+ throw err;
32
+ }
33
+ });
34
+ }
35
+ getApi() {
36
+ if (!this.api)
37
+ this.api = new fitconvert_1.IncyclistFitConvertApi();
38
+ return this.api;
39
+ }
40
+ getFitActivity(activity) {
41
+ const { id, title, time, timeTotal, timePause, distance } = activity;
42
+ const status = 'created';
43
+ const startTime = new Date(activity.startTime).toISOString();
44
+ const logs = activity.logs.map(this.mapLogToFit.bind(this));
45
+ const screenshots = [];
46
+ const laps = [];
47
+ const user = {
48
+ id: this.getUserSettings().get('uuid', undefined),
49
+ weight: activity.user.weight
50
+ };
51
+ return { id, title, status, logs, laps, startTime, time, timeTotal, timePause, distance, user, screenshots };
52
+ }
53
+ mapLogToFit(log) {
54
+ const { time, speed, slope, cadence, heartrate, distance, power, lat, lng, elevation } = log;
55
+ return { time, speed, slope, cadence, heartrate, distance, power, lat, lon: lng, elevation };
56
+ }
57
+ getUserSettings() {
58
+ return (0, settings_1.useUserSettings)();
59
+ }
60
+ }
61
+ exports.RemoteFitConverter = RemoteFitConverter;
@@ -0,0 +1,4 @@
1
+ export * from './factory';
2
+ export * from './tcx';
3
+ export * from './fit';
4
+ export * from './converter';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./factory"), exports);
18
+ __exportStar(require("./tcx"), exports);
19
+ __exportStar(require("./fit"), exports);
20
+ __exportStar(require("./converter"), exports);
@@ -0,0 +1 @@
1
+ export * from './tcx';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./tcx"), exports);
@@ -0,0 +1,12 @@
1
+ import { EventLogger } from 'gd-eventlog';
2
+ import { TrackPoint, ActivityLap } from 'tcx-builder';
3
+ import { IActivityConverter } from '../types';
4
+ import { ActivityDetails } from '../../model';
5
+ export declare class TcxConverter implements IActivityConverter {
6
+ protected logger: EventLogger;
7
+ constructor();
8
+ convert(activity: ActivityDetails): Promise<string>;
9
+ protected createLaps(startTime: Date, activity: ActivityDetails, trackPoints: TrackPoint[]): ActivityLap[];
10
+ protected creatTrackPoints(activity: ActivityDetails, startTime: Date): TrackPoint[];
11
+ protected getRideService(): import("../../../ride").ActivityRideService;
12
+ }
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.TcxConverter = void 0;
13
+ const gd_eventlog_1 = require("gd-eventlog");
14
+ const tcx_builder_1 = require("tcx-builder");
15
+ const ride_1 = require("../../../ride");
16
+ class TcxConverter {
17
+ constructor() {
18
+ this.logger = new gd_eventlog_1.EventLogger('TcxExporter');
19
+ }
20
+ convert(activity) {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ this.logger.logEvent({ message: 'convert start', format: 'TCX' });
23
+ try {
24
+ const startTime = new Date(activity.startTime);
25
+ const trackPoints = this.creatTrackPoints(activity, startTime);
26
+ const laps = this.createLaps(startTime, activity, trackPoints);
27
+ const tcxActivity = new tcx_builder_1.Activity('Biking', { Id: startTime, Notes: 'Incyclist Ride', Laps: laps });
28
+ const activityList = new tcx_builder_1.ActivityList({ activity: [tcxActivity] });
29
+ const tcxObj = new tcx_builder_1.TrainingCenterDatabase({ activities: activityList });
30
+ const xml = tcxObj.toXml();
31
+ this.logger.logEvent({ message: 'convert success', format: 'TCX' });
32
+ return xml;
33
+ }
34
+ catch (err) {
35
+ this.logger.logEvent({ message: 'convert result', format: 'TCX', result: 'error', error: err.message });
36
+ throw err;
37
+ }
38
+ });
39
+ }
40
+ createLaps(startTime, activity, trackPoints) {
41
+ var _a, _b, _c, _d, _e, _f, _g, _h;
42
+ const lap = new tcx_builder_1.ActivityLap(startTime, {
43
+ Calories: 0,
44
+ DistanceMeters: activity.distance,
45
+ Intensity: 'Active',
46
+ TotalTimeSeconds: activity.time,
47
+ TriggerMethod: 'Distance',
48
+ MaximumSpeed: ((_b = (_a = activity.stats) === null || _a === void 0 ? void 0 : _a.speed) === null || _b === void 0 ? void 0 : _b.max) || 0,
49
+ MaximumHeartRateBpm: ((_c = activity.stats) === null || _c === void 0 ? void 0 : _c.hrm) ? new tcx_builder_1.HeartRateInBeatsPerMinute({ value: (_d = activity.stats.hrm) === null || _d === void 0 ? void 0 : _d.max }) : undefined,
50
+ AverageHeartRateBpm: ((_e = activity.stats) === null || _e === void 0 ? void 0 : _e.hrm) ? new tcx_builder_1.HeartRateInBeatsPerMinute({ value: (_f = activity.stats.hrm) === null || _f === void 0 ? void 0 : _f.avg }) : undefined,
51
+ Cadence: (_h = (_g = activity.stats) === null || _g === void 0 ? void 0 : _g.cadence) === null || _h === void 0 ? void 0 : _h.avg,
52
+ Track: new tcx_builder_1.Track({ trackPoints })
53
+ });
54
+ return [lap];
55
+ }
56
+ creatTrackPoints(activity, startTime) {
57
+ return activity.logs.map((log) => {
58
+ const tp = new tcx_builder_1.TrackPoint({
59
+ time: log ? new Date(startTime.valueOf() + log.time * 1000) : undefined,
60
+ altitudeMeters: log === null || log === void 0 ? void 0 : log.elevation,
61
+ distanceMeters: log === null || log === void 0 ? void 0 : log.distance,
62
+ heartRateBpm: (log === null || log === void 0 ? void 0 : log.heartrate) ? new tcx_builder_1.HeartRateBpm(log.heartrate) : undefined,
63
+ cadence: log === null || log === void 0 ? void 0 : log.cadence,
64
+ sensorState: 'Present',
65
+ extensions: new tcx_builder_1.TrackPointExtensions({
66
+ Speed: log === null || log === void 0 ? void 0 : log.speed,
67
+ Watts: log === null || log === void 0 ? void 0 : log.power,
68
+ }),
69
+ });
70
+ const lat = log === null || log === void 0 ? void 0 : log.lat;
71
+ let lng;
72
+ if ((activity === null || activity === void 0 ? void 0 : activity.type) === 'IncyclistActivity') {
73
+ lng = log === null || log === void 0 ? void 0 : log.lng;
74
+ }
75
+ else {
76
+ lng = log === null || log === void 0 ? void 0 : log.lon;
77
+ }
78
+ if (!isNaN(Number(lat !== null && lat !== void 0 ? lat : 'XX')) && !isNaN(Number(lng !== null && lng !== void 0 ? lng : 'XX')))
79
+ tp.Position = new tcx_builder_1.Position(lat, lng);
80
+ return tp;
81
+ });
82
+ }
83
+ getRideService() {
84
+ return (0, ride_1.useActivityRide)();
85
+ }
86
+ }
87
+ exports.TcxConverter = TcxConverter;
@@ -0,0 +1,7 @@
1
+ import { ActivityDetails } from "../model";
2
+ export interface IActivityConverter {
3
+ convert(activity: ActivityDetails): any;
4
+ }
5
+ export declare class ActivityConverter implements IActivityConverter {
6
+ convert(activity?: ActivityDetails): void;
7
+ }
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActivityConverter = void 0;
4
+ class ActivityConverter {
5
+ convert(activity) {
6
+ throw new Error("Method not implemented.");
7
+ }
8
+ }
9
+ exports.ActivityConverter = ActivityConverter;
@@ -1,3 +1,5 @@
1
1
  export * from './repo';
2
2
  export * from './model';
3
3
  export * from './utils';
4
+ export * from './convert';
5
+ export * from './api/fitconvert';
@@ -17,3 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./repo"), exports);
18
18
  __exportStar(require("./model"), exports);
19
19
  __exportStar(require("./utils"), exports);
20
+ __exportStar(require("./convert"), exports);
21
+ __exportStar(require("./api/fitconvert"), exports);
@@ -2,7 +2,7 @@ import { RoutePoint } from "../../../routes/base/types";
2
2
  export type ActivityUser = {
3
3
  uuid?: string;
4
4
  weight: number;
5
- ftp: number;
5
+ ftp?: number;
6
6
  };
7
7
  export type ActivityRoute = {
8
8
  id?: string;
@@ -18,20 +18,6 @@ export type ActivityStatsRecord = {
18
18
  minAllowed?: number;
19
19
  weighted?: number;
20
20
  };
21
- export type ActivityLogRecord = {
22
- time: number;
23
- timeDelta: number;
24
- speed: number;
25
- slope?: number;
26
- cadence: number;
27
- heartrate?: number;
28
- distance?: number;
29
- power: number;
30
- lat?: number;
31
- lon?: number;
32
- lng?: number;
33
- elevation?: number;
34
- };
35
21
  export type ActivityStats = {
36
22
  hrm?: ActivityStatsRecord;
37
23
  cadence?: ActivityStatsRecord;
@@ -124,7 +110,7 @@ export type FitExportActivity = {
124
110
  logs: Array<FitLogEntry>;
125
111
  laps: Array<FitLapEntry>;
126
112
  startTime: string;
127
- stopTime: string;
113
+ stopTime?: string;
128
114
  time: number;
129
115
  timeTotal: number;
130
116
  distance: number;
@@ -162,6 +148,20 @@ export interface ActivityDetails {
162
148
  fitFileName?: string;
163
149
  links?: ActivityAppLinks;
164
150
  }
151
+ export type ActivityLogRecord = {
152
+ time: number;
153
+ timeDelta: number;
154
+ speed: number;
155
+ slope?: number;
156
+ cadence: number;
157
+ heartrate?: number;
158
+ distance?: number;
159
+ power: number;
160
+ lat?: number;
161
+ lng?: number;
162
+ elevation?: number;
163
+ lon?: number;
164
+ };
165
165
  export type ActivityInfo = {
166
166
  summary: ActivitySummary;
167
167
  details?: ActivityDetails;
@@ -3,7 +3,7 @@ import { IncyclistService } from "../../base/service";
3
3
  import { Observer } from "../../base/types/observer";
4
4
  import { DeviceData } from "incyclist-devices";
5
5
  import { ExtendedIncyclistCapability, HealthStatus } from "../../devices";
6
- import { ActivitiesRepository, ActivityDetails, ActivityLogRecord, ActivityRouteType, FitExportActivity, FitLogEntry, ScreenShotInfo } from "../base";
6
+ import { ActivitiesRepository, ActivityDetails, ActivityLogRecord, ActivityRouteType, ScreenShotInfo } from "../base";
7
7
  import { FreeRideStartSettings } from "../../routes/list/types";
8
8
  import { RoutePoint } from "../../routes/base/types";
9
9
  import { ActivityState } from "./types";
@@ -53,8 +53,6 @@ export declare class ActivityRideService extends IncyclistService {
53
53
  getDashboardDisplayProperties(): any[];
54
54
  getActivitySummaryDisplayProperties(): void;
55
55
  getActivity(): ActivityDetails;
56
- protected mapLogToFit(log: ActivityLogRecord): FitLogEntry;
57
- getFitActivity(): FitExportActivity;
58
56
  save(): Promise<void>;
59
57
  getObserver(): Observer;
60
58
  addSceenshot(screenshot: ScreenShotInfo): void;
@@ -121,6 +121,8 @@ let ActivityRideService = (() => {
121
121
  }
122
122
  stop() {
123
123
  this.stopWorker();
124
+ if (!this.observer)
125
+ return;
124
126
  (0, devices_1.useDeviceRide)().off('data', this.deviceDataHandler);
125
127
  this.state = 'completed';
126
128
  this.updateActivityTime();
@@ -132,6 +134,8 @@ let ActivityRideService = (() => {
132
134
  }
133
135
  updateActivityTime() {
134
136
  var _a;
137
+ if (!this.activity)
138
+ return;
135
139
  this.activity.timeTotal = (Date.now() - this.tsStart) / 1000;
136
140
  this.activity.time = this.activity.timeTotal - ((_a = this.activity.timePause) !== null && _a !== void 0 ? _a : 0);
137
141
  }
@@ -229,24 +233,6 @@ let ActivityRideService = (() => {
229
233
  getActivity() {
230
234
  return this.activity;
231
235
  }
232
- mapLogToFit(log) {
233
- const { time, speed, slope, cadence, heartrate, distance, power, lat, lng, elevation } = log;
234
- return { time, speed, slope, cadence, heartrate, distance, power, lat, lon: lng, elevation };
235
- }
236
- getFitActivity() {
237
- const { id, title, time, timeTotal, timePause, distance } = this.activity;
238
- const status = 'active';
239
- const startTime = new Date(this.activity.startTime).toISOString();
240
- const logs = this.activity.logs.map(this.mapLogToFit.bind(this));
241
- const screenshots = [];
242
- const laps = [];
243
- const user = {
244
- id: this.getUserSettings().get('uuid', undefined),
245
- weight: this.activity.user.weight
246
- };
247
- const stopTime = new Date(this.tsStart + timeTotal * 1000).toISOString();
248
- return { id, title, status, logs, laps, startTime, stopTime, time, timeTotal, timePause, distance, user, screenshots };
249
- }
250
236
  save() {
251
237
  return this._save();
252
238
  }
@@ -338,13 +324,13 @@ let ActivityRideService = (() => {
338
324
  return new base_1.ActivitiesRepository();
339
325
  }
340
326
  createLogRecord() {
341
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
327
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
342
328
  const prevLogs = this.activity.logs;
343
329
  const prev = (prevLogs === null || prevLogs === void 0 ? void 0 : prevLogs.length) ? prevLogs[prevLogs.length - 1] : undefined;
344
330
  const time = this.activity.time;
345
331
  const timeDelta = prev ? time - prev.time : time;
346
332
  const deviceData = (_a = this.current) === null || _a === void 0 ? void 0 : _a.deviceData;
347
- const distance = ((_b = this.current.routeDistance) !== null && _b !== void 0 ? _b : 0) - ((_c = this.prevLogRouteDistane) !== null && _c !== void 0 ? _c : this.activity.startPos);
333
+ const distance = ((_c = (_b = this.current.routeDistance) !== null && _b !== void 0 ? _b : this.activity.startPos) !== null && _c !== void 0 ? _c : 0) - ((_d = this.activity.startPos) !== null && _d !== void 0 ? _d : 0);
348
334
  this.prevLogRouteDistane = this.current.routeDistance;
349
335
  const log = {
350
336
  time,
@@ -354,13 +340,13 @@ let ActivityRideService = (() => {
354
340
  heartrate: deviceData === null || deviceData === void 0 ? void 0 : deviceData.heartrate,
355
341
  power: deviceData === null || deviceData === void 0 ? void 0 : deviceData.power,
356
342
  distance,
357
- slope: (_d = this.current.position) === null || _d === void 0 ? void 0 : _d.slope,
358
- elevation: (_e = this.current.position) === null || _e === void 0 ? void 0 : _e.elevation
343
+ slope: (_e = this.current.position) === null || _e === void 0 ? void 0 : _e.slope,
344
+ elevation: (_f = this.current.position) === null || _f === void 0 ? void 0 : _f.elevation
359
345
  };
360
- if (((_g = (_f = this.current) === null || _f === void 0 ? void 0 : _f.position) === null || _g === void 0 ? void 0 : _g.lat) && !isNaN((_j = (_h = this.current) === null || _h === void 0 ? void 0 : _h.position) === null || _j === void 0 ? void 0 : _j.lat))
361
- log.lat = (_l = (_k = this.current) === null || _k === void 0 ? void 0 : _k.position) === null || _l === void 0 ? void 0 : _l.lat;
362
- if (((_o = (_m = this.current) === null || _m === void 0 ? void 0 : _m.position) === null || _o === void 0 ? void 0 : _o.lng) && !isNaN((_q = (_p = this.current) === null || _p === void 0 ? void 0 : _p.position) === null || _q === void 0 ? void 0 : _q.lng)) {
363
- log.lng = (_s = (_r = this.current) === null || _r === void 0 ? void 0 : _r.position) === null || _s === void 0 ? void 0 : _s.lng;
346
+ if (((_h = (_g = this.current) === null || _g === void 0 ? void 0 : _g.position) === null || _h === void 0 ? void 0 : _h.lat) && !isNaN((_k = (_j = this.current) === null || _j === void 0 ? void 0 : _j.position) === null || _k === void 0 ? void 0 : _k.lat))
347
+ log.lat = (_m = (_l = this.current) === null || _l === void 0 ? void 0 : _l.position) === null || _m === void 0 ? void 0 : _m.lat;
348
+ if (((_p = (_o = this.current) === null || _o === void 0 ? void 0 : _o.position) === null || _p === void 0 ? void 0 : _p.lng) && !isNaN((_r = (_q = this.current) === null || _q === void 0 ? void 0 : _q.position) === null || _r === void 0 ? void 0 : _r.lng)) {
349
+ log.lng = (_t = (_s = this.current) === null || _s === void 0 ? void 0 : _s.position) === null || _t === void 0 ? void 0 : _t.lng;
364
350
  }
365
351
  return log;
366
352
  }
@@ -509,11 +495,13 @@ let ActivityRideService = (() => {
509
495
  if (time !== prev) {
510
496
  const distance = this.current.routeDistance - ((_b = (_a = this.prevEmit) === null || _a === void 0 ? void 0 : _a.routeDistance) !== null && _b !== void 0 ? _b : 0);
511
497
  const data = {
498
+ time: this.activity.time,
512
499
  speed: this.current.deviceData.speed,
513
500
  routeDistance: this.current.routeDistance,
514
501
  distance
515
502
  };
516
503
  this.emit('data', data);
504
+ this.prevEmit = data;
517
505
  const logRecord = this.createLogRecord();
518
506
  if (logRecord) {
519
507
  this.activity.logs.push(logRecord);
@@ -1,5 +1,6 @@
1
1
  import { EventLogger } from "gd-eventlog";
2
- import { JSONObject, JsonAccess } from "../types";
2
+ import { JsonAccess } from "../types";
3
+ import { JSONObject } from "../../../utils/xml";
3
4
  export declare class JsonRepository {
4
5
  protected static _instances: {
5
6
  [x: string]: JsonRepository;
@@ -1,6 +1,4 @@
1
- export type JSONObject = string | number | boolean | {
2
- [x: string]: JSONObject;
3
- } | Array<JSONObject>;
1
+ import { JSONObject } from "../../utils/xml";
4
2
  export type JsonAccess = {
5
3
  read(resourceName: string): Promise<JSONObject>;
6
4
  write(resourceName: string, data: JSONObject): Promise<boolean>;
@@ -1,7 +1,7 @@
1
1
  import { FileInfo } from "../../../api";
2
2
  import { RouteApiDetail } from "../api/types";
3
3
  import { ParseResult, Parser } from "../types";
4
- import { XmlJSON } from "../utils/xml";
4
+ import { XmlJSON } from "../../../utils/xml";
5
5
  import { XMLParser } from "./xml";
6
6
  export declare class MultipleXMLParser implements Parser<XmlJSON, RouteApiDetail> {
7
7
  protected parsers: any;
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.MultipleXMLParser = void 0;
13
13
  const api_1 = require("../../../api");
14
- const xml_1 = require("../utils/xml");
14
+ const xml_1 = require("../../../utils/xml");
15
15
  class MultipleXMLParser {
16
16
  constructor(classes) {
17
17
  this.parsers = [];
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
- import { FileInfo, JSONObject } from "../../../api";
2
+ import { FileInfo } from "../../../api";
3
3
  import { RouteInfoText } from "../types";
4
+ import { JSONObject } from "../../../utils/xml";
4
5
  export declare class BinaryReader {
5
6
  protected pos: number;
6
7
  protected buffer: Buffer;
@@ -1,7 +1,7 @@
1
- import { XmlJSON } from '../utils/xml';
1
+ import { JSONObject, XmlJSON } from '../../../utils/xml';
2
2
  import { RouteApiDetail } from '../api/types';
3
3
  import { ParseResult, Parser, RouteInfo } from '../types';
4
- import { FileInfo, JSONObject } from '../../../api';
4
+ import { FileInfo } from '../../../api';
5
5
  export type XmlParserContext = {
6
6
  fileInfo: FileInfo;
7
7
  data: JSONObject;
@@ -11,7 +11,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.XMLParser = void 0;
13
13
  const gd_eventlog_1 = require("gd-eventlog");
14
- const xml_1 = require("../utils/xml");
14
+ const xml_1 = require("../../../utils/xml");
15
15
  const api_1 = require("../../../api");
16
16
  const route_1 = require("../utils/route");
17
17
  const utils_1 = require("./utils");
@@ -259,7 +259,7 @@ const getNextPosition = (route, props) => {
259
259
  let lap = (0, valid_1.valid)(pPrev.lap) ? pPrev.lap : 1;
260
260
  let cnt = ((_a = props.prev) === null || _a === void 0 ? void 0 : _a.cnt) || 0;
261
261
  let targetRouteInLap;
262
- if (route.description.isLoop) {
262
+ if ((0, exports.checkIsLoop)(route)) {
263
263
  targetRouteInLap = targetRouteDistance % route.description.distance;
264
264
  const prevTargetRouteinLap = props.prev.routeDistance;
265
265
  if (prevTargetRouteinLap > targetRouteInLap) {
@@ -378,7 +378,7 @@ function updatePoint(pPrev, point, props, p, distance, targetRouteInLap, route,
378
378
  point.lng = pDest.lng;
379
379
  point.routeDistance = targetRouteInLap;
380
380
  point.distance = point.routeDistance - pPrev.routeDistance;
381
- point.elevation = point.distance * pPrev.slope / 100;
381
+ point.elevation = pPrev.elevation + point.distance * pPrev.slope / 100;
382
382
  if (route.description.isLoop) {
383
383
  point.lap = lap;
384
384
  }
@@ -407,6 +407,7 @@ const createFromJson = (data) => {
407
407
  }
408
408
  const routeInfo = buildRouteInfo(data);
409
409
  const route = new route_1.Route(routeInfo, data);
410
+ (0, exports.validateRoute)(route.details);
410
411
  return route;
411
412
  };
412
413
  exports.createFromJson = createFromJson;
@@ -1,4 +1,6 @@
1
- import { JSONObject } from '../../../api';
1
+ export type JSONObject = string | number | boolean | {
2
+ [x: string]: JSONObject;
3
+ } | Array<JSONObject>;
2
4
  export declare const toXml: (obj: JSONObject) => string;
3
5
  export declare const parseXml: (str: string) => Promise<XmlJSON>;
4
6
  export declare class XmlJSON {
@@ -2,3 +2,4 @@ export declare const formatDateTime: (date: Date, fstr?: string, utc?: boolean)
2
2
  export declare const formatTime: (seconds: number, cutMissing: boolean) => string;
3
3
  export declare const formatNumber: (value: number, maxDigits: number, maxLength?: number) => string;
4
4
  export declare const pad: (value: number, size?: number) => string;
5
+ export declare const trimTrailingChars: (s: string, charToTrim: string) => string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.pad = exports.formatNumber = exports.formatTime = exports.formatDateTime = void 0;
3
+ exports.trimTrailingChars = exports.pad = exports.formatNumber = exports.formatTime = exports.formatDateTime = void 0;
4
4
  const valid_1 = require("./valid");
5
5
  const formatDateTime = (date, fstr = '%Y%m%d%H%M%S', utc = false) => {
6
6
  if (!(0, valid_1.valid)(date) || !(date instanceof Date))
@@ -69,3 +69,13 @@ const pad = (value, size = 2) => {
69
69
  return s;
70
70
  };
71
71
  exports.pad = pad;
72
+ const trimTrailingChars = (s, charToTrim) => {
73
+ let c = charToTrim;
74
+ if (charToTrim === undefined) {
75
+ c = s.charAt(s.length - 1);
76
+ }
77
+ const regExp = new RegExp(c + "+$");
78
+ const result = s.replace(regExp, "");
79
+ return result;
80
+ };
81
+ exports.trimTrailingChars = trimTrailingChars;
@@ -3,3 +3,4 @@ export * as geo from './geo';
3
3
  export * as math from './math';
4
4
  export * from './nextTick';
5
5
  export * from './formatting';
6
+ export * from './xml';
@@ -32,3 +32,4 @@ exports.geo = __importStar(require("./geo"));
32
32
  exports.math = __importStar(require("./math"));
33
33
  __exportStar(require("./nextTick"), exports);
34
34
  __exportStar(require("./formatting"), exports);
35
+ __exportStar(require("./xml"), exports);
@@ -0,0 +1,17 @@
1
+ export type JSONObject = string | number | boolean | {
2
+ [x: string]: JSONObject;
3
+ } | Array<JSONObject>;
4
+ export declare const toXml: (obj: JSONObject) => string;
5
+ export declare const parseXml: (str: string) => Promise<XmlJSON>;
6
+ export declare class XmlJSON {
7
+ private _json;
8
+ private scheme?;
9
+ constructor(_json: JSONObject, scheme?: string);
10
+ get json(): any;
11
+ get raw(): JSONObject;
12
+ expectScheme(scheme: string): void;
13
+ getSchemeData(): JSONObject;
14
+ detectScheme(): string;
15
+ get(key: any): any;
16
+ map(key: any, item: any): any;
17
+ }
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.XmlJSON = exports.parseXml = exports.toXml = void 0;
13
+ const xml2js_1 = require("xml2js");
14
+ const toXml = (obj) => {
15
+ const keys = Object.keys(obj);
16
+ let xml = '';
17
+ keys.forEach((key, index) => {
18
+ const value = obj[key];
19
+ if (value !== undefined)
20
+ xml += `${index > 0 ? ' ' : ''}${key}="${value}"`;
21
+ });
22
+ return xml;
23
+ };
24
+ exports.toXml = toXml;
25
+ const parseXml = (str) => __awaiter(void 0, void 0, void 0, function* () {
26
+ return new Promise((resolve, reject) => {
27
+ (0, xml2js_1.parseString)(str, (err, result) => {
28
+ if (err) {
29
+ return reject(err);
30
+ }
31
+ return resolve(new XmlJSON(result));
32
+ });
33
+ });
34
+ });
35
+ exports.parseXml = parseXml;
36
+ class XmlJSON {
37
+ constructor(_json, scheme) {
38
+ this._json = _json;
39
+ this.scheme = scheme;
40
+ }
41
+ get json() {
42
+ if (!this.scheme)
43
+ return this._json;
44
+ return this.map(this.scheme, this._json[this.scheme]);
45
+ }
46
+ get raw() {
47
+ return this._json;
48
+ }
49
+ expectScheme(scheme) {
50
+ this.detectScheme();
51
+ if (scheme !== this.scheme) {
52
+ if (!this._json[scheme])
53
+ throw new Error(`cannot parse <${this.scheme}>`);
54
+ this.scheme = scheme;
55
+ }
56
+ }
57
+ getSchemeData() {
58
+ if (!this.scheme)
59
+ return this._json;
60
+ return this._json[this.scheme];
61
+ }
62
+ detectScheme() {
63
+ const keys = Object.keys(this._json);
64
+ if (keys.length === 1) {
65
+ this.scheme = keys[0];
66
+ return this.scheme;
67
+ }
68
+ }
69
+ get(key) {
70
+ const data = this.getSchemeData();
71
+ const item = data[key] ? data[key][0] : undefined;
72
+ if (item === undefined)
73
+ return undefined;
74
+ return this.map(key, item);
75
+ }
76
+ map(key, item) {
77
+ if (typeof (item) === 'object') {
78
+ const keys = Object.keys(item);
79
+ if (keys.length === 1 && keys[0] === '0') {
80
+ return this.map(key, item[keys[0]]);
81
+ }
82
+ if (keys.length === 1 && `${keys[0]}s` === key) {
83
+ return item[keys[0]].map(i => this.map(key, i.$));
84
+ }
85
+ else if (!keys.find(k => isNaN(Number(k)))) {
86
+ const obj = [];
87
+ keys.forEach(key => {
88
+ if (key === '$')
89
+ Object.assign(obj, this.map(key, item.$));
90
+ else
91
+ obj.push(this.map(key, item[key]));
92
+ });
93
+ return obj;
94
+ }
95
+ else {
96
+ const obj = {};
97
+ keys.forEach(key => {
98
+ if (key === '$')
99
+ Object.assign(obj, this.map(key, item.$));
100
+ else
101
+ obj[key] = this.map(key, item[key]);
102
+ });
103
+ return obj;
104
+ }
105
+ }
106
+ return item;
107
+ }
108
+ }
109
+ exports.XmlJSON = XmlJSON;
@@ -17,7 +17,7 @@ const gd_eventlog_1 = require("gd-eventlog");
17
17
  const api_1 = require("../../../api");
18
18
  const Workout_1 = require("../model/Workout");
19
19
  const xml2js_1 = __importDefault(require("xml2js"));
20
- const xml_1 = require("../../../routes/base/utils/xml");
20
+ const xml_1 = require("../../../utils/xml");
21
21
  const parser = new xml2js_1.default.Parser({ explicitChildren: true, preserveChildrenOrder: true, mergeAttrs: false });
22
22
  const intVal = v => Number.parseInt(v);
23
23
  const floatVal = v => Number.parseFloat(v);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "incyclist-services",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "peerDependencies": {
5
5
  "gd-eventlog": "^0.1.26"
6
6
  },
@@ -23,7 +23,9 @@
23
23
  "lint": "eslint . --ext .ts",
24
24
  "buildx": "npm run lint && tsc",
25
25
  "build": "tsc",
26
- "test": "npx jest --coverage",
26
+ "test": "npx jest",
27
+ "test:e2e": "npx jest --coverage -c jest.e2e-config.js --coverageDirectory coverage.e2e",
28
+ "test:unit": "npx jest --coverage -c jest.unit-config.js ",
27
29
  "dev": "tsc --watch",
28
30
  "docgen": "typedoc --options typedoc.json",
29
31
  "docgen1": "typedoc --readme none --excludeProtected --excludePrivate --plugin typedoc-plugin-no-inherit --plugin typedoc-plugin-markdown src/index.ts",
@@ -41,6 +43,7 @@
41
43
  "axios": "^1.6.1",
42
44
  "incyclist-devices": "^2.2.1",
43
45
  "promise.any": "^2.0.6",
46
+ "tcx-builder": "^1.1.1",
44
47
  "uuid": "^9.0.0",
45
48
  "xml2js": "^0.6.2"
46
49
  }