@flow-js/garmin-connect 1.6.3

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.
Files changed (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +627 -0
  3. package/dist/common/CFClient.d.ts +22 -0
  4. package/dist/common/CFClient.js +137 -0
  5. package/dist/common/CFClient.js.map +1 -0
  6. package/dist/common/DateUtils.d.ts +1 -0
  7. package/dist/common/DateUtils.js +11 -0
  8. package/dist/common/DateUtils.js.map +1 -0
  9. package/dist/common/HttpClient.d.ts +37 -0
  10. package/dist/common/HttpClient.js +496 -0
  11. package/dist/common/HttpClient.js.map +1 -0
  12. package/dist/garmin/GarminConnect.d.ts +112 -0
  13. package/dist/garmin/GarminConnect.js +816 -0
  14. package/dist/garmin/GarminConnect.js.map +1 -0
  15. package/dist/garmin/UrlClass.d.ts +53 -0
  16. package/dist/garmin/UrlClass.js +267 -0
  17. package/dist/garmin/UrlClass.js.map +1 -0
  18. package/dist/garmin/Urls.d.ts +56 -0
  19. package/dist/garmin/Urls.js +88 -0
  20. package/dist/garmin/Urls.js.map +1 -0
  21. package/dist/garmin/common/DateUtils.d.ts +6 -0
  22. package/dist/garmin/common/DateUtils.js +38 -0
  23. package/dist/garmin/common/DateUtils.js.map +1 -0
  24. package/dist/garmin/common/GpxUtils.d.ts +2 -0
  25. package/dist/garmin/common/GpxUtils.js +28 -0
  26. package/dist/garmin/common/GpxUtils.js.map +1 -0
  27. package/dist/garmin/common/HydrationUtils.d.ts +2 -0
  28. package/dist/garmin/common/HydrationUtils.js +16 -0
  29. package/dist/garmin/common/HydrationUtils.js.map +1 -0
  30. package/dist/garmin/common/WeightUtils.d.ts +1 -0
  31. package/dist/garmin/common/WeightUtils.js +9 -0
  32. package/dist/garmin/common/WeightUtils.js.map +1 -0
  33. package/dist/garmin/types/activity.d.ts +408 -0
  34. package/dist/garmin/types/activity.js +27 -0
  35. package/dist/garmin/types/activity.js.map +1 -0
  36. package/dist/garmin/types/gear.d.ts +20 -0
  37. package/dist/garmin/types/gear.js +3 -0
  38. package/dist/garmin/types/gear.js.map +1 -0
  39. package/dist/garmin/types/golf.d.ts +67 -0
  40. package/dist/garmin/types/golf.js +3 -0
  41. package/dist/garmin/types/golf.js.map +1 -0
  42. package/dist/garmin/types/gpx.d.ts +171 -0
  43. package/dist/garmin/types/gpx.js +15 -0
  44. package/dist/garmin/types/gpx.js.map +1 -0
  45. package/dist/garmin/types/heartrate.d.ts +22 -0
  46. package/dist/garmin/types/heartrate.js +2 -0
  47. package/dist/garmin/types/heartrate.js.map +1 -0
  48. package/dist/garmin/types/hydration.d.ts +28 -0
  49. package/dist/garmin/types/hydration.js +2 -0
  50. package/dist/garmin/types/hydration.js.map +1 -0
  51. package/dist/garmin/types/index.d.ts +445 -0
  52. package/dist/garmin/types/index.js +37 -0
  53. package/dist/garmin/types/index.js.map +1 -0
  54. package/dist/garmin/types/sleep.d.ts +120 -0
  55. package/dist/garmin/types/sleep.js +3 -0
  56. package/dist/garmin/types/sleep.js.map +1 -0
  57. package/dist/garmin/types/weight.d.ts +42 -0
  58. package/dist/garmin/types/weight.js +3 -0
  59. package/dist/garmin/types/weight.js.map +1 -0
  60. package/dist/garmin/types/workout-builder.d.ts +138 -0
  61. package/dist/garmin/types/workout-builder.js +286 -0
  62. package/dist/garmin/types/workout-builder.js.map +1 -0
  63. package/dist/garmin/types/workout.d.ts +56 -0
  64. package/dist/garmin/types/workout.js +3 -0
  65. package/dist/garmin/types/workout.js.map +1 -0
  66. package/dist/garmin/types.d.ts +504 -0
  67. package/dist/garmin/types.js +3 -0
  68. package/dist/garmin/types.js.map +1 -0
  69. package/dist/garmin/workout-builder/duration.d.ts +87 -0
  70. package/dist/garmin/workout-builder/duration.js +173 -0
  71. package/dist/garmin/workout-builder/duration.js.map +1 -0
  72. package/dist/garmin/workout-builder/index.d.ts +5 -0
  73. package/dist/garmin/workout-builder/index.js +22 -0
  74. package/dist/garmin/workout-builder/index.js.map +1 -0
  75. package/dist/garmin/workout-builder/step.d.ts +28 -0
  76. package/dist/garmin/workout-builder/step.js +60 -0
  77. package/dist/garmin/workout-builder/step.js.map +1 -0
  78. package/dist/garmin/workout-builder/target.d.ts +49 -0
  79. package/dist/garmin/workout-builder/target.js +193 -0
  80. package/dist/garmin/workout-builder/target.js.map +1 -0
  81. package/dist/garmin/workout-builder/workout-builder.d.ts +12 -0
  82. package/dist/garmin/workout-builder/workout-builder.js +37 -0
  83. package/dist/garmin/workout-builder/workout-builder.js.map +1 -0
  84. package/dist/garmin/workout-builder/workout-type.d.ts +11 -0
  85. package/dist/garmin/workout-builder/workout-type.js +26 -0
  86. package/dist/garmin/workout-builder/workout-type.js.map +1 -0
  87. package/dist/garmin/workouts/Running.d.ts +16 -0
  88. package/dist/garmin/workouts/Running.js +64 -0
  89. package/dist/garmin/workouts/Running.js.map +1 -0
  90. package/dist/garmin/workouts/templates/RunningTemplate.d.ts +68 -0
  91. package/dist/garmin/workouts/templates/RunningTemplate.js +78 -0
  92. package/dist/garmin/workouts/templates/RunningTemplate.js.map +1 -0
  93. package/dist/garmin/workouts/workout-builder.d.ts +138 -0
  94. package/dist/garmin/workouts/workout-builder.js +286 -0
  95. package/dist/garmin/workouts/workout-builder.js.map +1 -0
  96. package/dist/garmin/workouts-builder/workout-builder.d.ts +138 -0
  97. package/dist/garmin/workouts-builder/workout-builder.js +286 -0
  98. package/dist/garmin/workouts-builder/workout-builder.js.map +1 -0
  99. package/dist/index.d.ts +4 -0
  100. package/dist/index.js +26 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/utils.d.ts +3 -0
  103. package/dist/utils.js +46 -0
  104. package/dist/utils.js.map +1 -0
  105. package/examples/assets/paris-marathon.gpx +2037 -0
  106. package/examples/example-gpx-file.js +54 -0
  107. package/examples/example-workout.js +162 -0
  108. package/examples/example.js +34 -0
  109. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 Oskar Bernberg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,627 @@
1
+ # garmin-connect
2
+
3
+ This is a fork of https://github.com/Pythe1337N/garmin-connect
4
+
5
+ ## v1.6.0 refactor
6
+
7
+ TODO:
8
+
9
+ - [x] New HttpClient class
10
+ - [x] Login and get user token
11
+ - [x] Garmin URLs works with `garmin.cn` and `garmin.com`
12
+ - [x] Auto refresh Ouath2 token
13
+ - [x] Oauth1,Oauth2 token import and export.
14
+ - [x] Download Activity, countActivities, getActivities, getActivity, getUserProfile, getUserSettings
15
+ - [x] Upload Activity, delete Activity
16
+ - [ ] Implementation of other methods:
17
+ - [ ] Badge
18
+ - [x] Gear
19
+ - [x] Workout
20
+ - [x] Course
21
+ - ...etc
22
+ - [ ] Handle MFA
23
+ - [x] Handle Account locked
24
+ - [ ] Unit test
25
+ - [ ] Listeners
26
+
27
+ If something is not working, please check [https://connect.garmin.com/status/](https://connect.garmin.com/status/) first.
28
+
29
+ Currently, most of previous features are working, but some of Rest API are not added, such as `Gear`,`Workout`,`Badge` etc. So if you need these features, please add a PR.
30
+
31
+ All of above work inspired by [https://github.com/matin/garth](https://github.com/matin/garth). Many thanks.
32
+
33
+ ---
34
+
35
+ A powerful JavaScript library for connecting to Garmin Connect for sending and receiving health and workout data. It comes with some predefined methods to get and set different kinds of data for your Garmin account, but also have the possibility to make [custom requests](#custom-requests) `GET`, `POST` and `PUT` are currently supported. This makes it easy to implement whatever may be missing to suite your needs.
36
+
37
+ ## Prerequisites
38
+
39
+ This library will require you to add a configuration file to your project root called `garmin.config.json` containing your username and password for the Garmin Connect service.
40
+
41
+ ```json
42
+ {
43
+ "username": "my.email@example.com",
44
+ "password": "MySecretPassword"
45
+ }
46
+ ```
47
+
48
+ ## How to install
49
+
50
+ ```shell
51
+ $ npm install garmin-connect
52
+ ```
53
+
54
+ ## How to use
55
+
56
+ ```js
57
+ const { GarminConnect } = require('garmin-connect');
58
+ // Create a new Garmin Connect Client
59
+ const GCClient = new GarminConnect({
60
+ username: 'my.email@example.com',
61
+ password: 'MySecretPassword'
62
+ });
63
+ // Uses credentials from garmin.config.json or uses supplied params
64
+ await GCClient.login();
65
+ const userProfile = await GCClient.getUserProfile();
66
+ ```
67
+
68
+ Now you can check `userProfile.userName` to verify that your login was successful.
69
+
70
+ ## Reusing your session(since v1.6.0)
71
+
72
+ ### Save token to file and reuse it.
73
+
74
+ ```js
75
+ GCClient.saveTokenToFile('/path/to/save/tokens');
76
+ ```
77
+
78
+ Result:
79
+
80
+ ```bash
81
+ $ ls /path/to/save/tokens
82
+ oauth1_token.json oauth2_token.json
83
+ ```
84
+
85
+ Reuse token:
86
+
87
+ ```js
88
+ GCClient.loadTokenByFile('/path/to/save/tokens');
89
+ ```
90
+
91
+ ### Or just save your token to db or other storage.
92
+
93
+ ```js
94
+ const oauth1 = GCClient.client.oauth1Token;
95
+ const oauth2 = GCClient.client.oauth2Token;
96
+ // save to db or other storage
97
+ ...
98
+ ```
99
+
100
+ Reuse token:
101
+
102
+ ```js
103
+ GCClient.loadToken(oauth1, oauth2);
104
+ ```
105
+
106
+ ## Reusing your session(deprecated)
107
+
108
+ This is an experimental feature and might not yet provide full stability.
109
+
110
+ After a successful login the `sessionJson` getter and setter can be used to export and restore your session.
111
+
112
+ ```js
113
+ // Exporting the session
114
+ const session = GCClient.sessionJson;
115
+
116
+ // Use this instead of GCClient.login() to restore the session
117
+ // This will throw an error if the stored session cannot be reused
118
+ GCClient.restore(session);
119
+ ```
120
+
121
+ The exported session should be serializable and can be stored as a JSON string.
122
+
123
+ A stored session can only be reused once and will need to be stored after each request. This can be done by attaching some storage to the `sessionChange` event.
124
+
125
+ ```js
126
+ GCClient.onSessionChange((session) => {
127
+ /*
128
+ Your choice of storage here
129
+ node-persist will probably work in most cases
130
+ */
131
+ });
132
+ ```
133
+
134
+ ### Login fallback
135
+
136
+ To make sure to use a stored session if possible, but fallback to regular login, one can use the `restoreOrLogin` method.
137
+ The arguments `username` and `password` are both optional and the regular `.login()` will be
138
+ called if session restore fails.
139
+
140
+ ```js
141
+ await GCClient.restoreOrLogin(session, username, password);
142
+ ```
143
+
144
+ ## Events
145
+
146
+ - `sessionChange` will trigger on a change in the current `sessionJson`
147
+
148
+ To attach a listener to an event, use the `.on()` method.
149
+
150
+ ```js
151
+ GCClient.on('sessionChange', (session) => console.log(session));
152
+ ```
153
+
154
+ There's currently no way of removing listeners.
155
+
156
+ ## Reading data
157
+
158
+ ### User info is not implemented yet. // TODO: Implement this function
159
+
160
+ Receive basic user information
161
+
162
+ ```js
163
+ GCClient.getUserInfo();
164
+ ```
165
+
166
+ ### Social Profile is not implemented yet. // TODO: Implement this function
167
+
168
+ Receive social user information
169
+
170
+ ```js
171
+ GCClient.getSocialProfile();
172
+ ```
173
+
174
+ ### Social Connections is not implemented yet. // TODO: Implement this function
175
+
176
+ Get a list of all social connections
177
+
178
+ ```js
179
+ GCClient.getSocialConnections();
180
+ ```
181
+
182
+ ### Device info is not implemented yet. // TODO: Implement this function
183
+
184
+ Get a list of all registered devices including model numbers and firmware versions.
185
+
186
+ ```js
187
+ GCClient.getDeviceInfo();
188
+ ```
189
+
190
+ ### `getActivities(start: number, limit: number, activityType?: ActivityType, subActivityType?: ActivitySubType): Promise<IActivity[]>`
191
+
192
+ Retrieves a list of activities based on specified parameters.
193
+
194
+ #### Parameters:
195
+
196
+ - `start` (number, optonal): Index to start fetching activities.
197
+ - `limit` (number, optonal): Number of activities to retrieve.
198
+ - `activityType` (ActivityType, optional): Type of activity (if specified, start must be null).
199
+ - `subActivityType` (ActivitySubType, optional): Subtype of activity (if specified, start must be null).
200
+
201
+ #### Returns:
202
+
203
+ - `Promise<IActivity[]>`: A Promise that resolves to an array of activities.
204
+
205
+ #### Example:
206
+
207
+ ```js
208
+ const activities = await GCClient.getActivities(
209
+ 0,
210
+ 10,
211
+ ActivityType.Running,
212
+ ActivitySubType.Outdoor
213
+ );
214
+ ```
215
+
216
+ ### `getActivity(activity: { activityId: GCActivityId }): Promise<IActivity>`
217
+
218
+ Retrieves details for a specific activity based on the provided `activityId`.
219
+
220
+ #### Parameters:
221
+
222
+ - `activity` (object): An object containing the `activityId` property.
223
+
224
+ - `activityId` (GCActivityId): Identifier for the desired activity.
225
+
226
+ #### Returns:
227
+
228
+ - `Promise<IActivity>`: A Promise that resolves to the details of the specified activity.
229
+
230
+ #### Example:
231
+
232
+ ```js
233
+ const activityDetails = await GCClient.getActivity({
234
+ activityId: 'exampleActivityId'
235
+ });
236
+ ```
237
+
238
+ ### News Feed is not implemented yet. // TODO: Implement this function
239
+
240
+ To get a list of activities in your news feed, use the `getNewsFeed` method. This function takes two arguments, _start_ and _limit_, which is used for pagination. Both are optional and will default to whatever Garmin Connect is using. To be sure to get all activities, use this correctly.
241
+
242
+ ```js
243
+ // Get the news feed with a default length with most recent activities
244
+ GCClient.getNewsFeed();
245
+ // Get activities in feed, 10 through 15. (start 10, limit 5)
246
+ GCClient.getNewsFeed(10, 5);
247
+ ```
248
+
249
+ ### Download original activity data
250
+
251
+ Use the activityId to download the original activity data. Usually this is supplied as a .zip file.
252
+
253
+ ```js
254
+ const [activity] = await GCClient.getActivities(0, 1);
255
+ // Directory path is optional and defaults to the current working directory.
256
+ // Downloads filename will be supplied by Garmin.
257
+ GCClient.downloadOriginalActivityData(activity, './some/path/that/exists');
258
+ ```
259
+
260
+ ### Upload activity file
261
+
262
+ Uploads an activity file as a new Activity. The file can be a `gpx`, `tcx`, or `fit` file. If the activity already exists, the result will have a status code of 409.
263
+ Upload fixed in 1.4.4, Garmin changed the upload api, the response `detailedImportResult` doesn't contain the new activityId.
264
+
265
+ ```js
266
+ const upload = await GCClient.uploadActivity('./some/path/to/file.fit');
267
+ // not working
268
+ const activityId = upload.detailedImportResult.successes[0].internalId;
269
+ const uploadId = upload.detailedImportResult.uploadId;
270
+ ```
271
+
272
+ ### Upload activity image
273
+
274
+ Uploads an image to activity
275
+
276
+ ```js
277
+ const [latestActivty] = await GCClient.getActivities(0, 1);
278
+
279
+ const upload = await GCClient.uploadImage(
280
+ latestActivty,
281
+ './some/path/to/file.jpg'
282
+ );
283
+ ```
284
+
285
+ ### Delete activity image
286
+
287
+ Delete an image from activity
288
+
289
+ ```js
290
+ const [activity] = await GCClient.getActivities(0, 1);
291
+ const activityDetails = await GCClient.getActivityDetails(activity.activityId);
292
+
293
+ await GCClient.deleteImage(
294
+ activity,
295
+ activityDetails.metadataDTO.activityImages[0].imageId
296
+ );
297
+ ```
298
+
299
+ ### `getSteps(date?: Date): Promise<number>`
300
+
301
+ Retrieves the total steps for a given date.
302
+
303
+ #### Parameters:
304
+
305
+ - `date` (Date, optional): Date of the steps information requested; defaults to today if no date is supplied.
306
+
307
+ #### Returns:
308
+
309
+ - `Promise<number>`: A Promise that resolves to the total steps for the specified date.
310
+
311
+ #### Example:
312
+
313
+ ```js
314
+ const totalSteps = await GCClient.getSteps(new Date('2020-03-24'));
315
+ ```
316
+
317
+ ### `getSleepData(date: string): Promise<SleepData>`
318
+
319
+ Retrieves all sleep data for a given date
320
+
321
+ #### Parameters:
322
+
323
+ - `date` (Date, optional): Date of information requested, this will default to today if no date is supplied
324
+
325
+ #### Returns:
326
+
327
+ - `Promise<SleepData>`: A Promise that resolves to an object containing detailed sleep information.
328
+
329
+ - `dailySleepDTO` (object): Information about the user's daily sleep.
330
+ - `id` (number): The unique identifier of the sleep record.
331
+ - `userProfilePK` (number): The user's profile identifier.
332
+ - `calendarDate` (string): The date of the sleep record.
333
+ - ...
334
+ - `sleepMovement` (array): An array of sleep movement data.
335
+ - `remSleepData` (boolean): Indicates whether REM sleep data is available.
336
+ - `sleepLevels` (array): An array of sleep levels data.
337
+ - `restlessMomentsCount` (number): Count of restless moments during sleep.
338
+ - ...
339
+
340
+ #### Example:
341
+
342
+ ```js
343
+ const detailedSleep = await GCClient.getSleepDuration(new Date('2020-03-24'));
344
+ ```
345
+
346
+ ### `getSleepDuration(date: string): Promise<{hours: number, minutes: number}`
347
+
348
+ Retrieves hours and minutes slept for a given date
349
+
350
+ #### Parameters:
351
+
352
+ - `date` (Date, optional): Date of information requested, this will default to today if no date is supplied
353
+
354
+ #### Returns:
355
+
356
+ - `Promise<{hours: string, minutes: string }>`: A Promise that resolves to an object containing information about the sleep duration
357
+
358
+ - `hours` (string): Number of hours
359
+ - `minutes` (string): Number of minutes
360
+
361
+ #### Example:
362
+
363
+ ```js
364
+ const detailedSleep = await GCClient.getSleepDuration(new Date('2020-03-24'));
365
+ ```
366
+
367
+ ### `getDailyWeightData(date?: Date): Promise<number>`
368
+
369
+ Retrieves the daily weight and converts it from grams to pounds.
370
+
371
+ #### Parameters:
372
+
373
+ - `date` (Date, optional): Date of information requested. Defaults to the current date.
374
+
375
+ #### Returns:
376
+
377
+ - `Promise<number>`: A Promise that resolves to the daily weight converted from grams to pounds.
378
+
379
+ #### Throws:
380
+
381
+ - `Error`: If valid daily weight data cannot be found for the specified date.
382
+
383
+ #### Example:
384
+
385
+ ```js
386
+ const weightData = await GCClient.getDailyWeightData(new Date('2023-12-25'));
387
+ ```
388
+
389
+ ### `getDailyWeightInPounds(date?: Date): Promise<number>`
390
+
391
+ Retrieves the daily weight in pounds for a given date.
392
+
393
+ #### Parameters:
394
+
395
+ - `date` (Date, optional): Date of information requested; defaults to today if no date is supplied.
396
+
397
+ #### Returns:
398
+
399
+ - `Promise<number>`: A Promise that resolves to the daily weight in pounds.
400
+
401
+ #### Example:
402
+
403
+ ```js
404
+ const weightInPounds = await GCClient.getDailyWeightInPounds(
405
+ new Date('2020-03-24')
406
+ );
407
+ ```
408
+
409
+ ## `getDailyHydration(date?: Date): Promise<number>`
410
+
411
+ Retrieves the daily hydration data and converts it from milliliters to ounces.
412
+
413
+ ### Parameters:
414
+
415
+ - `date` (Date, optional): Date of the requested information. Defaults to the current date.
416
+
417
+ ### Returns:
418
+
419
+ - `Promise<number>`: A Promise that resolves to the daily hydration data converted from milliliters to ounces.
420
+
421
+ ### Throws:
422
+
423
+ - `Error`: If valid daily hydration data cannot be found for the specified date or if the response is invalid.
424
+
425
+ ### Example:
426
+
427
+ ```js
428
+ const hydrationInOunces = await GCClient.getDailyHydration(
429
+ new Date('2023-12-25')
430
+ );
431
+ ```
432
+
433
+ ### `getGolfSummary(): Promise<GolfSummary>`
434
+
435
+ Retrieves a summary of golf scorecard data.
436
+
437
+ #### Returns:
438
+
439
+ - `Promise<GolfSummary>`: A Promise that resolves to the golf scorecard summary.
440
+
441
+ #### Example:
442
+
443
+ ```js
444
+ const golfSummary = await GCClient.getGolfSummary();
445
+ ```
446
+
447
+ ### `getGolfScorecard(scorecardId: number): Promise<GolfScorecard>`
448
+
449
+ Retrieves golf scorecard data for a specific scorecard.
450
+
451
+ #### Parameters:
452
+
453
+ - `scorecardId` (number): Identifier for the desired golf scorecard.
454
+
455
+ #### Returns:
456
+
457
+ - `Promise<GolfScorecard>`: A Promise that resolves to the golf scorecard data.
458
+
459
+ #### Example:
460
+
461
+ ```js
462
+ const scorecardId = 123; // Replace with the desired scorecard ID
463
+ const golfScorecard = await GCClient.getGolfScorecard(scorecardId);
464
+ ```
465
+
466
+ ### `getHeartRate(date?: Date): Promise<HeartRate>`
467
+
468
+ Retrieves daily heart rate data for a given date.
469
+
470
+ #### Parameters:
471
+
472
+ - `date` (Date, optional): Date of the heart rate data requested; defaults to today if no date is supplied.
473
+
474
+ #### Returns:
475
+
476
+ - `Promise<HeartRate>`: A Promise that resolves to the daily heart rate data.
477
+
478
+ #### Example:
479
+
480
+ ```js
481
+ const heartRateData = await GCClient.getHeartRate(new Date('2020-03-24'));
482
+ ```
483
+
484
+ ## Modifying data
485
+
486
+ ### Update activity is not implemented yet. // TODO: Implement this function
487
+
488
+ ```js
489
+ const activities = await GCClient.getActivities(0, 1);
490
+ const activity = activities[0];
491
+ activity['activityName'] = 'The Updated Name';
492
+ await GCClient.updateActivity(activity);
493
+ ```
494
+
495
+ ### Delete an activity
496
+
497
+ Deletes an activty.
498
+
499
+ ```js
500
+ const activities = await GCClient.getActivities(0, 1);
501
+ const activity = activities[0];
502
+ await GCClient.deleteActivity(activity);
503
+ ```
504
+
505
+ ### `updateHydrationLogOunces(date?: Date, valueInOz: number): Promise<WaterIntake>`
506
+
507
+ Adds a hydration log entry in ounces for a given date.
508
+
509
+ #### Parameters:
510
+
511
+ - `date` (Date, optional): Date of the log entry; defaults to today if no date is supplied.
512
+ - `valueInOz` (number): Amount of water intake in ounces. Accepts negative number.
513
+
514
+ #### Returns:
515
+
516
+ - `Promise<WaterIntake>`: A Promise that resolves to the hydration log entry.
517
+
518
+ #### Example:
519
+
520
+ ```js
521
+ const hydrationLogEntry = await GCClient.addHydrationLogOunces(
522
+ new Date('2020-03-24'),
523
+ 16
524
+ );
525
+ ```
526
+
527
+ ### `updateWeight(date = new Date(), lbs: number, timezone: string): Promise<UpdateWeight>`
528
+
529
+ Updates weight information
530
+
531
+ #### Parameters:
532
+
533
+ - `date` (optional): Date object representing the weight entry date. Defaults to the current date if not provided.
534
+ - `lbs` (number): Weight value in pounds.
535
+ - `timezone` (string): String representing the timezone for the weight entry.
536
+
537
+ #### Returns:
538
+
539
+ - `Promise<UpdateWeight>`: A Promise that resolves to the result of the weight update.
540
+
541
+ #### Example:
542
+
543
+ ```js
544
+ await GCClient.updateWeight(undefined, 202.9, 'America/Los_Angeles');
545
+ ```
546
+
547
+ ### Add workout
548
+
549
+ To add a custom workout, use the `addWorkout` or more specifically `addRunningWorkout`.
550
+
551
+ ```js
552
+ GCClient.addRunningWorkout('My 5k run', 5000, 'Some description');
553
+ ```
554
+
555
+ Will add a running workout of 5km called 'My 5k run' and return a JSON object representing the saved workout.
556
+
557
+ ### Schedule workout
558
+
559
+ To add a workout to your calendar, first find your workout and then add it to a specific date.
560
+
561
+ ```js
562
+ const workouts = await GCClient.getWorkouts();
563
+ const id = workouts[0].workoutId;
564
+ GCClient.scheduleWorkout({ workoutId: id }, new Date('2020-03-24'));
565
+ ```
566
+
567
+ This will add the workout to a specific date in your calendar and make it show up automatically if you're using any of the Garmin watches.
568
+
569
+ ### Delete workout
570
+
571
+ Deleting a workout is very similar to [scheduling](#schedule-workout) one.
572
+
573
+ ```js
574
+ const workouts = await GCClient.getWorkouts();
575
+ const id = workouts[0].workoutId;
576
+ GCClient.deleteWorkout({ workoutId: id });
577
+ ```
578
+
579
+ ## Custom requests
580
+
581
+ This library will handle custom requests to your active Garmin Connect session. There are a lot of different url's that is used, which means that this library probably wont cover them all. By using the network analyze tool you can find url's that are used by Garmin Connect to fetch data.
582
+
583
+ Let's assume I found a `GET` requests to the following url:
584
+
585
+ ```
586
+ https://connect.garmin.com/modern/proxy/wellness-service/wellness/dailyHeartRate/22f5f84c-de9d-4ad6-97f2-201097b3b983?date=2020-03-24
587
+ ```
588
+
589
+ The request can be sent using `GCClient` by running
590
+
591
+ ```js
592
+ // You can get your displayName by using the getUserInfo method;
593
+ const displayName = '22f5f84c-de9d-4ad6-97f2-201097b3b983';
594
+ const url =
595
+ 'https://connect.garmin.com/modern/proxy/wellness-service/wellness/dailyHeartRate/';
596
+ const dateString = '2020-03-24';
597
+ GCClient.get(url + displayName, { date: dateString });
598
+ ```
599
+
600
+ and will net you the same result as using the provided way
601
+
602
+ ```js
603
+ GCClient.getHeartRate();
604
+ ```
605
+
606
+ Notice how the client will keep track of the url's, your user information as well as keeping the session alive.
607
+
608
+ ## Limitations
609
+
610
+ Many responses from Garmin Connect are missing type definitions and defaults to `unknown`. Feel free to add types by opening a pull request.
611
+
612
+ For now, this library only supports the following:
613
+
614
+ - Get user info
615
+ - Get social user info
616
+ - Get heart rate
617
+ - Set body weight
618
+ - Get list of workouts
619
+ - Add new workouts
620
+ - Add workouts to you calendar
621
+ - Remove previously added workouts
622
+ - Get list of activities
623
+ - Get details about one specific activity
624
+ - Get the step count
625
+ - Get earned badges
626
+ - Get available badges
627
+ - Get details about one specific badge
@@ -0,0 +1,22 @@
1
+ import { Options, Response } from 'cloudscraper';
2
+ import { Headers } from 'request';
3
+ import { CookieJar as ToughCookieJar } from 'tough-cookie';
4
+ export default class CFClient {
5
+ private cookies;
6
+ private headers;
7
+ constructor(headers: Headers);
8
+ serializeCookies(): ToughCookieJar.Serialized | undefined;
9
+ importCookies(cookies: ToughCookieJar.Serialized): void;
10
+ scraper(options: Options): Promise<Response>;
11
+ /**
12
+ * @param {string} downloadDir
13
+ * @param {string} url
14
+ * @param {*} data
15
+ */
16
+ downloadBlob(downloadDir: string | undefined, url: string, data?: any): Promise<unknown>;
17
+ get<T>(url: string, data?: any): Promise<T>;
18
+ post<T>(url: string, data: any): Promise<T>;
19
+ delete<T>(url: string): Promise<T>;
20
+ postJson<T>(url: string, data: any, headers: Headers): Promise<T>;
21
+ putJson<T>(url: string, data: any): Promise<T>;
22
+ }