fit-file-parser 4.0.0 → 4.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.
- package/CHANGELOG.md +7 -0
- package/dist/binary.d.ts +8 -0
- package/dist/binary.js +114 -39
- package/dist/cjs/binary.d.ts +8 -0
- package/dist/cjs/binary.js +114 -39
- package/dist/cjs/fit.js +420 -100
- package/dist/cjs/fit_types.d.ts +1 -1
- package/dist/fit.js +420 -100
- package/dist/fit_types.d.ts +1 -1
- package/package.json +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 4.0.2
|
|
4
|
+
|
|
5
|
+
- Preserve record alignment when developer-field descriptions are missing or
|
|
6
|
+
appear after their message definitions.
|
|
7
|
+
- Decode subsequent developer-field values once their descriptions become
|
|
8
|
+
available, in both strict and force modes.
|
|
9
|
+
|
|
3
10
|
## 4.0.0
|
|
4
11
|
|
|
5
12
|
### FIT decoder performance
|
package/dist/binary.d.ts
CHANGED
|
@@ -7,8 +7,16 @@ export interface MessageTypeDefinition {
|
|
|
7
7
|
globalMessageNumber: number;
|
|
8
8
|
numberOfFields: number;
|
|
9
9
|
fieldDefs: FieldDefinition[];
|
|
10
|
+
developerFieldDefs?: DeveloperFieldDefinition[];
|
|
10
11
|
rawData?: any[];
|
|
11
12
|
}
|
|
13
|
+
export interface DeveloperFieldDefinition {
|
|
14
|
+
developerDataIndex: number;
|
|
15
|
+
fieldDefinitionNumber: number;
|
|
16
|
+
size: number;
|
|
17
|
+
resolvedFieldDef?: FieldDefinition;
|
|
18
|
+
resolvedFrom?: unknown;
|
|
19
|
+
}
|
|
12
20
|
export declare function addEndian(littleEndian: boolean, bytes: number[]): number;
|
|
13
21
|
export declare function readRecord(blob: Uint8Array, messageTypes: MessageTypeDefinition[], developerFields: any[], startIndex: number, options: FitParserOptions, startDate: number | undefined, pausedTime: number, dataView?: DataView): {
|
|
14
22
|
messageType: MesgNum | '';
|
package/dist/binary.js
CHANGED
|
@@ -319,8 +319,63 @@ function applyOptions(data, field, options, fields) {
|
|
|
319
319
|
return data;
|
|
320
320
|
}
|
|
321
321
|
}
|
|
322
|
+
function applyGarminProductName(fields) {
|
|
323
|
+
if (fields.product_name !== undefined || fields.manufacturer !== 'garmin') {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
const product = fields.product;
|
|
327
|
+
if (typeof product !== 'number') {
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const productName = FIT.types.garmin_product[product];
|
|
331
|
+
if (typeof productName === 'string') {
|
|
332
|
+
// Keep the raw protocol ID and expose the SDK product name separately.
|
|
333
|
+
fields.product_name = productName;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function resolveDeveloperFieldDefinition(developerFieldDef, littleEndian, developerFields, options) {
|
|
337
|
+
var _a, _b, _c, _d;
|
|
338
|
+
const description = (_a = developerFields[developerFieldDef.developerDataIndex]) === null || _a === void 0 ? void 0 : _a[developerFieldDef.fieldDefinitionNumber];
|
|
339
|
+
if (!description) {
|
|
340
|
+
developerFieldDef.resolvedFieldDef = undefined;
|
|
341
|
+
developerFieldDef.resolvedFrom = undefined;
|
|
342
|
+
return undefined;
|
|
343
|
+
}
|
|
344
|
+
if (developerFieldDef.resolvedFrom === description
|
|
345
|
+
&& developerFieldDef.resolvedFieldDef) {
|
|
346
|
+
return developerFieldDef.resolvedFieldDef;
|
|
347
|
+
}
|
|
348
|
+
const baseType = description.fit_base_type_id;
|
|
349
|
+
const type = FIT.types.fit_base_type[baseType];
|
|
350
|
+
if (typeof baseType !== 'number' || type === undefined) {
|
|
351
|
+
developerFieldDef.resolvedFieldDef = undefined;
|
|
352
|
+
developerFieldDef.resolvedFrom = undefined;
|
|
353
|
+
if (options.force) {
|
|
354
|
+
return undefined;
|
|
355
|
+
}
|
|
356
|
+
throw new Error(`Unsupported base type for developer data index ${developerFieldDef.developerDataIndex}, field ${developerFieldDef.fieldDefinitionNumber}`);
|
|
357
|
+
}
|
|
358
|
+
const resolvedFieldDef = {
|
|
359
|
+
type,
|
|
360
|
+
fDefNo: developerFieldDef.fieldDefinitionNumber,
|
|
361
|
+
size: developerFieldDef.size,
|
|
362
|
+
endianAbility: (baseType & 128) === 128,
|
|
363
|
+
littleEndian,
|
|
364
|
+
baseTypeNo: baseType,
|
|
365
|
+
name: (_b = description.field_name) !== null && _b !== void 0 ? _b : '',
|
|
366
|
+
dataType: getFitMessageBaseType(baseType & 15),
|
|
367
|
+
scale: (_c = description.scale) !== null && _c !== void 0 ? _c : 1,
|
|
368
|
+
offset: (_d = description.offset) !== null && _d !== void 0 ? _d : 0,
|
|
369
|
+
requiresBoundedDataView: requiresBoundedEndianDataView(type, developerFieldDef.size),
|
|
370
|
+
developerDataIndex: developerFieldDef.developerDataIndex,
|
|
371
|
+
isDeveloperField: true,
|
|
372
|
+
};
|
|
373
|
+
developerFieldDef.resolvedFieldDef = resolvedFieldDef;
|
|
374
|
+
developerFieldDef.resolvedFrom = description;
|
|
375
|
+
return resolvedFieldDef;
|
|
376
|
+
}
|
|
322
377
|
export function readRecord(blob, messageTypes, developerFields, startIndex, options, startDate, pausedTime, dataView = new DataView(blob.buffer, blob.byteOffset, blob.byteLength)) {
|
|
323
|
-
var _a, _b, _c, _d, _e;
|
|
378
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
324
379
|
const recordHeader = blob[startIndex];
|
|
325
380
|
let localMessageType = recordHeader & 15;
|
|
326
381
|
if ((recordHeader & CompressedHeaderMask) === CompressedHeaderMask) {
|
|
@@ -344,6 +399,7 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
344
399
|
]),
|
|
345
400
|
numberOfFields: numberOfFields + numberOfDeveloperDataFields,
|
|
346
401
|
fieldDefs: [],
|
|
402
|
+
developerFieldDefs: [],
|
|
347
403
|
rawData: [],
|
|
348
404
|
};
|
|
349
405
|
const message = getFitMessage(mTypeDef.globalMessageNumber);
|
|
@@ -366,41 +422,15 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
366
422
|
};
|
|
367
423
|
mTypeDef.fieldDefs.push(fDef);
|
|
368
424
|
}
|
|
369
|
-
// numberOfDeveloperDataFields = 0 so it wont crash here and wont loop
|
|
370
425
|
for (let i = 0; i < numberOfDeveloperDataFields; i++) {
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
const devDef = developerFields[devDataIndex][fieldNum];
|
|
378
|
-
const baseType = devDef.fit_base_type_id;
|
|
379
|
-
const fDef = {
|
|
380
|
-
type: FIT.types.fit_base_type[baseType],
|
|
381
|
-
fDefNo: fieldNum,
|
|
382
|
-
size,
|
|
383
|
-
endianAbility: (baseType & 128) === 128,
|
|
384
|
-
littleEndian: lEnd,
|
|
385
|
-
baseTypeNo: baseType,
|
|
386
|
-
name: devDef.field_name,
|
|
387
|
-
dataType: getFitMessageBaseType(baseType & 15),
|
|
388
|
-
scale: devDef.scale || 1,
|
|
389
|
-
offset: devDef.offset || 0,
|
|
390
|
-
requiresBoundedDataView: requiresBoundedEndianDataView(FIT.types.fit_base_type[baseType], size),
|
|
391
|
-
developerDataIndex: devDataIndex,
|
|
392
|
-
isDeveloperField: true,
|
|
393
|
-
};
|
|
394
|
-
mTypeDef.fieldDefs.push(fDef);
|
|
395
|
-
}
|
|
396
|
-
catch (e) {
|
|
397
|
-
if (options.force) {
|
|
398
|
-
continue;
|
|
399
|
-
}
|
|
400
|
-
throw e;
|
|
401
|
-
}
|
|
426
|
+
const fDefIndex = startIndex + 6 + numberOfFields * 3 + 1 + i * 3;
|
|
427
|
+
(_a = mTypeDef.developerFieldDefs) === null || _a === void 0 ? void 0 : _a.push({
|
|
428
|
+
fieldDefinitionNumber: blob[fDefIndex],
|
|
429
|
+
size: blob[fDefIndex + 1],
|
|
430
|
+
developerDataIndex: blob[fDefIndex + 2],
|
|
431
|
+
});
|
|
402
432
|
}
|
|
403
|
-
mTypeDef.rawData = Array.from({ length: mTypeDef.
|
|
433
|
+
mTypeDef.rawData = Array.from({ length: mTypeDef.numberOfFields }, () => InvalidFieldData);
|
|
404
434
|
messageTypes[localMessageType] = mTypeDef;
|
|
405
435
|
const nextIndex = startIndex + 6 + mTypeDef.numberOfFields * 3;
|
|
406
436
|
const nextIndexWithDeveloperData = nextIndex + 1;
|
|
@@ -416,7 +446,9 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
416
446
|
let readDataFromIndex = startIndex + 1;
|
|
417
447
|
const fields = {};
|
|
418
448
|
const message = getFitMessage(messageType.globalMessageNumber);
|
|
419
|
-
const
|
|
449
|
+
const developerFieldDefs = (_b = messageType.developerFieldDefs) !== null && _b !== void 0 ? _b : [];
|
|
450
|
+
const totalFieldCount = messageType.fieldDefs.length + developerFieldDefs.length;
|
|
451
|
+
const rawData = (_c = messageType.rawData) !== null && _c !== void 0 ? _c : (messageType.rawData = Array.from({ length: totalFieldCount }, () => InvalidFieldData));
|
|
420
452
|
let validFieldCount = 0;
|
|
421
453
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
422
454
|
const fDef = messageType.fieldDefs[i];
|
|
@@ -431,6 +463,26 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
431
463
|
readDataFromIndex += fDef.size;
|
|
432
464
|
messageSize += fDef.size;
|
|
433
465
|
}
|
|
466
|
+
for (let i = 0; i < developerFieldDefs.length; i++) {
|
|
467
|
+
const developerFieldDef = developerFieldDefs[i];
|
|
468
|
+
const rawDataIndex = messageType.fieldDefs.length + i;
|
|
469
|
+
const fDef = resolveDeveloperFieldDefinition(developerFieldDef, messageType.littleEndian, developerFields, options);
|
|
470
|
+
if (fDef) {
|
|
471
|
+
const data = readData(blob, dataView, fDef, readDataFromIndex, options);
|
|
472
|
+
if (!isInvalidValue(data, fDef.type) && !isInvalidBaseTypeValue(data, fDef.baseTypeNo)) {
|
|
473
|
+
rawData[rawDataIndex] = data;
|
|
474
|
+
validFieldCount++;
|
|
475
|
+
}
|
|
476
|
+
else {
|
|
477
|
+
rawData[rawDataIndex] = InvalidFieldData;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
rawData[rawDataIndex] = InvalidFieldData;
|
|
482
|
+
}
|
|
483
|
+
readDataFromIndex += developerFieldDef.size;
|
|
484
|
+
messageSize += developerFieldDef.size;
|
|
485
|
+
}
|
|
434
486
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
435
487
|
const data = rawData[i];
|
|
436
488
|
if (data === InvalidFieldData) {
|
|
@@ -442,6 +494,17 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
442
494
|
fields[field] = data;
|
|
443
495
|
}
|
|
444
496
|
}
|
|
497
|
+
for (let i = 0; i < developerFieldDefs.length; i++) {
|
|
498
|
+
const data = rawData[messageType.fieldDefs.length + i];
|
|
499
|
+
const fDef = developerFieldDefs[i].resolvedFieldDef;
|
|
500
|
+
if (data === InvalidFieldData || !fDef) {
|
|
501
|
+
continue;
|
|
502
|
+
}
|
|
503
|
+
const field = fDef.name;
|
|
504
|
+
if (field !== 'unknown' && field !== '') {
|
|
505
|
+
fields[field] = data;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
445
508
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
446
509
|
const data = rawData[i];
|
|
447
510
|
if (data === InvalidFieldData) {
|
|
@@ -451,19 +514,31 @@ export function readRecord(blob, messageTypes, developerFields, startIndex, opti
|
|
|
451
514
|
if (fDef.isDeveloperField) {
|
|
452
515
|
const field = fDef.name;
|
|
453
516
|
const { type } = fDef;
|
|
454
|
-
const scale = (
|
|
455
|
-
const offset = (
|
|
517
|
+
const scale = (_d = fDef.scale) !== null && _d !== void 0 ? _d : null;
|
|
518
|
+
const offset = (_e = fDef.offset) !== null && _e !== void 0 ? _e : 0;
|
|
456
519
|
fields[fDef.name] = applyOptions(formatByType(data, type, scale, offset), field, options, fields);
|
|
457
520
|
}
|
|
458
521
|
else {
|
|
459
522
|
const { name: field, type } = fDef;
|
|
460
|
-
const scale = (
|
|
461
|
-
const offset = (
|
|
523
|
+
const scale = (_f = fDef.scale) !== null && _f !== void 0 ? _f : null;
|
|
524
|
+
const offset = (_g = fDef.offset) !== null && _g !== void 0 ? _g : 0;
|
|
462
525
|
if (field !== 'unknown' && field !== '' && field !== undefined) {
|
|
463
526
|
fields[field] = applyOptions(formatByType(data, type, scale, offset), field, options, fields);
|
|
464
527
|
}
|
|
465
528
|
}
|
|
466
529
|
}
|
|
530
|
+
for (let i = 0; i < developerFieldDefs.length; i++) {
|
|
531
|
+
const data = rawData[messageType.fieldDefs.length + i];
|
|
532
|
+
const fDef = developerFieldDefs[i].resolvedFieldDef;
|
|
533
|
+
if (data === InvalidFieldData || !fDef) {
|
|
534
|
+
continue;
|
|
535
|
+
}
|
|
536
|
+
const field = fDef.name;
|
|
537
|
+
if (field !== 'unknown' && field !== '') {
|
|
538
|
+
fields[field] = applyOptions(formatByType(data, fDef.type, (_h = fDef.scale) !== null && _h !== void 0 ? _h : null, (_j = fDef.offset) !== null && _j !== void 0 ? _j : 0), field, options, fields);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
applyGarminProductName(fields);
|
|
467
542
|
if (validFieldCount > 0 && message.name === 'record' && options.elapsedRecordField) {
|
|
468
543
|
fields.elapsed_time = (fields.timestamp - (startDate || 0)) / 1000;
|
|
469
544
|
fields.timer_time = fields.elapsed_time - pausedTime;
|
package/dist/cjs/binary.d.ts
CHANGED
|
@@ -7,8 +7,16 @@ export interface MessageTypeDefinition {
|
|
|
7
7
|
globalMessageNumber: number;
|
|
8
8
|
numberOfFields: number;
|
|
9
9
|
fieldDefs: FieldDefinition[];
|
|
10
|
+
developerFieldDefs?: DeveloperFieldDefinition[];
|
|
10
11
|
rawData?: any[];
|
|
11
12
|
}
|
|
13
|
+
export interface DeveloperFieldDefinition {
|
|
14
|
+
developerDataIndex: number;
|
|
15
|
+
fieldDefinitionNumber: number;
|
|
16
|
+
size: number;
|
|
17
|
+
resolvedFieldDef?: FieldDefinition;
|
|
18
|
+
resolvedFrom?: unknown;
|
|
19
|
+
}
|
|
12
20
|
export declare function addEndian(littleEndian: boolean, bytes: number[]): number;
|
|
13
21
|
export declare function readRecord(blob: Uint8Array, messageTypes: MessageTypeDefinition[], developerFields: any[], startIndex: number, options: FitParserOptions, startDate: number | undefined, pausedTime: number, dataView?: DataView): {
|
|
14
22
|
messageType: MesgNum | '';
|
package/dist/cjs/binary.js
CHANGED
|
@@ -325,8 +325,63 @@ function applyOptions(data, field, options, fields) {
|
|
|
325
325
|
return data;
|
|
326
326
|
}
|
|
327
327
|
}
|
|
328
|
+
function applyGarminProductName(fields) {
|
|
329
|
+
if (fields.product_name !== undefined || fields.manufacturer !== 'garmin') {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const product = fields.product;
|
|
333
|
+
if (typeof product !== 'number') {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
const productName = fit_js_1.FIT.types.garmin_product[product];
|
|
337
|
+
if (typeof productName === 'string') {
|
|
338
|
+
// Keep the raw protocol ID and expose the SDK product name separately.
|
|
339
|
+
fields.product_name = productName;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function resolveDeveloperFieldDefinition(developerFieldDef, littleEndian, developerFields, options) {
|
|
343
|
+
var _a, _b, _c, _d;
|
|
344
|
+
const description = (_a = developerFields[developerFieldDef.developerDataIndex]) === null || _a === void 0 ? void 0 : _a[developerFieldDef.fieldDefinitionNumber];
|
|
345
|
+
if (!description) {
|
|
346
|
+
developerFieldDef.resolvedFieldDef = undefined;
|
|
347
|
+
developerFieldDef.resolvedFrom = undefined;
|
|
348
|
+
return undefined;
|
|
349
|
+
}
|
|
350
|
+
if (developerFieldDef.resolvedFrom === description
|
|
351
|
+
&& developerFieldDef.resolvedFieldDef) {
|
|
352
|
+
return developerFieldDef.resolvedFieldDef;
|
|
353
|
+
}
|
|
354
|
+
const baseType = description.fit_base_type_id;
|
|
355
|
+
const type = fit_js_1.FIT.types.fit_base_type[baseType];
|
|
356
|
+
if (typeof baseType !== 'number' || type === undefined) {
|
|
357
|
+
developerFieldDef.resolvedFieldDef = undefined;
|
|
358
|
+
developerFieldDef.resolvedFrom = undefined;
|
|
359
|
+
if (options.force) {
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
throw new Error(`Unsupported base type for developer data index ${developerFieldDef.developerDataIndex}, field ${developerFieldDef.fieldDefinitionNumber}`);
|
|
363
|
+
}
|
|
364
|
+
const resolvedFieldDef = {
|
|
365
|
+
type,
|
|
366
|
+
fDefNo: developerFieldDef.fieldDefinitionNumber,
|
|
367
|
+
size: developerFieldDef.size,
|
|
368
|
+
endianAbility: (baseType & 128) === 128,
|
|
369
|
+
littleEndian,
|
|
370
|
+
baseTypeNo: baseType,
|
|
371
|
+
name: (_b = description.field_name) !== null && _b !== void 0 ? _b : '',
|
|
372
|
+
dataType: (0, messages_js_1.getFitMessageBaseType)(baseType & 15),
|
|
373
|
+
scale: (_c = description.scale) !== null && _c !== void 0 ? _c : 1,
|
|
374
|
+
offset: (_d = description.offset) !== null && _d !== void 0 ? _d : 0,
|
|
375
|
+
requiresBoundedDataView: requiresBoundedEndianDataView(type, developerFieldDef.size),
|
|
376
|
+
developerDataIndex: developerFieldDef.developerDataIndex,
|
|
377
|
+
isDeveloperField: true,
|
|
378
|
+
};
|
|
379
|
+
developerFieldDef.resolvedFieldDef = resolvedFieldDef;
|
|
380
|
+
developerFieldDef.resolvedFrom = description;
|
|
381
|
+
return resolvedFieldDef;
|
|
382
|
+
}
|
|
328
383
|
function readRecord(blob, messageTypes, developerFields, startIndex, options, startDate, pausedTime, dataView = new DataView(blob.buffer, blob.byteOffset, blob.byteLength)) {
|
|
329
|
-
var _a, _b, _c, _d, _e;
|
|
384
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
330
385
|
const recordHeader = blob[startIndex];
|
|
331
386
|
let localMessageType = recordHeader & 15;
|
|
332
387
|
if ((recordHeader & CompressedHeaderMask) === CompressedHeaderMask) {
|
|
@@ -350,6 +405,7 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
350
405
|
]),
|
|
351
406
|
numberOfFields: numberOfFields + numberOfDeveloperDataFields,
|
|
352
407
|
fieldDefs: [],
|
|
408
|
+
developerFieldDefs: [],
|
|
353
409
|
rawData: [],
|
|
354
410
|
};
|
|
355
411
|
const message = (0, messages_js_1.getFitMessage)(mTypeDef.globalMessageNumber);
|
|
@@ -372,41 +428,15 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
372
428
|
};
|
|
373
429
|
mTypeDef.fieldDefs.push(fDef);
|
|
374
430
|
}
|
|
375
|
-
// numberOfDeveloperDataFields = 0 so it wont crash here and wont loop
|
|
376
431
|
for (let i = 0; i < numberOfDeveloperDataFields; i++) {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
const devDef = developerFields[devDataIndex][fieldNum];
|
|
384
|
-
const baseType = devDef.fit_base_type_id;
|
|
385
|
-
const fDef = {
|
|
386
|
-
type: fit_js_1.FIT.types.fit_base_type[baseType],
|
|
387
|
-
fDefNo: fieldNum,
|
|
388
|
-
size,
|
|
389
|
-
endianAbility: (baseType & 128) === 128,
|
|
390
|
-
littleEndian: lEnd,
|
|
391
|
-
baseTypeNo: baseType,
|
|
392
|
-
name: devDef.field_name,
|
|
393
|
-
dataType: (0, messages_js_1.getFitMessageBaseType)(baseType & 15),
|
|
394
|
-
scale: devDef.scale || 1,
|
|
395
|
-
offset: devDef.offset || 0,
|
|
396
|
-
requiresBoundedDataView: requiresBoundedEndianDataView(fit_js_1.FIT.types.fit_base_type[baseType], size),
|
|
397
|
-
developerDataIndex: devDataIndex,
|
|
398
|
-
isDeveloperField: true,
|
|
399
|
-
};
|
|
400
|
-
mTypeDef.fieldDefs.push(fDef);
|
|
401
|
-
}
|
|
402
|
-
catch (e) {
|
|
403
|
-
if (options.force) {
|
|
404
|
-
continue;
|
|
405
|
-
}
|
|
406
|
-
throw e;
|
|
407
|
-
}
|
|
432
|
+
const fDefIndex = startIndex + 6 + numberOfFields * 3 + 1 + i * 3;
|
|
433
|
+
(_a = mTypeDef.developerFieldDefs) === null || _a === void 0 ? void 0 : _a.push({
|
|
434
|
+
fieldDefinitionNumber: blob[fDefIndex],
|
|
435
|
+
size: blob[fDefIndex + 1],
|
|
436
|
+
developerDataIndex: blob[fDefIndex + 2],
|
|
437
|
+
});
|
|
408
438
|
}
|
|
409
|
-
mTypeDef.rawData = Array.from({ length: mTypeDef.
|
|
439
|
+
mTypeDef.rawData = Array.from({ length: mTypeDef.numberOfFields }, () => InvalidFieldData);
|
|
410
440
|
messageTypes[localMessageType] = mTypeDef;
|
|
411
441
|
const nextIndex = startIndex + 6 + mTypeDef.numberOfFields * 3;
|
|
412
442
|
const nextIndexWithDeveloperData = nextIndex + 1;
|
|
@@ -422,7 +452,9 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
422
452
|
let readDataFromIndex = startIndex + 1;
|
|
423
453
|
const fields = {};
|
|
424
454
|
const message = (0, messages_js_1.getFitMessage)(messageType.globalMessageNumber);
|
|
425
|
-
const
|
|
455
|
+
const developerFieldDefs = (_b = messageType.developerFieldDefs) !== null && _b !== void 0 ? _b : [];
|
|
456
|
+
const totalFieldCount = messageType.fieldDefs.length + developerFieldDefs.length;
|
|
457
|
+
const rawData = (_c = messageType.rawData) !== null && _c !== void 0 ? _c : (messageType.rawData = Array.from({ length: totalFieldCount }, () => InvalidFieldData));
|
|
426
458
|
let validFieldCount = 0;
|
|
427
459
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
428
460
|
const fDef = messageType.fieldDefs[i];
|
|
@@ -437,6 +469,26 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
437
469
|
readDataFromIndex += fDef.size;
|
|
438
470
|
messageSize += fDef.size;
|
|
439
471
|
}
|
|
472
|
+
for (let i = 0; i < developerFieldDefs.length; i++) {
|
|
473
|
+
const developerFieldDef = developerFieldDefs[i];
|
|
474
|
+
const rawDataIndex = messageType.fieldDefs.length + i;
|
|
475
|
+
const fDef = resolveDeveloperFieldDefinition(developerFieldDef, messageType.littleEndian, developerFields, options);
|
|
476
|
+
if (fDef) {
|
|
477
|
+
const data = readData(blob, dataView, fDef, readDataFromIndex, options);
|
|
478
|
+
if (!isInvalidValue(data, fDef.type) && !isInvalidBaseTypeValue(data, fDef.baseTypeNo)) {
|
|
479
|
+
rawData[rawDataIndex] = data;
|
|
480
|
+
validFieldCount++;
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
rawData[rawDataIndex] = InvalidFieldData;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
rawData[rawDataIndex] = InvalidFieldData;
|
|
488
|
+
}
|
|
489
|
+
readDataFromIndex += developerFieldDef.size;
|
|
490
|
+
messageSize += developerFieldDef.size;
|
|
491
|
+
}
|
|
440
492
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
441
493
|
const data = rawData[i];
|
|
442
494
|
if (data === InvalidFieldData) {
|
|
@@ -448,6 +500,17 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
448
500
|
fields[field] = data;
|
|
449
501
|
}
|
|
450
502
|
}
|
|
503
|
+
for (let i = 0; i < developerFieldDefs.length; i++) {
|
|
504
|
+
const data = rawData[messageType.fieldDefs.length + i];
|
|
505
|
+
const fDef = developerFieldDefs[i].resolvedFieldDef;
|
|
506
|
+
if (data === InvalidFieldData || !fDef) {
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
const field = fDef.name;
|
|
510
|
+
if (field !== 'unknown' && field !== '') {
|
|
511
|
+
fields[field] = data;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
451
514
|
for (let i = 0; i < messageType.fieldDefs.length; i++) {
|
|
452
515
|
const data = rawData[i];
|
|
453
516
|
if (data === InvalidFieldData) {
|
|
@@ -457,19 +520,31 @@ function readRecord(blob, messageTypes, developerFields, startIndex, options, st
|
|
|
457
520
|
if (fDef.isDeveloperField) {
|
|
458
521
|
const field = fDef.name;
|
|
459
522
|
const { type } = fDef;
|
|
460
|
-
const scale = (
|
|
461
|
-
const offset = (
|
|
523
|
+
const scale = (_d = fDef.scale) !== null && _d !== void 0 ? _d : null;
|
|
524
|
+
const offset = (_e = fDef.offset) !== null && _e !== void 0 ? _e : 0;
|
|
462
525
|
fields[fDef.name] = applyOptions(formatByType(data, type, scale, offset), field, options, fields);
|
|
463
526
|
}
|
|
464
527
|
else {
|
|
465
528
|
const { name: field, type } = fDef;
|
|
466
|
-
const scale = (
|
|
467
|
-
const offset = (
|
|
529
|
+
const scale = (_f = fDef.scale) !== null && _f !== void 0 ? _f : null;
|
|
530
|
+
const offset = (_g = fDef.offset) !== null && _g !== void 0 ? _g : 0;
|
|
468
531
|
if (field !== 'unknown' && field !== '' && field !== undefined) {
|
|
469
532
|
fields[field] = applyOptions(formatByType(data, type, scale, offset), field, options, fields);
|
|
470
533
|
}
|
|
471
534
|
}
|
|
472
535
|
}
|
|
536
|
+
for (let i = 0; i < developerFieldDefs.length; i++) {
|
|
537
|
+
const data = rawData[messageType.fieldDefs.length + i];
|
|
538
|
+
const fDef = developerFieldDefs[i].resolvedFieldDef;
|
|
539
|
+
if (data === InvalidFieldData || !fDef) {
|
|
540
|
+
continue;
|
|
541
|
+
}
|
|
542
|
+
const field = fDef.name;
|
|
543
|
+
if (field !== 'unknown' && field !== '') {
|
|
544
|
+
fields[field] = applyOptions(formatByType(data, fDef.type, (_h = fDef.scale) !== null && _h !== void 0 ? _h : null, (_j = fDef.offset) !== null && _j !== void 0 ? _j : 0), field, options, fields);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
applyGarminProductName(fields);
|
|
473
548
|
if (validFieldCount > 0 && message.name === 'record' && options.elapsedRecordField) {
|
|
474
549
|
fields.elapsed_time = (fields.timestamp - (startDate || 0)) / 1000;
|
|
475
550
|
fields.timer_time = fields.elapsed_time - pausedTime;
|