fit-file-parser 5.2.1 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "FitBaseType", { enumerable: true, get: function
8
8
  Object.defineProperty(exports, "FitEncoder", { enumerable: true, get: function () { return fit_encoder_js_1.FitEncoder; } });
9
9
  class FitParser {
10
10
  constructor(options = {}) {
11
- var _a, _b, _c;
11
+ var _a, _b, _c, _d;
12
12
  this.options = {
13
13
  force: options.force != null ? options.force : true,
14
14
  speedUnit: options.speedUnit || 'm/s',
@@ -19,7 +19,8 @@ class FitParser {
19
19
  mode: options.mode || 'list',
20
20
  includeRawDeveloperFields: (_a = options.includeRawDeveloperFields) !== null && _a !== void 0 ? _a : false,
21
21
  includeRawMessages: (_b = options.includeRawMessages) !== null && _b !== void 0 ? _b : false,
22
- rawMessagesOnly: (_c = options.rawMessagesOnly) !== null && _c !== void 0 ? _c : false,
22
+ includeUnmappedMessages: (_c = options.includeUnmappedMessages) !== null && _c !== void 0 ? _c : false,
23
+ rawMessagesOnly: (_d = options.rawMessagesOnly) !== null && _d !== void 0 ? _d : false,
23
24
  };
24
25
  }
25
26
  parseAsync(content) {
@@ -130,6 +131,7 @@ class FitParser {
130
131
  || Array.isArray(this.options.includeRawMessages)
131
132
  ? []
132
133
  : undefined;
134
+ const unmappedMessages = this.options.includeUnmappedMessages ? [] : undefined;
133
135
  const messageCountsByGlobalNumber = new Map();
134
136
  let loopIndex = headerLength;
135
137
  const messageTypes = [];
@@ -141,7 +143,7 @@ class FitParser {
141
143
  let lastStopTimestamp;
142
144
  let pausedTime = 0;
143
145
  while (loopIndex < crcStart) {
144
- const { globalMessageNumber, littleEndian, message, messageType, nextIndex, compressedTimestamp, rawFields: recordRawFields, rawDeveloperFields: recordRawDeveloperFields, } = (0, binary_js_1.readRecord)(blob, messageTypes, developerFields, loopIndex, this.options, startDate, pausedTime, dataView, decoderState, crcStart);
146
+ const { globalMessageNumber, littleEndian, message, messageType, nextIndex, compressedTimestamp, rawFields: recordRawFields, rawDeveloperFields: recordRawDeveloperFields, unmappedFields: recordUnmappedFields, unmappedDeveloperFields: recordUnmappedDeveloperFields, } = (0, binary_js_1.readRecord)(blob, messageTypes, developerFields, loopIndex, this.options, startDate, pausedTime, dataView, decoderState, crcStart);
145
147
  loopIndex = nextIndex;
146
148
  if (globalMessageNumber !== undefined) {
147
149
  const messageIndex = (_a = messageCountsByGlobalNumber.get(globalMessageNumber)) !== null && _a !== void 0 ? _a : 0;
@@ -168,6 +170,20 @@ class FitParser {
168
170
  raw_value: field.rawValue,
169
171
  });
170
172
  });
173
+ if (littleEndian !== undefined
174
+ && ((recordUnmappedFields === null || recordUnmappedFields === void 0 ? void 0 : recordUnmappedFields.length) || (recordUnmappedDeveloperFields === null || recordUnmappedDeveloperFields === void 0 ? void 0 : recordUnmappedDeveloperFields.length))) {
175
+ unmappedMessages === null || unmappedMessages === void 0 ? void 0 : unmappedMessages.push(Object.assign(Object.assign({ global_message_number: globalMessageNumber, message_index: messageIndex, little_endian: littleEndian }, (compressedTimestamp === undefined
176
+ ? {}
177
+ : { compressed_timestamp: compressedTimestamp })), { fields: (recordUnmappedFields !== null && recordUnmappedFields !== void 0 ? recordUnmappedFields : []).map(field => ({
178
+ field_definition_number: field.fieldDefinitionNumber,
179
+ base_type: field.baseType,
180
+ raw_value: field.rawValue,
181
+ })), developer_fields: (recordUnmappedDeveloperFields !== null && recordUnmappedDeveloperFields !== void 0 ? recordUnmappedDeveloperFields : []).map(field => ({
182
+ developer_data_index: field.developerDataIndex,
183
+ field_definition_number: field.fieldDefinitionNumber,
184
+ raw_value: field.rawValue,
185
+ })) }));
186
+ }
171
187
  }
172
188
  if (this.options.rawMessagesOnly) {
173
189
  continue;
@@ -298,6 +314,9 @@ class FitParser {
298
314
  if (rawMessages) {
299
315
  fitObj.raw_messages = rawMessages;
300
316
  }
317
+ if (unmappedMessages && unmappedMessages.length > 0) {
318
+ fitObj.unmapped_messages = unmappedMessages;
319
+ }
301
320
  callback(undefined, fitObj);
302
321
  return;
303
322
  }
@@ -326,6 +345,9 @@ class FitParser {
326
345
  if (rawMessages) {
327
346
  fitObj.raw_messages = rawMessages;
328
347
  }
348
+ if (unmappedMessages && unmappedMessages.length > 0) {
349
+ fitObj.unmapped_messages = unmappedMessages;
350
+ }
329
351
  if (isCascadeNeeded) {
330
352
  laps = (0, helper_js_1.mapDataIntoLap)(laps, 'records', records);
331
353
  laps = (0, helper_js_1.mapDataIntoLap)(laps, 'lengths', lengths);
package/dist/cjs/fit.d.ts CHANGED
@@ -37,10 +37,4 @@ export interface FitType {
37
37
  messages: Record<number, Message>;
38
38
  types: Record<string, Record<number, string | number>>;
39
39
  }
40
- /**
41
- * Garmin fields observed in the external FIT corpus but absent from the pinned
42
- * public SDK profile. These additions may not replace standard SDK fields.
43
- */
44
- export declare const FIT_VENDOR_MESSAGE_EXTENSIONS: Record<number, Message>;
45
- export declare const FIT_VENDOR_TYPE_EXTENSIONS: Record<string, Record<number, string>>;
46
40
  export declare const FIT: FitType;
package/dist/cjs/fit.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FIT = exports.FIT_VENDOR_TYPE_EXTENSIONS = exports.FIT_VENDOR_MESSAGE_EXTENSIONS = void 0;
4
- const garmin_profile_generated_js_1 = require("./garmin_profile.generated.js");
3
+ exports.FIT = void 0;
4
+ const profile_js_1 = require("./profile.js");
5
5
  const metersInOneKilometer = 1000;
6
6
  const secondsInOneHour = 3600;
7
7
  // according to https://en.wikipedia.org/wiki/Mile
@@ -31,119 +31,9 @@ const options = {
31
31
  psi: { multiplier: psiInOneBar, offset: 0 },
32
32
  },
33
33
  };
34
- /**
35
- * Garmin fields observed in the external FIT corpus but absent from the pinned
36
- * public SDK profile. These additions may not replace standard SDK fields.
37
- */
38
- exports.FIT_VENDOR_MESSAGE_EXTENSIONS = {
39
- 18: {
40
- name: 'session',
41
- 178: field('est_sweat_loss', 'uint16', 1, 'ml'),
42
- 188: field('primary_benefit', 'uint8'),
43
- 205: field('beginning_potential_stamina', 'uint8', 1, 'percent'),
44
- 206: field('ending_potential_stamina', 'uint8', 1, 'percent'),
45
- 207: field('min_stamina', 'uint8', 1, 'percent'),
46
- },
47
- 20: {
48
- name: 'record',
49
- 90: field('garmin_performance_condition', 'sint8'),
50
- 137: field('potential_stamina', 'uint8', 1, 'percent'),
51
- 138: field('stamina', 'uint8', 1, 'percent'),
52
- },
53
- 23: {
54
- name: 'device_info',
55
- 24: field('ant_id', 'uint32z'),
56
- },
57
- // Undocumented Garmin user metrics message observed in activity FIT files.
58
- 79: {
59
- name: 'user_metrics',
60
- 0: field('vo2_max', 'uint16', 1024 / 3.5, 'ml/kg/min'),
61
- 1: field('age', 'uint8', 1, 'years'),
62
- 2: field('height', 'uint8', 100, 'm'),
63
- 3: field('weight', 'uint16', 10, 'kg'),
64
- 4: field('gender', 'gender'),
65
- 6: field('max_heart_rate', 'uint8', 1, 'bpm'),
66
- 8: field('remaining_recovery_time', 'uint16'),
67
- 11: field('lthr', 'uint16', 1, 'bpm'),
68
- 12: field('ltpower', 'uint16', 1, 'watts'),
69
- 13: field('ltspeed', 'uint16', 1000, 'm/s'),
70
- 16: field('start_of_activity', 'date_time'),
71
- 19: field('first_vo2_max', 'uint32', 65536 / 3.5, 'ml/kg/min'),
72
- 35: field('end_of_previous_activity', 'date_time'),
73
- 253: field('timestamp', 'date_time'),
74
- },
75
- // Undocumented Garmin activity metrics message observed in activity FIT files.
76
- 140: {
77
- name: 'activity_metrics',
78
- 1: field('new_max_heart_rate', 'uint8', 1, 'bpm'),
79
- 4: field('aerobic_training_effect', 'uint8', 10),
80
- 7: field('vo2_max', 'uint32', 65536 / 3.5, 'ml/kg/min'),
81
- 9: field('recovery_time', 'uint16', 1, 'min'),
82
- 11: field('sport', 'sport'),
83
- 20: field('anaerobic_training_effect', 'uint8', 10),
84
- 29: field('first_vo2_max', 'uint32', 65536 / 3.5, 'ml/kg/min'),
85
- 41: field('primary_benefit', 'uint8'),
86
- 60: field('total_ascent', 'uint16', 1, 'm'),
87
- 61: field('total_descent', 'uint16', 1, 'm'),
88
- 62: field('avg_power', 'uint16', 1, 'watts'),
89
- 63: field('avg_heart_rate', 'uint8', 1, 'bpm'),
90
- },
91
- 312: {
92
- name: 'split',
93
- 107: field('beginning_potential_stamina', 'uint8', 1, 'percent'),
94
- 108: field('ending_potential_stamina', 'uint8', 1, 'percent'),
95
- 109: field('min_stamina', 'uint8', 1, 'percent'),
96
- },
97
- };
98
- exports.FIT_VENDOR_TYPE_EXTENSIONS = {
99
- mesg_num: {
100
- 79: 'user_metrics',
101
- 140: 'activity_metrics',
102
- },
103
- };
104
- function field(name, type, scale = 1, units = '', baseType) {
105
- return Object.assign(Object.assign({ field: name, type }, (baseType ? { baseType } : {})), { scale, offset: 0, units });
106
- }
107
- function mergeVendorMessages() {
108
- const messages = Object.assign({}, garmin_profile_generated_js_1.GARMIN_MESSAGES);
109
- Object.entries(exports.FIT_VENDOR_MESSAGE_EXTENSIONS).forEach(([messageIdText, extension]) => {
110
- const messageId = Number(messageIdText);
111
- const standardMessage = messages[messageId];
112
- if (!standardMessage) {
113
- messages[messageId] = extension;
114
- return;
115
- }
116
- if (standardMessage.name !== extension.name) {
117
- throw new Error(`Vendor message ${messageId} conflicts with the Garmin SDK name`);
118
- }
119
- Object.keys(extension)
120
- .filter(key => key !== 'name')
121
- .forEach((fieldId) => {
122
- if (standardMessage[Number(fieldId)]) {
123
- throw new Error(`Vendor message ${messageId}, field ${fieldId} conflicts with the Garmin SDK profile`);
124
- }
125
- });
126
- messages[messageId] = Object.assign(Object.assign({}, standardMessage), extension);
127
- });
128
- return messages;
129
- }
130
- function mergeVendorTypes() {
131
- const types = Object.fromEntries(Object.entries(garmin_profile_generated_js_1.GARMIN_TYPES).map(([name, values]) => [name, Object.assign({}, values)]));
132
- Object.entries(exports.FIT_VENDOR_TYPE_EXTENSIONS).forEach(([name, extension]) => {
133
- var _a;
134
- const standardValues = (_a = types[name]) !== null && _a !== void 0 ? _a : {};
135
- Object.keys(extension).forEach((valueId) => {
136
- if (standardValues[Number(valueId)] !== undefined) {
137
- throw new Error(`Vendor type ${name}, value ${valueId} conflicts with the Garmin SDK profile`);
138
- }
139
- });
140
- types[name] = Object.assign(Object.assign({}, standardValues), extension);
141
- });
142
- return types;
143
- }
144
34
  exports.FIT = {
145
35
  scConst: 180 / Math.pow(2, 31),
146
36
  options,
147
- messages: mergeVendorMessages(),
148
- types: mergeVendorTypes(),
37
+ messages: profile_js_1.PROFILE_MESSAGES,
38
+ types: profile_js_1.PROFILE_TYPES,
149
39
  };
@@ -2097,6 +2097,7 @@ export interface ParsedFit {
2097
2097
  messages?: ParsedMessages;
2098
2098
  raw_developer_fields?: ParsedRawDeveloperField[];
2099
2099
  raw_messages?: ParsedRawFitMessage[];
2100
+ unmapped_messages?: ParsedRawFitMessage[];
2100
2101
  file_creator: ParsedFileCreator;
2101
2102
  device_settings: ParsedDeviceSettings;
2102
2103
  dive_summary?: ParsedDiveSummary;
@@ -0,0 +1,9 @@
1
+ import type { Message } from './fit.js';
2
+ /**
3
+ * Static, community-maintained FIT interoperability profile.
4
+ *
5
+ * This table is ordinary project source maintained under the repository's MIT
6
+ * license. See PROFILE.md for the maintenance and verification policy.
7
+ */
8
+ export declare const PROFILE_MESSAGES: Record<number, Message>;
9
+ export declare const PROFILE_TYPES: Record<string, Record<number, string | number>>;
@@ -1,10 +1,13 @@
1
- export const GARMIN_PROFILE_VERSION = {
2
- major: 21,
3
- minor: 208,
4
- patch: 0,
5
- type: 'Release',
6
- };
7
- export const GARMIN_MESSAGES = {
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROFILE_TYPES = exports.PROFILE_MESSAGES = void 0;
4
+ /**
5
+ * Static, community-maintained FIT interoperability profile.
6
+ *
7
+ * This table is ordinary project source maintained under the repository's MIT
8
+ * license. See PROFILE.md for the maintenance and verification policy.
9
+ */
10
+ exports.PROFILE_MESSAGES = {
8
11
  0: {
9
12
  0: {
10
13
  field: 'type',
@@ -2586,6 +2589,13 @@ export const GARMIN_MESSAGES = {
2586
2589
  offset: 0,
2587
2590
  units: 'Breaths/min',
2588
2591
  },
2592
+ 178: {
2593
+ field: 'est_sweat_loss',
2594
+ type: 'uint16',
2595
+ scale: 1,
2596
+ offset: 0,
2597
+ units: 'ml',
2598
+ },
2589
2599
  180: {
2590
2600
  field: 'enhanced_min_respiration_rate',
2591
2601
  type: 'uint16',
@@ -2640,6 +2650,13 @@ export const GARMIN_MESSAGES = {
2640
2650
  offset: 0,
2641
2651
  units: 'Flow',
2642
2652
  },
2653
+ 188: {
2654
+ field: 'primary_benefit',
2655
+ type: 'uint8',
2656
+ scale: 1,
2657
+ offset: 0,
2658
+ units: '',
2659
+ },
2643
2660
  192: {
2644
2661
  field: 'workout_feel',
2645
2662
  type: 'uint8',
@@ -2721,6 +2738,27 @@ export const GARMIN_MESSAGES = {
2721
2738
  offset: 0,
2722
2739
  units: 'm',
2723
2740
  },
2741
+ 205: {
2742
+ field: 'beginning_potential_stamina',
2743
+ type: 'uint8',
2744
+ scale: 1,
2745
+ offset: 0,
2746
+ units: 'percent',
2747
+ },
2748
+ 206: {
2749
+ field: 'ending_potential_stamina',
2750
+ type: 'uint8',
2751
+ scale: 1,
2752
+ offset: 0,
2753
+ units: 'percent',
2754
+ },
2755
+ 207: {
2756
+ field: 'min_stamina',
2757
+ type: 'uint8',
2758
+ scale: 1,
2759
+ offset: 0,
2760
+ units: 'percent',
2761
+ },
2724
2762
  208: {
2725
2763
  field: 'avg_core_temperature',
2726
2764
  type: 'uint16',
@@ -4419,6 +4457,13 @@ export const GARMIN_MESSAGES = {
4419
4457
  offset: 0,
4420
4458
  units: 'm',
4421
4459
  },
4460
+ 90: {
4461
+ field: 'garmin_performance_condition',
4462
+ type: 'sint8',
4463
+ scale: 1,
4464
+ offset: 0,
4465
+ units: '',
4466
+ },
4422
4467
  91: {
4423
4468
  field: 'absolute_pressure',
4424
4469
  type: 'uint32',
@@ -4626,6 +4671,20 @@ export const GARMIN_MESSAGES = {
4626
4671
  offset: 0,
4627
4672
  units: 'percent',
4628
4673
  },
4674
+ 137: {
4675
+ field: 'potential_stamina',
4676
+ type: 'uint8',
4677
+ scale: 1,
4678
+ offset: 0,
4679
+ units: 'percent',
4680
+ },
4681
+ 138: {
4682
+ field: 'stamina',
4683
+ type: 'uint8',
4684
+ scale: 1,
4685
+ offset: 0,
4686
+ units: 'percent',
4687
+ },
4629
4688
  139: {
4630
4689
  field: 'core_temperature',
4631
4690
  type: 'uint16',
@@ -4956,6 +5015,13 @@ export const GARMIN_MESSAGES = {
4956
5015
  offset: 0,
4957
5016
  units: '',
4958
5017
  },
5018
+ 24: {
5019
+ field: 'ant_id',
5020
+ type: 'uint32z',
5021
+ scale: 1,
5022
+ offset: 0,
5023
+ units: '',
5024
+ },
4959
5025
  25: {
4960
5026
  field: 'source_type',
4961
5027
  type: 'source_type',
@@ -6398,6 +6464,107 @@ export const GARMIN_MESSAGES = {
6398
6464
  },
6399
6465
  name: 'hrv',
6400
6466
  },
6467
+ 79: {
6468
+ 0: {
6469
+ field: 'vo2_max',
6470
+ type: 'uint16',
6471
+ scale: 292.57142857142856,
6472
+ offset: 0,
6473
+ units: 'ml/kg/min',
6474
+ },
6475
+ 1: {
6476
+ field: 'age',
6477
+ type: 'uint8',
6478
+ scale: 1,
6479
+ offset: 0,
6480
+ units: 'years',
6481
+ },
6482
+ 2: {
6483
+ field: 'height',
6484
+ type: 'uint8',
6485
+ scale: 100,
6486
+ offset: 0,
6487
+ units: 'm',
6488
+ },
6489
+ 3: {
6490
+ field: 'weight',
6491
+ type: 'uint16',
6492
+ scale: 10,
6493
+ offset: 0,
6494
+ units: 'kg',
6495
+ },
6496
+ 4: {
6497
+ field: 'gender',
6498
+ type: 'gender',
6499
+ scale: 1,
6500
+ offset: 0,
6501
+ units: '',
6502
+ },
6503
+ 6: {
6504
+ field: 'max_heart_rate',
6505
+ type: 'uint8',
6506
+ scale: 1,
6507
+ offset: 0,
6508
+ units: 'bpm',
6509
+ },
6510
+ 8: {
6511
+ field: 'remaining_recovery_time',
6512
+ type: 'uint16',
6513
+ scale: 1,
6514
+ offset: 0,
6515
+ units: '',
6516
+ },
6517
+ 11: {
6518
+ field: 'lthr',
6519
+ type: 'uint16',
6520
+ scale: 1,
6521
+ offset: 0,
6522
+ units: 'bpm',
6523
+ },
6524
+ 12: {
6525
+ field: 'ltpower',
6526
+ type: 'uint16',
6527
+ scale: 1,
6528
+ offset: 0,
6529
+ units: 'watts',
6530
+ },
6531
+ 13: {
6532
+ field: 'ltspeed',
6533
+ type: 'uint16',
6534
+ scale: 1000,
6535
+ offset: 0,
6536
+ units: 'm/s',
6537
+ },
6538
+ 16: {
6539
+ field: 'start_of_activity',
6540
+ type: 'date_time',
6541
+ scale: 1,
6542
+ offset: 0,
6543
+ units: '',
6544
+ },
6545
+ 19: {
6546
+ field: 'first_vo2_max',
6547
+ type: 'uint32',
6548
+ scale: 18724.571428571428,
6549
+ offset: 0,
6550
+ units: 'ml/kg/min',
6551
+ },
6552
+ 35: {
6553
+ field: 'end_of_previous_activity',
6554
+ type: 'date_time',
6555
+ scale: 1,
6556
+ offset: 0,
6557
+ units: '',
6558
+ },
6559
+ 253: {
6560
+ field: 'timestamp',
6561
+ type: 'date_time',
6562
+ scale: 1,
6563
+ offset: 0,
6564
+ units: '',
6565
+ },
6566
+ name: 'user_metrics',
6567
+ },
6401
6568
  80: {
6402
6569
  0: {
6403
6570
  field: 'fractional_timestamp',
@@ -7253,6 +7420,93 @@ export const GARMIN_MESSAGES = {
7253
7420
  },
7254
7421
  name: 'hr',
7255
7422
  },
7423
+ 140: {
7424
+ 1: {
7425
+ field: 'new_max_heart_rate',
7426
+ type: 'uint8',
7427
+ scale: 1,
7428
+ offset: 0,
7429
+ units: 'bpm',
7430
+ },
7431
+ 4: {
7432
+ field: 'aerobic_training_effect',
7433
+ type: 'uint8',
7434
+ scale: 10,
7435
+ offset: 0,
7436
+ units: '',
7437
+ },
7438
+ 7: {
7439
+ field: 'vo2_max',
7440
+ type: 'uint32',
7441
+ scale: 18724.571428571428,
7442
+ offset: 0,
7443
+ units: 'ml/kg/min',
7444
+ },
7445
+ 9: {
7446
+ field: 'recovery_time',
7447
+ type: 'uint16',
7448
+ scale: 1,
7449
+ offset: 0,
7450
+ units: 'min',
7451
+ },
7452
+ 11: {
7453
+ field: 'sport',
7454
+ type: 'sport',
7455
+ scale: 1,
7456
+ offset: 0,
7457
+ units: '',
7458
+ },
7459
+ 20: {
7460
+ field: 'anaerobic_training_effect',
7461
+ type: 'uint8',
7462
+ scale: 10,
7463
+ offset: 0,
7464
+ units: '',
7465
+ },
7466
+ 29: {
7467
+ field: 'first_vo2_max',
7468
+ type: 'uint32',
7469
+ scale: 18724.571428571428,
7470
+ offset: 0,
7471
+ units: 'ml/kg/min',
7472
+ },
7473
+ 41: {
7474
+ field: 'primary_benefit',
7475
+ type: 'uint8',
7476
+ scale: 1,
7477
+ offset: 0,
7478
+ units: '',
7479
+ },
7480
+ 60: {
7481
+ field: 'total_ascent',
7482
+ type: 'uint16',
7483
+ scale: 1,
7484
+ offset: 0,
7485
+ units: 'm',
7486
+ },
7487
+ 61: {
7488
+ field: 'total_descent',
7489
+ type: 'uint16',
7490
+ scale: 1,
7491
+ offset: 0,
7492
+ units: 'm',
7493
+ },
7494
+ 62: {
7495
+ field: 'avg_power',
7496
+ type: 'uint16',
7497
+ scale: 1,
7498
+ offset: 0,
7499
+ units: 'watts',
7500
+ },
7501
+ 63: {
7502
+ field: 'avg_heart_rate',
7503
+ type: 'uint8',
7504
+ scale: 1,
7505
+ offset: 0,
7506
+ units: 'bpm',
7507
+ },
7508
+ name: 'activity_metrics',
7509
+ },
7256
7510
  142: {
7257
7511
  0: {
7258
7512
  field: 'event',
@@ -11787,6 +12041,27 @@ export const GARMIN_MESSAGES = {
11787
12041
  offset: 0,
11788
12042
  units: 's',
11789
12043
  },
12044
+ 107: {
12045
+ field: 'beginning_potential_stamina',
12046
+ type: 'uint8',
12047
+ scale: 1,
12048
+ offset: 0,
12049
+ units: 'percent',
12050
+ },
12051
+ 108: {
12052
+ field: 'ending_potential_stamina',
12053
+ type: 'uint8',
12054
+ scale: 1,
12055
+ offset: 0,
12056
+ units: 'percent',
12057
+ },
12058
+ 109: {
12059
+ field: 'min_stamina',
12060
+ type: 'uint8',
12061
+ scale: 1,
12062
+ offset: 0,
12063
+ units: 'percent',
12064
+ },
11790
12065
  110: {
11791
12066
  field: 'total_moving_time',
11792
12067
  type: 'uint32',
@@ -13032,7 +13307,7 @@ export const GARMIN_MESSAGES = {
13032
13307
  name: 'sleep_disruption_overnight_severity',
13033
13308
  },
13034
13309
  };
13035
- export const GARMIN_TYPES = {
13310
+ exports.PROFILE_TYPES = {
13036
13311
  activity: {
13037
13312
  0: 'manual',
13038
13313
  1: 'auto_multi_sport',
@@ -15762,6 +16037,7 @@ export const GARMIN_TYPES = {
15762
16037
  55: 'monitoring',
15763
16038
  72: 'training_file',
15764
16039
  78: 'hrv',
16040
+ 79: 'user_metrics',
15765
16041
  80: 'ant_rx',
15766
16042
  81: 'ant_tx',
15767
16043
  82: 'ant_channel_id',
@@ -15774,6 +16050,7 @@ export const GARMIN_TYPES = {
15774
16050
  129: 'weather_alert',
15775
16051
  131: 'cadence_zone',
15776
16052
  132: 'hr',
16053
+ 140: 'activity_metrics',
15777
16054
  142: 'segment_lap',
15778
16055
  145: 'memo_glob',
15779
16056
  148: 'segment_id',
@@ -285,6 +285,7 @@ function generateFitType() {
285
285
  generateProperty('messages', typescript_1.default.factory.createTypeReferenceNode('ParsedMessages')),
286
286
  generateArrayProperty('raw_developer_fields', typescript_1.default.factory.createTypeReferenceNode('ParsedRawDeveloperField')),
287
287
  generateArrayProperty('raw_messages', typescript_1.default.factory.createTypeReferenceNode('ParsedRawFitMessage')),
288
+ generateArrayProperty('unmapped_messages', typescript_1.default.factory.createTypeReferenceNode('ParsedRawFitMessage')),
288
289
  ...Object.keys(referenceProperties).map(prop => generateProperty(prop, typescript_1.default.factory.createTypeReferenceNode(snakeToCamel(referenceProperties[prop].replace('?', ''))), referenceProperties[prop].startsWith('?'))),
289
290
  ...Object.keys(collectionProperties).map(prop => generateArrayProperty(prop, collectionProperties[prop] === 'unknown'
290
291
  ? typescript_1.default.factory.createKeywordTypeNode(typescript_1.default.SyntaxKind.UnknownKeyword)
@@ -15,6 +15,8 @@ export interface FitParserOptions {
15
15
  includeRawDeveloperFields?: boolean | readonly number[];
16
16
  /** Retains exact native and developer fields for all or selected global message numbers. */
17
17
  includeRawMessages?: boolean | readonly number[];
18
+ /** Retains exact bytes for fields that have no semantic profile mapping. */
19
+ includeUnmappedMessages?: boolean;
18
20
  /** Returns only parser metadata and retained raw messages instead of decoded activity collections. */
19
21
  rawMessagesOnly?: boolean;
20
22
  }