@garmin/fitsdk 21.202.0 → 21.205.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/package.json CHANGED
@@ -1,23 +1,25 @@
1
1
  {
2
- "name": "@garmin/fitsdk",
3
- "version": "21.202.0",
4
- "description": "FIT JavaScript SDK",
5
- "main": "src/index.js",
6
- "type": "module",
7
- "scripts": {
8
- "build": "node .",
9
- "test": "vitest run"
10
- },
11
- "author": "Garmin International, Inc.",
12
- "license": "SEE LICENSE IN LICENSE.txt",
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/garmin/fit-javascript-sdk"
16
- },
17
- "files": [
18
- "src/"
19
- ],
20
- "devDependencies": {
21
- "vitest": "^2.1.8"
22
- }
23
- }
2
+ "name": "@garmin/fitsdk",
3
+ "version": "21.205.0",
4
+ "description": "FIT JavaScript SDK",
5
+ "main": "src/index.js",
6
+ "types": "src/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "test": "vitest run --silent=passed-only --typecheck"
10
+ },
11
+ "author": "Garmin International, Inc.",
12
+ "license": "SEE LICENSE IN LICENSE.txt",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/garmin/fit-javascript-sdk"
16
+ },
17
+ "files": [
18
+ "src/"
19
+ ],
20
+ "devDependencies": {
21
+ "@types/node": "^22.0.0",
22
+ "typescript": "^5.0.0",
23
+ "vitest": "^4.1.5"
24
+ }
25
+ }
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
package/src/bit-stream.js CHANGED
@@ -5,25 +5,28 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
13
13
  import FIT from "./fit.js";
14
14
 
