suunto-api-wrapper 1.1.1 → 1.2.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 CHANGED
@@ -82,6 +82,7 @@ payload, typed to the real API response shape (an envelope of
82
82
  | ------------------ | ------------------------------ | ----------------------------------------- |
83
83
  | `suunto.workouts` | `.own(params?)` | your own workouts |
84
84
  | | `.public(username, params?)` | a user's public workouts |
85
+ | | `.byKey(username, key, params?)` | a single workout (public, or your own when authed) |
85
86
  | `suunto.users` | `.byName(username)` | a user's public profile |
86
87
  | | `.search(terms)` | search for users |
87
88
  | `suunto.gear` | `.latest(username, params?)` | a user's latest gear |
@@ -90,6 +91,7 @@ payload, typed to the real API response shape (an envelope of
90
91
  // Workouts
91
92
  const own = await suunto.workouts.own({ limit: 20, offset: 0, since: 0 });
92
93
  const publicItems = await suunto.workouts.public("someuser", { limit: 40 });
94
+ const single = await suunto.workouts.byKey("someuser", "workoutKey123");
93
95
 
94
96
  // Users
95
97
  const profile = await suunto.users.byName("someuser");
package/dist/index.d.mts CHANGED
@@ -95,6 +95,30 @@ interface GetOwnWorkoutsParams {
95
95
  offset?: number;
96
96
  limit?: number;
97
97
  }
98
+ /** Valid values for the `extensions` query param on the single-workout endpoint. */
99
+ declare enum WorkoutExtensionName {
100
+ Dive = "DiveExtension",
101
+ JumpRope = "JumpRopeExtension",
102
+ Summary = "SummaryExtension",
103
+ Swimming = "SwimmingExtension",
104
+ Weather = "WeatherExtension",
105
+ Workout = "WorkoutExtension",
106
+ CompetitionHeader = "CompetitionHeaderExtension"
107
+ }
108
+ /** Valid values for the `additionalData` query param on the single-workout endpoint. */
109
+ declare enum WorkoutAdditionalData {
110
+ Achievements = "achievements",
111
+ Photos = "photos",
112
+ Videos = "videos",
113
+ Comments = "comments",
114
+ UserReacted = "user_reacted"
115
+ }
116
+ interface GetWorkoutParams {
117
+ /** Extensions to include in the response. Defaults to `[Summary, CompetitionHeader]`. */
118
+ extensions?: WorkoutExtensionName[];
119
+ /** Extra data blocks to include. Defaults to all five values. */
120
+ additionalData?: WorkoutAdditionalData[];
121
+ }
98
122
  /** GPS coordinate: x = longitude, y = latitude. */
99
123
  interface Position {
100
124
  x: number;
@@ -355,6 +379,11 @@ interface WorkoutsResponse {
355
379
  until: string;
356
380
  };
357
381
  }
382
+ interface WorkoutResponse {
383
+ error: string | null;
384
+ payload: Workout;
385
+ metadata: Record<string, unknown>;
386
+ }
358
387
 
359
388
  declare function getWorkouts(client: HttpClient, username: string, params?: GetWorkoutsParams): Promise<WorkoutsResponse>;
360
389
  declare function getOwnWorkouts(client: HttpClient, params?: GetOwnWorkoutsParams): Promise<WorkoutsResponse>;
@@ -366,6 +395,11 @@ declare class WorkoutsResource {
366
395
  own(params?: GetOwnWorkoutsParams): Promise<WorkoutsResponse>;
367
396
  /** A given user's public workouts. */
368
397
  public(username: string, params?: GetWorkoutsParams): Promise<WorkoutsResponse>;
398
+ /**
399
+ * A single workout by username and workout key. Works for any public workout
400
+ * and, when the client is authenticated as the owner, for private ones too.
401
+ */
402
+ byKey(username: string, workoutKey: string, params?: GetWorkoutParams): Promise<WorkoutResponse>;
369
403
  }
370
404
 
371
405
  interface UserProfile {
package/dist/index.d.ts CHANGED
@@ -95,6 +95,30 @@ interface GetOwnWorkoutsParams {
95
95
  offset?: number;
96
96
  limit?: number;
97
97
  }
98
+ /** Valid values for the `extensions` query param on the single-workout endpoint. */
99
+ declare enum WorkoutExtensionName {
100
+ Dive = "DiveExtension",
101
+ JumpRope = "JumpRopeExtension",
102
+ Summary = "SummaryExtension",
103
+ Swimming = "SwimmingExtension",
104
+ Weather = "WeatherExtension",
105
+ Workout = "WorkoutExtension",
106
+ CompetitionHeader = "CompetitionHeaderExtension"
107
+ }
108
+ /** Valid values for the `additionalData` query param on the single-workout endpoint. */
109
+ declare enum WorkoutAdditionalData {
110
+ Achievements = "achievements",
111
+ Photos = "photos",
112
+ Videos = "videos",
113
+ Comments = "comments",
114
+ UserReacted = "user_reacted"
115
+ }
116
+ interface GetWorkoutParams {
117
+ /** Extensions to include in the response. Defaults to `[Summary, CompetitionHeader]`. */
118
+ extensions?: WorkoutExtensionName[];
119
+ /** Extra data blocks to include. Defaults to all five values. */
120
+ additionalData?: WorkoutAdditionalData[];
121
+ }
98
122
  /** GPS coordinate: x = longitude, y = latitude. */
99
123
  interface Position {
100
124
  x: number;
@@ -355,6 +379,11 @@ interface WorkoutsResponse {
355
379
  until: string;
356
380
  };
357
381
  }
382
+ interface WorkoutResponse {
383
+ error: string | null;
384
+ payload: Workout;
385
+ metadata: Record<string, unknown>;
386
+ }
358
387
 
359
388
  declare function getWorkouts(client: HttpClient, username: string, params?: GetWorkoutsParams): Promise<WorkoutsResponse>;
360
389
  declare function getOwnWorkouts(client: HttpClient, params?: GetOwnWorkoutsParams): Promise<WorkoutsResponse>;
@@ -366,6 +395,11 @@ declare class WorkoutsResource {
366
395
  own(params?: GetOwnWorkoutsParams): Promise<WorkoutsResponse>;
367
396
  /** A given user's public workouts. */
368
397
  public(username: string, params?: GetWorkoutsParams): Promise<WorkoutsResponse>;
398
+ /**
399
+ * A single workout by username and workout key. Works for any public workout
400
+ * and, when the client is authenticated as the owner, for private ones too.
401
+ */
402
+ byKey(username: string, workoutKey: string, params?: GetWorkoutParams): Promise<WorkoutResponse>;
369
403
  }
370
404
 
371
405
  interface UserProfile {
package/dist/index.js CHANGED
@@ -68,13 +68,14 @@ var HttpClient = class {
68
68
  this.timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;
69
69
  this.retries = options.retries ?? DEFAULTS.retries;
70
70
  this.retryBackoffMs = options.retryBackoffMs ?? DEFAULTS.retryBackoffMs;
71
- this.fetchImpl = options.fetch ?? globalThis.fetch;
71
+ const fetchImpl = options.fetch ?? globalThis.fetch;
72
72
  this.beforeRequest = options.beforeRequest;
73
- if (typeof this.fetchImpl !== "function") {
73
+ if (typeof fetchImpl !== "function") {
74
74
  throw new TypeError(
75
75
  "No fetch implementation available. Use Node 18+ or pass `fetch` in options."
76
76
  );
77
77
  }
78
+ this.fetchImpl = options.fetch ? fetchImpl : fetchImpl.bind(globalThis);
78
79
  }
79
80
  get(path, options) {
80
81
  return this.request("GET", path, options);
@@ -290,6 +291,17 @@ function sessionTokenFrom(response) {
290
291
  }
291
292
 
292
293
  // src/workouts/index.ts
294
+ var DEFAULT_WORKOUT_EXTENSIONS = [
295
+ "SummaryExtension" /* Summary */,
296
+ "CompetitionHeaderExtension" /* CompetitionHeader */
297
+ ];
298
+ var DEFAULT_WORKOUT_ADDITIONAL_DATA = [
299
+ "achievements" /* Achievements */,
300
+ "photos" /* Photos */,
301
+ "videos" /* Videos */,
302
+ "comments" /* Comments */,
303
+ "user_reacted" /* UserReacted */
304
+ ];
293
305
  async function getWorkouts(client, username, params = {}) {
294
306
  const { limit = 40, sortonst = true } = params;
295
307
  const res = await client.get(
@@ -309,6 +321,22 @@ async function getOwnWorkouts(client, params = {}) {
309
321
  );
310
322
  return res.data;
311
323
  }
324
+ async function getWorkout(client, username, workoutKey, params = {}) {
325
+ const {
326
+ extensions = DEFAULT_WORKOUT_EXTENSIONS,
327
+ additionalData = DEFAULT_WORKOUT_ADDITIONAL_DATA
328
+ } = params;
329
+ const res = await client.get(
330
+ `/apiserver/v2/workouts/${encodeURIComponent(username)}/${encodeURIComponent(workoutKey)}/combined`,
331
+ {
332
+ query: {
333
+ extensions: extensions.join(","),
334
+ additionalData: additionalData.join(",")
335
+ }
336
+ }
337
+ );
338
+ return res.data;
339
+ }
312
340
  var WorkoutsResource = class {
313
341
  constructor(client) {
314
342
  this.client = client;
@@ -321,6 +349,13 @@ var WorkoutsResource = class {
321
349
  public(username, params) {
322
350
  return getWorkouts(this.client, username, params);
323
351
  }
352
+ /**
353
+ * A single workout by username and workout key. Works for any public workout
354
+ * and, when the client is authenticated as the owner, for private ones too.
355
+ */
356
+ byKey(username, workoutKey, params) {
357
+ return getWorkout(this.client, username, workoutKey, params);
358
+ }
324
359
  };
325
360
 
326
361
  // src/users/index.ts
package/dist/index.mjs CHANGED
@@ -26,13 +26,14 @@ var HttpClient = class {
26
26
  this.timeoutMs = options.timeoutMs ?? DEFAULTS.timeoutMs;
27
27
  this.retries = options.retries ?? DEFAULTS.retries;
28
28
  this.retryBackoffMs = options.retryBackoffMs ?? DEFAULTS.retryBackoffMs;
29
- this.fetchImpl = options.fetch ?? globalThis.fetch;
29
+ const fetchImpl = options.fetch ?? globalThis.fetch;
30
30
  this.beforeRequest = options.beforeRequest;
31
- if (typeof this.fetchImpl !== "function") {
31
+ if (typeof fetchImpl !== "function") {
32
32
  throw new TypeError(
33
33
  "No fetch implementation available. Use Node 18+ or pass `fetch` in options."
34
34
  );
35
35
  }
36
+ this.fetchImpl = options.fetch ? fetchImpl : fetchImpl.bind(globalThis);
36
37
  }
37
38
  get(path, options) {
38
39
  return this.request("GET", path, options);
@@ -248,6 +249,17 @@ function sessionTokenFrom(response) {
248
249
  }
249
250
 
250
251
  // src/workouts/index.ts
252
+ var DEFAULT_WORKOUT_EXTENSIONS = [
253
+ "SummaryExtension" /* Summary */,
254
+ "CompetitionHeaderExtension" /* CompetitionHeader */
255
+ ];
256
+ var DEFAULT_WORKOUT_ADDITIONAL_DATA = [
257
+ "achievements" /* Achievements */,
258
+ "photos" /* Photos */,
259
+ "videos" /* Videos */,
260
+ "comments" /* Comments */,
261
+ "user_reacted" /* UserReacted */
262
+ ];
251
263
  async function getWorkouts(client, username, params = {}) {
252
264
  const { limit = 40, sortonst = true } = params;
253
265
  const res = await client.get(
@@ -267,6 +279,22 @@ async function getOwnWorkouts(client, params = {}) {
267
279
  );
268
280
  return res.data;
269
281
  }
282
+ async function getWorkout(client, username, workoutKey, params = {}) {
283
+ const {
284
+ extensions = DEFAULT_WORKOUT_EXTENSIONS,
285
+ additionalData = DEFAULT_WORKOUT_ADDITIONAL_DATA
286
+ } = params;
287
+ const res = await client.get(
288
+ `/apiserver/v2/workouts/${encodeURIComponent(username)}/${encodeURIComponent(workoutKey)}/combined`,
289
+ {
290
+ query: {
291
+ extensions: extensions.join(","),
292
+ additionalData: additionalData.join(",")
293
+ }
294
+ }
295
+ );
296
+ return res.data;
297
+ }
270
298
  var WorkoutsResource = class {
271
299
  constructor(client) {
272
300
  this.client = client;
@@ -279,6 +307,13 @@ var WorkoutsResource = class {
279
307
  public(username, params) {
280
308
  return getWorkouts(this.client, username, params);
281
309
  }
310
+ /**
311
+ * A single workout by username and workout key. Works for any public workout
312
+ * and, when the client is authenticated as the owner, for private ones too.
313
+ */
314
+ byKey(username, workoutKey, params) {
315
+ return getWorkout(this.client, username, workoutKey, params);
316
+ }
282
317
  };
283
318
 
284
319
  // src/users/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suunto-api-wrapper",
3
- "version": "1.1.1",
3
+ "version": "1.2.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"