@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
@@ -0,0 +1,168 @@
1
+ /**
2
+ * Rate limit tracking and queue management
3
+ */
4
+ /**
5
+ * Rate limiter for Strava API
6
+ */
7
+ export class RateLimiter {
8
+ constructor(strategy = "queue") {
9
+ Object.defineProperty(this, "shortTermLimit", {
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: true,
13
+ value: 600
14
+ });
15
+ Object.defineProperty(this, "shortTermWindow", {
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true,
19
+ value: 15 * 60 * 1000
20
+ });
21
+ Object.defineProperty(this, "dailyLimit", {
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true,
25
+ value: 30000
26
+ });
27
+ Object.defineProperty(this, "dailyWindow", {
28
+ enumerable: true,
29
+ configurable: true,
30
+ writable: true,
31
+ value: 24 * 60 * 60 * 1000
32
+ });
33
+ Object.defineProperty(this, "shortTermRequests", {
34
+ enumerable: true,
35
+ configurable: true,
36
+ writable: true,
37
+ value: []
38
+ });
39
+ Object.defineProperty(this, "dailyRequests", {
40
+ enumerable: true,
41
+ configurable: true,
42
+ writable: true,
43
+ value: []
44
+ });
45
+ Object.defineProperty(this, "queue", {
46
+ enumerable: true,
47
+ configurable: true,
48
+ writable: true,
49
+ value: []
50
+ });
51
+ Object.defineProperty(this, "strategy", {
52
+ enumerable: true,
53
+ configurable: true,
54
+ writable: true,
55
+ value: void 0
56
+ });
57
+ this.strategy = strategy;
58
+ }
59
+ /**
60
+ * Update rate limit info from response headers
61
+ */
62
+ updateFromHeaders(headers) {
63
+ const shortTermLimit = headers.get("X-RateLimit-Limit");
64
+ const shortTermUsage = headers.get("X-RateLimit-Usage");
65
+ const dailyLimit = headers.get("X-RateLimit-Limit-Daily");
66
+ const dailyUsage = headers.get("X-RateLimit-Usage-Daily");
67
+ if (shortTermLimit) {
68
+ this.shortTermLimit = parseInt(shortTermLimit, 10);
69
+ }
70
+ if (shortTermUsage) {
71
+ const parts = shortTermUsage.split(",");
72
+ if (parts.length >= 1) {
73
+ const current = parseInt(parts[0], 10);
74
+ this.recordRequest("shortTerm", current);
75
+ }
76
+ }
77
+ if (dailyLimit) {
78
+ this.dailyLimit = parseInt(dailyLimit, 10);
79
+ }
80
+ if (dailyUsage) {
81
+ const parts = dailyUsage.split(",");
82
+ if (parts.length >= 1) {
83
+ const current = parseInt(parts[0], 10);
84
+ this.recordRequest("daily", current);
85
+ }
86
+ }
87
+ }
88
+ /**
89
+ * Record a request timestamp
90
+ */
91
+ recordRequest(type, _currentUsage) {
92
+ const now = Date.now();
93
+ const window = type === "shortTerm" ? this.shortTermWindow : this.dailyWindow;
94
+ const requests = type === "shortTerm" ? this.shortTermRequests : this.dailyRequests;
95
+ const cutoff = now - window;
96
+ while (requests.length > 0 && requests[0] < cutoff) {
97
+ requests.shift();
98
+ }
99
+ requests.push(now);
100
+ }
101
+ /**
102
+ * Get current rate limit info
103
+ */
104
+ getRateLimitInfo() {
105
+ const now = Date.now();
106
+ const shortTermCutoff = now - this.shortTermWindow;
107
+ this.shortTermRequests = this.shortTermRequests.filter((t) => t >= shortTermCutoff);
108
+ const dailyCutoff = now - this.dailyWindow;
109
+ this.dailyRequests = this.dailyRequests.filter((t) => t >= dailyCutoff);
110
+ return {
111
+ shortTermLimit: this.shortTermLimit,
112
+ shortTermUsage: this.shortTermRequests.length,
113
+ dailyLimit: this.dailyLimit,
114
+ dailyUsage: this.dailyRequests.length,
115
+ };
116
+ }
117
+ /**
118
+ * Check if we can make a request
119
+ */
120
+ canMakeRequest() {
121
+ const info = this.getRateLimitInfo();
122
+ return (info.shortTermUsage ?? 0) < (info.shortTermLimit ?? 600) &&
123
+ (info.dailyUsage ?? 0) < (info.dailyLimit ?? 30000);
124
+ }
125
+ /**
126
+ * Wait until we can make a request
127
+ */
128
+ async waitForAvailability() {
129
+ if (this.canMakeRequest()) {
130
+ return;
131
+ }
132
+ if (this.strategy === "throw") {
133
+ const info = this.getRateLimitInfo();
134
+ throw new Error(`Rate limit exceeded. Short-term: ${info.shortTermUsage}/${info.shortTermLimit}, ` +
135
+ `Daily: ${info.dailyUsage}/${info.dailyLimit}`);
136
+ }
137
+ if (this.strategy === "wait") {
138
+ while (!this.canMakeRequest()) {
139
+ await new Promise((resolve) => setTimeout(resolve, 1000));
140
+ }
141
+ return;
142
+ }
143
+ return new Promise((resolve, reject) => {
144
+ this.queue.push({
145
+ resolve,
146
+ reject,
147
+ timestamp: Date.now(),
148
+ });
149
+ });
150
+ }
151
+ /**
152
+ * Process queued requests
153
+ */
154
+ processQueue() {
155
+ while (this.queue.length > 0 && this.canMakeRequest()) {
156
+ const request = this.queue.shift();
157
+ if (request) {
158
+ request.resolve(undefined);
159
+ }
160
+ }
161
+ }
162
+ /**
163
+ * Set rate limit strategy
164
+ */
165
+ setStrategy(strategy) {
166
+ this.strategy = strategy;
167
+ }
168
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Core HTTP request handler
3
+ */
4
+ import type { RateLimiter } from "./rate-limiter.js";
5
+ import type { RequestDeduplicator } from "./deduplication.js";
6
+ import type { RequestConfig, RetryConfig } from "../types/common.js";
7
+ interface RequestOptions {
8
+ baseUrl?: string;
9
+ timeout?: number;
10
+ accessToken?: string;
11
+ rateLimiter?: RateLimiter;
12
+ deduplicator?: RequestDeduplicator;
13
+ retryConfig?: RetryConfig;
14
+ normalizeKeys?: boolean;
15
+ transformDates?: boolean;
16
+ flattenResponses?: boolean;
17
+ addComputedFields?: boolean;
18
+ }
19
+ /**
20
+ * Make HTTP request with retry, rate limiting, and error handling
21
+ */
22
+ export declare function request<T>(config: RequestConfig, options?: RequestOptions): Promise<T>;
23
+ export {};
24
+ //# sourceMappingURL=request.d.ts.map
@@ -0,0 +1,158 @@
1
+ /**
2
+ * Core HTTP request handler
3
+ */
4
+ import { StravaAuthError, StravaError, StravaNotFoundError, StravaRateLimitError, StravaServerError, StravaValidationError } from "../errors.js";
5
+ import { withRetry } from "./retry.js";
6
+ import { applyTransformations } from "../utils/transformers.js";
7
+ const DEFAULT_BASE_URL = "https://www.strava.com/api/v3";
8
+ const DEFAULT_TIMEOUT = 30000;
9
+ /**
10
+ * Extract rate limit info from response headers
11
+ */
12
+ function extractRateLimitInfo(headers) {
13
+ const shortTermLimit = headers.get("X-RateLimit-Limit");
14
+ const shortTermUsage = headers.get("X-RateLimit-Usage");
15
+ const dailyLimit = headers.get("X-RateLimit-Limit-Daily");
16
+ const dailyUsage = headers.get("X-RateLimit-Usage-Daily");
17
+ const info = {};
18
+ if (shortTermLimit) {
19
+ info.shortTermLimit = parseInt(shortTermLimit, 10);
20
+ }
21
+ if (shortTermUsage) {
22
+ const parts = shortTermUsage.split(",");
23
+ if (parts.length >= 1) {
24
+ info.shortTermUsage = parseInt(parts[0], 10);
25
+ }
26
+ }
27
+ if (dailyLimit) {
28
+ info.dailyLimit = parseInt(dailyLimit, 10);
29
+ }
30
+ if (dailyUsage) {
31
+ const parts = dailyUsage.split(",");
32
+ if (parts.length >= 1) {
33
+ info.dailyUsage = parseInt(parts[0], 10);
34
+ }
35
+ }
36
+ return info;
37
+ }
38
+ /**
39
+ * Build query string from query parameters
40
+ */
41
+ function buildQueryString(query) {
42
+ if (!query)
43
+ return "";
44
+ const params = new URLSearchParams();
45
+ for (const [key, value] of Object.entries(query)) {
46
+ if (value !== undefined && value !== null) {
47
+ params.append(key, String(value));
48
+ }
49
+ }
50
+ const queryString = params.toString();
51
+ return queryString ? `?${queryString}` : "";
52
+ }
53
+ /**
54
+ * Create error from response
55
+ */
56
+ async function createErrorFromResponse(response) {
57
+ const statusCode = response.status;
58
+ let errorData;
59
+ try {
60
+ errorData = await response.json();
61
+ }
62
+ catch {
63
+ errorData = await response.text().catch(() => undefined);
64
+ }
65
+ const message = typeof errorData === "object" && errorData !== null && "message" in errorData
66
+ ? String(errorData.message)
67
+ : `HTTP ${statusCode}: ${response.statusText}`;
68
+ const rateLimitInfo = extractRateLimitInfo(response.headers);
69
+ const retryAfter = response.headers.get("Retry-After");
70
+ switch (statusCode) {
71
+ case 401:
72
+ case 403:
73
+ return new StravaAuthError(message, statusCode, errorData);
74
+ case 404:
75
+ return new StravaNotFoundError(message, statusCode, errorData);
76
+ case 422: {
77
+ const errors = typeof errorData === "object" && errorData !== null && "errors" in errorData
78
+ ? errorData.errors
79
+ : undefined;
80
+ return new StravaValidationError(message, statusCode, errorData, errors);
81
+ }
82
+ case 429:
83
+ return new StravaRateLimitError(message, statusCode, errorData, retryAfter ? parseInt(retryAfter, 10) : undefined, rateLimitInfo.shortTermLimit, rateLimitInfo.shortTermUsage);
84
+ case 500:
85
+ case 502:
86
+ case 503:
87
+ case 504:
88
+ return new StravaServerError(message, statusCode, errorData);
89
+ default:
90
+ return new StravaError(message, statusCode, errorData);
91
+ }
92
+ }
93
+ /**
94
+ * Make HTTP request with retry, rate limiting, and error handling
95
+ */
96
+ export function request(config, options = {}) {
97
+ const { baseUrl = DEFAULT_BASE_URL, timeout = DEFAULT_TIMEOUT, accessToken, rateLimiter, deduplicator, retryConfig, normalizeKeys = true, transformDates = false, flattenResponses = false, addComputedFields = false, } = options;
98
+ const queryString = buildQueryString(config.query);
99
+ const url = `${baseUrl}${config.path}${queryString}`;
100
+ const headers = {
101
+ "Content-Type": "application/json",
102
+ ...config.headers,
103
+ };
104
+ if (accessToken) {
105
+ headers["Authorization"] = `Bearer ${accessToken}`;
106
+ }
107
+ const makeRequest = async () => {
108
+ if (rateLimiter) {
109
+ await rateLimiter.waitForAvailability();
110
+ }
111
+ const controller = new AbortController();
112
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
113
+ try {
114
+ const response = await fetch(url, {
115
+ method: config.method,
116
+ headers,
117
+ body: config.body ? JSON.stringify(config.body) : undefined,
118
+ signal: controller.signal,
119
+ });
120
+ if (rateLimiter) {
121
+ rateLimiter.updateFromHeaders(response.headers);
122
+ rateLimiter.processQueue();
123
+ }
124
+ if (!response.ok) {
125
+ throw await createErrorFromResponse(response);
126
+ }
127
+ const rawData = await response.json();
128
+ const transformedData = applyTransformations(rawData, normalizeKeys, transformDates, flattenResponses, addComputedFields);
129
+ return transformedData;
130
+ }
131
+ catch (error) {
132
+ if (error instanceof StravaError) {
133
+ throw error;
134
+ }
135
+ if (error instanceof Error && error.name === "AbortError") {
136
+ throw new StravaError(`Request timeout after ${timeout}ms`, undefined, error);
137
+ }
138
+ throw new StravaError(error instanceof Error ? error.message : "Unknown error", undefined, error);
139
+ }
140
+ finally {
141
+ clearTimeout(timeoutId);
142
+ }
143
+ };
144
+ if (deduplicator) {
145
+ return deduplicator.getOrCreate(config.method, config.path, config.query, config.body, () => withRetry(makeRequest, retryConfig, (error) => {
146
+ if (error instanceof StravaRateLimitError && error.retryAfter) {
147
+ return error.retryAfter;
148
+ }
149
+ return undefined;
150
+ }));
151
+ }
152
+ return withRetry(makeRequest, retryConfig, (error) => {
153
+ if (error instanceof StravaRateLimitError && error.retryAfter) {
154
+ return error.retryAfter;
155
+ }
156
+ return undefined;
157
+ });
158
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Retry logic with exponential backoff
3
+ */
4
+ import type { RetryConfig } from "../types/common.js";
5
+ /**
6
+ * Execute a function with retry logic
7
+ */
8
+ export declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig, getRetryAfter?: (error: unknown) => number | undefined): Promise<T>;
9
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Retry logic with exponential backoff
3
+ */
4
+ const DEFAULT_RETRY_CONFIG = {
5
+ maxAttempts: 3,
6
+ initialDelay: 1000,
7
+ maxDelay: 10000,
8
+ backoffFactor: 2,
9
+ retryableStatusCodes: [429, 500, 502, 503, 504],
10
+ };
11
+ /**
12
+ * Calculate delay for retry attempt
13
+ */
14
+ function calculateDelay(attempt, config, retryAfter) {
15
+ if (retryAfter !== undefined) {
16
+ return Math.min(retryAfter * 1000, config.maxDelay);
17
+ }
18
+ const delay = config.initialDelay * Math.pow(config.backoffFactor, attempt - 1);
19
+ return Math.min(delay, config.maxDelay);
20
+ }
21
+ /**
22
+ * Sleep for specified milliseconds
23
+ */
24
+ function sleep(ms) {
25
+ return new Promise((resolve) => setTimeout(resolve, ms));
26
+ }
27
+ /**
28
+ * Check if error/status code is retryable
29
+ */
30
+ function isRetryable(statusCode, config) {
31
+ if (statusCode === undefined) {
32
+ return true;
33
+ }
34
+ return config.retryableStatusCodes.includes(statusCode);
35
+ }
36
+ /**
37
+ * Execute a function with retry logic
38
+ */
39
+ export async function withRetry(fn, config, getRetryAfter) {
40
+ const retryConfig = { ...DEFAULT_RETRY_CONFIG, ...config };
41
+ let lastError;
42
+ for (let attempt = 1; attempt <= retryConfig.maxAttempts; attempt++) {
43
+ try {
44
+ return await fn();
45
+ }
46
+ catch (error) {
47
+ lastError = error;
48
+ if (attempt >= retryConfig.maxAttempts) {
49
+ break;
50
+ }
51
+ const statusCode = error && typeof error === "object" && "statusCode" in error ? error.statusCode : undefined;
52
+ if (!isRetryable(statusCode, retryConfig)) {
53
+ throw error;
54
+ }
55
+ const retryAfter = getRetryAfter ? getRetryAfter(error) : undefined;
56
+ const delay = calculateDelay(attempt, retryConfig, retryAfter);
57
+ await sleep(delay);
58
+ }
59
+ }
60
+ throw lastError;
61
+ }
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Activities resource
3
+ */
4
+ import type { StravaClient } from "../client.js";
5
+ import type { ActivityZone, Comment, DetailedActivity, DetailedSegmentEffort, Lap, StreamSet, SummaryActivity, SummaryAthlete } from "../types/api.js";
6
+ import type { StreamType } from "./streams.js";
7
+ /**
8
+ * Options for listing activities
9
+ */
10
+ export interface ListActivitiesOptions {
11
+ /** Unix timestamp for activities before this time */
12
+ before?: number;
13
+ /** Unix timestamp for activities after this time */
14
+ after?: number;
15
+ /** Page number (default: 1) */
16
+ page?: number;
17
+ /** Number of items per page (default: 30, max: 200) */
18
+ perPage?: number;
19
+ }
20
+ /**
21
+ * Data for creating a new activity
22
+ */
23
+ export interface CreateActivityData {
24
+ /** Activity name */
25
+ name: string;
26
+ /** Activity type (e.g., "Run", "Ride") */
27
+ type: string;
28
+ /** Start date in ISO 8601 format */
29
+ startDateLocal: string;
30
+ /** Elapsed time in seconds */
31
+ elapsedTime: number;
32
+ /** Activity description */
33
+ description?: string;
34
+ /** Distance in meters */
35
+ distance?: number;
36
+ /** Whether activity was done on trainer */
37
+ trainer?: boolean;
38
+ /** Whether activity is a commute */
39
+ commute?: boolean;
40
+ }
41
+ /**
42
+ * Data for updating an existing activity
43
+ */
44
+ export interface UpdateActivityData {
45
+ /** Activity name */
46
+ name?: string;
47
+ /** Activity type (e.g., "Run", "Ride") */
48
+ type?: string;
49
+ /** Sport type */
50
+ sportType?: string;
51
+ /** Start date in ISO 8601 format */
52
+ startDateLocal?: string;
53
+ /** Elapsed time in seconds */
54
+ elapsedTime?: number;
55
+ /** Activity description */
56
+ description?: string;
57
+ /** Distance in meters */
58
+ distance?: number;
59
+ /** Whether activity was done on trainer */
60
+ trainer?: boolean;
61
+ /** Whether activity is a commute */
62
+ commute?: boolean;
63
+ /** Gear ID */
64
+ gearId?: string;
65
+ }
66
+ /**
67
+ * Resource for interacting with Strava activities
68
+ */
69
+ export declare class ActivitiesResource {
70
+ private client;
71
+ constructor(client: StravaClient);
72
+ /**
73
+ * Get activity by ID
74
+ */
75
+ getById(id: number): Promise<DetailedActivity>;
76
+ /**
77
+ * List athlete activities
78
+ */
79
+ list(options?: ListActivitiesOptions): Promise<SummaryActivity[]>;
80
+ /**
81
+ * List all activities (auto-pagination)
82
+ */
83
+ listAll(options?: Omit<ListActivitiesOptions, "page">): AsyncGenerator<SummaryActivity, void, unknown>;
84
+ /**
85
+ * Create activity
86
+ */
87
+ create(data: CreateActivityData): Promise<DetailedActivity>;
88
+ /**
89
+ * Update activity
90
+ */
91
+ update(id: number, data: UpdateActivityData): Promise<DetailedActivity>;
92
+ /**
93
+ * Delete activity
94
+ */
95
+ delete(id: number): Promise<void>;
96
+ /**
97
+ * Get activity with details (combines activity + laps + zones + comments + kudoers)
98
+ */
99
+ getWithDetails(id: number): Promise<DetailedActivity & {
100
+ laps: Lap[];
101
+ zones: ActivityZone[];
102
+ comments: Comment[];
103
+ kudoers: SummaryAthlete[];
104
+ }>;
105
+ /**
106
+ * Get activity laps
107
+ */
108
+ getLaps(id: number): Promise<Lap[]>;
109
+ /**
110
+ * Get activity zones
111
+ */
112
+ getZones(id: number): Promise<ActivityZone[]>;
113
+ /**
114
+ * Get activity comments
115
+ */
116
+ getComments(id: number, options?: {
117
+ page?: number;
118
+ perPage?: number;
119
+ }): Promise<Comment[]>;
120
+ /**
121
+ * Get activity kudoers
122
+ */
123
+ getKudoers(id: number, options?: {
124
+ page?: number;
125
+ perPage?: number;
126
+ }): Promise<SummaryAthlete[]>;
127
+ /**
128
+ * Analyze activity with comprehensive data
129
+ * Combines activity, zones, laps, best efforts (segments), and optionally streams
130
+ */
131
+ analyze(id: number, options?: {
132
+ includeStreams?: boolean;
133
+ streamTypes?: StreamType[];
134
+ }): Promise<DetailedActivity & {
135
+ zones: ActivityZone[];
136
+ laps: Lap[];
137
+ bestEfforts: DetailedSegmentEffort[];
138
+ streams?: StreamSet;
139
+ analysis: {
140
+ hasPowerData: boolean;
141
+ hasHeartRateData: boolean;
142
+ totalLaps: number;
143
+ bestEffortCount: number;
144
+ averageLapTime?: number;
145
+ averageLapDistance?: number;
146
+ };
147
+ }>;
148
+ }
149
+ //# sourceMappingURL=activities.d.ts.map