@nativesquare/soma 0.13.1 → 0.14.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 +2 -2
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/strava.d.ts +45 -33
- package/dist/client/strava.d.ts.map +1 -1
- package/dist/client/strava.js +138 -22
- package/dist/client/strava.js.map +1 -1
- package/dist/client/types.d.ts +108 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -2
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +19 -17
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/garmin/auth.d.ts +2 -1
- package/dist/component/garmin/auth.d.ts.map +1 -1
- package/dist/component/garmin/auth.js +6 -1
- package/dist/component/garmin/auth.js.map +1 -1
- package/dist/component/garmin/private.d.ts +17 -75
- package/dist/component/garmin/private.d.ts.map +1 -1
- package/dist/component/garmin/private.js +4 -167
- package/dist/component/garmin/private.js.map +1 -1
- package/dist/component/garmin/public.d.ts +18 -33
- package/dist/component/garmin/public.d.ts.map +1 -1
- package/dist/component/garmin/public.js +23 -22
- package/dist/component/garmin/public.js.map +1 -1
- package/dist/component/garmin/webhooks.d.ts +3 -6
- package/dist/component/garmin/webhooks.d.ts.map +1 -1
- package/dist/component/garmin/webhooks.js +17 -28
- package/dist/component/garmin/webhooks.js.map +1 -1
- package/dist/component/private.d.ts +59 -0
- package/dist/component/private.d.ts.map +1 -1
- package/dist/component/private.js +182 -1
- package/dist/component/private.js.map +1 -1
- package/dist/component/strava/auth.d.ts +2 -1
- package/dist/component/strava/auth.d.ts.map +1 -1
- package/dist/component/strava/auth.js +6 -1
- package/dist/component/strava/auth.js.map +1 -1
- package/dist/component/strava/public.d.ts +26 -50
- package/dist/component/strava/public.d.ts.map +1 -1
- package/dist/component/strava/public.js +88 -132
- package/dist/component/strava/public.js.map +1 -1
- package/dist/component/strava/webhooks.d.ts +17 -0
- package/dist/component/strava/webhooks.d.ts.map +1 -0
- package/dist/component/strava/webhooks.js +231 -0
- package/dist/component/strava/webhooks.js.map +1 -0
- package/dist/component/utils.d.ts +10 -0
- package/dist/component/utils.d.ts.map +1 -1
- package/dist/component/utils.js.map +1 -1
- package/dist/component/validators/shared.d.ts +3 -0
- package/dist/component/validators/shared.d.ts.map +1 -1
- package/dist/component/validators/shared.js +1 -1
- package/dist/component/validators/shared.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +8 -1
- package/src/client/strava.ts +190 -26
- package/src/client/types.ts +125 -0
- package/src/component/_generated/api.ts +2 -2
- package/src/component/_generated/component.ts +25 -6
- package/src/component/garmin/auth.ts +9 -2
- package/src/component/garmin/private.ts +22 -243
- package/src/component/garmin/public.ts +56 -54
- package/src/component/garmin/webhooks.ts +38 -55
- package/src/component/private.ts +245 -1
- package/src/component/strava/auth.ts +9 -2
- package/src/component/strava/public.ts +105 -171
- package/src/component/strava/webhooks.ts +312 -0
- package/src/component/utils.ts +11 -0
- package/src/component/validators/shared.ts +5 -2
- package/dist/component/strava/private.d.ts +0 -49
- package/dist/component/strava/private.d.ts.map +0 -1
- package/dist/component/strava/private.js +0 -121
- package/dist/component/strava/private.js.map +0 -1
- package/src/component/strava/private.ts +0 -147
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
// Pure helper functions for the Garmin OAuth 2.0 PKCE flow.
|
|
3
3
|
// Uses the Web Crypto API for SHA-256 challenge generation and global `fetch`.
|
|
4
4
|
|
|
5
|
+
import type { OAuthRefreshResult } from "../utils.js";
|
|
6
|
+
|
|
5
7
|
export interface GarminOAuth2TokenResponse {
|
|
6
8
|
access_token: string;
|
|
7
9
|
refresh_token: string;
|
|
@@ -158,7 +160,7 @@ export interface RefreshTokenOptions {
|
|
|
158
160
|
*/
|
|
159
161
|
export async function refreshToken(
|
|
160
162
|
opts: RefreshTokenOptions,
|
|
161
|
-
): Promise<
|
|
163
|
+
): Promise<OAuthRefreshResult> {
|
|
162
164
|
const body = new URLSearchParams({
|
|
163
165
|
grant_type: "refresh_token",
|
|
164
166
|
client_id: opts.clientId,
|
|
@@ -179,5 +181,10 @@ export async function refreshToken(
|
|
|
179
181
|
);
|
|
180
182
|
}
|
|
181
183
|
|
|
182
|
-
|
|
184
|
+
const raw = (await response.json()) as GarminOAuth2TokenResponse;
|
|
185
|
+
return {
|
|
186
|
+
access_token: raw.access_token,
|
|
187
|
+
refresh_token: raw.refresh_token,
|
|
188
|
+
expiresAt: Math.floor(Date.now() / 1000) + raw.expires_in,
|
|
189
|
+
};
|
|
183
190
|
}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
// ─── Garmin Internal
|
|
2
|
-
//
|
|
3
|
-
//
|
|
1
|
+
// ─── Garmin Internal Functions ───────────────────────────────────────────────
|
|
2
|
+
// Garmin-specific internal actions (token refresh, webhook payload processing).
|
|
3
|
+
// Shared CRUD (tokens, pending OAuth) lives in the root private.ts.
|
|
4
4
|
|
|
5
5
|
import { v } from "convex/values";
|
|
6
|
-
import {
|
|
7
|
-
internalAction,
|
|
8
|
-
internalMutation,
|
|
9
|
-
internalQuery,
|
|
10
|
-
} from "../_generated/server";
|
|
6
|
+
import { internalAction } from "../_generated/server";
|
|
11
7
|
import { internal } from "../_generated/api";
|
|
8
|
+
import type { SomaError } from "../validators/shared.js";
|
|
12
9
|
import {
|
|
13
10
|
garminActivityPingPayloadSchema,
|
|
14
11
|
garminActivityPushPayloadSchema,
|
|
@@ -94,224 +91,6 @@ import {
|
|
|
94
91
|
garminMenstrualCycleTrackingPushPayloadSchema,
|
|
95
92
|
} from "./schemas/menstrualCycleTracking.js";
|
|
96
93
|
import { transformMenstrualCycleTracking } from "./transform/menstrualCycleTracking.js";
|
|
97
|
-
import { refreshToken } from "./auth";
|
|
98
|
-
import type { Doc, Id } from "../_generated/dataModel";
|
|
99
|
-
|
|
100
|
-
const REFRESH_BUFFER_SECONDS = 600;
|
|
101
|
-
// ─── Internal Pending OAuth CRUD ─────────────────────────────────────────────
|
|
102
|
-
// Temporary storage for in-progress Garmin OAuth 2.0 PKCE flows.
|
|
103
|
-
// Bridges getGarminAuthUrl and completeGarminOAuth.
|
|
104
|
-
|
|
105
|
-
export const storePendingOAuth = internalMutation({
|
|
106
|
-
args: {
|
|
107
|
-
provider: v.string(),
|
|
108
|
-
state: v.string(),
|
|
109
|
-
codeVerifier: v.string(),
|
|
110
|
-
userId: v.string(),
|
|
111
|
-
},
|
|
112
|
-
returns: v.null(),
|
|
113
|
-
handler: async (ctx, args) => {
|
|
114
|
-
await ctx.db.insert("pendingOAuth", {
|
|
115
|
-
...args,
|
|
116
|
-
createdAt: Date.now(),
|
|
117
|
-
});
|
|
118
|
-
return null;
|
|
119
|
-
},
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
export const getPendingOAuth = internalQuery({
|
|
123
|
-
args: { state: v.string() },
|
|
124
|
-
handler: async (ctx, args) => {
|
|
125
|
-
return await ctx.db
|
|
126
|
-
.query("pendingOAuth")
|
|
127
|
-
.withIndex("by_state", (q) => q.eq("state", args.state))
|
|
128
|
-
.first();
|
|
129
|
-
},
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
export const deletePendingOAuth = internalMutation({
|
|
133
|
-
args: { state: v.string() },
|
|
134
|
-
returns: v.null(),
|
|
135
|
-
handler: async (ctx, args) => {
|
|
136
|
-
const pending = await ctx.db
|
|
137
|
-
.query("pendingOAuth")
|
|
138
|
-
.withIndex("by_state", (q) => q.eq("state", args.state))
|
|
139
|
-
.first();
|
|
140
|
-
if (pending) {
|
|
141
|
-
await ctx.db.delete(pending._id);
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
},
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
export const resolveConnectionAndAccessToken = internalAction({
|
|
148
|
-
args: {
|
|
149
|
-
userId: v.string(),
|
|
150
|
-
clientId: v.string(),
|
|
151
|
-
clientSecret: v.string(),
|
|
152
|
-
},
|
|
153
|
-
handler: async (ctx, args): Promise<{
|
|
154
|
-
connectionId: Id<"connections">;
|
|
155
|
-
accessToken: string;
|
|
156
|
-
}> => {
|
|
157
|
-
const connection: Doc<"connections"> | null = await ctx.runQuery(
|
|
158
|
-
internal.private.getConnectionByProvider,
|
|
159
|
-
{ userId: args.userId, provider: "GARMIN" },
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
if (!connection) {
|
|
163
|
-
throw new Error(
|
|
164
|
-
`No Garmin connection found for user "${args.userId}". ` +
|
|
165
|
-
"Connect to Garmin first via getGarminAuthUrl.",
|
|
166
|
-
);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (!connection.active) {
|
|
170
|
-
throw new Error(
|
|
171
|
-
`Garmin connection for user "${args.userId}" is inactive. Reconnect first.`,
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const connectionId = connection._id;
|
|
176
|
-
|
|
177
|
-
const tokenDoc: Doc<"providerTokens"> | null = await ctx.runQuery(
|
|
178
|
-
internal.garmin.private.getTokens,
|
|
179
|
-
{ connectionId },
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
if (!tokenDoc) {
|
|
183
|
-
throw new Error(
|
|
184
|
-
"No Garmin tokens found for this connection. " +
|
|
185
|
-
"The connection may have been created before token storage was available.",
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
let accessToken = tokenDoc.accessToken;
|
|
190
|
-
|
|
191
|
-
// Refresh the token if it's expired or about to expire
|
|
192
|
-
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
193
|
-
if (
|
|
194
|
-
tokenDoc.expiresAt &&
|
|
195
|
-
tokenDoc.refreshToken &&
|
|
196
|
-
nowSeconds >= tokenDoc.expiresAt - REFRESH_BUFFER_SECONDS
|
|
197
|
-
) {
|
|
198
|
-
const refreshed = await refreshToken({
|
|
199
|
-
clientId: args.clientId,
|
|
200
|
-
clientSecret: args.clientSecret,
|
|
201
|
-
refreshToken: tokenDoc.refreshToken,
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
accessToken = refreshed.access_token;
|
|
205
|
-
const newExpiresAt = nowSeconds + refreshed.expires_in;
|
|
206
|
-
|
|
207
|
-
const _refreshed: null = await ctx.runMutation(
|
|
208
|
-
internal.garmin.private.storeTokens,
|
|
209
|
-
{
|
|
210
|
-
connectionId,
|
|
211
|
-
accessToken: refreshed.access_token,
|
|
212
|
-
refreshToken: refreshed.refresh_token,
|
|
213
|
-
expiresAt: newExpiresAt,
|
|
214
|
-
},
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
connectionId,
|
|
220
|
-
accessToken,
|
|
221
|
-
};
|
|
222
|
-
},
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// ─── Internal Token CRUD ─────────────────────────────────────────────────────
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Store OAuth 2.0 tokens for a Garmin connection.
|
|
229
|
-
* Upserts by connectionId — one token record per connection.
|
|
230
|
-
*/
|
|
231
|
-
export const storeTokens = internalMutation({
|
|
232
|
-
args: {
|
|
233
|
-
connectionId: v.id("connections"),
|
|
234
|
-
accessToken: v.string(),
|
|
235
|
-
refreshToken: v.string(),
|
|
236
|
-
expiresAt: v.number(),
|
|
237
|
-
},
|
|
238
|
-
returns: v.null(),
|
|
239
|
-
handler: async (ctx, args) => {
|
|
240
|
-
const existing = await ctx.db
|
|
241
|
-
.query("providerTokens")
|
|
242
|
-
.withIndex("by_connectionId", (q) =>
|
|
243
|
-
q.eq("connectionId", args.connectionId),
|
|
244
|
-
)
|
|
245
|
-
.first();
|
|
246
|
-
|
|
247
|
-
if (existing) {
|
|
248
|
-
await ctx.db.patch(existing._id, {
|
|
249
|
-
accessToken: args.accessToken,
|
|
250
|
-
refreshToken: args.refreshToken,
|
|
251
|
-
expiresAt: args.expiresAt,
|
|
252
|
-
});
|
|
253
|
-
return null;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
await ctx.db.insert("providerTokens", {
|
|
257
|
-
connectionId: args.connectionId,
|
|
258
|
-
accessToken: args.accessToken,
|
|
259
|
-
refreshToken: args.refreshToken,
|
|
260
|
-
expiresAt: args.expiresAt,
|
|
261
|
-
});
|
|
262
|
-
return null;
|
|
263
|
-
},
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Get stored tokens for a connection.
|
|
268
|
-
*/
|
|
269
|
-
export const getTokens = internalQuery({
|
|
270
|
-
args: { connectionId: v.id("connections") },
|
|
271
|
-
returns: v.union(
|
|
272
|
-
v.object({
|
|
273
|
-
_id: v.id("providerTokens"),
|
|
274
|
-
_creationTime: v.number(),
|
|
275
|
-
connectionId: v.id("connections"),
|
|
276
|
-
accessToken: v.string(),
|
|
277
|
-
refreshToken: v.optional(v.string()),
|
|
278
|
-
expiresAt: v.optional(v.number()),
|
|
279
|
-
}),
|
|
280
|
-
v.null(),
|
|
281
|
-
),
|
|
282
|
-
handler: async (ctx, args) => {
|
|
283
|
-
return await ctx.db
|
|
284
|
-
.query("providerTokens")
|
|
285
|
-
.withIndex("by_connectionId", (q) =>
|
|
286
|
-
q.eq("connectionId", args.connectionId),
|
|
287
|
-
)
|
|
288
|
-
.first();
|
|
289
|
-
},
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* Delete stored tokens for a connection.
|
|
294
|
-
*/
|
|
295
|
-
export const deleteTokens = internalMutation({
|
|
296
|
-
args: { connectionId: v.id("connections") },
|
|
297
|
-
returns: v.null(),
|
|
298
|
-
handler: async (ctx, args) => {
|
|
299
|
-
const existing = await ctx.db
|
|
300
|
-
.query("providerTokens")
|
|
301
|
-
.withIndex("by_connectionId", (q) =>
|
|
302
|
-
q.eq("connectionId", args.connectionId),
|
|
303
|
-
)
|
|
304
|
-
.first();
|
|
305
|
-
|
|
306
|
-
if (existing) {
|
|
307
|
-
await ctx.db.delete(existing._id);
|
|
308
|
-
}
|
|
309
|
-
return null;
|
|
310
|
-
},
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
94
|
// ─── Activity Push Processing ───────────────────────────────────────────────
|
|
316
95
|
|
|
317
96
|
/**
|
|
@@ -325,7 +104,7 @@ export const processActivityPushPayload = internalAction({
|
|
|
325
104
|
const { activities } = garminActivityPushPayloadSchema.parse(args.payload);
|
|
326
105
|
|
|
327
106
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
328
|
-
const errors:
|
|
107
|
+
const errors: SomaError[] = [];
|
|
329
108
|
|
|
330
109
|
// Group items by Garmin userId
|
|
331
110
|
const byUser = new Map<string, typeof activities>();
|
|
@@ -416,7 +195,7 @@ export const processActivityDetailsPushPayload = internalAction({
|
|
|
416
195
|
garminActivityDetailsPushPayloadSchema.parse(args.payload);
|
|
417
196
|
|
|
418
197
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
419
|
-
const errors:
|
|
198
|
+
const errors: SomaError[] = [];
|
|
420
199
|
|
|
421
200
|
// Group items by Garmin userId
|
|
422
201
|
const byUser = new Map<string, typeof activityDetails>();
|
|
@@ -507,7 +286,7 @@ export const processManuallyUpdatedActivitiesPushPayload = internalAction({
|
|
|
507
286
|
garminManuallyUpdatedActivitiesPushPayloadSchema.parse(args.payload);
|
|
508
287
|
|
|
509
288
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
510
|
-
const errors:
|
|
289
|
+
const errors: SomaError[] = [];
|
|
511
290
|
|
|
512
291
|
// Group items by Garmin userId
|
|
513
292
|
const byUser = new Map<string, typeof manuallyUpdatedActivities>();
|
|
@@ -600,7 +379,7 @@ export const processMoveIQPushPayload = internalAction({
|
|
|
600
379
|
);
|
|
601
380
|
|
|
602
381
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
603
|
-
const errors:
|
|
382
|
+
const errors: SomaError[] = [];
|
|
604
383
|
|
|
605
384
|
// Group items by Garmin userId
|
|
606
385
|
const byUser = new Map<string, typeof moveIQActivities>();
|
|
@@ -692,7 +471,7 @@ export const processBloodPressurePushPayload = internalAction({
|
|
|
692
471
|
garminBloodPressurePushPayloadSchema.parse(args.payload);
|
|
693
472
|
|
|
694
473
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
695
|
-
const errors:
|
|
474
|
+
const errors: SomaError[] = [];
|
|
696
475
|
|
|
697
476
|
// Group items by Garmin userId
|
|
698
477
|
const byUser = new Map<string, typeof bloodPressures>();
|
|
@@ -784,7 +563,7 @@ export const processBodyCompositionsPushPayload = internalAction({
|
|
|
784
563
|
garminBodyCompositionsPushPayloadSchema.parse(args.payload);
|
|
785
564
|
|
|
786
565
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
787
|
-
const errors:
|
|
566
|
+
const errors: SomaError[] = [];
|
|
788
567
|
|
|
789
568
|
// Group items by Garmin userId
|
|
790
569
|
const byUser = new Map<string, typeof bodyComps>();
|
|
@@ -876,7 +655,7 @@ export const processDailiesPushPayload = internalAction({
|
|
|
876
655
|
garminDailiesPushPayloadSchema.parse(args.payload);
|
|
877
656
|
|
|
878
657
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
879
|
-
const errors:
|
|
658
|
+
const errors: SomaError[] = [];
|
|
880
659
|
|
|
881
660
|
// Group items by Garmin userId
|
|
882
661
|
const byUser = new Map<string, typeof dailies>();
|
|
@@ -968,7 +747,7 @@ export const processHealthSnapshotPushPayload = internalAction({
|
|
|
968
747
|
garminHealthSnapshotPushPayloadSchema.parse(args.payload);
|
|
969
748
|
|
|
970
749
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
971
|
-
const errors:
|
|
750
|
+
const errors: SomaError[] = [];
|
|
972
751
|
|
|
973
752
|
// Group items by Garmin userId
|
|
974
753
|
const byUser = new Map<string, typeof healthSnapshot>();
|
|
@@ -1060,7 +839,7 @@ export const processHRVSummaryPushPayload = internalAction({
|
|
|
1060
839
|
garminHRVSummaryPushPayloadSchema.parse(args.payload);
|
|
1061
840
|
|
|
1062
841
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1063
|
-
const errors:
|
|
842
|
+
const errors: SomaError[] = [];
|
|
1064
843
|
|
|
1065
844
|
// Group items by Garmin userId
|
|
1066
845
|
const byUser = new Map<string, typeof hrv>();
|
|
@@ -1152,7 +931,7 @@ export const processEpochPushPayload = internalAction({
|
|
|
1152
931
|
garminEpochPushPayloadSchema.parse(args.payload);
|
|
1153
932
|
|
|
1154
933
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1155
|
-
const errors:
|
|
934
|
+
const errors: SomaError[] = [];
|
|
1156
935
|
|
|
1157
936
|
// Group items by Garmin userId
|
|
1158
937
|
const byUser = new Map<string, typeof epochs>();
|
|
@@ -1244,7 +1023,7 @@ export const processPulseOxPushPayload = internalAction({
|
|
|
1244
1023
|
garminPulseOxPushPayloadSchema.parse(args.payload);
|
|
1245
1024
|
|
|
1246
1025
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1247
|
-
const errors:
|
|
1026
|
+
const errors: SomaError[] = [];
|
|
1248
1027
|
|
|
1249
1028
|
// Group items by Garmin userId
|
|
1250
1029
|
const byUser = new Map<string, typeof pulseox>();
|
|
@@ -1336,7 +1115,7 @@ export const processRespirationPushPayload = internalAction({
|
|
|
1336
1115
|
garminRespirationPushPayloadSchema.parse(args.payload);
|
|
1337
1116
|
|
|
1338
1117
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1339
|
-
const errors:
|
|
1118
|
+
const errors: SomaError[] = [];
|
|
1340
1119
|
|
|
1341
1120
|
// Group items by Garmin userId
|
|
1342
1121
|
const byUser = new Map<string, typeof allDayRespiration>();
|
|
@@ -1428,7 +1207,7 @@ export const processStressPushPayload = internalAction({
|
|
|
1428
1207
|
garminStressPushPayloadSchema.parse(args.payload);
|
|
1429
1208
|
|
|
1430
1209
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1431
|
-
const errors:
|
|
1210
|
+
const errors: SomaError[] = [];
|
|
1432
1211
|
|
|
1433
1212
|
// Group items by Garmin userId
|
|
1434
1213
|
const byUser = new Map<string, typeof stressDetails>();
|
|
@@ -1520,7 +1299,7 @@ export const processSkinTemperaturePushPayload = internalAction({
|
|
|
1520
1299
|
garminSkinTemperaturePushPayloadSchema.parse(args.payload);
|
|
1521
1300
|
|
|
1522
1301
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1523
|
-
const errors:
|
|
1302
|
+
const errors: SomaError[] = [];
|
|
1524
1303
|
|
|
1525
1304
|
// Group items by Garmin userId
|
|
1526
1305
|
const byUser = new Map<string, typeof skinTemp>();
|
|
@@ -1611,7 +1390,7 @@ export const processSleepsPushPayload = internalAction({
|
|
|
1611
1390
|
const { sleeps } = garminSleepsPushPayloadSchema.parse(args.payload);
|
|
1612
1391
|
|
|
1613
1392
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1614
|
-
const errors:
|
|
1393
|
+
const errors: SomaError[] = [];
|
|
1615
1394
|
|
|
1616
1395
|
// Group items by Garmin userId
|
|
1617
1396
|
const byUser = new Map<string, typeof sleeps>();
|
|
@@ -1701,7 +1480,7 @@ export const processUserMetricsPushPayload = internalAction({
|
|
|
1701
1480
|
garminUserMetricsPushPayloadSchema.parse(args.payload);
|
|
1702
1481
|
|
|
1703
1482
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1704
|
-
const errors:
|
|
1483
|
+
const errors: SomaError[] = [];
|
|
1705
1484
|
|
|
1706
1485
|
// Group items by Garmin userId
|
|
1707
1486
|
const byUser = new Map<string, typeof userMetrics>();
|
|
@@ -1793,7 +1572,7 @@ export const processMenstrualCycleTrackingPushPayload = internalAction({
|
|
|
1793
1572
|
garminMenstrualCycleTrackingPushPayloadSchema.parse(args.payload);
|
|
1794
1573
|
|
|
1795
1574
|
const items: Array<{ connectionId: string; userId: string; data: Record<string, unknown> }> = [];
|
|
1796
|
-
const errors:
|
|
1575
|
+
const errors: SomaError[] = [];
|
|
1797
1576
|
|
|
1798
1577
|
// Group items by Garmin userId
|
|
1799
1578
|
const byUser = new Map<string, typeof mct>();
|