fit-file-parser 2.0.2 → 2.0.4

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/.editorconfig ADDED
@@ -0,0 +1,3 @@
1
+ [*]
2
+ indent_style = space
3
+ indent_size = 2
@@ -20,10 +20,21 @@ jobs:
20
20
  uses: actions/setup-node@v6
21
21
  with:
22
22
  node-version: ${{ matrix.node-version }}
23
+ cache: npm
24
+ cache-dependency-path: package-lock.json
23
25
  - run: npm ci
24
26
  - run: npm run build
25
- - run: npm run test
27
+ - run: npm run test -- --coverage
26
28
  - run: npm run lint
27
29
  if: matrix.node-version == '25.x'
28
30
  - run: npm run type-check
29
31
  if: matrix.node-version == '25.x'
32
+ - run: |
33
+ npm run codegen
34
+ if git diff --exit-code src/fit_types.ts; then
35
+ echo "✓ src/fit_types.ts is unchanged after codegen"
36
+ else
37
+ echo "✗ src/fit_types.ts has been modified - please commit the changes"
38
+ exit 1
39
+ fi
40
+ if: matrix.node-version == '25.x'
package/README.md CHANGED
@@ -57,6 +57,49 @@ const buffer = await fs.readFile('./example.fit')
57
57
  const fitObject = await fitParser.parseAsync(buffer)
