@nativesquare/soma 0.8.0 → 0.9.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 (325) hide show
  1. package/dist/client/index.d.ts +7 -128
  2. package/dist/client/index.d.ts.map +1 -1
  3. package/dist/client/index.js +31 -112
  4. package/dist/client/index.js.map +1 -1
  5. package/dist/component/_generated/api.d.ts +80 -4
  6. package/dist/component/_generated/api.d.ts.map +1 -1
  7. package/dist/component/_generated/api.js.map +1 -1
  8. package/dist/component/_generated/component.d.ts +135 -261
  9. package/dist/component/_generated/component.d.ts.map +1 -1
  10. package/dist/component/garmin/private.d.ts +475 -0
  11. package/dist/component/garmin/private.d.ts.map +1 -0
  12. package/dist/component/garmin/private.js +1614 -0
  13. package/dist/component/garmin/private.js.map +1 -0
  14. package/dist/component/garmin/public.d.ts +155 -0
  15. package/dist/component/garmin/public.d.ts.map +1 -0
  16. package/dist/component/garmin/public.js +787 -0
  17. package/dist/component/garmin/public.js.map +1 -0
  18. package/dist/component/garmin/schemas/activity.d.ts +94 -0
  19. package/dist/component/garmin/schemas/activity.d.ts.map +1 -0
  20. package/dist/component/garmin/schemas/activity.js +27 -0
  21. package/dist/component/garmin/schemas/activity.js.map +1 -0
  22. package/dist/component/garmin/schemas/activityDetails.d.ts +146 -0
  23. package/dist/component/garmin/schemas/activityDetails.d.ts.map +1 -0
  24. package/dist/component/garmin/schemas/activityDetails.js +27 -0
  25. package/dist/component/garmin/schemas/activityDetails.js.map +1 -0
  26. package/dist/component/garmin/schemas/bloodPressure.d.ts +38 -0
  27. package/dist/component/garmin/schemas/bloodPressure.d.ts.map +1 -0
  28. package/dist/component/garmin/schemas/bloodPressure.js +27 -0
  29. package/dist/component/garmin/schemas/bloodPressure.js.map +1 -0
  30. package/dist/component/garmin/schemas/bodyCompositions.d.ts +42 -0
  31. package/dist/component/garmin/schemas/bodyCompositions.d.ts.map +1 -0
  32. package/dist/component/garmin/schemas/bodyCompositions.js +27 -0
  33. package/dist/component/garmin/schemas/bodyCompositions.js.map +1 -0
  34. package/dist/component/garmin/schemas/dailies.d.ts +98 -0
  35. package/dist/component/garmin/schemas/dailies.d.ts.map +1 -0
  36. package/dist/component/garmin/schemas/dailies.js +27 -0
  37. package/dist/component/garmin/schemas/dailies.js.map +1 -0
  38. package/dist/component/garmin/schemas/epochs.d.ts +54 -0
  39. package/dist/component/garmin/schemas/epochs.d.ts.map +1 -0
  40. package/dist/component/garmin/schemas/epochs.js +27 -0
  41. package/dist/component/garmin/schemas/epochs.js.map +1 -0
  42. package/dist/component/garmin/schemas/healthSnapshot.d.ts +48 -0
  43. package/dist/component/garmin/schemas/healthSnapshot.d.ts.map +1 -0
  44. package/dist/component/garmin/schemas/healthSnapshot.js +27 -0
  45. package/dist/component/garmin/schemas/healthSnapshot.js.map +1 -0
  46. package/dist/component/garmin/schemas/hrvSummary.d.ts +40 -0
  47. package/dist/component/garmin/schemas/hrvSummary.d.ts.map +1 -0
  48. package/dist/component/garmin/schemas/hrvSummary.js +27 -0
  49. package/dist/component/garmin/schemas/hrvSummary.js.map +1 -0
  50. package/dist/component/garmin/schemas/manuallyUpdatedActivities.d.ts +94 -0
  51. package/dist/component/garmin/schemas/manuallyUpdatedActivities.d.ts.map +1 -0
  52. package/dist/component/garmin/schemas/manuallyUpdatedActivities.js +27 -0
  53. package/dist/component/garmin/schemas/manuallyUpdatedActivities.js.map +1 -0
  54. package/dist/component/garmin/schemas/menstrualCycleTracking.d.ts +100 -0
  55. package/dist/component/garmin/schemas/menstrualCycleTracking.d.ts.map +1 -0
  56. package/dist/component/garmin/schemas/menstrualCycleTracking.js +28 -0
  57. package/dist/component/garmin/schemas/menstrualCycleTracking.js.map +1 -0
  58. package/dist/component/garmin/schemas/moveIQ.d.ts +40 -0
  59. package/dist/component/garmin/schemas/moveIQ.d.ts.map +1 -0
  60. package/dist/component/garmin/schemas/moveIQ.js +27 -0
  61. package/dist/component/garmin/schemas/moveIQ.js.map +1 -0
  62. package/dist/component/garmin/schemas/pulseOx.d.ts +38 -0
  63. package/dist/component/garmin/schemas/pulseOx.d.ts.map +1 -0
  64. package/dist/component/garmin/schemas/pulseOx.js +28 -0
  65. package/dist/component/garmin/schemas/pulseOx.js.map +1 -0
  66. package/dist/component/garmin/schemas/respiration.d.ts +34 -0
  67. package/dist/component/garmin/schemas/respiration.d.ts.map +1 -0
  68. package/dist/component/garmin/schemas/respiration.js +28 -0
  69. package/dist/component/garmin/schemas/respiration.js.map +1 -0
  70. package/dist/component/garmin/schemas/skinTemperature.d.ts +36 -0
  71. package/dist/component/garmin/schemas/skinTemperature.d.ts.map +1 -0
  72. package/dist/component/garmin/schemas/skinTemperature.js +28 -0
  73. package/dist/component/garmin/schemas/skinTemperature.js.map +1 -0
  74. package/dist/component/garmin/schemas/sleeps.d.ts +88 -0
  75. package/dist/component/garmin/schemas/sleeps.d.ts.map +1 -0
  76. package/dist/component/garmin/schemas/sleeps.js +27 -0
  77. package/dist/component/garmin/schemas/sleeps.js.map +1 -0
  78. package/dist/component/garmin/schemas/stress.d.ts +70 -0
  79. package/dist/component/garmin/schemas/stress.d.ts.map +1 -0
  80. package/dist/component/garmin/schemas/stress.js +28 -0
  81. package/dist/component/garmin/schemas/stress.js.map +1 -0
  82. package/dist/component/garmin/schemas/userMetrics.d.ts +36 -0
  83. package/dist/component/garmin/schemas/userMetrics.d.ts.map +1 -0
  84. package/dist/component/garmin/schemas/userMetrics.js +28 -0
  85. package/dist/component/garmin/schemas/userMetrics.js.map +1 -0
  86. package/dist/component/garmin/transform/activity.d.ts +13 -0
  87. package/dist/component/garmin/transform/activity.d.ts.map +1 -0
  88. package/dist/component/garmin/transform/activity.js +111 -0
  89. package/dist/component/garmin/transform/activity.js.map +1 -0
  90. package/dist/component/garmin/transform/activityDetails.d.ts +13 -0
  91. package/dist/component/garmin/transform/activityDetails.d.ts.map +1 -0
  92. package/dist/component/garmin/transform/activityDetails.js +173 -0
  93. package/dist/component/garmin/transform/activityDetails.js.map +1 -0
  94. package/dist/component/garmin/transform/bloodPressure.d.ts +12 -0
  95. package/dist/component/garmin/transform/bloodPressure.d.ts.map +1 -0
  96. package/dist/component/garmin/transform/bloodPressure.js +33 -0
  97. package/dist/component/garmin/transform/bloodPressure.js.map +1 -0
  98. package/dist/component/garmin/transform/bodyCompositions.d.ts +12 -0
  99. package/dist/component/garmin/transform/bodyCompositions.d.ts.map +1 -0
  100. package/dist/component/garmin/transform/bodyCompositions.js +42 -0
  101. package/dist/component/garmin/transform/bodyCompositions.js.map +1 -0
  102. package/dist/component/garmin/transform/dailies.d.ts +12 -0
  103. package/dist/component/garmin/transform/dailies.d.ts.map +1 -0
  104. package/dist/component/garmin/transform/dailies.js +132 -0
  105. package/dist/component/garmin/transform/dailies.js.map +1 -0
  106. package/dist/component/garmin/transform/epochs.d.ts +13 -0
  107. package/dist/component/garmin/transform/epochs.d.ts.map +1 -0
  108. package/dist/component/garmin/transform/epochs.js +76 -0
  109. package/dist/component/garmin/transform/epochs.js.map +1 -0
  110. package/dist/component/garmin/transform/healthSnapshot.d.ts +12 -0
  111. package/dist/component/garmin/transform/healthSnapshot.d.ts.map +1 -0
  112. package/dist/component/garmin/transform/healthSnapshot.js +111 -0
  113. package/dist/component/garmin/transform/healthSnapshot.js.map +1 -0
  114. package/dist/component/garmin/transform/hrvSummary.d.ts +12 -0
  115. package/dist/component/garmin/transform/hrvSummary.d.ts.map +1 -0
  116. package/dist/component/garmin/transform/hrvSummary.js +45 -0
  117. package/dist/component/garmin/transform/hrvSummary.js.map +1 -0
  118. package/dist/component/garmin/transform/manuallyUpdatedActivities.d.ts +11 -0
  119. package/dist/component/garmin/transform/manuallyUpdatedActivities.d.ts.map +1 -0
  120. package/dist/component/garmin/transform/manuallyUpdatedActivities.js +20 -0
  121. package/dist/component/garmin/transform/manuallyUpdatedActivities.js.map +1 -0
  122. package/dist/component/garmin/transform/menstrualCycleTracking.d.ts +10 -0
  123. package/dist/component/garmin/transform/menstrualCycleTracking.d.ts.map +1 -0
  124. package/dist/component/garmin/transform/menstrualCycleTracking.js +43 -0
  125. package/dist/component/garmin/transform/menstrualCycleTracking.js.map +1 -0
  126. package/dist/component/garmin/transform/moveIQ.d.ts +17 -0
  127. package/dist/component/garmin/transform/moveIQ.d.ts.map +1 -0
  128. package/dist/component/garmin/transform/moveIQ.js +41 -0
  129. package/dist/component/garmin/transform/moveIQ.js.map +1 -0
  130. package/dist/component/garmin/transform/pulseOx.d.ts +12 -0
  131. package/dist/component/garmin/transform/pulseOx.d.ts.map +1 -0
  132. package/dist/component/garmin/transform/pulseOx.js +46 -0
  133. package/dist/component/garmin/transform/pulseOx.js.map +1 -0
  134. package/dist/component/garmin/transform/respiration.d.ts +12 -0
  135. package/dist/component/garmin/transform/respiration.d.ts.map +1 -0
  136. package/dist/component/garmin/transform/respiration.js +54 -0
  137. package/dist/component/garmin/transform/respiration.js.map +1 -0
  138. package/dist/component/garmin/transform/skinTemperature.d.ts +12 -0
  139. package/dist/component/garmin/transform/skinTemperature.d.ts.map +1 -0
  140. package/dist/component/garmin/transform/skinTemperature.js +38 -0
  141. package/dist/component/garmin/transform/skinTemperature.js.map +1 -0
  142. package/dist/component/garmin/transform/sleeps.d.ts +55 -0
  143. package/dist/component/garmin/transform/sleeps.d.ts.map +1 -0
  144. package/dist/component/garmin/transform/sleeps.js +120 -0
  145. package/dist/component/garmin/transform/sleeps.js.map +1 -0
  146. package/dist/component/garmin/transform/stress.d.ts +12 -0
  147. package/dist/component/garmin/transform/stress.d.ts.map +1 -0
  148. package/dist/component/garmin/transform/stress.js +56 -0
  149. package/dist/component/garmin/transform/stress.js.map +1 -0
  150. package/dist/component/garmin/transform/userMetrics.d.ts +12 -0
  151. package/dist/component/garmin/transform/userMetrics.d.ts.map +1 -0
  152. package/dist/component/garmin/transform/userMetrics.js +48 -0
  153. package/dist/component/garmin/transform/userMetrics.js.map +1 -0
  154. package/dist/component/garmin/types/garmin.d.ts +21 -0
  155. package/dist/component/garmin/types/garmin.d.ts.map +1 -0
  156. package/dist/component/garmin/types/garmin.js +6 -0
  157. package/dist/component/garmin/types/garmin.js.map +1 -0
  158. package/dist/component/garmin/types/zod/zod.gen.d.ts +1319 -0
  159. package/dist/component/garmin/types/zod/zod.gen.d.ts.map +1 -0
  160. package/dist/component/garmin/types/zod/zod.gen.js +784 -0
  161. package/dist/component/garmin/types/zod/zod.gen.js.map +1 -0
  162. package/dist/component/garmin/webhooks.d.ts +141 -0
  163. package/dist/component/garmin/webhooks.d.ts.map +1 -0
  164. package/dist/component/garmin/webhooks.js +766 -0
  165. package/dist/component/garmin/webhooks.js.map +1 -0
  166. package/dist/component/private.d.ts +4 -4
  167. package/dist/component/public.d.ts +333 -333
  168. package/dist/component/schema.d.ts +133 -133
  169. package/dist/component/strava/private.d.ts +30 -0
  170. package/dist/component/strava/private.d.ts.map +1 -0
  171. package/dist/component/strava/private.js +71 -0
  172. package/dist/component/strava/private.js.map +1 -0
  173. package/dist/component/{strava.d.ts → strava/public.d.ts} +3 -31
  174. package/dist/component/strava/public.d.ts.map +1 -0
  175. package/dist/component/{strava.js → strava/public.js} +22 -101
  176. package/dist/component/strava/public.js.map +1 -0
  177. package/dist/component/validators/activity.d.ts +6 -0
  178. package/dist/component/validators/activity.d.ts.map +1 -1
  179. package/dist/component/validators/activity.js.map +1 -1
  180. package/dist/component/validators/body.d.ts +20 -14
  181. package/dist/component/validators/body.d.ts.map +1 -1
  182. package/dist/component/validators/body.js.map +1 -1
  183. package/dist/component/validators/daily.d.ts +6 -0
  184. package/dist/component/validators/daily.d.ts.map +1 -1
  185. package/dist/component/validators/daily.js.map +1 -1
  186. package/dist/component/validators/enums.d.ts +1 -1
  187. package/dist/component/validators/menstruation.d.ts +5 -0
  188. package/dist/component/validators/menstruation.d.ts.map +1 -1
  189. package/dist/component/validators/menstruation.js.map +1 -1
  190. package/dist/garmin/client.js.map +1 -1
  191. package/dist/garmin/index.d.ts +0 -2
  192. package/dist/garmin/index.d.ts.map +1 -1
  193. package/dist/garmin/index.js +0 -1
  194. package/dist/garmin/index.js.map +1 -1
  195. package/dist/garmin/sync.d.ts.map +1 -1
  196. package/dist/garmin/sync.js +3 -2
  197. package/dist/garmin/sync.js.map +1 -1
  198. package/dist/garmin/types.d.ts +1 -1
  199. package/dist/garmin/types.d.ts.map +1 -1
  200. package/dist/validators.d.ts +31 -28
  201. package/dist/validators.d.ts.map +1 -1
  202. package/dist/validators.js +2 -2
  203. package/dist/validators.js.map +1 -1
  204. package/package.json +4 -7
  205. package/src/client/index.ts +41 -172
  206. package/src/component/_generated/api.ts +96 -4
  207. package/src/component/_generated/component.ts +252 -284
  208. package/src/{garmin → component/garmin}/auth.ts +8 -1
  209. package/src/component/garmin/client.ts +39 -0
  210. package/src/component/garmin/private.ts +1798 -0
  211. package/src/component/garmin/public.ts +938 -0
  212. package/src/component/garmin/schemas/activity.ts +40 -0
  213. package/src/component/garmin/schemas/activityDetails.ts +45 -0
  214. package/src/component/garmin/schemas/bloodPressure.ts +38 -0
  215. package/src/component/garmin/schemas/bodyCompositions.ts +38 -0
  216. package/src/component/garmin/schemas/dailies.ts +38 -0
  217. package/src/component/garmin/schemas/epochs.ts +38 -0
  218. package/src/component/garmin/schemas/healthSnapshot.ts +38 -0
  219. package/src/component/garmin/schemas/hrvSummary.ts +38 -0
  220. package/src/component/garmin/schemas/manuallyUpdatedActivities.ts +49 -0
  221. package/src/component/garmin/schemas/menstrualCycleTracking.ts +39 -0
  222. package/src/component/garmin/schemas/moveIQ.ts +38 -0
  223. package/src/component/garmin/schemas/pulseOx.ts +39 -0
  224. package/src/component/garmin/schemas/respiration.ts +39 -0
  225. package/src/component/garmin/schemas/skinTemperature.ts +39 -0
  226. package/src/component/garmin/schemas/sleeps.ts +38 -0
  227. package/src/component/garmin/schemas/stress.ts +43 -0
  228. package/src/component/garmin/schemas/userMetrics.ts +39 -0
  229. package/src/component/garmin/transform/activity.ts +143 -0
  230. package/src/component/garmin/transform/activityDetails.ts +236 -0
  231. package/src/{garmin → component/garmin/transform}/bloodPressure.ts +39 -41
  232. package/src/component/garmin/transform/bodyCompositions.ts +51 -0
  233. package/src/component/garmin/transform/dailies.ts +179 -0
  234. package/src/component/garmin/transform/epochs.ts +94 -0
  235. package/src/component/garmin/transform/healthSnapshot.ts +152 -0
  236. package/src/component/garmin/transform/hrvSummary.ts +56 -0
  237. package/src/component/garmin/transform/manuallyUpdatedActivities.ts +27 -0
  238. package/src/{garmin/maps/activity-type.ts → component/garmin/transform/maps/activityType.ts} +116 -116
  239. package/src/{garmin/maps/sleep-level.ts → component/garmin/transform/maps/sleepLevel.ts} +22 -22
  240. package/src/component/garmin/transform/menstrualCycleTracking.ts +48 -0
  241. package/src/component/garmin/transform/moveIQ.ts +48 -0
  242. package/src/{garmin → component/garmin/transform}/plannedWorkout.ts +328 -333
  243. package/src/component/garmin/transform/pulseOx.ts +64 -0
  244. package/src/component/garmin/transform/respiration.ts +73 -0
  245. package/src/component/garmin/transform/skinTemperature.ts +44 -0
  246. package/src/component/garmin/transform/sleeps.ts +159 -0
  247. package/src/component/garmin/transform/stress.ts +78 -0
  248. package/src/component/garmin/transform/userMetrics.ts +56 -0
  249. package/src/component/garmin/types/specs/training-api-workouts.json +699 -0
  250. package/src/component/garmin/types/trainingApiWorkouts/client/client.gen.ts +290 -0
  251. package/src/component/garmin/types/trainingApiWorkouts/client/index.ts +25 -0
  252. package/src/component/garmin/types/trainingApiWorkouts/client/types.gen.ts +214 -0
  253. package/src/component/garmin/types/trainingApiWorkouts/client/utils.gen.ts +316 -0
  254. package/src/component/garmin/types/trainingApiWorkouts/client.gen.ts +16 -0
  255. package/src/component/garmin/types/trainingApiWorkouts/core/auth.gen.ts +41 -0
  256. package/src/component/garmin/types/trainingApiWorkouts/core/bodySerializer.gen.ts +82 -0
  257. package/src/component/garmin/types/trainingApiWorkouts/core/params.gen.ts +169 -0
  258. package/src/component/garmin/types/trainingApiWorkouts/core/pathSerializer.gen.ts +171 -0
  259. package/src/component/garmin/types/trainingApiWorkouts/core/queryKeySerializer.gen.ts +117 -0
  260. package/src/component/garmin/types/trainingApiWorkouts/core/serverSentEvents.gen.ts +243 -0
  261. package/src/component/garmin/types/trainingApiWorkouts/core/types.gen.ts +104 -0
  262. package/src/component/garmin/types/trainingApiWorkouts/core/utils.gen.ts +140 -0
  263. package/src/component/garmin/types/trainingApiWorkouts/index.ts +4 -0
  264. package/src/component/garmin/types/trainingApiWorkouts/sdk.gen.ts +126 -0
  265. package/src/component/garmin/types/trainingApiWorkouts/types.gen.ts +387 -0
  266. package/src/component/garmin/types/trainingApiWorkouts/zod.gen.ts +423 -0
  267. package/src/component/garmin/types/wellnessApi/client/client.gen.ts +290 -0
  268. package/src/component/garmin/types/wellnessApi/client/index.ts +25 -0
  269. package/src/component/garmin/types/wellnessApi/client/types.gen.ts +214 -0
  270. package/src/component/garmin/types/wellnessApi/client/utils.gen.ts +316 -0
  271. package/src/component/garmin/types/wellnessApi/client.gen.ts +16 -0
  272. package/src/component/garmin/types/wellnessApi/core/auth.gen.ts +41 -0
  273. package/src/component/garmin/types/wellnessApi/core/bodySerializer.gen.ts +82 -0
  274. package/src/component/garmin/types/wellnessApi/core/params.gen.ts +169 -0
  275. package/src/component/garmin/types/wellnessApi/core/pathSerializer.gen.ts +171 -0
  276. package/src/component/garmin/types/wellnessApi/core/queryKeySerializer.gen.ts +117 -0
  277. package/src/component/garmin/types/wellnessApi/core/serverSentEvents.gen.ts +243 -0
  278. package/src/component/garmin/types/wellnessApi/core/types.gen.ts +104 -0
  279. package/src/component/garmin/types/wellnessApi/core/utils.gen.ts +140 -0
  280. package/src/component/garmin/types/wellnessApi/index.ts +4 -0
  281. package/src/component/garmin/types/wellnessApi/sdk.gen.ts +207 -0
  282. package/src/component/garmin/types/wellnessApi/types.gen.ts +2942 -0
  283. package/src/component/garmin/types/wellnessApi/zod.gen.ts +878 -0
  284. package/src/component/garmin/utils.ts +25 -0
  285. package/src/component/garmin/webhooks.ts +852 -0
  286. package/src/component/strava/private.ts +89 -0
  287. package/src/component/{strava.ts → strava/public.ts} +341 -404
  288. package/src/component/validators/activity.ts +5 -0
  289. package/src/component/validators/body.ts +5 -0
  290. package/src/component/validators/daily.ts +5 -0
  291. package/src/component/validators/menstruation.ts +5 -1
  292. package/src/component/validators/plannedWorkout.ts +5 -0
  293. package/src/validators.ts +12 -2
  294. package/dist/component/garmin.d.ts +0 -366
  295. package/dist/component/garmin.d.ts.map +0 -1
  296. package/dist/component/garmin.js +0 -1481
  297. package/dist/component/garmin.js.map +0 -1
  298. package/dist/component/strava.d.ts.map +0 -1
  299. package/dist/component/strava.js.map +0 -1
  300. package/dist/garmin/activity.d.ts +0 -92
  301. package/dist/garmin/activity.d.ts.map +0 -1
  302. package/dist/garmin/activity.js +0 -201
  303. package/dist/garmin/activity.js.map +0 -1
  304. package/src/component/garmin.ts +0 -1722
  305. package/src/garmin/activity.test.ts +0 -170
  306. package/src/garmin/activity.ts +0 -265
  307. package/src/garmin/auth.test.ts +0 -103
  308. package/src/garmin/body.ts +0 -59
  309. package/src/garmin/client.ts +0 -886
  310. package/src/garmin/daily.ts +0 -215
  311. package/src/garmin/hrv.ts +0 -57
  312. package/src/garmin/index.ts +0 -145
  313. package/src/garmin/maps/activity-type.test.ts +0 -78
  314. package/src/garmin/menstruation.ts +0 -44
  315. package/src/garmin/pulseOx.ts +0 -45
  316. package/src/garmin/respiration.ts +0 -55
  317. package/src/garmin/skinTemp.ts +0 -42
  318. package/src/garmin/sleep.test.ts +0 -109
  319. package/src/garmin/sleep.ts +0 -176
  320. package/src/garmin/stressDetails.ts +0 -71
  321. package/src/garmin/sync.ts +0 -566
  322. package/src/garmin/types.ts +0 -268
  323. package/src/garmin/userMetrics.ts +0 -50
  324. package/src/garmin/wellness-api.d.ts +0 -5637
  325. /package/src/{garmin/spec → component/garmin/types/specs}/wellness-api.json +0 -0