15
15
  class BitStream {
16
+ #data = null;
16
17
  #array = null;
17
18
  #currentArrayPosition = 0;
18
19
  #bitPerPosition = 0;
20
+ #isBigInt = false;
19
21
  #currentByte = 0;
20
22
  #currentBit = 0;
21
23
  #bitsAvailable = 0;
22
24
 
23
25
  constructor(data, baseType = FIT.BaseType.UINT8) {
24
- this.#array = Array.isArray(data) ? data : [data];
26
+ this.#data = Array.isArray(data) ? data : [data];
25
27
  const baseTypeSize = FIT.BaseTypeDefinitions[baseType].size;
26
28
  this.#bitPerPosition = baseTypeSize * 8;
29
+ this.#isBigInt = this.#bitPerPosition > 32;
27
30
  this.reset();
28
31
  }
29
32
 
@@ -36,9 +39,11 @@ class BitStream {
36
39
  }
37
40
 
38
41
  reset() {
42
+ this.#array = null;
39
43
  this.#currentArrayPosition = 0;
40
- this.#bitsAvailable = this.#bitPerPosition * this.#array.length;
41
- this.#nextByte();
44
+ this.#bitsAvailable = this.#bitPerPosition * this.#data.length;
45
+ this.#currentByte = 0;
46
+ this.#currentBit = 0;
42
47
  }
43
48
 
44
49
  readBit() {
@@ -46,12 +51,24 @@ class BitStream {
46
51
  this.#throwError();
47
52
  }
48
53
 
54
+ if (this.#array === null) {
55
+ this.#array = this.#data;
56
+ this.#currentArrayPosition = this.#data.length - (this.#bitsAvailable / this.#bitPerPosition);
57
+ this.#nextByte();
58
+ }
59
+
49
60
  if (this.#currentBit >= this.#bitPerPosition) {
50
61
  this.#nextByte();
51
62
  }
52
63
 
53
- const bit = this.#currentByte & 0x01;
54
- this.#currentByte = this.#currentByte >> 1;
64
+ let bit;
65
+ if (this.#isBigInt) {
66
+ bit = Number(this.#currentByte & 1n);
67
+ this.#currentByte >>= 1n;
68
+ } else {
69
+ bit = this.#currentByte & 0x01;
70
+ this.#currentByte >>= 1;
71
+ }
55
72
  this.#currentBit++;
56
73
  this.#bitsAvailable--;
57
74
 
@@ -59,10 +76,36 @@ class BitStream {
59
76
  }
60
77
 
61
78
  readBits(nBitsToRead) {
79
+ // Fast path: reading exactly one value's worth of bits and #array not yet initialized
80
+ if (nBitsToRead === this.#bitPerPosition && this.#array === null) {
81
+ if (!this.hasBitsAvailable) {
82
+ this.#throwError();
83
+ }
84
+ const index = this.#data.length - (this.#bitsAvailable / this.#bitPerPosition);
85
+ const value = this.#data[index];
86
+ this.#bitsAvailable -= nBitsToRead;
87
+
88
+ if (this.#isBigInt) {
89
+ return Number(BigInt.asUintN(nBitsToRead, value));
90
+ }
91
+ if (nBitsToRead < 32) {
92
+ return (value & ((1 << nBitsToRead) - 1)) >>> 0;
93
+ }
94
+ return value >>> 0;
95
+ }
96
+
97
+ if (nBitsToRead <= 32) {
98
+ let value = 0;
99
+ for (let i = 0; i < nBitsToRead; i++) {
100
+ value |= this.readBit() << i;
101
+ }
102
+ return value >>> 0;
103
+ }
104
+
62
105
  let value = 0n;
63
106
 
64
- for (let i = 0n; i < nBitsToRead; i++) {
65
- value |= BigInt(this.readBit()) << i;
107
+ for (let i = 0, shift = 0n; i < nBitsToRead; i++, shift++) {
108
+ value |= BigInt(this.readBit()) << shift;
66
109
  }
67
110
 
68
111
  return Number(value);
@@ -77,6 +120,10 @@ class BitStream {
77
120
  this.#currentBit = 0;
78
121
  }
79
122
 
123
+ get array() {
124
+ return this.#array;
125
+ }
126
+
80
127
  #throwError(error = "") {
81
128
  throw Error("FIT Runtime Error no bits available.");
82
129
  }
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
package/src/decoder.js CHANGED
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
@@ -61,12 +61,8 @@ class Decoder {
61
61
  #optIncludeUnknownData = false;
62
62
  #optMergeHeartRates = true;
63
63
  #optDecodeMemoGlobs = false;
64
+ #optLegacyArrayMode = false;
64
65
 
65
- /**
66
- * Creates a FIT File Decoder
67
- * @constructor
68
- * @param {Stream} stream - representing the FIT file to decode
69
- */
70
66
  constructor(stream) {
71
67
  if (stream == null) {
72
68
  throw Error("FIT Runtime Error stream parameter is null or undefined");
@@ -75,12 +71,6 @@ class Decoder {
75
71
  this.#stream = stream;
76
72
  }
77
73
 
78
- /**
79
- * Inspects the file header to determine if the input stream is a FIT file
80
- * @param {Stream} stream
81
- * @returns {Boolean} True if the stream is a FIT file
82
- * @static
83
- */
84
74
  static isFIT(stream) {
85
75
  try {
86
76
  const fileHeaderSize = stream.peekByte();
@@ -104,18 +94,10 @@ class Decoder {
104
94
  return true;
105
95
  }
106
96
 
107
- /**
108
- * Inspects the file header to determine if the input stream is a FIT file
109
- * @returns {Boolean} True if the stream is a FIT file
110
- */
111
97
  isFIT() {
112
98
  return Decoder.isFIT(this.#stream);
113
99
  }
114
100
 
115
- /**
116
- * Checks that the input stream is a FIT file and verifies both the header and file CRC values
117
- * @returns {Boolean} True if the stream passes the isFit() and CRC checks
118
- */
119
101
  checkIntegrity() {
120
102
  try {
121
103
  if (!this.isFIT()) {
@@ -128,7 +110,7 @@ class Decoder {
128
110
  return false;
129
111
  }
130
112
 
131
- const buf = new Uint8Array(this.#stream.slice(0, this.#stream.length))
113
+ const buf = this.#stream.asUint8Array();
132
114
 
133
115
  if (fileHeader.headerSize === HEADER_WITH_CRC_SIZE && fileHeader.headerCRC !== 0x0000
134
116
  && fileHeader.headerCRC != CrcCalculator.calculateCRC(buf, 0, 12)) {
@@ -147,48 +129,6 @@ class Decoder {
147
129
  return true;
148
130
  }
149
131
 
150
- /**
151
- * Message Listener Callback
152
- *
153
- * @callback Decoder~mesgListener
154
- * @param {Number} mesgNum - Profile.MesgNum
155
- * @param {Object} message - The message
156
- */
157
-
158
- /**
159
- * Message Definition Listener Callback
160
- *
161
- * @callback Decoder~mesgDefinitionListener
162
- * @param {Object} messageDefinition - The message Definition
163
- */
164
-
165
- /**
166
- * Developer Field Description Listener Callback
167
- *
168
- * @callback Decoder~fieldDescriptionListener
169
- * @param {Number} key - The key associated with this pairing of of Developer Data Id and Field Description Mesgs
170
- * @param {Object} developerDataIdMesg - The Developer Data Id Mesg associated with this pairing
171
- * @param {Object} fieldDescriptionMesg - The Field Description Mesg associated with this pairing
172
- */
173
-
174
- /**
175
- * Read the messages from the stream.
176
- * @param {Object=} [options] - Read options (optional)
177
- * @param {Decoder~mesgListener} [options.mesgListener=null] - (optional, default null) mesgListener(mesgNum, message)
178
- * @param {Decoder~mesgDefinitionListener} [options.mesgDefinitionListener=null] - (optional, default null) mesgDefinitionListener(mesgDefinition)
179
- * @param {Decoder~fieldDescriptionListener} [options.fieldDescriptionListener=null] - (optional, default null) fieldDescriptionListener(key, developerDataIdMesg, fieldDescriptionMesg)
180
- * @param {Boolean} [options.expandSubFields=true] - (optional, default true)
181
- * @param {Boolean} [options.expandComponents=true] - (optional, default true)
182
- * @param {Boolean} [options.applyScaleAndOffset=true] - (optional, default true)
183
- * @param {Boolean} [options.convertTypesToStrings=true] - (optional, default true)
184
- * @param {boolean} [options.convertDateTimesToDates=true] - (optional, default true)
185
- * @param {Boolean} [options.includeUnknownData=false] - (optional, default false)
186
- * @param {boolean} [options.mergeHeartRates=true] - (optional, default true)
187
- * @param {boolean} [options.decodeMemoGlobs=true] - (optional, default false)
188
- * @param {boolean} [options.skipHeader=false] - (optional, default false)
189
- * @param {boolean} [options.dataOnly=false] - (optional, default false)
190
- * @return {Object} result - {messages:Array, errors:Array}
191
- */
192
132
  read({
193
133
  mesgListener = null,
194
134
  mesgDefinitionListener = null,
@@ -202,7 +142,8 @@ class Decoder {
202
142
  mergeHeartRates = true,
203
143
  decodeMemoGlobs = false,
204
144
  skipHeader = false,
205
- dataOnly = false, } = {}) {
145
+ dataOnly = false,
146
+ legacyArrayMode = false, } = {}) {
206
147
 
207
148
  this.#mesgListener = mesgListener;
208
149
  this.#mesgDefinitionListener = mesgDefinitionListener;
@@ -215,6 +156,7 @@ class Decoder {
215
156
  this.#optIncludeUnknownData = includeUnknownData;
216
157
  this.#optMergeHeartRates = mergeHeartRates;
217
158
  this.#optDecodeMemoGlobs = decodeMemoGlobs;
159
+ this.#optLegacyArrayMode = legacyArrayMode;
218
160
 
219
161
  this.#localMessageDefinitions = [];
220
162
  this.#developerDataDefinitions = {};
@@ -224,6 +166,10 @@ class Decoder {
224
166
  const errors = [];
225
167
 
226
168
  try {
169
+ if (this.#optLegacyArrayMode) {
170
+ console.log("Decoder Warning: legacyArrayMode is deprecated and will be removed in the future. Afterwards, the default behavior will be equivalent to legacyArrayMode=false.");
171
+ }
172
+
227
173
  if (this.#optMergeHeartRates && (!this.#optApplyScaleAndOffset || !this.#optExpandComponents)) {
228
174
  this.#throwError("mergeHeartRates requires applyScaleAndOffset and expandComponents to be enabled");
229
175
  }
@@ -233,6 +179,7 @@ class Decoder {
233
179
  }
234
180
 
235
181
  this.#decodeMode = skipHeader ? DecodeMode.SKIP_HEADER : dataOnly ? DecodeMode.DATA_ONLY : DecodeMode.NORMAL;
182
+ this.#stream.legacyArrayMode = this.#optLegacyArrayMode;
236
183
 
237
184
  while (this.#stream.position < this.#stream.length) {
238
185
  this.#decodeNextFile();
@@ -304,9 +251,9 @@ class Decoder {
304
251
  messageDefinition["reserved"] = this.#stream.readByte();
305
252
 
306
253
  messageDefinition["architecture"] = this.#stream.readByte();
307
- messageDefinition["endianness"] = messageDefinition.architecture === 0 ? Stream.LITTLE_ENDIAN : Stream.BIG_ENDIAN;
254
+ messageDefinition["endianness"] = messageDefinition.architecture === 0;
308
255
 
309
- messageDefinition["globalMessageNumber"] = this.#stream.readUInt16({ endianness: messageDefinition["endianness"] });
256
+ messageDefinition["globalMessageNumber"] = this.#stream.readUInt16({ littleEndian: messageDefinition["endianness"] });
310
257
  messageDefinition["numFields"] = this.#stream.readByte();
311
258
  messageDefinition["fieldDefinitions"] = [];
312
259
  messageDefinition["developerFieldDefinitions"] = [];
@@ -346,7 +293,7 @@ class Decoder {
346
293
  }
347
294
  }
348
295
 
349
- this.#mesgDefinitionListener?.({...messageDefinition});
296
+ this.#mesgDefinitionListener?.({ ...messageDefinition });
350
297
 
351
298
  let messageProfile = Profile.messages[messageDefinition.globalMessageNumber];
352
299
 
@@ -417,7 +364,7 @@ class Decoder {
417
364
  developerFieldDefinition["invalidValue"] = FIT.BaseTypeDefinitions[developerFieldDefinition.baseType].invalid;
418
365
  developerFieldDefinition["baseTypeSize"] = FIT.BaseTypeDefinitions[developerFieldDefinition.baseType].size;
419
366
 
420
- const { rawFieldValue: fieldValue } = this.#readFieldValue(messageDefinition, developerFieldDefinition, field);
367
+ const fieldValue = this.#readDeveloperFieldValue(messageDefinition, developerFieldDefinition, field);
421
368
 
422
369
  if (fieldValue != null) {
423
370
  developerFields[field.key] = fieldValue;
@@ -458,7 +405,7 @@ class Decoder {
458
405
  return developerDataIdMesg.developerDataIndex === message.developerDataIndex;
459
406
  }) ?? {};
460
407
 
461
- this.#fieldDescriptionListener(message.key, {...developerDataIdMesg}, {...message});
408
+ this.#fieldDescriptionListener(message.key, { ...developerDataIdMesg }, { ...message });
462
409
  }
463
410
  }
464
411
  }
@@ -485,10 +432,22 @@ class Decoder {
485
432
  fieldDefinition.baseType,
486
433
  fieldDefinition.size,
487
434
  {
488
- endianness: messageDefinition["endianness"],
489
- convertInvalidToNull: !field?.hasComponents ?? false
490
- }
435
+ littleEndian: messageDefinition["endianness"],
436
+ convertInvalidToNull: !field?.hasComponents ?? false,
437
+ isArray: field?.array ?? fieldDefinition.size > fieldDefinition.baseTypeSize,
438
+ },
491
439
  );
440
+
441
+ return rawFieldValue;
442
+ }
443
+
444
+ #readDeveloperFieldValue(messageDefinition, developerFieldDefinition, field) {
445
+
446
+ // Preserve arrays for developer fields
447
+ this.#stream.legacyArrayMode = true;
448
+ const rawFieldValue = this.#readRawFieldValue(messageDefinition, developerFieldDefinition, field);
449
+ this.#stream.legacyArrayMode = this.#optLegacyArrayMode;
450
+
492
451
  return rawFieldValue;
493
452
  }
494
453
 
@@ -570,8 +529,9 @@ class Decoder {
570
529
  continue;
571
530
  }
572
531
  if (referenceField.rawFieldValue === map.value) {
573
- message[subField.name] = JSON.parse(JSON.stringify(message[field.name]));
574
- message[subField.name].isSubField = true;
532
+ const src = message[field.name];
533
+ const rawFieldValue = Array.isArray(src.rawFieldValue) ? [...src.rawFieldValue] : src.rawFieldValue;
534
+ message[subField.name] = { ...src, rawFieldValue, isSubField: true };
575
535
 
576
536
  if (subField.hasComponents) {
577
537
  this.#fieldsToExpand.push(subField.name);
@@ -625,6 +585,7 @@ class Decoder {
625
585
  rawFieldValue: [],
626
586
  fieldDefinitionNumber: targetField.num,
627
587
  isExpandedField: true,
588
+ isArray: targetField?.array ?? false,
628
589
  invalidValue,
629
590
  };
630
591
  }
@@ -663,8 +624,9 @@ class Decoder {
663
624
  }
664
625
 
665
626
  Object.keys(mesg).forEach((key) => {
666
- mesg[key].fieldValue = UtilsInternal.sanitizeValues(mesg[key].fieldValue);
667
- mesg[key].rawFieldValue = UtilsInternal.sanitizeValues(mesg[key].rawFieldValue);
627
+ const field = mesg[key];
628
+ mesg[key].fieldValue = UtilsInternal.sanitizeValues(field.fieldValue, { legacyArrayMode: this.#optLegacyArrayMode, isArray: field.isArray });
629
+ mesg[key].rawFieldValue = UtilsInternal.sanitizeValues(field.rawFieldValue, { legacyArrayMode: this.#optLegacyArrayMode, isArray: field.isArray });
668
630
 
669
631
  message[key] = mesg[key];
670
632
  });
@@ -693,7 +655,7 @@ class Decoder {
693
655
  if (field == null) {
694
656
  fieldValue = rawFieldValue;
695
657
  }
696
- else if (FIT.NumericFieldTypes.includes(field?.type ?? -1)) {
658
+ else if (FIT.NumericFieldTypesSet.has(field?.type ?? -1)) {
697
659
  fieldValue = this.#applyScaleAndOffset(messageDefinition, field, rawFieldValue);
698
660
  }
699
661
  else if (field.type === "string") {
@@ -717,7 +679,7 @@ class Decoder {
717
679
  return rawFieldValue;
718
680
  }
719
681
 
720
- if (FIT.NumericFieldTypes.includes(field?.type ?? -1) === false) {
682
+ if (FIT.NumericFieldTypesSet.has(field?.type ?? -1) === false) {
721
683
  return rawFieldValue;
722
684
  }
723
685
 
@@ -760,7 +722,7 @@ class Decoder {
760
722
  components.forEach((componentFieldNum, i) => {
761
723
  const targetField = messageDefinition.fields[componentFieldNum];
762
724
 
763
- if(targetField?.num == field.num && targetField?.isAccumulated) {
725
+ if (targetField?.num == field.num && targetField?.isAccumulated) {
764
726
  value = (((value / field.scale) - field.offset) + containingField.offset[i]) * containingField.scale[i];
765
727
  }
766
728
  });
@@ -775,7 +737,7 @@ class Decoder {
775
737
  return rawFieldValue;
776
738
  }
777
739
 
778
- if (FIT.NumericFieldTypes.includes(field?.type ?? -1)) {
740
+ if (FIT.NumericFieldTypesSet.has(field?.type ?? -1)) {
779
741
  return rawFieldValue;
780
742
  }
781
743
 
package/src/encoder.js CHANGED
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
@@ -20,17 +20,7 @@ import Utils from "./utils.js";
20
20
  const HEADER_WITH_CRC_SIZE = 14;
21
21
  const HEADER_WITHOUT_CRC_SIZE = 12;
22
22
 
23
- /**
24
- * A class for encoding FIT files.
25
- * @class
26
- */
27
23
  class Encoder {
28
- /**
29
- Creates a FIT File Encoder
30
- * @param {Object} [options] - Encoder options (optional)
31
- * @param {Object.<number,{object, object }} [options.fieldDescriptions=null] - (optional, default null) fieldDescriptions
32
- * @constructor
33
- */
34
24
  constructor({ fieldDescriptions = null, } = {}) {
35
25
  this.#fieldDescriptions = {};
36
26
 
@@ -41,10 +31,6 @@ class Encoder {
41
31
  this.#writeEmptyFileHeader();
42
32
  }
43
33
 
44
- /**
45
- * Closes the encoder and returns the file data
46
- * @returns {Uint8Array} A Uint8Array containing the file data
47
- */
48
34
  close() {
49
35
  this.#updateFileHeader();
50
36
  this.#writeFileCrc();
@@ -52,23 +38,10 @@ class Encoder {
52
38
  return this.#outputStream.uint8Array;
53
39
  }
54
40
 
55
- /**
56
- * Encodes a mesg into the file.
57
- * @param {Object} mesg - The message data
58
- * @param {Number} mesg.mesgNum - The mesg number for this message
59
- * @return {this}
60
- */
61
41
  writeMesg(mesg) {
62
42
  return this.onMesg(mesg.mesgNum, mesg);
63
43
  }
64
44
 
65
- /**
66
- * Encodes a mesg into the file.
67
- * This method can be used as a Decoder~mesgListener callback.
68
- * @param {Number} mesgNum - The message number for this message
69
- * @param {Object} mesg - The message data
70
- * @return {this}
71
- */
72
45
  onMesg(mesgNum, mesg) {
73
46
  try {
74
47
  const mesgDefinition = this.#createMesgDefinition(mesgNum, mesg);
@@ -113,16 +86,6 @@ class Encoder {
113
86
  return this;
114
87
  };
115
88
 
116
- /**
117
- * Adds a Developer Data Field Description and associated Developer Data Id Message to the Endoder
118
- * This provides the Encoder with the context required to write Developer Fields to the output-stream.
119
- * *** This method does not write the messages to the output-stream ***
120
- * This method can be used as a Decoder~fieldDescriptionListener callback.
121
- * @param {Number} key - The message number for this message
122
- * @param {Object} developerDataIdMesg - The Developer Data Id mesg
123
- * @param {Object} fieldDescriptionMesg - The Field Description mesg
124
- * @return {this}
125
- */
126
89
  addDeveloperField(key, developerDataIdMesg, fieldDescriptionMesg) {
127
90
  if(developerDataIdMesg.developerDataIndex == null || fieldDescriptionMesg.developerDataIndex == null) {
128
91
  throw new Error("addDeveloperField() - one or more developerDataIndex values are null.", {
package/src/fit.js CHANGED
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
@@ -73,6 +73,8 @@ const NumericFieldTypes = [
73
73
  "uint64z"
74
74
  ];
75
75
 
76
+ const NumericFieldTypesSet = new Set(NumericFieldTypes);
77
+
76
78
  const FieldTypeToJsType = {
77
79
  "enum": "number",
78
80
  "sint8": "number",
@@ -202,6 +204,7 @@ export default {
202
204
  BaseTypeMask,
203
205
  BaseTypeDefinitions,
204
206
  NumericFieldTypes,
207
+ NumericFieldTypesSet,
205
208
  BigIntFieldTypes,
206
209
  FloatingPointFieldTypes,
207
210
  FieldTypeToBaseType,
package/src/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ /////////////////////////////////////////////////////////////////////////////////////////////
2
+ // Copyright 2026 Garmin International, Inc.
3
+ // Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
4
+ // may not use this file except in compliance with the Flexible and Interoperable Data
5
+ // Transfer (FIT) Protocol License.
6
+ /////////////////////////////////////////////////////////////////////////////////////////////
7
+ // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
+ /////////////////////////////////////////////////////////////////////////////////////////////
11
+
12
+
13
+ export * from './types/crc-calculator';
14
+ export * from './types/decoder';
15
+ export * from './types/encoder';
16
+ export * from './types/mesg';
17
+ export * from './types/mesgs';
18
+ export * from './types/profile';
19
+ export * from './types/stream';
20
+ export * from './types/types';
21
+ export { default as Types } from './types/types';
22
+ export * from './types/utils';
package/src/index.js CHANGED
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12
 
@@ -5,8 +5,8 @@
5
5
  // Transfer (FIT) Protocol License.
6
6
  /////////////////////////////////////////////////////////////////////////////////////////////
7
7
  // ****WARNING**** This file is auto-generated! Do NOT edit this file.
8
- // Profile Version = 21.202.0Release
9
- // Tag = production/release/21.202.0-0-g9a57aebc
8
+ // Profile Version = 21.205.0Release
9
+ // Tag = production/release/21.205.0-0-gb3c261eb
10
10
  /////////////////////////////////////////////////////////////////////////////////////////////
11
11
 
12
12