@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,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Routes resource
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.RoutesResource = void 0;
|
|
7
|
+
const validators_js_1 = require("../utils/validators.js");
|
|
8
|
+
const pagination_js_1 = require("../utils/pagination.js");
|
|
9
|
+
/**
|
|
10
|
+
* Resource for interacting with Strava routes
|
|
11
|
+
*/
|
|
12
|
+
class RoutesResource {
|
|
13
|
+
constructor(client) {
|
|
14
|
+
Object.defineProperty(this, "client", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: client
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get route by ID
|
|
23
|
+
*/
|
|
24
|
+
async getById(id) {
|
|
25
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
26
|
+
return await this.client.request({
|
|
27
|
+
method: "GET",
|
|
28
|
+
path: `/routes/${id}`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* List athlete routes
|
|
33
|
+
*/
|
|
34
|
+
async list(options) {
|
|
35
|
+
return await this.client.request({
|
|
36
|
+
method: "GET",
|
|
37
|
+
path: "/athlete/routes",
|
|
38
|
+
query: (0, pagination_js_1.buildPaginationQuery)(options),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Download route as GPX
|
|
43
|
+
*/
|
|
44
|
+
async downloadAsGPX(id) {
|
|
45
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
46
|
+
const response = await fetch(`https://www.strava.com/api/v3/routes/${id}/export_gpx`, {
|
|
47
|
+
headers: {
|
|
48
|
+
"Authorization": `Bearer ${await this.getAccessToken()}`,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
throw new Error(`Failed to download GPX: ${response.statusText}`);
|
|
53
|
+
}
|
|
54
|
+
return response.text();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Download route as TCX
|
|
58
|
+
*/
|
|
59
|
+
async downloadAsTCX(id) {
|
|
60
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
61
|
+
const response = await fetch(`https://www.strava.com/api/v3/routes/${id}/export_tcx`, {
|
|
62
|
+
headers: {
|
|
63
|
+
"Authorization": `Bearer ${await this.getAccessToken()}`,
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
throw new Error(`Failed to download TCX: ${response.statusText}`);
|
|
68
|
+
}
|
|
69
|
+
return response.text();
|
|
70
|
+
}
|
|
71
|
+
async getAccessToken() {
|
|
72
|
+
return await this.client.getAccessToken();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.RoutesResource = RoutesResource;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Segment efforts resource
|
|
3
|
+
*/
|
|
4
|
+
import type { StravaClient } from "../client.js";
|
|
5
|
+
import type { DetailedSegmentEffort, SummarySegmentEffort } from "../types/api.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for listing segment efforts
|
|
8
|
+
*/
|
|
9
|
+
export interface ListSegmentEffortsOptions {
|
|
10
|
+
/** Filter by segment ID */
|
|
11
|
+
segmentId?: number;
|
|
12
|
+
/** Filter by athlete ID */
|
|
13
|
+
athleteId?: number;
|
|
14
|
+
/** Start date in ISO 8601 format */
|
|
15
|
+
startDateLocal?: string;
|
|
16
|
+
/** End date in ISO 8601 format */
|
|
17
|
+
endDateLocal?: string;
|
|
18
|
+
/** Page number (default: 1) */
|
|
19
|
+
page?: number;
|
|
20
|
+
/** Number of items per page (default: 30, max: 200) */
|
|
21
|
+
perPage?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resource for interacting with Strava segment efforts
|
|
25
|
+
*/
|
|
26
|
+
export declare class SegmentEffortsResource {
|
|
27
|
+
private client;
|
|
28
|
+
constructor(client: StravaClient);
|
|
29
|
+
/**
|
|
30
|
+
* Get segment effort by ID
|
|
31
|
+
*/
|
|
32
|
+
getById(id: number): Promise<DetailedSegmentEffort>;
|
|
33
|
+
/**
|
|
34
|
+
* List segment efforts
|
|
35
|
+
*/
|
|
36
|
+
list(options?: ListSegmentEffortsOptions): Promise<SummarySegmentEffort[]>;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=segment-efforts.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Segment efforts resource
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SegmentEffortsResource = void 0;
|
|
7
|
+
const validators_js_1 = require("../utils/validators.js");
|
|
8
|
+
const pagination_js_1 = require("../utils/pagination.js");
|
|
9
|
+
/**
|
|
10
|
+
* Resource for interacting with Strava segment efforts
|
|
11
|
+
*/
|
|
12
|
+
class SegmentEffortsResource {
|
|
13
|
+
constructor(client) {
|
|
14
|
+
Object.defineProperty(this, "client", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: client
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get segment effort by ID
|
|
23
|
+
*/
|
|
24
|
+
async getById(id) {
|
|
25
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
26
|
+
return await this.client.request({
|
|
27
|
+
method: "GET",
|
|
28
|
+
path: `/segment_efforts/${id}`,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* List segment efforts
|
|
33
|
+
*/
|
|
34
|
+
async list(options) {
|
|
35
|
+
const query = {
|
|
36
|
+
...(0, pagination_js_1.buildPaginationQuery)(options),
|
|
37
|
+
};
|
|
38
|
+
if (options?.segmentId) {
|
|
39
|
+
query.segment_id = options.segmentId;
|
|
40
|
+
}
|
|
41
|
+
if (options?.athleteId) {
|
|
42
|
+
query.athlete_id = options.athleteId;
|
|
43
|
+
}
|
|
44
|
+
if (options?.startDateLocal) {
|
|
45
|
+
query.start_date_local = options.startDateLocal;
|
|
46
|
+
}
|
|
47
|
+
if (options?.endDateLocal) {
|
|
48
|
+
query.end_date_local = options.endDateLocal;
|
|
49
|
+
}
|
|
50
|
+
return await this.client.request({
|
|
51
|
+
method: "GET",
|
|
52
|
+
path: "/segment_efforts",
|
|
53
|
+
query,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.SegmentEffortsResource = SegmentEffortsResource;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Segments resource
|
|
3
|
+
*/
|
|
4
|
+
import type { StravaClient } from "../client.js";
|
|
5
|
+
import type { DetailedSegment, ExplorerResponse } from "../types/api.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for exploring segments
|
|
8
|
+
*/
|
|
9
|
+
export interface ExploreSegmentsOptions {
|
|
10
|
+
/** Bounding box as [south, west, north, east] */
|
|
11
|
+
bounds: [number, number, number, number];
|
|
12
|
+
/** Activity type filter */
|
|
13
|
+
activityType?: "running" | "riding";
|
|
14
|
+
/** Minimum category */
|
|
15
|
+
minCat?: number;
|
|
16
|
+
/** Maximum category */
|
|
17
|
+
maxCat?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resource for interacting with Strava segments
|
|
21
|
+
*/
|
|
22
|
+
export declare class SegmentsResource {
|
|
23
|
+
private client;
|
|
24
|
+
constructor(client: StravaClient);
|
|
25
|
+
/**
|
|
26
|
+
* Get segment by ID
|
|
27
|
+
*/
|
|
28
|
+
getById(id: number): Promise<DetailedSegment>;
|
|
29
|
+
/**
|
|
30
|
+
* Explore segments
|
|
31
|
+
*/
|
|
32
|
+
explore(options: ExploreSegmentsOptions): Promise<ExplorerResponse>;
|
|
33
|
+
/**
|
|
34
|
+
* Star segment
|
|
35
|
+
*/
|
|
36
|
+
star(id: number, starred?: boolean): Promise<DetailedSegment>;
|
|
37
|
+
/**
|
|
38
|
+
* Unstar segment
|
|
39
|
+
*/
|
|
40
|
+
unstar(id: number): Promise<DetailedSegment>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=segments.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Segments resource
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SegmentsResource = void 0;
|
|
7
|
+
const validators_js_1 = require("../utils/validators.js");
|
|
8
|
+
/**
|
|
9
|
+
* Resource for interacting with Strava segments
|
|
10
|
+
*/
|
|
11
|
+
class SegmentsResource {
|
|
12
|
+
constructor(client) {
|
|
13
|
+
Object.defineProperty(this, "client", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: client
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get segment by ID
|
|
22
|
+
*/
|
|
23
|
+
async getById(id) {
|
|
24
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
25
|
+
return await this.client.request({
|
|
26
|
+
method: "GET",
|
|
27
|
+
path: `/segments/${id}`,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Explore segments
|
|
32
|
+
*/
|
|
33
|
+
async explore(options) {
|
|
34
|
+
const [south, west, north, east] = options.bounds;
|
|
35
|
+
const query = {
|
|
36
|
+
bounds: `${south},${west},${north},${east}`,
|
|
37
|
+
};
|
|
38
|
+
if (options.activityType) {
|
|
39
|
+
query.activity_type = options.activityType;
|
|
40
|
+
}
|
|
41
|
+
if (options.minCat !== undefined) {
|
|
42
|
+
query.min_cat = options.minCat;
|
|
43
|
+
}
|
|
44
|
+
if (options.maxCat !== undefined) {
|
|
45
|
+
query.max_cat = options.maxCat;
|
|
46
|
+
}
|
|
47
|
+
return await this.client.request({
|
|
48
|
+
method: "GET",
|
|
49
|
+
path: "/segments/explore",
|
|
50
|
+
query,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Star segment
|
|
55
|
+
*/
|
|
56
|
+
async star(id, starred = true) {
|
|
57
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
58
|
+
return await this.client.request({
|
|
59
|
+
method: "PUT",
|
|
60
|
+
path: `/segments/${id}/starred`,
|
|
61
|
+
query: { starred: starred ? "true" : "false" },
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Unstar segment
|
|
66
|
+
*/
|
|
67
|
+
async unstar(id) {
|
|
68
|
+
return await this.star(id, false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.SegmentsResource = SegmentsResource;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streams resource
|
|
3
|
+
*/
|
|
4
|
+
import type { StravaClient } from "../client.js";
|
|
5
|
+
import type { StreamSet } from "../types/api.js";
|
|
6
|
+
/**
|
|
7
|
+
* Available stream types
|
|
8
|
+
*/
|
|
9
|
+
export type StreamType = "time" | "distance" | "latlng" | "altitude" | "velocity_smooth" | "heartrate" | "cadence" | "watts" | "temp" | "moving" | "grade_smooth";
|
|
10
|
+
/**
|
|
11
|
+
* Options for getting streams
|
|
12
|
+
*/
|
|
13
|
+
export interface GetStreamsOptions {
|
|
14
|
+
/** Stream types to retrieve */
|
|
15
|
+
types?: StreamType[];
|
|
16
|
+
/** Whether to key streams by type */
|
|
17
|
+
keyByType?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resource for interacting with Strava streams
|
|
21
|
+
*/
|
|
22
|
+
export declare class StreamsResource {
|
|
23
|
+
private client;
|
|
24
|
+
constructor(client: StravaClient);
|
|
25
|
+
/**
|
|
26
|
+
* Get activity streams
|
|
27
|
+
*/
|
|
28
|
+
getForActivity(id: number, options?: GetStreamsOptions): Promise<StreamSet>;
|
|
29
|
+
/**
|
|
30
|
+
* Get segment effort streams
|
|
31
|
+
*/
|
|
32
|
+
getForSegmentEffort(id: number, options?: GetStreamsOptions): Promise<StreamSet>;
|
|
33
|
+
/**
|
|
34
|
+
* Get segment streams
|
|
35
|
+
*/
|
|
36
|
+
getForSegment(id: number, options?: Omit<GetStreamsOptions, "types"> & {
|
|
37
|
+
types?: Array<"distance" | "latlng" | "altitude">;
|
|
38
|
+
}): Promise<StreamSet>;
|
|
39
|
+
/**
|
|
40
|
+
* Get route streams
|
|
41
|
+
*/
|
|
42
|
+
getForRoute(id: number): Promise<StreamSet>;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=streams.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Streams resource
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.StreamsResource = void 0;
|
|
7
|
+
const validators_js_1 = require("../utils/validators.js");
|
|
8
|
+
/**
|
|
9
|
+
* Resource for interacting with Strava streams
|
|
10
|
+
*/
|
|
11
|
+
class StreamsResource {
|
|
12
|
+
constructor(client) {
|
|
13
|
+
Object.defineProperty(this, "client", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: client
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get activity streams
|
|
22
|
+
*/
|
|
23
|
+
async getForActivity(id, options) {
|
|
24
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
25
|
+
const types = options?.types || ["time", "distance", "latlng", "altitude", "heartrate"];
|
|
26
|
+
const query = {
|
|
27
|
+
keys: types.join(","),
|
|
28
|
+
key_by_type: options?.keyByType ?? true,
|
|
29
|
+
};
|
|
30
|
+
return await this.client.request({
|
|
31
|
+
method: "GET",
|
|
32
|
+
path: `/activities/${id}/streams`,
|
|
33
|
+
query,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Get segment effort streams
|
|
38
|
+
*/
|
|
39
|
+
async getForSegmentEffort(id, options) {
|
|
40
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
41
|
+
const types = options?.types || ["time", "distance", "latlng", "altitude", "heartrate"];
|
|
42
|
+
const query = {
|
|
43
|
+
keys: types.join(","),
|
|
44
|
+
key_by_type: options?.keyByType ?? true,
|
|
45
|
+
};
|
|
46
|
+
return await this.client.request({
|
|
47
|
+
method: "GET",
|
|
48
|
+
path: `/segment_efforts/${id}/streams`,
|
|
49
|
+
query,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get segment streams
|
|
54
|
+
*/
|
|
55
|
+
async getForSegment(id, options) {
|
|
56
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
57
|
+
const types = options?.types || ["distance", "latlng", "altitude"];
|
|
58
|
+
const query = {
|
|
59
|
+
keys: types.join(","),
|
|
60
|
+
key_by_type: options?.keyByType ?? true,
|
|
61
|
+
};
|
|
62
|
+
return await this.client.request({
|
|
63
|
+
method: "GET",
|
|
64
|
+
path: `/segments/${id}/streams`,
|
|
65
|
+
query,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get route streams
|
|
70
|
+
*/
|
|
71
|
+
async getForRoute(id) {
|
|
72
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
73
|
+
return await this.client.request({
|
|
74
|
+
method: "GET",
|
|
75
|
+
path: `/routes/${id}/streams`,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.StreamsResource = StreamsResource;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uploads resource
|
|
3
|
+
*/
|
|
4
|
+
import type { StravaClient } from "../client.js";
|
|
5
|
+
import type { Upload } from "../types/api.js";
|
|
6
|
+
/**
|
|
7
|
+
* Options for creating an upload
|
|
8
|
+
*/
|
|
9
|
+
export interface CreateUploadOptions {
|
|
10
|
+
/** Activity file (FIT, TCX, or GPX format) */
|
|
11
|
+
file: File | Blob | Uint8Array;
|
|
12
|
+
/** Activity name */
|
|
13
|
+
name?: string;
|
|
14
|
+
/** Activity description */
|
|
15
|
+
description?: string;
|
|
16
|
+
/** Whether activity was done on trainer */
|
|
17
|
+
trainer?: boolean;
|
|
18
|
+
/** Whether activity is a commute */
|
|
19
|
+
commute?: boolean;
|
|
20
|
+
/** File data type */
|
|
21
|
+
dataType?: "fit" | "fit.gz" | "tcx" | "tcx.gz" | "gpx" | "gpx.gz";
|
|
22
|
+
/** External ID for the activity */
|
|
23
|
+
externalId?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resource for uploading activities to Strava
|
|
27
|
+
*/
|
|
28
|
+
export declare class UploadsResource {
|
|
29
|
+
private client;
|
|
30
|
+
constructor(client: StravaClient);
|
|
31
|
+
/**
|
|
32
|
+
* Create upload
|
|
33
|
+
*/
|
|
34
|
+
create(options: CreateUploadOptions): Promise<Upload>;
|
|
35
|
+
/**
|
|
36
|
+
* Get upload by ID
|
|
37
|
+
*/
|
|
38
|
+
getById(id: number): Promise<Upload>;
|
|
39
|
+
private getAccessToken;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=uploads.d.ts.map
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Uploads resource
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UploadsResource = void 0;
|
|
7
|
+
const validators_js_1 = require("../utils/validators.js");
|
|
8
|
+
/**
|
|
9
|
+
* Resource for uploading activities to Strava
|
|
10
|
+
*/
|
|
11
|
+
class UploadsResource {
|
|
12
|
+
constructor(client) {
|
|
13
|
+
Object.defineProperty(this, "client", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: client
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create upload
|
|
22
|
+
*/
|
|
23
|
+
async create(options) {
|
|
24
|
+
const formData = new FormData();
|
|
25
|
+
if (options.file instanceof File) {
|
|
26
|
+
formData.append("file", options.file);
|
|
27
|
+
}
|
|
28
|
+
else if (options.file instanceof Blob) {
|
|
29
|
+
formData.append("file", options.file, "activity.fit");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
// Uint8Array
|
|
33
|
+
const blob = new Blob([options.file], { type: "application/octet-stream" });
|
|
34
|
+
formData.append("file", blob, "activity.fit");
|
|
35
|
+
}
|
|
36
|
+
if (options.name) {
|
|
37
|
+
formData.append("name", options.name);
|
|
38
|
+
}
|
|
39
|
+
if (options.description) {
|
|
40
|
+
formData.append("description", options.description);
|
|
41
|
+
}
|
|
42
|
+
if (options.trainer !== undefined) {
|
|
43
|
+
formData.append("trainer", options.trainer ? "1" : "0");
|
|
44
|
+
}
|
|
45
|
+
if (options.commute !== undefined) {
|
|
46
|
+
formData.append("commute", options.commute ? "1" : "0");
|
|
47
|
+
}
|
|
48
|
+
if (options.dataType) {
|
|
49
|
+
formData.append("data_type", options.dataType);
|
|
50
|
+
}
|
|
51
|
+
if (options.externalId) {
|
|
52
|
+
formData.append("external_id", options.externalId);
|
|
53
|
+
}
|
|
54
|
+
// Use direct fetch for multipart/form-data
|
|
55
|
+
const token = await this.getAccessToken();
|
|
56
|
+
const response = await fetch("https://www.strava.com/api/v3/uploads", {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Authorization": `Bearer ${token}`,
|
|
60
|
+
},
|
|
61
|
+
body: formData,
|
|
62
|
+
});
|
|
63
|
+
if (!response.ok) {
|
|
64
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
65
|
+
throw new Error(`Upload failed: ${error.message || response.statusText}`);
|
|
66
|
+
}
|
|
67
|
+
return await response.json();
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get upload by ID
|
|
71
|
+
*/
|
|
72
|
+
async getById(id) {
|
|
73
|
+
(0, validators_js_1.validatePositiveInteger)(id, "id");
|
|
74
|
+
return await this.client.request({
|
|
75
|
+
method: "GET",
|
|
76
|
+
path: `/uploads/${id}`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async getAccessToken() {
|
|
80
|
+
return await this.client.getAccessToken();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
exports.UploadsResource = UploadsResource;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API types - Re-exports and type aliases for generated types
|
|
3
|
+
*
|
|
4
|
+
* This file provides convenient access to all generated types from the Swagger specification.
|
|
5
|
+
* Types are automatically generated from https://developers.strava.com/swagger/swagger.json
|
|
6
|
+
*/
|
|
7
|
+
export * from "./generated.js";
|
|
8
|
+
export type { ActivityStats, ActivityTotal, ActivityType, ActivityZone, ClubActivity, ClubAnnouncement, ClubAthlete, Comment, DetailedActivity, DetailedActivity as Activity, DetailedAthlete as Athlete, DetailedClub as Club, DetailedGear as Gear, DetailedSegment as Segment, DetailedSegmentEffort as SegmentEffort, ExplorerResponse, ExplorerSegment, Fault, HeartRateZoneRanges, Lap, LatLng, MetaActivity, MetaAthlete, MetaClub, PhotosSummary, PolylineMap, PowerZoneRanges, Route, Split, SportType, StreamSet, StreamType, SummaryActivity, SummaryAthlete, SummaryClub, SummaryGear, SummaryPRSegmentEffort, SummarySegment, SummarySegmentEffort, UpdatableActivity, Upload, Waypoint, ZoneRange, ZoneRanges, Zones, } from "./generated.js";
|
|
9
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* API types - Re-exports and type aliases for generated types
|
|
4
|
+
*
|
|
5
|
+
* This file provides convenient access to all generated types from the Swagger specification.
|
|
6
|
+
* Types are automatically generated from https://developers.strava.com/swagger/swagger.json
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
20
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
|
+
};
|
|
22
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
+
__exportStar(require("./generated.js"), exports);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common types and interfaces for the Strava client
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Retry configuration for failed requests
|
|
6
|
+
*/
|
|
7
|
+
export interface RetryConfig {
|
|
8
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
9
|
+
maxAttempts?: number;
|
|
10
|
+
/** Initial delay in milliseconds (default: 1000) */
|
|
11
|
+
initialDelay?: number;
|
|
12
|
+
/** Maximum delay in milliseconds (default: 10000) */
|
|
13
|
+
maxDelay?: number;
|
|
14
|
+
/** Exponential backoff factor (default: 2) */
|
|
15
|
+
backoffFactor?: number;
|
|
16
|
+
/** HTTP status codes that should trigger retry (default: [429, 500, 502, 503, 504]) */
|
|
17
|
+
retryableStatusCodes?: number[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Rate limit strategy for handling rate limit errors
|
|
21
|
+
* - "queue": Queue requests and process when rate limit resets
|
|
22
|
+
* - "throw": Immediately throw error when rate limit is hit
|
|
23
|
+
* - "wait": Wait until rate limit resets before making request
|
|
24
|
+
*/
|
|
25
|
+
export type RateLimitStrategy = "queue" | "throw" | "wait";
|
|
26
|
+
/**
|
|
27
|
+
* HTTP request configuration
|
|
28
|
+
*/
|
|
29
|
+
export interface RequestConfig {
|
|
30
|
+
/** HTTP method */
|
|
31
|
+
method: string;
|
|
32
|
+
/** API path (without base URL) */
|
|
33
|
+
path: string;
|
|
34
|
+
/** Query parameters */
|
|
35
|
+
query?: Record<string, string | number | boolean | undefined>;
|
|
36
|
+
/** Request headers */
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
/** Request body */
|
|
39
|
+
body?: unknown;
|
|
40
|
+
/** Request timeout in milliseconds */
|
|
41
|
+
timeout?: number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Pagination options for list endpoints
|
|
45
|
+
*/
|
|
46
|
+
export interface PaginationOptions {
|
|
47
|
+
/** Page number (default: 1) */
|
|
48
|
+
page?: number;
|
|
49
|
+
/** Number of items per page (default: 30, max: 200) */
|
|
50
|
+
perPage?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Rate limit information from response headers
|
|
54
|
+
*/
|
|
55
|
+
export interface RateLimitInfo {
|
|
56
|
+
/** Short-term rate limit (15-minute window) */
|
|
57
|
+
shortTermLimit?: number;
|
|
58
|
+
/** Short-term usage count */
|
|
59
|
+
shortTermUsage?: number;
|
|
60
|
+
/** Daily rate limit */
|
|
61
|
+
dailyLimit?: number;
|
|
62
|
+
/** Daily usage count */
|
|
63
|
+
dailyUsage?: number;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=common.d.ts.map
|