Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
586 changes: 298 additions & 288 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@garmin/fitsdk",
"version": "21.188.0",
"version": "21.194.0",
"description": "FIT JavaScript SDK",
"main": "src/index.js",
"type": "module",
Expand Down
6 changes: 3 additions & 3 deletions src/accumulator.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down
6 changes: 3 additions & 3 deletions src/bit-stream.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down
6 changes: 3 additions & 3 deletions src/crc-calculator.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down
6 changes: 3 additions & 3 deletions src/decoder.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down
35 changes: 30 additions & 5 deletions src/encoder.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down Expand Up @@ -212,12 +212,25 @@ class Encoder {
throw new Error();
}

// Convert valid numeric strings to the correct type
if (FIT.isString(value)) {
value = FIT.BigIntFieldTypes.includes(fieldDefinition.type)
? BigInt(value)
: Number(value);
}

const hasScaleOrOffset = (fieldDefinition.scale != FIT.FIELD_DEFAULT_SCALE || fieldDefinition.offset != FIT.FIELD_DEFAULT_OFFSET);

if (!hasScaleOrOffset && !this.#isValidType(value, fieldDefinition.type)) {
throw new Error();
}

if (hasScaleOrOffset) {
const scaledValue = (value + fieldDefinition.offset) * fieldDefinition.scale;
const scaledValue = this.#unapplyScaleAndOffset(value, fieldDefinition.scale, fieldDefinition.offset);

const roundedValue = FIT.FloatingPointFieldTypes.includes(fieldDefinition.type) || FIT.isBigInt(scaledValue) ? scaledValue : Math.round(scaledValue);

return FIT.FloatingPointFieldTypes.includes(fieldDefinition.type) ? scaledValue : Math.round(scaledValue);
return FIT.BigIntFieldTypes.includes(fieldDefinition.type) ? BigInt(roundedValue) : Number(roundedValue);
}

return value;
Expand Down Expand Up @@ -265,6 +278,18 @@ class Encoder {
}
}

#isValidType = (value, type) => {
const jsType = FIT.FieldTypeToJsType[type];

return typeof value === jsType
}

#unapplyScaleAndOffset(value, scale, offset) {
return FIT.isBigInt(value)
? (value + BigInt(offset)) * BigInt(scale)
: (value + offset) * scale;
}

