@nativesquare/soma 0.2.0 → 0.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/client/index.d.ts +167 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +150 -0
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +56 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/garmin.d.ts +110 -0
- package/dist/component/garmin.d.ts.map +1 -0
- package/dist/component/garmin.js +454 -0
- package/dist/component/garmin.js.map +1 -0
- package/dist/component/public.d.ts +761 -761
- package/dist/component/schema.d.ts +390 -388
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +3 -2
- package/dist/component/schema.js.map +1 -1
- package/dist/component/strava.d.ts +5 -4
- package/dist/component/strava.d.ts.map +1 -1
- package/dist/component/strava.js +18 -1
- package/dist/component/strava.js.map +1 -1
- package/dist/component/validators/activity.d.ts +42 -42
- package/dist/component/validators/body.d.ts +47 -47
- package/dist/component/validators/daily.d.ts +17 -17
- package/dist/component/validators/plannedWorkout.d.ts +5 -5
- package/dist/component/validators/samples.d.ts +2 -2
- package/dist/component/validators/shared.d.ts +17 -17
- package/dist/component/validators/sleep.d.ts +17 -17
- package/dist/garmin/activity.d.ts +101 -0
- package/dist/garmin/activity.d.ts.map +1 -0
- package/dist/garmin/activity.js +207 -0
- package/dist/garmin/activity.js.map +1 -0
- package/dist/garmin/auth.d.ts +65 -0
- package/dist/garmin/auth.d.ts.map +1 -0
- package/dist/garmin/auth.js +155 -0
- package/dist/garmin/auth.js.map +1 -0
- package/dist/garmin/body.d.ts +26 -0
- package/dist/garmin/body.d.ts.map +1 -0
- package/dist/garmin/body.js +44 -0
- package/dist/garmin/body.js.map +1 -0
- package/dist/garmin/client.d.ts +99 -0
- package/dist/garmin/client.d.ts.map +1 -0
- package/dist/garmin/client.js +153 -0
- package/dist/garmin/client.js.map +1 -0
- package/dist/garmin/daily.d.ts +74 -0
- package/dist/garmin/daily.d.ts.map +1 -0
- package/dist/garmin/daily.js +143 -0
- package/dist/garmin/daily.js.map +1 -0
- package/dist/garmin/index.d.ts +20 -0
- package/dist/garmin/index.d.ts.map +1 -0
- package/dist/garmin/index.js +21 -0
- package/dist/garmin/index.js.map +1 -0
- package/dist/garmin/maps/activity-type.d.ts +7 -0
- package/dist/garmin/maps/activity-type.d.ts.map +1 -0
- package/dist/garmin/maps/activity-type.js +98 -0
- package/dist/garmin/maps/activity-type.js.map +1 -0
- package/dist/garmin/maps/sleep-level.d.ts +6 -0
- package/dist/garmin/maps/sleep-level.d.ts.map +1 -0
- package/dist/garmin/maps/sleep-level.js +21 -0
- package/dist/garmin/maps/sleep-level.js.map +1 -0
- package/dist/garmin/menstruation.d.ts +23 -0
- package/dist/garmin/menstruation.d.ts.map +1 -0
- package/dist/garmin/menstruation.js +34 -0
- package/dist/garmin/menstruation.js.map +1 -0
- package/dist/garmin/sleep.d.ts +62 -0
- package/dist/garmin/sleep.d.ts.map +1 -0
- package/dist/garmin/sleep.js +125 -0
- package/dist/garmin/sleep.js.map +1 -0
- package/dist/garmin/sync.d.ts +39 -0
- package/dist/garmin/sync.d.ts.map +1 -0
- package/dist/garmin/sync.js +175 -0
- package/dist/garmin/sync.js.map +1 -0
- package/dist/garmin/types.d.ts +212 -0
- package/dist/garmin/types.d.ts.map +1 -0
- package/dist/garmin/types.js +8 -0
- package/dist/garmin/types.js.map +1 -0
- package/dist/validators.d.ts +6617 -0
- package/dist/validators.d.ts.map +1 -0
- package/dist/validators.js +78 -0
- package/dist/validators.js.map +1 -0
- package/package.json +9 -1
- package/src/client/index.ts +194 -1
- package/src/component/_generated/api.ts +2 -0
- package/src/component/_generated/component.ts +62 -0
- package/src/component/garmin.ts +534 -0
- package/src/component/schema.ts +3 -2
- package/src/component/strava.ts +23 -1
- package/src/garmin/activity.test.ts +178 -0
- package/src/garmin/activity.ts +272 -0
- package/src/garmin/auth.test.ts +128 -0
- package/src/garmin/auth.ts +249 -0
- package/src/garmin/body.ts +59 -0
- package/src/garmin/client.ts +254 -0
- package/src/garmin/daily.ts +211 -0
- package/src/garmin/index.ts +76 -0
- package/src/garmin/maps/activity-type.test.ts +78 -0
- package/src/garmin/maps/activity-type.ts +116 -0
- package/src/garmin/maps/sleep-level.ts +22 -0
- package/src/garmin/menstruation.ts +42 -0
- package/src/garmin/sleep.test.ts +110 -0
- package/src/garmin/sleep.ts +170 -0
- package/src/garmin/sync.ts +223 -0
- package/src/garmin/types.ts +338 -0
- package/src/validators.ts +89 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
// ─── Garmin Health API Response Types ────────────────────────────────────────
|
|
2
|
+
// TypeScript interfaces representing Garmin Health API data shapes.
|
|
3
|
+
// Derived from the Garmin Connect Developer Program documentation.
|
|
4
|
+
//
|
|
5
|
+
// These types define the CONTRACT for data coming from the Garmin API.
|
|
6
|
+
// They are used by transformers, the API client, and OAuth helpers.
|
|
7
|
+
|
|
8
|
+
// ─── Activity ─────────────────────────────────────────────────────────────────
|
|
9
|
+
|
|
10
|
+
export interface GarminActivity {
|
|
11
|
+
userId: string;
|
|
12
|
+
userAccessToken: string;
|
|
13
|
+
summaryId: string;
|
|
14
|
+
activityId: number;
|
|
15
|
+
activityName?: string;
|
|
16
|
+
activityType: string;
|
|
17
|
+
durationInSeconds: number;
|
|
18
|
+
startTimeInSeconds: number;
|
|
19
|
+
startTimeOffsetInSeconds: number;
|
|
20
|
+
deviceName?: string;
|
|
21
|
+
manual?: boolean;
|
|
22
|
+
|
|
23
|
+
// Distance
|
|
24
|
+
distanceInMeters?: number;
|
|
25
|
+
elevationGainInMeters?: number;
|
|
26
|
+
elevationLossInMeters?: number;
|
|
27
|
+
|
|
28
|
+
// Calories
|
|
29
|
+
activeKilocalories?: number;
|
|
30
|
+
bmrKilocalories?: number;
|
|
31
|
+
|
|
32
|
+
// Heart rate
|
|
33
|
+
averageHeartRateInBeatsPerMinute?: number;
|
|
34
|
+
maxHeartRateInBeatsPerMinute?: number;
|
|
35
|
+
|
|
36
|
+
// Speed / pace
|
|
37
|
+
averageSpeedInMetersPerSecond?: number;
|
|
38
|
+
maxSpeedInMetersPerSecond?: number;
|
|
39
|
+
averagePaceInMinutesPerKilometer?: number;
|
|
40
|
+
maxPaceInMinutesPerKilometer?: number;
|
|
41
|
+
|
|
42
|
+
// Cadence
|
|
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;
|
|
132
|
+
timeOffsetStressLevelValues?: Record<string, number>;
|
|
133
|
+
|
|
134
|
+
// Body battery
|
|
135
|
+
timeOffsetBodyBatteryValues?: Record<string, number>;
|
|
136
|
+
|
|
137
|
+
// Pulse Ox
|
|
138
|
+
averageSpo2Value?: number;
|
|
139
|
+
lowestSpo2Value?: number;
|
|
140
|
+
latestSpo2Value?: number;
|
|
141
|
+
timeOffsetSpo2Values?: Record<string, number>;
|
|
142
|
+
|
|
143
|
+
// Respiration
|
|
144
|
+
averageRespirationInBreathsPerMinute?: number;
|
|
145
|
+
lowestRespirationInBreathsPerMinute?: number;
|
|
146
|
+
highestRespirationInBreathsPerMinute?: number;
|
|
147
|
+
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;
|
|
167
|
+
|
|
168
|
+
// Nap
|
|
169
|
+
totalNapDurationInSeconds?: number;
|
|
170
|
+
|
|
171
|
+
// Validation
|
|
172
|
+
validation: "ENHANCED_TENTATIVE" | "ENHANCED_FINAL" | "AUTO_TENTATIVE" | "AUTO_FINAL" | "MANUAL" | string;
|
|
173
|
+
|
|
174
|
+
// Respiration
|
|
175
|
+
averageRespirationInBreathsPerMinute?: number;
|
|
176
|
+
lowestRespirationInBreathsPerMinute?: number;
|
|
177
|
+
highestRespirationInBreathsPerMinute?: number;
|
|
178
|
+
timeOffsetSleepRespiration?: Record<string, number>;
|
|
179
|
+
|
|
180
|
+
// SpO2
|
|
181
|
+
averageSpo2Value?: number;
|
|
182
|
+
lowestSpo2Value?: number;
|
|
183
|
+
highestSpo2Value?: number;
|
|
184
|
+
timeOffsetSpo2Values?: Record<string, number>;
|
|
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
|
|
195
|
+
timeOffsetHeartRateSamples?: Record<string, number>;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
export interface GarminSleepLevel {
|
|
199
|
+
startTimeInSeconds: number;
|
|
200
|
+
endTimeInSeconds: number;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ─── Body Composition ───────────────────────────────────────────────────────
|
|
204
|
+
|
|
205
|
+
export interface GarminBodyComposition {
|
|
206
|
+
userId: string;
|
|
207
|
+
userAccessToken: string;
|
|
208
|
+
summaryId?: string;
|
|
209
|
+
measurementTimeInSeconds: number;
|
|
210
|
+
measurementTimeOffsetInSeconds?: number;
|
|
211
|
+
|
|
212
|
+
muscleMassInGrams?: number;
|
|
213
|
+
boneMassInGrams?: number;
|
|
214
|
+
bodyWaterInPercent?: number;
|
|
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
|
+
}
|
|
249
|
+
|
|
250
|
+
// ─── Garmin Activity Type ───────────────────────────────────────────────────
|
|
251
|
+
// Known Garmin activity type strings from the API.
|
|
252
|
+
|
|
253
|
+
export type GarminActivityType =
|
|
254
|
+
| "RUNNING"
|
|
255
|
+
| "INDOOR_RUNNING"
|
|
256
|
+
| "TRAIL_RUNNING"
|
|
257
|
+
| "TREADMILL_RUNNING"
|
|
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 & {});
|
|
316
|
+
|
|
317
|
+
// ─── OAuth ──────────────────────────────────────────────────────────────────
|
|
318
|
+
|
|
319
|
+
export interface GarminOAuthRequestTokenResponse {
|
|
320
|
+
oauthToken: string;
|
|
321
|
+
oauthTokenSecret: string;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
export interface GarminOAuthAccessTokenResponse {
|
|
325
|
+
oauthToken: string;
|
|
326
|
+
oauthTokenSecret: string;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// ─── API Response Wrappers ──────────────────────────────────────────────────
|
|
330
|
+
|
|
331
|
+
export interface GarminWebhookPayload {
|
|
332
|
+
activities?: Array<{ userId: string; summaryId: string; callbackURL: string }>;
|
|
333
|
+
activityDetails?: Array<{ userId: string; summaryId: string; callbackURL: string }>;
|
|
334
|
+
dailies?: Array<{ userId: string; summaryId: string; callbackURL: string }>;
|
|
335
|
+
sleeps?: Array<{ userId: string; summaryId: string; callbackURL: string }>;
|
|
336
|
+
bodyComps?: Array<{ userId: string; summaryId: string; callbackURL: string }>;
|
|
337
|
+
stressDetails?: Array<{ userId: string; summaryId: string; callbackURL: string }>;
|
|
338
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
// ─── Soma Validators ─────────────────────────────────────────────────────────
|
|
2
|
+
// Re-exports the Convex validators for each Soma table so host apps can use
|
|
3
|
+
// them for type-safe argument validation in their own mutations.
|
|
4
|
+
//
|
|
5
|
+
// Two flavors are exported for each table:
|
|
6
|
+
//
|
|
7
|
+
// *Validator — Full validator including connectionId (v.string()) and userId.
|
|
8
|
+
// Use when the mutation args map 1:1 to a soma.ingestX() call.
|
|
9
|
+
//
|
|
10
|
+
// *Data — Data-only validator (no connectionId/userId).
|
|
11
|
+
// Use when connection is resolved server-side and the client
|
|
12
|
+
// only sends the health data payload.
|
|
13
|
+
//
|
|
14
|
+
// ─── Examples ────────────────────────────────────────────────────────────────
|
|
15
|
+
//
|
|
16
|
+
// Direct ingest (client provides connectionId):
|
|
17
|
+
//
|
|
18
|
+
// import { activityValidator } from "@nativesquare/soma/validators";
|
|
19
|
+
//
|
|
20
|
+
// export const storeActivity = mutation({
|
|
21
|
+
// args: activityValidator,
|
|
22
|
+
// handler: async (ctx, args) => {
|
|
23
|
+
// await soma.ingestActivity(ctx, args);
|
|
24
|
+
// },
|
|
25
|
+
// });
|
|
26
|
+
//
|
|
27
|
+
// Batch sync (connection resolved server-side):
|
|
28
|
+
//
|
|
29
|
+
// import { activityData } from "@nativesquare/soma/validators";
|
|
30
|
+
//
|
|
31
|
+
// export const syncHealthKit = mutation({
|
|
32
|
+
// args: { activities: v.array(v.object(activityData)) },
|
|
33
|
+
// handler: async (ctx, args) => {
|
|
34
|
+
// const connectionId = await soma.connect(ctx, { userId, provider: "HEALTHKIT" });
|
|
35
|
+
// for (const activity of args.activities) {
|
|
36
|
+
// await soma.ingestActivity(ctx, { connectionId, userId, ...activity });
|
|
37
|
+
// }
|
|
38
|
+
// },
|
|
39
|
+
// });
|
|
40
|
+
|
|
41
|
+
import { v } from "convex/values";
|
|
42
|
+
import { connectionValidator as _connectionValidator } from "./component/validators/connection.js";
|
|
43
|
+
import { athleteValidator as _athleteValidator } from "./component/validators/athlete.js";
|
|
44
|
+
import { activityValidator as _activityValidator } from "./component/validators/activity.js";
|
|
45
|
+
import { bodyValidator as _bodyValidator } from "./component/validators/body.js";
|
|
46
|
+
import { dailyValidator as _dailyValidator } from "./component/validators/daily.js";
|
|
47
|
+
import { sleepValidator as _sleepValidator } from "./component/validators/sleep.js";
|
|
48
|
+
import { menstruationValidator as _menstruationValidator } from "./component/validators/menstruation.js";
|
|
49
|
+
import { nutritionValidator as _nutritionValidator } from "./component/validators/nutrition.js";
|
|
50
|
+
import { plannedWorkoutValidator as _plannedWorkoutValidator } from "./component/validators/plannedWorkout.js";
|
|
51
|
+
|
|
52
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
53
|
+
|
|
54
|
+
const asString = { connectionId: v.string() };
|
|
55
|
+
|
|
56
|
+
type WithConnection = { connectionId: unknown; userId: unknown };
|
|
57
|
+
|
|
58
|
+
function stripConnection<T extends WithConnection>(
|
|
59
|
+
validator: T,
|
|
60
|
+
): Omit<T, "connectionId" | "userId"> {
|
|
61
|
+
const { connectionId, userId, ...rest } = validator;
|
|
62
|
+
return rest as Omit<T, "connectionId" | "userId">;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ─── Full validators (connectionId as v.string() + userId) ───────────────────
|
|
66
|
+
|
|
67
|
+
export const connectionValidator = _connectionValidator;
|
|
68
|
+
export const athleteValidator = { ..._athleteValidator, ...asString };
|
|
69
|
+
export const activityValidator = { ..._activityValidator, ...asString };
|
|
70
|
+
export const bodyValidator = { ..._bodyValidator, ...asString };
|
|
71
|
+
export const dailyValidator = { ..._dailyValidator, ...asString };
|
|
72
|
+
export const sleepValidator = { ..._sleepValidator, ...asString };
|
|
73
|
+
export const menstruationValidator = { ..._menstruationValidator, ...asString };
|
|
74
|
+
export const nutritionValidator = { ..._nutritionValidator, ...asString };
|
|
75
|
+
export const plannedWorkoutValidator = {
|
|
76
|
+
..._plannedWorkoutValidator,
|
|
77
|
+
...asString,
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// ─── Data-only validators (no connectionId / userId) ─────────────────────────
|
|
81
|
+
|
|
82
|
+
export const athleteData = stripConnection(_athleteValidator);
|
|
83
|
+
export const activityData = stripConnection(_activityValidator);
|
|
84
|
+
export const bodyData = stripConnection(_bodyValidator);
|
|
85
|
+
export const dailyData = stripConnection(_dailyValidator);
|
|
86
|
+
export const sleepData = stripConnection(_sleepValidator);
|
|
87
|
+
export const menstruationData = stripConnection(_menstruationValidator);
|
|
88
|
+
export const nutritionData = stripConnection(_nutritionValidator);
|
|
89
|
+
export const plannedWorkoutData = stripConnection(_plannedWorkoutValidator);
|