@garmin/fitsdk 21.178.0 → 21.194.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/README.md +298 -288
- package/package.json +1 -1
- package/src/accumulator.js +3 -3
- package/src/bit-stream.js +3 -3
- package/src/crc-calculator.js +3 -3
- package/src/decoder.js +26 -13
- package/src/encoder.js +30 -5
- package/src/fit.js +78 -33
- package/src/index.js +3 -3
- package/src/mesg-definition.js +11 -6
- package/src/output-stream.js +11 -8
- package/src/profile.js +37 -7
- package/src/stream.js +3 -3
- package/src/utils-hr-mesg.js +3 -3
- package/src/utils-internal.js +3 -3
- package/src/utils-memo-glob.js +3 -3
- package/src/utils.js +3 -3
package/src/bit-stream.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
package/src/crc-calculator.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
package/src/decoder.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
@@ -30,6 +30,7 @@ const LOCAL_MESG_NUM_MASK = 0x0F;
|
|
|
30
30
|
const HEADER_WITH_CRC_SIZE = 14;
|
|
31
31
|
const HEADER_WITHOUT_CRC_SIZE = 12;
|
|
32
32
|
const CRC_SIZE = 2;
|
|
33
|
+
const PROFILE_VERSION_SCALE_CHANGE_VALUE = 2199;
|
|
33
34
|
|
|
34
35
|
const DecodeMode = Object.freeze({
|
|
35
36
|
NORMAL: "normal",
|
|
@@ -43,6 +44,7 @@ class Decoder {
|
|
|
43
44
|
#stream = null;
|
|
44
45
|
#accumulator = new Accumulator();
|
|
45
46
|
#messages = {};
|
|
47
|
+
#profileVersion = null;
|
|
46
48
|
#fieldsWithSubFields = [];
|
|
47
49
|
#fieldsToExpand = [];
|
|
48
50
|
|
|
@@ -200,7 +202,7 @@ class Decoder {
|
|
|
200
202
|
mergeHeartRates = true,
|
|
201
203
|
decodeMemoGlobs = false,
|
|
202
204
|
skipHeader = false,
|
|
203
|
-
dataOnly = false,} = {}) {
|
|
205
|
+
dataOnly = false, } = {}) {
|
|
204
206
|
|
|
205
207
|
this.#mesgListener = mesgListener;
|
|
206
208
|
this.#mesgDefinitionListener = mesgDefinitionListener;
|
|
@@ -217,6 +219,7 @@ class Decoder {
|
|
|
217
219
|
this.#localMessageDefinitions = [];
|
|
218
220
|
this.#developerDataDefinitions = {};
|
|
219
221
|
this.#messages = {};
|
|
222
|
+
this.#profileVersion = null;
|
|
220
223
|
|
|
221
224
|
const errors = [];
|
|
222
225
|
|
|
@@ -247,7 +250,7 @@ class Decoder {
|
|
|
247
250
|
errors.push(error);
|
|
248
251
|
}
|
|
249
252
|
finally {
|
|
250
|
-
return { messages: this.#messages, errors: errors };
|
|
253
|
+
return { messages: this.#messages, profileVersion: this.#profileVersion, errors: errors };
|
|
251
254
|
}
|
|
252
255
|
}
|
|
253
256
|
|
|
@@ -260,7 +263,8 @@ class Decoder {
|
|
|
260
263
|
|
|
261
264
|
this.#stream.crcCalculator = new CrcCalculator();
|
|
262
265
|
|
|
263
|
-
const { headerSize, dataSize } = Decoder.#readFileHeader(this.#stream, { decodeMode: this.#decodeMode });
|
|
266
|
+
const { headerSize, dataSize, profileVersion, } = Decoder.#readFileHeader(this.#stream, { decodeMode: this.#decodeMode });
|
|
267
|
+
this.#profileVersion ??= profileVersion;
|
|
264
268
|
|
|
265
269
|
// Read data messages and definitions
|
|
266
270
|
while (this.#stream.position < (position + headerSize + dataSize)) {
|
|
@@ -313,7 +317,7 @@ class Decoder {
|
|
|
313
317
|
const fieldDefinition = {
|
|
314
318
|
fieldDefinitionNumber: this.#stream.readByte(),
|
|
315
319
|
size: this.#stream.readByte(),
|
|
316
|
-
baseType: this.#stream.readByte()
|
|
320
|
+
baseType: this.#stream.readByte() & FIT.BaseTypeMask,
|
|
317
321
|
};
|
|
318
322
|
|
|
319
323
|
if (!(fieldDefinition.baseType in FIT.BaseTypeDefinitions)) {
|
|
@@ -515,7 +519,7 @@ class Decoder {
|
|
|
515
519
|
this.#developerDataDefinitions[message.developerDataIndex.rawFieldValue].fields.push({
|
|
516
520
|
developerDataIndex: message.developerDataIndex?.rawFieldValue,
|
|
517
521
|
fieldDefinitionNumber: message.fieldDefinitionNumber?.rawFieldValue,
|
|
518
|
-
fitBaseTypeId: message.fitBaseTypeId?.rawFieldValue ?? null,
|
|
522
|
+
fitBaseTypeId: message.fitBaseTypeId?.rawFieldValue & FIT.BaseTypeMask ?? null,
|
|
519
523
|
fieldName: message.fieldName?.rawFieldValue ?? null,
|
|
520
524
|
array: message.array?.rawFieldValue ?? null,
|
|
521
525
|
components: message.components?.rawFieldValue ?? null,
|
|
@@ -799,26 +803,27 @@ class Decoder {
|
|
|
799
803
|
static #readFileHeader(stream, { resetPosition = false, decodeMode = DecodeMode.NORMAL }) {
|
|
800
804
|
const position = stream.position;
|
|
801
805
|
|
|
802
|
-
if(decodeMode !== DecodeMode.NORMAL) {
|
|
803
|
-
if(decodeMode === DecodeMode.SKIP_HEADER) {
|
|
806
|
+
if (decodeMode !== DecodeMode.NORMAL) {
|
|
807
|
+
if (decodeMode === DecodeMode.SKIP_HEADER) {
|
|
804
808
|
stream.seek(HEADER_WITH_CRC_SIZE);
|
|
805
809
|
}
|
|
806
810
|
|
|
807
811
|
const headerSize = decodeMode === DecodeMode.SKIP_HEADER ? HEADER_WITH_CRC_SIZE : 0;
|
|
812
|
+
const dataSize = stream.length - headerSize - CRC_SIZE;
|
|
808
813
|
|
|
809
814
|
return {
|
|
810
815
|
headerSize,
|
|
811
|
-
dataSize
|
|
816
|
+
dataSize,
|
|
812
817
|
};
|
|
813
818
|
}
|
|
814
819
|
|
|
815
820
|
const fileHeader = {
|
|
816
821
|
headerSize: stream.readByte(),
|
|
817
822
|
protocolVersion: stream.readByte(),
|
|
818
|
-
profileVersion: stream.readUInt16(),
|
|
823
|
+
profileVersion: this.#expandProfileVersion(stream.readUInt16()),
|
|
819
824
|
dataSize: stream.readUInt32(),
|
|
820
825
|
dataType: stream.readString(4),
|
|
821
|
-
headerCRC:
|
|
826
|
+
headerCRC: null
|
|
822
827
|
};
|
|
823
828
|
|
|
824
829
|
if (fileHeader.headerSize === 14) {
|
|
@@ -835,6 +840,14 @@ class Decoder {
|
|
|
835
840
|
#throwError(error = "") {
|
|
836
841
|
throw Error(`FIT Runtime Error at byte ${this.#stream.position} ${error}`.trimEnd());
|
|
837
842
|
}
|
|
843
|
+
|
|
844
|
+
static #expandProfileVersion = (profileVersion) => {
|
|
845
|
+
const scale = profileVersion > PROFILE_VERSION_SCALE_CHANGE_VALUE ? 1000 : 100
|
|
846
|
+
return {
|
|
847
|
+
major: Math.floor(profileVersion / scale),
|
|
848
|
+
minor: profileVersion % scale
|
|
849
|
+
}
|
|
850
|
+
}
|
|
838
851
|
}
|
|
839
852
|
|
|
840
853
|
export default Decoder;
|
package/src/encoder.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
@@ -212,12 +212,25 @@ class Encoder {
|
|
|
212
212
|
throw new Error();
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
+
// Convert valid numeric strings to the correct type
|
|
216
|
+
if (FIT.isString(value)) {
|
|
217
|
+
value = FIT.BigIntFieldTypes.includes(fieldDefinition.type)
|
|
218
|
+
? BigInt(value)
|
|
219
|
+
: Number(value);
|
|
220
|
+
}
|
|
221
|
+
|
|
215
222
|
const hasScaleOrOffset = (fieldDefinition.scale != FIT.FIELD_DEFAULT_SCALE || fieldDefinition.offset != FIT.FIELD_DEFAULT_OFFSET);
|
|
216
223
|
|
|
224
|
+
if (!hasScaleOrOffset && !this.#isValidType(value, fieldDefinition.type)) {
|
|
225
|
+
throw new Error();
|
|
226
|
+
}
|
|
227
|
+
|
|
217
228
|
if (hasScaleOrOffset) {
|
|
218
|
-
const scaledValue = (value
|
|
229
|
+
const scaledValue = this.#unapplyScaleAndOffset(value, fieldDefinition.scale, fieldDefinition.offset);
|
|
230
|
+
|
|
231
|
+
const roundedValue = FIT.FloatingPointFieldTypes.includes(fieldDefinition.type) || FIT.isBigInt(scaledValue) ? scaledValue : Math.round(scaledValue);
|
|
219
232
|
|
|
220
|
-
return FIT.
|
|
233
|
+
return FIT.BigIntFieldTypes.includes(fieldDefinition.type) ? BigInt(roundedValue) : Number(roundedValue);
|
|
221
234
|
}
|
|
222
235
|
|
|
223
236
|
return value;
|
|
@@ -265,6 +278,18 @@ class Encoder {
|
|
|
265
278
|
}
|
|
266
279
|
}
|
|
267
280
|
|
|
281
|
+
#isValidType = (value, type) => {
|
|
282
|
+
const jsType = FIT.FieldTypeToJsType[type];
|
|
283
|
+
|
|
284
|
+
return typeof value === jsType
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
#unapplyScaleAndOffset(value, scale, offset) {
|
|
288
|
+
return FIT.isBigInt(value)
|
|
289
|
+
? (value + BigInt(offset)) * BigInt(scale)
|
|
290
|
+
: (value + offset) * scale;
|
|
291
|
+
}
|
|
292
|
+
|
|
268
293
|
/**
|
|
269
294
|
* Creates a MesgDefinition from the mesgNum and mesg.
|
|
270
295
|
* @param {Number} mesgNum - The mesg number for this message
|
package/src/fit.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
@@ -17,40 +17,42 @@ const BaseType = {
|
|
|
17
17
|
ENUM: 0x00,
|
|
18
18
|
SINT8: 0x01,
|
|
19
19
|
UINT8: 0x02,
|
|
20
|
-
SINT16:
|
|
21
|
-
UINT16:
|
|
22
|
-
SINT32:
|
|
23
|
-
UINT32:
|
|
20
|
+
SINT16: 0x03,
|
|
21
|
+
UINT16: 0x04,
|
|
22
|
+
SINT32: 0x05,
|
|
23
|
+
UINT32: 0x06,
|
|
24
24
|
STRING: 0x07,
|
|
25
|
-
FLOAT32:
|
|
26
|
-
FLOAT64:
|
|
25
|
+
FLOAT32: 0x08,
|
|
26
|
+
FLOAT64: 0x09,
|
|
27
27
|
UINT8Z: 0x0A,
|
|
28
|
-
UINT16Z:
|
|
29
|
-
UINT32Z:
|
|
28
|
+
UINT16Z: 0x0B,
|
|
29
|
+
UINT32Z: 0x0C,
|
|
30
30
|
BYTE: 0x0D,
|
|
31
|
-
SINT64:
|
|
32
|
-
UINT64:
|
|
33
|
-
UINT64Z:
|
|
31
|
+
SINT64: 0x0E,
|
|
32
|
+
UINT64: 0x0F,
|
|
33
|
+
UINT64Z: 0x10
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
const BaseTypeMask = 0x1F;
|
|
37
|
+
|
|
36
38
|
const BaseTypeDefinitions = {
|
|
37
|
-
0x00: { size: 1, type: BaseType.ENUM, invalid: 0xFF },
|
|
38
|
-
0x01: { size: 1, type: BaseType.SINT8, invalid: 0x7F },
|
|
39
|
-
0x02: { size: 1, type: BaseType.UINT8, invalid: 0xFF },
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
0x07: { size: 1, type: BaseType.STRING, invalid: 0x00 },
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
0x0A: { size: 1, type: BaseType.UINT8Z, invalid: 0x00 },
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
0x0D: { size: 1, type: BaseType.BYTE, invalid: 0xFF },
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
39
|
+
0x00: { size: 1, type: BaseType.ENUM, baseTypeEndianFlag: 0x00, invalid: 0xFF },
|
|
40
|
+
0x01: { size: 1, type: BaseType.SINT8, baseTypeEndianFlag: 0x00, invalid: 0x7F },
|
|
41
|
+
0x02: { size: 1, type: BaseType.UINT8, baseTypeEndianFlag: 0x00, invalid: 0xFF },
|
|
42
|
+
0x03: { size: 2, type: BaseType.SINT16, baseTypeEndianFlag: 0x80, invalid: 0x7FFF },
|
|
43
|
+
0x04: { size: 2, type: BaseType.UINT16, baseTypeEndianFlag: 0x80, invalid: 0xFFFF },
|
|
44
|
+
0x05: { size: 4, type: BaseType.SINT32, baseTypeEndianFlag: 0x80, invalid: 0x7FFFFFFF },
|
|
45
|
+
0x06: { size: 4, type: BaseType.UINT32, baseTypeEndianFlag: 0x80, invalid: 0xFFFFFFFF },
|
|
46
|
+
0x07: { size: 1, type: BaseType.STRING, baseTypeEndianFlag: 0x00, invalid: 0x00 },
|
|
47
|
+
0x08: { size: 4, type: BaseType.FLOAT32, baseTypeEndianFlag: 0x80, invalid: 0xFFFFFFFF },
|
|
48
|
+
0x09: { size: 8, type: BaseType.FLOAT64, baseTypeEndianFlag: 0x80, invalid: 0xFFFFFFFFFFFFFFFF },
|
|
49
|
+
0x0A: { size: 1, type: BaseType.UINT8Z, baseTypeEndianFlag: 0x00, invalid: 0x00 },
|
|
50
|
+
0x0B: { size: 2, type: BaseType.UINT16Z, baseTypeEndianFlag: 0x80, invalid: 0x0000 },
|
|
51
|
+
0x0C: { size: 4, type: BaseType.UINT32Z, baseTypeEndianFlag: 0x80, invalid: 0x00000000 },
|
|
52
|
+
0x0D: { size: 1, type: BaseType.BYTE, baseTypeEndianFlag: 0x00, invalid: 0xFF },
|
|
53
|
+
0x0E: { size: 8, type: BaseType.SINT64, baseTypeEndianFlag: 0x80, invalid: 0x7FFFFFFFFFFFFFFF },
|
|
54
|
+
0x0F: { size: 8, type: BaseType.UINT64, baseTypeEndianFlag: 0x80, invalid: 0xFFFFFFFFFFFFFFFF },
|
|
55
|
+
0x10: { size: 8, type: BaseType.UINT64Z, baseTypeEndianFlag: 0x80, invalid: 0x0000000000000000 },
|
|
54
56
|
};
|
|
55
57
|
|
|
56
58
|
const NumericFieldTypes = [
|
|
@@ -71,6 +73,32 @@ const NumericFieldTypes = [
|
|
|
71
73
|
"uint64z"
|
|
72
74
|
];
|
|
73
75
|
|
|
76
|
+
const FieldTypeToJsType = {
|
|
77
|
+
"enum": "number",
|
|
78
|
+
"sint8": "number",
|
|
79
|
+
"uint8": "number",
|
|
80
|
+
"sint16": "number",
|
|
81
|
+
"uint16": "number",
|
|
82
|
+
"sint32": "number",
|
|
83
|
+
"uint32": "number",
|
|
84
|
+
"string": "string",
|
|
85
|
+
"float32": "number",
|
|
86
|
+
"float64": "number",
|
|
87
|
+
"uint8z": "number",
|
|
88
|
+
"uint16z": "number",
|
|
89
|
+
"uint32z": "number",
|
|
90
|
+
"byte": "number",
|
|
91
|
+
"sint64": "bigint",
|
|
92
|
+
"uint64": "bigint",
|
|
93
|
+
"uint64z": "bigint"
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const BigIntFieldTypes = [
|
|
97
|
+
"sint64",
|
|
98
|
+
"uint64",
|
|
99
|
+
"uint64z"
|
|
100
|
+
];
|
|
101
|
+
|
|
74
102
|
const FloatingPointFieldTypes = [
|
|
75
103
|
"float32",
|
|
76
104
|
"float64",
|
|
@@ -136,8 +164,21 @@ const isString = (obj) => {
|
|
|
136
164
|
return typeof obj === "string";
|
|
137
165
|
};
|
|
138
166
|
|
|
167
|
+
const isBigInt = (obj) => {
|
|
168
|
+
return typeof obj === "bigint";
|
|
169
|
+
};
|
|
170
|
+
|
|
139
171
|
const isNumeric = (obj) => {
|
|
140
|
-
|
|
172
|
+
if (typeof obj === "number") {
|
|
173
|
+
return !isNaN(obj) && isFinite(obj);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (typeof obj === "bigint") {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const num = parseFloat(obj);
|
|
181
|
+
return !isNaN(num) && isFinite(num);
|
|
141
182
|
};
|
|
142
183
|
|
|
143
184
|
const isNotNumberStringDateOrBoolean = (obj) => {
|
|
@@ -149,7 +190,7 @@ const isNumberStringDateOrBoolean = (obj) => {
|
|
|
149
190
|
return false;
|
|
150
191
|
}
|
|
151
192
|
|
|
152
|
-
if (!
|
|
193
|
+
if (!isNumeric(obj) && !isDate(obj) && !isString(obj) && !isBoolean(obj)) {
|
|
153
194
|
return false;
|
|
154
195
|
}
|
|
155
196
|
|
|
@@ -158,16 +199,20 @@ const isNumberStringDateOrBoolean = (obj) => {
|
|
|
158
199
|
|
|
159
200
|
export default {
|
|
160
201
|
BaseType,
|
|
202
|
+
BaseTypeMask,
|
|
161
203
|
BaseTypeDefinitions,
|
|
162
204
|
NumericFieldTypes,
|
|
205
|
+
BigIntFieldTypes,
|
|
163
206
|
FloatingPointFieldTypes,
|
|
164
207
|
FieldTypeToBaseType,
|
|
165
208
|
BaseTypeToFieldType,
|
|
209
|
+
FieldTypeToJsType,
|
|
166
210
|
isNullOrUndefined,
|
|
167
211
|
isObject,
|
|
168
212
|
isBoolean,
|
|
169
213
|
isDate,
|
|
170
214
|
isString,
|
|
215
|
+
isBigInt,
|
|
171
216
|
isNumeric,
|
|
172
217
|
isNumberStringDateOrBoolean,
|
|
173
218
|
isNotNumberStringDateOrBoolean,
|
package/src/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
package/src/mesg-definition.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
@@ -67,6 +67,7 @@ class MesgDefinition {
|
|
|
67
67
|
num: fieldProfile[1].num,
|
|
68
68
|
size: this.#fieldSize(mesg[fieldName], baseTypeDef),
|
|
69
69
|
baseType: baseType,
|
|
70
|
+
baseTypeEndianFlag: baseTypeDef.baseTypeEndianFlag,
|
|
70
71
|
type: fieldProfile[1].type,
|
|
71
72
|
scale,
|
|
72
73
|
offset,
|
|
@@ -77,14 +78,18 @@ class MesgDefinition {
|
|
|
77
78
|
Object.keys(mesg.developerFields ?? {})?.sort()?.forEach((key) => {
|
|
78
79
|
const { developerDataIdMesg, fieldDescriptionMesg, } = this.#fieldDescriptionForKey(fieldDescriptions, key);
|
|
79
80
|
|
|
80
|
-
const baseTypeDef = FIT.BaseTypeDefinitions[fieldDescriptionMesg.fitBaseTypeId];
|
|
81
|
+
const baseTypeDef = FIT.BaseTypeDefinitions[fieldDescriptionMesg.fitBaseTypeId & FIT.BaseTypeMask];
|
|
81
82
|
|
|
82
83
|
this.developerFieldDefinitions.push({
|
|
83
84
|
key,
|
|
84
|
-
baseType: fieldDescriptionMesg.fitBaseTypeId,
|
|
85
|
+
baseType: fieldDescriptionMesg.fitBaseTypeId & FIT.BaseTypeMask,
|
|
85
86
|
fieldDefinitionNumber: fieldDescriptionMesg.fieldDefinitionNumber,
|
|
86
87
|
size: this.#fieldSize(mesg.developerFields[key], baseTypeDef),
|
|
87
88
|
developerDataIndex: developerDataIdMesg.developerDataIndex,
|
|
89
|
+
type: FIT.BaseTypeToFieldType[baseTypeDef.type],
|
|
90
|
+
scale: 1,
|
|
91
|
+
offset: 0,
|
|
92
|
+
components: [],
|
|
88
93
|
});
|
|
89
94
|
});
|
|
90
95
|
|
|
@@ -137,7 +142,7 @@ class MesgDefinition {
|
|
|
137
142
|
this.fieldDefinitions.forEach((fieldDefinition) => {
|
|
138
143
|
outputStream.writeUInt8(fieldDefinition.num);
|
|
139
144
|
outputStream.writeUInt8(fieldDefinition.size);
|
|
140
|
-
outputStream.writeUInt8(fieldDefinition.baseType);
|
|
145
|
+
outputStream.writeUInt8(fieldDefinition.baseType | fieldDefinition.baseTypeEndianFlag);
|
|
141
146
|
});
|
|
142
147
|
|
|
143
148
|
// Developer Field Definitions
|
package/src/output-stream.js
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
2
|
-
// Copyright
|
|
2
|
+
// Copyright 2026 Garmin International, Inc.
|
|
3
3
|
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
|
|
4
4
|
// may not use this file except in compliance with the Flexible and Interoperable Data
|
|
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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.194.0Release
|
|
9
|
+
// Tag = production/release/21.194.0-0-g65135fc
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
import FIT from "./fit.js";
|
|
14
14
|
|
|
15
15
|
const ONE_MEGABYTE = 1048576;
|
|
16
|
-
const
|
|
16
|
+
const FIVE_HUNDRED_MEGABYTES = ONE_MEGABYTE * 500;
|
|
17
17
|
const HALF_MEGABYTE = ONE_MEGABYTE / 2;
|
|
18
|
+
const MAX_BYTE_LENGTH = FIVE_HUNDRED_MEGABYTES;
|
|
18
19
|
|
|
19
20
|
class OutputStream {
|
|
20
21
|
#arrayBuffer = null;
|
|
@@ -29,12 +30,12 @@ class OutputStream {
|
|
|
29
30
|
* @constructor
|
|
30
31
|
* @param {Object=} [options] - Read options (optional)
|
|
31
32
|
* @param {Number} [options.initialByteLength=0.5MB] - (optional, default 0.5 MB)
|
|
32
|
-
* @param {Number} [options.maxByteLength=
|
|
33
|
+
* @param {Number} [options.maxByteLength=500MB] - (optional, default 500 MB)
|
|
33
34
|
* @param {Number} [options.resizeByBytes=0.5MB] - (optional, default 0.5 MB)
|
|
34
35
|
*/
|
|
35
36
|
constructor({
|
|
36
37
|
initialByteLength = HALF_MEGABYTE,
|
|
37
|
-
maxByteLength =
|
|
38
|
+
maxByteLength = MAX_BYTE_LENGTH,
|
|
38
39
|
resizeByBytes = HALF_MEGABYTE,
|
|
39
40
|
} = {}) {
|
|
40
41
|
this.#arrayBuffer = new ArrayBuffer(initialByteLength, { maxByteLength, });
|
|
@@ -209,11 +210,13 @@ class OutputStream {
|
|
|
209
210
|
return;
|
|
210
211
|
}
|
|
211
212
|
|
|
212
|
-
|
|
213
|
+
const newByteLength = this.#arrayBuffer.byteLength + Math.max(this.#resizeByBytes, byteCount);
|
|
214
|
+
|
|
215
|
+
if (newByteLength > this.#arrayBuffer.maxByteLength) {
|
|
213
216
|
throw new Error("Can not resize OutputStream. Set a larger initial size.");
|
|
214
217
|
}
|
|
215
218
|
|
|
216
|
-
this.#arrayBuffer.resize(
|
|
219
|
+
this.#arrayBuffer.resize(newByteLength);
|
|
217
220
|
}
|
|
218
221
|
}
|
|
219
222
|
|