fit-file-parser 4.0.2 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/README.md +190 -119
- package/dist/binary.d.ts +5 -1
- package/dist/binary.js +202 -141
- package/dist/cjs/binary.d.ts +5 -1
- package/dist/cjs/binary.js +202 -141
- package/dist/cjs/fit-parser.js +37 -19
- package/dist/cjs/fit.d.ts +6 -0
- package/dist/cjs/fit.js +167 -44
- package/dist/cjs/fit_types.d.ts +1297 -207
- package/dist/cjs/garmin_profile.generated.d.ts +9 -0
- package/dist/cjs/garmin_profile.generated.js +17838 -0
- package/dist/cjs/type_generator.d.ts +3 -0
- package/dist/cjs/type_generator.js +37 -9
- package/dist/fit-parser.js +37 -19
- package/dist/fit.d.ts +6 -0
- package/dist/fit.js +167 -44
- package/dist/fit_types.d.ts +1297 -207
- package/dist/garmin_profile.generated.d.ts +9 -0
- package/dist/garmin_profile.generated.js +17835 -0
- package/dist/type_generator.d.ts +3 -0
- package/dist/type_generator.js +36 -9
- package/package.json +9 -6
package/dist/cjs/fit.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { FitOptions, MesgNum } from './fit_types.js';
|
|
2
2
|
export interface FieldDefinition {
|
|
3
3
|
type: string | number;
|
|
4
|
+
rawType?: string | number;
|
|
4
5
|
fDefNo: number;
|
|
5
6
|
size: number;
|
|
7
|
+
array?: boolean;
|
|
6
8
|
endianAbility: boolean;
|
|
7
9
|
littleEndian: boolean;
|
|
8
10
|
baseTypeNo: number;
|
|
@@ -13,13 +15,17 @@ export interface FieldDefinition {
|
|
|
13
15
|
requiresBoundedDataView?: boolean;
|
|
14
16
|
developerDataIndex?: number;
|
|
15
17
|
isDeveloperField?: boolean;
|
|
18
|
+
aliases?: MessageObject[];
|
|
16
19
|
}
|
|
17
20
|
export interface MessageObject {
|
|
18
21
|
field: string;
|
|
19
22
|
type: string;
|
|
23
|
+
baseType?: string;
|
|
24
|
+
array?: boolean;
|
|
20
25
|
scale: number | null;
|
|
21
26
|
offset: number;
|
|
22
27
|
units: string;
|
|
28
|
+
aliases?: MessageObject[];
|
|
23
29
|
}
|
|
24
30
|
export interface Message {
|
|
25
31
|
name: MesgNum;
|
package/dist/cjs/fit.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FIT = void 0;
|
|
4
|
+
const garmin_profile_generated_js_1 = require("./garmin_profile.generated.js");
|
|
4
5
|
const metersInOneKilometer = 1000;
|
|
5
6
|
const secondsInOneHour = 3600;
|
|
6
7
|
// according to https://en.wikipedia.org/wiki/Mile
|
|
@@ -11,7 +12,7 @@ const psiInOneBar = 14.5037738;
|
|
|
11
12
|
// which contains all the types and values
|
|
12
13
|
// i would wish for some kind of inference mechanism here but for now we leave it as any
|
|
13
14
|
// maybe zod could help here
|
|
14
|
-
|
|
15
|
+
const FIT_OVERRIDES = {
|
|
15
16
|
scConst: 180 / Math.pow(2, 31),
|
|
16
17
|
options: {
|
|
17
18
|
speedUnits: {
|
|
@@ -49,6 +50,11 @@ exports.FIT = {
|
|
|
49
50
|
},
|
|
50
51
|
},
|
|
51
52
|
temperatureUnits: {
|
|
53
|
+
// canonical native temperature unit: degree Celsius [°C]
|
|
54
|
+
'celsius': {
|
|
55
|
+
multiplier: 1,
|
|
56
|
+
offset: 0,
|
|
57
|
+
},
|
|
52
58
|
// native temperature unit: degree Celsius [°C]
|
|
53
59
|
'°C': {
|
|
54
60
|
multiplier: 1,
|
|
@@ -57,7 +63,7 @@ exports.FIT = {
|
|
|
57
63
|
// kelvin [K]
|
|
58
64
|
'kelvin': {
|
|
59
65
|
multiplier: 1,
|
|
60
|
-
offset:
|
|
66
|
+
offset: 273.15,
|
|
61
67
|
},
|
|
62
68
|
// degree fahrenheit [°F]
|
|
63
69
|
'fahrenheit': {
|
|
@@ -1797,20 +1803,6 @@ exports.FIT = {
|
|
|
1797
1803
|
offset: 0,
|
|
1798
1804
|
units: 'percent',
|
|
1799
1805
|
},
|
|
1800
|
-
214: {
|
|
1801
|
-
field: 'avg_grit',
|
|
1802
|
-
type: 'float32',
|
|
1803
|
-
scale: null,
|
|
1804
|
-
offset: 0,
|
|
1805
|
-
units: '',
|
|
1806
|
-
},
|
|
1807
|
-
215: {
|
|
1808
|
-
field: 'avg_flow',
|
|
1809
|
-
type: 'float32',
|
|
1810
|
-
scale: null,
|
|
1811
|
-
offset: 0,
|
|
1812
|
-
units: '',
|
|
1813
|
-
},
|
|
1814
1806
|
140: {
|
|
1815
1807
|
field: 'recovery_advisor',
|
|
1816
1808
|
type: 'uint16', // Minutes?
|
|
@@ -4135,22 +4127,25 @@ exports.FIT = {
|
|
|
4135
4127
|
},
|
|
4136
4128
|
2: {
|
|
4137
4129
|
field: 'distance',
|
|
4138
|
-
type: '
|
|
4139
|
-
|
|
4130
|
+
type: 'uint32',
|
|
4131
|
+
baseType: 'uint32',
|
|
4132
|
+
scale: 100,
|
|
4140
4133
|
offset: 0,
|
|
4141
4134
|
units: 'm',
|
|
4142
4135
|
},
|
|
4143
4136
|
3: {
|
|
4144
4137
|
field: 'cycles',
|
|
4145
|
-
type: '
|
|
4146
|
-
|
|
4138
|
+
type: 'uint32',
|
|
4139
|
+
baseType: 'uint32',
|
|
4140
|
+
scale: 2,
|
|
4147
4141
|
offset: 0,
|
|
4148
4142
|
units: 'cycles',
|
|
4149
4143
|
},
|
|
4150
4144
|
4: {
|
|
4151
4145
|
field: 'active_time',
|
|
4152
|
-
type: '
|
|
4153
|
-
|
|
4146
|
+
type: 'uint32',
|
|
4147
|
+
baseType: 'uint32',
|
|
4148
|
+
scale: 1000,
|
|
4154
4149
|
offset: 0,
|
|
4155
4150
|
units: 's',
|
|
4156
4151
|
},
|
|
@@ -4205,28 +4200,33 @@ exports.FIT = {
|
|
|
4205
4200
|
},
|
|
4206
4201
|
12: {
|
|
4207
4202
|
field: 'temperature',
|
|
4208
|
-
type: '
|
|
4209
|
-
|
|
4203
|
+
type: 'sint16',
|
|
4204
|
+
baseType: 'sint16',
|
|
4205
|
+
scale: 100,
|
|
4210
4206
|
offset: 0,
|
|
4211
4207
|
units: 'C',
|
|
4212
4208
|
},
|
|
4213
4209
|
14: {
|
|
4214
4210
|
field: 'temperature_min',
|
|
4215
|
-
type: '
|
|
4216
|
-
|
|
4211
|
+
type: 'sint16',
|
|
4212
|
+
baseType: 'sint16',
|
|
4213
|
+
scale: 100,
|
|
4217
4214
|
offset: 0,
|
|
4218
4215
|
units: 'C',
|
|
4219
4216
|
},
|
|
4220
4217
|
15: {
|
|
4221
4218
|
field: 'temperature_max',
|
|
4222
|
-
type: '
|
|
4223
|
-
|
|
4219
|
+
type: 'sint16',
|
|
4220
|
+
baseType: 'sint16',
|
|
4221
|
+
scale: 100,
|
|
4224
4222
|
offset: 0,
|
|
4225
4223
|
units: 'C',
|
|
4226
4224
|
},
|
|
4227
4225
|
16: {
|
|
4228
4226
|
field: 'activity_time',
|
|
4229
|
-
type: '
|
|
4227
|
+
type: 'uint16',
|
|
4228
|
+
baseType: 'uint16',
|
|
4229
|
+
array: true,
|
|
4230
4230
|
scale: null,
|
|
4231
4231
|
offset: 0,
|
|
4232
4232
|
units: '',
|
|
@@ -4597,17 +4597,6 @@ exports.FIT = {
|
|
|
4597
4597
|
units: '',
|
|
4598
4598
|
},
|
|
4599
4599
|
},
|
|
4600
|
-
108: {
|
|
4601
|
-
name: 'o_hr_settings',
|
|
4602
|
-
253: {
|
|
4603
|
-
field: 'timestamp',
|
|
4604
|
-
type: 'date_time',
|
|
4605
|
-
scale: null,
|
|
4606
|
-
offset: 0,
|
|
4607
|
-
units: '',
|
|
4608
|
-
},
|
|
4609
|
-
0: { field: 'enabled', type: 'byte', scale: null, offset: 0, units: '' },
|
|
4610
|
-
},
|
|
4611
4600
|
140: {
|
|
4612
4601
|
name: 'activity_metrics',
|
|
4613
4602
|
1: {
|
|
@@ -4742,6 +4731,86 @@ exports.FIT = {
|
|
|
4742
4731
|
units: '',
|
|
4743
4732
|
},
|
|
4744
4733
|
},
|
|
4734
|
+
225: {
|
|
4735
|
+
name: 'set',
|
|
4736
|
+
254: {
|
|
4737
|
+
field: 'timestamp',
|
|
4738
|
+
type: 'date_time',
|
|
4739
|
+
scale: null,
|
|
4740
|
+
offset: 0,
|
|
4741
|
+
units: '',
|
|
4742
|
+
},
|
|
4743
|
+
0: {
|
|
4744
|
+
field: 'duration',
|
|
4745
|
+
type: 'uint32',
|
|
4746
|
+
scale: 1000,
|
|
4747
|
+
offset: 0,
|
|
4748
|
+
units: 's',
|
|
4749
|
+
},
|
|
4750
|
+
3: {
|
|
4751
|
+
field: 'repetitions',
|
|
4752
|
+
type: 'uint16',
|
|
4753
|
+
scale: null,
|
|
4754
|
+
offset: 0,
|
|
4755
|
+
units: '',
|
|
4756
|
+
},
|
|
4757
|
+
4: {
|
|
4758
|
+
field: 'weight',
|
|
4759
|
+
type: 'uint16',
|
|
4760
|
+
scale: 16,
|
|
4761
|
+
offset: 0,
|
|
4762
|
+
units: 'kg',
|
|
4763
|
+
},
|
|
4764
|
+
5: {
|
|
4765
|
+
field: 'set_type',
|
|
4766
|
+
type: 'set_type',
|
|
4767
|
+
scale: null,
|
|
4768
|
+
offset: 0,
|
|
4769
|
+
units: '',
|
|
4770
|
+
},
|
|
4771
|
+
6: {
|
|
4772
|
+
field: 'start_time',
|
|
4773
|
+
type: 'date_time',
|
|
4774
|
+
scale: null,
|
|
4775
|
+
offset: 0,
|
|
4776
|
+
units: '',
|
|
4777
|
+
},
|
|
4778
|
+
7: {
|
|
4779
|
+
field: 'category',
|
|
4780
|
+
type: 'exercise_category_array',
|
|
4781
|
+
scale: null,
|
|
4782
|
+
offset: 0,
|
|
4783
|
+
units: '',
|
|
4784
|
+
},
|
|
4785
|
+
8: {
|
|
4786
|
+
field: 'category_subtype',
|
|
4787
|
+
type: 'uint16_array',
|
|
4788
|
+
scale: null,
|
|
4789
|
+
offset: 0,
|
|
4790
|
+
units: '',
|
|
4791
|
+
},
|
|
4792
|
+
9: {
|
|
4793
|
+
field: 'weight_display_unit',
|
|
4794
|
+
type: 'fit_base_unit',
|
|
4795
|
+
scale: null,
|
|
4796
|
+
offset: 0,
|
|
4797
|
+
units: '',
|
|
4798
|
+
},
|
|
4799
|
+
10: {
|
|
4800
|
+
field: 'message_index',
|
|
4801
|
+
type: 'message_index',
|
|
4802
|
+
scale: null,
|
|
4803
|
+
offset: 0,
|
|
4804
|
+
units: '',
|
|
4805
|
+
},
|
|
4806
|
+
11: {
|
|
4807
|
+
field: 'wkt_step_index',
|
|
4808
|
+
type: 'message_index',
|
|
4809
|
+
scale: null,
|
|
4810
|
+
offset: 0,
|
|
4811
|
+
units: '',
|
|
4812
|
+
},
|
|
4813
|
+
},
|
|
4745
4814
|
227: {
|
|
4746
4815
|
name: 'stress_level',
|
|
4747
4816
|
0: {
|
|
@@ -5203,7 +5272,7 @@ exports.FIT = {
|
|
|
5203
5272
|
units: 's',
|
|
5204
5273
|
},
|
|
5205
5274
|
4: {
|
|
5206
|
-
field: '
|
|
5275
|
+
field: 'time_in_cadence_zone',
|
|
5207
5276
|
type: 'uint32_array',
|
|
5208
5277
|
scale: 1000,
|
|
5209
5278
|
offset: 0,
|
|
@@ -5231,11 +5300,11 @@ exports.FIT = {
|
|
|
5231
5300
|
units: 'm/s',
|
|
5232
5301
|
},
|
|
5233
5302
|
8: {
|
|
5234
|
-
field: '
|
|
5235
|
-
type: '
|
|
5303
|
+
field: 'cadence_zone_high_boundary',
|
|
5304
|
+
type: 'uint8_array',
|
|
5236
5305
|
scale: null,
|
|
5237
5306
|
offset: 0,
|
|
5238
|
-
units: '
|
|
5307
|
+
units: 'rpm',
|
|
5239
5308
|
},
|
|
5240
5309
|
9: {
|
|
5241
5310
|
field: 'power_zone_high_boundary',
|
|
@@ -9088,3 +9157,57 @@ exports.FIT = {
|
|
|
9088
9157
|
},
|
|
9089
9158
|
},
|
|
9090
9159
|
};
|
|
9160
|
+
function equivalentProfileName(left, right) {
|
|
9161
|
+
return String(left).replace(/_/g, '').toLowerCase()
|
|
9162
|
+
=== String(right).replace(/_/g, '').toLowerCase();
|
|
9163
|
+
}
|
|
9164
|
+
function mergeMessages() {
|
|
9165
|
+
const messages = Object.assign({}, FIT_OVERRIDES.messages);
|
|
9166
|
+
Object.entries(garmin_profile_generated_js_1.GARMIN_MESSAGES).forEach(([messageId, generatedMessage]) => {
|
|
9167
|
+
const overrideMessage = FIT_OVERRIDES.messages[Number(messageId)];
|
|
9168
|
+
if (!overrideMessage) {
|
|
9169
|
+
messages[Number(messageId)] = generatedMessage;
|
|
9170
|
+
return;
|
|
9171
|
+
}
|
|
9172
|
+
const mergedMessage = Object.assign(Object.assign({}, overrideMessage), generatedMessage);
|
|
9173
|
+
Object.entries(generatedMessage).forEach(([fieldId, generatedField]) => {
|
|
9174
|
+
var _a;
|
|
9175
|
+
if (fieldId === 'name') {
|
|
9176
|
+
return;
|
|
9177
|
+
}
|
|
9178
|
+
const overrideField = overrideMessage[Number(fieldId)];
|
|
9179
|
+
const hasCompatibleName = overrideField
|
|
9180
|
+
&& equivalentProfileName(overrideField.field, generatedField.field);
|
|
9181
|
+
mergedMessage[Number(fieldId)] = hasCompatibleName
|
|
9182
|
+
? Object.assign(Object.assign(Object.assign({}, generatedField), overrideField), { baseType: generatedField.baseType, array: (_a = overrideField.array) !== null && _a !== void 0 ? _a : generatedField.array }) : Object.assign(Object.assign(Object.assign({}, overrideField), generatedField), { aliases: overrideField ? [overrideField] : undefined });
|
|
9183
|
+
});
|
|
9184
|
+
messages[Number(messageId)] = mergedMessage;
|
|
9185
|
+
});
|
|
9186
|
+
return messages;
|
|
9187
|
+
}
|
|
9188
|
+
function mergeTypes() {
|
|
9189
|
+
const typeNames = new Set([
|
|
9190
|
+
...Object.keys(garmin_profile_generated_js_1.GARMIN_TYPES),
|
|
9191
|
+
...Object.keys(FIT_OVERRIDES.types),
|
|
9192
|
+
]);
|
|
9193
|
+
return Object.fromEntries([...typeNames].map((typeName) => {
|
|
9194
|
+
var _a, _b;
|
|
9195
|
+
const generatedValues = (_a = garmin_profile_generated_js_1.GARMIN_TYPES[typeName]) !== null && _a !== void 0 ? _a : {};
|
|
9196
|
+
const overrideValues = (_b = FIT_OVERRIDES.types[typeName]) !== null && _b !== void 0 ? _b : {};
|
|
9197
|
+
const values = Object.assign({}, generatedValues);
|
|
9198
|
+
Object.entries(overrideValues).forEach(([valueId, overrideValue]) => {
|
|
9199
|
+
const generatedValue = generatedValues[Number(valueId)];
|
|
9200
|
+
if (generatedValue === undefined
|
|
9201
|
+
|| equivalentProfileName(overrideValue, generatedValue)) {
|
|
9202
|
+
values[Number(valueId)] = overrideValue;
|
|
9203
|
+
}
|
|
9204
|
+
});
|
|
9205
|
+
return [typeName, values];
|
|
9206
|
+
}));
|
|
9207
|
+
}
|
|
9208
|
+
exports.FIT = {
|
|
9209
|
+
scConst: FIT_OVERRIDES.scConst,
|
|
9210
|
+
options: FIT_OVERRIDES.options,
|
|
9211
|
+
messages: mergeMessages(),
|
|
9212
|
+
types: mergeTypes(),
|
|
9213
|
+
};
|