@sports-alliance/sports-lib 6.1.0 → 6.1.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.
- package/jest.config.js +3 -2
- package/lib/cjs/activities/activity.d.ts +1 -0
- package/lib/cjs/activities/activity.interface.d.ts +5 -0
- package/lib/cjs/activities/activity.js +7 -0
- package/lib/cjs/activities/activity.types.d.ts +1 -0
- package/lib/cjs/activities/activity.types.js +1 -0
- package/lib/cjs/data/data.store.export.spec.js +2 -2
- package/lib/cjs/events/adapters/importers/fit/importer.fit.garmin.profile.data.d.ts +12 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.garmin.profile.data.js +868 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.d.ts +22 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.js +110 -0
- package/lib/cjs/events/adapters/importers/fit/importer.fit.js +26 -10
- package/lib/cjs/events/adapters/importers/fit/importer.fit.spec.js +1 -1
- package/lib/cjs/index.d.ts +114 -0
- package/lib/cjs/index.js +124 -0
- package/lib/cjs/specs/activity-duration-stream.integration.spec.d.ts +1 -0
- package/lib/cjs/specs/activity-duration-stream.integration.spec.js +59 -0
- package/lib/esm/activities/activity.d.ts +1 -0
- package/lib/esm/activities/activity.interface.d.ts +5 -0
- package/lib/esm/activities/activity.js +7 -0
- package/lib/esm/activities/activity.types.d.ts +1 -0
- package/lib/esm/activities/activity.types.js +1 -0
- package/lib/esm/data/data.store.export.spec.js +2 -2
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.data.d.ts +12 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.data.js +865 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.d.ts +22 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.garmin.profile.mapper.js +106 -0
- package/lib/esm/events/adapters/importers/fit/importer.fit.js +26 -10
- package/lib/esm/events/adapters/importers/fit/importer.fit.spec.js +1 -1
- package/lib/esm/index.d.ts +114 -0
- package/lib/esm/index.js +114 -0
- package/lib/esm/specs/activity-duration-stream.integration.spec.d.ts +1 -0
- package/lib/esm/specs/activity-duration-stream.integration.spec.js +57 -0
- package/package.json +2 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare class GarminProfileMapper {
|
|
2
|
+
/**
|
|
3
|
+
* Translates a Garmin Product ID to a readable device name
|
|
4
|
+
*/
|
|
5
|
+
static getDeviceName(productId: number | string): string | null;
|
|
6
|
+
/**
|
|
7
|
+
* Translates a Manufacturer ID to a readable name
|
|
8
|
+
*/
|
|
9
|
+
static getManufacturerName(manufacturerId: number | string): string | null;
|
|
10
|
+
/**
|
|
11
|
+
* Translates a Sport ID to a readable name
|
|
12
|
+
*/
|
|
13
|
+
static getSportName(sportId: number | string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Translates a Sub-Sport ID to a readable name
|
|
16
|
+
*/
|
|
17
|
+
static getSubSportName(subSportId: number | string): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* Formats internal Garmin names into pretty names (e.g. fr945 -> Forerunner 945)
|
|
20
|
+
*/
|
|
21
|
+
private static formatDeviceName;
|
|
22
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GarminProfileMapper = void 0;
|
|
4
|
+
const importer_fit_garmin_profile_data_1 = require("./importer.fit.garmin.profile.data");
|
|
5
|
+
class GarminProfileMapper {
|
|
6
|
+
/**
|
|
7
|
+
* Translates a Garmin Product ID to a readable device name
|
|
8
|
+
*/
|
|
9
|
+
static getDeviceName(productId) {
|
|
10
|
+
if (productId === null || productId === undefined) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const id = typeof productId === 'string' ? parseInt(productId, 10) : productId;
|
|
14
|
+
const name = importer_fit_garmin_profile_data_1.GarminProducts[id];
|
|
15
|
+
return name ? this.formatDeviceName(name) : null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Translates a Manufacturer ID to a readable name
|
|
19
|
+
*/
|
|
20
|
+
static getManufacturerName(manufacturerId) {
|
|
21
|
+
if (manufacturerId === null || manufacturerId === undefined) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const id = typeof manufacturerId === 'string' ? parseInt(manufacturerId, 10) : manufacturerId;
|
|
25
|
+
return importer_fit_garmin_profile_data_1.GarminManufacturers[id] || null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Translates a Sport ID to a readable name
|
|
29
|
+
*/
|
|
30
|
+
static getSportName(sportId) {
|
|
31
|
+
if (sportId === null || sportId === undefined) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
const id = typeof sportId === 'string' ? parseInt(sportId, 10) : sportId;
|
|
35
|
+
return importer_fit_garmin_profile_data_1.GarminSports[id] || null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Translates a Sub-Sport ID to a readable name
|
|
39
|
+
*/
|
|
40
|
+
static getSubSportName(subSportId) {
|
|
41
|
+
if (subSportId === null || subSportId === undefined) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const id = typeof subSportId === 'string' ? parseInt(subSportId, 10) : subSportId;
|
|
45
|
+
return importer_fit_garmin_profile_data_1.GarminSubSports[id] || null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Formats internal Garmin names into pretty names (e.g. fr945 -> Forerunner 945)
|
|
49
|
+
*/
|
|
50
|
+
static formatDeviceName(name) {
|
|
51
|
+
if (!name)
|
|
52
|
+
return 'Unknown';
|
|
53
|
+
// First expand known abbreviations and add spaces
|
|
54
|
+
let formatted = name
|
|
55
|
+
.replace(/^fr(\d+)/i, 'Forerunner $1')
|
|
56
|
+
.replace(/^fenix(\d+)/i, 'Fenix $1')
|
|
57
|
+
.replace(/^edge(\d+)/i, 'Edge $1')
|
|
58
|
+
.replace(/^vivoactive/i, 'VivoActive')
|
|
59
|
+
.replace(/^vivosmart/i, 'VivoSmart')
|
|
60
|
+
.replace(/^vivofit/i, 'VivoFit')
|
|
61
|
+
.replace(/^vivomove/i, 'VivoMove')
|
|
62
|
+
.replace(/^vivosport/i, 'VivoSport')
|
|
63
|
+
.replace(/^approach([A-Z\d])/i, 'Approach $1')
|
|
64
|
+
.replace(/^marq([A-Z])/i, 'Marq $1')
|
|
65
|
+
.replace(/^hrm/i, 'HRM ')
|
|
66
|
+
.replace(/_/g, ' ') // Replace underscores with spaces
|
|
67
|
+
.replace(/([a-z])([A-Z0-9])/g, '$1 $2') // Add spaces between camelCase
|
|
68
|
+
.replace(/([0-9])([a-zA-Z])/g, '$1 $2'); // Add spaces between numbers and letters
|
|
69
|
+
// Capitalize and clean up special terms
|
|
70
|
+
formatted = formatted
|
|
71
|
+
.split(' ')
|
|
72
|
+
.map(word => {
|
|
73
|
+
const lower = word.toLowerCase();
|
|
74
|
+
if (lower === 'apac')
|
|
75
|
+
return 'APAC';
|
|
76
|
+
if (lower === 'xt')
|
|
77
|
+
return 'XT';
|
|
78
|
+
if (lower === 'lte')
|
|
79
|
+
return 'LTE';
|
|
80
|
+
if (lower === 'hr')
|
|
81
|
+
return 'HR';
|
|
82
|
+
if (lower === 'gps')
|
|
83
|
+
return 'GPS';
|
|
84
|
+
if (lower === 'ii')
|
|
85
|
+
return 'II';
|
|
86
|
+
if (lower === 'iii')
|
|
87
|
+
return 'III';
|
|
88
|
+
if (lower === 'm' && name.toLowerCase().includes('645m'))
|
|
89
|
+
return 'Music'; // Special case for Fr645m
|
|
90
|
+
if (lower === 'jpn')
|
|
91
|
+
return 'Japan';
|
|
92
|
+
if (lower === 'chn')
|
|
93
|
+
return 'China';
|
|
94
|
+
if (lower === 'twn')
|
|
95
|
+
return 'Taiwan';
|
|
96
|
+
if (lower === 'kor')
|
|
97
|
+
return 'Korea';
|
|
98
|
+
if (lower === 'rus')
|
|
99
|
+
return 'Russia';
|
|
100
|
+
if (lower === 'sea')
|
|
101
|
+
return 'SEA';
|
|
102
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
103
|
+
})
|
|
104
|
+
.join(' ')
|
|
105
|
+
.replace(/Vivo Active/g, 'VivoActive')
|
|
106
|
+
.trim();
|
|
107
|
+
return formatted;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
exports.GarminProfileMapper = GarminProfileMapper;
|
|
@@ -21,8 +21,8 @@ const activity_types_1 = require("../../../../activities/activity.types");
|
|
|
21
21
|
const data_duration_1 = require("../../../../data/data.duration");
|
|
22
22
|
const data_energy_1 = require("../../../../data/data.energy");
|
|
23
23
|
const data_distance_1 = require("../../../../data/data.distance");
|
|
24
|
-
const importer_fit_garmin_device_names_1 = require("./importer.fit.garmin.device.names");
|
|
25
24
|
const importer_fit_suunto_device_names_1 = require("./importer.fit.suunto.device.names");
|
|
25
|
+
const importer_fit_garmin_profile_mapper_1 = require("./importer.fit.garmin.profile.mapper");
|
|
26
26
|
const data_pause_1 = require("../../../../data/data.pause");
|
|
27
27
|
const data_cadence_avg_1 = require("../../../../data/data.cadence-avg");
|
|
28
28
|
const data_power_avg_1 = require("../../../../data/data.power-avg");
|
|
@@ -544,13 +544,24 @@ class EventImporterFIT {
|
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
546
|
static getActivityTypeFromSessionObject(session) {
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
547
|
+
const activityTypeKey = session.sub_sport && session.sub_sport !== 'generic' ? `${session.sport}_${session.sub_sport}` : session.sport;
|
|
548
|
+
let activityType = activity_types_1.ActivityTypes[activityTypeKey];
|
|
549
|
+
if (!activityType || activityType === activity_types_1.ActivityTypes.unknown) {
|
|
550
|
+
// Fallback to Garmin SDK mappings
|
|
551
|
+
const sportName = importer_fit_garmin_profile_mapper_1.GarminProfileMapper.getSportName(session.sport);
|
|
552
|
+
const subSportName = session.sub_sport && session.sub_sport !== 'generic'
|
|
553
|
+
? importer_fit_garmin_profile_mapper_1.GarminProfileMapper.getSubSportName(session.sub_sport)
|
|
554
|
+
: null;
|
|
555
|
+
if (sportName || subSportName) {
|
|
556
|
+
// Try to find in ActivityTypes using the name from Garmin SDK
|
|
557
|
+
const nameKey = subSportName ? `${sportName}_${subSportName}` : sportName;
|
|
558
|
+
activityType =
|
|
559
|
+
activity_types_1.ActivityTypes[nameKey] ||
|
|
560
|
+
activity_types_1.ActivityTypes[sportName] ||
|
|
561
|
+
nameKey;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return activityType || session.sport || activity_types_1.ActivityTypes.unknown;
|
|
554
565
|
}
|
|
555
566
|
// @todo move this to a mapper
|
|
556
567
|
static getStatsFromObject(object, activity, isLap) {
|
|
@@ -847,7 +858,7 @@ class EventImporterFIT {
|
|
|
847
858
|
break;
|
|
848
859
|
}
|
|
849
860
|
case 'garmin': {
|
|
850
|
-
recognizedName =
|
|
861
|
+
recognizedName = importer_fit_garmin_profile_mapper_1.GarminProfileMapper.getDeviceName(productId);
|
|
851
862
|
creator = new creator_1.Creator(formatDeviceName(manufacturer, productName, recognizedName, 'Garmin'), productId);
|
|
852
863
|
break;
|
|
853
864
|
}
|
|
@@ -908,7 +919,12 @@ class EventImporterFIT {
|
|
|
908
919
|
break;
|
|
909
920
|
}
|
|
910
921
|
default: {
|
|
911
|
-
|
|
922
|
+
// Try to find if it's a numeric Garmin mapping that was missed
|
|
923
|
+
const manufacturerName = typeof manufacturer === 'number' ? importer_fit_garmin_profile_mapper_1.GarminProfileMapper.getManufacturerName(manufacturer) : manufacturer;
|
|
924
|
+
if (manufacturerName === 'garmin') {
|
|
925
|
+
recognizedName = importer_fit_garmin_profile_mapper_1.GarminProfileMapper.getDeviceName(productId);
|
|
926
|
+
}
|
|
927
|
+
creator = new creator_1.Creator(formatDeviceName(manufacturer, productName, recognizedName, manufacturerName === 'garmin' ? 'Garmin' : null), productId);
|
|
912
928
|
}
|
|
913
929
|
}
|
|
914
930
|
creator.manufacturer = manufacturer;
|
|
@@ -48,7 +48,7 @@ describe('EventImporterFIT', () => {
|
|
|
48
48
|
it('should recognize a known Garmin device', done => {
|
|
49
49
|
const manufacturer = 'garmin';
|
|
50
50
|
const expectedName = 'Garmin Edge 1000';
|
|
51
|
-
const productId =
|
|
51
|
+
const productId = 1836;
|
|
52
52
|
const fitDataObject = generateFitDeviceDataObject(manufacturer, productId);
|
|
53
53
|
// When
|
|
54
54
|
const creator = importer_fit_1.EventImporterFIT.getCreatorFromFitDataObject(fitDataObject);
|
package/lib/cjs/index.d.ts
CHANGED
|
@@ -33,3 +33,117 @@ export declare class SportsLib {
|
|
|
33
33
|
*/
|
|
34
34
|
static importFromJSON(json: EventJSONInterface): EventInterface;
|
|
35
35
|
}
|
|
36
|
+
export * from './activities/activity.interface';
|
|
37
|
+
export * from './activities/activity.json.interface';
|
|
38
|
+
export * from './activities/activity.types';
|
|
39
|
+
export * from './constants/constants';
|
|
40
|
+
export * from './data/data-aerobic-training-effect';
|
|
41
|
+
export * from './data/data.absolute-pressure';
|
|
42
|
+
export * from './data/data.accumulated-power';
|
|
43
|
+
export * from './data/data.activity-types';
|
|
44
|
+
export * from './data/data.air-power';
|
|
45
|
+
export * from './data/data.altitude';
|
|
46
|
+
export * from './data/data.altitude-avg';
|
|
47
|
+
export * from './data/data.altitude-gps';
|
|
48
|
+
export * from './data/data.altitude-max';
|
|
49
|
+
export * from './data/data.altitude-min';
|
|
50
|
+
export * from './data/data.ascent';
|
|
51
|
+
export * from './data/data.cadence-avg';
|
|
52
|
+
export * from './data/data.cadence-max';
|
|
53
|
+
export * from './data/data.cadence-min';
|
|
54
|
+
export * from './data/data.descent';
|
|
55
|
+
export * from './data/data.description';
|
|
56
|
+
export * from './data/data.device-names';
|
|
57
|
+
export * from './data/data.distance';
|
|
58
|
+
export * from './data/data.duration';
|
|
59
|
+
export * from './data/data.ehpe';
|
|
60
|
+
export * from './data/data.energy';
|
|
61
|
+
export * from './data/data.epoc';
|
|
62
|
+
export * from './data/data.evpe';
|
|
63
|
+
export * from './data/data.feeling';
|
|
64
|
+
export * from './data/data.grade-adjusted-pace';
|
|
65
|
+
export * from './data/data.grade-adjusted-pace-avg';
|
|
66
|
+
export * from './data/data.grade-adjusted-speed';
|
|
67
|
+
export * from './data/data.grade-adjusted-speed-avg';
|
|
68
|
+
export * from './data/data.heart-rate';
|
|
69
|
+
export * from './data/data.heart-rate-avg';
|
|
70
|
+
export * from './data/data.heart-rate-max';
|
|
71
|
+
export * from './data/data.heart-rate-min';
|
|
72
|
+
export * from './data/data.ibi';
|
|
73
|
+
export * from './data/data.interface';
|
|
74
|
+
export * from './data/data.latitude-degrees';
|
|
75
|
+
export * from './data/data.left-balance';
|
|
76
|
+
export * from './data/data.longitude-degrees';
|
|
77
|
+
export * from './data/data.moving-time';
|
|
78
|
+
export * from './data/data.pace';
|
|
79
|
+
export * from './data/data.pace-avg';
|
|
80
|
+
export * from './data/data.peak-epoc';
|
|
81
|
+
export * from './data/data.peak-training-effect';
|
|
82
|
+
export * from './data/data.position.interface';
|
|
83
|
+
export * from './data/data.power';
|
|
84
|
+
export * from './data/data.power-avg';
|
|
85
|
+
export * from './data/data.power-left';
|
|
86
|
+
export * from './data/data.power-max';
|
|
87
|
+
export * from './data/data.power-min';
|
|
88
|
+
export * from './data/data.power-right';
|
|
89
|
+
export * from './data/data.recovery-time';
|
|
90
|
+
export * from './data/data.right-balance';
|
|
91
|
+
export * from './data/data.rpe';
|
|
92
|
+
export * from './data/data.sea-level-pressure';
|
|
93
|
+
export * from './data/data.speed';
|
|
94
|
+
export * from './data/data.speed-avg';
|
|
95
|
+
export * from './data/data.speed-max';
|
|
96
|
+
export * from './data/data.speed-min';
|
|
97
|
+
export * from './data/data.start-position';
|
|
98
|
+
export * from './data/data.store';
|
|
99
|
+
export * from './data/data.stryd-altitude';
|
|
100
|
+
export * from './data/data.stryd-distance';
|
|
101
|
+
export * from './data/data.stryd-speed';
|
|
102
|
+
export * from './data/data.swim-pace';
|
|
103
|
+
export * from './data/data.swim-pace-avg';
|
|
104
|
+
export * from './data/data.swim-pace-max';
|
|
105
|
+
export * from './data/data.temperature';
|
|
106
|
+
export * from './data/data.temperature-avg';
|
|
107
|
+
export * from './data/data.temperature-max';
|
|
108
|
+
export * from './data/data.temperature-min';
|
|
109
|
+
export * from './data/data.vertical-speed';
|
|
110
|
+
export * from './data/data.vertical-speed-avg';
|
|
111
|
+
export * from './data/data.vo2-max';
|
|
112
|
+
export * from './data/ibi/data.ibi';
|
|
113
|
+
export * from './events/adapters/exporters/exporter.gpx';
|
|
114
|
+
export * from './events/adapters/exporters/exporter.json';
|
|
115
|
+
export * from './events/adapters/importers/fit/importer.fit';
|
|
116
|
+
export * from './events/adapters/importers/gpx/importer.gpx';
|
|
117
|
+
export * from './events/adapters/importers/json/importer.json';
|
|
118
|
+
export * from './events/adapters/importers/suunto/importer.suunto.json';
|
|
119
|
+
export * from './events/adapters/importers/suunto/importer.suunto.sml';
|
|
120
|
+
export * from './events/adapters/importers/tcx/importer.tcx';
|
|
121
|
+
export * from './events/event.interface';
|
|
122
|
+
export * from './events/event.json.interface';
|
|
123
|
+
export * from './events/utilities/activity.utilities';
|
|
124
|
+
export * from './events/utilities/event.utilities';
|
|
125
|
+
export * from './events/utilities/helpers';
|
|
126
|
+
export * from './geodesy/adapters/geolib.adapter';
|
|
127
|
+
export * from './laps/lap.interface';
|
|
128
|
+
export * from './laps/lap.types';
|
|
129
|
+
export * from './meta-data/event-meta-data.interface';
|
|
130
|
+
export * from './meta-data/meta-data';
|
|
131
|
+
export * from './privacy/privacy.class.interface';
|
|
132
|
+
export * from './service-tokens/oauth1-service-token.interface';
|
|
133
|
+
export * from './service-tokens/oauth2-service-token.interface';
|
|
134
|
+
export * from './stats/stats.class.interface';
|
|
135
|
+
export * from './streams/compressed.stream.interface';
|
|
136
|
+
export * from './streams/stream';
|
|
137
|
+
export * from './streams/stream.interface';
|
|
138
|
+
export * from './tiles/tile.settings.interface';
|
|
139
|
+
export * from './users/settings/dashboard/user.dashboard.settings.interface';
|
|
140
|
+
export * from './users/settings/user.app.settings.interface';
|
|
141
|
+
export * from './users/settings/user.chart.settings.interface';
|
|
142
|
+
export * from './users/settings/user.map.settings.interface';
|
|
143
|
+
export * from './users/settings/user.my-tracks.settings.interface';
|
|
144
|
+
export * from './users/settings/user.settings.interface';
|
|
145
|
+
export * from './users/settings/user.summaries.settings.interface';
|
|
146
|
+
export * from './users/settings/user.unit.settings.interface';
|
|
147
|
+
export * from './users/user';
|
|
148
|
+
export * from './users/user.export-to-csv.settings.interface';
|
|
149
|
+
export * from './users/user.service.meta.interface';
|
package/lib/cjs/index.js
CHANGED
|
@@ -1,4 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
+
};
|
|
2
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
13
|
exports.SportsLib = void 0;
|
|
4
14
|
const importer_gpx_1 = require("./events/adapters/importers/gpx/importer.gpx");
|
|
@@ -49,3 +59,117 @@ class SportsLib {
|
|
|
49
59
|
}
|
|
50
60
|
}
|
|
51
61
|
exports.SportsLib = SportsLib;
|
|
62
|
+
__exportStar(require("./activities/activity.interface"), exports);
|
|
63
|
+
__exportStar(require("./activities/activity.json.interface"), exports);
|
|
64
|
+
__exportStar(require("./activities/activity.types"), exports);
|
|
65
|
+
__exportStar(require("./constants/constants"), exports);
|
|
66
|
+
__exportStar(require("./data/data-aerobic-training-effect"), exports);
|
|
67
|
+
__exportStar(require("./data/data.absolute-pressure"), exports);
|
|
68
|
+
__exportStar(require("./data/data.accumulated-power"), exports);
|
|
69
|
+
__exportStar(require("./data/data.activity-types"), exports);
|
|
70
|
+
__exportStar(require("./data/data.air-power"), exports);
|
|
71
|
+
__exportStar(require("./data/data.altitude"), exports);
|
|
72
|
+
__exportStar(require("./data/data.altitude-avg"), exports);
|
|
73
|
+
__exportStar(require("./data/data.altitude-gps"), exports);
|
|
74
|
+
__exportStar(require("./data/data.altitude-max"), exports);
|
|
75
|
+
__exportStar(require("./data/data.altitude-min"), exports);
|
|
76
|
+
__exportStar(require("./data/data.ascent"), exports);
|
|
77
|
+
__exportStar(require("./data/data.cadence-avg"), exports);
|
|
78
|
+
__exportStar(require("./data/data.cadence-max"), exports);
|
|
79
|
+
__exportStar(require("./data/data.cadence-min"), exports);
|
|
80
|
+
__exportStar(require("./data/data.descent"), exports);
|
|
81
|
+
__exportStar(require("./data/data.description"), exports);
|
|
82
|
+
__exportStar(require("./data/data.device-names"), exports);
|
|
83
|
+
__exportStar(require("./data/data.distance"), exports);
|
|
84
|
+
__exportStar(require("./data/data.duration"), exports);
|
|
85
|
+
__exportStar(require("./data/data.ehpe"), exports);
|
|
86
|
+
__exportStar(require("./data/data.energy"), exports);
|
|
87
|
+
__exportStar(require("./data/data.epoc"), exports);
|
|
88
|
+
__exportStar(require("./data/data.evpe"), exports);
|
|
89
|
+
__exportStar(require("./data/data.feeling"), exports);
|
|
90
|
+
__exportStar(require("./data/data.grade-adjusted-pace"), exports);
|
|
91
|
+
__exportStar(require("./data/data.grade-adjusted-pace-avg"), exports);
|
|
92
|
+
__exportStar(require("./data/data.grade-adjusted-speed"), exports);
|
|
93
|
+
__exportStar(require("./data/data.grade-adjusted-speed-avg"), exports);
|
|
94
|
+
__exportStar(require("./data/data.heart-rate"), exports);
|
|
95
|
+
__exportStar(require("./data/data.heart-rate-avg"), exports);
|
|
96
|
+
__exportStar(require("./data/data.heart-rate-max"), exports);
|
|
97
|
+
__exportStar(require("./data/data.heart-rate-min"), exports);
|
|
98
|
+
__exportStar(require("./data/data.ibi"), exports);
|
|
99
|
+
__exportStar(require("./data/data.interface"), exports);
|
|
100
|
+
__exportStar(require("./data/data.latitude-degrees"), exports);
|
|
101
|
+
__exportStar(require("./data/data.left-balance"), exports);
|
|
102
|
+
__exportStar(require("./data/data.longitude-degrees"), exports);
|
|
103
|
+
__exportStar(require("./data/data.moving-time"), exports);
|
|
104
|
+
__exportStar(require("./data/data.pace"), exports);
|
|
105
|
+
__exportStar(require("./data/data.pace-avg"), exports);
|
|
106
|
+
__exportStar(require("./data/data.peak-epoc"), exports);
|
|
107
|
+
__exportStar(require("./data/data.peak-training-effect"), exports);
|
|
108
|
+
__exportStar(require("./data/data.position.interface"), exports);
|
|
109
|
+
__exportStar(require("./data/data.power"), exports);
|
|
110
|
+
__exportStar(require("./data/data.power-avg"), exports);
|
|
111
|
+
__exportStar(require("./data/data.power-left"), exports);
|
|
112
|
+
__exportStar(require("./data/data.power-max"), exports);
|
|
113
|
+
__exportStar(require("./data/data.power-min"), exports);
|
|
114
|
+
__exportStar(require("./data/data.power-right"), exports);
|
|
115
|
+
__exportStar(require("./data/data.recovery-time"), exports);
|
|
116
|
+
__exportStar(require("./data/data.right-balance"), exports);
|
|
117
|
+
__exportStar(require("./data/data.rpe"), exports);
|
|
118
|
+
__exportStar(require("./data/data.sea-level-pressure"), exports);
|
|
119
|
+
__exportStar(require("./data/data.speed"), exports);
|
|
120
|
+
__exportStar(require("./data/data.speed-avg"), exports);
|
|
121
|
+
__exportStar(require("./data/data.speed-max"), exports);
|
|
122
|
+
__exportStar(require("./data/data.speed-min"), exports);
|
|
123
|
+
__exportStar(require("./data/data.start-position"), exports);
|
|
124
|
+
__exportStar(require("./data/data.store"), exports);
|
|
125
|
+
__exportStar(require("./data/data.stryd-altitude"), exports);
|
|
126
|
+
__exportStar(require("./data/data.stryd-distance"), exports);
|
|
127
|
+
__exportStar(require("./data/data.stryd-speed"), exports);
|
|
128
|
+
__exportStar(require("./data/data.swim-pace"), exports);
|
|
129
|
+
__exportStar(require("./data/data.swim-pace-avg"), exports);
|
|
130
|
+
__exportStar(require("./data/data.swim-pace-max"), exports);
|
|
131
|
+
__exportStar(require("./data/data.temperature"), exports);
|
|
132
|
+
__exportStar(require("./data/data.temperature-avg"), exports);
|
|
133
|
+
__exportStar(require("./data/data.temperature-max"), exports);
|
|
134
|
+
__exportStar(require("./data/data.temperature-min"), exports);
|
|
135
|
+
__exportStar(require("./data/data.vertical-speed"), exports);
|
|
136
|
+
__exportStar(require("./data/data.vertical-speed-avg"), exports);
|
|
137
|
+
__exportStar(require("./data/data.vo2-max"), exports);
|
|
138
|
+
__exportStar(require("./data/ibi/data.ibi"), exports);
|
|
139
|
+
__exportStar(require("./events/adapters/exporters/exporter.gpx"), exports);
|
|
140
|
+
__exportStar(require("./events/adapters/exporters/exporter.json"), exports);
|
|
141
|
+
__exportStar(require("./events/adapters/importers/fit/importer.fit"), exports);
|
|
142
|
+
__exportStar(require("./events/adapters/importers/gpx/importer.gpx"), exports);
|
|
143
|
+
__exportStar(require("./events/adapters/importers/json/importer.json"), exports);
|
|
144
|
+
__exportStar(require("./events/adapters/importers/suunto/importer.suunto.json"), exports);
|
|
145
|
+
__exportStar(require("./events/adapters/importers/suunto/importer.suunto.sml"), exports);
|
|
146
|
+
__exportStar(require("./events/adapters/importers/tcx/importer.tcx"), exports);
|
|
147
|
+
__exportStar(require("./events/event.interface"), exports);
|
|
148
|
+
__exportStar(require("./events/event.json.interface"), exports);
|
|
149
|
+
__exportStar(require("./events/utilities/activity.utilities"), exports);
|
|
150
|
+
__exportStar(require("./events/utilities/event.utilities"), exports);
|
|
151
|
+
__exportStar(require("./events/utilities/helpers"), exports);
|
|
152
|
+
__exportStar(require("./geodesy/adapters/geolib.adapter"), exports);
|
|
153
|
+
__exportStar(require("./laps/lap.interface"), exports);
|
|
154
|
+
__exportStar(require("./laps/lap.types"), exports);
|
|
155
|
+
__exportStar(require("./meta-data/event-meta-data.interface"), exports);
|
|
156
|
+
__exportStar(require("./meta-data/meta-data"), exports);
|
|
157
|
+
__exportStar(require("./privacy/privacy.class.interface"), exports);
|
|
158
|
+
__exportStar(require("./service-tokens/oauth1-service-token.interface"), exports);
|
|
159
|
+
__exportStar(require("./service-tokens/oauth2-service-token.interface"), exports);
|
|
160
|
+
__exportStar(require("./stats/stats.class.interface"), exports);
|
|
161
|
+
__exportStar(require("./streams/compressed.stream.interface"), exports);
|
|
162
|
+
__exportStar(require("./streams/stream"), exports);
|
|
163
|
+
__exportStar(require("./streams/stream.interface"), exports);
|
|
164
|
+
__exportStar(require("./tiles/tile.settings.interface"), exports);
|
|
165
|
+
__exportStar(require("./users/settings/dashboard/user.dashboard.settings.interface"), exports);
|
|
166
|
+
__exportStar(require("./users/settings/user.app.settings.interface"), exports);
|
|
167
|
+
__exportStar(require("./users/settings/user.chart.settings.interface"), exports);
|
|
168
|
+
__exportStar(require("./users/settings/user.map.settings.interface"), exports);
|
|
169
|
+
__exportStar(require("./users/settings/user.my-tracks.settings.interface"), exports);
|
|
170
|
+
__exportStar(require("./users/settings/user.settings.interface"), exports);
|
|
171
|
+
__exportStar(require("./users/settings/user.summaries.settings.interface"), exports);
|
|
172
|
+
__exportStar(require("./users/settings/user.unit.settings.interface"), exports);
|
|
173
|
+
__exportStar(require("./users/user"), exports);
|
|
174
|
+
__exportStar(require("./users/user.export-to-csv.settings.interface"), exports);
|
|
175
|
+
__exportStar(require("./users/user.service.meta.interface"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const activity_1 = require("../activities/activity");
|
|
4
|
+
const creator_1 = require("../creators/creator");
|
|
5
|
+
const data_distance_1 = require("../data/data.distance");
|
|
6
|
+
const activity_types_1 = require("../activities/activity.types");
|
|
7
|
+
const data_duration_1 = require("../data/data.duration");
|
|
8
|
+
describe('Activity Duration Stream', () => {
|
|
9
|
+
let activity;
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
// Create a 10-second activity
|
|
12
|
+
const startDate = new Date('2023-01-01T10:00:00Z');
|
|
13
|
+
const endDate = new Date('2023-01-01T10:00:10Z');
|
|
14
|
+
const creator = new creator_1.Creator('Test Creator');
|
|
15
|
+
activity = new activity_1.Activity(startDate, endDate, activity_types_1.ActivityTypes.Running, creator);
|
|
16
|
+
});
|
|
17
|
+
it('should generate a duration stream based on time stream logic', () => {
|
|
18
|
+
// Add a distance stream with some data
|
|
19
|
+
const distanceStream = activity.createStream(data_distance_1.DataDistance.type);
|
|
20
|
+
// Data at 0s, 5s, 10s
|
|
21
|
+
distanceStream.getData()[0] = 0;
|
|
22
|
+
distanceStream.getData()[5] = 50;
|
|
23
|
+
distanceStream.getData()[10] = 100;
|
|
24
|
+
activity.addStream(distanceStream);
|
|
25
|
+
const durationStream = activity.generateDurationStream();
|
|
26
|
+
expect(durationStream.type).toBe(data_duration_1.DataDuration.type);
|
|
27
|
+
const data = durationStream.getData();
|
|
28
|
+
// Assuming generateTimeStream fills data where source stream has data
|
|
29
|
+
expect(data[0]).toBe(0);
|
|
30
|
+
expect(data[5]).toBe(5);
|
|
31
|
+
expect(data[10]).toBe(10);
|
|
32
|
+
// Other indices should be null/undefined as per generateTimeStream logic?
|
|
33
|
+
// Let's verify what generateTimeStream does.
|
|
34
|
+
// It uses `getStreamDataByDuration` with filterNull=true.
|
|
35
|
+
// So it only populates indices where source stream has data.
|
|
36
|
+
expect(data[1]).toBeFalsy();
|
|
37
|
+
expect(data[2]).toBeFalsy();
|
|
38
|
+
});
|
|
39
|
+
it('should allow specifying stream types to base duration on', () => {
|
|
40
|
+
// Scenario where we want duration based on HeartRate, not Distance
|
|
41
|
+
// Although logic reuses generateTimeStream which filters by streamTypes if provided.
|
|
42
|
+
// But generateTimeStream implementation:
|
|
43
|
+
/*
|
|
44
|
+
if (streamTypes.length) {
|
|
45
|
+
streams = streams.filter(stream => streamTypes.indexOf(stream.type) !== -1);
|
|
46
|
+
}
|
|
47
|
+
*/
|
|
48
|
+
// It unions all provided streams?
|
|
49
|
+
// "streams.forEach(stream => { ... })"
|
|
50
|
+
// Yes, it iterates all matching streams and fills the time stream.
|
|
51
|
+
// Let's create a custom stream
|
|
52
|
+
const customStream = activity.createStream('Custom');
|
|
53
|
+
customStream.getData()[2] = 123;
|
|
54
|
+
activity.addStream(customStream);
|
|
55
|
+
const durationStream = activity.generateDurationStream(['Custom']);
|
|
56
|
+
expect(durationStream.getData()[2]).toBe(2);
|
|
57
|
+
expect(durationStream.getData()[0]).toBeFalsy(); // Distance stream at 0 should be ignored if we only asked for Custom
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -70,6 +70,7 @@ export declare class Activity extends DurationClassAbstract implements ActivityI
|
|
|
70
70
|
addEvent(event: DataEvent): this;
|
|
71
71
|
setAllEvents(events: DataEvent[]): this;
|
|
72
72
|
generateTimeStream(streamTypes?: string[]): StreamInterface;
|
|
73
|
+
generateDurationStream(streamTypes?: string[]): StreamInterface;
|
|
73
74
|
getDateIndex(date: Date): number;
|
|
74
75
|
toJSON(): ActivityJSONInterface;
|
|
75
76
|
}
|
|
@@ -197,6 +197,11 @@ export interface ActivityInterface extends StatsClassInterface, DurationClassInt
|
|
|
197
197
|
* @param streamTypes
|
|
198
198
|
*/
|
|
199
199
|
generateTimeStream(streamTypes?: string[]): StreamInterface;
|
|
200
|
+
/**
|
|
201
|
+
* Generates a duration stream based on the type of streams requested
|
|
202
|
+
* @param streamTypes
|
|
203
|
+
*/
|
|
204
|
+
generateDurationStream(streamTypes?: string[]): StreamInterface;
|
|
200
205
|
/**
|
|
201
206
|
* Gets the date index/duration from a date relative to the activity
|
|
202
207
|
* @param date
|
|
@@ -11,6 +11,7 @@ import { DataStopAllEvent } from '../data/data.stop-all-event';
|
|
|
11
11
|
import { DataTime } from '../data/data.time';
|
|
12
12
|
import { ActivityUtilities } from '../events/utilities/activity.utilities';
|
|
13
13
|
import { DataDistance } from '../data/data.distance';
|
|
14
|
+
import { DataDuration } from '../data/data.duration';
|
|
14
15
|
import { DataRiderPositionChangeEvent } from '../data/data.rider-position-change-event';
|
|
15
16
|
import { ActivityParsingOptions } from './activity-parsing-options';
|
|
16
17
|
import { ParsingEventLibError } from '../errors/parsing-event-lib.error';
|
|
@@ -213,6 +214,12 @@ export class Activity extends DurationClassAbstract {
|
|
|
213
214
|
});
|
|
214
215
|
return timeStream;
|
|
215
216
|
}
|
|
217
|
+
generateDurationStream(streamTypes = []) {
|
|
218
|
+
const timeStream = this.generateTimeStream(streamTypes);
|
|
219
|
+
const durationStream = this.createStream(DataDuration.type);
|
|
220
|
+
durationStream.setData(timeStream.getData());
|
|
221
|
+
return durationStream;
|
|
222
|
+
}
|
|
216
223
|
getDateIndex(date) {
|
|
217
224
|
// @todo ceil vs floor (still debatable)
|
|
218
225
|
return Math.round((+date - +this.startDate) / 1000);
|
|
@@ -228,6 +228,7 @@ export var ActivityTypes;
|
|
|
228
228
|
ActivityTypes["cycling_cyclocross"] = "Mountain Biking";
|
|
229
229
|
ActivityTypes["mountain"] = "Mountain Biking";
|
|
230
230
|
ActivityTypes["Mountain biking"] = "Mountain Biking";
|
|
231
|
+
ActivityTypes["cycling_downhill"] = "Downhill Cycling";
|
|
231
232
|
/**
|
|
232
233
|
* Motorcycling
|
|
233
234
|
*/
|
|
@@ -19,7 +19,7 @@ describe('DataStore Export Verification', () => {
|
|
|
19
19
|
'data.boolean.ts',
|
|
20
20
|
'data.percent.ts',
|
|
21
21
|
'data.array.ts',
|
|
22
|
-
'data.balance.ts'
|
|
22
|
+
'data.balance.ts' // interface/base
|
|
23
23
|
];
|
|
24
24
|
files.forEach(file => {
|
|
25
25
|
// Only verify regular TS files related to data
|
|
@@ -55,7 +55,7 @@ describe('DataStore Export Verification', () => {
|
|
|
55
55
|
else {
|
|
56
56
|
// If it doesn't have a 'type', it acts like a base class (e.g. DataQuantity)
|
|
57
57
|
// We can log it or ignore it.
|
|
58
|
-
// For now, let's assume if it's named Data*, it might be relevant,
|
|
58
|
+
// For now, let's assume if it's named Data*, it might be relevant,
|
|
59
59
|
// but strictly enforcing presence in DataStore usually requires the 'type' to be useful for the loader.
|
|
60
60
|
}
|
|
61
61
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const GarminManufacturers: {
|
|
2
|
+
[index: number]: string;
|
|
3
|
+
};
|
|
4
|
+
export declare const GarminProducts: {
|
|
5
|
+
[index: number]: string;
|
|
6
|
+
};
|
|
7
|
+
export declare const GarminSports: {
|
|
8
|
+
[index: number]: string;
|
|
9
|
+
};
|
|
10
|
+
export declare const GarminSubSports: {
|
|
11
|
+
[index: number]: string;
|
|
12
|
+
};
|