58
58
  ```
59
59
 
60
+ ## Development
61
+
62
+ To build the project, run:
63
+
64
+ ```
65
+ npm run build
66
+ ```
67
+ To run tests, run:
68
+
69
+ ```
70
+ npm test
71
+ ```
72
+
73
+ To rebuild the typescript types (as they are autogenerated from the `FIT` object) run:
74
+
75
+ ```npm run codegen
76
+ ```
77
+
78
+ > this will update the file `src/fit_types.ts` as it is only running with node (with type stripping), regenerating them requires node>=245
79
+
80
+ To run the codegen in watch mode during local development, run:
81
+
82
+ ```npm run dev
83
+ ```
84
+
85
+ To build the local examples, run:
86
+
87
+ ```
88
+ npm run examples
89
+ ```
90
+
91
+ To lint and format the code, run:
92
+
93
+ ```
94
+ npm run lint
95
+ ```
96
+
97
+ To run the typechecker, run:
98
+
99
+ ```
100
+ npm run type-check
101
+ ```
102
+
60
103
  ## API Documentation
61
104
 
62
105
  ### new FitParser(Object _options_)
@@ -0,0 +1,9 @@
1
+ import { execSync } from 'node:child_process'
2
+ import fs from 'node:fs'
3
+ import { main } from '../src/type_generator.js'
4
+
5
+ const out = main()
6
+
7
+ fs.writeFileSync(`${import.meta.dirname}/../src/fit_types.ts`, out)
8
+
9
+ execSync('npx eslint --fix src/fit_types.ts', { stdio: 'inherit' })
package/dist/binary.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import type { FitParserOptions } from './fit-parser.js';
2
- import type { MessageName } from './fit.js';
2
+ import type { MesgNum } from './fit_types.js';
3
3
  import { Buffer } from 'node:buffer';
4
4
  export declare function addEndian(littleEndian: boolean, bytes: number[]): number;
5
5
  export declare function readRecord(blob: Uint8Array, messageTypes: any[], developerFields: any[], startIndex: number, options: FitParserOptions, startDate: number | undefined, pausedTime: number): {
6
- messageType: MessageName | '';
6
+ messageType: MesgNum | '';
7
7
  nextIndex: number;
8
8
  message?: any;
9
9
  };
@@ -1,5 +1,5 @@
1
1
  import type { Buffer } from 'node:buffer';
2
- import type { ParsedFit } from './types.js';
2
+ import type { ParsedFit } from './fit_types.js';
3
3
  export interface FitParserOptions {
4
4
  force?: boolean;
5
5
  speedUnit?: string;
@@ -85,7 +85,7 @@ export default class FitParser {
85
85
  const hr_zone = [];
86
86
  const power_zone = [];
87
87
  const hrv = [];
88
- const devices = [];
88
+ const device_infos = [];
89
89
  const applications = [];
90
90
  const fieldDescriptions = [];
91
91
  const dive_gases = [];
@@ -152,7 +152,7 @@ export default class FitParser {
152
152
  fieldDescriptions.push(message);
153
153
  break;
154
154
  case 'device_info':
155
- devices.push(message);
155
+ device_infos.push(message);
156
156
  break;
157
157
  case 'developer_data_id':
158
158
  applications.push(message);
@@ -201,16 +201,27 @@ export default class FitParser {
201
201
  break;
202
202
  }
203
203
  }
204
+ fitObj.hr_zone = hr_zone;
205
+ fitObj.power_zone = power_zone;
206
+ fitObj.dive_gases = dive_gases;
207
+ fitObj.course_points = course_points;
208
+ fitObj.sports = sports;
209
+ fitObj.monitors = monitors;
210
+ fitObj.stress = stress;
211
+ fitObj.file_ids = file_ids;
212
+ fitObj.monitor_info = monitor_info;
213
+ fitObj.definitions = definitions;
214
+ fitObj.tank_updates = tank_updates;
215
+ fitObj.tank_summaries = tank_summaries;
204
216
  if (isCascadeNeeded) {
205
217
  laps = mapDataIntoLap(laps, 'records', records);
206
218
  laps = mapDataIntoLap(laps, 'lengths', lengths);
207
219
  sessions = mapDataIntoSession(sessions, laps);
208
- fitObj.hr_zone = hr_zone;
209
- fitObj.power_zone = power_zone;
210
220
  fitObj.activity = Object.assign(Object.assign({}, ((_a = fitObj.activity) !== null && _a !== void 0 ? _a : {})), { // ugly but we assume the activity was parsed correctly with all other members correctly
211
221
  sessions,
212
222
  events,
213
- hrv, device_infos: devices, developer_data_ids: applications, field_descriptions: fieldDescriptions, sports });
223
+ hrv,
224
+ device_infos, developer_data_ids: applications, field_descriptions: fieldDescriptions, sports });
214
225
  }
215
226
  if (!isModeCascade) {
216
227
  fitObj.sessions = sessions;
@@ -218,23 +229,10 @@ export default class FitParser {
218
229
  fitObj.lengths = lengths;
219
230
  fitObj.records = records;
220
231
  fitObj.events = events;
221
- fitObj.device_infos = devices;
232
+ fitObj.device_infos = device_infos;
222
233
  fitObj.developer_data_ids = applications;
223
234
  fitObj.field_descriptions = fieldDescriptions;
224
235
  fitObj.hrv = hrv;
225
- fitObj.hr_zone = hr_zone;
226
- fitObj.power_zone = power_zone;
227
- fitObj.dive_gases = dive_gases;
228
- fitObj.course_points = course_points;
229
- fitObj.sports = sports;
230
- fitObj.devices = devices;
231
- fitObj.monitors = monitors;
232
- fitObj.stress = stress;
233
- fitObj.file_ids = file_ids;
234
- fitObj.monitor_info = monitor_info;
235
- fitObj.definitions = definitions;
236
- fitObj.tank_updates = tank_updates;
237
- fitObj.tank_summaries = tank_summaries;
238
236
  }
239
237
  callback(undefined, fitObj);
240
238
  }
package/dist/fit.d.ts CHANGED
@@ -1,12 +1,4 @@
1
- export type SpeedUnits = 'm/s' | 'mph' | 'km/h';
2
- export type LengthUnits = 'm' | 'mi' | 'km';
3
- export type TemperatureUnits = '°C' | 'kelvin' | 'fahrenheit';
4
- export type PressureUnits = 'cbar' | 'bar' | 'psi';
5
- export type MessageName = 'file_id' | 'file_creator' | 'timestamp_correlation' | 'o_hr_settings' | 'software' | 'slave_device' | 'capabilities' | 'file_capabilities' | 'mesg_capabilities' | 'field_capabilities' | 'device_settings' | 'user_profile' | 'hrm_profile' | 'sdm_profile' | 'bike_profile' | 'connectivity' | 'watchface_settings' | 'ohr_settings' | 'time_in_zone' | 'zones_target' | 'sport' | 'hr_zone' | 'speed_zone' | 'cadence_zone' | 'power_zone' | 'met_zone' | 'dive_settings' | 'dive_alarm' | 'dive_gas' | 'goal' | 'activity' | 'session' | 'lap' | 'length' | 'record' | 'event' | 'device_info' | 'device_aux_battery_info' | 'training_file' | 'weather_conditions' | 'weather_alert' | 'gps_metadata' | 'camera_event' | 'gyroscope_data' | 'accelerometer_data' | 'magnetometer_data' | 'barometer_data' | 'three_d_sensor_calibration' | 'one_d_sensor_calibration' | 'video_frame' | 'obdii_data' | 'nmea_sentence' | 'aviation_attitude' | 'video' | 'video_title' | 'video_description' | 'video_clip' | 'set' | 'jump' | 'course' | 'course_point' | 'segment_id' | 'segment_leaderboard_entry' | 'segment_point' | 'segment_lap' | 'segment_file' | 'workout' | 'workout_session' | 'workout_step' | 'exercise_title' | 'schedule' | 'totals' | 'weight_scale' | 'blood_pressure' | 'monitoring_info' | 'monitoring' | 'monitoring_hr_data' | 'hr' | 'memo_glob' | 'stress_level' | 'dive_summary' | 'hrv' | 'beat_intervals' | 'respiration_rate' | 'spo2_data' | 'sleep_level' | 'pad' | 'field_description' | 'developer_data_id' | 'definition' | 'tank_update' | 'tank_summary';
6
- export type Unit<T extends string> = Record<T, {
7
- multiplier: number;
8
- offset: number;
9
- }>;
1
+ import type { FitOptions, MesgNum } from './fit_types.js';
10
2
  export interface FieldDefinition {
11
3
  type: string | number;
12
4
  fDefNo: number;
@@ -28,19 +20,13 @@ export interface MessageObject {
28
20
  offset: number;
29
21
  units: string;
30
22
  }
31
- interface Message {
32
- name: MessageName;
23
+ export interface Message {
24
+ name: MesgNum;
33
25
  [fieldId: number]: MessageObject;
34
26
  }
35
- export interface FitTypeOptions {
36
- speedUnits: Unit<SpeedUnits>;
37
- lengthUnits: Unit<LengthUnits>;
38
- temperatureUnits: Unit<TemperatureUnits>;
39
- pressureUnits: Unit<PressureUnits>;
40
- }
41
27
  export interface FitType {
42
28
  scConst: number;
43
- options: FitTypeOptions;
29
+ options: FitOptions;
44
30
  messages: {
45
31
  [messageId: number]: Message;
46
32
  };
@@ -49,4 +35,3 @@ export interface FitType {
49
35
  };
50
36
  }
51
37
  export declare const FIT: FitType;
52
- export {};
package/dist/fit.js CHANGED
@@ -1,4 +1,3 @@
1
- // some unit conversion constants
2
1
  const metersInOneKilometer = 1000;
3
2
  const secondsInOneHour = 3600;
4
3
  // according to https://en.wikipedia.org/wiki/Mile