@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.
- package/LICENSE +21 -0
- package/README.md +390 -0
- package/esm/_dnt.shims.d.ts +2 -0
- package/esm/_dnt.shims.js +57 -0
- package/esm/deps/jsr.io/@cross/runtime/1.2.1/mod.d.ts +126 -0
- package/esm/deps/jsr.io/@cross/runtime/1.2.1/mod.js +480 -0
- package/esm/mod.d.ts +27 -0
- package/esm/mod.js +27 -0
- package/esm/package.json +3 -0
- package/esm/src/auth/oauth.d.ts +68 -0
- package/esm/src/auth/oauth.js +203 -0
- package/esm/src/auth/scopes.d.ts +52 -0
- package/esm/src/auth/scopes.js +71 -0
- package/esm/src/auth/token-store.d.ts +57 -0
- package/esm/src/auth/token-store.js +142 -0
- package/esm/src/client.d.ts +98 -0
- package/esm/src/client.js +235 -0
- package/esm/src/errors.d.ts +52 -0
- package/esm/src/errors.js +102 -0
- package/esm/src/http/deduplication.d.ts +33 -0
- package/esm/src/http/deduplication.js +96 -0
- package/esm/src/http/rate-limiter.d.ts +47 -0
- package/esm/src/http/rate-limiter.js +168 -0
- package/esm/src/http/request.d.ts +24 -0
- package/esm/src/http/request.js +158 -0
- package/esm/src/http/retry.d.ts +9 -0
- package/esm/src/http/retry.js +61 -0
- package/esm/src/resources/activities.d.ts +149 -0
- package/esm/src/resources/activities.js +189 -0
- package/esm/src/resources/athletes.d.ts +37 -0
- package/esm/src/resources/athletes.js +85 -0
- package/esm/src/resources/clubs.d.ts +45 -0
- package/esm/src/resources/clubs.js +71 -0
- package/esm/src/resources/gears.d.ts +17 -0
- package/esm/src/resources/gears.js +27 -0
- package/esm/src/resources/routes.d.ts +33 -0
- package/esm/src/resources/routes.js +71 -0
- package/esm/src/resources/segment-efforts.d.ts +38 -0
- package/esm/src/resources/segment-efforts.js +53 -0
- package/esm/src/resources/segments.d.ts +42 -0
- package/esm/src/resources/segments.js +67 -0
- package/esm/src/resources/streams.d.ts +44 -0
- package/esm/src/resources/streams.js +75 -0
- package/esm/src/resources/uploads.d.ts +41 -0
- package/esm/src/resources/uploads.js +79 -0
- package/esm/src/types/api.d.ts +9 -0
- package/esm/src/types/api.js +7 -0
- package/esm/src/types/common.d.ts +65 -0
- package/esm/src/types/common.js +4 -0
- package/esm/src/types/generated.d.ts +731 -0
- package/esm/src/types/generated.js +7 -0
- package/esm/src/utils/pagination.d.ts +45 -0
- package/esm/src/utils/pagination.js +112 -0
- package/esm/src/utils/transformers.d.ts +30 -0
- package/esm/src/utils/transformers.js +189 -0
- package/esm/src/utils/validators.d.ts +53 -0
- package/esm/src/utils/validators.js +84 -0
- package/package.json +40 -0
- package/script/_dnt.shims.d.ts +2 -0
- package/script/_dnt.shims.js +60 -0
- package/script/deps/jsr.io/@cross/runtime/1.2.1/mod.d.ts +126 -0
- package/script/deps/jsr.io/@cross/runtime/1.2.1/mod.js +526 -0
- package/script/mod.d.ts +27 -0
- package/script/mod.js +73 -0
- package/script/package.json +3 -0
- package/script/src/auth/oauth.d.ts +68 -0
- package/script/src/auth/oauth.js +211 -0
- package/script/src/auth/scopes.d.ts +52 -0
- package/script/src/auth/scopes.js +79 -0
- package/script/src/auth/token-store.d.ts +57 -0
- package/script/src/auth/token-store.js +182 -0
- package/script/src/client.d.ts +98 -0
- package/script/src/client.js +239 -0
- package/script/src/errors.d.ts +52 -0
- package/script/src/errors.js +111 -0
- package/script/src/http/deduplication.d.ts +33 -0
- package/script/src/http/deduplication.js +100 -0
- package/script/src/http/rate-limiter.d.ts +47 -0
- package/script/src/http/rate-limiter.js +172 -0
- package/script/src/http/request.d.ts +24 -0
- package/script/src/http/request.js +161 -0
- package/script/src/http/retry.d.ts +9 -0
- package/script/src/http/retry.js +64 -0
- package/script/src/resources/activities.d.ts +149 -0
- package/script/src/resources/activities.js +193 -0
- package/script/src/resources/athletes.d.ts +37 -0
- package/script/src/resources/athletes.js +89 -0
- package/script/src/resources/clubs.d.ts +45 -0
- package/script/src/resources/clubs.js +75 -0
- package/script/src/resources/gears.d.ts +17 -0
- package/script/src/resources/gears.js +31 -0
- package/script/src/resources/routes.d.ts +33 -0
- package/script/src/resources/routes.js +75 -0
- package/script/src/resources/segment-efforts.d.ts +38 -0
- package/script/src/resources/segment-efforts.js +57 -0
- package/script/src/resources/segments.d.ts +42 -0
- package/script/src/resources/segments.js +71 -0
- package/script/src/resources/streams.d.ts +44 -0
- package/script/src/resources/streams.js +79 -0
- package/script/src/resources/uploads.d.ts +41 -0
- package/script/src/resources/uploads.js +83 -0
- package/script/src/types/api.d.ts +9 -0
- package/script/src/types/api.js +23 -0
- package/script/src/types/common.d.ts +65 -0
- package/script/src/types/common.js +5 -0
- package/script/src/types/generated.d.ts +731 -0
- package/script/src/types/generated.js +8 -0
- package/script/src/utils/pagination.d.ts +45 -0
- package/script/src/utils/pagination.js +118 -0
- package/script/src/utils/transformers.d.ts +30 -0
- package/script/src/utils/transformers.js +196 -0
- package/script/src/utils/validators.d.ts +53 -0
- package/script/src/utils/validators.js +92 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Token storage interface and implementations
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
22
|
+
var ownKeys = function(o) {
|
|
23
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
24
|
+
var ar = [];
|
|
25
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
26
|
+
return ar;
|
|
27
|
+
};
|
|
28
|
+
return ownKeys(o);
|
|
29
|
+
};
|
|
30
|
+
return function (mod) {
|
|
31
|
+
if (mod && mod.__esModule) return mod;
|
|
32
|
+
var result = {};
|
|
33
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
34
|
+
__setModuleDefault(result, mod);
|
|
35
|
+
return result;
|
|
36
|
+
};
|
|
37
|
+
})();
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.FileSystemTokenStore = exports.LocalStorageTokenStore = exports.MemoryTokenStore = void 0;
|
|
40
|
+
exports.getDefaultTokenStore = getDefaultTokenStore;
|
|
41
|
+
const mod_js_1 = require("../../deps/jsr.io/@cross/runtime/1.2.1/mod.js");
|
|
42
|
+
/**
|
|
43
|
+
* In-memory token store (default)
|
|
44
|
+
*/
|
|
45
|
+
class MemoryTokenStore {
|
|
46
|
+
constructor() {
|
|
47
|
+
Object.defineProperty(this, "token", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
configurable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
value: null
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
get() {
|
|
55
|
+
return Promise.resolve(this.token);
|
|
56
|
+
}
|
|
57
|
+
set(token) {
|
|
58
|
+
this.token = token;
|
|
59
|
+
return Promise.resolve();
|
|
60
|
+
}
|
|
61
|
+
clear() {
|
|
62
|
+
this.token = null;
|
|
63
|
+
return Promise.resolve();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.MemoryTokenStore = MemoryTokenStore;
|
|
67
|
+
/**
|
|
68
|
+
* Browser localStorage token store
|
|
69
|
+
*/
|
|
70
|
+
class LocalStorageTokenStore {
|
|
71
|
+
constructor(key = "strava_tokens") {
|
|
72
|
+
Object.defineProperty(this, "key", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
configurable: true,
|
|
75
|
+
writable: true,
|
|
76
|
+
value: void 0
|
|
77
|
+
});
|
|
78
|
+
this.key = key;
|
|
79
|
+
}
|
|
80
|
+
get() {
|
|
81
|
+
if (mod_js_1.CurrentRuntime !== mod_js_1.Runtime.Browser) {
|
|
82
|
+
throw new Error("LocalStorageTokenStore can only be used in browser environment");
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const stored = localStorage.getItem(this.key);
|
|
86
|
+
if (!stored)
|
|
87
|
+
return Promise.resolve(null);
|
|
88
|
+
return Promise.resolve(JSON.parse(stored));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return Promise.resolve(null);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
set(token) {
|
|
95
|
+
if (mod_js_1.CurrentRuntime !== mod_js_1.Runtime.Browser) {
|
|
96
|
+
throw new Error("LocalStorageTokenStore can only be used in browser environment");
|
|
97
|
+
}
|
|
98
|
+
localStorage.setItem(this.key, JSON.stringify(token));
|
|
99
|
+
return Promise.resolve();
|
|
100
|
+
}
|
|
101
|
+
clear() {
|
|
102
|
+
if (mod_js_1.CurrentRuntime !== mod_js_1.Runtime.Browser) {
|
|
103
|
+
throw new Error("LocalStorageTokenStore can only be used in browser environment");
|
|
104
|
+
}
|
|
105
|
+
localStorage.removeItem(this.key);
|
|
106
|
+
return Promise.resolve();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.LocalStorageTokenStore = LocalStorageTokenStore;
|
|
110
|
+
/**
|
|
111
|
+
* File system token store (Node.js/Deno)
|
|
112
|
+
*/
|
|
113
|
+
class FileSystemTokenStore {
|
|
114
|
+
constructor(path = "./.strava-tokens.json") {
|
|
115
|
+
Object.defineProperty(this, "path", {
|
|
116
|
+
enumerable: true,
|
|
117
|
+
configurable: true,
|
|
118
|
+
writable: true,
|
|
119
|
+
value: void 0
|
|
120
|
+
});
|
|
121
|
+
this.path = path;
|
|
122
|
+
}
|
|
123
|
+
async get() {
|
|
124
|
+
try {
|
|
125
|
+
let content;
|
|
126
|
+
if (mod_js_1.CurrentRuntime === mod_js_1.Runtime.Node || mod_js_1.CurrentRuntime === mod_js_1.Runtime.Bun) {
|
|
127
|
+
const { readFile } = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
|
|
128
|
+
content = await readFile(this.path, "utf-8");
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
// Deno
|
|
132
|
+
content = await Deno.readTextFile(this.path);
|
|
133
|
+
}
|
|
134
|
+
return JSON.parse(content);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async set(token) {
|
|
141
|
+
const content = JSON.stringify(token, null, 2);
|
|
142
|
+
if (mod_js_1.CurrentRuntime === mod_js_1.Runtime.Node || mod_js_1.CurrentRuntime === mod_js_1.Runtime.Bun) {
|
|
143
|
+
const { writeFile } = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
|
|
144
|
+
await writeFile(this.path, content, "utf-8");
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
// Deno
|
|
148
|
+
await Deno.writeTextFile(this.path, content);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
async clear() {
|
|
152
|
+
try {
|
|
153
|
+
if (mod_js_1.CurrentRuntime === mod_js_1.Runtime.Node || mod_js_1.CurrentRuntime === mod_js_1.Runtime.Bun) {
|
|
154
|
+
const { unlink } = await Promise.resolve().then(() => __importStar(require("node:fs/promises")));
|
|
155
|
+
await unlink(this.path);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// Deno
|
|
159
|
+
await Deno.remove(this.path);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// File doesn't exist, ignore
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
exports.FileSystemTokenStore = FileSystemTokenStore;
|
|
168
|
+
/**
|
|
169
|
+
* Get default token store based on runtime environment
|
|
170
|
+
* @returns TokenStore appropriate for the current runtime (browser, Node.js, Deno, Bun)
|
|
171
|
+
*/
|
|
172
|
+
function getDefaultTokenStore() {
|
|
173
|
+
if (mod_js_1.CurrentRuntime === mod_js_1.Runtime.Browser) {
|
|
174
|
+
return new LocalStorageTokenStore();
|
|
175
|
+
}
|
|
176
|
+
else if (mod_js_1.CurrentRuntime === mod_js_1.Runtime.Node || mod_js_1.CurrentRuntime === mod_js_1.Runtime.Deno || mod_js_1.CurrentRuntime === mod_js_1.Runtime.Bun) {
|
|
177
|
+
return new FileSystemTokenStore();
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
return new MemoryTokenStore();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main Strava API client
|
|
3
|
+
*/
|
|
4
|
+
import { type TokenStore } from "./auth/token-store.js";
|
|
5
|
+
import type { RateLimitStrategy, RequestConfig, RetryConfig } from "./types/common.js";
|
|
6
|
+
/**
|
|
7
|
+
* Client configuration options
|
|
8
|
+
*/
|
|
9
|
+
export interface ClientOptions {
|
|
10
|
+
clientId: string;
|
|
11
|
+
clientSecret: string;
|
|
12
|
+
redirectUri?: string;
|
|
13
|
+
tokenStore?: TokenStore;
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
retries?: RetryConfig;
|
|
17
|
+
rateLimitStrategy?: RateLimitStrategy;
|
|
18
|
+
deduplicationWindow?: number;
|
|
19
|
+
normalizeKeys?: boolean;
|
|
20
|
+
transformDates?: boolean;
|
|
21
|
+
flattenResponses?: boolean;
|
|
22
|
+
addComputedFields?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Authentication credentials
|
|
26
|
+
*/
|
|
27
|
+
export interface AuthCredentials {
|
|
28
|
+
code: string;
|
|
29
|
+
redirectUri?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Main Strava API client class
|
|
33
|
+
*/
|
|
34
|
+
export declare class StravaClient {
|
|
35
|
+
private readonly options;
|
|
36
|
+
private readonly oauthManager;
|
|
37
|
+
private readonly rateLimiter;
|
|
38
|
+
private readonly deduplicator;
|
|
39
|
+
private _athletes?;
|
|
40
|
+
private _activities?;
|
|
41
|
+
private _segments?;
|
|
42
|
+
private _segmentEfforts?;
|
|
43
|
+
private _clubs?;
|
|
44
|
+
private _gears?;
|
|
45
|
+
private _routes?;
|
|
46
|
+
private _uploads?;
|
|
47
|
+
private _streams?;
|
|
48
|
+
constructor(options: ClientOptions);
|
|
49
|
+
/**
|
|
50
|
+
* Authenticate with authorization code
|
|
51
|
+
*/
|
|
52
|
+
authenticate(credentials: AuthCredentials): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Refresh access token
|
|
55
|
+
*/
|
|
56
|
+
refreshToken(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Get authorization URL
|
|
59
|
+
*/
|
|
60
|
+
getAuthorizationUrl(options: {
|
|
61
|
+
redirectUri?: string;
|
|
62
|
+
scope: string[];
|
|
63
|
+
state?: string;
|
|
64
|
+
approvalPrompt?: "force" | "auto";
|
|
65
|
+
}): string;
|
|
66
|
+
/**
|
|
67
|
+
* Get current access token (for direct fetch calls)
|
|
68
|
+
*/
|
|
69
|
+
getAccessToken(): Promise<string>;
|
|
70
|
+
/**
|
|
71
|
+
* Low-level request method
|
|
72
|
+
*/
|
|
73
|
+
request<T>(config: RequestConfig): Promise<T>;
|
|
74
|
+
get athletes(): AthletesResource;
|
|
75
|
+
get activities(): ActivitiesResource;
|
|
76
|
+
get segments(): SegmentsResource;
|
|
77
|
+
get segmentEfforts(): SegmentEffortsResource;
|
|
78
|
+
get clubs(): ClubsResource;
|
|
79
|
+
get gears(): GearsResource;
|
|
80
|
+
get routes(): RoutesResource;
|
|
81
|
+
get uploads(): UploadsResource;
|
|
82
|
+
get streams(): StreamsResource;
|
|
83
|
+
/**
|
|
84
|
+
* Clean up resources (stop timers, clear caches)
|
|
85
|
+
* Call this when you're done with the client to allow the process to exit
|
|
86
|
+
*/
|
|
87
|
+
destroy(): void;
|
|
88
|
+
}
|
|
89
|
+
import { AthletesResource } from "./resources/athletes.js";
|
|
90
|
+
import { ActivitiesResource } from "./resources/activities.js";
|
|
91
|
+
import { SegmentsResource } from "./resources/segments.js";
|
|
92
|
+
import { SegmentEffortsResource } from "./resources/segment-efforts.js";
|
|
93
|
+
import { ClubsResource } from "./resources/clubs.js";
|
|
94
|
+
import { GearsResource } from "./resources/gears.js";
|
|
95
|
+
import { RoutesResource } from "./resources/routes.js";
|
|
96
|
+
import { UploadsResource } from "./resources/uploads.js";
|
|
97
|
+
import { StreamsResource } from "./resources/streams.js";
|
|
98
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Main Strava API client
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.StravaClient = void 0;
|
|
7
|
+
const request_js_1 = require("./http/request.js");
|
|
8
|
+
const rate_limiter_js_1 = require("./http/rate-limiter.js");
|
|
9
|
+
const deduplication_js_1 = require("./http/deduplication.js");
|
|
10
|
+
const oauth_js_1 = require("./auth/oauth.js");
|
|
11
|
+
const token_store_js_1 = require("./auth/token-store.js");
|
|
12
|
+
/**
|
|
13
|
+
* Main Strava API client class
|
|
14
|
+
*/
|
|
15
|
+
class StravaClient {
|
|
16
|
+
constructor(options) {
|
|
17
|
+
Object.defineProperty(this, "options", {
|
|
18
|
+
enumerable: true,
|
|
19
|
+
configurable: true,
|
|
20
|
+
writable: true,
|
|
21
|
+
value: void 0
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(this, "oauthManager", {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
writable: true,
|
|
27
|
+
value: void 0
|
|
28
|
+
});
|
|
29
|
+
Object.defineProperty(this, "rateLimiter", {
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
writable: true,
|
|
33
|
+
value: void 0
|
|
34
|
+
});
|
|
35
|
+
Object.defineProperty(this, "deduplicator", {
|
|
36
|
+
enumerable: true,
|
|
37
|
+
configurable: true,
|
|
38
|
+
writable: true,
|
|
39
|
+
value: void 0
|
|
40
|
+
});
|
|
41
|
+
Object.defineProperty(this, "_athletes", {
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true,
|
|
45
|
+
value: void 0
|
|
46
|
+
});
|
|
47
|
+
Object.defineProperty(this, "_activities", {
|
|
48
|
+
enumerable: true,
|
|
49
|
+
configurable: true,
|
|
50
|
+
writable: true,
|
|
51
|
+
value: void 0
|
|
52
|
+
});
|
|
53
|
+
Object.defineProperty(this, "_segments", {
|
|
54
|
+
enumerable: true,
|
|
55
|
+
configurable: true,
|
|
56
|
+
writable: true,
|
|
57
|
+
value: void 0
|
|
58
|
+
});
|
|
59
|
+
Object.defineProperty(this, "_segmentEfforts", {
|
|
60
|
+
enumerable: true,
|
|
61
|
+
configurable: true,
|
|
62
|
+
writable: true,
|
|
63
|
+
value: void 0
|
|
64
|
+
});
|
|
65
|
+
Object.defineProperty(this, "_clubs", {
|
|
66
|
+
enumerable: true,
|
|
67
|
+
configurable: true,
|
|
68
|
+
writable: true,
|
|
69
|
+
value: void 0
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(this, "_gears", {
|
|
72
|
+
enumerable: true,
|
|
73
|
+
configurable: true,
|
|
74
|
+
writable: true,
|
|
75
|
+
value: void 0
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(this, "_routes", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
configurable: true,
|
|
80
|
+
writable: true,
|
|
81
|
+
value: void 0
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(this, "_uploads", {
|
|
84
|
+
enumerable: true,
|
|
85
|
+
configurable: true,
|
|
86
|
+
writable: true,
|
|
87
|
+
value: void 0
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(this, "_streams", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
configurable: true,
|
|
92
|
+
writable: true,
|
|
93
|
+
value: void 0
|
|
94
|
+
});
|
|
95
|
+
this.options = {
|
|
96
|
+
baseUrl: options.baseUrl || "https://www.strava.com/api/v3",
|
|
97
|
+
timeout: options.timeout || 30000,
|
|
98
|
+
retries: options.retries || {},
|
|
99
|
+
rateLimitStrategy: options.rateLimitStrategy || "queue",
|
|
100
|
+
deduplicationWindow: options.deduplicationWindow || 5000,
|
|
101
|
+
normalizeKeys: options.normalizeKeys ?? true,
|
|
102
|
+
transformDates: options.transformDates ?? true,
|
|
103
|
+
flattenResponses: options.flattenResponses ?? true,
|
|
104
|
+
addComputedFields: options.addComputedFields ?? true,
|
|
105
|
+
tokenStore: options.tokenStore || (0, token_store_js_1.getDefaultTokenStore)(),
|
|
106
|
+
redirectUri: options.redirectUri,
|
|
107
|
+
clientId: options.clientId,
|
|
108
|
+
clientSecret: options.clientSecret,
|
|
109
|
+
};
|
|
110
|
+
this.oauthManager = new oauth_js_1.OAuthManager(this.options.clientId, this.options.clientSecret, this.options.tokenStore);
|
|
111
|
+
this.rateLimiter = new rate_limiter_js_1.RateLimiter(this.options.rateLimitStrategy);
|
|
112
|
+
this.deduplicator = new deduplication_js_1.RequestDeduplicator(this.options.deduplicationWindow);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Authenticate with authorization code
|
|
116
|
+
*/
|
|
117
|
+
async authenticate(credentials) {
|
|
118
|
+
await this.oauthManager.authenticate(credentials.code, credentials.redirectUri || this.options.redirectUri);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Refresh access token
|
|
122
|
+
*/
|
|
123
|
+
async refreshToken() {
|
|
124
|
+
await this.oauthManager.refreshToken();
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get authorization URL
|
|
128
|
+
*/
|
|
129
|
+
getAuthorizationUrl(options) {
|
|
130
|
+
return this.oauthManager.getAuthorizationUrl({
|
|
131
|
+
redirectUri: options.redirectUri || this.options.redirectUri || "",
|
|
132
|
+
scope: options.scope,
|
|
133
|
+
state: options.state,
|
|
134
|
+
approvalPrompt: options.approvalPrompt,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Get current access token (for direct fetch calls)
|
|
139
|
+
*/
|
|
140
|
+
async getAccessToken() {
|
|
141
|
+
const token = await this.oauthManager.getToken();
|
|
142
|
+
if (!token) {
|
|
143
|
+
throw new Error("Not authenticated. Call authenticate() first.");
|
|
144
|
+
}
|
|
145
|
+
return token.accessToken;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Low-level request method
|
|
149
|
+
*/
|
|
150
|
+
async request(config) {
|
|
151
|
+
const token = await this.oauthManager.getToken();
|
|
152
|
+
if (!token) {
|
|
153
|
+
throw new Error("Not authenticated. Call authenticate() first.");
|
|
154
|
+
}
|
|
155
|
+
return (0, request_js_1.request)(config, {
|
|
156
|
+
baseUrl: this.options.baseUrl,
|
|
157
|
+
timeout: this.options.timeout,
|
|
158
|
+
accessToken: token.accessToken,
|
|
159
|
+
rateLimiter: this.rateLimiter,
|
|
160
|
+
deduplicator: this.deduplicator,
|
|
161
|
+
retryConfig: this.options.retries,
|
|
162
|
+
normalizeKeys: this.options.normalizeKeys,
|
|
163
|
+
transformDates: this.options.transformDates,
|
|
164
|
+
flattenResponses: this.options.flattenResponses,
|
|
165
|
+
addComputedFields: this.options.addComputedFields,
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
get athletes() {
|
|
169
|
+
if (!this._athletes) {
|
|
170
|
+
this._athletes = new athletes_js_1.AthletesResource(this);
|
|
171
|
+
}
|
|
172
|
+
return this._athletes;
|
|
173
|
+
}
|
|
174
|
+
get activities() {
|
|
175
|
+
if (!this._activities) {
|
|
176
|
+
this._activities = new activities_js_1.ActivitiesResource(this);
|
|
177
|
+
}
|
|
178
|
+
return this._activities;
|
|
179
|
+
}
|
|
180
|
+
get segments() {
|
|
181
|
+
if (!this._segments) {
|
|
182
|
+
this._segments = new segments_js_1.SegmentsResource(this);
|
|
183
|
+
}
|
|
184
|
+
return this._segments;
|
|
185
|
+
}
|
|
186
|
+
get segmentEfforts() {
|
|
187
|
+
if (!this._segmentEfforts) {
|
|
188
|
+
this._segmentEfforts = new segment_efforts_js_1.SegmentEffortsResource(this);
|
|
189
|
+
}
|
|
190
|
+
return this._segmentEfforts;
|
|
191
|
+
}
|
|
192
|
+
get clubs() {
|
|
193
|
+
if (!this._clubs) {
|
|
194
|
+
this._clubs = new clubs_js_1.ClubsResource(this);
|
|
195
|
+
}
|
|
196
|
+
return this._clubs;
|
|
197
|
+
}
|
|
198
|
+
get gears() {
|
|
199
|
+
if (!this._gears) {
|
|
200
|
+
this._gears = new gears_js_1.GearsResource(this);
|
|
201
|
+
}
|
|
202
|
+
return this._gears;
|
|
203
|
+
}
|
|
204
|
+
get routes() {
|
|
205
|
+
if (!this._routes) {
|
|
206
|
+
this._routes = new routes_js_1.RoutesResource(this);
|
|
207
|
+
}
|
|
208
|
+
return this._routes;
|
|
209
|
+
}
|
|
210
|
+
get uploads() {
|
|
211
|
+
if (!this._uploads) {
|
|
212
|
+
this._uploads = new uploads_js_1.UploadsResource(this);
|
|
213
|
+
}
|
|
214
|
+
return this._uploads;
|
|
215
|
+
}
|
|
216
|
+
get streams() {
|
|
217
|
+
if (!this._streams) {
|
|
218
|
+
this._streams = new streams_js_1.StreamsResource(this);
|
|
219
|
+
}
|
|
220
|
+
return this._streams;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Clean up resources (stop timers, clear caches)
|
|
224
|
+
* Call this when you're done with the client to allow the process to exit
|
|
225
|
+
*/
|
|
226
|
+
destroy() {
|
|
227
|
+
this.deduplicator.destroy();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
exports.StravaClient = StravaClient;
|
|
231
|
+
const athletes_js_1 = require("./resources/athletes.js");
|
|
232
|
+
const activities_js_1 = require("./resources/activities.js");
|
|
233
|
+
const segments_js_1 = require("./resources/segments.js");
|
|
234
|
+
const segment_efforts_js_1 = require("./resources/segment-efforts.js");
|
|
235
|
+
const clubs_js_1 = require("./resources/clubs.js");
|
|
236
|
+
const gears_js_1 = require("./resources/gears.js");
|
|
237
|
+
const routes_js_1 = require("./resources/routes.js");
|
|
238
|
+
const uploads_js_1 = require("./resources/uploads.js");
|
|
239
|
+
const streams_js_1 = require("./resources/streams.js");
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes for Strava API interactions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Base error class for all Strava API errors
|
|
6
|
+
*/
|
|
7
|
+
export declare class StravaError extends Error {
|
|
8
|
+
statusCode?: number;
|
|
9
|
+
response?: unknown;
|
|
10
|
+
constructor(message: string, statusCode?: number, response?: unknown);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Authentication-related errors (401, invalid credentials, token expired)
|
|
14
|
+
*/
|
|
15
|
+
export declare class StravaAuthError extends StravaError {
|
|
16
|
+
constructor(message: string, statusCode?: number, response?: unknown);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Rate limit errors (429)
|
|
20
|
+
*/
|
|
21
|
+
export declare class StravaRateLimitError extends StravaError {
|
|
22
|
+
retryAfter?: number;
|
|
23
|
+
limit?: number;
|
|
24
|
+
usage?: number;
|
|
25
|
+
constructor(message: string, statusCode?: number, response?: unknown, retryAfter?: number, limit?: number, usage?: number);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Resource not found errors (404)
|
|
29
|
+
*/
|
|
30
|
+
export declare class StravaNotFoundError extends StravaError {
|
|
31
|
+
constructor(message: string, statusCode?: number, response?: unknown);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Validation errors (422)
|
|
35
|
+
*/
|
|
36
|
+
export declare class StravaValidationError extends StravaError {
|
|
37
|
+
errors?: Array<{
|
|
38
|
+
field: string;
|
|
39
|
+
message: string;
|
|
40
|
+
}>;
|
|
41
|
+
constructor(message: string, statusCode?: number, response?: unknown, errors?: Array<{
|
|
42
|
+
field: string;
|
|
43
|
+
message: string;
|
|
44
|
+
}>);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Server errors (5xx)
|
|
48
|
+
*/
|
|
49
|
+
export declare class StravaServerError extends StravaError {
|
|
50
|
+
constructor(message: string, statusCode?: number, response?: unknown);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Custom error classes for Strava API interactions
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.StravaServerError = exports.StravaValidationError = exports.StravaNotFoundError = exports.StravaRateLimitError = exports.StravaAuthError = exports.StravaError = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for all Strava API errors
|
|
9
|
+
*/
|
|
10
|
+
class StravaError extends Error {
|
|
11
|
+
constructor(message, statusCode, response) {
|
|
12
|
+
super(message);
|
|
13
|
+
Object.defineProperty(this, "statusCode", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: void 0
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "response", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: void 0
|
|
24
|
+
});
|
|
25
|
+
this.name = "StravaError";
|
|
26
|
+
this.statusCode = statusCode;
|
|
27
|
+
this.response = response;
|
|
28
|
+
if (Error.captureStackTrace) {
|
|
29
|
+
Error.captureStackTrace(this, StravaError);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.StravaError = StravaError;
|
|
34
|
+
/**
|
|
35
|
+
* Authentication-related errors (401, invalid credentials, token expired)
|
|
36
|
+
*/
|
|
37
|
+
class StravaAuthError extends StravaError {
|
|
38
|
+
constructor(message, statusCode, response) {
|
|
39
|
+
super(message, statusCode, response);
|
|
40
|
+
this.name = "StravaAuthError";
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
exports.StravaAuthError = StravaAuthError;
|
|
44
|
+
/**
|
|
45
|
+
* Rate limit errors (429)
|
|
46
|
+
*/
|
|
47
|
+
class StravaRateLimitError extends StravaError {
|
|
48
|
+
constructor(message, statusCode, response, retryAfter, limit, usage) {
|
|
49
|
+
super(message, statusCode, response);
|
|
50
|
+
Object.defineProperty(this, "retryAfter", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: true,
|
|
54
|
+
value: void 0
|
|
55
|
+
});
|
|
56
|
+
Object.defineProperty(this, "limit", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
configurable: true,
|
|
59
|
+
writable: true,
|
|
60
|
+
value: void 0
|
|
61
|
+
});
|
|
62
|
+
Object.defineProperty(this, "usage", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
writable: true,
|
|
66
|
+
value: void 0
|
|
67
|
+
});
|
|
68
|
+
this.name = "StravaRateLimitError";
|
|
69
|
+
this.retryAfter = retryAfter;
|
|
70
|
+
this.limit = limit;
|
|
71
|
+
this.usage = usage;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.StravaRateLimitError = StravaRateLimitError;
|
|
75
|
+
/**
|
|
76
|
+
* Resource not found errors (404)
|
|
77
|
+
*/
|
|
78
|
+
class StravaNotFoundError extends StravaError {
|
|
79
|
+
constructor(message, statusCode, response) {
|
|
80
|
+
super(message, statusCode, response);
|
|
81
|
+
this.name = "StravaNotFoundError";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
exports.StravaNotFoundError = StravaNotFoundError;
|
|
85
|
+
/**
|
|
86
|
+
* Validation errors (422)
|
|
87
|
+
*/
|
|
88
|
+
class StravaValidationError extends StravaError {
|
|
89
|
+
constructor(message, statusCode, response, errors) {
|
|
90
|
+
super(message, statusCode, response);
|
|
91
|
+
Object.defineProperty(this, "errors", {
|
|
92
|
+
enumerable: true,
|
|
93
|
+
configurable: true,
|
|
94
|
+
writable: true,
|
|
95
|
+
value: void 0
|
|
96
|
+
});
|
|
97
|
+
this.name = "StravaValidationError";
|
|
98
|
+
this.errors = errors;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
exports.StravaValidationError = StravaValidationError;
|
|
102
|
+
/**
|
|
103
|
+
* Server errors (5xx)
|
|
104
|
+
*/
|
|
105
|
+
class StravaServerError extends StravaError {
|
|
106
|
+
constructor(message, statusCode, response) {
|
|
107
|
+
super(message, statusCode, response);
|
|
108
|
+
this.name = "StravaServerError";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
exports.StravaServerError = StravaServerError;
|