@pinta365/strava 0.0.1

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 (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +390 -0
  3. package/esm/_dnt.shims.d.ts +2 -0
  4. package/esm/_dnt.shims.js +57 -0
  5. package/esm/deps/jsr.io/@cross/runtime/1.2.1/mod.d.ts +126 -0
  6. package/esm/deps/jsr.io/@cross/runtime/1.2.1/mod.js +480 -0
  7. package/esm/mod.d.ts +27 -0
  8. package/esm/mod.js +27 -0
  9. package/esm/package.json +3 -0
  10. package/esm/src/auth/oauth.d.ts +68 -0
  11. package/esm/src/auth/oauth.js +203 -0
  12. package/esm/src/auth/scopes.d.ts +52 -0
  13. package/esm/src/auth/scopes.js +71 -0
  14. package/esm/src/auth/token-store.d.ts +57 -0
  15. package/esm/src/auth/token-store.js +142 -0
  16. package/esm/src/client.d.ts +98 -0
  17. package/esm/src/client.js +235 -0
  18. package/esm/src/errors.d.ts +52 -0
  19. package/esm/src/errors.js +102 -0
  20. package/esm/src/http/deduplication.d.ts +33 -0
  21. package/esm/src/http/deduplication.js +96 -0
  22. package/esm/src/http/rate-limiter.d.ts +47 -0
  23. package/esm/src/http/rate-limiter.js +168 -0
  24. package/esm/src/http/request.d.ts +24 -0
  25. package/esm/src/http/request.js +158 -0
  26. package/esm/src/http/retry.d.ts +9 -0
  27. package/esm/src/http/retry.js +61 -0
  28. package/esm/src/resources/activities.d.ts +149 -0
  29. package/esm/src/resources/activities.js +189 -0
  30. package/esm/src/resources/athletes.d.ts +37 -0
  31. package/esm/src/resources/athletes.js +85 -0
  32. package/esm/src/resources/clubs.d.ts +45 -0
  33. package/esm/src/resources/clubs.js +71 -0
  34. package/esm/src/resources/gears.d.ts +17 -0
  35. package/esm/src/resources/gears.js +27 -0
  36. package/esm/src/resources/routes.d.ts +33 -0
  37. package/esm/src/resources/routes.js +71 -0
  38. package/esm/src/resources/segment-efforts.d.ts +38 -0
  39. package/esm/src/resources/segment-efforts.js +53 -0
  40. package/esm/src/resources/segments.d.ts +42 -0
  41. package/esm/src/resources/segments.js +67 -0
  42. package/esm/src/resources/streams.d.ts +44 -0
  43. package/esm/src/resources/streams.js +75 -0
  44. package/esm/src/resources/uploads.d.ts +41 -0
  45. package/esm/src/resources/uploads.js +79 -0
  46. package/esm/src/types/api.d.ts +9 -0
  47. package/esm/src/types/api.js +7 -0
  48. package/esm/src/types/common.d.ts +65 -0
  49. package/esm/src/types/common.js +4 -0
  50. package/esm/src/types/generated.d.ts +731 -0
  51. package/esm/src/types/generated.js +7 -0
  52. package/esm/src/utils/pagination.d.ts +45 -0
  53. package/esm/src/utils/pagination.js +112 -0
  54. package/esm/src/utils/transformers.d.ts +30 -0
  55. package/esm/src/utils/transformers.js +189 -0
  56. package/esm/src/utils/validators.d.ts +53 -0
  57. package/esm/src/utils/validators.js +84 -0
  58. package/package.json +40 -0
  59. package/script/_dnt.shims.d.ts +2 -0
  60. package/script/_dnt.shims.js +60 -0
  61. package/script/deps/jsr.io/@cross/runtime/1.2.1/mod.d.ts +126 -0
  62. package/script/deps/jsr.io/@cross/runtime/1.2.1/mod.js +526 -0
  63. package/script/mod.d.ts +27 -0
  64. package/script/mod.js +73 -0
  65. package/script/package.json +3 -0
  66. package/script/src/auth/oauth.d.ts +68 -0
  67. package/script/src/auth/oauth.js +211 -0
  68. package/script/src/auth/scopes.d.ts +52 -0
  69. package/script/src/auth/scopes.js +79 -0
  70. package/script/src/auth/token-store.d.ts +57 -0
  71. package/script/src/auth/token-store.js +182 -0
  72. package/script/src/client.d.ts +98 -0
  73. package/script/src/client.js +239 -0
  74. package/script/src/errors.d.ts +52 -0
  75. package/script/src/errors.js +111 -0
  76. package/script/src/http/deduplication.d.ts +33 -0
  77. package/script/src/http/deduplication.js +100 -0
  78. package/script/src/http/rate-limiter.d.ts +47 -0
  79. package/script/src/http/rate-limiter.js +172 -0
  80. package/script/src/http/request.d.ts +24 -0
  81. package/script/src/http/request.js +161 -0
  82. package/script/src/http/retry.d.ts +9 -0
  83. package/script/src/http/retry.js +64 -0
  84. package/script/src/resources/activities.d.ts +149 -0
  85. package/script/src/resources/activities.js +193 -0
  86. package/script/src/resources/athletes.d.ts +37 -0
  87. package/script/src/resources/athletes.js +89 -0
  88. package/script/src/resources/clubs.d.ts +45 -0
  89. package/script/src/resources/clubs.js +75 -0
  90. package/script/src/resources/gears.d.ts +17 -0
  91. package/script/src/resources/gears.js +31 -0
  92. package/script/src/resources/routes.d.ts +33 -0
  93. package/script/src/resources/routes.js +75 -0
  94. package/script/src/resources/segment-efforts.d.ts +38 -0
  95. package/script/src/resources/segment-efforts.js +57 -0
  96. package/script/src/resources/segments.d.ts +42 -0
  97. package/script/src/resources/segments.js +71 -0
  98. package/script/src/resources/streams.d.ts +44 -0
  99. package/script/src/resources/streams.js +79 -0
  100. package/script/src/resources/uploads.d.ts +41 -0
  101. package/script/src/resources/uploads.js +83 -0
  102. package/script/src/types/api.d.ts +9 -0
  103. package/script/src/types/api.js +23 -0
  104. package/script/src/types/common.d.ts +65 -0
  105. package/script/src/types/common.js +5 -0
  106. package/script/src/types/generated.d.ts +731 -0
  107. package/script/src/types/generated.js +8 -0
  108. package/script/src/utils/pagination.d.ts +45 -0
  109. package/script/src/utils/pagination.js +118 -0
  110. package/script/src/utils/transformers.d.ts +30 -0
  111. package/script/src/utils/transformers.js +196 -0
  112. package/script/src/utils/validators.d.ts +53 -0
  113. package/script/src/utils/validators.js +92 -0
package/script/mod.js ADDED
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ /**
3
+ * @pinta365/strava - TypeScript client for Strava API v3
4
+ *
5
+ * A cross-runtime (Deno, Node.js, Bun, Browser) library for interacting with the Strava API.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.validateRange = exports.validatePositiveInteger = exports.validatePagination = exports.validateNonNegativeInteger = exports.validateNonEmptyString = exports.validateDate = exports.transformDates = exports.flattenResponses = exports.applyTransformations = exports.addComputedFields = exports.PaginatedIterator = exports.listAll = exports.buildPaginationQuery = exports.StreamsResource = exports.UploadsResource = exports.RoutesResource = exports.GearsResource = exports.ClubsResource = exports.SegmentEffortsResource = exports.SegmentsResource = exports.ActivitiesResource = exports.AthletesResource = exports.MemoryTokenStore = exports.LocalStorageTokenStore = exports.getDefaultTokenStore = exports.FileSystemTokenStore = exports.validateScopes = exports.StravaScope = exports.parseScopes = exports.hasScope = exports.hasAllScopes = exports.formatScopes = exports.refreshAccessToken = exports.OAuthManager = exports.getAuthorizationUrl = exports.exchangeCode = exports.StravaValidationError = exports.StravaServerError = exports.StravaRateLimitError = exports.StravaNotFoundError = exports.StravaError = exports.StravaAuthError = exports.StravaClient = void 0;
9
+ // Main client
10
+ var client_js_1 = require("./src/client.js");
11
+ Object.defineProperty(exports, "StravaClient", { enumerable: true, get: function () { return client_js_1.StravaClient; } });
12
+ // Error classes
13
+ var errors_js_1 = require("./src/errors.js");
14
+ Object.defineProperty(exports, "StravaAuthError", { enumerable: true, get: function () { return errors_js_1.StravaAuthError; } });
15
+ Object.defineProperty(exports, "StravaError", { enumerable: true, get: function () { return errors_js_1.StravaError; } });
16
+ Object.defineProperty(exports, "StravaNotFoundError", { enumerable: true, get: function () { return errors_js_1.StravaNotFoundError; } });
17
+ Object.defineProperty(exports, "StravaRateLimitError", { enumerable: true, get: function () { return errors_js_1.StravaRateLimitError; } });
18
+ Object.defineProperty(exports, "StravaServerError", { enumerable: true, get: function () { return errors_js_1.StravaServerError; } });
19
+ Object.defineProperty(exports, "StravaValidationError", { enumerable: true, get: function () { return errors_js_1.StravaValidationError; } });
20
+ // Auth
21
+ var oauth_js_1 = require("./src/auth/oauth.js");
22
+ Object.defineProperty(exports, "exchangeCode", { enumerable: true, get: function () { return oauth_js_1.exchangeCode; } });
23
+ Object.defineProperty(exports, "getAuthorizationUrl", { enumerable: true, get: function () { return oauth_js_1.getAuthorizationUrl; } });
24
+ Object.defineProperty(exports, "OAuthManager", { enumerable: true, get: function () { return oauth_js_1.OAuthManager; } });
25
+ Object.defineProperty(exports, "refreshAccessToken", { enumerable: true, get: function () { return oauth_js_1.refreshAccessToken; } });
26
+ var scopes_js_1 = require("./src/auth/scopes.js");
27
+ Object.defineProperty(exports, "formatScopes", { enumerable: true, get: function () { return scopes_js_1.formatScopes; } });
28
+ Object.defineProperty(exports, "hasAllScopes", { enumerable: true, get: function () { return scopes_js_1.hasAllScopes; } });
29
+ Object.defineProperty(exports, "hasScope", { enumerable: true, get: function () { return scopes_js_1.hasScope; } });
30
+ Object.defineProperty(exports, "parseScopes", { enumerable: true, get: function () { return scopes_js_1.parseScopes; } });
31
+ Object.defineProperty(exports, "StravaScope", { enumerable: true, get: function () { return scopes_js_1.StravaScope; } });
32
+ Object.defineProperty(exports, "validateScopes", { enumerable: true, get: function () { return scopes_js_1.validateScopes; } });
33
+ var token_store_js_1 = require("./src/auth/token-store.js");
34
+ Object.defineProperty(exports, "FileSystemTokenStore", { enumerable: true, get: function () { return token_store_js_1.FileSystemTokenStore; } });
35
+ Object.defineProperty(exports, "getDefaultTokenStore", { enumerable: true, get: function () { return token_store_js_1.getDefaultTokenStore; } });
36
+ Object.defineProperty(exports, "LocalStorageTokenStore", { enumerable: true, get: function () { return token_store_js_1.LocalStorageTokenStore; } });
37
+ Object.defineProperty(exports, "MemoryTokenStore", { enumerable: true, get: function () { return token_store_js_1.MemoryTokenStore; } });
38
+ // Resources (for advanced usage)
39
+ var athletes_js_1 = require("./src/resources/athletes.js");
40
+ Object.defineProperty(exports, "AthletesResource", { enumerable: true, get: function () { return athletes_js_1.AthletesResource; } });
41
+ var activities_js_1 = require("./src/resources/activities.js");
42
+ Object.defineProperty(exports, "ActivitiesResource", { enumerable: true, get: function () { return activities_js_1.ActivitiesResource; } });
43
+ var segments_js_1 = require("./src/resources/segments.js");
44
+ Object.defineProperty(exports, "SegmentsResource", { enumerable: true, get: function () { return segments_js_1.SegmentsResource; } });
45
+ var segment_efforts_js_1 = require("./src/resources/segment-efforts.js");
46
+ Object.defineProperty(exports, "SegmentEffortsResource", { enumerable: true, get: function () { return segment_efforts_js_1.SegmentEffortsResource; } });
47
+ var clubs_js_1 = require("./src/resources/clubs.js");
48
+ Object.defineProperty(exports, "ClubsResource", { enumerable: true, get: function () { return clubs_js_1.ClubsResource; } });
49
+ var gears_js_1 = require("./src/resources/gears.js");
50
+ Object.defineProperty(exports, "GearsResource", { enumerable: true, get: function () { return gears_js_1.GearsResource; } });
51
+ var routes_js_1 = require("./src/resources/routes.js");
52
+ Object.defineProperty(exports, "RoutesResource", { enumerable: true, get: function () { return routes_js_1.RoutesResource; } });
53
+ var uploads_js_1 = require("./src/resources/uploads.js");
54
+ Object.defineProperty(exports, "UploadsResource", { enumerable: true, get: function () { return uploads_js_1.UploadsResource; } });
55
+ var streams_js_1 = require("./src/resources/streams.js");
56
+ Object.defineProperty(exports, "StreamsResource", { enumerable: true, get: function () { return streams_js_1.StreamsResource; } });
57
+ // Utilities
58
+ var pagination_js_1 = require("./src/utils/pagination.js");
59
+ Object.defineProperty(exports, "buildPaginationQuery", { enumerable: true, get: function () { return pagination_js_1.buildPaginationQuery; } });
60
+ Object.defineProperty(exports, "listAll", { enumerable: true, get: function () { return pagination_js_1.listAll; } });
61
+ Object.defineProperty(exports, "PaginatedIterator", { enumerable: true, get: function () { return pagination_js_1.PaginatedIterator; } });
62
+ var transformers_js_1 = require("./src/utils/transformers.js");
63
+ Object.defineProperty(exports, "addComputedFields", { enumerable: true, get: function () { return transformers_js_1.addComputedFields; } });
64
+ Object.defineProperty(exports, "applyTransformations", { enumerable: true, get: function () { return transformers_js_1.applyTransformations; } });
65
+ Object.defineProperty(exports, "flattenResponses", { enumerable: true, get: function () { return transformers_js_1.flattenResponses; } });
66
+ Object.defineProperty(exports, "transformDates", { enumerable: true, get: function () { return transformers_js_1.transformDates; } });
67
+ var validators_js_1 = require("./src/utils/validators.js");
68
+ Object.defineProperty(exports, "validateDate", { enumerable: true, get: function () { return validators_js_1.validateDate; } });
69
+ Object.defineProperty(exports, "validateNonEmptyString", { enumerable: true, get: function () { return validators_js_1.validateNonEmptyString; } });
70
+ Object.defineProperty(exports, "validateNonNegativeInteger", { enumerable: true, get: function () { return validators_js_1.validateNonNegativeInteger; } });
71
+ Object.defineProperty(exports, "validatePagination", { enumerable: true, get: function () { return validators_js_1.validatePagination; } });
72
+ Object.defineProperty(exports, "validatePositiveInteger", { enumerable: true, get: function () { return validators_js_1.validatePositiveInteger; } });
73
+ Object.defineProperty(exports, "validateRange", { enumerable: true, get: function () { return validators_js_1.validateRange; } });
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * OAuth 2.0 authentication flow for Strava API
3
+ */
4
+ import type { TokenData, TokenStore } from "./token-store.js";
5
+ import { type StravaScope } from "./scopes.js";
6
+ interface AuthorizationUrlOptions {
7
+ clientId: string;
8
+ redirectUri: string;
9
+ scope: StravaScope[];
10
+ state?: string;
11
+ approvalPrompt?: "force" | "auto";
12
+ }
13
+ /**
14
+ * Generate authorization URL
15
+ */
16
+ export declare function getAuthorizationUrl(options: AuthorizationUrlOptions): string;
17
+ /**
18
+ * Exchange authorization code for tokens
19
+ * @param code - Authorization code from OAuth callback
20
+ * @param clientId - Strava client ID
21
+ * @param clientSecret - Strava client secret
22
+ * @param redirectUri - Redirect URI used in authorization (optional)
23
+ * @returns Token data
24
+ */
25
+ export declare function exchangeCode(code: string, clientId: string, clientSecret: string, redirectUri?: string): Promise<TokenData>;
26
+ /**
27
+ * Refresh access token using refresh token
28
+ */
29
+ export declare function refreshAccessToken(refreshToken: string, clientId: string, clientSecret: string): Promise<TokenData>;
30
+ /**
31
+ * Check if token is expired or about to expire
32
+ */
33
+ export declare function isTokenExpired(token: TokenData, bufferSeconds?: number): boolean;
34
+ /**
35
+ * OAuth manager for handling authentication and token refresh
36
+ */
37
+ export declare class OAuthManager {
38
+ private tokenStore;
39
+ private clientId;
40
+ private clientSecret;
41
+ constructor(clientId: string, clientSecret: string, tokenStore: TokenStore);
42
+ /**
43
+ * Get authorization URL
44
+ */
45
+ getAuthorizationUrl(options: Omit<AuthorizationUrlOptions, "clientId">): string;
46
+ /**
47
+ * Exchange code and store tokens
48
+ */
49
+ authenticate(code: string, redirectUri?: string): Promise<TokenData>;
50
+ /**
51
+ * Get current token, refreshing if needed
52
+ */
53
+ getToken(): Promise<TokenData | null>;
54
+ /**
55
+ * Manually refresh token
56
+ */
57
+ refreshToken(): Promise<TokenData>;
58
+ /**
59
+ * Get current scopes
60
+ */
61
+ getScopes(): Promise<StravaScope[]>;
62
+ /**
63
+ * Clear stored tokens
64
+ */
65
+ clearTokens(): Promise<void>;
66
+ }
67
+ export {};
68
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth 2.0 authentication flow for Strava API
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.OAuthManager = void 0;
7
+ exports.getAuthorizationUrl = getAuthorizationUrl;
8
+ exports.exchangeCode = exchangeCode;
9
+ exports.refreshAccessToken = refreshAccessToken;
10
+ exports.isTokenExpired = isTokenExpired;
11
+ const errors_js_1 = require("../errors.js");
12
+ const scopes_js_1 = require("./scopes.js");
13
+ const OAUTH_BASE_URL = "https://www.strava.com/api/v3/oauth";
14
+ /**
15
+ * Generate authorization URL
16
+ */
17
+ function getAuthorizationUrl(options) {
18
+ const { clientId, redirectUri, scope, state, approvalPrompt = "auto" } = options;
19
+ const params = new URLSearchParams({
20
+ client_id: clientId,
21
+ redirect_uri: redirectUri,
22
+ response_type: "code",
23
+ scope: (0, scopes_js_1.formatScopes)(scope),
24
+ approval_prompt: approvalPrompt,
25
+ });
26
+ if (state) {
27
+ params.append("state", state);
28
+ }
29
+ return `${OAUTH_BASE_URL}/authorize?${params.toString()}`;
30
+ }
31
+ /**
32
+ * Exchange authorization code for tokens
33
+ * @param code - Authorization code from OAuth callback
34
+ * @param clientId - Strava client ID
35
+ * @param clientSecret - Strava client secret
36
+ * @param redirectUri - Redirect URI used in authorization (optional)
37
+ * @returns Token data
38
+ */
39
+ async function exchangeCode(code, clientId, clientSecret, redirectUri) {
40
+ const params = new URLSearchParams({
41
+ client_id: clientId,
42
+ client_secret: clientSecret,
43
+ code,
44
+ grant_type: "authorization_code",
45
+ });
46
+ if (redirectUri) {
47
+ params.append("redirect_uri", redirectUri);
48
+ }
49
+ const response = await fetch(`${OAUTH_BASE_URL}/token`, {
50
+ method: "POST",
51
+ headers: {
52
+ "Content-Type": "application/x-www-form-urlencoded",
53
+ },
54
+ body: params.toString(),
55
+ });
56
+ if (!response.ok) {
57
+ const error = await response.json().catch(() => ({ message: response.statusText }));
58
+ throw new errors_js_1.StravaAuthError(`Failed to exchange code: ${error.message || response.statusText}`, response.status, error);
59
+ }
60
+ const data = await response.json();
61
+ return {
62
+ accessToken: data.access_token,
63
+ refreshToken: data.refresh_token,
64
+ expiresAt: data.expires_at,
65
+ tokenType: data.token_type,
66
+ athleteId: data.athlete?.id,
67
+ };
68
+ }
69
+ /**
70
+ * Refresh access token using refresh token
71
+ */
72
+ async function refreshAccessToken(refreshToken, clientId, clientSecret) {
73
+ const params = new URLSearchParams({
74
+ client_id: clientId,
75
+ client_secret: clientSecret,
76
+ refresh_token: refreshToken,
77
+ grant_type: "refresh_token",
78
+ });
79
+ const response = await fetch(`${OAUTH_BASE_URL}/token`, {
80
+ method: "POST",
81
+ headers: {
82
+ "Content-Type": "application/x-www-form-urlencoded",
83
+ },
84
+ body: params.toString(),
85
+ });
86
+ if (!response.ok) {
87
+ const error = await response.json().catch(() => ({ message: response.statusText }));
88
+ throw new errors_js_1.StravaAuthError(`Failed to refresh token: ${error.message || response.statusText}`, response.status, error);
89
+ }
90
+ const data = await response.json();
91
+ return {
92
+ accessToken: data.access_token,
93
+ refreshToken: data.refresh_token,
94
+ expiresAt: data.expires_at,
95
+ tokenType: data.token_type,
96
+ athleteId: data.athlete?.id,
97
+ };
98
+ }
99
+ /**
100
+ * Check if token is expired or about to expire
101
+ */
102
+ function isTokenExpired(token, bufferSeconds = 300) {
103
+ const now = Math.floor(Date.now() / 1000);
104
+ return token.expiresAt <= (now + bufferSeconds);
105
+ }
106
+ /**
107
+ * OAuth manager for handling authentication and token refresh
108
+ */
109
+ class OAuthManager {
110
+ constructor(clientId, clientSecret, tokenStore) {
111
+ Object.defineProperty(this, "tokenStore", {
112
+ enumerable: true,
113
+ configurable: true,
114
+ writable: true,
115
+ value: void 0
116
+ });
117
+ Object.defineProperty(this, "clientId", {
118
+ enumerable: true,
119
+ configurable: true,
120
+ writable: true,
121
+ value: void 0
122
+ });
123
+ Object.defineProperty(this, "clientSecret", {
124
+ enumerable: true,
125
+ configurable: true,
126
+ writable: true,
127
+ value: void 0
128
+ });
129
+ this.clientId = clientId;
130
+ this.clientSecret = clientSecret;
131
+ this.tokenStore = tokenStore;
132
+ }
133
+ /**
134
+ * Get authorization URL
135
+ */
136
+ getAuthorizationUrl(options) {
137
+ return getAuthorizationUrl({
138
+ ...options,
139
+ clientId: this.clientId,
140
+ });
141
+ }
142
+ /**
143
+ * Exchange code and store tokens
144
+ */
145
+ async authenticate(code, redirectUri) {
146
+ const token = await exchangeCode(code, this.clientId, this.clientSecret, redirectUri);
147
+ await this.tokenStore.set(token);
148
+ return token;
149
+ }
150
+ /**
151
+ * Get current token, refreshing if needed
152
+ */
153
+ async getToken() {
154
+ const token = await this.tokenStore.get();
155
+ if (!token) {
156
+ return null;
157
+ }
158
+ // Refresh if expired or about to expire
159
+ if (isTokenExpired(token)) {
160
+ try {
161
+ const newToken = await refreshAccessToken(token.refreshToken, this.clientId, this.clientSecret);
162
+ const refreshedToken = {
163
+ ...newToken,
164
+ scope: token.scope,
165
+ athleteId: token.athleteId || newToken.athleteId,
166
+ };
167
+ await this.tokenStore.set(refreshedToken);
168
+ return refreshedToken;
169
+ }
170
+ catch (error) {
171
+ await this.tokenStore.clear();
172
+ throw error;
173
+ }
174
+ }
175
+ return token;
176
+ }
177
+ /**
178
+ * Manually refresh token
179
+ */
180
+ async refreshToken() {
181
+ const token = await this.tokenStore.get();
182
+ if (!token) {
183
+ throw new errors_js_1.StravaAuthError("No token available to refresh");
184
+ }
185
+ const newToken = await refreshAccessToken(token.refreshToken, this.clientId, this.clientSecret);
186
+ const refreshedToken = {
187
+ ...newToken,
188
+ scope: token.scope,
189
+ athleteId: token.athleteId || newToken.athleteId,
190
+ };
191
+ await this.tokenStore.set(refreshedToken);
192
+ return refreshedToken;
193
+ }
194
+ /**
195
+ * Get current scopes
196
+ */
197
+ async getScopes() {
198
+ const token = await this.tokenStore.get();
199
+ if (!token || !token.scope) {
200
+ return [];
201
+ }
202
+ return (0, scopes_js_1.parseScopes)(token.scope);
203
+ }
204
+ /**
205
+ * Clear stored tokens
206
+ */
207
+ async clearTokens() {
208
+ await this.tokenStore.clear();
209
+ }
210
+ }
211
+ exports.OAuthManager = OAuthManager;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * OAuth 2.0 scope definitions for Strava API
3
+ */
4
+ /**
5
+ * Available OAuth scopes
6
+ */
7
+ export declare enum StravaScope {
8
+ Read = "read",
9
+ ReadAll = "read_all",
10
+ ProfileReadAll = "profile:read_all",
11
+ ProfileWrite = "profile:write",
12
+ ActivityRead = "activity:read",
13
+ ActivityReadAll = "activity:read_all",
14
+ ActivityWrite = "activity:write"
15
+ }
16
+ /**
17
+ * Scope descriptions
18
+ */
19
+ export declare const SCOPE_DESCRIPTIONS: Record<StravaScope, string>;
20
+ /**
21
+ * Parse scope string into array
22
+ * @param scopeString - Comma-separated scope string
23
+ * @returns Array of scope enums
24
+ */
25
+ export declare function parseScopes(scopeString: string): StravaScope[];
26
+ /**
27
+ * Format scopes array into string
28
+ * @param scopes - Array of scope enums
29
+ * @returns Comma-separated scope string
30
+ */
31
+ export declare function formatScopes(scopes: StravaScope[]): string;
32
+ /**
33
+ * Check if a scope is included in the provided scopes
34
+ * @param required - Required scope
35
+ * @param available - Available scopes
36
+ * @returns True if the required scope is available
37
+ */
38
+ export declare function hasScope(required: StravaScope, available: StravaScope[]): boolean;
39
+ /**
40
+ * Check if all required scopes are available
41
+ * @param required - Required scopes
42
+ * @param available - Available scopes
43
+ * @returns True if all required scopes are available
44
+ */
45
+ export declare function hasAllScopes(required: StravaScope[], available: StravaScope[]): boolean;
46
+ /**
47
+ * Validate scopes
48
+ * @param scopes - Scopes to validate
49
+ * @returns True if all scopes are valid
50
+ */
51
+ export declare function validateScopes(scopes: StravaScope[]): boolean;
52
+ //# sourceMappingURL=scopes.d.ts.map
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ /**
3
+ * OAuth 2.0 scope definitions for Strava API
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SCOPE_DESCRIPTIONS = exports.StravaScope = void 0;
7
+ exports.parseScopes = parseScopes;
8
+ exports.formatScopes = formatScopes;
9
+ exports.hasScope = hasScope;
10
+ exports.hasAllScopes = hasAllScopes;
11
+ exports.validateScopes = validateScopes;
12
+ /**
13
+ * Available OAuth scopes
14
+ */
15
+ var StravaScope;
16
+ (function (StravaScope) {
17
+ StravaScope["Read"] = "read";
18
+ StravaScope["ReadAll"] = "read_all";
19
+ StravaScope["ProfileReadAll"] = "profile:read_all";
20
+ StravaScope["ProfileWrite"] = "profile:write";
21
+ StravaScope["ActivityRead"] = "activity:read";
22
+ StravaScope["ActivityReadAll"] = "activity:read_all";
23
+ StravaScope["ActivityWrite"] = "activity:write";
24
+ })(StravaScope || (exports.StravaScope = StravaScope = {}));
25
+ /**
26
+ * Scope descriptions
27
+ */
28
+ exports.SCOPE_DESCRIPTIONS = {
29
+ [StravaScope.Read]: "Read public segments, public routes, public profile data, public posts, public events, club feeds, and leaderboards",
30
+ [StravaScope.ReadAll]: "Read private routes, private segments, and private events for the user",
31
+ [StravaScope.ProfileReadAll]: "Read all profile information even if the user has set their profile visibility to Followers or Only You",
32
+ [StravaScope.ProfileWrite]: "Update the user's weight and Functional Threshold Power (FTP), and access to star or unstar segments on their behalf",
33
+ [StravaScope.ActivityRead]: "Read the user's activity data for activities that are visible to Everyone and Followers, excluding privacy zone data",
34
+ [StravaScope.ActivityReadAll]: "The same access as activity:read, plus privacy zone data and access to read the user's activities with visibility set to Only You",
35
+ [StravaScope.ActivityWrite]: "Access to create manual activities and uploads, and access to edit any activities that are visible to the app, based on activity read access level",
36
+ };
37
+ /**
38
+ * Parse scope string into array
39
+ * @param scopeString - Comma-separated scope string
40
+ * @returns Array of scope enums
41
+ */
42
+ function parseScopes(scopeString) {
43
+ return scopeString.split(",").map((s) => s.trim()).filter(Boolean);
44
+ }
45
+ /**
46
+ * Format scopes array into string
47
+ * @param scopes - Array of scope enums
48
+ * @returns Comma-separated scope string
49
+ */
50
+ function formatScopes(scopes) {
51
+ return scopes.join(",");
52
+ }
53
+ /**
54
+ * Check if a scope is included in the provided scopes
55
+ * @param required - Required scope
56
+ * @param available - Available scopes
57
+ * @returns True if the required scope is available
58
+ */
59
+ function hasScope(required, available) {
60
+ return available.includes(required);
61
+ }
62
+ /**
63
+ * Check if all required scopes are available
64
+ * @param required - Required scopes
65
+ * @param available - Available scopes
66
+ * @returns True if all required scopes are available
67
+ */
68
+ function hasAllScopes(required, available) {
69
+ return required.every((scope) => available.includes(scope));
70
+ }
71
+ /**
72
+ * Validate scopes
73
+ * @param scopes - Scopes to validate
74
+ * @returns True if all scopes are valid
75
+ */
76
+ function validateScopes(scopes) {
77
+ const validScopes = Object.values(StravaScope);
78
+ return scopes.every((scope) => validScopes.includes(scope));
79
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Token storage interface and implementations
3
+ */
4
+ /**
5
+ * Token data structure
6
+ */
7
+ export interface TokenData {
8
+ accessToken: string;
9
+ refreshToken: string;
10
+ expiresAt: number;
11
+ tokenType: string;
12
+ scope?: string;
13
+ athleteId?: number;
14
+ }
15
+ /**
16
+ * Token storage interface
17
+ */
18
+ export interface TokenStore {
19
+ get(): Promise<TokenData | null>;
20
+ set(token: TokenData): Promise<void>;
21
+ clear(): Promise<void>;
22
+ }
23
+ /**
24
+ * In-memory token store (default)
25
+ */
26
+ export declare class MemoryTokenStore implements TokenStore {
27
+ private token;
28
+ get(): Promise<TokenData | null>;
29
+ set(token: TokenData): Promise<void>;
30
+ clear(): Promise<void>;
31
+ }
32
+ /**
33
+ * Browser localStorage token store
34
+ */
35
+ export declare class LocalStorageTokenStore implements TokenStore {
36
+ private readonly key;
37
+ constructor(key?: string);
38
+ get(): Promise<TokenData | null>;
39
+ set(token: TokenData): Promise<void>;
40
+ clear(): Promise<void>;
41
+ }
42
+ /**
43
+ * File system token store (Node.js/Deno)
44
+ */
45
+ export declare class FileSystemTokenStore implements TokenStore {
46
+ private readonly path;
47
+ constructor(path?: string);
48
+ get(): Promise<TokenData | null>;
49
+ set(token: TokenData): Promise<void>;
50
+ clear(): Promise<void>;
51
+ }
52
+ /**
53
+ * Get default token store based on runtime environment
54
+ * @returns TokenStore appropriate for the current runtime (browser, Node.js, Deno, Bun)
55
+ */
56
+ export declare function getDefaultTokenStore(): TokenStore;
57
+ //# sourceMappingURL=token-store.d.ts.map