@nativesquare/soma 0.11.0 → 0.13.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/garmin.d.ts +291 -0
- package/dist/client/garmin.d.ts.map +1 -0
- package/dist/client/garmin.js +493 -0
- package/dist/client/garmin.js.map +1 -0
- package/dist/client/index.d.ts +29 -394
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +30 -520
- package/dist/client/index.js.map +1 -1
- package/dist/client/strava.d.ts +97 -0
- package/dist/client/strava.d.ts.map +1 -0
- package/dist/client/strava.js +160 -0
- package/dist/client/strava.js.map +1 -0
- package/dist/client/types.d.ts +238 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/component/_generated/component.d.ts +24 -12
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/garmin/private.d.ts +53 -68
- package/dist/component/garmin/private.d.ts.map +1 -1
- package/dist/component/garmin/private.js +87 -85
- package/dist/component/garmin/private.js.map +1 -1
- package/dist/component/garmin/public.d.ts +97 -53
- package/dist/component/garmin/public.d.ts.map +1 -1
- package/dist/component/garmin/public.js +75 -148
- package/dist/component/garmin/public.js.map +1 -1
- package/dist/component/garmin/webhooks.d.ts +22 -20
- package/dist/component/garmin/webhooks.d.ts.map +1 -1
- package/dist/component/garmin/webhooks.js +115 -76
- package/dist/component/garmin/webhooks.js.map +1 -1
- package/dist/component/public.d.ts +15 -15
- package/dist/component/schema.d.ts +25 -25
- package/dist/component/strava/public.d.ts +12 -8
- package/dist/component/strava/public.d.ts.map +1 -1
- package/dist/component/strava/public.js +7 -7
- package/dist/component/strava/public.js.map +1 -1
- package/dist/component/validators/activity.d.ts +4 -4
- package/dist/component/validators/body.d.ts +4 -4
- package/dist/component/validators/daily.d.ts +4 -4
- package/dist/component/validators/nutrition.d.ts +3 -3
- package/dist/component/validators/samples.d.ts +4 -4
- package/dist/component/validators/shared.d.ts +13 -4
- package/dist/component/validators/shared.d.ts.map +1 -1
- package/dist/component/validators/shared.js +7 -0
- package/dist/component/validators/shared.js.map +1 -1
- package/dist/component/validators/sleep.d.ts +5 -5
- package/dist/validators.d.ts +41 -40
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +1 -0
- package/dist/validators.js.map +1 -1
- package/package.json +1 -1
- package/src/client/garmin.ts +692 -0
- package/src/client/index.ts +68 -933
- package/src/client/strava.ts +199 -0
- package/src/client/types.ts +285 -0
- package/src/component/_generated/component.ts +19 -32
- package/src/component/garmin/private.ts +1872 -1870
- package/src/component/garmin/public.ts +1073 -1184
- package/src/component/garmin/webhooks.ts +898 -857
- package/src/component/strava/public.ts +393 -393
- package/src/component/validators/shared.ts +9 -0
- package/src/validators.ts +1 -0
|
@@ -179,7 +179,7 @@ export const pullActivities = action({
|
|
|
179
179
|
errors.push({
|
|
180
180
|
type: "activity",
|
|
181
181
|
id: activity.summaryId ?? String(activity.activityId),
|
|
182
|
-
|
|
182
|
+
message: err instanceof Error ? err.message : String(err),
|
|
183
183
|
});
|
|
184
184
|
}
|
|
185
185
|
}
|
|
@@ -188,14 +188,14 @@ export const pullActivities = action({
|
|
|
188
188
|
errors.push({
|
|
189
189
|
type: "activity",
|
|
190
190
|
id: "fetch",
|
|
191
|
-
|
|
191
|
+
message: err instanceof Error ? err.message : String(err),
|
|
192
192
|
});
|
|
193
193
|
}
|
|
194
194
|
await ctx.runMutation(api.public.updateConnection, {
|
|
195
195
|
connectionId,
|
|
196
196
|
lastDataUpdate: new Date().toISOString(),
|
|
197
197
|
});
|
|
198
|
-
return { synced, errors };
|
|
198
|
+
return { data: { synced }, errors };
|
|
199
199
|
},
|
|
200
200
|
});
|
|
201
201
|
export const pullDailies = action({
|
|
@@ -225,15 +225,15 @@ export const pullDailies = action({
|
|
|
225
225
|
synced.dailies++;
|
|
226
226
|
}
|
|
227
227
|
catch (err) {
|
|
228
|
-
errors.push({ type: "daily", id: daily.summaryId ?? daily.calendarDate ?? "unknown",
|
|
228
|
+
errors.push({ type: "daily", id: daily.summaryId ?? daily.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
}
|
|
232
232
|
catch (err) {
|
|
233
|
-
errors.push({ type: "daily", id: "fetch",
|
|
233
|
+
errors.push({ type: "daily", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
234
234
|
}
|
|
235
235
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
236
|
-
return { synced, errors };
|
|
236
|
+
return { data: { synced }, errors };
|
|
237
237
|
},
|
|
238
238
|
});
|
|
239
239
|
export const pullSleep = action({
|
|
@@ -261,15 +261,15 @@ export const pullSleep = action({
|
|
|
261
261
|
synced.sleep++;
|
|
262
262
|
}
|
|
263
263
|
catch (err) {
|
|
264
|
-
errors.push({ type: "sleep", id: sleep.summaryId ?? sleep.calendarDate ?? "unknown",
|
|
264
|
+
errors.push({ type: "sleep", id: sleep.summaryId ?? sleep.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
catch (err) {
|
|
269
|
-
errors.push({ type: "sleep", id: "fetch",
|
|
269
|
+
errors.push({ type: "sleep", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
270
270
|
}
|
|
271
271
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
272
|
-
return { synced, errors };
|
|
272
|
+
return { data: { synced }, errors };
|
|
273
273
|
},
|
|
274
274
|
});
|
|
275
275
|
export const pullBody = action({
|
|
@@ -299,15 +299,15 @@ export const pullBody = action({
|
|
|
299
299
|
synced.body++;
|
|
300
300
|
}
|
|
301
301
|
catch (err) {
|
|
302
|
-
errors.push({ type: "body", id: body.summaryId ?? String(body.measurementTimeInSeconds),
|
|
302
|
+
errors.push({ type: "body", id: body.summaryId ?? String(body.measurementTimeInSeconds), message: err instanceof Error ? err.message : String(err) });
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
}
|
|
306
306
|
catch (err) {
|
|
307
|
-
errors.push({ type: "body", id: "fetch",
|
|
307
|
+
errors.push({ type: "body", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
308
308
|
}
|
|
309
309
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
310
|
-
return { synced, errors };
|
|
310
|
+
return { data: { synced }, errors };
|
|
311
311
|
},
|
|
312
312
|
});
|
|
313
313
|
export const pullMenstruation = action({
|
|
@@ -335,15 +335,15 @@ export const pullMenstruation = action({
|
|
|
335
335
|
synced.menstruation++;
|
|
336
336
|
}
|
|
337
337
|
catch (err) {
|
|
338
|
-
errors.push({ type: "menstruation", id: record.summaryId ?? record.periodStartDate ?? "unknown",
|
|
338
|
+
errors.push({ type: "menstruation", id: record.summaryId ?? record.periodStartDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
342
|
catch (err) {
|
|
343
|
-
errors.push({ type: "menstruation", id: "fetch",
|
|
343
|
+
errors.push({ type: "menstruation", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
344
344
|
}
|
|
345
345
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
346
|
-
return { synced, errors };
|
|
346
|
+
return { data: { synced }, errors };
|
|
347
347
|
},
|
|
348
348
|
});
|
|
349
349
|
export const pullBloodPressures = action({
|
|
@@ -373,15 +373,15 @@ export const pullBloodPressures = action({
|
|
|
373
373
|
synced.bloodPressures++;
|
|
374
374
|
}
|
|
375
375
|
catch (err) {
|
|
376
|
-
errors.push({ type: "bloodPressure", id: bp.summaryId ?? String(bp.measurementTimeInSeconds),
|
|
376
|
+
errors.push({ type: "bloodPressure", id: bp.summaryId ?? String(bp.measurementTimeInSeconds), message: err instanceof Error ? err.message : String(err) });
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
}
|
|
380
380
|
catch (err) {
|
|
381
|
-
errors.push({ type: "bloodPressure", id: "fetch",
|
|
381
|
+
errors.push({ type: "bloodPressure", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
382
382
|
}
|
|
383
383
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
384
|
-
return { synced, errors };
|
|
384
|
+
return { data: { synced }, errors };
|
|
385
385
|
},
|
|
386
386
|
});
|
|
387
387
|
export const pullSkinTemperature = action({
|
|
@@ -411,15 +411,15 @@ export const pullSkinTemperature = action({
|
|
|
411
411
|
synced.skinTemp++;
|
|
412
412
|
}
|
|
413
413
|
catch (err) {
|
|
414
|
-
errors.push({ type: "skinTemp", id: skin.summaryId ?? skin.calendarDate ?? "unknown",
|
|
414
|
+
errors.push({ type: "skinTemp", id: skin.summaryId ?? skin.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
415
415
|
}
|
|
416
416
|
}
|
|
417
417
|
}
|
|
418
418
|
catch (err) {
|
|
419
|
-
errors.push({ type: "skinTemp", id: "fetch",
|
|
419
|
+
errors.push({ type: "skinTemp", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
420
420
|
}
|
|
421
421
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
422
|
-
return { synced, errors };
|
|
422
|
+
return { data: { synced }, errors };
|
|
423
423
|
},
|
|
424
424
|
});
|
|
425
425
|
export const pullUserMetrics = action({
|
|
@@ -449,15 +449,15 @@ export const pullUserMetrics = action({
|
|
|
449
449
|
synced.userMetrics++;
|
|
450
450
|
}
|
|
451
451
|
catch (err) {
|
|
452
|
-
errors.push({ type: "userMetrics", id: metrics.summaryId ?? metrics.calendarDate ?? "unknown",
|
|
452
|
+
errors.push({ type: "userMetrics", id: metrics.summaryId ?? metrics.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
453
453
|
}
|
|
454
454
|
}
|
|
455
455
|
}
|
|
456
456
|
catch (err) {
|
|
457
|
-
errors.push({ type: "userMetrics", id: "fetch",
|
|
457
|
+
errors.push({ type: "userMetrics", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
458
458
|
}
|
|
459
459
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
460
|
-
return { synced, errors };
|
|
460
|
+
return { data: { synced }, errors };
|
|
461
461
|
},
|
|
462
462
|
});
|
|
463
463
|
export const pullHRV = action({
|
|
@@ -487,15 +487,15 @@ export const pullHRV = action({
|
|
|
487
487
|
synced.hrv++;
|
|
488
488
|
}
|
|
489
489
|
catch (err) {
|
|
490
|
-
errors.push({ type: "hrv", id: hrv.summaryId ?? hrv.calendarDate ?? "unknown",
|
|
490
|
+
errors.push({ type: "hrv", id: hrv.summaryId ?? hrv.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
491
491
|
}
|
|
492
492
|
}
|
|
493
493
|
}
|
|
494
494
|
catch (err) {
|
|
495
|
-
errors.push({ type: "hrv", id: "fetch",
|
|
495
|
+
errors.push({ type: "hrv", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
496
496
|
}
|
|
497
497
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
498
|
-
return { synced, errors };
|
|
498
|
+
return { data: { synced }, errors };
|
|
499
499
|
},
|
|
500
500
|
});
|
|
501
501
|
export const pullStressDetails = action({
|
|
@@ -525,15 +525,15 @@ export const pullStressDetails = action({
|
|
|
525
525
|
synced.stressDetails++;
|
|
526
526
|
}
|
|
527
527
|
catch (err) {
|
|
528
|
-
errors.push({ type: "stressDetails", id: stress.summaryId ?? stress.calendarDate ?? "unknown",
|
|
528
|
+
errors.push({ type: "stressDetails", id: stress.summaryId ?? stress.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
529
529
|
}
|
|
530
530
|
}
|
|
531
531
|
}
|
|
532
532
|
catch (err) {
|
|
533
|
-
errors.push({ type: "stressDetails", id: "fetch",
|
|
533
|
+
errors.push({ type: "stressDetails", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
534
534
|
}
|
|
535
535
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
536
|
-
return { synced, errors };
|
|
536
|
+
return { data: { synced }, errors };
|
|
537
537
|
},
|
|
538
538
|
});
|
|
539
539
|
export const pullPulseOx = action({
|
|
@@ -563,15 +563,15 @@ export const pullPulseOx = action({
|
|
|
563
563
|
synced.pulseOx++;
|
|
564
564
|
}
|
|
565
565
|
catch (err) {
|
|
566
|
-
errors.push({ type: "pulseOx", id: po.summaryId ?? po.calendarDate ?? "unknown",
|
|
566
|
+
errors.push({ type: "pulseOx", id: po.summaryId ?? po.calendarDate ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
567
567
|
}
|
|
568
568
|
}
|
|
569
569
|
}
|
|
570
570
|
catch (err) {
|
|
571
|
-
errors.push({ type: "pulseOx", id: "fetch",
|
|
571
|
+
errors.push({ type: "pulseOx", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
572
572
|
}
|
|
573
573
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
574
|
-
return { synced, errors };
|
|
574
|
+
return { data: { synced }, errors };
|
|
575
575
|
},
|
|
576
576
|
});
|
|
577
577
|
export const pullRespiration = action({
|
|
@@ -601,15 +601,15 @@ export const pullRespiration = action({
|
|
|
601
601
|
synced.respiration++;
|
|
602
602
|
}
|
|
603
603
|
catch (err) {
|
|
604
|
-
errors.push({ type: "respiration", id: resp.summaryId ?? "unknown",
|
|
604
|
+
errors.push({ type: "respiration", id: resp.summaryId ?? "unknown", message: err instanceof Error ? err.message : String(err) });
|
|
605
605
|
}
|
|
606
606
|
}
|
|
607
607
|
}
|
|
608
608
|
catch (err) {
|
|
609
|
-
errors.push({ type: "respiration", id: "fetch",
|
|
609
|
+
errors.push({ type: "respiration", id: "fetch", message: err instanceof Error ? err.message : String(err) });
|
|
610
610
|
}
|
|
611
611
|
await ctx.runMutation(api.public.updateConnection, { connectionId, lastDataUpdate: new Date().toISOString() });
|
|
612
|
-
return { synced, errors };
|
|
612
|
+
return { data: { synced }, errors };
|
|
613
613
|
},
|
|
614
614
|
});
|
|
615
615
|
export const pullAll = action({
|
|
@@ -647,118 +647,21 @@ export const pullAll = action({
|
|
|
647
647
|
for (const { ref, name } of pullFns) {
|
|
648
648
|
try {
|
|
649
649
|
const result = await ctx.runAction(ref, sharedArgs);
|
|
650
|
-
Object.assign(synced, result.synced);
|
|
650
|
+
Object.assign(synced, result.data.synced);
|
|
651
651
|
errors.push(...result.errors);
|
|
652
652
|
}
|
|
653
653
|
catch (err) {
|
|
654
654
|
errors.push({
|
|
655
655
|
type: name,
|
|
656
656
|
id: "pull",
|
|
657
|
-
|
|
657
|
+
message: err instanceof Error ? err.message : String(err),
|
|
658
658
|
});
|
|
659
659
|
}
|
|
660
660
|
}
|
|
661
|
-
return { synced, errors };
|
|
661
|
+
return { data: { synced }, errors };
|
|
662
662
|
},
|
|
663
663
|
});
|
|
664
664
|
// ─── Push ───────────────────────────────────────────────────────────────────
|
|
665
|
-
export const pushPlannedWorkout = action({
|
|
666
|
-
args: {
|
|
667
|
-
userId: v.string(),
|
|
668
|
-
clientId: v.string(),
|
|
669
|
-
clientSecret: v.string(),
|
|
670
|
-
plannedWorkoutId: v.string(),
|
|
671
|
-
workoutProvider: v.optional(v.string()),
|
|
672
|
-
},
|
|
673
|
-
handler: async (ctx, args) => {
|
|
674
|
-
const connection = await ctx.runQuery(internal.private.getConnectionByProvider, { userId: args.userId, provider: "GARMIN" });
|
|
675
|
-
if (!connection) {
|
|
676
|
-
throw new Error(`No Garmin connection found for user "${args.userId}". ` +
|
|
677
|
-
"Connect to Garmin first via getGarminAuthUrl.");
|
|
678
|
-
}
|
|
679
|
-
if (!connection.active) {
|
|
680
|
-
throw new Error(`Garmin connection for user "${args.userId}" is inactive. Reconnect first.`);
|
|
681
|
-
}
|
|
682
|
-
const connectionId = connection._id;
|
|
683
|
-
const tokenDoc = await ctx.runQuery(internal.garmin.private.getTokens, {
|
|
684
|
-
connectionId,
|
|
685
|
-
});
|
|
686
|
-
if (!tokenDoc) {
|
|
687
|
-
throw new Error("No Garmin tokens found for this connection. " +
|
|
688
|
-
"The connection may have been created before token storage was available.");
|
|
689
|
-
}
|
|
690
|
-
// Always force-refresh the token for Training API calls to rule out
|
|
691
|
-
// stale tokens (the initial sync swallows 401 errors silently).
|
|
692
|
-
let accessToken = tokenDoc.accessToken;
|
|
693
|
-
if (tokenDoc.refreshToken) {
|
|
694
|
-
try {
|
|
695
|
-
const refreshed = await refreshToken({
|
|
696
|
-
clientId: args.clientId,
|
|
697
|
-
clientSecret: args.clientSecret,
|
|
698
|
-
refreshToken: tokenDoc.refreshToken,
|
|
699
|
-
});
|
|
700
|
-
accessToken = refreshed.access_token;
|
|
701
|
-
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
702
|
-
const newExpiresAt = nowSeconds + refreshed.expires_in;
|
|
703
|
-
const _refreshed = await ctx.runMutation(internal.garmin.private.storeTokens, {
|
|
704
|
-
connectionId,
|
|
705
|
-
accessToken: refreshed.access_token,
|
|
706
|
-
refreshToken: refreshed.refresh_token,
|
|
707
|
-
expiresAt: newExpiresAt,
|
|
708
|
-
});
|
|
709
|
-
}
|
|
710
|
-
catch (refreshErr) {
|
|
711
|
-
throw new Error(`Garmin token refresh failed: ${refreshErr instanceof Error ? refreshErr.message : String(refreshErr)}. ` +
|
|
712
|
-
"The user may need to reconnect their Garmin account.");
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
const plannedWorkout = await ctx.runQuery(api.public.getPlannedWorkout, { plannedWorkoutId: args.plannedWorkoutId });
|
|
716
|
-
if (!plannedWorkout) {
|
|
717
|
-
throw new Error(`Planned workout "${args.plannedWorkoutId}" not found.`);
|
|
718
|
-
}
|
|
719
|
-
const providerName = args.workoutProvider ?? "Soma";
|
|
720
|
-
const garminWorkout = transformPlannedWorkoutToGarmin(plannedWorkout, providerName);
|
|
721
|
-
const trainingClient = createTrainingClient(accessToken);
|
|
722
|
-
const { data: created, error: createError } = await sdkCreateWorkoutV2({
|
|
723
|
-
client: trainingClient,
|
|
724
|
-
body: garminWorkout,
|
|
725
|
-
});
|
|
726
|
-
if (createError || !created) {
|
|
727
|
-
throw new Error(`Garmin API error creating workout: ${createError ? JSON.stringify(createError) : "No data"}`);
|
|
728
|
-
}
|
|
729
|
-
if (!created.workoutId) {
|
|
730
|
-
throw new Error("Garmin API did not return a workoutId after creation.");
|
|
731
|
-
}
|
|
732
|
-
let garminScheduleId = null;
|
|
733
|
-
const plannedDate = plannedWorkout.metadata?.planned_date;
|
|
734
|
-
if (plannedDate) {
|
|
735
|
-
const { data: scheduleId, error: scheduleError } = await sdkCreateWorkoutSchedule({
|
|
736
|
-
client: trainingClient,
|
|
737
|
-
body: { workoutId: Number(created.workoutId), date: plannedDate },
|
|
738
|
-
});
|
|
739
|
-
if (scheduleError) {
|
|
740
|
-
throw new Error(`Garmin API error creating schedule: ${JSON.stringify(scheduleError)}`);
|
|
741
|
-
}
|
|
742
|
-
garminScheduleId = scheduleId ?? null;
|
|
743
|
-
}
|
|
744
|
-
// Store the Garmin workout/schedule IDs back on the planned workout
|
|
745
|
-
// so the host app can match completed activities to planned sessions.
|
|
746
|
-
const _ingested = await ctx.runMutation(api.public.ingestPlannedWorkout, {
|
|
747
|
-
...plannedWorkout,
|
|
748
|
-
_id: undefined,
|
|
749
|
-
_creationTime: undefined,
|
|
750
|
-
metadata: {
|
|
751
|
-
...plannedWorkout.metadata,
|
|
752
|
-
provider_workout_id: String(created.workoutId),
|
|
753
|
-
provider_schedule_id: garminScheduleId != null ? String(garminScheduleId) : undefined,
|
|
754
|
-
},
|
|
755
|
-
});
|
|
756
|
-
return {
|
|
757
|
-
garminWorkoutId: created.workoutId,
|
|
758
|
-
garminScheduleId,
|
|
759
|
-
};
|
|
760
|
-
},
|
|
761
|
-
});
|
|
762
665
|
export const pushWorkout = action({
|
|
763
666
|
args: {
|
|
764
667
|
userId: v.string(),
|
|
@@ -788,7 +691,10 @@ export const pushWorkout = action({
|
|
|
788
691
|
path: { workoutId: numericId },
|
|
789
692
|
});
|
|
790
693
|
if (updateError) {
|
|
791
|
-
|
|
694
|
+
return {
|
|
695
|
+
data: null,
|
|
696
|
+
errors: [{ type: "pushWorkout", id: args.plannedWorkoutId, message: `Garmin API error updating workout: ${JSON.stringify(updateError)}` }],
|
|
697
|
+
};
|
|
792
698
|
}
|
|
793
699
|
workoutId = numericId;
|
|
794
700
|
}
|
|
@@ -799,10 +705,16 @@ export const pushWorkout = action({
|
|
|
799
705
|
body: garminWorkout,
|
|
800
706
|
});
|
|
801
707
|
if (createError || !created) {
|
|
802
|
-
|
|
708
|
+
return {
|
|
709
|
+
data: null,
|
|
710
|
+
errors: [{ type: "pushWorkout", id: args.plannedWorkoutId, message: `Garmin API error creating workout: ${createError ? JSON.stringify(createError) : "No data"}` }],
|
|
711
|
+
};
|
|
803
712
|
}
|
|
804
713
|
if (!created.workoutId) {
|
|
805
|
-
|
|
714
|
+
return {
|
|
715
|
+
data: null,
|
|
716
|
+
errors: [{ type: "pushWorkout", id: args.plannedWorkoutId, message: "Garmin API did not return a workoutId after creation." }],
|
|
717
|
+
};
|
|
806
718
|
}
|
|
807
719
|
workoutId = created.workoutId;
|
|
808
720
|
}
|
|
@@ -816,7 +728,7 @@ export const pushWorkout = action({
|
|
|
816
728
|
provider_workout_id: String(workoutId),
|
|
817
729
|
},
|
|
818
730
|
});
|
|
819
|
-
return { garminWorkoutId: workoutId };
|
|
731
|
+
return { data: { garminWorkoutId: workoutId }, errors: [] };
|
|
820
732
|
},
|
|
821
733
|
});
|
|
822
734
|
export const pushSchedule = action({
|
|
@@ -853,7 +765,10 @@ export const pushSchedule = action({
|
|
|
853
765
|
path: { workoutScheduleId: numericScheduleId },
|
|
854
766
|
});
|
|
855
767
|
if (updateError) {
|
|
856
|
-
|
|
768
|
+
return {
|
|
769
|
+
data: null,
|
|
770
|
+
errors: [{ type: "pushSchedule", id: args.plannedWorkoutId, message: `Garmin API error updating schedule: ${JSON.stringify(updateError)}` }],
|
|
771
|
+
};
|
|
857
772
|
}
|
|
858
773
|
scheduleId = numericScheduleId;
|
|
859
774
|
}
|
|
@@ -864,10 +779,16 @@ export const pushSchedule = action({
|
|
|
864
779
|
body: { workoutId: Number(providerWorkoutId), date: scheduleDate },
|
|
865
780
|
});
|
|
866
781
|
if (scheduleError) {
|
|
867
|
-
|
|
782
|
+
return {
|
|
783
|
+
data: null,
|
|
784
|
+
errors: [{ type: "pushSchedule", id: args.plannedWorkoutId, message: `Garmin API error creating schedule: ${JSON.stringify(scheduleError)}` }],
|
|
785
|
+
};
|
|
868
786
|
}
|
|
869
787
|
if (createdScheduleId == null) {
|
|
870
|
-
|
|
788
|
+
return {
|
|
789
|
+
data: null,
|
|
790
|
+
errors: [{ type: "pushSchedule", id: args.plannedWorkoutId, message: "Garmin API did not return a scheduleId after creation." }],
|
|
791
|
+
};
|
|
871
792
|
}
|
|
872
793
|
scheduleId = createdScheduleId;
|
|
873
794
|
}
|
|
@@ -881,7 +802,7 @@ export const pushSchedule = action({
|
|
|
881
802
|
provider_schedule_id: String(scheduleId),
|
|
882
803
|
},
|
|
883
804
|
});
|
|
884
|
-
return { garminScheduleId: scheduleId };
|
|
805
|
+
return { data: { garminScheduleId: scheduleId }, errors: [] };
|
|
885
806
|
},
|
|
886
807
|
});
|
|
887
808
|
// ─── Delete ───────────────────────────────────────────────────────────────────
|
|
@@ -908,7 +829,10 @@ export const deleteWorkout = action({
|
|
|
908
829
|
path: { workoutId: Number(providerWorkoutId) },
|
|
909
830
|
});
|
|
910
831
|
if (deleteError) {
|
|
911
|
-
|
|
832
|
+
return {
|
|
833
|
+
data: null,
|
|
834
|
+
errors: [{ type: "deleteWorkout", id: args.plannedWorkoutId, message: `Garmin API error deleting workout: ${JSON.stringify(deleteError)}` }],
|
|
835
|
+
};
|
|
912
836
|
}
|
|
913
837
|
// Clear both provider IDs — deleting a workout on Garmin cascades to its schedules
|
|
914
838
|
const _ingested = await ctx.runMutation(api.public.ingestPlannedWorkout, {
|
|
@@ -921,7 +845,7 @@ export const deleteWorkout = action({
|
|
|
921
845
|
provider_schedule_id: undefined,
|
|
922
846
|
},
|
|
923
847
|
});
|
|
924
|
-
return null;
|
|
848
|
+
return { data: null, errors: [] };
|
|
925
849
|
},
|
|
926
850
|
});
|
|
927
851
|
export const deleteSchedule = action({
|
|
@@ -947,7 +871,10 @@ export const deleteSchedule = action({
|
|
|
947
871
|
path: { workoutScheduleId: Number(providerScheduleId) },
|
|
948
872
|
});
|
|
949
873
|
if (deleteError) {
|
|
950
|
-
|
|
874
|
+
return {
|
|
875
|
+
data: null,
|
|
876
|
+
errors: [{ type: "deleteSchedule", id: args.plannedWorkoutId, message: `Garmin API error deleting schedule: ${JSON.stringify(deleteError)}` }],
|
|
877
|
+
};
|
|
951
878
|
}
|
|
952
879
|
// Clear only the schedule ID — the workout still exists on Garmin
|
|
953
880
|
const _ingested = await ctx.runMutation(api.public.ingestPlannedWorkout, {
|
|
@@ -959,7 +886,7 @@ export const deleteSchedule = action({
|
|
|
959
886
|
provider_schedule_id: undefined,
|
|
960
887
|
},
|
|
961
888
|
});
|
|
962
|
-
return null;
|
|
889
|
+
return { data: null, errors: [] };
|
|
963
890
|
},
|
|
964
891
|
});
|
|
965
892
|
//# sourceMappingURL=public.js.map
|