/**
* Creates a MesgDefinition from the mesgNum and mesg.
* @param {Number} mesgNum - The mesg number for this message
Expand Down
52 changes: 47 additions & 5 deletions src/fit.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down Expand Up @@ -73,6 +73,32 @@ const NumericFieldTypes = [
"uint64z"
];

const FieldTypeToJsType = {
"enum": "number",
"sint8": "number",
"uint8": "number",
"sint16": "number",
"uint16": "number",
"sint32": "number",
"uint32": "number",
"string": "string",
"float32": "number",
"float64": "number",
"uint8z": "number",
"uint16z": "number",
"uint32z": "number",
"byte": "number",
"sint64": "bigint",
"uint64": "bigint",
"uint64z": "bigint"
}

const BigIntFieldTypes = [
"sint64",
"uint64",
"uint64z"
];

const FloatingPointFieldTypes = [
"float32",
"float64",
Expand Down Expand Up @@ -138,8 +164,21 @@ const isString = (obj) => {
return typeof obj === "string";
};

const isBigInt = (obj) => {
return typeof obj === "bigint";
};

const isNumeric = (obj) => {
return !isNaN(parseFloat(obj)) && isFinite(obj);
if (typeof obj === "number") {
return !isNaN(obj) && isFinite(obj);
}

if (typeof obj === "bigint") {
return true;
}

const num = parseFloat(obj);
return !isNaN(num) && isFinite(num);
};

const isNotNumberStringDateOrBoolean = (obj) => {
Expand All @@ -151,7 +190,7 @@ const isNumberStringDateOrBoolean = (obj) => {
return false;
}

if (!isDate(obj) && !isString(obj) && !isNumeric(obj) && !isBoolean(obj)) {
if (!isNumeric(obj) && !isDate(obj) && !isString(obj) && !isBoolean(obj)) {
return false;
}

Expand All @@ -163,14 +202,17 @@ export default {
BaseTypeMask,
BaseTypeDefinitions,
NumericFieldTypes,
BigIntFieldTypes,
FloatingPointFieldTypes,
FieldTypeToBaseType,
BaseTypeToFieldType,
FieldTypeToJsType,
isNullOrUndefined,
isObject,
isBoolean,
isDate,
isString,
isBigInt,
isNumeric,
isNumberStringDateOrBoolean,
isNotNumberStringDateOrBoolean,
Expand Down
6 changes: 3 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down
10 changes: 7 additions & 3 deletions src/mesg-definition.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


Expand Down Expand Up @@ -86,6 +86,10 @@ class MesgDefinition {
fieldDefinitionNumber: fieldDescriptionMesg.fieldDefinitionNumber,
size: this.#fieldSize(mesg.developerFields[key], baseTypeDef),
developerDataIndex: developerDataIdMesg.developerDataIndex,
type: FIT.BaseTypeToFieldType[baseTypeDef.type],
scale: 1,
offset: 0,
components: [],
});
});

Expand Down
19 changes: 11 additions & 8 deletions src/output-stream.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


import FIT from "./fit.js";

const ONE_MEGABYTE = 1048576;
const TEN_MEGABYTES = ONE_MEGABYTE * 10;
const FIVE_HUNDRED_MEGABYTES = ONE_MEGABYTE * 500;
const HALF_MEGABYTE = ONE_MEGABYTE / 2;
const MAX_BYTE_LENGTH = FIVE_HUNDRED_MEGABYTES;

class OutputStream {
#arrayBuffer = null;
Expand All @@ -29,12 +30,12 @@ class OutputStream {
* @constructor
* @param {Object=} [options] - Read options (optional)
* @param {Number} [options.initialByteLength=0.5MB] - (optional, default 0.5 MB)
* @param {Number} [options.maxByteLength=2MB] - (optional, default 2 MB)
* @param {Number} [options.maxByteLength=500MB] - (optional, default 500 MB)
* @param {Number} [options.resizeByBytes=0.5MB] - (optional, default 0.5 MB)
*/
constructor({
initialByteLength = HALF_MEGABYTE,
maxByteLength = TEN_MEGABYTES,
maxByteLength = MAX_BYTE_LENGTH,
resizeByBytes = HALF_MEGABYTE,
} = {}) {
this.#arrayBuffer = new ArrayBuffer(initialByteLength, { maxByteLength, });
Expand Down Expand Up @@ -209,11 +210,13 @@ class OutputStream {
return;
}

if (!this.#arrayBuffer.resizable) {
const newByteLength = this.#arrayBuffer.byteLength + Math.max(this.#resizeByBytes, byteCount);

if (newByteLength > this.#arrayBuffer.maxByteLength) {
throw new Error("Can not resize OutputStream. Set a larger initial size.");
}

this.#arrayBuffer.resize(this.#arrayBuffer.byteLength + Math.max(this.#resizeByBytes, byteCount));
this.#arrayBuffer.resize(newByteLength);
}
}

Expand Down
28 changes: 24 additions & 4 deletions src/profile.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
/////////////////////////////////////////////////////////////////////////////////////////////
// Copyright 2025 Garmin International, Inc.
// Copyright 2026 Garmin International, Inc.
// Licensed under the Flexible and Interoperable Data Transfer (FIT) Protocol License; you
// may not use this file except in compliance with the Flexible and Interoperable Data
// Transfer (FIT) Protocol License.
/////////////////////////////////////////////////////////////////////////////////////////////
// ****WARNING**** This file is auto-generated! Do NOT edit this file.
// Profile Version = 21.188.0Release
// Tag = production/release/21.188.0-0-g55050f8
// Profile Version = 21.194.0Release
// Tag = production/release/21.194.0-0-g65135fc
/////////////////////////////////////////////////////////////////////////////////////////////


const Profile = {
version: {
major: 21,
minor: 188,
minor: 194,
patch: 0,
type: "Release"
},
Expand Down Expand Up @@ -7042,6 +7042,21 @@ const Profile = {
hasComponents: false,
subFields: []
},
196: {
num: 196,
name: "metabolicCalories",
type: "uint16",
baseType: "uint16",
array: false,
scale: 1,
offset: 0,
units: "kcal",
bits: [],
components: [],
isAccumulated: false,
hasComponents: false,
subFields: []
},
197: {
num: 197, // Standard deviation of R-R interval (SDRR) - Heart rate variability measure most useful for wellness users.
name: "sdrrHrv",
Expand Down Expand Up @@ -24363,6 +24378,10 @@ types: {
334: "daradInnovationCorporation",
335: "cycloptim",
337: "runna",
339: "zepp",
340: "peloton",
341: "carv",
342: "tissot",
5759: "actigraphcorp",
},
garminProduct: {
Expand Down Expand Up @@ -24825,6 +24844,7 @@ types: {
4759: "instinct3Solar50mm",
4775: "tactix8Amoled",
4776: "tactix8Solar",
4825: "approachJ1",
4879: "d2Mach2",
4678: "instinctCrossoverAmoled",
4944: "d2AirX15",
Expand Down
Loading