garmin-connect-client 0.1.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/README.md +84 -0
- package/dist/client.d.ts +14 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +56 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +101 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +184 -0
- package/dist/errors.js.map +1 -0
- package/dist/http-client.d.ts +32 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +440 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +2905 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +569 -0
- package/dist/types.js.map +1 -0
- package/dist/urls.d.ts +23 -0
- package/dist/urls.d.ts.map +1 -0
- package/dist/urls.js +92 -0
- package/dist/urls.js.map +1 -0
- package/package.json +69 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Garmin Connect
|
|
2
|
+
|
|
3
|
+
TypeScript library for reading data from Garmin Connect.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install garmin-connect-client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Development
|
|
12
|
+
|
|
13
|
+
### Setup
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Build
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm run build
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Watch Mode
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm run watch
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Clean
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm run clean
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Basic Usage
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { create, type GarminConnectClient } from 'garmin-connect-client';
|
|
43
|
+
|
|
44
|
+
// Create an authenticated client
|
|
45
|
+
const client: GarminConnectClient = await create({
|
|
46
|
+
username: 'your-username',
|
|
47
|
+
password: 'your-password',
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Get activities
|
|
51
|
+
const activities = await client.getActivities();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### With MFA
|
|
55
|
+
|
|
56
|
+
If your account uses Multi-Factor Authentication (MFA), provide an `mfaCodeProvider`:
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { create } from 'garmin-connect-client';
|
|
60
|
+
|
|
61
|
+
const client = await create({
|
|
62
|
+
username: 'your-username',
|
|
63
|
+
password: 'your-password',
|
|
64
|
+
mfaCodeProvider: async () => {
|
|
65
|
+
// Return the MFA code
|
|
66
|
+
return '123456';
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Testing
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npm test # Run tests in watch mode
|
|
75
|
+
npm run test:run # Run tests once
|
|
76
|
+
npm run test:ui # Open Vitest UI
|
|
77
|
+
npm run test:coverage # Generate coverage report
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
MIT
|
|
83
|
+
|
|
84
|
+
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Activity, GarminConnectClient, GarminConnectClientConfig, GolfActivitiesResponse } from './types';
|
|
2
|
+
export declare class GarminConnectClientImpl implements GarminConnectClient {
|
|
3
|
+
private config;
|
|
4
|
+
private httpClient;
|
|
5
|
+
private urls;
|
|
6
|
+
private constructor();
|
|
7
|
+
static createAuthenticated(config: GarminConnectClientConfig): Promise<GarminConnectClientImpl>;
|
|
8
|
+
private login;
|
|
9
|
+
private isAuthenticated;
|
|
10
|
+
getActivities(start?: number, limit?: number): Promise<Activity[]>;
|
|
11
|
+
getActivity(id: string): Promise<Activity>;
|
|
12
|
+
getGolfActivities(page?: number, perPage?: number, locale?: string): Promise<GolfActivitiesResponse>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAOhH,qBAAa,uBAAwB,YAAW,mBAAmB;IACjE,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,IAAI,CAAa;IAEzB,OAAO;WAMM,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,OAAO,CAAC,uBAAuB,CAAC;YAMvF,KAAK;IAMnB,OAAO,CAAC,eAAe;IAIjB,aAAa,CAAC,KAAK,SAAI,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAUzD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAU1C,iBAAiB,CAAC,IAAI,SAAI,EAAE,OAAO,SAAK,EAAE,MAAM,SAAO,GAAG,OAAO,CAAC,sBAAsB,CAAC;CAShG"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GarminConnectClientImpl = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
const http_client_1 = require("./http-client");
|
|
7
|
+
const types_1 = require("./types");
|
|
8
|
+
const urls_1 = require("./urls");
|
|
9
|
+
// Response schema for activities list
|
|
10
|
+
const ActivitiesResponseSchema = zod_1.z.array(types_1.ActivitySchema);
|
|
11
|
+
class GarminConnectClientImpl {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.urls = new urls_1.GarminUrls();
|
|
15
|
+
this.httpClient = new http_client_1.HttpClient(this.urls, config.mfaCodeProvider);
|
|
16
|
+
}
|
|
17
|
+
static async createAuthenticated(config) {
|
|
18
|
+
const client = new GarminConnectClientImpl(config);
|
|
19
|
+
await client.login();
|
|
20
|
+
return client;
|
|
21
|
+
}
|
|
22
|
+
async login() {
|
|
23
|
+
await this.httpClient.authenticate(this.config.username, this.config.password);
|
|
24
|
+
}
|
|
25
|
+
// Checks if the client is authenticated by delegating to HttpClient
|
|
26
|
+
// This ensures the authentication state is always in sync with token state
|
|
27
|
+
isAuthenticated() {
|
|
28
|
+
return this.httpClient.isAuthenticated();
|
|
29
|
+
}
|
|
30
|
+
async getActivities(start = 0, limit = 20) {
|
|
31
|
+
if (!this.isAuthenticated()) {
|
|
32
|
+
throw new errors_1.NotAuthenticatedError();
|
|
33
|
+
}
|
|
34
|
+
const url = this.urls.ACTIVITY_SEARCH(start, limit);
|
|
35
|
+
const response = await this.httpClient.get(url);
|
|
36
|
+
return ActivitiesResponseSchema.parse(response);
|
|
37
|
+
}
|
|
38
|
+
async getActivity(id) {
|
|
39
|
+
if (!this.isAuthenticated()) {
|
|
40
|
+
throw new errors_1.NotAuthenticatedError();
|
|
41
|
+
}
|
|
42
|
+
const url = this.urls.ACTIVITY_DETAIL(id);
|
|
43
|
+
const response = await this.httpClient.get(url);
|
|
44
|
+
return types_1.ActivitySchema.parse(response);
|
|
45
|
+
}
|
|
46
|
+
async getGolfActivities(page = 1, perPage = 20, locale = 'en') {
|
|
47
|
+
if (!this.isAuthenticated()) {
|
|
48
|
+
throw new errors_1.NotAuthenticatedError();
|
|
49
|
+
}
|
|
50
|
+
const url = this.urls.GOLF_ACTIVITIES(page, perPage, locale);
|
|
51
|
+
const response = await this.httpClient.get(url);
|
|
52
|
+
return types_1.GolfActivitiesResponseSchema.parse(response);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.GarminConnectClientImpl = GarminConnectClientImpl;
|
|
56
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AAExB,qCAAiD;AACjD,+CAA2C;AAE3C,mCAAuE;AACvE,iCAAoC;AAEpC,sCAAsC;AACtC,MAAM,wBAAwB,GAAG,OAAC,CAAC,KAAK,CAAC,sBAAc,CAAC,CAAC;AAEzD,MAAa,uBAAuB;IAKlC,YAAoB,MAAiC;QACnD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,iBAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,wBAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAiC;QAChE,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACjF,CAAC;IAED,oEAAoE;IACpE,2EAA2E;IACnE,eAAe;QACrB,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,EAAE;QACvC,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,8BAAqB,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACpD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAU,GAAG,CAAC,CAAC;QACzD,OAAO,wBAAwB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC1B,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,8BAAqB,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAU,GAAG,CAAC,CAAC;QACzD,OAAO,sBAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,IAAI,GAAG,CAAC,EAAE,OAAO,GAAG,EAAE,EAAE,MAAM,GAAG,IAAI;QAC3D,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;YAC5B,MAAM,IAAI,8BAAqB,EAAE,CAAC;QACpC,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAChD,OAAO,oCAA4B,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtD,CAAC;CACF;AAxDD,0DAwDC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom exception classes for Garmin Connect client
|
|
3
|
+
*
|
|
4
|
+
* All exceptions extend GarminConnectError, allowing consumers to catch
|
|
5
|
+
* all library errors with a single catch block, or handle specific error
|
|
6
|
+
* types individually.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Base exception class for all Garmin Connect client errors
|
|
10
|
+
*/
|
|
11
|
+
export declare class GarminConnectError extends Error {
|
|
12
|
+
constructor(message: string);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Base class for authentication-related errors
|
|
16
|
+
*/
|
|
17
|
+
export declare class AuthenticationError extends GarminConnectError {
|
|
18
|
+
constructor(message: string);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Thrown when username/password combination is invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare class InvalidCredentialsError extends AuthenticationError {
|
|
24
|
+
constructor(message?: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Thrown when CSRF token cannot be found during authentication
|
|
28
|
+
*/
|
|
29
|
+
export declare class CsrfTokenError extends AuthenticationError {
|
|
30
|
+
constructor(message?: string);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Base class for MFA-related errors
|
|
34
|
+
*/
|
|
35
|
+
export declare class MfaError extends GarminConnectError {
|
|
36
|
+
constructor(message: string);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Thrown when MFA is required but no MFA code provider was configured
|
|
40
|
+
*/
|
|
41
|
+
export declare class MfaRequiredError extends MfaError {
|
|
42
|
+
constructor(message?: string);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Thrown when MFA code is empty or invalid
|
|
46
|
+
*/
|
|
47
|
+
export declare class MfaCodeError extends MfaError {
|
|
48
|
+
constructor(message?: string);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Thrown when MFA code submission fails or code is incorrect
|
|
52
|
+
*/
|
|
53
|
+
export declare class MfaCodeInvalidError extends MfaError {
|
|
54
|
+
constructor(message?: string);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Base class for OAuth-related errors
|
|
58
|
+
*/
|
|
59
|
+
export declare class OAuthError extends GarminConnectError {
|
|
60
|
+
constructor(message: string);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Thrown when OAuth app identity (key/secret) is not available
|
|
64
|
+
*/
|
|
65
|
+
export declare class OAuthIdentityError extends OAuthError {
|
|
66
|
+
constructor(message?: string);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Thrown when OAuth token is not available (e.g., for refresh)
|
|
70
|
+
*/
|
|
71
|
+
export declare class OAuthTokenError extends OAuthError {
|
|
72
|
+
constructor(message?: string);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Base class for client state errors
|
|
76
|
+
*/
|
|
77
|
+
export declare class ClientError extends GarminConnectError {
|
|
78
|
+
constructor(message: string);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Thrown when client method is called before authentication
|
|
82
|
+
*/
|
|
83
|
+
export declare class NotAuthenticatedError extends ClientError {
|
|
84
|
+
constructor(message?: string);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Thrown when a method is not yet implemented
|
|
88
|
+
*/
|
|
89
|
+
export declare class NotImplementedError extends ClientError {
|
|
90
|
+
constructor(message?: string);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Thrown for HTTP-related errors
|
|
94
|
+
*/
|
|
95
|
+
export declare class HttpError extends GarminConnectError {
|
|
96
|
+
readonly statusCode?: number;
|
|
97
|
+
readonly statusText?: string;
|
|
98
|
+
readonly responseData?: unknown;
|
|
99
|
+
constructor(message: string, statusCode?: number, statusText?: string, responseData?: unknown);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAU5B;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,kBAAkB;gBAC7C,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,mBAAmB;gBAClD,OAAO,GAAE,MAAuC;CAK7D;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,mBAAmB;gBACzC,OAAO,GAAE,MAA4C;CAKlE;AAED;;GAEG;AACH,qBAAa,QAAS,SAAQ,kBAAkB;gBAClC,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;gBAChC,OAAO,GAAE,MAAkE;CAKxF;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,QAAQ;gBAC5B,OAAO,GAAE,MAAmC;CAKzD;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,QAAQ;gBACnC,OAAO,GAAE,MAAkE;CAKxF;AAED;;GAEG;AACH,qBAAa,UAAW,SAAQ,kBAAkB;gBACpC,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,UAAU;gBACpC,OAAO,GAAE,MAA0C;CAKhE;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,UAAU;gBACjC,OAAO,GAAE,MAAmC;CAKzD;AAED;;GAEG;AACH,qBAAa,WAAY,SAAQ,kBAAkB;gBACrC,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,WAAW;gBACxC,OAAO,GAAE,MAA4D;CAKlF;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,WAAW;gBACtC,OAAO,GAAE,MAA0B;CAKhD;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,kBAAkB;IAC/C,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpC,SAAgB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpC,SAAgB,YAAY,CAAC,EAAE,OAAO,CAAC;gBAE3B,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO;CAQ9F"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Custom exception classes for Garmin Connect client
|
|
4
|
+
*
|
|
5
|
+
* All exceptions extend GarminConnectError, allowing consumers to catch
|
|
6
|
+
* all library errors with a single catch block, or handle specific error
|
|
7
|
+
* types individually.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.HttpError = exports.NotImplementedError = exports.NotAuthenticatedError = exports.ClientError = exports.OAuthTokenError = exports.OAuthIdentityError = exports.OAuthError = exports.MfaCodeInvalidError = exports.MfaCodeError = exports.MfaRequiredError = exports.MfaError = exports.CsrfTokenError = exports.InvalidCredentialsError = exports.AuthenticationError = exports.GarminConnectError = void 0;
|
|
11
|
+
/**
|
|
12
|
+
* Base exception class for all Garmin Connect client errors
|
|
13
|
+
*/
|
|
14
|
+
class GarminConnectError extends Error {
|
|
15
|
+
constructor(message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.name = 'GarminConnectError';
|
|
18
|
+
// Maintains proper stack trace for where our error was thrown (only available on V8)
|
|
19
|
+
if (Error.captureStackTrace) {
|
|
20
|
+
Error.captureStackTrace(this, this.constructor);
|
|
21
|
+
}
|
|
22
|
+
// Ensure instanceof works correctly
|
|
23
|
+
Object.setPrototypeOf(this, GarminConnectError.prototype);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.GarminConnectError = GarminConnectError;
|
|
27
|
+
/**
|
|
28
|
+
* Base class for authentication-related errors
|
|
29
|
+
*/
|
|
30
|
+
class AuthenticationError extends GarminConnectError {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = 'AuthenticationError';
|
|
34
|
+
Object.setPrototypeOf(this, AuthenticationError.prototype);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.AuthenticationError = AuthenticationError;
|
|
38
|
+
/**
|
|
39
|
+
* Thrown when username/password combination is invalid
|
|
40
|
+
*/
|
|
41
|
+
class InvalidCredentialsError extends AuthenticationError {
|
|
42
|
+
constructor(message = 'Invalid username or password') {
|
|
43
|
+
super(message);
|
|
44
|
+
this.name = 'InvalidCredentialsError';
|
|
45
|
+
Object.setPrototypeOf(this, InvalidCredentialsError.prototype);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.InvalidCredentialsError = InvalidCredentialsError;
|
|
49
|
+
/**
|
|
50
|
+
* Thrown when CSRF token cannot be found during authentication
|
|
51
|
+
*/
|
|
52
|
+
class CsrfTokenError extends AuthenticationError {
|
|
53
|
+
constructor(message = 'CSRF token not found during login') {
|
|
54
|
+
super(message);
|
|
55
|
+
this.name = 'CsrfTokenError';
|
|
56
|
+
Object.setPrototypeOf(this, CsrfTokenError.prototype);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.CsrfTokenError = CsrfTokenError;
|
|
60
|
+
/**
|
|
61
|
+
* Base class for MFA-related errors
|
|
62
|
+
*/
|
|
63
|
+
class MfaError extends GarminConnectError {
|
|
64
|
+
constructor(message) {
|
|
65
|
+
super(message);
|
|
66
|
+
this.name = 'MfaError';
|
|
67
|
+
Object.setPrototypeOf(this, MfaError.prototype);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
exports.MfaError = MfaError;
|
|
71
|
+
/**
|
|
72
|
+
* Thrown when MFA is required but no MFA code provider was configured
|
|
73
|
+
*/
|
|
74
|
+
class MfaRequiredError extends MfaError {
|
|
75
|
+
constructor(message = 'MFA is required but no MFA code provider was configured') {
|
|
76
|
+
super(message);
|
|
77
|
+
this.name = 'MfaRequiredError';
|
|
78
|
+
Object.setPrototypeOf(this, MfaRequiredError.prototype);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.MfaRequiredError = MfaRequiredError;
|
|
82
|
+
/**
|
|
83
|
+
* Thrown when MFA code is empty or invalid
|
|
84
|
+
*/
|
|
85
|
+
class MfaCodeError extends MfaError {
|
|
86
|
+
constructor(message = 'MFA code cannot be empty') {
|
|
87
|
+
super(message);
|
|
88
|
+
this.name = 'MfaCodeError';
|
|
89
|
+
Object.setPrototypeOf(this, MfaCodeError.prototype);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.MfaCodeError = MfaCodeError;
|
|
93
|
+
/**
|
|
94
|
+
* Thrown when MFA code submission fails or code is incorrect
|
|
95
|
+
*/
|
|
96
|
+
class MfaCodeInvalidError extends MfaError {
|
|
97
|
+
constructor(message = 'MFA code submission failed - please check your MFA code') {
|
|
98
|
+
super(message);
|
|
99
|
+
this.name = 'MfaCodeInvalidError';
|
|
100
|
+
Object.setPrototypeOf(this, MfaCodeInvalidError.prototype);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
exports.MfaCodeInvalidError = MfaCodeInvalidError;
|
|
104
|
+
/**
|
|
105
|
+
* Base class for OAuth-related errors
|
|
106
|
+
*/
|
|
107
|
+
class OAuthError extends GarminConnectError {
|
|
108
|
+
constructor(message) {
|
|
109
|
+
super(message);
|
|
110
|
+
this.name = 'OAuthError';
|
|
111
|
+
Object.setPrototypeOf(this, OAuthError.prototype);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.OAuthError = OAuthError;
|
|
115
|
+
/**
|
|
116
|
+
* Thrown when OAuth app identity (key/secret) is not available
|
|
117
|
+
*/
|
|
118
|
+
class OAuthIdentityError extends OAuthError {
|
|
119
|
+
constructor(message = 'No OAuth app identity available') {
|
|
120
|
+
super(message);
|
|
121
|
+
this.name = 'OAuthIdentityError';
|
|
122
|
+
Object.setPrototypeOf(this, OAuthIdentityError.prototype);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.OAuthIdentityError = OAuthIdentityError;
|
|
126
|
+
/**
|
|
127
|
+
* Thrown when OAuth token is not available (e.g., for refresh)
|
|
128
|
+
*/
|
|
129
|
+
class OAuthTokenError extends OAuthError {
|
|
130
|
+
constructor(message = 'No OAuth token available') {
|
|
131
|
+
super(message);
|
|
132
|
+
this.name = 'OAuthTokenError';
|
|
133
|
+
Object.setPrototypeOf(this, OAuthTokenError.prototype);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
exports.OAuthTokenError = OAuthTokenError;
|
|
137
|
+
/**
|
|
138
|
+
* Base class for client state errors
|
|
139
|
+
*/
|
|
140
|
+
class ClientError extends GarminConnectError {
|
|
141
|
+
constructor(message) {
|
|
142
|
+
super(message);
|
|
143
|
+
this.name = 'ClientError';
|
|
144
|
+
Object.setPrototypeOf(this, ClientError.prototype);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.ClientError = ClientError;
|
|
148
|
+
/**
|
|
149
|
+
* Thrown when client method is called before authentication
|
|
150
|
+
*/
|
|
151
|
+
class NotAuthenticatedError extends ClientError {
|
|
152
|
+
constructor(message = 'Client is not authenticated. Call create() first.') {
|
|
153
|
+
super(message);
|
|
154
|
+
this.name = 'NotAuthenticatedError';
|
|
155
|
+
Object.setPrototypeOf(this, NotAuthenticatedError.prototype);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
exports.NotAuthenticatedError = NotAuthenticatedError;
|
|
159
|
+
/**
|
|
160
|
+
* Thrown when a method is not yet implemented
|
|
161
|
+
*/
|
|
162
|
+
class NotImplementedError extends ClientError {
|
|
163
|
+
constructor(message = 'Not implemented') {
|
|
164
|
+
super(message);
|
|
165
|
+
this.name = 'NotImplementedError';
|
|
166
|
+
Object.setPrototypeOf(this, NotImplementedError.prototype);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.NotImplementedError = NotImplementedError;
|
|
170
|
+
/**
|
|
171
|
+
* Thrown for HTTP-related errors
|
|
172
|
+
*/
|
|
173
|
+
class HttpError extends GarminConnectError {
|
|
174
|
+
constructor(message, statusCode, statusText, responseData) {
|
|
175
|
+
super(message);
|
|
176
|
+
this.name = 'HttpError';
|
|
177
|
+
this.statusCode = statusCode;
|
|
178
|
+
this.statusText = statusText;
|
|
179
|
+
this.responseData = responseData;
|
|
180
|
+
Object.setPrototypeOf(this, HttpError.prototype);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.HttpError = HttpError;
|
|
184
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
2
|
+
import type { MfaCodeProvider, OAuth1Token, OAuth2Token } from './types';
|
|
3
|
+
import { GarminUrls } from './urls';
|
|
4
|
+
export declare class HttpClient {
|
|
5
|
+
private client;
|
|
6
|
+
private oauth1Token?;
|
|
7
|
+
private oauth2Token?;
|
|
8
|
+
private urls;
|
|
9
|
+
private mfaCodeProvider?;
|
|
10
|
+
private readonly appOauthIdentity;
|
|
11
|
+
private isRefreshing;
|
|
12
|
+
private refreshPromise?;
|
|
13
|
+
constructor(urls: GarminUrls, mfaCodeProvider?: MfaCodeProvider);
|
|
14
|
+
authenticate(username: string, password: string): Promise<{
|
|
15
|
+
oauth1Token: OAuth1Token;
|
|
16
|
+
oauth2Token: OAuth2Token;
|
|
17
|
+
}>;
|
|
18
|
+
private getLoginTicket;
|
|
19
|
+
private verifyMfaCode;
|
|
20
|
+
private getOauth1Token;
|
|
21
|
+
private getOauthClient;
|
|
22
|
+
private exchange;
|
|
23
|
+
private setOauth2TokenExpiresAt;
|
|
24
|
+
private refreshToken;
|
|
25
|
+
get<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
26
|
+
post<T>(url: string, data: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
27
|
+
put<T>(url: string, data: unknown, config?: AxiosRequestConfig): Promise<T>;
|
|
28
|
+
delete<T>(url: string, config?: AxiosRequestConfig): Promise<T>;
|
|
29
|
+
handleError(response: AxiosResponse): void;
|
|
30
|
+
isAuthenticated(): boolean;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=http-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-client.d.ts","sourceRoot":"","sources":["../src/http-client.ts"],"names":[],"mappings":"AAcA,OAAc,EAAiB,kBAAkB,EAAE,aAAa,EAA8B,MAAM,OAAO,CAAC;AAc5G,OAAO,KAAK,EAAE,eAAe,EAAqB,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC5F,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAoDpC,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAgB;IAE9B,OAAO,CAAC,WAAW,CAAC,CAAc;IAElC,OAAO,CAAC,WAAW,CAAC,CAAc;IAClC,OAAO,CAAC,IAAI,CAAa;IAEzB,OAAO,CAAC,eAAe,CAAC,CAAkB;IAE1C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAoB;IAErD,OAAO,CAAC,YAAY,CAAS;IAE7B,OAAO,CAAC,cAAc,CAAC,CAAkB;gBAE7B,IAAI,EAAE,UAAU,EAAE,eAAe,CAAC,EAAE,eAAe;IA+DzD,YAAY,CAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,WAAW,EAAE,WAAW,CAAC;QAAC,WAAW,EAAE,WAAW,CAAA;KAAE,CAAC;YAqBpD,cAAc;YA8Fd,aAAa;YA6Db,cAAc;IAkC5B,OAAO,CAAC,cAAc;YAeR,QAAQ;IA8BtB,OAAO,CAAC,uBAAuB;YAmBjB,YAAY;IA2BpB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ5D,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAQ5E,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAU3E,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC;IAarE,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAQ1C,eAAe,IAAI,OAAO;CAG3B"}
|