@@ -0,0 +1,43 @@
1
+ // ─── Stress Details Webhook Zod Schemas ───────────────────────────────────────
2
+ // Runtime validation schemas for Garmin Stress Details webhook payloads.
3
+ //
4
+ // The base schema (zClientStress) is auto-generated from the
5
+ // OpenAPI spec. We extend it here with webhook-specific fields (userId,
6
+ // userAccessToken).
7
+
8
+ import { z } from "zod";
9
+ import { zBodyBatteryActivityEvent, zClientStress } from "../types/wellnessApi/zod.gen.js";
10
+
11
+ // ─── Push Mode ──────────────────────────────────────────────────────────────
12
+ // Push payloads contain full stress details data plus webhook envelope fields.
13
+
14
+ export const garminStressPushItemSchema = zClientStress.extend({
15
+ // Webhook envelope fields
16
+ userId: z.string(),
17
+ userAccessToken: z.string().optional(),
18
+ // Override bigint → number (openapi-ts maps int64 to bigint in zod)
19
+ bodyBatteryActivityEvents: z.array(
20
+ zBodyBatteryActivityEvent.extend({ activityId: z.coerce.number().optional() }),
21
+ ).optional(),
22
+ });
23
+
24
+ export const garminStressPushPayloadSchema = z.object({
25
+ stressDetails: z.array(garminStressPushItemSchema),
26
+ });
27
+
28
+ // ─── Ping Mode ──────────────────────────────────────────────────────────────
29
+ // Ping payloads are lightweight notifications — not in any OpenAPI spec.
30
+
31
+ export const garminStressPingItemSchema = z.object({
32
+ userId: z.string(),
33
+ callbackURL: z.string().optional(), // absent for deregistration notifications
34
+ });
35
+
36
+ export const garminStressPingPayloadSchema = z.object({
37
+ stressDetails: z.array(garminStressPingItemSchema),
38
+ });
39
+
40
+ // ─── Inferred Types ─────────────────────────────────────────────────────────
41
+
42
+ export type GarminStressPushItem = z.infer<typeof garminStressPushItemSchema>;
43
+ export type GarminStressPingItem = z.infer<typeof garminStressPingItemSchema>;
@@ -0,0 +1,39 @@
1
+ // ─── User Metrics Webhook Zod Schemas ─────────────────────────────────────────
2
+ // Runtime validation schemas for Garmin User Metrics webhook payloads.
3
+ //
4
+ // The base schema (zClientUserMetrics) is auto-generated from the
5
+ // OpenAPI spec. We extend it here with webhook-specific fields (userId,
6
+ // userAccessToken).
7
+
8
+ import { z } from "zod";
9
+ import { zClientUserMetrics } from "../types/wellnessApi/zod.gen.js";
10
+
11
+ // ─── Push Mode ──────────────────────────────────────────────────────────────
12
+ // Push payloads contain full user metrics data plus webhook envelope fields.
13
+
14
+ export const garminUserMetricsPushItemSchema = zClientUserMetrics.extend({
15
+ // Webhook envelope fields
16
+ userId: z.string(),
17
+ userAccessToken: z.string().optional(),
18
+ });
19
+
20
+ export const garminUserMetricsPushPayloadSchema = z.object({
21
+ userMetrics: z.array(garminUserMetricsPushItemSchema),
22
+ });
23
+
24
+ // ─── Ping Mode ──────────────────────────────────────────────────────────────
25
+ // Ping payloads are lightweight notifications — not in any OpenAPI spec.
26
+
27
+ export const garminUserMetricsPingItemSchema = z.object({
28
+ userId: z.string(),
29
+ callbackURL: z.string().optional(), // absent for deregistration notifications
30
+ });
31
+
32
+ export const garminUserMetricsPingPayloadSchema = z.object({
33
+ userMetrics: z.array(garminUserMetricsPingItemSchema),
34
+ });
35
+
36
+ // ─── Inferred Types ─────────────────────────────────────────────────────────
37
+
38
+ export type GarminUserMetricsPushItem = z.infer<typeof garminUserMetricsPushItemSchema>;
39
+ export type GarminUserMetricsPingItem = z.infer<typeof garminUserMetricsPingItemSchema>;
@@ -0,0 +1,143 @@
1
+ // ─── Activity Transformer ────────────────────────────────────────────────────
2
+ // Transforms a Garmin activity push item into the Soma Activity schema shape.
3
+
4
+ import { mapActivityType } from "./maps/activityType.js";
5
+ import type { SomaActivity } from "../../validators/activity.js";
6
+ import type { ClientActivity } from "../types/wellnessApi/types.gen.js";
7
+
8
+ /**
9
+ * Transform a Garmin activity push item into a Soma Activity document shape.
10
+ *
11
+ * Accepts activity summaries from webhook push payloads. These contain
12
+ * summary-level fields only (no laps, samples, or power data).
13
+ *
14
+ * The returned object is ready to be spread into an `ingestActivity` call
15
+ * alongside `connectionId` and `userId`.
16
+ */
17
+ export function transformActivity(activity: ClientActivity): SomaActivity {
18
+ const startMs = (activity.startTimeInSeconds ?? 0) * 1000;
19
+ const endMs = startMs + (activity.durationInSeconds ?? 0) * 1000;
20
+ const startDate = new Date(startMs).toISOString();
21
+ const endDate = new Date(endMs).toISOString();
22
+
23
+ return {
24
+ metadata: {
25
+ summary_id: activity.summaryId ?? String(activity.activityId),
26
+ start_time: startDate,
27
+ end_time: endDate,
28
+ type: mapActivityType(activity.activityType ?? "OTHER"),
29
+ upload_type: activity.manual ? 2 : 1,
30
+ name: activity.activityName,
31
+ },
32
+
33
+ active_durations_data: {
34
+ activity_seconds: activity.durationInSeconds,
35
+ },
36
+
37
+ calories_data: buildCaloriesData(activity),
38
+
39
+ device_data: activity.deviceName
40
+ ? { name: activity.deviceName }
41
+ : undefined,
42
+
43
+ distance_data: buildDistanceData(activity),
44
+
45
+ heart_rate_data: buildHeartRateData(activity),
46
+
47
+ movement_data: buildMovementData(activity),
48
+
49
+ position_data: buildPositionData(activity),
50
+ };
51
+ }
52
+
53
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
54
+
55
+ function buildCaloriesData(activity: ClientActivity) {
56
+ if (activity.activeKilocalories == null) return undefined;
57
+
58
+ return {
59
+ net_activity_calories: activity.activeKilocalories,
60
+ total_burned_calories: activity.activeKilocalories,
61
+ };
62
+ }
63
+
64
+ function buildDistanceData(activity: ClientActivity) {
65
+ const elevGain = activity.totalElevationGainInMeters;
66
+ const elevLoss = activity.totalElevationLossInMeters;
67
+
68
+ if (activity.distanceInMeters == null && elevGain == null) {
69
+ return undefined;
70
+ }
71
+
72
+ return {
73
+ summary: {
74
+ distance_meters: activity.distanceInMeters,
75
+ steps: activity.steps,
76
+ elevation:
77
+ elevGain != null
78
+ ? {
79
+ gain_actual_meters: elevGain,
80
+ loss_actual_meters: elevLoss,
81
+ }
82
+ : undefined,
83
+ },
84
+ };
85
+ }
86
+
87
+ function buildHeartRateData(activity: ClientActivity) {
88
+ if (
89
+ activity.averageHeartRateInBeatsPerMinute == null &&
90
+ activity.maxHeartRateInBeatsPerMinute == null
91
+ ) {
92
+ return undefined;
93
+ }
94
+
95
+ return {
96
+ summary: {
97
+ avg_hr_bpm: activity.averageHeartRateInBeatsPerMinute,
98
+ max_hr_bpm: activity.maxHeartRateInBeatsPerMinute,
99
+ },
100
+ };
101
+ }
102
+
103
+ function buildMovementData(activity: ClientActivity) {
104
+ const avgCadence =
105
+ activity.averageRunCadenceInStepsPerMinute ??
106
+ activity.averageBikeCadenceInRoundsPerMinute;
107
+ const maxCadence =
108
+ activity.maxRunCadenceInStepsPerMinute ??
109
+ activity.maxBikeCadenceInRoundsPerMinute;
110
+
111
+ if (
112
+ activity.averageSpeedInMetersPerSecond == null &&
113
+ activity.maxSpeedInMetersPerSecond == null &&
114
+ avgCadence == null
115
+ ) {
116
+ return undefined;
117
+ }
118
+
119
+ return {
120
+ avg_speed_meters_per_second: activity.averageSpeedInMetersPerSecond,
121
+ max_speed_meters_per_second: activity.maxSpeedInMetersPerSecond,
122
+ avg_pace_minutes_per_kilometer: activity.averagePaceInMinutesPerKilometer,
123
+ max_pace_minutes_per_kilometer: activity.maxPaceInMinutesPerKilometer,
124
+ avg_cadence_rpm: avgCadence,
125
+ max_cadence_rpm: maxCadence,
126
+ };
127
+ }
128
+
129
+ function buildPositionData(activity: ClientActivity) {
130
+ if (
131
+ activity.startingLatitudeInDegree == null ||
132
+ activity.startingLongitudeInDegree == null
133
+ ) {
134
+ return undefined;
135
+ }
136
+
137
+ return {
138
+ start_pos_lat_lng_deg: [
139
+ activity.startingLatitudeInDegree,
140
+ activity.startingLongitudeInDegree,
141
+ ],
142
+ };
143
+ }
@@ -0,0 +1,236 @@
1
+ // ─── Activity Details Transformer ────────────────────────────────────────────
2
+ // Transforms a Garmin activity detail push item into the Soma Activity schema.
3
+ // Enriches the summary-level data from transformActivity with detailed
4
+ // samples (GPS, heart rate, speed, cadence, power, etc.) and lap data.
5
+
6
+ import type { SomaActivity } from "../../validators/activity.js";
7
+ import type {
8
+ ClientActivityDetail,
9
+ ClientLap,
10
+ Sample,
11
+ } from "../types/wellnessApi/types.gen.js";
12
+ import { transformActivity } from "./activity.js";
13
+
14
+ /**
15
+ * Transform a Garmin activity detail push item into a Soma Activity document.
16
+ *
17
+ * Accepts activity details from webhook push payloads. These contain
18
+ * a summary plus per-second samples and lap markers.
19
+ *
20
+ * The returned object is ready to be spread into an `ingestActivity` call
21
+ * alongside `connectionId` and `userId`.
22
+ */
23
+ export function transformActivityDetails(
24
+ detail: ClientActivityDetail,
25
+ ): SomaActivity {
26
+ // Start from summary-level transform
27
+ const summary = detail.summary;
28
+ if (!summary) {
29
+ throw new Error(
30
+ `Activity detail ${detail.summaryId ?? "unknown"} has no summary`,
31
+ );
32
+ }
33
+
34
+ const base = transformActivity(summary);
35
+
36
+ // Override summary_id to use the detail-level one if present
37
+ if (detail.summaryId) {
38
+ base.metadata.summary_id = detail.summaryId;
39
+ }
40
+
41
+ const samples = detail.samples ?? [];
42
+ const laps = detail.laps ?? [];
43
+
44
+ // Enrich with detailed sample data
45
+ return {
46
+ ...base,
47
+ heart_rate_data: buildDetailedHeartRateData(base, samples),
48
+ distance_data: buildDetailedDistanceData(base, samples),
49
+ movement_data: buildDetailedMovementData(base, samples),
50
+ position_data: buildDetailedPositionData(base, samples),
51
+ power_data: buildDetailedPowerData(base, samples),
52
+ lap_data: buildLapData(laps),
53
+ };
54
+ }
55
+
56
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
57
+
58
+ function toIso(epochSeconds: number): string {
59
+ return new Date(epochSeconds * 1000).toISOString();
60
+ }
61
+
62
+ function buildDetailedHeartRateData(
63
+ base: SomaActivity,
64
+ samples: Sample[],
65
+ ): SomaActivity["heart_rate_data"] {
66
+ const hrSamples = samples.filter((s) => s.heartRate != null);
67
+ if (hrSamples.length === 0) return base.heart_rate_data;
68
+
69
+ return {
70
+ ...base.heart_rate_data,
71
+ detailed: {
72
+ hr_samples: hrSamples.map((s) => ({
73
+ timestamp: s.startTimeInSeconds
74
+ ? toIso(s.startTimeInSeconds)
75
+ : undefined,
76
+ bpm: s.heartRate ?? undefined,
77
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
78
+ })),
79
+ },
80
+ };
81
+ }
82
+
83
+ function buildDetailedDistanceData(
84
+ base: SomaActivity,
85
+ samples: Sample[],
86
+ ): SomaActivity["distance_data"] {
87
+ const distanceSamples = samples.filter(
88
+ (s) => s.totalDistanceInMeters != null,
89
+ );
90
+ const elevationSamples = samples.filter(
91
+ (s) => s.elevationInMeters != null,
92
+ );
93
+
94
+ if (distanceSamples.length === 0 && elevationSamples.length === 0) {
95
+ return base.distance_data;
96
+ }
97
+
98
+ return {
99
+ ...base.distance_data,
100
+ detailed: {
101
+ distance_samples:
102
+ distanceSamples.length > 0
103
+ ? distanceSamples.map((s) => ({
104
+ timestamp: s.startTimeInSeconds
105
+ ? toIso(s.startTimeInSeconds)
106
+ : undefined,
107
+ distance_meters: s.totalDistanceInMeters ?? undefined,
108
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
109
+ }))
110
+ : undefined,
111
+ elevation_samples:
112
+ elevationSamples.length > 0
113
+ ? elevationSamples.map((s) => ({
114
+ timestamp: s.startTimeInSeconds
115
+ ? toIso(s.startTimeInSeconds)
116
+ : undefined,
117
+ elev_meters: s.elevationInMeters ?? undefined,
118
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
119
+ }))
120
+ : undefined,
121
+ },
122
+ };
123
+ }
124
+
125
+ function buildDetailedMovementData(
126
+ base: SomaActivity,
127
+ samples: Sample[],
128
+ ): SomaActivity["movement_data"] {
129
+ const speedSamples = samples.filter(
130
+ (s) => s.speedMetersPerSecond != null,
131
+ );
132
+ const cadenceSamples = samples.filter(
133
+ (s) =>
134
+ s.stepsPerMinute != null ||
135
+ s.bikeCadenceInRPM != null ||
136
+ s.swimCadenceInStrokesPerMinute != null,
137
+ );
138
+
139
+ if (speedSamples.length === 0 && cadenceSamples.length === 0) {
140
+ return base.movement_data;
141
+ }
142
+
143
+ return {
144
+ ...base.movement_data,
145
+ speed_samples:
146
+ speedSamples.length > 0
147
+ ? speedSamples.map((s) => ({
148
+ timestamp: s.startTimeInSeconds
149
+ ? toIso(s.startTimeInSeconds)
150
+ : undefined,
151
+ speed_meters_per_second: s.speedMetersPerSecond ?? undefined,
152
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
153
+ }))
154
+ : undefined,
155
+ cadence_samples:
156
+ cadenceSamples.length > 0
157
+ ? cadenceSamples.map((s) => ({
158
+ timestamp: s.startTimeInSeconds
159
+ ? toIso(s.startTimeInSeconds)
160
+ : undefined,
161
+ cadence_rpm:
162
+ s.stepsPerMinute ??
163
+ s.bikeCadenceInRPM ??
164
+ s.swimCadenceInStrokesPerMinute ??
165
+ undefined,
166
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
167
+ }))
168
+ : undefined,
169
+ };
170
+ }
171
+
172
+ function buildDetailedPositionData(
173
+ base: SomaActivity,
174
+ samples: Sample[],
175
+ ): SomaActivity["position_data"] {
176
+ const posSamples = samples.filter(
177
+ (s) => s.latitudeInDegree != null && s.longitudeInDegree != null,
178
+ );
179
+
180
+ if (posSamples.length === 0) return base.position_data;
181
+
182
+ return {
183
+ ...base.position_data,
184
+ position_samples: posSamples.map((s) => ({
185
+ timestamp: s.startTimeInSeconds
186
+ ? toIso(s.startTimeInSeconds)
187
+ : undefined,
188
+ coords_lat_lng_deg: [s.latitudeInDegree ?? 0, s.longitudeInDegree ?? 0],
189
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
190
+ })),
191
+ };
192
+ }
193
+
194
+ function buildDetailedPowerData(
195
+ base: SomaActivity,
196
+ samples: Sample[],
197
+ ): SomaActivity["power_data"] {
198
+ const powerSamples = samples.filter((s) => s.powerInWatts != null);
199
+
200
+ if (powerSamples.length === 0) return base.power_data;
201
+
202
+ return {
203
+ ...base.power_data,
204
+ power_samples: powerSamples.map((s) => ({
205
+ timestamp: s.startTimeInSeconds
206
+ ? toIso(s.startTimeInSeconds)
207
+ : undefined,
208
+ watts: s.powerInWatts ?? undefined,
209
+ timer_duration_seconds: s.timerDurationInSeconds ?? undefined,
210
+ })),
211
+ };
212
+ }
213
+
214
+ function buildLapData(
215
+ laps: ClientLap[],
216
+ ): SomaActivity["lap_data"] {
217
+ if (laps.length === 0) return undefined;
218
+
219
+ return {
220
+ laps: laps.map((lap, i) => {
221
+ const startTime = lap.startTimeInSeconds
222
+ ? toIso(lap.startTimeInSeconds)
223
+ : undefined;
224
+ // Estimate end time from next lap's start, if available
225
+ const nextLap = laps[i + 1];
226
+ const endTime = nextLap?.startTimeInSeconds
227
+ ? toIso(nextLap.startTimeInSeconds)
228
+ : undefined;
229
+
230
+ return {
231
+ start_time: startTime,
232
+ end_time: endTime,
233
+ };
234
+ }),
235
+ };
236
+ }
@@ -1,41 +1,39 @@
1
- // ─── Blood Pressure Transformer ──────────────────────────────────────────────
2
- // Transforms Garmin blood pressure data into the Soma Body schema shape.
3
-
4
- import type { GarminBloodPressure } from "./types.js";
5
-
6
- export type BloodPressureData = ReturnType<typeof transformBloodPressure>;
7
-
8
- /**
9
- * Transform a Garmin blood pressure record into a Soma Body document shape.
10
- *
11
- * @param bp - The Garmin blood pressure data from the Health API
12
- * @returns Soma Body fields (without connectionId/userId)
13
- */
14
- export function transformBloodPressure(bp: GarminBloodPressure) {
15
- const measurementMs = (bp.measurementTimeInSeconds ?? 0) * 1000;
16
- const timestamp = new Date(measurementMs).toISOString();
17
-
18
- if (bp.systolic == null && bp.diastolic == null) {
19
- return {
20
- metadata: { start_time: timestamp, end_time: timestamp },
21
- blood_pressure_data: undefined,
22
- };
23
- }
24
-
25
- return {
26
- metadata: {
27
- start_time: timestamp,
28
- end_time: timestamp,
29
- },
30
-
31
- blood_pressure_data: {
32
- blood_pressure_samples: [
33
- {
34
- timestamp,
35
- diastolic_bp: bp.diastolic,
36
- systolic_bp: bp.systolic,
37
- },
38
- ],
39
- },
40
- };
41
- }
1
+ // ─── Blood Pressure Transformer ──────────────────────────────────────────────
2
+ // Transforms a Garmin blood pressure push item into the Soma Body schema shape.
3
+
4
+ import type { SomaBody } from "../../validators/body.js";
5
+ import type { ClientBloodPressure } from "../types/wellnessApi/types.gen.js";
6
+
7
+ /**
8
+ * Transform a Garmin blood pressure push item into a Soma Body document shape.
9
+ *
10
+ * Blood pressure records are ingested into the `body` table via `ingestBody`,
11
+ * keyed by `metadata.start_time + metadata.end_time`.
12
+ *
13
+ * Returns `null` when neither systolic nor diastolic data is present.
14
+ */
15
+ export function transformBloodPressure(bp: ClientBloodPressure): SomaBody | null {
16
+ const measurementMs = (bp.measurementTimeInSeconds ?? 0) * 1000;
17
+ const timestamp = new Date(measurementMs).toISOString();
18
+
19
+ if (bp.systolic == null && bp.diastolic == null) {
20
+ return null;
21
+ }
22
+
23
+ return {
24
+ metadata: {
25
+ start_time: timestamp,
26
+ end_time: timestamp,
27
+ },
28
+
29
+ blood_pressure_data: {
30
+ blood_pressure_samples: [
31
+ {
32
+ timestamp,
33
+ diastolic_bp: bp.diastolic,
34
+ systolic_bp: bp.systolic,
35
+ },
36
+ ],
37
+ },
38
+ };
39
+ }
@@ -0,0 +1,51 @@
1
+ // ─── Body Compositions Transformer ───────────────────────────────────────────
2
+ // Transforms a Garmin body composition push item into the Soma Body schema shape.
3
+
4
+ import type { SomaBody } from "../../validators/body.js";
5
+ import type { ClientBodyComp } from "../types/wellnessApi/types.gen.js";
6
+
7
+ /**
8
+ * Transform a Garmin body composition push item into a Soma Body document shape.
9
+ *
10
+ * Body composition records are ingested into the `body` table via `ingestBody`,
11
+ * keyed by `metadata.start_time + metadata.end_time`.
12
+ *
13
+ * Returns `null` when no meaningful measurement data is present.
14
+ */
15
+ export function transformBodyComposition(body: ClientBodyComp): SomaBody | null {
16
+ const measurementMs = (body.measurementTimeInSeconds ?? 0) * 1000;
17
+ const timestamp = new Date(measurementMs).toISOString();
18
+
19
+ if (
20
+ body.weightInGrams == null &&
21
+ body.bodyFatInPercent == null &&
22
+ body.bodyMassIndex == null &&
23
+ body.muscleMassInGrams == null &&
24
+ body.boneMassInGrams == null &&
25
+ body.bodyWaterInPercent == null
26
+ ) {
27
+ return null;
28
+ }
29
+
30
+ return {
31
+ metadata: {
32
+ start_time: timestamp,
33
+ end_time: timestamp,
34
+ },
35
+
36
+ measurements_data: {
37
+ measurements: [
38
+ {
39
+ measurement_time: timestamp,
40
+ weight_kg:
41
+ body.weightInGrams != null ? body.weightInGrams / 1000 : undefined,
42
+ BMI: body.bodyMassIndex,
43
+ bodyfat_percentage: body.bodyFatInPercent,
44
+ muscle_mass_g: body.muscleMassInGrams,
45
+ bone_mass_g: body.boneMassInGrams,
46
+ water_percentage: body.bodyWaterInPercent,
47
+ },
48
+ ],
49
+ },
50
+ };
51
+ }