suunto-api-wrapper 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +32 -38
- package/dist/index.d.ts +32 -38
- package/dist/index.js +122 -171
- package/dist/index.mjs +122 -160
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -81,6 +81,19 @@ interface LoginResponse {
|
|
|
81
81
|
[key: string]: unknown;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
interface AuthSessionInit {
|
|
85
|
+
email?: string;
|
|
86
|
+
sessionKey?: string;
|
|
87
|
+
}
|
|
88
|
+
declare class AuthSession {
|
|
89
|
+
private readonly XTOTP_HEADER;
|
|
90
|
+
private readonly AUTH_HEADER;
|
|
91
|
+
readonly email?: string;
|
|
92
|
+
readonly sessionKey?: string;
|
|
93
|
+
constructor(init?: AuthSessionInit);
|
|
94
|
+
applyTo(ctx: Pick<RequestContext, "headers">): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
declare const SPORTS_TRACKER_API = "https://api.sports-tracker.com";
|
|
85
98
|
declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36";
|
|
86
99
|
declare function login(options: LoginOptions): Promise<LoginResponse>;
|
|
@@ -646,18 +659,6 @@ interface WorkoutStatsResponse {
|
|
|
646
659
|
};
|
|
647
660
|
}
|
|
648
661
|
|
|
649
|
-
declare function getWorkouts(client: HttpClient, username: string, params?: GetWorkoutsParams): Promise<WorkoutsResponse>;
|
|
650
|
-
declare function getOwnWorkouts(client: HttpClient, params?: GetOwnWorkoutsParams): Promise<WorkoutsResponse>;
|
|
651
|
-
/**
|
|
652
|
-
* Public workouts whose center position falls inside the given geographic
|
|
653
|
-
* bounding box. Used by the "explore nearby" map view. Unauthenticated.
|
|
654
|
-
*/
|
|
655
|
-
declare function getWorkoutsWithin(client: HttpClient, params: GetWorkoutsWithinParams): Promise<WorkoutsWithinResponse>;
|
|
656
|
-
/**
|
|
657
|
-
* Aggregated workout stats per activity for a user. Unauthenticated — no
|
|
658
|
-
* session required.
|
|
659
|
-
*/
|
|
660
|
-
declare function getWorkoutStats(client: HttpClient, username: string): Promise<WorkoutStatsResponse>;
|
|
661
662
|
/** Workout endpoints, bound to an {@link HttpClient}. Accessed via `suunto.workouts`. */
|
|
662
663
|
declare class WorkoutsResource {
|
|
663
664
|
private readonly client;
|
|
@@ -676,17 +677,13 @@ declare class WorkoutsResource {
|
|
|
676
677
|
* unauthenticated.
|
|
677
678
|
*/
|
|
678
679
|
stats(username: string): Promise<WorkoutStatsResponse>;
|
|
679
|
-
/**
|
|
680
|
+
/**
|
|
681
|
+
* Public workouts whose center position falls inside the given geographic
|
|
682
|
+
* bounding box. Used by the "explore nearby" map view. Unauthenticated.
|
|
683
|
+
*/
|
|
680
684
|
within(params: GetWorkoutsWithinParams): Promise<WorkoutsWithinResponse>;
|
|
681
685
|
}
|
|
682
686
|
|
|
683
|
-
/**
|
|
684
|
-
* Fetch a user's public profile by username. Unauthenticated — no session
|
|
685
|
-
* required.
|
|
686
|
-
*/
|
|
687
|
-
declare function getUserByName(client: HttpClient, username: string): Promise<UserProfileResponse>;
|
|
688
|
-
/** Search for users by name/username. */
|
|
689
|
-
declare function searchUsers(client: HttpClient, searchTerms: string): Promise<UserSearchResponse>;
|
|
690
687
|
/** User endpoints, bound to an {@link HttpClient}. Accessed via `suunto.users`. */
|
|
691
688
|
declare class UsersResource {
|
|
692
689
|
private readonly client;
|
|
@@ -714,13 +711,11 @@ interface GearResponse {
|
|
|
714
711
|
};
|
|
715
712
|
}
|
|
716
713
|
|
|
717
|
-
/** A user's latest gear. */
|
|
718
|
-
declare function getLatestGear(client: HttpClient, username: string, params?: GetLatestGearParams): Promise<GearResponse>;
|
|
719
714
|
/** Gear endpoints, bound to an {@link HttpClient}. Accessed via `suunto.gear`. */
|
|
720
715
|
declare class GearResource {
|
|
721
716
|
private readonly client;
|
|
722
717
|
constructor(client: HttpClient);
|
|
723
|
-
/** A user's latest
|
|
718
|
+
/** A user's latest gear. */
|
|
724
719
|
latest(username: string, params?: GetLatestGearParams): Promise<GearResponse>;
|
|
725
720
|
}
|
|
726
721
|
|
|
@@ -790,25 +785,26 @@ type SleepStagesExportResponse = SleepStageInterval[];
|
|
|
790
785
|
type RecoveryExportResponse = RecoveryEntry[];
|
|
791
786
|
type ActivityExportResponse = ActivityEntry[];
|
|
792
787
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
/** Recovery entries (balance + stress state) from the 247 service. */
|
|
798
|
-
declare function getRecoveryExport(client: HttpClient, params?: ExportParams): Promise<RecoveryExportResponse>;
|
|
799
|
-
/** Daily activity entries from the 247 service. */
|
|
800
|
-
declare function getActivityExport(client: HttpClient, params?: ExportParams): Promise<ActivityExportResponse>;
|
|
788
|
+
interface WellnessResourceOptions extends Omit<HttpClientOptions, "beforeRequest" | "baseUrl"> {
|
|
789
|
+
auth: AuthSession;
|
|
790
|
+
baseUrl?: string;
|
|
791
|
+
}
|
|
801
792
|
/**
|
|
802
793
|
* Endpoints served by `https://247.sports-tracker.com` (sleep, recovery,
|
|
803
|
-
* activity).
|
|
804
|
-
*
|
|
794
|
+
* activity). Owns its own {@link HttpClient} configured against that host,
|
|
795
|
+
* including the wellness-specific wildcard accept header. Accessed via
|
|
796
|
+
* `suunto.wellness`.
|
|
805
797
|
*/
|
|
806
798
|
declare class WellnessResource {
|
|
807
|
-
|
|
808
|
-
constructor(
|
|
799
|
+
readonly http: HttpClient;
|
|
800
|
+
constructor(options: WellnessResourceOptions);
|
|
801
|
+
/** Sleep summaries from the 247 service. */
|
|
809
802
|
sleep(params?: ExportParams): Promise<SleepExportResponse>;
|
|
803
|
+
/** Per-stage sleep intervals from the 247 service. */
|
|
810
804
|
sleepStages(params?: ExportParams): Promise<SleepStagesExportResponse>;
|
|
805
|
+
/** Recovery entries (balance + stress state) from the 247 service. */
|
|
811
806
|
recovery(params?: ExportParams): Promise<RecoveryExportResponse>;
|
|
807
|
+
/** Daily activity entries from the 247 service. */
|
|
812
808
|
activity(params?: ExportParams): Promise<ActivityExportResponse>;
|
|
813
809
|
}
|
|
814
810
|
|
|
@@ -840,8 +836,6 @@ declare class SuuntoClient {
|
|
|
840
836
|
readonly http: HttpClient;
|
|
841
837
|
/** Session key in use, if the client was authenticated. */
|
|
842
838
|
readonly sessionKey?: string;
|
|
843
|
-
/** Dedicated HTTP client for the 247 host (sleep/recovery/activity). */
|
|
844
|
-
readonly http247: HttpClient;
|
|
845
839
|
readonly workouts: WorkoutsResource;
|
|
846
840
|
readonly users: UsersResource;
|
|
847
841
|
readonly gear: GearResource;
|
|
@@ -856,4 +850,4 @@ declare class SuuntoClient {
|
|
|
856
850
|
static unauthenticated(options?: Omit<SuuntoClientOptions, "email" | "sessionKey">): SuuntoClient;
|
|
857
851
|
}
|
|
858
852
|
|
|
859
|
-
export { type ActivityCounts, type ActivityData, type ActivityEntry, type ActivityExportResponse, type Cadence, type ClientCalculatedAchievements, type CumulativeAchievement, DEFAULT_USER_AGENT, type ExportEntry, type ExportParams, type FitnessExtension, type Gear, GearResource, type GearResponse, type GearSummary, type GetLatestGearParams, type GetOwnWorkoutsParams, type GetWorkoutsParams, type GetWorkoutsWithinParams, type HeartRateRecovery, type HrData, HttpClient, type HttpClientOptions, HttpError, type HttpResponse, type IntensityExtension, type IntensityZone, type IntensityZones, type LoginOptions, type LoginResponse, type PersonalBestAchievement, type Position, type Query, type Rankings, type RecoveryData, type RecoveryEntry, type RecoveryExportResponse, type RequestBody, type RequestContext, type RequestOptions, type RouteRanking, SPORTS_TRACKER_247_API, SPORTS_TRACKER_API, type SearchUser, type SleepExportResponse, type SleepStage, type SleepStageData, type SleepStageInterval, type SleepStagesExportResponse, type SleepSummary, type SleepSummaryData, type SummaryExtension, SuuntoActivityType, SuuntoClient, type SuuntoClientOptions, type SwimmingHeaderExtension, type TssEntry, type UserProfile, type UserProfileResponse, type UserSearchResponse, type UserSearchResult, UsersResource, type WeatherExtension, WellnessResource, type Workout, type WorkoutComment, type WorkoutExtension, type WorkoutReaction, type WorkoutStats, type WorkoutStatsEntry, type WorkoutStatsResponse, WorkoutsResource, type WorkoutsResponse, type WorkoutsWithinItem, type WorkoutsWithinResponse, generateXtotp,
|
|
853
|
+
export { type ActivityCounts, type ActivityData, type ActivityEntry, type ActivityExportResponse, type Cadence, type ClientCalculatedAchievements, type CumulativeAchievement, DEFAULT_USER_AGENT, type ExportEntry, type ExportParams, type FitnessExtension, type Gear, GearResource, type GearResponse, type GearSummary, type GetLatestGearParams, type GetOwnWorkoutsParams, type GetWorkoutsParams, type GetWorkoutsWithinParams, type HeartRateRecovery, type HrData, HttpClient, type HttpClientOptions, HttpError, type HttpResponse, type IntensityExtension, type IntensityZone, type IntensityZones, type LoginOptions, type LoginResponse, type PersonalBestAchievement, type Position, type Query, type Rankings, type RecoveryData, type RecoveryEntry, type RecoveryExportResponse, type RequestBody, type RequestContext, type RequestOptions, type RouteRanking, SPORTS_TRACKER_247_API, SPORTS_TRACKER_API, type SearchUser, type SleepExportResponse, type SleepStage, type SleepStageData, type SleepStageInterval, type SleepStagesExportResponse, type SleepSummary, type SleepSummaryData, type SummaryExtension, SuuntoActivityType, SuuntoClient, type SuuntoClientOptions, type SwimmingHeaderExtension, type TssEntry, type UserProfile, type UserProfileResponse, type UserSearchResponse, type UserSearchResult, UsersResource, type WeatherExtension, WellnessResource, type Workout, type WorkoutComment, type WorkoutExtension, type WorkoutReaction, type WorkoutStats, type WorkoutStatsEntry, type WorkoutStatsResponse, WorkoutsResource, type WorkoutsResponse, type WorkoutsWithinItem, type WorkoutsWithinResponse, generateXtotp, login, secondsUntilRollover, sessionTokenFrom };
|
package/dist/index.d.ts
CHANGED
|
@@ -81,6 +81,19 @@ interface LoginResponse {
|
|
|
81
81
|
[key: string]: unknown;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
interface AuthSessionInit {
|
|
85
|
+
email?: string;
|
|
86
|
+
sessionKey?: string;
|
|
87
|
+
}
|
|
88
|
+
declare class AuthSession {
|
|
89
|
+
private readonly XTOTP_HEADER;
|
|
90
|
+
private readonly AUTH_HEADER;
|
|
91
|
+
readonly email?: string;
|
|
92
|
+
readonly sessionKey?: string;
|
|
93
|
+
constructor(init?: AuthSessionInit);
|
|
94
|
+
applyTo(ctx: Pick<RequestContext, "headers">): Promise<void>;
|
|
95
|
+
}
|
|
96
|
+
|
|
84
97
|
declare const SPORTS_TRACKER_API = "https://api.sports-tracker.com";
|
|
85
98
|
declare const DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36";
|
|
86
99
|
declare function login(options: LoginOptions): Promise<LoginResponse>;
|
|
@@ -646,18 +659,6 @@ interface WorkoutStatsResponse {
|
|
|
646
659
|
};
|
|
647
660
|
}
|
|
648
661
|
|
|
649
|
-
declare function getWorkouts(client: HttpClient, username: string, params?: GetWorkoutsParams): Promise<WorkoutsResponse>;
|
|
650
|
-
declare function getOwnWorkouts(client: HttpClient, params?: GetOwnWorkoutsParams): Promise<WorkoutsResponse>;
|
|
651
|
-
/**
|
|
652
|
-
* Public workouts whose center position falls inside the given geographic
|
|
653
|
-
* bounding box. Used by the "explore nearby" map view. Unauthenticated.
|
|
654
|
-
*/
|
|
655
|
-
declare function getWorkoutsWithin(client: HttpClient, params: GetWorkoutsWithinParams): Promise<WorkoutsWithinResponse>;
|
|
656
|
-
/**
|
|
657
|
-
* Aggregated workout stats per activity for a user. Unauthenticated — no
|
|
658
|
-
* session required.
|
|
659
|
-
*/
|
|
660
|
-
declare function getWorkoutStats(client: HttpClient, username: string): Promise<WorkoutStatsResponse>;
|
|
661
662
|
/** Workout endpoints, bound to an {@link HttpClient}. Accessed via `suunto.workouts`. */
|
|
662
663
|
declare class WorkoutsResource {
|
|
663
664
|
private readonly client;
|
|
@@ -676,17 +677,13 @@ declare class WorkoutsResource {
|
|
|
676
677
|
* unauthenticated.
|
|
677
678
|
*/
|
|
678
679
|
stats(username: string): Promise<WorkoutStatsResponse>;
|
|
679
|
-
/**
|
|
680
|
+
/**
|
|
681
|
+
* Public workouts whose center position falls inside the given geographic
|
|
682
|
+
* bounding box. Used by the "explore nearby" map view. Unauthenticated.
|
|
683
|
+
*/
|
|
680
684
|
within(params: GetWorkoutsWithinParams): Promise<WorkoutsWithinResponse>;
|
|
681
685
|
}
|
|
682
686
|
|
|
683
|
-
/**
|
|
684
|
-
* Fetch a user's public profile by username. Unauthenticated — no session
|
|
685
|
-
* required.
|
|
686
|
-
*/
|
|
687
|
-
declare function getUserByName(client: HttpClient, username: string): Promise<UserProfileResponse>;
|
|
688
|
-
/** Search for users by name/username. */
|
|
689
|
-
declare function searchUsers(client: HttpClient, searchTerms: string): Promise<UserSearchResponse>;
|
|
690
687
|
/** User endpoints, bound to an {@link HttpClient}. Accessed via `suunto.users`. */
|
|
691
688
|
declare class UsersResource {
|
|
692
689
|
private readonly client;
|
|
@@ -714,13 +711,11 @@ interface GearResponse {
|
|
|
714
711
|
};
|
|
715
712
|
}
|
|
716
713
|
|
|
717
|
-
/** A user's latest gear. */
|
|
718
|
-
declare function getLatestGear(client: HttpClient, username: string, params?: GetLatestGearParams): Promise<GearResponse>;
|
|
719
714
|
/** Gear endpoints, bound to an {@link HttpClient}. Accessed via `suunto.gear`. */
|
|
720
715
|
declare class GearResource {
|
|
721
716
|
private readonly client;
|
|
722
717
|
constructor(client: HttpClient);
|
|
723
|
-
/** A user's latest
|
|
718
|
+
/** A user's latest gear. */
|
|
724
719
|
latest(username: string, params?: GetLatestGearParams): Promise<GearResponse>;
|
|
725
720
|
}
|
|
726
721
|
|
|
@@ -790,25 +785,26 @@ type SleepStagesExportResponse = SleepStageInterval[];
|
|
|
790
785
|
type RecoveryExportResponse = RecoveryEntry[];
|
|
791
786
|
type ActivityExportResponse = ActivityEntry[];
|
|
792
787
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
/** Recovery entries (balance + stress state) from the 247 service. */
|
|
798
|
-
declare function getRecoveryExport(client: HttpClient, params?: ExportParams): Promise<RecoveryExportResponse>;
|
|
799
|
-
/** Daily activity entries from the 247 service. */
|
|
800
|
-
declare function getActivityExport(client: HttpClient, params?: ExportParams): Promise<ActivityExportResponse>;
|
|
788
|
+
interface WellnessResourceOptions extends Omit<HttpClientOptions, "beforeRequest" | "baseUrl"> {
|
|
789
|
+
auth: AuthSession;
|
|
790
|
+
baseUrl?: string;
|
|
791
|
+
}
|
|
801
792
|
/**
|
|
802
793
|
* Endpoints served by `https://247.sports-tracker.com` (sleep, recovery,
|
|
803
|
-
* activity).
|
|
804
|
-
*
|
|
794
|
+
* activity). Owns its own {@link HttpClient} configured against that host,
|
|
795
|
+
* including the wellness-specific wildcard accept header. Accessed via
|
|
796
|
+
* `suunto.wellness`.
|
|
805
797
|
*/
|
|
806
798
|
declare class WellnessResource {
|
|
807
|
-
|
|
808
|
-
constructor(
|
|
799
|
+
readonly http: HttpClient;
|
|
800
|
+
constructor(options: WellnessResourceOptions);
|
|
801
|
+
/** Sleep summaries from the 247 service. */
|
|
809
802
|
sleep(params?: ExportParams): Promise<SleepExportResponse>;
|
|
803
|
+
/** Per-stage sleep intervals from the 247 service. */
|
|
810
804
|
sleepStages(params?: ExportParams): Promise<SleepStagesExportResponse>;
|
|
805
|
+
/** Recovery entries (balance + stress state) from the 247 service. */
|
|
811
806
|
recovery(params?: ExportParams): Promise<RecoveryExportResponse>;
|
|
807
|
+
/** Daily activity entries from the 247 service. */
|
|
812
808
|
activity(params?: ExportParams): Promise<ActivityExportResponse>;
|
|
813
809
|
}
|
|
814
810
|
|
|
@@ -840,8 +836,6 @@ declare class SuuntoClient {
|
|
|
840
836
|
readonly http: HttpClient;
|
|
841
837
|
/** Session key in use, if the client was authenticated. */
|
|
842
838
|
readonly sessionKey?: string;
|
|
843
|
-
/** Dedicated HTTP client for the 247 host (sleep/recovery/activity). */
|
|
844
|
-
readonly http247: HttpClient;
|
|
845
839
|
readonly workouts: WorkoutsResource;
|
|
846
840
|
readonly users: UsersResource;
|
|
847
841
|
readonly gear: GearResource;
|
|
@@ -856,4 +850,4 @@ declare class SuuntoClient {
|
|
|
856
850
|
static unauthenticated(options?: Omit<SuuntoClientOptions, "email" | "sessionKey">): SuuntoClient;
|
|
857
851
|
}
|
|
858
852
|
|
|
859
|
-
export { type ActivityCounts, type ActivityData, type ActivityEntry, type ActivityExportResponse, type Cadence, type ClientCalculatedAchievements, type CumulativeAchievement, DEFAULT_USER_AGENT, type ExportEntry, type ExportParams, type FitnessExtension, type Gear, GearResource, type GearResponse, type GearSummary, type GetLatestGearParams, type GetOwnWorkoutsParams, type GetWorkoutsParams, type GetWorkoutsWithinParams, type HeartRateRecovery, type HrData, HttpClient, type HttpClientOptions, HttpError, type HttpResponse, type IntensityExtension, type IntensityZone, type IntensityZones, type LoginOptions, type LoginResponse, type PersonalBestAchievement, type Position, type Query, type Rankings, type RecoveryData, type RecoveryEntry, type RecoveryExportResponse, type RequestBody, type RequestContext, type RequestOptions, type RouteRanking, SPORTS_TRACKER_247_API, SPORTS_TRACKER_API, type SearchUser, type SleepExportResponse, type SleepStage, type SleepStageData, type SleepStageInterval, type SleepStagesExportResponse, type SleepSummary, type SleepSummaryData, type SummaryExtension, SuuntoActivityType, SuuntoClient, type SuuntoClientOptions, type SwimmingHeaderExtension, type TssEntry, type UserProfile, type UserProfileResponse, type UserSearchResponse, type UserSearchResult, UsersResource, type WeatherExtension, WellnessResource, type Workout, type WorkoutComment, type WorkoutExtension, type WorkoutReaction, type WorkoutStats, type WorkoutStatsEntry, type WorkoutStatsResponse, WorkoutsResource, type WorkoutsResponse, type WorkoutsWithinItem, type WorkoutsWithinResponse, generateXtotp,
|
|
853
|
+
export { type ActivityCounts, type ActivityData, type ActivityEntry, type ActivityExportResponse, type Cadence, type ClientCalculatedAchievements, type CumulativeAchievement, DEFAULT_USER_AGENT, type ExportEntry, type ExportParams, type FitnessExtension, type Gear, GearResource, type GearResponse, type GearSummary, type GetLatestGearParams, type GetOwnWorkoutsParams, type GetWorkoutsParams, type GetWorkoutsWithinParams, type HeartRateRecovery, type HrData, HttpClient, type HttpClientOptions, HttpError, type HttpResponse, type IntensityExtension, type IntensityZone, type IntensityZones, type LoginOptions, type LoginResponse, type PersonalBestAchievement, type Position, type Query, type Rankings, type RecoveryData, type RecoveryEntry, type RecoveryExportResponse, type RequestBody, type RequestContext, type RequestOptions, type RouteRanking, SPORTS_TRACKER_247_API, SPORTS_TRACKER_API, type SearchUser, type SleepExportResponse, type SleepStage, type SleepStageData, type SleepStageInterval, type SleepStagesExportResponse, type SleepSummary, type SleepSummaryData, type SummaryExtension, SuuntoActivityType, SuuntoClient, type SuuntoClientOptions, type SwimmingHeaderExtension, type TssEntry, type UserProfile, type UserProfileResponse, type UserSearchResponse, type UserSearchResult, UsersResource, type WeatherExtension, WellnessResource, type Workout, type WorkoutComment, type WorkoutExtension, type WorkoutReaction, type WorkoutStats, type WorkoutStatsEntry, type WorkoutStatsResponse, WorkoutsResource, type WorkoutsResponse, type WorkoutsWithinItem, type WorkoutsWithinResponse, generateXtotp, login, secondsUntilRollover, sessionTokenFrom };
|
package/dist/index.js
CHANGED
|
@@ -32,18 +32,7 @@ __export(index_exports, {
|
|
|
32
32
|
WellnessResource: () => WellnessResource,
|
|
33
33
|
WorkoutsResource: () => WorkoutsResource,
|
|
34
34
|
generateXtotp: () => generateXtotp,
|
|
35
|
-
getActivityExport: () => getActivityExport,
|
|
36
|
-
getLatestGear: () => getLatestGear,
|
|
37
|
-
getOwnWorkouts: () => getOwnWorkouts,
|
|
38
|
-
getRecoveryExport: () => getRecoveryExport,
|
|
39
|
-
getSleepExport: () => getSleepExport,
|
|
40
|
-
getSleepStagesExport: () => getSleepStagesExport,
|
|
41
|
-
getUserByName: () => getUserByName,
|
|
42
|
-
getWorkoutStats: () => getWorkoutStats,
|
|
43
|
-
getWorkouts: () => getWorkouts,
|
|
44
|
-
getWorkoutsWithin: () => getWorkoutsWithin,
|
|
45
35
|
login: () => login,
|
|
46
|
-
searchUsers: () => searchUsers,
|
|
47
36
|
secondsUntilRollover: () => secondsUntilRollover,
|
|
48
37
|
sessionTokenFrom: () => sessionTokenFrom
|
|
49
38
|
});
|
|
@@ -61,6 +50,12 @@ var HttpError = class extends Error {
|
|
|
61
50
|
}
|
|
62
51
|
};
|
|
63
52
|
|
|
53
|
+
// src/http/endpoint.ts
|
|
54
|
+
async function endpoint(client, spec) {
|
|
55
|
+
const res = spec.query === void 0 ? await client.get(spec.path) : await client.get(spec.path, { query: spec.query });
|
|
56
|
+
return res.data;
|
|
57
|
+
}
|
|
58
|
+
|
|
64
59
|
// src/http/index.ts
|
|
65
60
|
var DEFAULTS = {
|
|
66
61
|
timeoutMs: 3e4,
|
|
@@ -273,6 +268,20 @@ function secondsUntilRollover(now = Date.now()) {
|
|
|
273
268
|
return periodSeconds - Math.floor(now / 1e3) % periodSeconds;
|
|
274
269
|
}
|
|
275
270
|
|
|
271
|
+
// src/auth/session.ts
|
|
272
|
+
var AuthSession = class {
|
|
273
|
+
constructor(init = {}) {
|
|
274
|
+
this.XTOTP_HEADER = "x-totp";
|
|
275
|
+
this.AUTH_HEADER = "sttauthorization";
|
|
276
|
+
this.email = init.email;
|
|
277
|
+
this.sessionKey = init.sessionKey;
|
|
278
|
+
}
|
|
279
|
+
async applyTo(ctx) {
|
|
280
|
+
if (this.email) ctx.headers[this.XTOTP_HEADER] = await generateXtotp(this.email);
|
|
281
|
+
if (this.sessionKey) ctx.headers[this.AUTH_HEADER] = this.sessionKey;
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
|
|
276
285
|
// src/auth/index.ts
|
|
277
286
|
var SPORTS_TRACKER_API = "https://api.sports-tracker.com";
|
|
278
287
|
var DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36";
|
|
@@ -288,13 +297,14 @@ async function login(options) {
|
|
|
288
297
|
} = options;
|
|
289
298
|
const http = new HttpClient({ baseUrl, fetch: fetchImpl, timeoutMs });
|
|
290
299
|
const body = new URLSearchParams({ l: email, p: password, version });
|
|
300
|
+
const headers = {
|
|
301
|
+
"user-agent": userAgent,
|
|
302
|
+
"content-type": "application/x-www-form-urlencoded"
|
|
303
|
+
};
|
|
304
|
+
await new AuthSession({ email }).applyTo({ headers });
|
|
291
305
|
const response = await http.post("/apiserver/v1/login2", {
|
|
292
306
|
body,
|
|
293
|
-
headers
|
|
294
|
-
"user-agent": userAgent,
|
|
295
|
-
"x-totp": await generateXtotp(email),
|
|
296
|
-
"content-type": "application/x-www-form-urlencoded"
|
|
297
|
-
}
|
|
307
|
+
headers
|
|
298
308
|
});
|
|
299
309
|
return response.data;
|
|
300
310
|
}
|
|
@@ -439,138 +449,100 @@ var DEFAULT_WORKOUT_ADDITIONAL_DATA = [
|
|
|
439
449
|
"comments" /* Comments */,
|
|
440
450
|
"user_reacted" /* UserReacted */
|
|
441
451
|
];
|
|
442
|
-
async function getWorkouts(client, username, params = {}) {
|
|
443
|
-
const { limit = 40, sortonst = true } = params;
|
|
444
|
-
const res = await client.get(
|
|
445
|
-
`/apiserver/v1/workouts/${encodeURIComponent(username)}/public`,
|
|
446
|
-
{ query: { limit, sortonst } }
|
|
447
|
-
);
|
|
448
|
-
return res.data;
|
|
449
|
-
}
|
|
450
|
-
async function getOwnWorkouts(client, params = {}) {
|
|
451
|
-
const { offset = 0, limit = 50, since = 0 } = params;
|
|
452
|
-
const searchParams = new URLSearchParams();
|
|
453
|
-
searchParams.append("offset", String(offset));
|
|
454
|
-
searchParams.append("limit", String(limit));
|
|
455
|
-
searchParams.append("since", String(since));
|
|
456
|
-
const res = await client.get(
|
|
457
|
-
`/apiserver/v1/workouts?${searchParams.toString()}`
|
|
458
|
-
);
|
|
459
|
-
return res.data;
|
|
460
|
-
}
|
|
461
|
-
async function getWorkout(client, username, workoutKey, params = {}) {
|
|
462
|
-
const {
|
|
463
|
-
extensions = DEFAULT_WORKOUT_EXTENSIONS,
|
|
464
|
-
additionalData = DEFAULT_WORKOUT_ADDITIONAL_DATA
|
|
465
|
-
} = params;
|
|
466
|
-
const res = await client.get(
|
|
467
|
-
`/apiserver/v2/workouts/${encodeURIComponent(username)}/${encodeURIComponent(workoutKey)}/combined`,
|
|
468
|
-
{
|
|
469
|
-
query: {
|
|
470
|
-
extensions: extensions.join(","),
|
|
471
|
-
additionalData: additionalData.join(",")
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
);
|
|
475
|
-
return res.data;
|
|
476
|
-
}
|
|
477
|
-
async function getWorkoutsWithin(client, params) {
|
|
478
|
-
const { lowerLat, lowerLng, upperLat, upperLng, limit = 50 } = params;
|
|
479
|
-
const res = await client.get(
|
|
480
|
-
"/apiserver/v1/workouts/public/within",
|
|
481
|
-
{
|
|
482
|
-
query: {
|
|
483
|
-
lowerlat: lowerLat,
|
|
484
|
-
lowerlng: lowerLng,
|
|
485
|
-
upperlat: upperLat,
|
|
486
|
-
upperlng: upperLng,
|
|
487
|
-
limit
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
);
|
|
491
|
-
return res.data;
|
|
492
|
-
}
|
|
493
|
-
async function getWorkoutStats(client, username) {
|
|
494
|
-
const res = await client.get(
|
|
495
|
-
`/apiserver/v1/workouts/${encodeURIComponent(username)}/stats`
|
|
496
|
-
);
|
|
497
|
-
return res.data;
|
|
498
|
-
}
|
|
499
452
|
var WorkoutsResource = class {
|
|
500
453
|
constructor(client) {
|
|
501
454
|
this.client = client;
|
|
502
455
|
}
|
|
503
456
|
/** The authenticated user's own workouts. */
|
|
504
|
-
own(params) {
|
|
505
|
-
return
|
|
457
|
+
own(params = {}) {
|
|
458
|
+
return endpoint(this.client, {
|
|
459
|
+
path: "/apiserver/v1/workouts",
|
|
460
|
+
query: {
|
|
461
|
+
offset: params.offset ?? 0,
|
|
462
|
+
limit: params.limit ?? 50,
|
|
463
|
+
since: params.since ?? 0
|
|
464
|
+
}
|
|
465
|
+
});
|
|
506
466
|
}
|
|
507
467
|
/** A given user's public workouts. */
|
|
508
|
-
public(username, params) {
|
|
509
|
-
return
|
|
468
|
+
public(username, params = {}) {
|
|
469
|
+
return endpoint(this.client, {
|
|
470
|
+
path: `/apiserver/v1/workouts/${encodeURIComponent(username)}/public`,
|
|
471
|
+
query: { limit: params.limit ?? 40, sortonst: params.sortonst ?? true }
|
|
472
|
+
});
|
|
510
473
|
}
|
|
511
474
|
/**
|
|
512
475
|
* A single workout by username and workout key. Works for any public workout
|
|
513
476
|
* and, when the client is authenticated as the owner, for private ones too.
|
|
514
477
|
*/
|
|
515
|
-
byKey(username, workoutKey, params) {
|
|
516
|
-
|
|
478
|
+
byKey(username, workoutKey, params = {}) {
|
|
479
|
+
const extensions = params.extensions ?? DEFAULT_WORKOUT_EXTENSIONS;
|
|
480
|
+
const additionalData = params.additionalData ?? DEFAULT_WORKOUT_ADDITIONAL_DATA;
|
|
481
|
+
return endpoint(this.client, {
|
|
482
|
+
path: `/apiserver/v2/workouts/${encodeURIComponent(username)}/${encodeURIComponent(workoutKey)}/combined`,
|
|
483
|
+
query: {
|
|
484
|
+
extensions: extensions.join(","),
|
|
485
|
+
additionalData: additionalData.join(",")
|
|
486
|
+
}
|
|
487
|
+
});
|
|
517
488
|
}
|
|
518
489
|
/**
|
|
519
490
|
* Aggregated workout stats per activity for the given user. Works
|
|
520
491
|
* unauthenticated.
|
|
521
492
|
*/
|
|
522
493
|
stats(username) {
|
|
523
|
-
return
|
|
494
|
+
return endpoint(this.client, {
|
|
495
|
+
path: `/apiserver/v1/workouts/${encodeURIComponent(username)}/stats`
|
|
496
|
+
});
|
|
524
497
|
}
|
|
525
|
-
/**
|
|
498
|
+
/**
|
|
499
|
+
* Public workouts whose center position falls inside the given geographic
|
|
500
|
+
* bounding box. Used by the "explore nearby" map view. Unauthenticated.
|
|
501
|
+
*/
|
|
526
502
|
within(params) {
|
|
527
|
-
return
|
|
503
|
+
return endpoint(this.client, {
|
|
504
|
+
path: "/apiserver/v1/workouts/public/within",
|
|
505
|
+
query: {
|
|
506
|
+
lowerlat: params.lowerLat,
|
|
507
|
+
lowerlng: params.lowerLng,
|
|
508
|
+
upperlat: params.upperLat,
|
|
509
|
+
upperlng: params.upperLng,
|
|
510
|
+
limit: params.limit ?? 50
|
|
511
|
+
}
|
|
512
|
+
});
|
|
528
513
|
}
|
|
529
514
|
};
|
|
530
515
|
|
|
531
516
|
// src/users/index.ts
|
|
532
|
-
async function getUserByName(client, username) {
|
|
533
|
-
const res = await client.get(
|
|
534
|
-
`/apiserver/v1/user/name/${encodeURIComponent(username)}`
|
|
535
|
-
);
|
|
536
|
-
return res.data;
|
|
537
|
-
}
|
|
538
|
-
async function searchUsers(client, searchTerms) {
|
|
539
|
-
const res = await client.get(
|
|
540
|
-
`/apiserver/v1/user/search/${encodeURIComponent(searchTerms)}`
|
|
541
|
-
);
|
|
542
|
-
return res.data;
|
|
543
|
-
}
|
|
544
517
|
var UsersResource = class {
|
|
545
518
|
constructor(client) {
|
|
546
519
|
this.client = client;
|
|
547
520
|
}
|
|
548
521
|
/** A user's public profile, by username. */
|
|
549
522
|
byName(username) {
|
|
550
|
-
return
|
|
523
|
+
return endpoint(this.client, {
|
|
524
|
+
path: `/apiserver/v1/user/name/${encodeURIComponent(username)}`
|
|
525
|
+
});
|
|
551
526
|
}
|
|
552
527
|
/** Search for users by name/username. */
|
|
553
528
|
search(searchTerms) {
|
|
554
|
-
return
|
|
529
|
+
return endpoint(this.client, {
|
|
530
|
+
path: `/apiserver/v1/user/search/${encodeURIComponent(searchTerms)}`
|
|
531
|
+
});
|
|
555
532
|
}
|
|
556
533
|
};
|
|
557
534
|
|
|
558
535
|
// src/gear/index.ts
|
|
559
|
-
async function getLatestGear(client, username, params = {}) {
|
|
560
|
-
const { allTypes = true } = params;
|
|
561
|
-
const res = await client.get(
|
|
562
|
-
`/apiserver/v1/gear/${encodeURIComponent(username)}/latest`,
|
|
563
|
-
{ query: { allTypes } }
|
|
564
|
-
);
|
|
565
|
-
return res.data;
|
|
566
|
-
}
|
|
567
536
|
var GearResource = class {
|
|
568
537
|
constructor(client) {
|
|
569
538
|
this.client = client;
|
|
570
539
|
}
|
|
571
|
-
/** A user's latest
|
|
572
|
-
latest(username, params) {
|
|
573
|
-
return
|
|
540
|
+
/** A user's latest gear. */
|
|
541
|
+
latest(username, params = {}) {
|
|
542
|
+
return endpoint(this.client, {
|
|
543
|
+
path: `/apiserver/v1/gear/${encodeURIComponent(username)}/latest`,
|
|
544
|
+
query: { allTypes: params.allTypes ?? true }
|
|
545
|
+
});
|
|
574
546
|
}
|
|
575
547
|
};
|
|
576
548
|
|
|
@@ -578,49 +550,46 @@ var GearResource = class {
|
|
|
578
550
|
var SPORTS_TRACKER_247_API = "https://247.sports-tracker.com";
|
|
579
551
|
|
|
580
552
|
// src/wellness/index.ts
|
|
581
|
-
|
|
582
|
-
return params.since == null ? void 0 : { since: params.since };
|
|
583
|
-
}
|
|
584
|
-
async function getSleepExport(client, params = {}) {
|
|
585
|
-
const res = await client.get("/v1/sleep/export", {
|
|
586
|
-
query: exportQuery(params)
|
|
587
|
-
});
|
|
588
|
-
return res.data;
|
|
589
|
-
}
|
|
590
|
-
async function getSleepStagesExport(client, params = {}) {
|
|
591
|
-
const res = await client.get(
|
|
592
|
-
"/v1/sleepstages/export",
|
|
593
|
-
{ query: exportQuery(params) }
|
|
594
|
-
);
|
|
595
|
-
return res.data;
|
|
596
|
-
}
|
|
597
|
-
async function getRecoveryExport(client, params = {}) {
|
|
598
|
-
const res = await client.get("/v1/recovery/export", {
|
|
599
|
-
query: exportQuery(params)
|
|
600
|
-
});
|
|
601
|
-
return res.data;
|
|
602
|
-
}
|
|
603
|
-
async function getActivityExport(client, params = {}) {
|
|
604
|
-
const res = await client.get("/v1/activity/export", {
|
|
605
|
-
query: exportQuery(params)
|
|
606
|
-
});
|
|
607
|
-
return res.data;
|
|
608
|
-
}
|
|
553
|
+
var exportQuery = (params) => params.since == null ? void 0 : { since: params.since };
|
|
609
554
|
var WellnessResource = class {
|
|
610
|
-
constructor(
|
|
611
|
-
|
|
555
|
+
constructor(options) {
|
|
556
|
+
const { auth, baseUrl, ...rest } = options;
|
|
557
|
+
this.http = new HttpClient({
|
|
558
|
+
...rest,
|
|
559
|
+
baseUrl: baseUrl ?? SPORTS_TRACKER_247_API,
|
|
560
|
+
beforeRequest: async (ctx) => {
|
|
561
|
+
await auth.applyTo(ctx);
|
|
562
|
+
ctx.headers["accept"] = "*/*";
|
|
563
|
+
}
|
|
564
|
+
});
|
|
612
565
|
}
|
|
613
|
-
|
|
614
|
-
|
|
566
|
+
/** Sleep summaries from the 247 service. */
|
|
567
|
+
sleep(params = {}) {
|
|
568
|
+
return endpoint(this.http, {
|
|
569
|
+
path: "/v1/sleep/export",
|
|
570
|
+
query: exportQuery(params)
|
|
571
|
+
});
|
|
615
572
|
}
|
|
616
|
-
|
|
617
|
-
|
|
573
|
+
/** Per-stage sleep intervals from the 247 service. */
|
|
574
|
+
sleepStages(params = {}) {
|
|
575
|
+
return endpoint(this.http, {
|
|
576
|
+
path: "/v1/sleepstages/export",
|
|
577
|
+
query: exportQuery(params)
|
|
578
|
+
});
|
|
618
579
|
}
|
|
619
|
-
|
|
620
|
-
|
|
580
|
+
/** Recovery entries (balance + stress state) from the 247 service. */
|
|
581
|
+
recovery(params = {}) {
|
|
582
|
+
return endpoint(this.http, {
|
|
583
|
+
path: "/v1/recovery/export",
|
|
584
|
+
query: exportQuery(params)
|
|
585
|
+
});
|
|
621
586
|
}
|
|
622
|
-
activity
|
|
623
|
-
|
|
587
|
+
/** Daily activity entries from the 247 service. */
|
|
588
|
+
activity(params = {}) {
|
|
589
|
+
return endpoint(this.http, {
|
|
590
|
+
path: "/v1/activity/export",
|
|
591
|
+
query: exportQuery(params)
|
|
592
|
+
});
|
|
624
593
|
}
|
|
625
594
|
};
|
|
626
595
|
|
|
@@ -637,30 +606,23 @@ var SuuntoClient = class _SuuntoClient {
|
|
|
637
606
|
...rest
|
|
638
607
|
} = options;
|
|
639
608
|
this.sessionKey = sessionKey;
|
|
640
|
-
const
|
|
641
|
-
if (email) ctx.headers["x-totp"] = await generateXtotp(email);
|
|
642
|
-
if (sessionKey) ctx.headers["sttauthorization"] = sessionKey;
|
|
643
|
-
};
|
|
609
|
+
const auth = new AuthSession({ email, sessionKey });
|
|
644
610
|
const sharedHeaders = { "user-agent": userAgent, ...headers };
|
|
645
611
|
this.http = new HttpClient({
|
|
646
612
|
baseUrl: baseUrl ?? SPORTS_TRACKER_API,
|
|
647
613
|
headers: sharedHeaders,
|
|
648
614
|
...rest,
|
|
649
|
-
beforeRequest
|
|
650
|
-
});
|
|
651
|
-
this.http247 = new HttpClient({
|
|
652
|
-
baseUrl: baseUrl247 ?? SPORTS_TRACKER_247_API,
|
|
653
|
-
headers: sharedHeaders,
|
|
654
|
-
...rest,
|
|
655
|
-
beforeRequest: async (ctx) => {
|
|
656
|
-
await beforeRequest(ctx);
|
|
657
|
-
ctx.headers["accept"] = "*/*";
|
|
658
|
-
}
|
|
615
|
+
beforeRequest: (ctx) => auth.applyTo(ctx)
|
|
659
616
|
});
|
|
660
617
|
this.workouts = new WorkoutsResource(this.http);
|
|
661
618
|
this.users = new UsersResource(this.http);
|
|
662
619
|
this.gear = new GearResource(this.http);
|
|
663
|
-
this.wellness = new WellnessResource(
|
|
620
|
+
this.wellness = new WellnessResource({
|
|
621
|
+
auth,
|
|
622
|
+
baseUrl: baseUrl247,
|
|
623
|
+
headers: sharedHeaders,
|
|
624
|
+
...rest
|
|
625
|
+
});
|
|
664
626
|
}
|
|
665
627
|
/** Log in with email/password and return an authenticated client. */
|
|
666
628
|
static async login(options) {
|
|
@@ -691,18 +653,7 @@ var SuuntoClient = class _SuuntoClient {
|
|
|
691
653
|
WellnessResource,
|
|
692
654
|
WorkoutsResource,
|
|
693
655
|
generateXtotp,
|
|
694
|
-
getActivityExport,
|
|
695
|
-
getLatestGear,
|
|
696
|
-
getOwnWorkouts,
|
|
697
|
-
getRecoveryExport,
|
|
698
|
-
getSleepExport,
|
|
699
|
-
getSleepStagesExport,
|
|
700
|
-
getUserByName,
|
|
701
|
-
getWorkoutStats,
|
|
702
|
-
getWorkouts,
|
|
703
|
-
getWorkoutsWithin,
|
|
704
656
|
login,
|
|
705
|
-
searchUsers,
|
|
706
657
|
secondsUntilRollover,
|
|
707
658
|
sessionTokenFrom
|
|
708
659
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -10,6 +10,12 @@ var HttpError = class extends Error {
|
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
+
// src/http/endpoint.ts
|
|
14
|
+
async function endpoint(client, spec) {
|
|
15
|
+
const res = spec.query === void 0 ? await client.get(spec.path) : await client.get(spec.path, { query: spec.query });
|
|
16
|
+
return res.data;
|
|
17
|
+
}
|
|
18
|
+
|
|
13
19
|
// src/http/index.ts
|
|
14
20
|
var DEFAULTS = {
|
|
15
21
|
timeoutMs: 3e4,
|
|
@@ -222,6 +228,20 @@ function secondsUntilRollover(now = Date.now()) {
|
|
|
222
228
|
return periodSeconds - Math.floor(now / 1e3) % periodSeconds;
|
|
223
229
|
}
|
|
224
230
|
|
|
231
|
+
// src/auth/session.ts
|
|
232
|
+
var AuthSession = class {
|
|
233
|
+
constructor(init = {}) {
|
|
234
|
+
this.XTOTP_HEADER = "x-totp";
|
|
235
|
+
this.AUTH_HEADER = "sttauthorization";
|
|
236
|
+
this.email = init.email;
|
|
237
|
+
this.sessionKey = init.sessionKey;
|
|
238
|
+
}
|
|
239
|
+
async applyTo(ctx) {
|
|
240
|
+
if (this.email) ctx.headers[this.XTOTP_HEADER] = await generateXtotp(this.email);
|
|
241
|
+
if (this.sessionKey) ctx.headers[this.AUTH_HEADER] = this.sessionKey;
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
|
|
225
245
|
// src/auth/index.ts
|
|
226
246
|
var SPORTS_TRACKER_API = "https://api.sports-tracker.com";
|
|
227
247
|
var DEFAULT_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36";
|
|
@@ -237,13 +257,14 @@ async function login(options) {
|
|
|
237
257
|
} = options;
|
|
238
258
|
const http = new HttpClient({ baseUrl, fetch: fetchImpl, timeoutMs });
|
|
239
259
|
const body = new URLSearchParams({ l: email, p: password, version });
|
|
260
|
+
const headers = {
|
|
261
|
+
"user-agent": userAgent,
|
|
262
|
+
"content-type": "application/x-www-form-urlencoded"
|
|
263
|
+
};
|
|
264
|
+
await new AuthSession({ email }).applyTo({ headers });
|
|
240
265
|
const response = await http.post("/apiserver/v1/login2", {
|
|
241
266
|
body,
|
|
242
|
-
headers
|
|
243
|
-
"user-agent": userAgent,
|
|
244
|
-
"x-totp": await generateXtotp(email),
|
|
245
|
-
"content-type": "application/x-www-form-urlencoded"
|
|
246
|
-
}
|
|
267
|
+
headers
|
|
247
268
|
});
|
|
248
269
|
return response.data;
|
|
249
270
|
}
|
|
@@ -388,138 +409,100 @@ var DEFAULT_WORKOUT_ADDITIONAL_DATA = [
|
|
|
388
409
|
"comments" /* Comments */,
|
|
389
410
|
"user_reacted" /* UserReacted */
|
|
390
411
|
];
|
|
391
|
-
async function getWorkouts(client, username, params = {}) {
|
|
392
|
-
const { limit = 40, sortonst = true } = params;
|
|
393
|
-
const res = await client.get(
|
|
394
|
-
`/apiserver/v1/workouts/${encodeURIComponent(username)}/public`,
|
|
395
|
-
{ query: { limit, sortonst } }
|
|
396
|
-
);
|
|
397
|
-
return res.data;
|
|
398
|
-
}
|
|
399
|
-
async function getOwnWorkouts(client, params = {}) {
|
|
400
|
-
const { offset = 0, limit = 50, since = 0 } = params;
|
|
401
|
-
const searchParams = new URLSearchParams();
|
|
402
|
-
searchParams.append("offset", String(offset));
|
|
403
|
-
searchParams.append("limit", String(limit));
|
|
404
|
-
searchParams.append("since", String(since));
|
|
405
|
-
const res = await client.get(
|
|
406
|
-
`/apiserver/v1/workouts?${searchParams.toString()}`
|
|
407
|
-
);
|
|
408
|
-
return res.data;
|
|
409
|
-
}
|
|
410
|
-
async function getWorkout(client, username, workoutKey, params = {}) {
|
|
411
|
-
const {
|
|
412
|
-
extensions = DEFAULT_WORKOUT_EXTENSIONS,
|
|
413
|
-
additionalData = DEFAULT_WORKOUT_ADDITIONAL_DATA
|
|
414
|
-
} = params;
|
|
415
|
-
const res = await client.get(
|
|
416
|
-
`/apiserver/v2/workouts/${encodeURIComponent(username)}/${encodeURIComponent(workoutKey)}/combined`,
|
|
417
|
-
{
|
|
418
|
-
query: {
|
|
419
|
-
extensions: extensions.join(","),
|
|
420
|
-
additionalData: additionalData.join(",")
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
);
|
|
424
|
-
return res.data;
|
|
425
|
-
}
|
|
426
|
-
async function getWorkoutsWithin(client, params) {
|
|
427
|
-
const { lowerLat, lowerLng, upperLat, upperLng, limit = 50 } = params;
|
|
428
|
-
const res = await client.get(
|
|
429
|
-
"/apiserver/v1/workouts/public/within",
|
|
430
|
-
{
|
|
431
|
-
query: {
|
|
432
|
-
lowerlat: lowerLat,
|
|
433
|
-
lowerlng: lowerLng,
|
|
434
|
-
upperlat: upperLat,
|
|
435
|
-
upperlng: upperLng,
|
|
436
|
-
limit
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
);
|
|
440
|
-
return res.data;
|
|
441
|
-
}
|
|
442
|
-
async function getWorkoutStats(client, username) {
|
|
443
|
-
const res = await client.get(
|
|
444
|
-
`/apiserver/v1/workouts/${encodeURIComponent(username)}/stats`
|
|
445
|
-
);
|
|
446
|
-
return res.data;
|
|
447
|
-
}
|
|
448
412
|
var WorkoutsResource = class {
|
|
449
413
|
constructor(client) {
|
|
450
414
|
this.client = client;
|
|
451
415
|
}
|
|
452
416
|
/** The authenticated user's own workouts. */
|
|
453
|
-
own(params) {
|
|
454
|
-
return
|
|
417
|
+
own(params = {}) {
|
|
418
|
+
return endpoint(this.client, {
|
|
419
|
+
path: "/apiserver/v1/workouts",
|
|
420
|
+
query: {
|
|
421
|
+
offset: params.offset ?? 0,
|
|
422
|
+
limit: params.limit ?? 50,
|
|
423
|
+
since: params.since ?? 0
|
|
424
|
+
}
|
|
425
|
+
});
|
|
455
426
|
}
|
|
456
427
|
/** A given user's public workouts. */
|
|
457
|
-
public(username, params) {
|
|
458
|
-
return
|
|
428
|
+
public(username, params = {}) {
|
|
429
|
+
return endpoint(this.client, {
|
|
430
|
+
path: `/apiserver/v1/workouts/${encodeURIComponent(username)}/public`,
|
|
431
|
+
query: { limit: params.limit ?? 40, sortonst: params.sortonst ?? true }
|
|
432
|
+
});
|
|
459
433
|
}
|
|
460
434
|
/**
|
|
461
435
|
* A single workout by username and workout key. Works for any public workout
|
|
462
436
|
* and, when the client is authenticated as the owner, for private ones too.
|
|
463
437
|
*/
|
|
464
|
-
byKey(username, workoutKey, params) {
|
|
465
|
-
|
|
438
|
+
byKey(username, workoutKey, params = {}) {
|
|
439
|
+
const extensions = params.extensions ?? DEFAULT_WORKOUT_EXTENSIONS;
|
|
440
|
+
const additionalData = params.additionalData ?? DEFAULT_WORKOUT_ADDITIONAL_DATA;
|
|
441
|
+
return endpoint(this.client, {
|
|
442
|
+
path: `/apiserver/v2/workouts/${encodeURIComponent(username)}/${encodeURIComponent(workoutKey)}/combined`,
|
|
443
|
+
query: {
|
|
444
|
+
extensions: extensions.join(","),
|
|
445
|
+
additionalData: additionalData.join(",")
|
|
446
|
+
}
|
|
447
|
+
});
|
|
466
448
|
}
|
|
467
449
|
/**
|
|
468
450
|
* Aggregated workout stats per activity for the given user. Works
|
|
469
451
|
* unauthenticated.
|
|
470
452
|
*/
|
|
471
453
|
stats(username) {
|
|
472
|
-
return
|
|
454
|
+
return endpoint(this.client, {
|
|
455
|
+
path: `/apiserver/v1/workouts/${encodeURIComponent(username)}/stats`
|
|
456
|
+
});
|
|
473
457
|
}
|
|
474
|
-
/**
|
|
458
|
+
/**
|
|
459
|
+
* Public workouts whose center position falls inside the given geographic
|
|
460
|
+
* bounding box. Used by the "explore nearby" map view. Unauthenticated.
|
|
461
|
+
*/
|
|
475
462
|
within(params) {
|
|
476
|
-
return
|
|
463
|
+
return endpoint(this.client, {
|
|
464
|
+
path: "/apiserver/v1/workouts/public/within",
|
|
465
|
+
query: {
|
|
466
|
+
lowerlat: params.lowerLat,
|
|
467
|
+
lowerlng: params.lowerLng,
|
|
468
|
+
upperlat: params.upperLat,
|
|
469
|
+
upperlng: params.upperLng,
|
|
470
|
+
limit: params.limit ?? 50
|
|
471
|
+
}
|
|
472
|
+
});
|
|
477
473
|
}
|
|
478
474
|
};
|
|
479
475
|
|
|
480
476
|
// src/users/index.ts
|
|
481
|
-
async function getUserByName(client, username) {
|
|
482
|
-
const res = await client.get(
|
|
483
|
-
`/apiserver/v1/user/name/${encodeURIComponent(username)}`
|
|
484
|
-
);
|
|
485
|
-
return res.data;
|
|
486
|
-
}
|
|
487
|
-
async function searchUsers(client, searchTerms) {
|
|
488
|
-
const res = await client.get(
|
|
489
|
-
`/apiserver/v1/user/search/${encodeURIComponent(searchTerms)}`
|
|
490
|
-
);
|
|
491
|
-
return res.data;
|
|
492
|
-
}
|
|
493
477
|
var UsersResource = class {
|
|
494
478
|
constructor(client) {
|
|
495
479
|
this.client = client;
|
|
496
480
|
}
|
|
497
481
|
/** A user's public profile, by username. */
|
|
498
482
|
byName(username) {
|
|
499
|
-
return
|
|
483
|
+
return endpoint(this.client, {
|
|
484
|
+
path: `/apiserver/v1/user/name/${encodeURIComponent(username)}`
|
|
485
|
+
});
|
|
500
486
|
}
|
|
501
487
|
/** Search for users by name/username. */
|
|
502
488
|
search(searchTerms) {
|
|
503
|
-
return
|
|
489
|
+
return endpoint(this.client, {
|
|
490
|
+
path: `/apiserver/v1/user/search/${encodeURIComponent(searchTerms)}`
|
|
491
|
+
});
|
|
504
492
|
}
|
|
505
493
|
};
|
|
506
494
|
|
|
507
495
|
// src/gear/index.ts
|
|
508
|
-
async function getLatestGear(client, username, params = {}) {
|
|
509
|
-
const { allTypes = true } = params;
|
|
510
|
-
const res = await client.get(
|
|
511
|
-
`/apiserver/v1/gear/${encodeURIComponent(username)}/latest`,
|
|
512
|
-
{ query: { allTypes } }
|
|
513
|
-
);
|
|
514
|
-
return res.data;
|
|
515
|
-
}
|
|
516
496
|
var GearResource = class {
|
|
517
497
|
constructor(client) {
|
|
518
498
|
this.client = client;
|
|
519
499
|
}
|
|
520
|
-
/** A user's latest
|
|
521
|
-
latest(username, params) {
|
|
522
|
-
return
|
|
500
|
+
/** A user's latest gear. */
|
|
501
|
+
latest(username, params = {}) {
|
|
502
|
+
return endpoint(this.client, {
|
|
503
|
+
path: `/apiserver/v1/gear/${encodeURIComponent(username)}/latest`,
|
|
504
|
+
query: { allTypes: params.allTypes ?? true }
|
|
505
|
+
});
|
|
523
506
|
}
|
|
524
507
|
};
|
|
525
508
|
|
|
@@ -527,49 +510,46 @@ var GearResource = class {
|
|
|
527
510
|
var SPORTS_TRACKER_247_API = "https://247.sports-tracker.com";
|
|
528
511
|
|
|
529
512
|
// src/wellness/index.ts
|
|
530
|
-
|
|
531
|
-
return params.since == null ? void 0 : { since: params.since };
|
|
532
|
-
}
|
|
533
|
-
async function getSleepExport(client, params = {}) {
|
|
534
|
-
const res = await client.get("/v1/sleep/export", {
|
|
535
|
-
query: exportQuery(params)
|
|
536
|
-
});
|
|
537
|
-
return res.data;
|
|
538
|
-
}
|
|
539
|
-
async function getSleepStagesExport(client, params = {}) {
|
|
540
|
-
const res = await client.get(
|
|
541
|
-
"/v1/sleepstages/export",
|
|
542
|
-
{ query: exportQuery(params) }
|
|
543
|
-
);
|
|
544
|
-
return res.data;
|
|
545
|
-
}
|
|
546
|
-
async function getRecoveryExport(client, params = {}) {
|
|
547
|
-
const res = await client.get("/v1/recovery/export", {
|
|
548
|
-
query: exportQuery(params)
|
|
549
|
-
});
|
|
550
|
-
return res.data;
|
|
551
|
-
}
|
|
552
|
-
async function getActivityExport(client, params = {}) {
|
|
553
|
-
const res = await client.get("/v1/activity/export", {
|
|
554
|
-
query: exportQuery(params)
|
|
555
|
-
});
|
|
556
|
-
return res.data;
|
|
557
|
-
}
|
|
513
|
+
var exportQuery = (params) => params.since == null ? void 0 : { since: params.since };
|
|
558
514
|
var WellnessResource = class {
|
|
559
|
-
constructor(
|
|
560
|
-
|
|
515
|
+
constructor(options) {
|
|
516
|
+
const { auth, baseUrl, ...rest } = options;
|
|
517
|
+
this.http = new HttpClient({
|
|
518
|
+
...rest,
|
|
519
|
+
baseUrl: baseUrl ?? SPORTS_TRACKER_247_API,
|
|
520
|
+
beforeRequest: async (ctx) => {
|
|
521
|
+
await auth.applyTo(ctx);
|
|
522
|
+
ctx.headers["accept"] = "*/*";
|
|
523
|
+
}
|
|
524
|
+
});
|
|
561
525
|
}
|
|
562
|
-
|
|
563
|
-
|
|
526
|
+
/** Sleep summaries from the 247 service. */
|
|
527
|
+
sleep(params = {}) {
|
|
528
|
+
return endpoint(this.http, {
|
|
529
|
+
path: "/v1/sleep/export",
|
|
530
|
+
query: exportQuery(params)
|
|
531
|
+
});
|
|
564
532
|
}
|
|
565
|
-
|
|
566
|
-
|
|
533
|
+
/** Per-stage sleep intervals from the 247 service. */
|
|
534
|
+
sleepStages(params = {}) {
|
|
535
|
+
return endpoint(this.http, {
|
|
536
|
+
path: "/v1/sleepstages/export",
|
|
537
|
+
query: exportQuery(params)
|
|
538
|
+
});
|
|
567
539
|
}
|
|
568
|
-
|
|
569
|
-
|
|
540
|
+
/** Recovery entries (balance + stress state) from the 247 service. */
|
|
541
|
+
recovery(params = {}) {
|
|
542
|
+
return endpoint(this.http, {
|
|
543
|
+
path: "/v1/recovery/export",
|
|
544
|
+
query: exportQuery(params)
|
|
545
|
+
});
|
|
570
546
|
}
|
|
571
|
-
activity
|
|
572
|
-
|
|
547
|
+
/** Daily activity entries from the 247 service. */
|
|
548
|
+
activity(params = {}) {
|
|
549
|
+
return endpoint(this.http, {
|
|
550
|
+
path: "/v1/activity/export",
|
|
551
|
+
query: exportQuery(params)
|
|
552
|
+
});
|
|
573
553
|
}
|
|
574
554
|
};
|
|
575
555
|
|
|
@@ -586,30 +566,23 @@ var SuuntoClient = class _SuuntoClient {
|
|
|
586
566
|
...rest
|
|
587
567
|
} = options;
|
|
588
568
|
this.sessionKey = sessionKey;
|
|
589
|
-
const
|
|
590
|
-
if (email) ctx.headers["x-totp"] = await generateXtotp(email);
|
|
591
|
-
if (sessionKey) ctx.headers["sttauthorization"] = sessionKey;
|
|
592
|
-
};
|
|
569
|
+
const auth = new AuthSession({ email, sessionKey });
|
|
593
570
|
const sharedHeaders = { "user-agent": userAgent, ...headers };
|
|
594
571
|
this.http = new HttpClient({
|
|
595
572
|
baseUrl: baseUrl ?? SPORTS_TRACKER_API,
|
|
596
573
|
headers: sharedHeaders,
|
|
597
574
|
...rest,
|
|
598
|
-
beforeRequest
|
|
599
|
-
});
|
|
600
|
-
this.http247 = new HttpClient({
|
|
601
|
-
baseUrl: baseUrl247 ?? SPORTS_TRACKER_247_API,
|
|
602
|
-
headers: sharedHeaders,
|
|
603
|
-
...rest,
|
|
604
|
-
beforeRequest: async (ctx) => {
|
|
605
|
-
await beforeRequest(ctx);
|
|
606
|
-
ctx.headers["accept"] = "*/*";
|
|
607
|
-
}
|
|
575
|
+
beforeRequest: (ctx) => auth.applyTo(ctx)
|
|
608
576
|
});
|
|
609
577
|
this.workouts = new WorkoutsResource(this.http);
|
|
610
578
|
this.users = new UsersResource(this.http);
|
|
611
579
|
this.gear = new GearResource(this.http);
|
|
612
|
-
this.wellness = new WellnessResource(
|
|
580
|
+
this.wellness = new WellnessResource({
|
|
581
|
+
auth,
|
|
582
|
+
baseUrl: baseUrl247,
|
|
583
|
+
headers: sharedHeaders,
|
|
584
|
+
...rest
|
|
585
|
+
});
|
|
613
586
|
}
|
|
614
587
|
/** Log in with email/password and return an authenticated client. */
|
|
615
588
|
static async login(options) {
|
|
@@ -639,18 +612,7 @@ export {
|
|
|
639
612
|
WellnessResource,
|
|
640
613
|
WorkoutsResource,
|
|
641
614
|
generateXtotp,
|
|
642
|
-
getActivityExport,
|
|
643
|
-
getLatestGear,
|
|
644
|
-
getOwnWorkouts,
|
|
645
|
-
getRecoveryExport,
|
|
646
|
-
getSleepExport,
|
|
647
|
-
getSleepStagesExport,
|
|
648
|
-
getUserByName,
|
|
649
|
-
getWorkoutStats,
|
|
650
|
-
getWorkouts,
|
|
651
|
-
getWorkoutsWithin,
|
|
652
615
|
login,
|
|
653
|
-
searchUsers,
|
|
654
616
|
secondsUntilRollover,
|
|
655
617
|
sessionTokenFrom
|
|
656
618
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suunto-api-wrapper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Unofficial typed TypeScript client for the Suunto app API (Sports Tracker backend). Not affiliated with or endorsed by Suunto or Sports Tracker.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/Marius-Ar/suunto-api-wrapper"
|