@nativesquare/soma 0.7.3 → 0.8.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/client/index.d.ts +83 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +131 -0
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/component.d.ts +159 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/garmin.d.ts +190 -6
- package/dist/component/garmin.d.ts.map +1 -1
- package/dist/component/garmin.js +805 -25
- package/dist/component/garmin.js.map +1 -1
- package/dist/component/private.d.ts +18 -0
- package/dist/component/private.d.ts.map +1 -1
- package/dist/component/private.js +18 -0
- package/dist/component/private.js.map +1 -1
- package/dist/component/public.d.ts +88 -42
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +12 -2
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +87 -32
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +2 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/validators/connection.d.ts +1 -0
- package/dist/component/validators/connection.d.ts.map +1 -1
- package/dist/component/validators/connection.js +2 -0
- package/dist/component/validators/connection.js.map +1 -1
- package/dist/component/validators/daily.d.ts +40 -5
- package/dist/component/validators/daily.d.ts.map +1 -1
- package/dist/component/validators/daily.js +10 -1
- package/dist/component/validators/daily.js.map +1 -1
- package/dist/component/validators/enums.d.ts +1 -1
- package/dist/component/validators/plannedWorkout.d.ts +5 -1
- package/dist/component/validators/plannedWorkout.d.ts.map +1 -1
- package/dist/component/validators/plannedWorkout.js +4 -0
- package/dist/component/validators/plannedWorkout.js.map +1 -1
- package/dist/component/validators/sleep.d.ts +8 -8
- package/dist/garmin/activity.d.ts +7 -16
- package/dist/garmin/activity.d.ts.map +1 -1
- package/dist/garmin/activity.js +17 -23
- package/dist/garmin/activity.js.map +1 -1
- package/dist/garmin/bloodPressure.d.ts +28 -0
- package/dist/garmin/bloodPressure.d.ts.map +1 -0
- package/dist/garmin/bloodPressure.js +34 -0
- package/dist/garmin/bloodPressure.js.map +1 -0
- package/dist/garmin/body.js +1 -1
- package/dist/garmin/body.js.map +1 -1
- package/dist/garmin/client.d.ts +117 -17
- package/dist/garmin/client.d.ts.map +1 -1
- package/dist/garmin/client.js +337 -43
- package/dist/garmin/client.js.map +1 -1
- package/dist/garmin/daily.d.ts.map +1 -1
- package/dist/garmin/daily.js +3 -3
- package/dist/garmin/daily.js.map +1 -1
- package/dist/garmin/hrv.d.ts +30 -0
- package/dist/garmin/hrv.d.ts.map +1 -0
- package/dist/garmin/hrv.js +45 -0
- package/dist/garmin/hrv.js.map +1 -0
- package/dist/garmin/index.d.ts +16 -2
- package/dist/garmin/index.d.ts.map +1 -1
- package/dist/garmin/index.js +8 -1
- package/dist/garmin/index.js.map +1 -1
- package/dist/garmin/maps/activity-type.d.ts +1 -2
- package/dist/garmin/maps/activity-type.d.ts.map +1 -1
- package/dist/garmin/maps/activity-type.js +1 -0
- package/dist/garmin/maps/activity-type.js.map +1 -1
- package/dist/garmin/menstruation.d.ts +6 -4
- package/dist/garmin/menstruation.d.ts.map +1 -1
- package/dist/garmin/menstruation.js +12 -8
- package/dist/garmin/menstruation.js.map +1 -1
- package/dist/garmin/pulseOx.d.ts +24 -0
- package/dist/garmin/pulseOx.d.ts.map +1 -0
- package/dist/garmin/pulseOx.js +33 -0
- package/dist/garmin/pulseOx.js.map +1 -0
- package/dist/garmin/respiration.d.ts +29 -0
- package/dist/garmin/respiration.d.ts.map +1 -0
- package/dist/garmin/respiration.js +42 -0
- package/dist/garmin/respiration.js.map +1 -0
- package/dist/garmin/skinTemp.d.ts +27 -0
- package/dist/garmin/skinTemp.d.ts.map +1 -0
- package/dist/garmin/skinTemp.js +35 -0
- package/dist/garmin/skinTemp.js.map +1 -0
- package/dist/garmin/sleep.d.ts +4 -4
- package/dist/garmin/sleep.d.ts.map +1 -1
- package/dist/garmin/sleep.js +15 -9
- package/dist/garmin/sleep.js.map +1 -1
- package/dist/garmin/stressDetails.d.ts +30 -0
- package/dist/garmin/stressDetails.d.ts.map +1 -0
- package/dist/garmin/stressDetails.js +49 -0
- package/dist/garmin/stressDetails.js.map +1 -0
- package/dist/garmin/sync.d.ts +14 -0
- package/dist/garmin/sync.d.ts.map +1 -1
- package/dist/garmin/sync.js +287 -5
- package/dist/garmin/sync.js.map +1 -1
- package/dist/garmin/types.d.ts +77 -186
- package/dist/garmin/types.d.ts.map +1 -1
- package/dist/garmin/types.js +4 -2
- package/dist/garmin/types.js.map +1 -1
- package/dist/garmin/userMetrics.d.ts +23 -0
- package/dist/garmin/userMetrics.d.ts.map +1 -0
- package/dist/garmin/userMetrics.js +41 -0
- package/dist/garmin/userMetrics.js.map +1 -0
- package/dist/validators.d.ts +107 -28
- package/dist/validators.d.ts.map +1 -1
- package/package.json +133 -124
- package/src/client/index.ts +199 -0
- package/src/component/_generated/component.ts +161 -2
- package/src/component/garmin.ts +898 -26
- package/src/component/private.ts +21 -0
- package/src/component/public.ts +11 -2
- package/src/component/schema.ts +2 -1
- package/src/component/validators/connection.ts +2 -0
- package/src/component/validators/daily.ts +15 -0
- package/src/component/validators/plannedWorkout.ts +4 -0
- package/src/garmin/activity.test.ts +13 -21
- package/src/garmin/activity.ts +38 -45
- package/src/garmin/bloodPressure.ts +41 -0
- package/src/garmin/body.ts +1 -1
- package/src/garmin/client.ts +550 -71
- package/src/garmin/daily.ts +8 -4
- package/src/garmin/hrv.ts +57 -0
- package/src/garmin/index.ts +77 -7
- package/src/garmin/maps/activity-type.ts +2 -2
- package/src/garmin/menstruation.ts +14 -12
- package/src/garmin/pulseOx.ts +45 -0
- package/src/garmin/respiration.ts +55 -0
- package/src/garmin/skinTemp.ts +42 -0
- package/src/garmin/sleep.test.ts +5 -6
- package/src/garmin/sleep.ts +22 -16
- package/src/garmin/spec/wellness-api.json +1 -0
- package/src/garmin/stressDetails.ts +71 -0
- package/src/garmin/sync.ts +348 -5
- package/src/garmin/types.ts +88 -300
- package/src/garmin/userMetrics.ts +50 -0
- package/src/garmin/wellness-api.d.ts +5637 -0
package/src/garmin/types.ts
CHANGED
|
@@ -1,318 +1,100 @@
|
|
|
1
1
|
// ─── Garmin Health API Response Types ────────────────────────────────────────
|
|
2
|
-
// TypeScript
|
|
3
|
-
//
|
|
2
|
+
// TypeScript types representing Garmin Health API data shapes.
|
|
3
|
+
//
|
|
4
|
+
// Wellness API types are derived from the OpenAPI spec (wellness-api.d.ts).
|
|
5
|
+
// Training API types are manually defined from the Garmin Connect docs.
|
|
4
6
|
//
|
|
5
7
|
// These types define the CONTRACT for data coming from the Garmin API.
|
|
6
8
|
// They are used by transformers, the API client, and OAuth helpers.
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
averageRunCadenceInStepsPerMinute?: number;
|
|
44
|
-
maxRunCadenceInStepsPerMinute?: number;
|
|
45
|
-
averageBikeCadenceInRoundsPerMinute?: number;
|
|
46
|
-
maxBikeCadenceInRoundsPerMinute?: number;
|
|
47
|
-
|
|
48
|
-
// Power
|
|
49
|
-
averagePowerInWatts?: number;
|
|
50
|
-
maxPowerInWatts?: number;
|
|
51
|
-
normalizedPowerInWatts?: number;
|
|
52
|
-
|
|
53
|
-
// Swimming
|
|
54
|
-
numberOfActiveLengths?: number;
|
|
55
|
-
poolLengthInMeters?: number;
|
|
56
|
-
averageSwimCadenceInStrokesPerMinute?: number;
|
|
57
|
-
|
|
58
|
-
// Position
|
|
59
|
-
startingLatitudeInDegree?: number;
|
|
60
|
-
startingLongitudeInDegree?: number;
|
|
61
|
-
|
|
62
|
-
// Steps
|
|
63
|
-
steps?: number;
|
|
64
|
-
|
|
65
|
-
// Laps
|
|
66
|
-
laps?: GarminActivityLap[];
|
|
67
|
-
|
|
68
|
-
// Samples (time-series)
|
|
69
|
-
samples?: GarminActivitySample[];
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface GarminActivityLap {
|
|
73
|
-
startTimeInSeconds: number;
|
|
74
|
-
airTemperatureCelsius?: number;
|
|
75
|
-
heartRate?: number;
|
|
76
|
-
totalDistanceInMeters?: number;
|
|
77
|
-
timerDurationInSeconds: number;
|
|
78
|
-
maxSpeed?: number;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export interface GarminActivitySample {
|
|
82
|
-
startTimeInSeconds?: number;
|
|
83
|
-
latitudeInDegree?: number;
|
|
84
|
-
longitudeInDegree?: number;
|
|
85
|
-
elevationInMeters?: number;
|
|
86
|
-
heartRate?: number;
|
|
87
|
-
speedMetersPerSecond?: number;
|
|
88
|
-
bikeCadenceInRPM?: number;
|
|
89
|
-
runCadenceInStepsPerMinute?: number;
|
|
90
|
-
powerInWatts?: number;
|
|
91
|
-
timerDurationInSeconds?: number;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// ─── Daily Summary ──────────────────────────────────────────────────────────
|
|
95
|
-
|
|
96
|
-
export interface GarminDailySummary {
|
|
97
|
-
userId: string;
|
|
98
|
-
userAccessToken: string;
|
|
99
|
-
summaryId: string;
|
|
100
|
-
calendarDate: string; // "YYYY-MM-DD"
|
|
101
|
-
startTimeInSeconds: number;
|
|
102
|
-
startTimeOffsetInSeconds: number;
|
|
103
|
-
durationInSeconds: number;
|
|
104
|
-
|
|
105
|
-
// Activity
|
|
106
|
-
steps?: number;
|
|
107
|
-
distanceInMeters?: number;
|
|
108
|
-
floorsClimbed?: number;
|
|
109
|
-
activeTimeInSeconds?: number;
|
|
110
|
-
activeKilocalories?: number;
|
|
111
|
-
bmrKilocalories?: number;
|
|
112
|
-
moderateIntensityDurationInSeconds?: number;
|
|
113
|
-
vigorousIntensityDurationInSeconds?: number;
|
|
114
|
-
intensityDurationGoalInSeconds?: number;
|
|
115
|
-
|
|
116
|
-
// Heart rate
|
|
117
|
-
minHeartRateInBeatsPerMinute?: number;
|
|
118
|
-
maxHeartRateInBeatsPerMinute?: number;
|
|
119
|
-
averageHeartRateInBeatsPerMinute?: number;
|
|
120
|
-
restingHeartRateInBeatsPerMinute?: number;
|
|
121
|
-
timeOffsetHeartRateSamples?: Record<string, number>;
|
|
122
|
-
|
|
123
|
-
// Stress
|
|
124
|
-
averageStressLevel?: number;
|
|
125
|
-
maxStressLevel?: number;
|
|
126
|
-
stressDurationInSeconds?: number;
|
|
127
|
-
restStressDurationInSeconds?: number;
|
|
128
|
-
activityStressDurationInSeconds?: number;
|
|
129
|
-
lowStressDurationInSeconds?: number;
|
|
130
|
-
mediumStressDurationInSeconds?: number;
|
|
131
|
-
highStressDurationInSeconds?: number;
|
|
10
|
+
import type { components } from "./wellness-api.js";
|
|
11
|
+
|
|
12
|
+
// ─── Wellness API Type Aliases ──────────────────────────────────────────────
|
|
13
|
+
// Convenience aliases for the generated OpenAPI schema types.
|
|
14
|
+
|
|
15
|
+
export type GarminDaily = components["schemas"]["ClientDaily"];
|
|
16
|
+
export type GarminActivity = components["schemas"]["ClientActivity"];
|
|
17
|
+
export type GarminActivityDetail = components["schemas"]["ClientActivityDetail"];
|
|
18
|
+
export type GarminSleep = components["schemas"]["ClientSleep"];
|
|
19
|
+
export type GarminBodyComposition = components["schemas"]["ClientBodyComp"];
|
|
20
|
+
export type GarminMenstrualCycle = components["schemas"]["ClientSummarizedMenstrualCycle"];
|
|
21
|
+
export type GarminUserMetrics = components["schemas"]["ClientUserMetrics"];
|
|
22
|
+
export type GarminStressDetail = components["schemas"]["ClientStress"];
|
|
23
|
+
export type GarminSkinTemperature = components["schemas"]["ClientSkinTemp"];
|
|
24
|
+
export type GarminRespiration = components["schemas"]["ClientRespiration"];
|
|
25
|
+
export type GarminPulseOx = components["schemas"]["ClientDailySpo2Acclimation"];
|
|
26
|
+
export type GarminMoveIQEvent = components["schemas"]["ClientAutoActivityMoveIq"];
|
|
27
|
+
export type GarminHRVSummary = components["schemas"]["ClientHRVSummary"];
|
|
28
|
+
export type GarminHealthSnapshot = components["schemas"]["ClientHealthSnapshot"];
|
|
29
|
+
export type GarminEpoch = components["schemas"]["ClientEpoch"];
|
|
30
|
+
export type GarminBloodPressure = components["schemas"]["ClientBloodPressure"];
|
|
31
|
+
export type GarminSolar = components["schemas"]["ClientSolar"];
|
|
32
|
+
export type GarminSample = components["schemas"]["Sample"];
|
|
33
|
+
export type GarminLap = components["schemas"]["ClientLap"];
|
|
34
|
+
export type GarminTimeRange = components["schemas"]["TimeRange"];
|
|
35
|
+
export type GarminSleepScoreItem = components["schemas"]["ClientSleepScoreItem"];
|
|
36
|
+
export type GarminNap = components["schemas"]["ClientNaps"];
|
|
37
|
+
|
|
38
|
+
// ─── Extended Types ─────────────────────────────────────────────────────────
|
|
39
|
+
// The Garmin API returns additional fields beyond what the OpenAPI spec
|
|
40
|
+
// documents. These extended types add those fields so transformers can use them.
|
|
41
|
+
|
|
42
|
+
// Extended daily type with fields the API returns beyond what the spec documents
|
|
43
|
+
export type GarminDailyExtended = GarminDaily & {
|
|
44
|
+
// Time-series stress data (returned by API, not in spec)
|
|
132
45
|
timeOffsetStressLevelValues?: Record<string, number>;
|
|
133
|
-
|
|
134
|
-
// Body battery
|
|
135
46
|
timeOffsetBodyBatteryValues?: Record<string, number>;
|
|
136
|
-
|
|
137
|
-
// Pulse Ox
|
|
47
|
+
// SpO2 data (returned by API, not in spec)
|
|
138
48
|
averageSpo2Value?: number;
|
|
139
49
|
lowestSpo2Value?: number;
|
|
140
50
|
latestSpo2Value?: number;
|
|
141
51
|
timeOffsetSpo2Values?: Record<string, number>;
|
|
142
|
-
|
|
143
|
-
// Respiration
|
|
52
|
+
// Respiration data (returned by API, not in spec)
|
|
144
53
|
averageRespirationInBreathsPerMinute?: number;
|
|
145
54
|
lowestRespirationInBreathsPerMinute?: number;
|
|
146
55
|
highestRespirationInBreathsPerMinute?: number;
|
|
147
56
|
timeOffsetRespirationSamples?: Record<string, number>;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// ─── Sleep ──────────────────────────────────────────────────────────────────
|
|
151
|
-
|
|
152
|
-
export interface GarminSleep {
|
|
153
|
-
userId: string;
|
|
154
|
-
userAccessToken: string;
|
|
155
|
-
summaryId: string;
|
|
156
|
-
calendarDate: string;
|
|
157
|
-
startTimeInSeconds: number;
|
|
158
|
-
startTimeOffsetInSeconds: number;
|
|
159
|
-
durationInSeconds: number;
|
|
160
|
-
unmeasurableSleepInSeconds?: number;
|
|
161
|
-
|
|
162
|
-
// Sleep stages
|
|
163
|
-
deepSleepDurationInSeconds?: number;
|
|
164
|
-
lightSleepDurationInSeconds?: number;
|
|
165
|
-
remSleepInSeconds?: number;
|
|
166
|
-
awakeDurationInSeconds?: number;
|
|
57
|
+
};
|
|
167
58
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
// Validation
|
|
172
|
-
validation: "ENHANCED_TENTATIVE" | "ENHANCED_FINAL" | "AUTO_TENTATIVE" | "AUTO_FINAL" | "MANUAL" | string;
|
|
173
|
-
|
|
174
|
-
// Respiration
|
|
59
|
+
// Extended sleep type with fields the API returns beyond what the spec documents
|
|
60
|
+
export type GarminSleepExtended = GarminSleep & {
|
|
61
|
+
// Respiration aggregates (returned by API, not in spec)
|
|
175
62
|
averageRespirationInBreathsPerMinute?: number;
|
|
176
63
|
lowestRespirationInBreathsPerMinute?: number;
|
|
177
64
|
highestRespirationInBreathsPerMinute?: number;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// SpO2
|
|
65
|
+
// SpO2 aggregates (returned by API, not in spec)
|
|
181
66
|
averageSpo2Value?: number;
|
|
182
67
|
lowestSpo2Value?: number;
|
|
183
68
|
highestSpo2Value?: number;
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
// Sleep levels (time-series)
|
|
187
|
-
sleepLevelsMap?: {
|
|
188
|
-
deep?: GarminSleepLevel[];
|
|
189
|
-
light?: GarminSleepLevel[];
|
|
190
|
-
rem?: GarminSleepLevel[];
|
|
191
|
-
awake?: GarminSleepLevel[];
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
// Heart rate
|
|
69
|
+
// Heart rate samples (returned by API, not in spec)
|
|
195
70
|
timeOffsetHeartRateSamples?: Record<string, number>;
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
//
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
bodyFatInPercent?: number;
|
|
216
|
-
bodyMassIndex?: number;
|
|
217
|
-
weightInGrams?: number;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// ─── Menstrual Cycle ────────────────────────────────────────────────────────
|
|
221
|
-
|
|
222
|
-
export interface GarminMenstrualCycleData {
|
|
223
|
-
userId: string;
|
|
224
|
-
userAccessToken: string;
|
|
225
|
-
summaryId?: string;
|
|
226
|
-
calendarDate: string;
|
|
227
|
-
startTimeInSeconds?: number;
|
|
228
|
-
startTimeOffsetInSeconds?: number;
|
|
229
|
-
|
|
230
|
-
dayInCycle?: number;
|
|
231
|
-
currentPhase?: string;
|
|
232
|
-
lengthOfCurrentPhase?: number;
|
|
233
|
-
periodLength?: number;
|
|
234
|
-
predictedCycleLength?: number;
|
|
235
|
-
isPredictedCycle?: boolean;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// ─── User Profile ───────────────────────────────────────────────────────────
|
|
239
|
-
// Limited profile info available from the Garmin Health API.
|
|
240
|
-
|
|
241
|
-
export interface GarminUserProfile {
|
|
242
|
-
userId: string;
|
|
243
|
-
displayName?: string;
|
|
244
|
-
weight?: number;
|
|
245
|
-
height?: number;
|
|
246
|
-
birthDate?: string;
|
|
247
|
-
gender?: string;
|
|
248
|
-
}
|
|
71
|
+
// Alternate SpO2 field name (some responses use this instead of timeOffsetSleepSpo2)
|
|
72
|
+
timeOffsetSpo2Values?: Record<string, number>;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Extended activity type for webhook payloads which include detail-level fields
|
|
76
|
+
// (laps, samples, power) that the summary endpoint does not return.
|
|
77
|
+
export type GarminActivityExtended = GarminActivity & {
|
|
78
|
+
// Fields from /rest/activityDetails and webhook payloads
|
|
79
|
+
laps?: GarminLap[];
|
|
80
|
+
samples?: GarminSample[];
|
|
81
|
+
bmrKilocalories?: number;
|
|
82
|
+
averagePowerInWatts?: number;
|
|
83
|
+
maxPowerInWatts?: number;
|
|
84
|
+
normalizedPowerInWatts?: number;
|
|
85
|
+
poolLengthInMeters?: number;
|
|
86
|
+
// Webhook payloads may use these alternate field names
|
|
87
|
+
elevationGainInMeters?: number;
|
|
88
|
+
elevationLossInMeters?: number;
|
|
89
|
+
};
|
|
249
90
|
|
|
250
|
-
// ───
|
|
251
|
-
// Known Garmin activity type strings from the API.
|
|
91
|
+
// ─── Backward Compatibility Aliases ─────────────────────────────────────────
|
|
252
92
|
|
|
253
|
-
export type
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
| "CYCLING"
|
|
259
|
-
| "INDOOR_CYCLING"
|
|
260
|
-
| "MOUNTAIN_BIKING"
|
|
261
|
-
| "GRAVEL_CYCLING"
|
|
262
|
-
| "VIRTUAL_RIDE"
|
|
263
|
-
| "WALKING"
|
|
264
|
-
| "HIKING"
|
|
265
|
-
| "SWIMMING"
|
|
266
|
-
| "OPEN_WATER_SWIMMING"
|
|
267
|
-
| "LAP_SWIMMING"
|
|
268
|
-
| "POOL_SWIMMING"
|
|
269
|
-
| "STRENGTH_TRAINING"
|
|
270
|
-
| "YOGA"
|
|
271
|
-
| "PILATES"
|
|
272
|
-
| "CARDIO"
|
|
273
|
-
| "ELLIPTICAL"
|
|
274
|
-
| "STAIR_CLIMBING"
|
|
275
|
-
| "ROWING"
|
|
276
|
-
| "INDOOR_ROWING"
|
|
277
|
-
| "CROSS_COUNTRY_SKIING"
|
|
278
|
-
| "ALPINE_SKIING"
|
|
279
|
-
| "SNOWBOARDING"
|
|
280
|
-
| "SNOWSHOEING"
|
|
281
|
-
| "SKATING"
|
|
282
|
-
| "INLINE_SKATING"
|
|
283
|
-
| "GOLF"
|
|
284
|
-
| "TENNIS"
|
|
285
|
-
| "TABLE_TENNIS"
|
|
286
|
-
| "BADMINTON"
|
|
287
|
-
| "RACQUETBALL"
|
|
288
|
-
| "SQUASH"
|
|
289
|
-
| "PADDLEBOARDING"
|
|
290
|
-
| "KAYAKING"
|
|
291
|
-
| "CANOEING"
|
|
292
|
-
| "SAILING"
|
|
293
|
-
| "SURFING"
|
|
294
|
-
| "KITESURFING"
|
|
295
|
-
| "WINDSURFING"
|
|
296
|
-
| "ROCK_CLIMBING"
|
|
297
|
-
| "BOULDERING"
|
|
298
|
-
| "SOCCER"
|
|
299
|
-
| "BASKETBALL"
|
|
300
|
-
| "VOLLEYBALL"
|
|
301
|
-
| "CRICKET"
|
|
302
|
-
| "RUGBY"
|
|
303
|
-
| "BOXING"
|
|
304
|
-
| "MARTIAL_ARTS"
|
|
305
|
-
| "CROSSFIT"
|
|
306
|
-
| "HIIT"
|
|
307
|
-
| "BREATHWORK"
|
|
308
|
-
| "FLOOR_CLIMBING"
|
|
309
|
-
| "HANDCYCLING"
|
|
310
|
-
| "WHEELCHAIR_PUSH_WALKING"
|
|
311
|
-
| "WHEELCHAIR_PUSH_RUNNING"
|
|
312
|
-
| "OTHER"
|
|
313
|
-
| "MULTI_SPORT"
|
|
314
|
-
| "FITNESS_EQUIPMENT"
|
|
315
|
-
| (string & {});
|
|
93
|
+
export type GarminDailySummary = GarminDailyExtended;
|
|
94
|
+
export type GarminMenstrualCycleData = GarminMenstrualCycle;
|
|
95
|
+
export type GarminSleepLevel = GarminTimeRange;
|
|
96
|
+
export type GarminActivityLap = GarminLap;
|
|
97
|
+
export type GarminActivitySample = GarminSample;
|
|
316
98
|
|
|
317
99
|
// ─── OAuth 2.0 ──────────────────────────────────────────────────────────────
|
|
318
100
|
|
|
@@ -468,13 +250,19 @@ export interface GarminWorkoutSchedule {
|
|
|
468
250
|
date: string;
|
|
469
251
|
}
|
|
470
252
|
|
|
471
|
-
// ───
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
253
|
+
// ─── Push-Mode Webhook Payloads ─────────────────────────────────────────────
|
|
254
|
+
// In push mode, Garmin sends full data objects directly in the POST body.
|
|
255
|
+
// Each data type has its own webhook URL configured in the Garmin developer
|
|
256
|
+
// portal, so each payload is a typed array of the corresponding summary type.
|
|
257
|
+
|
|
258
|
+
export type GarminWebhookActivityPayload = (GarminActivity & { userAccessToken?: string })[];
|
|
259
|
+
export type GarminWebhookDailyPayload = (GarminDailyExtended & { userAccessToken?: string })[];
|
|
260
|
+
export type GarminWebhookSleepPayload = (GarminSleepExtended & { userAccessToken?: string })[];
|
|
261
|
+
export type GarminWebhookBodyPayload = (GarminBodyComposition & { userAccessToken?: string })[];
|
|
262
|
+
export type GarminWebhookBloodPressurePayload = (GarminBloodPressure & { userAccessToken?: string })[];
|
|
263
|
+
export type GarminWebhookSkinTempPayload = (GarminSkinTemperature & { userAccessToken?: string })[];
|
|
264
|
+
export type GarminWebhookUserMetricsPayload = (GarminUserMetrics & { userAccessToken?: string })[];
|
|
265
|
+
export type GarminWebhookHRVPayload = (GarminHRVSummary & { userAccessToken?: string })[];
|
|
266
|
+
export type GarminWebhookStressDetailPayload = (GarminStressDetail & { userAccessToken?: string })[];
|
|
267
|
+
export type GarminWebhookPulseOxPayload = (GarminPulseOx & { userAccessToken?: string })[];
|
|
268
|
+
export type GarminWebhookRespirationPayload = (GarminRespiration & { userAccessToken?: string })[];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// ─── User Metrics Transformer ────────────────────────────────────────────────
|
|
2
|
+
// Transforms Garmin user metrics into the Soma Body schema shape.
|
|
3
|
+
|
|
4
|
+
import type { GarminUserMetrics } from "./types.js";
|
|
5
|
+
|
|
6
|
+
export type UserMetricsData = ReturnType<typeof transformUserMetrics>;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Transform Garmin user metrics into a Soma Body document shape.
|
|
10
|
+
*
|
|
11
|
+
* Maps VO2 Max and fitness age into oxygen_data and scores fields.
|
|
12
|
+
*
|
|
13
|
+
* @param metrics - The Garmin user metrics from the Health API
|
|
14
|
+
* @returns Soma Body fields (without connectionId/userId)
|
|
15
|
+
*/
|
|
16
|
+
export function transformUserMetrics(metrics: GarminUserMetrics) {
|
|
17
|
+
const dateStr = metrics.calendarDate;
|
|
18
|
+
const startTime = dateStr
|
|
19
|
+
? `${dateStr}T00:00:00.000Z`
|
|
20
|
+
: new Date(0).toISOString();
|
|
21
|
+
const endTime = dateStr
|
|
22
|
+
? `${dateStr}T23:59:59.999Z`
|
|
23
|
+
: new Date(0).toISOString();
|
|
24
|
+
|
|
25
|
+
const hasVo2 = metrics.vo2Max != null || metrics.vo2MaxCycling != null;
|
|
26
|
+
const hasFitnessAge = metrics.fitnessAge != null;
|
|
27
|
+
|
|
28
|
+
if (!hasVo2 && !hasFitnessAge) {
|
|
29
|
+
return {
|
|
30
|
+
metadata: { start_time: startTime, end_time: endTime },
|
|
31
|
+
oxygen_data: undefined,
|
|
32
|
+
scores: undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
metadata: {
|
|
38
|
+
start_time: startTime,
|
|
39
|
+
end_time: endTime,
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
oxygen_data: hasVo2
|
|
43
|
+
? { vo2max_ml_per_min_per_kg: metrics.vo2Max ?? metrics.vo2MaxCycling }
|
|
44
|
+
: undefined,
|
|
45
|
+
|
|
46
|
+
scores: hasFitnessAge
|
|
47
|
+
? { biological_age: metrics.fitnessAge }
|
|
48
|
+
: undefined,
|
|
49
|
+
};
|
|
50
|
+
}
|