suunto-api-wrapper 1.2.2 → 1.3.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/README.md +19 -0
- package/dist/index.d.mts +94 -1
- package/dist/index.d.ts +94 -1
- package/dist/index.js +80 -5
- package/dist/index.mjs +74 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -95,6 +95,10 @@ payload, typed to the real API response shape (an envelope of
|
|
|
95
95
|
| `suunto.users` | `.byName(username)` | a user's public profile |
|
|
96
96
|
| | `.search(terms)` | search for users |
|
|
97
97
|
| `suunto.gear` | `.latest(username, params?)` | a user's latest gear |
|
|
98
|
+
| `suunto.wellness` | `.sleep(params?)` | sleep summaries (247) |
|
|
99
|
+
| | `.sleepStages(params?)` | per‑stage sleep intervals (247) |
|
|
100
|
+
| | `.recovery(params?)` | recovery balance + stress state (247) |
|
|
101
|
+
| | `.activity(params?)` | daily activity samples (247) |
|
|
98
102
|
|
|
99
103
|
```ts
|
|
100
104
|
// Workouts
|
|
@@ -112,8 +116,23 @@ const matches = await suunto.users.search("john");
|
|
|
112
116
|
|
|
113
117
|
// Gear
|
|
114
118
|
const gear = await suunto.gear.latest("someuser", { allTypes: true });
|
|
119
|
+
|
|
120
|
+
// 247 wellness data — sleep, recovery, activity
|
|
121
|
+
const sleep = await suunto.wellness.sleep({ since: 0 }); // since = epoch ms; 0 returns all
|
|
122
|
+
const stages = await suunto.wellness.sleepStages({ since: 0 });
|
|
123
|
+
const recov = await suunto.wellness.recovery(); // omit `since` to fetch the default window
|
|
124
|
+
const daily = await suunto.wellness.activity();
|
|
115
125
|
```
|
|
116
126
|
|
|
127
|
+
#### What is 247 service?
|
|
128
|
+
|
|
129
|
+
The Suunto app exposes a second service at `247.sports-tracker.com` (separate
|
|
130
|
+
from `api.sports-tracker.com`) for **always‑on, around‑the‑clock body data**
|
|
131
|
+
collected by the watch outside recorded workouts.
|
|
132
|
+
|
|
133
|
+
The 247 client lives at `suunto.http247` if you need a raw escape hatch (same
|
|
134
|
+
auth headers). Override the host with the `baseUrl247` client option.
|
|
135
|
+
|
|
117
136
|
The response payloads are fully typed. For example, workout `extensions` are a
|
|
118
137
|
discriminated union you can narrow on:
|
|
119
138
|
|
package/dist/index.d.mts
CHANGED
|
@@ -724,6 +724,94 @@ declare class GearResource {
|
|
|
724
724
|
latest(username: string, params?: GetLatestGearParams): Promise<GearResponse>;
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
+
/** Default export host for the 247 service. */
|
|
728
|
+
declare const SPORTS_TRACKER_247_API = "https://247.sports-tracker.com";
|
|
729
|
+
interface ExportParams {
|
|
730
|
+
/** Epoch milliseconds. Only entries with a timestamp `>= since` are returned. Use 0 to retrieve all data */
|
|
731
|
+
since?: number;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* One row from a 247 NDJSON export stream. Every row wraps a typed payload
|
|
735
|
+
* under `entryData` plus a top-level ISO `timestamp` (with offset).
|
|
736
|
+
*/
|
|
737
|
+
interface ExportEntry<T> {
|
|
738
|
+
timestamp: string;
|
|
739
|
+
entryData: T;
|
|
740
|
+
}
|
|
741
|
+
/** Sleep summary payload (durations are in seconds). */
|
|
742
|
+
interface SleepSummaryData {
|
|
743
|
+
sleepId: number;
|
|
744
|
+
bedtimeStart: string;
|
|
745
|
+
bedtimeEnd: string;
|
|
746
|
+
duration: number;
|
|
747
|
+
deepSleepDuration: number;
|
|
748
|
+
lightSleepDuration: number;
|
|
749
|
+
remSleepDuration: number;
|
|
750
|
+
sleepOnsetLatencyDuration: number;
|
|
751
|
+
wakeAfterSleepOnsetDuration: number;
|
|
752
|
+
wakeBeforeOffBedDuration: number;
|
|
753
|
+
hrAvg: number;
|
|
754
|
+
hrMin: number;
|
|
755
|
+
isNap: boolean;
|
|
756
|
+
quality?: number;
|
|
757
|
+
maxSpo2?: number;
|
|
758
|
+
altitude?: number;
|
|
759
|
+
avgHrv?: number;
|
|
760
|
+
avgHrvSampleCount?: number;
|
|
761
|
+
}
|
|
762
|
+
type SleepStage = "AWAKE" | "REM" | "LIGHT" | "DEEP";
|
|
763
|
+
/** Single sleep-stage interval. `duration` is in seconds. */
|
|
764
|
+
interface SleepStageData {
|
|
765
|
+
stage: SleepStage;
|
|
766
|
+
duration: number;
|
|
767
|
+
}
|
|
768
|
+
/** Recovery sample. `balance` is in [0, 1]; `stressState` is an integer code. */
|
|
769
|
+
interface RecoveryData {
|
|
770
|
+
balance: number;
|
|
771
|
+
stressState: number;
|
|
772
|
+
}
|
|
773
|
+
/** Activity sample. `energyConsumption` is in joules. */
|
|
774
|
+
interface ActivityData {
|
|
775
|
+
hr: number;
|
|
776
|
+
stepCount: number;
|
|
777
|
+
energyConsumption: number;
|
|
778
|
+
}
|
|
779
|
+
type SleepSummary = ExportEntry<SleepSummaryData>;
|
|
780
|
+
type SleepStageInterval = ExportEntry<SleepStageData>;
|
|
781
|
+
type RecoveryEntry = ExportEntry<RecoveryData>;
|
|
782
|
+
type ActivityEntry = ExportEntry<ActivityData>;
|
|
783
|
+
/**
|
|
784
|
+
* 247 `/export` endpoints stream `application/x-ndjson`. The HTTP layer parses
|
|
785
|
+
* each line into one record, so each function resolves with an array of
|
|
786
|
+
* records.
|
|
787
|
+
*/
|
|
788
|
+
type SleepExportResponse = SleepSummary[];
|
|
789
|
+
type SleepStagesExportResponse = SleepStageInterval[];
|
|
790
|
+
type RecoveryExportResponse = RecoveryEntry[];
|
|
791
|
+
type ActivityExportResponse = ActivityEntry[];
|
|
792
|
+
|
|
793
|
+
/** Sleep summaries from the 247 service. */
|
|
794
|
+
declare function getSleepExport(client: HttpClient, params?: ExportParams): Promise<SleepExportResponse>;
|
|
795
|
+
/** Per-stage sleep intervals from the 247 service. */
|
|
796
|
+
declare function getSleepStagesExport(client: HttpClient, params?: ExportParams): Promise<SleepStagesExportResponse>;
|
|
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>;
|
|
801
|
+
/**
|
|
802
|
+
* Endpoints served by `https://247.sports-tracker.com` (sleep, recovery,
|
|
803
|
+
* activity). Bound to a dedicated {@link HttpClient} configured against that
|
|
804
|
+
* host. Accessed via `suunto.wellness`.
|
|
805
|
+
*/
|
|
806
|
+
declare class WellnessResource {
|
|
807
|
+
private readonly client;
|
|
808
|
+
constructor(client: HttpClient);
|
|
809
|
+
sleep(params?: ExportParams): Promise<SleepExportResponse>;
|
|
810
|
+
sleepStages(params?: ExportParams): Promise<SleepStagesExportResponse>;
|
|
811
|
+
recovery(params?: ExportParams): Promise<RecoveryExportResponse>;
|
|
812
|
+
activity(params?: ExportParams): Promise<ActivityExportResponse>;
|
|
813
|
+
}
|
|
814
|
+
|
|
727
815
|
interface SuuntoClientOptions extends Omit<HttpClientOptions, "beforeRequest"> {
|
|
728
816
|
/**
|
|
729
817
|
* Account email. Drives the `x-totp` header. Omit it (e.g. via
|
|
@@ -734,6 +822,8 @@ interface SuuntoClientOptions extends Omit<HttpClientOptions, "beforeRequest"> {
|
|
|
734
822
|
/** Session key from login — sent as the `Sttauthorization` header. */
|
|
735
823
|
sessionKey?: string;
|
|
736
824
|
userAgent?: string;
|
|
825
|
+
/** Override host for the 247 service (sleep/recovery/activity). */
|
|
826
|
+
baseUrl247?: string;
|
|
737
827
|
}
|
|
738
828
|
/**
|
|
739
829
|
* The main entry point. Owns the authenticated {@link HttpClient} and exposes
|
|
@@ -750,9 +840,12 @@ declare class SuuntoClient {
|
|
|
750
840
|
readonly http: HttpClient;
|
|
751
841
|
/** Session key in use, if the client was authenticated. */
|
|
752
842
|
readonly sessionKey?: string;
|
|
843
|
+
/** Dedicated HTTP client for the 247 host (sleep/recovery/activity). */
|
|
844
|
+
readonly http247: HttpClient;
|
|
753
845
|
readonly workouts: WorkoutsResource;
|
|
754
846
|
readonly users: UsersResource;
|
|
755
847
|
readonly gear: GearResource;
|
|
848
|
+
readonly wellness: WellnessResource;
|
|
756
849
|
constructor(options: SuuntoClientOptions);
|
|
757
850
|
/** Log in with email/password and return an authenticated client. */
|
|
758
851
|
static login(options: LoginOptions & Omit<SuuntoClientOptions, "email" | "sessionKey">): Promise<SuuntoClient>;
|
|
@@ -763,4 +856,4 @@ declare class SuuntoClient {
|
|
|
763
856
|
static unauthenticated(options?: Omit<SuuntoClientOptions, "email" | "sessionKey">): SuuntoClient;
|
|
764
857
|
}
|
|
765
858
|
|
|
766
|
-
export { type ActivityCounts, type Cadence, type ClientCalculatedAchievements, type CumulativeAchievement, DEFAULT_USER_AGENT, 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 RequestBody, type RequestContext, type RequestOptions, type RouteRanking, SPORTS_TRACKER_API, type SearchUser, type SummaryExtension, SuuntoActivityType, SuuntoClient, type SuuntoClientOptions, type SwimmingHeaderExtension, type TssEntry, type UserProfile, type UserProfileResponse, type UserSearchResponse, type UserSearchResult, UsersResource, type WeatherExtension, type Workout, type WorkoutComment, type WorkoutExtension, type WorkoutReaction, type WorkoutStats, type WorkoutStatsEntry, type WorkoutStatsResponse, WorkoutsResource, type WorkoutsResponse, type WorkoutsWithinItem, type WorkoutsWithinResponse, generateXtotp, getLatestGear, getOwnWorkouts, getUserByName, getWorkoutStats, getWorkouts, getWorkoutsWithin, login, searchUsers, secondsUntilRollover, sessionTokenFrom };
|
|
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, getActivityExport, getLatestGear, getOwnWorkouts, getRecoveryExport, getSleepExport, getSleepStagesExport, getUserByName, getWorkoutStats, getWorkouts, getWorkoutsWithin, login, searchUsers, secondsUntilRollover, sessionTokenFrom };
|
package/dist/index.d.ts
CHANGED
|
@@ -724,6 +724,94 @@ declare class GearResource {
|
|
|
724
724
|
latest(username: string, params?: GetLatestGearParams): Promise<GearResponse>;
|
|
725
725
|
}
|
|
726
726
|
|
|
727
|
+
/** Default export host for the 247 service. */
|
|
728
|
+
declare const SPORTS_TRACKER_247_API = "https://247.sports-tracker.com";
|
|
729
|
+
interface ExportParams {
|
|
730
|
+
/** Epoch milliseconds. Only entries with a timestamp `>= since` are returned. Use 0 to retrieve all data */
|
|
731
|
+
since?: number;
|
|
732
|
+
}
|
|
733
|
+
/**
|
|
734
|
+
* One row from a 247 NDJSON export stream. Every row wraps a typed payload
|
|
735
|
+
* under `entryData` plus a top-level ISO `timestamp` (with offset).
|
|
736
|
+
*/
|
|
737
|
+
interface ExportEntry<T> {
|
|
738
|
+
timestamp: string;
|
|
739
|
+
entryData: T;
|
|
740
|
+
}
|
|
741
|
+
/** Sleep summary payload (durations are in seconds). */
|
|
742
|
+
interface SleepSummaryData {
|
|
743
|
+
sleepId: number;
|
|
744
|
+
bedtimeStart: string;
|
|
745
|
+
bedtimeEnd: string;
|
|
746
|
+
duration: number;
|
|
747
|
+
deepSleepDuration: number;
|
|
748
|
+
lightSleepDuration: number;
|
|
749
|
+
remSleepDuration: number;
|
|
750
|
+
sleepOnsetLatencyDuration: number;
|
|
751
|
+
wakeAfterSleepOnsetDuration: number;
|
|
752
|
+
wakeBeforeOffBedDuration: number;
|
|
753
|
+
hrAvg: number;
|
|
754
|
+
hrMin: number;
|
|
755
|
+
isNap: boolean;
|
|
756
|
+
quality?: number;
|
|
757
|
+
maxSpo2?: number;
|
|
758
|
+
altitude?: number;
|
|
759
|
+
avgHrv?: number;
|
|
760
|
+
avgHrvSampleCount?: number;
|
|
761
|
+
}
|
|
762
|
+
type SleepStage = "AWAKE" | "REM" | "LIGHT" | "DEEP";
|
|
763
|
+
/** Single sleep-stage interval. `duration` is in seconds. */
|
|
764
|
+
interface SleepStageData {
|
|
765
|
+
stage: SleepStage;
|
|
766
|
+
duration: number;
|
|
767
|
+
}
|
|
768
|
+
/** Recovery sample. `balance` is in [0, 1]; `stressState` is an integer code. */
|
|
769
|
+
interface RecoveryData {
|
|
770
|
+
balance: number;
|
|
771
|
+
stressState: number;
|
|
772
|
+
}
|
|
773
|
+
/** Activity sample. `energyConsumption` is in joules. */
|
|
774
|
+
interface ActivityData {
|
|
775
|
+
hr: number;
|
|
776
|
+
stepCount: number;
|
|
777
|
+
energyConsumption: number;
|
|
778
|
+
}
|
|
779
|
+
type SleepSummary = ExportEntry<SleepSummaryData>;
|
|
780
|
+
type SleepStageInterval = ExportEntry<SleepStageData>;
|
|
781
|
+
type RecoveryEntry = ExportEntry<RecoveryData>;
|
|
782
|
+
type ActivityEntry = ExportEntry<ActivityData>;
|
|
783
|
+
/**
|
|
784
|
+
* 247 `/export` endpoints stream `application/x-ndjson`. The HTTP layer parses
|
|
785
|
+
* each line into one record, so each function resolves with an array of
|
|
786
|
+
* records.
|
|
787
|
+
*/
|
|
788
|
+
type SleepExportResponse = SleepSummary[];
|
|
789
|
+
type SleepStagesExportResponse = SleepStageInterval[];
|
|
790
|
+
type RecoveryExportResponse = RecoveryEntry[];
|
|
791
|
+
type ActivityExportResponse = ActivityEntry[];
|
|
792
|
+
|
|
793
|
+
/** Sleep summaries from the 247 service. */
|
|
794
|
+
declare function getSleepExport(client: HttpClient, params?: ExportParams): Promise<SleepExportResponse>;
|
|
795
|
+
/** Per-stage sleep intervals from the 247 service. */
|
|
796
|
+
declare function getSleepStagesExport(client: HttpClient, params?: ExportParams): Promise<SleepStagesExportResponse>;
|
|
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>;
|
|
801
|
+
/**
|
|
802
|
+
* Endpoints served by `https://247.sports-tracker.com` (sleep, recovery,
|
|
803
|
+
* activity). Bound to a dedicated {@link HttpClient} configured against that
|
|
804
|
+
* host. Accessed via `suunto.wellness`.
|
|
805
|
+
*/
|
|
806
|
+
declare class WellnessResource {
|
|
807
|
+
private readonly client;
|
|
808
|
+
constructor(client: HttpClient);
|
|
809
|
+
sleep(params?: ExportParams): Promise<SleepExportResponse>;
|
|
810
|
+
sleepStages(params?: ExportParams): Promise<SleepStagesExportResponse>;
|
|
811
|
+
recovery(params?: ExportParams): Promise<RecoveryExportResponse>;
|
|
812
|
+
activity(params?: ExportParams): Promise<ActivityExportResponse>;
|
|
813
|
+
}
|
|
814
|
+
|
|
727
815
|
interface SuuntoClientOptions extends Omit<HttpClientOptions, "beforeRequest"> {
|
|
728
816
|
/**
|
|
729
817
|
* Account email. Drives the `x-totp` header. Omit it (e.g. via
|
|
@@ -734,6 +822,8 @@ interface SuuntoClientOptions extends Omit<HttpClientOptions, "beforeRequest"> {
|
|
|
734
822
|
/** Session key from login — sent as the `Sttauthorization` header. */
|
|
735
823
|
sessionKey?: string;
|
|
736
824
|
userAgent?: string;
|
|
825
|
+
/** Override host for the 247 service (sleep/recovery/activity). */
|
|
826
|
+
baseUrl247?: string;
|
|
737
827
|
}
|
|
738
828
|
/**
|
|
739
829
|
* The main entry point. Owns the authenticated {@link HttpClient} and exposes
|
|
@@ -750,9 +840,12 @@ declare class SuuntoClient {
|
|
|
750
840
|
readonly http: HttpClient;
|
|
751
841
|
/** Session key in use, if the client was authenticated. */
|
|
752
842
|
readonly sessionKey?: string;
|
|
843
|
+
/** Dedicated HTTP client for the 247 host (sleep/recovery/activity). */
|
|
844
|
+
readonly http247: HttpClient;
|
|
753
845
|
readonly workouts: WorkoutsResource;
|
|
754
846
|
readonly users: UsersResource;
|
|
755
847
|
readonly gear: GearResource;
|
|
848
|
+
readonly wellness: WellnessResource;
|
|
756
849
|
constructor(options: SuuntoClientOptions);
|
|
757
850
|
/** Log in with email/password and return an authenticated client. */
|
|
758
851
|
static login(options: LoginOptions & Omit<SuuntoClientOptions, "email" | "sessionKey">): Promise<SuuntoClient>;
|
|
@@ -763,4 +856,4 @@ declare class SuuntoClient {
|
|
|
763
856
|
static unauthenticated(options?: Omit<SuuntoClientOptions, "email" | "sessionKey">): SuuntoClient;
|
|
764
857
|
}
|
|
765
858
|
|
|
766
|
-
export { type ActivityCounts, type Cadence, type ClientCalculatedAchievements, type CumulativeAchievement, DEFAULT_USER_AGENT, 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 RequestBody, type RequestContext, type RequestOptions, type RouteRanking, SPORTS_TRACKER_API, type SearchUser, type SummaryExtension, SuuntoActivityType, SuuntoClient, type SuuntoClientOptions, type SwimmingHeaderExtension, type TssEntry, type UserProfile, type UserProfileResponse, type UserSearchResponse, type UserSearchResult, UsersResource, type WeatherExtension, type Workout, type WorkoutComment, type WorkoutExtension, type WorkoutReaction, type WorkoutStats, type WorkoutStatsEntry, type WorkoutStatsResponse, WorkoutsResource, type WorkoutsResponse, type WorkoutsWithinItem, type WorkoutsWithinResponse, generateXtotp, getLatestGear, getOwnWorkouts, getUserByName, getWorkoutStats, getWorkouts, getWorkoutsWithin, login, searchUsers, secondsUntilRollover, sessionTokenFrom };
|
|
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, getActivityExport, getLatestGear, getOwnWorkouts, getRecoveryExport, getSleepExport, getSleepStagesExport, getUserByName, getWorkoutStats, getWorkouts, getWorkoutsWithin, login, searchUsers, secondsUntilRollover, sessionTokenFrom };
|
package/dist/index.js
CHANGED
|
@@ -24,14 +24,20 @@ __export(index_exports, {
|
|
|
24
24
|
GearResource: () => GearResource,
|
|
25
25
|
HttpClient: () => HttpClient,
|
|
26
26
|
HttpError: () => HttpError,
|
|
27
|
+
SPORTS_TRACKER_247_API: () => SPORTS_TRACKER_247_API,
|
|
27
28
|
SPORTS_TRACKER_API: () => SPORTS_TRACKER_API,
|
|
28
29
|
SuuntoActivityType: () => SuuntoActivityType,
|
|
29
30
|
SuuntoClient: () => SuuntoClient,
|
|
30
31
|
UsersResource: () => UsersResource,
|
|
32
|
+
WellnessResource: () => WellnessResource,
|
|
31
33
|
WorkoutsResource: () => WorkoutsResource,
|
|
32
34
|
generateXtotp: () => generateXtotp,
|
|
35
|
+
getActivityExport: () => getActivityExport,
|
|
33
36
|
getLatestGear: () => getLatestGear,
|
|
34
37
|
getOwnWorkouts: () => getOwnWorkouts,
|
|
38
|
+
getRecoveryExport: () => getRecoveryExport,
|
|
39
|
+
getSleepExport: () => getSleepExport,
|
|
40
|
+
getSleepStagesExport: () => getSleepStagesExport,
|
|
35
41
|
getUserByName: () => getUserByName,
|
|
36
42
|
getWorkoutStats: () => getWorkoutStats,
|
|
37
43
|
getWorkouts: () => getWorkouts,
|
|
@@ -181,6 +187,9 @@ async function parseBody(response) {
|
|
|
181
187
|
const contentType = response.headers.get("content-type") ?? "";
|
|
182
188
|
const text = await response.text();
|
|
183
189
|
if (!text) return void 0;
|
|
190
|
+
if (contentType.includes("application/x-ndjson") || contentType.includes("application/jsonl") || contentType.includes("application/x-jsonlines")) {
|
|
191
|
+
return text.split(/\r?\n/).filter((line) => line.length > 0).map((line) => JSON.parse(line));
|
|
192
|
+
}
|
|
184
193
|
if (contentType.includes("application/json")) {
|
|
185
194
|
try {
|
|
186
195
|
return JSON.parse(text);
|
|
@@ -565,6 +574,56 @@ var GearResource = class {
|
|
|
565
574
|
}
|
|
566
575
|
};
|
|
567
576
|
|
|
577
|
+
// src/wellness/types.ts
|
|
578
|
+
var SPORTS_TRACKER_247_API = "https://247.sports-tracker.com";
|
|
579
|
+
|
|
580
|
+
// src/wellness/index.ts
|
|
581
|
+
function exportQuery(params) {
|
|
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
|
+
}
|
|
609
|
+
var WellnessResource = class {
|
|
610
|
+
constructor(client) {
|
|
611
|
+
this.client = client;
|
|
612
|
+
}
|
|
613
|
+
sleep(params) {
|
|
614
|
+
return getSleepExport(this.client, params);
|
|
615
|
+
}
|
|
616
|
+
sleepStages(params) {
|
|
617
|
+
return getSleepStagesExport(this.client, params);
|
|
618
|
+
}
|
|
619
|
+
recovery(params) {
|
|
620
|
+
return getRecoveryExport(this.client, params);
|
|
621
|
+
}
|
|
622
|
+
activity(params) {
|
|
623
|
+
return getActivityExport(this.client, params);
|
|
624
|
+
}
|
|
625
|
+
};
|
|
626
|
+
|
|
568
627
|
// src/client.ts
|
|
569
628
|
var SuuntoClient = class _SuuntoClient {
|
|
570
629
|
constructor(options) {
|
|
@@ -573,22 +632,32 @@ var SuuntoClient = class _SuuntoClient {
|
|
|
573
632
|
sessionKey,
|
|
574
633
|
userAgent = DEFAULT_USER_AGENT,
|
|
575
634
|
baseUrl,
|
|
635
|
+
baseUrl247,
|
|
576
636
|
headers,
|
|
577
637
|
...rest
|
|
578
638
|
} = options;
|
|
579
639
|
this.sessionKey = sessionKey;
|
|
640
|
+
const beforeRequest = async (ctx) => {
|
|
641
|
+
if (email) ctx.headers["x-totp"] = await generateXtotp(email);
|
|
642
|
+
if (sessionKey) ctx.headers["sttauthorization"] = sessionKey;
|
|
643
|
+
};
|
|
644
|
+
const sharedHeaders = { "user-agent": userAgent, ...headers };
|
|
580
645
|
this.http = new HttpClient({
|
|
581
646
|
baseUrl: baseUrl ?? SPORTS_TRACKER_API,
|
|
582
|
-
headers:
|
|
647
|
+
headers: sharedHeaders,
|
|
583
648
|
...rest,
|
|
584
|
-
beforeRequest
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
649
|
+
beforeRequest
|
|
650
|
+
});
|
|
651
|
+
this.http247 = new HttpClient({
|
|
652
|
+
baseUrl: baseUrl247 ?? SPORTS_TRACKER_247_API,
|
|
653
|
+
headers: sharedHeaders,
|
|
654
|
+
...rest,
|
|
655
|
+
beforeRequest
|
|
588
656
|
});
|
|
589
657
|
this.workouts = new WorkoutsResource(this.http);
|
|
590
658
|
this.users = new UsersResource(this.http);
|
|
591
659
|
this.gear = new GearResource(this.http);
|
|
660
|
+
this.wellness = new WellnessResource(this.http247);
|
|
592
661
|
}
|
|
593
662
|
/** Log in with email/password and return an authenticated client. */
|
|
594
663
|
static async login(options) {
|
|
@@ -611,14 +680,20 @@ var SuuntoClient = class _SuuntoClient {
|
|
|
611
680
|
GearResource,
|
|
612
681
|
HttpClient,
|
|
613
682
|
HttpError,
|
|
683
|
+
SPORTS_TRACKER_247_API,
|
|
614
684
|
SPORTS_TRACKER_API,
|
|
615
685
|
SuuntoActivityType,
|
|
616
686
|
SuuntoClient,
|
|
617
687
|
UsersResource,
|
|
688
|
+
WellnessResource,
|
|
618
689
|
WorkoutsResource,
|
|
619
690
|
generateXtotp,
|
|
691
|
+
getActivityExport,
|
|
620
692
|
getLatestGear,
|
|
621
693
|
getOwnWorkouts,
|
|
694
|
+
getRecoveryExport,
|
|
695
|
+
getSleepExport,
|
|
696
|
+
getSleepStagesExport,
|
|
622
697
|
getUserByName,
|
|
623
698
|
getWorkoutStats,
|
|
624
699
|
getWorkouts,
|
package/dist/index.mjs
CHANGED
|
@@ -136,6 +136,9 @@ async function parseBody(response) {
|
|
|
136
136
|
const contentType = response.headers.get("content-type") ?? "";
|
|
137
137
|
const text = await response.text();
|
|
138
138
|
if (!text) return void 0;
|
|
139
|
+
if (contentType.includes("application/x-ndjson") || contentType.includes("application/jsonl") || contentType.includes("application/x-jsonlines")) {
|
|
140
|
+
return text.split(/\r?\n/).filter((line) => line.length > 0).map((line) => JSON.parse(line));
|
|
141
|
+
}
|
|
139
142
|
if (contentType.includes("application/json")) {
|
|
140
143
|
try {
|
|
141
144
|
return JSON.parse(text);
|
|
@@ -520,6 +523,56 @@ var GearResource = class {
|
|
|
520
523
|
}
|
|
521
524
|
};
|
|
522
525
|
|
|
526
|
+
// src/wellness/types.ts
|
|
527
|
+
var SPORTS_TRACKER_247_API = "https://247.sports-tracker.com";
|
|
528
|
+
|
|
529
|
+
// src/wellness/index.ts
|
|
530
|
+
function exportQuery(params) {
|
|
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
|
+
}
|
|
558
|
+
var WellnessResource = class {
|
|
559
|
+
constructor(client) {
|
|
560
|
+
this.client = client;
|
|
561
|
+
}
|
|
562
|
+
sleep(params) {
|
|
563
|
+
return getSleepExport(this.client, params);
|
|
564
|
+
}
|
|
565
|
+
sleepStages(params) {
|
|
566
|
+
return getSleepStagesExport(this.client, params);
|
|
567
|
+
}
|
|
568
|
+
recovery(params) {
|
|
569
|
+
return getRecoveryExport(this.client, params);
|
|
570
|
+
}
|
|
571
|
+
activity(params) {
|
|
572
|
+
return getActivityExport(this.client, params);
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
|
|
523
576
|
// src/client.ts
|
|
524
577
|
var SuuntoClient = class _SuuntoClient {
|
|
525
578
|
constructor(options) {
|
|
@@ -528,22 +581,32 @@ var SuuntoClient = class _SuuntoClient {
|
|
|
528
581
|
sessionKey,
|
|
529
582
|
userAgent = DEFAULT_USER_AGENT,
|
|
530
583
|
baseUrl,
|
|
584
|
+
baseUrl247,
|
|
531
585
|
headers,
|
|
532
586
|
...rest
|
|
533
587
|
} = options;
|
|
534
588
|
this.sessionKey = sessionKey;
|
|
589
|
+
const beforeRequest = async (ctx) => {
|
|
590
|
+
if (email) ctx.headers["x-totp"] = await generateXtotp(email);
|
|
591
|
+
if (sessionKey) ctx.headers["sttauthorization"] = sessionKey;
|
|
592
|
+
};
|
|
593
|
+
const sharedHeaders = { "user-agent": userAgent, ...headers };
|
|
535
594
|
this.http = new HttpClient({
|
|
536
595
|
baseUrl: baseUrl ?? SPORTS_TRACKER_API,
|
|
537
|
-
headers:
|
|
596
|
+
headers: sharedHeaders,
|
|
538
597
|
...rest,
|
|
539
|
-
beforeRequest
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
598
|
+
beforeRequest
|
|
599
|
+
});
|
|
600
|
+
this.http247 = new HttpClient({
|
|
601
|
+
baseUrl: baseUrl247 ?? SPORTS_TRACKER_247_API,
|
|
602
|
+
headers: sharedHeaders,
|
|
603
|
+
...rest,
|
|
604
|
+
beforeRequest
|
|
543
605
|
});
|
|
544
606
|
this.workouts = new WorkoutsResource(this.http);
|
|
545
607
|
this.users = new UsersResource(this.http);
|
|
546
608
|
this.gear = new GearResource(this.http);
|
|
609
|
+
this.wellness = new WellnessResource(this.http247);
|
|
547
610
|
}
|
|
548
611
|
/** Log in with email/password and return an authenticated client. */
|
|
549
612
|
static async login(options) {
|
|
@@ -565,14 +628,20 @@ export {
|
|
|
565
628
|
GearResource,
|
|
566
629
|
HttpClient,
|
|
567
630
|
HttpError,
|
|
631
|
+
SPORTS_TRACKER_247_API,
|
|
568
632
|
SPORTS_TRACKER_API,
|
|
569
633
|
SuuntoActivityType,
|
|
570
634
|
SuuntoClient,
|
|
571
635
|
UsersResource,
|
|
636
|
+
WellnessResource,
|
|
572
637
|
WorkoutsResource,
|
|
573
638
|
generateXtotp,
|
|
639
|
+
getActivityExport,
|
|
574
640
|
getLatestGear,
|
|
575
641
|
getOwnWorkouts,
|
|
642
|
+
getRecoveryExport,
|
|
643
|
+
getSleepExport,
|
|
644
|
+
getSleepStagesExport,
|
|
576
645
|
getUserByName,
|
|
577
646
|
getWorkoutStats,
|
|
578
647
|
getWorkouts,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suunto-api-wrapper",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.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"
|