@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.
Files changed (60) hide show
  1. package/dist/client/garmin.d.ts +291 -0
  2. package/dist/client/garmin.d.ts.map +1 -0
  3. package/dist/client/garmin.js +493 -0
  4. package/dist/client/garmin.js.map +1 -0
  5. package/dist/client/index.d.ts +29 -394
  6. package/dist/client/index.d.ts.map +1 -1
  7. package/dist/client/index.js +30 -520
  8. package/dist/client/index.js.map +1 -1
  9. package/dist/client/strava.d.ts +97 -0
  10. package/dist/client/strava.d.ts.map +1 -0
  11. package/dist/client/strava.js +160 -0
  12. package/dist/client/strava.js.map +1 -0
  13. package/dist/client/types.d.ts +238 -0
  14. package/dist/client/types.d.ts.map +1 -1
  15. package/dist/component/_generated/component.d.ts +24 -12
  16. package/dist/component/_generated/component.d.ts.map +1 -1
  17. package/dist/component/garmin/private.d.ts +53 -68
  18. package/dist/component/garmin/private.d.ts.map +1 -1
  19. package/dist/component/garmin/private.js +87 -85
  20. package/dist/component/garmin/private.js.map +1 -1
  21. package/dist/component/garmin/public.d.ts +97 -53
  22. package/dist/component/garmin/public.d.ts.map +1 -1
  23. package/dist/component/garmin/public.js +75 -148
  24. package/dist/component/garmin/public.js.map +1 -1
  25. package/dist/component/garmin/webhooks.d.ts +22 -20
  26. package/dist/component/garmin/webhooks.d.ts.map +1 -1
  27. package/dist/component/garmin/webhooks.js +115 -76
  28. package/dist/component/garmin/webhooks.js.map +1 -1
  29. package/dist/component/public.d.ts +15 -15
  30. package/dist/component/schema.d.ts +25 -25
  31. package/dist/component/strava/public.d.ts +12 -8
  32. package/dist/component/strava/public.d.ts.map +1 -1
  33. package/dist/component/strava/public.js +7 -7
  34. package/dist/component/strava/public.js.map +1 -1
  35. package/dist/component/validators/activity.d.ts +4 -4
  36. package/dist/component/validators/body.d.ts +4 -4
  37. package/dist/component/validators/daily.d.ts +4 -4
  38. package/dist/component/validators/nutrition.d.ts +3 -3
  39. package/dist/component/validators/samples.d.ts +4 -4
  40. package/dist/component/validators/shared.d.ts +13 -4
  41. package/dist/component/validators/shared.d.ts.map +1 -1
  42. package/dist/component/validators/shared.js +7 -0
  43. package/dist/component/validators/shared.js.map +1 -1
  44. package/dist/component/validators/sleep.d.ts +5 -5
  45. package/dist/validators.d.ts +41 -40
  46. package/dist/validators.d.ts.map +1 -1
  47. package/dist/validators.js +1 -0
  48. package/dist/validators.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/client/garmin.ts +692 -0
  51. package/src/client/index.ts +68 -933
  52. package/src/client/strava.ts +199 -0
  53. package/src/client/types.ts +285 -0
  54. package/src/component/_generated/component.ts +19 -32
  55. package/src/component/garmin/private.ts +1872 -1870
  56. package/src/component/garmin/public.ts +1073 -1184
  57. package/src/component/garmin/webhooks.ts +898 -857
  58. package/src/component/strava/public.ts +393 -393
  59. package/src/component/validators/shared.ts +9 -0
  60. 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
- error: err instanceof Error ? err.message : String(err),
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
- error: err instanceof Error ? err.message : String(err),
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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), error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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), error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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", error: err instanceof Error ? err.message : String(err) });
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
- error: err instanceof Error ? err.message : String(err),
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
- throw new Error(`Garmin API error updating workout: ${JSON.stringify(updateError)}`);
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
- throw new Error(`Garmin API error creating workout: ${createError ? JSON.stringify(createError) : "No data"}`);
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
- throw new Error("Garmin API did not return a workoutId after creation.");
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
- throw new Error(`Garmin API error updating schedule: ${JSON.stringify(updateError)}`);
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
- throw new Error(`Garmin API error creating schedule: ${JSON.stringify(scheduleError)}`);
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
- throw new Error("Garmin API did not return a scheduleId after creation.");
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
- throw new Error(`Garmin API error deleting workout: ${JSON.stringify(deleteError)}`);
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
- throw new Error(`Garmin API error deleting schedule: ${JSON.stringify(deleteError)}`);
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