@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 +24 -22
- package/src/accumulator.js +2 -2
- package/src/bit-stream.js +56 -9
- package/src/crc-calculator.js +2 -2
- package/src/decoder.js +43 -81
- package/src/encoder.js +2 -39
- package/src/fit.js +5 -2
- package/src/index.d.ts +22 -0
- package/src/index.js +2 -2
- package/src/mesg-definition.js +2 -2
- package/src/output-stream.js +2 -2
- package/src/profile.js +8 -4
- package/src/stream.js +107 -90
- package/src/types/crc-calculator.d.ts +34 -0
- package/src/types/decoder.d.ts +140 -0
- package/src/types/encoder.d.ts +69 -0
- package/src/types/mesg.d.ts +35 -0
- package/src/types/mesgs.d.ts +2638 -0
- package/src/types/profile.d.ts +96 -0
- package/src/types/stream.d.ts +118 -0
- package/src/types/types.d.ts +4871 -0
- package/src/types/utils.d.ts +55 -0
- package/src/utils-hr-mesg.js +2 -2
- package/src/utils-internal.js +14 -6
- package/src/utils-memo-glob.js +2 -2
- package/src/utils.js +2 -16
package/src/profile.js
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
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.205.0Release
|
|
9
|
+
// Tag = production/release/21.205.0-0-gb3c261eb
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
const Profile = {
|
|
14
14
|
version: {
|
|
15
15
|
major: 21,
|
|
16
|
-
minor:
|
|
16
|
+
minor: 205,
|
|
17
17
|
patch: 0,
|
|
18
18
|
type: "Release"
|
|
19
19
|
},
|
|
@@ -20950,7 +20950,7 @@ const Profile = {
|
|
|
20950
20950
|
array: true,
|
|
20951
20951
|
scale: 1000,
|
|
20952
20952
|
offset: 0,
|
|
20953
|
-
units: "
|
|
20953
|
+
units: "C",
|
|
20954
20954
|
bits: [],
|
|
20955
20955
|
components: [],
|
|
20956
20956
|
isAccumulated: false,
|
|
@@ -25104,10 +25104,14 @@ types: {
|
|
|
25104
25104
|
4759: "instinct3Solar50mm",
|
|
25105
25105
|
4775: "tactix8Amoled",
|
|
25106
25106
|
4776: "tactix8Solar",
|
|
25107
|
+
4814: "fr170Music",
|
|
25108
|
+
4815: "fr170",
|
|
25107
25109
|
4825: "approachJ1",
|
|
25108
25110
|
4879: "d2Mach2",
|
|
25111
|
+
4916: "fr702026",
|
|
25109
25112
|
4678: "instinctCrossoverAmoled",
|
|
25110
25113
|
4944: "d2AirX15",
|
|
25114
|
+
5056: "d2Mach2Pro",
|
|
25111
25115
|
10007: "sdm4", // SDM4 footpod
|
|
25112
25116
|
10014: "edgeRemote",
|
|
25113
25117
|
20533: "tacxTrainingAppWin",
|
package/src/stream.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.
|
|
9
|
-
// Tag = production/release/21.
|
|
8
|
+
// Profile Version = 21.205.0Release
|
|
9
|
+
// Tag = production/release/21.205.0-0-gb3c261eb
|
|
10
10
|
/////////////////////////////////////////////////////////////////////////////////////////////
|
|
11
11
|
|
|
12
12
|
|
|
@@ -14,55 +14,32 @@ import FIT from "./fit.js";
|
|
|
14
14
|
import UtilsInternal from "./utils-internal.js";
|
|
15
15
|
|
|
16
16
|
class Stream {
|
|
17
|
-
static LITTLE_ENDIAN = true;
|
|
18
|
-
static BIG_ENDIAN = false;
|
|
19
|
-
|
|
20
17
|
#position = 0;
|
|
21
18
|
#arrayBuffer = null;
|
|
19
|
+
#dataView = null;
|
|
22
20
|
#textDecoder = new TextDecoder("utf-8", { fatal: false, ignoreBOM: true });
|
|
23
21
|
#crcCalculator = null;
|
|
22
|
+
#legacyArrayMode = false;
|
|
24
23
|
|
|
25
|
-
/**
|
|
26
|
-
* Convenience method for creating a Stream from a byte array
|
|
27
|
-
* @param {Array<number>} data An array of bytes
|
|
28
|
-
* @returns {Stream} A new Stream object
|
|
29
|
-
* @static
|
|
30
|
-
*/
|
|
31
24
|
static fromByteArray(data) {
|
|
32
25
|
const buf = new Uint8Array(data);
|
|
33
26
|
return this.fromArrayBuffer(buf.buffer);
|
|
34
27
|
}
|
|
35
28
|
|
|
36
|
-
/**
|
|
37
|
-
* Convenience method for creating a Stream from a Node Buffer
|
|
38
|
-
* @param {Buffer} buffer - Node Buffer of bytes
|
|
39
|
-
* @returns {Stream} A new Stream object
|
|
40
|
-
* @static
|
|
41
|
-
*/
|
|
42
29
|
static fromBuffer(buffer) {
|
|
43
30
|
const arrayBuffer = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
|
44
31
|
return this.fromArrayBuffer(arrayBuffer);
|
|
45
32
|
}
|
|
46
33
|
|
|
47
|
-
/**
|
|
48
|
-
* Convenience method for creating a Stream from an ArrayBuffer
|
|
49
|
-
* @param {ArrayBuffer} arrayBuffer - An ArrayBuffer of bytes
|
|
50
|
-
* @returns {Stream} A new Stream object
|
|
51
|
-
* @static
|
|
52
|
-
*/
|
|
53
34
|
static fromArrayBuffer(arrayBuffer) {
|
|
54
35
|
const stream = new Stream(arrayBuffer);
|
|
55
36
|
return stream;
|
|
56
37
|
}
|
|
57
38
|
|
|
58
|
-
/**
|
|
59
|
-
* Creates a Stream containing a FIT file
|
|
60
|
-
* @constructor
|
|
61
|
-
* @param {ArrayBuffer} stream - ArrayBuffer containing a FIT file
|
|
62
|
-
*/
|
|
63
39
|
constructor(arrayBuffer) {
|
|
64
40
|
this.#position = 0;
|
|
65
41
|
this.#arrayBuffer = arrayBuffer;
|
|
42
|
+
this.#dataView = new DataView(arrayBuffer);
|
|
66
43
|
}
|
|
67
44
|
|
|
68
45
|
get length() {
|
|
@@ -85,6 +62,14 @@ class Stream {
|
|
|
85
62
|
this.#crcCalculator = crcCalculator;
|
|
86
63
|
}
|
|
87
64
|
|
|
65
|
+
get legacyArrayMode() {
|
|
66
|
+
return this.#legacyArrayMode;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
set legacyArrayMode(legacyArrayMode) {
|
|
70
|
+
this.#legacyArrayMode = legacyArrayMode;
|
|
71
|
+
}
|
|
72
|
+
|
|
88
73
|
reset() {
|
|
89
74
|
this.seek(0);
|
|
90
75
|
}
|
|
@@ -98,9 +83,7 @@ class Stream {
|
|
|
98
83
|
}
|
|
99
84
|
|
|
100
85
|
peekByte() {
|
|
101
|
-
|
|
102
|
-
const dataView = new DataView(arrayBuffer);
|
|
103
|
-
return dataView.getUint8(0);
|
|
86
|
+
return this.#dataView.getUint8(this.#position);
|
|
104
87
|
}
|
|
105
88
|
|
|
106
89
|
readByte() {
|
|
@@ -160,14 +143,27 @@ class Stream {
|
|
|
160
143
|
return this.readValue(FIT.BaseType.FLOAT64, 8, { convertInvalidToNull: false, ...opts });
|
|
161
144
|
}
|
|
162
145
|
|
|
163
|
-
readString(strlen) {
|
|
164
|
-
return this.readValue(FIT.BaseType.STRING, strlen);
|
|
146
|
+
readString(strlen, opts = {}) {
|
|
147
|
+
return this.readValue(FIT.BaseType.STRING, strlen, opts);
|
|
165
148
|
}
|
|
166
149
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
150
|
+
asUint8Array() {
|
|
151
|
+
return new Uint8Array(this.#arrayBuffer);
|
|
152
|
+
}
|
|
170
153
|
|
|
154
|
+
readValue(
|
|
155
|
+
baseType,
|
|
156
|
+
size,
|
|
157
|
+
{
|
|
158
|
+
littleEndian = true,
|
|
159
|
+
convertInvalidToNull = true,
|
|
160
|
+
isArray = false
|
|
161
|
+
} = {}) {
|
|
162
|
+
const baseTypeDef = FIT.BaseTypeDefinitions[baseType];
|
|
163
|
+
const baseTypeSize = baseTypeDef.size;
|
|
164
|
+
const baseTypeInvalid = baseTypeDef.invalid;
|
|
165
|
+
|
|
166
|
+
const startPos = this.#position;
|
|
171
167
|
const bytes = this.readBytes(size);
|
|
172
168
|
|
|
173
169
|
if (size % baseTypeSize !== 0) {
|
|
@@ -186,73 +182,94 @@ class Stream {
|
|
|
186
182
|
return null;
|
|
187
183
|
}
|
|
188
184
|
|
|
189
|
-
|
|
190
|
-
|
|
185
|
+
if (this.#legacyArrayMode) {
|
|
186
|
+
return strings.length === 1 ? strings[0] : strings;
|
|
187
|
+
}
|
|
191
188
|
|
|
192
|
-
|
|
193
|
-
|
|
189
|
+
return strings[0];
|
|
190
|
+
}
|
|
194
191
|
|
|
195
192
|
const count = size / baseTypeSize;
|
|
196
193
|
|
|
197
|
-
|
|
194
|
+
if (count === 1) {
|
|
195
|
+
const value = this.#readSingleValue(baseType, startPos, littleEndian);
|
|
196
|
+
|
|
197
|
+
if (convertInvalidToNull && value === baseTypeInvalid) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
198
200
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
case FIT.BaseType.ENUM:
|
|
202
|
-
case FIT.BaseType.UINT8:
|
|
203
|
-
case FIT.BaseType.UINT8Z:
|
|
204
|
-
values.push(dataView.getUint8(i * baseTypeSize));
|
|
205
|
-
break;
|
|
206
|
-
|
|
207
|
-
case FIT.BaseType.SINT8:
|
|
208
|
-
values.push(dataView.getInt8(i * baseTypeSize));
|
|
209
|
-
break;
|
|
210
|
-
|
|
211
|
-
case FIT.BaseType.UINT16:
|
|
212
|
-
case FIT.BaseType.UINT16Z:
|
|
213
|
-
values.push(dataView.getUint16(i * baseTypeSize, endianness));
|
|
214
|
-
break;
|
|
215
|
-
|
|
216
|
-
case FIT.BaseType.SINT16:
|
|
217
|
-
values.push(dataView.getInt16(i * baseTypeSize, endianness));
|
|
218
|
-
break;
|
|
219
|
-
|
|
220
|
-
case FIT.BaseType.UINT32:
|
|
221
|
-
case FIT.BaseType.UINT32Z:
|
|
222
|
-
values.push(dataView.getUint32(i * baseTypeSize, endianness));
|
|
223
|
-
break;
|
|
224
|
-
|
|
225
|
-
case FIT.BaseType.SINT32:
|
|
226
|
-
values.push(dataView.getInt32(i * baseTypeSize, endianness));
|
|
227
|
-
break;
|
|
228
|
-
|
|
229
|
-
case FIT.BaseType.UINT64:
|
|
230
|
-
case FIT.BaseType.UINT64Z:
|
|
231
|
-
values.push(dataView.getBigUint64(i * baseTypeSize, endianness));
|
|
232
|
-
break;
|
|
233
|
-
case FIT.BaseType.SINT64:
|
|
234
|
-
values.push(dataView.getBigInt64(i * baseTypeSize, endianness));
|
|
235
|
-
break;
|
|
236
|
-
|
|
237
|
-
case FIT.BaseType.FLOAT32:
|
|
238
|
-
values.push(dataView.getFloat32(i * baseTypeSize, endianness));
|
|
239
|
-
break;
|
|
240
|
-
|
|
241
|
-
case FIT.BaseType.FLOAT64:
|
|
242
|
-
values.push(dataView.getFloat64(i * baseTypeSize, endianness));
|
|
243
|
-
break;
|
|
201
|
+
if (!this.#legacyArrayMode && !isArray) {
|
|
202
|
+
return value;
|
|
244
203
|
}
|
|
204
|
+
|
|
205
|
+
return UtilsInternal.sanitizeValues([value], { legacyArrayMode: this.#legacyArrayMode, isArray });
|
|
245
206
|
}
|
|
246
207
|
|
|
247
|
-
|
|
248
|
-
|
|
208
|
+
let values = [];
|
|
209
|
+
|
|
210
|
+
for (let i = 0; i < count; i++) {
|
|
211
|
+
values.push(this.#readSingleValue(baseType, startPos + i * baseTypeSize, littleEndian));
|
|
249
212
|
}
|
|
250
213
|
|
|
251
214
|
if (convertInvalidToNull) {
|
|
252
|
-
|
|
215
|
+
if (UtilsInternal.onlyInvalidValues(values, baseTypeInvalid)) {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (baseType !== FIT.BaseType.BYTE) {
|
|
220
|
+
values = values.map(value => value === baseTypeInvalid ? null : value);
|
|
221
|
+
}
|
|
253
222
|
}
|
|
254
223
|
|
|
255
|
-
return UtilsInternal.sanitizeValues(
|
|
224
|
+
return UtilsInternal.sanitizeValues(
|
|
225
|
+
values,
|
|
226
|
+
{
|
|
227
|
+
legacyArrayMode: this.#legacyArrayMode,
|
|
228
|
+
isArray
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
#readSingleValue(baseType, offset, littleEndian) {
|
|
233
|
+
switch (baseType) {
|
|
234
|
+
case FIT.BaseType.BYTE:
|
|
235
|
+
case FIT.BaseType.ENUM:
|
|
236
|
+
case FIT.BaseType.UINT8:
|
|
237
|
+
case FIT.BaseType.UINT8Z:
|
|
238
|
+
return this.#dataView.getUint8(offset);
|
|
239
|
+
|
|
240
|
+
case FIT.BaseType.SINT8:
|
|
241
|
+
return this.#dataView.getInt8(offset);
|
|
242
|
+
|
|
243
|
+
case FIT.BaseType.UINT16:
|
|
244
|
+
case FIT.BaseType.UINT16Z:
|
|
245
|
+
return this.#dataView.getUint16(offset, littleEndian);
|
|
246
|
+
|
|
247
|
+
case FIT.BaseType.SINT16:
|
|
248
|
+
return this.#dataView.getInt16(offset, littleEndian);
|
|
249
|
+
|
|
250
|
+
case FIT.BaseType.UINT32:
|
|
251
|
+
case FIT.BaseType.UINT32Z:
|
|
252
|
+
return this.#dataView.getUint32(offset, littleEndian);
|
|
253
|
+
|
|
254
|
+
case FIT.BaseType.SINT32:
|
|
255
|
+
return this.#dataView.getInt32(offset, littleEndian);
|
|
256
|
+
|
|
257
|
+
case FIT.BaseType.UINT64:
|
|
258
|
+
case FIT.BaseType.UINT64Z:
|
|
259
|
+
return this.#dataView.getBigUint64(offset, littleEndian);
|
|
260
|
+
|
|
261
|
+
case FIT.BaseType.SINT64:
|
|
262
|
+
return this.#dataView.getBigInt64(offset, littleEndian);
|
|
263
|
+
|
|
264
|
+
case FIT.BaseType.FLOAT32:
|
|
265
|
+
return this.#dataView.getFloat32(offset, littleEndian);
|
|
266
|
+
|
|
267
|
+
case FIT.BaseType.FLOAT64:
|
|
268
|
+
return this.#dataView.getFloat64(offset, littleEndian);
|
|
269
|
+
|
|
270
|
+
default:
|
|
271
|
+
throw new Error(`Unsupported FIT base type: ${baseType}`);
|
|
272
|
+
}
|
|
256
273
|
}
|
|
257
274
|
}
|
|
258
275
|
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
/** Computes the 16-bit CRC used to validate FIT file headers and file data. */
|
|
14
|
+
export class CrcCalculator {
|
|
15
|
+
constructor();
|
|
16
|
+
/** The current running CRC value. */
|
|
17
|
+
readonly crc: number;
|
|
18
|
+
/**
|
|
19
|
+
* Feeds a range of bytes into the running CRC.
|
|
20
|
+
* @param buf - The byte array to process.
|
|
21
|
+
* @param start - Inclusive start index within `buf`.
|
|
22
|
+
* @param end - Exclusive end index within `buf`.
|
|
23
|
+
* @returns The updated CRC value.
|
|
24
|
+
*/
|
|
25
|
+
addBytes(buf: Uint8Array, start: number, end: number): number;
|
|
26
|
+
/**
|
|
27
|
+
* Computes the CRC for a range of bytes without requiring an instance.
|
|
28
|
+
* @param buf - The byte array to process.
|
|
29
|
+
* @param start - Inclusive start index within `buf`.
|
|
30
|
+
* @param end - Exclusive end index within `buf`.
|
|
31
|
+
* @returns The computed CRC value.
|
|
32
|
+
*/
|
|
33
|
+
static calculateCRC(buf: Uint8Array, start: number, end: number): number;
|
|
34
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
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
|
+
import { Stream } from "./stream";
|
|
14
|
+
import { Mesg } from "./mesg";
|
|
15
|
+
import { FitMessages, DeveloperDataIdMesg, FieldDescriptionMesg } from "./mesgs";
|
|
16
|
+
|
|
17
|
+
/** Decodes FIT binary data from a {@link Stream}. */
|
|
18
|
+
export class Decoder {
|
|
19
|
+
/**
|
|
20
|
+
* Creates a FIT File Decoder.
|
|
21
|
+
* @param stream - Stream representing the FIT file to decode.
|
|
22
|
+
*/
|
|
23
|
+
constructor(stream: Stream);
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Inspects the file header to determine if the input stream is a FIT file.
|
|
27
|
+
* @param stream - The stream to inspect.
|
|
28
|
+
* @returns `true` if the stream is a FIT file.
|
|
29
|
+
*/
|
|
30
|
+
static isFIT(stream: Stream): boolean;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Inspects the file header to determine if the input stream is a FIT file.
|
|
34
|
+
* @returns `true` if the stream is a FIT file.
|
|
35
|
+
*/
|
|
36
|
+
isFIT(): boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Checks that the input stream is a FIT file and verifies both the header and file CRC values.
|
|
40
|
+
* @returns `true` if the stream passes the {@link isFIT} and CRC checks.
|
|
41
|
+
*/
|
|
42
|
+
checkIntegrity(): boolean;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Read the messages from the stream.
|
|
46
|
+
* @param options - Read options. See {@link DecoderOptions}.
|
|
47
|
+
* @returns Object containing decoded messages, profile version, and any errors.
|
|
48
|
+
*/
|
|
49
|
+
read(options?: DecoderOptions): { messages: FitMessages; profileVersion: ProfileVersion; errors: Error[] };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Describes a single field within a MesgDefinition. */
|
|
53
|
+
export interface FieldDefinition {
|
|
54
|
+
/** Field definition number identifying the field within its message. */
|
|
55
|
+
fieldDefinitionNumber: number;
|
|
56
|
+
/** Size in bytes of the field. */
|
|
57
|
+
size: number;
|
|
58
|
+
/** FIT base type identifier for this field's values. */
|
|
59
|
+
baseType: number;
|
|
60
|
+
/** The invalid value for this field's base type. */
|
|
61
|
+
invalidValue: number;
|
|
62
|
+
/** Byte size of a single element of this field's base type. */
|
|
63
|
+
baseTypeSize: number;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Describes a single developer-defined field within a raw FIT message definition record. */
|
|
67
|
+
export interface DeveloperFieldDefinition {
|
|
68
|
+
/** Developer field definition number, scoped to the developer data index. */
|
|
69
|
+
fieldDefinitionNumber: number;
|
|
70
|
+
/** Size in bytes of the field. */
|
|
71
|
+
size: number;
|
|
72
|
+
/** Index identifying the developer application that defined this field. */
|
|
73
|
+
developerDataIndex: number;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** The definition record for a FIT message*/
|
|
77
|
+
export interface MesgDefinition {
|
|
78
|
+
/** Raw record header byte. */
|
|
79
|
+
recordHeader: number;
|
|
80
|
+
/** Local message number used to map messages to a definition. */
|
|
81
|
+
localMesgNum: number;
|
|
82
|
+
/** Reserved byte from the definition record. */
|
|
83
|
+
reserved: number;
|
|
84
|
+
/** Architecture byte: `0` = little-endian, `1` = big-endian. */
|
|
85
|
+
architecture: number;
|
|
86
|
+
/** Endianness derived from `architecture` (`true` == little-endian or `false` == big-endian). */
|
|
87
|
+
endianness: boolean;
|
|
88
|
+
/** Global message number identifying the message type in the FIT profile. */
|
|
89
|
+
globalMessageNumber: number;
|
|
90
|
+
/** Number of fields in the message. */
|
|
91
|
+
numFields: number;
|
|
92
|
+
/** Array of field definitions for the message. */
|
|
93
|
+
fieldDefinitions: FieldDefinition[];
|
|
94
|
+
/** Developer field definitions for the message. */
|
|
95
|
+
developerFieldDefinitions: DeveloperFieldDefinition[];
|
|
96
|
+
/** Total size in bytes of the combined fields. */
|
|
97
|
+
messageSize: number;
|
|
98
|
+
/** Total size in bytes of the combined developer fields. */
|
|
99
|
+
developerDataSize: number;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Options controlling how {@link Decoder.read} decodes the FIT stream. */
|
|
103
|
+
export interface DecoderOptions {
|
|
104
|
+
/** Callback invoked for each decoded message. */
|
|
105
|
+
mesgListener?: (mesgNum: number, mesg: Mesg) => void;
|
|
106
|
+
/** Callback invoked for each decoded message definition. */
|
|
107
|
+
mesgDefinitionListener?: (mesgDefinition: MesgDefinition) => void;
|
|
108
|
+
/** Callback invoked for each developer field description. */
|
|
109
|
+
fieldDescriptionListener?: (key: number, developerDataIdMesg: DeveloperDataIdMesg, fieldDescriptionMesg: FieldDescriptionMesg) => void;
|
|
110
|
+
/** Expand sub fields. Default: `true`. */
|
|
111
|
+
expandSubFields?: boolean;
|
|
112
|
+
/** Expand component fields. Default: `true`. */
|
|
113
|
+
expandComponents?: boolean;
|
|
114
|
+
/** Apply scale and offset to numeric fields. Default: `true`. */
|
|
115
|
+
applyScaleAndOffset?: boolean;
|
|
116
|
+
/** Convert type values to their string representations. Default: `true`. */
|
|
117
|
+
convertTypesToStrings?: boolean;
|
|
118
|
+
/** Convert FIT epoch timestamps to `Date` objects. Default: `true`. */
|
|
119
|
+
convertDateTimesToDates?: boolean;
|
|
120
|
+
/** Include fields not in the profile. Default: `false`. */
|
|
121
|
+
includeUnknownData?: boolean;
|
|
122
|
+
/** Merge HR messages into record messages. Requires `applyScaleAndOffset` and `expandComponents`. Default: `true`. */
|
|
123
|
+
mergeHeartRates?: boolean;
|
|
124
|
+
/** Decode memo glob messages. Default: `false`. */
|
|
125
|
+
decodeMemoGlobs?: boolean;
|
|
126
|
+
/** Skip the FIT file header. Default: `false`. */
|
|
127
|
+
skipHeader?: boolean;
|
|
128
|
+
/** Decode data bytes only, no header or CRC. Default: `false`. */
|
|
129
|
+
dataOnly?: boolean;
|
|
130
|
+
/** @deprecated Default: `false`. */
|
|
131
|
+
legacyArrayMode?: boolean;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The FIT profile version embedded in a FIT file header. */
|
|
135
|
+
export interface ProfileVersion {
|
|
136
|
+
/** Major version number. */
|
|
137
|
+
major: number;
|
|
138
|
+
/** Minor version number (tenths). */
|
|
139
|
+
minor: number;
|
|
140
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
import { Encodable, Mesg } from "./mesg";
|
|
14
|
+
import { DeveloperDataIdMesg, FieldDescriptionMesg } from "./mesgs";
|
|
15
|
+
|
|
16
|
+
export interface FieldDescription {
|
|
17
|
+
/** The Developer Data Id message. */
|
|
18
|
+
developerDataIdMesg: DeveloperDataIdMesg;
|
|
19
|
+
/** The Field Description message. */
|
|
20
|
+
fieldDescriptionMesg: FieldDescriptionMesg;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Options for constructing an {@link Encoder}. */
|
|
24
|
+
export interface EncoderOptions {
|
|
25
|
+
/** Developer field descriptions keyed by developer data index. Equivalent to calling {@link Encoder.addDeveloperField} for each entry. */
|
|
26
|
+
fieldDescriptions?: Record<number, FieldDescription>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Encodes FIT messages into a binary FIT file. */
|
|
30
|
+
export class Encoder {
|
|
31
|
+
/**
|
|
32
|
+
* Creates a FIT File Encoder.
|
|
33
|
+
* @param options - Encoder options. See {@link EncoderOptions}.
|
|
34
|
+
*/
|
|
35
|
+
constructor(options?: EncoderOptions);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Closes the encoder and returns the encoded file data.
|
|
39
|
+
* @returns A `Uint8Array` containing the encoded FIT file.
|
|
40
|
+
*/
|
|
41
|
+
close(): Uint8Array;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Encodes a message into the file.
|
|
45
|
+
* @param mesg - The message data, must include a `mesgNum` property.
|
|
46
|
+
* @returns `this`.
|
|
47
|
+
*/
|
|
48
|
+
writeMesg(mesg: Encodable<Mesg>): this;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Encodes a message into the file.
|
|
52
|
+
* Can be used directly as a {@link DecoderOptions.mesgListener} callback.
|
|
53
|
+
* @param mesgNum - The message number.
|
|
54
|
+
* @param mesg - The message data.
|
|
55
|
+
* @returns `this`.
|
|
56
|
+
*/
|
|
57
|
+
onMesg(mesgNum: number, mesg: Mesg): this;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Adds a Developer Data Field Description and associated Developer Data Id Message to the Encoder.
|
|
61
|
+
* Does not write these messages to the output stream.
|
|
62
|
+
* Can be used directly as a {@link DecoderOptions.fieldDescriptionListener} callback.
|
|
63
|
+
* @param key - The key associated with this developer field pairing.
|
|
64
|
+
* @param developerDataIdMesg - The Developer Data Id message.
|
|
65
|
+
* @param fieldDescriptionMesg - The Field Description message.
|
|
66
|
+
* @returns `this`.
|
|
67
|
+
*/
|
|
68
|
+
addDeveloperField(key: number, developerDataIdMesg: DeveloperDataIdMesg, fieldDescriptionMesg: FieldDescriptionMesg): this;
|
|
69
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
import Types from "./types";
|
|
14
|
+
|
|
15
|
+
/** A FIT field value — a scalar or array of one of the primitive FIT base types. */
|
|
16
|
+
export type FieldValue =
|
|
17
|
+
| string
|
|
18
|
+
| number
|
|
19
|
+
| boolean
|
|
20
|
+
| bigint
|
|
21
|
+
| Date
|
|
22
|
+
| (string | number | boolean | bigint | Date)[];
|
|
23
|
+
|
|
24
|
+
/** Developer-defined fields keyed by developer field key. */
|
|
25
|
+
export type DeveloperFields = { [developerFieldKey: string]: FieldValue | undefined };
|
|
26
|
+
|
|
27
|
+
/** Base interface for all decoded FIT messages. */
|
|
28
|
+
export interface Mesg {
|
|
29
|
+
/** Global FIT message number identifying the message type. */
|
|
30
|
+
mesgNum?: Types.MesgNum;
|
|
31
|
+
/** Developer-defined field values attached to this message. */
|
|
32
|
+
developerFields?: DeveloperFields;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export type Encodable<T extends Mesg> = T & Required<Pick<Mesg, 'mesgNum'>>;
|