@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
@@ -1,215 +0,0 @@
1
- // ─── Daily Transformer ───────────────────────────────────────────────────────
2
- // Transforms a Garmin daily wellness summary into the Soma Daily schema shape.
3
-
4
- import type { GarminDailySummary } from "./types.js";
5
-
6
- // GarminDailySummary is an alias for GarminDailyExtended which includes
7
- // both spec fields and additional fields the API returns (stress time-series,
8
- // SpO2, body battery, respiration).
9
-
10
- export type DailyData = ReturnType<typeof transformDaily>;
11
-
12
- /**
13
- * Transform a Garmin daily summary into a Soma Daily document shape.
14
- *
15
- * @param daily - The Garmin daily summary from the Health API
16
- * @returns Soma Daily fields (without connectionId/userId)
17
- */
18
- export function transformDaily(daily: GarminDailySummary) {
19
- const startMs = (daily.startTimeInSeconds ?? 0) * 1000;
20
- const endMs = startMs + (daily.durationInSeconds ?? 0) * 1000;
21
-
22
- return {
23
- metadata: {
24
- start_time: new Date(startMs).toISOString(),
25
- end_time: new Date(endMs).toISOString(),
26
- upload_type: 1, // Automatic
27
- },
28
-
29
- active_durations_data: buildActiveDurationsData(daily),
30
-
31
- calories_data: buildCaloriesData(daily),
32
-
33
- distance_data: buildDistanceData(daily),
34
-
35
- heart_rate_data: buildHeartRateData(daily),
36
-
37
- oxygen_data: buildOxygenData(daily),
38
-
39
- stress_data: buildStressData(daily),
40
- };
41
- }
42
-
43
- // ─── Helpers ──────────────────────────────────────────────────────────────────
44
-
45
- function buildActiveDurationsData(daily: GarminDailySummary) {
46
- if (
47
- daily.activeTimeInSeconds == null &&
48
- daily.moderateIntensityDurationInSeconds == null &&
49
- daily.vigorousIntensityDurationInSeconds == null
50
- ) {
51
- return undefined;
52
- }
53
-
54
- return {
55
- activity_seconds: daily.activeTimeInSeconds,
56
- moderate_intensity_seconds: daily.moderateIntensityDurationInSeconds,
57
- vigorous_intensity_seconds: daily.vigorousIntensityDurationInSeconds,
58
- };
59
- }
60
-
61
- function buildCaloriesData(daily: GarminDailySummary) {
62
- if (daily.activeKilocalories == null && daily.bmrKilocalories == null) {
63
- return undefined;
64
- }
65
-
66
- const total =
67
- (daily.activeKilocalories ?? 0) + (daily.bmrKilocalories ?? 0);
68
-
69
- return {
70
- net_activity_calories: daily.activeKilocalories,
71
- BMR_calories: daily.bmrKilocalories,
72
- total_burned_calories: total || undefined,
73
- };
74
- }
75
-
76
- function buildDistanceData(daily: GarminDailySummary) {
77
- if (
78
- daily.distanceInMeters == null &&
79
- daily.steps == null &&
80
- daily.floorsClimbed == null
81
- ) {
82
- return undefined;
83
- }
84
-
85
- return {
86
- distance_meters: daily.distanceInMeters,
87
- steps: daily.steps,
88
- floors_climbed: daily.floorsClimbed,
89
- };
90
- }
91
-
92
- function buildHeartRateData(daily: GarminDailySummary) {
93
- const hasSummary =
94
- daily.averageHeartRateInBeatsPerMinute != null ||
95
- daily.maxHeartRateInBeatsPerMinute != null ||
96
- daily.restingHeartRateInBeatsPerMinute != null;
97
- const hasSamples =
98
- daily.timeOffsetHeartRateSamples != null &&
99
- Object.keys(daily.timeOffsetHeartRateSamples).length > 0;
100
-
101
- if (!hasSummary && !hasSamples) return undefined;
102
-
103
- const hrSamples = hasSamples
104
- ? buildTimeOffsetSamples(
105
- daily.startTimeInSeconds,
106
- daily.timeOffsetHeartRateSamples!,
107
- (bpm) => ({ bpm }),
108
- )
109
- : undefined;
110
-
111
- return {
112
- summary: hasSummary
113
- ? {
114
- avg_hr_bpm: daily.averageHeartRateInBeatsPerMinute,
115
- max_hr_bpm: daily.maxHeartRateInBeatsPerMinute,
116
- min_hr_bpm: daily.minHeartRateInBeatsPerMinute,
117
- resting_hr_bpm: daily.restingHeartRateInBeatsPerMinute,
118
- }
119
- : undefined,
120
- detailed:
121
- hrSamples && hrSamples.length > 0
122
- ? { hr_samples: hrSamples }
123
- : undefined,
124
- };
125
- }
126
-
127
- function buildOxygenData(daily: GarminDailySummary) {
128
- if (daily.averageSpo2Value == null && daily.timeOffsetSpo2Values == null) {
129
- return undefined;
130
- }
131
-
132
- const samples =
133
- daily.timeOffsetSpo2Values != null
134
- ? buildTimeOffsetSamples(
135
- daily.startTimeInSeconds,
136
- daily.timeOffsetSpo2Values,
137
- (pct) => ({ percentage: pct }),
138
- )
139
- : undefined;
140
-
141
- return {
142
- avg_saturation_percentage: daily.averageSpo2Value,
143
- saturation_samples:
144
- samples && samples.length > 0 ? samples : undefined,
145
- };
146
- }
147
-
148
- function buildStressData(daily: GarminDailySummary) {
149
- const hasStress =
150
- daily.averageStressLevel != null ||
151
- daily.maxStressLevel != null ||
152
- daily.stressDurationInSeconds != null;
153
- const hasStressSamples =
154
- daily.timeOffsetStressLevelValues != null &&
155
- Object.keys(daily.timeOffsetStressLevelValues).length > 0;
156
- const hasBodyBatterySamples =
157
- daily.timeOffsetBodyBatteryValues != null &&
158
- Object.keys(daily.timeOffsetBodyBatteryValues).length > 0;
159
-
160
- if (!hasStress && !hasStressSamples && !hasBodyBatterySamples) {
161
- return undefined;
162
- }
163
-
164
- const stressSamples = hasStressSamples
165
- ? buildTimeOffsetSamples(
166
- daily.startTimeInSeconds,
167
- daily.timeOffsetStressLevelValues!,
168
- (level) => ({ level }),
169
- )
170
- : undefined;
171
-
172
- const bodyBatterySamples = hasBodyBatterySamples
173
- ? buildTimeOffsetSamples(
174
- daily.startTimeInSeconds,
175
- daily.timeOffsetBodyBatteryValues!,
176
- (level) => ({ level }),
177
- )
178
- : undefined;
179
-
180
- return {
181
- avg_stress_level: daily.averageStressLevel,
182
- max_stress_level: daily.maxStressLevel,
183
- stress_duration_seconds: daily.stressDurationInSeconds,
184
- rest_stress_duration_seconds: daily.restStressDurationInSeconds,
185
- activity_stress_duration_seconds: daily.activityStressDurationInSeconds,
186
- low_stress_duration_seconds: daily.lowStressDurationInSeconds,
187
- medium_stress_duration_seconds: daily.mediumStressDurationInSeconds,
188
- high_stress_duration_seconds: daily.highStressDurationInSeconds,
189
- samples:
190
- stressSamples && stressSamples.length > 0 ? stressSamples : undefined,
191
- body_battery_samples:
192
- bodyBatterySamples && bodyBatterySamples.length > 0
193
- ? bodyBatterySamples
194
- : undefined,
195
- };
196
- }
197
-
198
- /**
199
- * Convert Garmin offset-keyed time-series data into timestamped samples.
200
- *
201
- * Garmin sends time-series as `{ [offsetSeconds]: value }` maps.
202
- * This converts to `{ timestamp: ISO-8601, ...fields }[]`.
203
- */
204
- function buildTimeOffsetSamples<T extends Record<string, unknown>>(
205
- startTimeInSeconds: number | undefined,
206
- offsets: Record<string, number>,
207
- mapValue: (value: number) => T,
208
- ): Array<{ timestamp: string } & T> {
209
- return Object.entries(offsets).map(([offset, value]) => ({
210
- timestamp: new Date(
211
- ((startTimeInSeconds ?? 0) + parseInt(offset, 10)) * 1000,
212
- ).toISOString(),
213
- ...mapValue(value),
214
- }));
215
- }
package/src/garmin/hrv.ts DELETED
@@ -1,57 +0,0 @@
1
- // ─── HRV Transformer ─────────────────────────────────────────────────────────
2
- // Transforms Garmin HRV summary data into fields that enrich a Soma Daily record.
3
-
4
- import type { GarminHRVSummary } from "./types.js";
5
-
6
- export type HRVData = ReturnType<typeof transformHRV>;
7
-
8
- /**
9
- * Transform a Garmin HRV summary into heart rate data fields for a Soma Daily.
10
- *
11
- * This produces a partial daily shape that can be merged into a matching
12
- * daily record by date.
13
- *
14
- * @param hrv - The Garmin HRV summary from the Health API
15
- * @returns Partial Soma Daily heart_rate_data fields
16
- */
17
- export function transformHRV(hrv: GarminHRVSummary) {
18
- const startMs = (hrv.startTimeInSeconds ?? 0) * 1000;
19
- const endMs = startMs + (hrv.durationInSeconds ?? 0) * 1000;
20
-
21
- const hasSummary = hrv.lastNightAvg != null || hrv.lastNight5MinHigh != null;
22
- const hasSamples =
23
- hrv.hrvValues != null && Object.keys(hrv.hrvValues).length > 0;
24
-
25
- if (!hasSummary && !hasSamples) {
26
- return {
27
- calendar_date: hrv.calendarDate,
28
- heart_rate_data: undefined,
29
- };
30
- }
31
-
32
- const startTime = hrv.startTimeInSeconds ?? 0;
33
- const hrvSamples = hasSamples
34
- ? Object.entries(hrv.hrvValues!).map(([offset, rmssd]) => ({
35
- timestamp: new Date(
36
- (startTime + parseInt(offset, 10)) * 1000,
37
- ).toISOString(),
38
- hrv_rmssd: rmssd,
39
- }))
40
- : undefined;
41
-
42
- return {
43
- calendar_date: hrv.calendarDate,
44
- heart_rate_data: {
45
- summary: hasSummary
46
- ? {
47
- avg_hrv_rmssd: hrv.lastNightAvg,
48
- max_hrv_rmssd: hrv.lastNight5MinHigh,
49
- }
50
- : undefined,
51
- detailed:
52
- hrvSamples && hrvSamples.length > 0
53
- ? { hrv_samples_rmssd: hrvSamples }
54
- : undefined,
55
- },
56
- };
57
- }
@@ -1,145 +0,0 @@
1
- // ─── @nativesquare/soma/garmin ───────────────────────────────────────────────
2
- // Garmin Health API → Soma schema transformers, API client, OAuth 2.0 PKCE helpers, and sync.
3
- //
4
- // Uses the Web Crypto API for PKCE code challenge generation.
5
- // Compatible with both the Convex V8 runtime and Node.js environments.
6
-
7
- // ── Transformers ─────────────────────────────────────────────────────────────
8
- export { transformActivity } from "./activity.js";
9
- export type { ActivityData } from "./activity.js";
10
-
11
- export { transformDaily } from "./daily.js";
12
- export type { DailyData } from "./daily.js";
13
-
14
- export { transformSleep } from "./sleep.js";
15
- export type { SleepData } from "./sleep.js";
16
-
17
- export { transformBody } from "./body.js";
18
- export type { BodyData } from "./body.js";
19
-
20
- export { transformMenstruation } from "./menstruation.js";
21
- export type { MenstruationData } from "./menstruation.js";
22
-
23
- export { transformBloodPressure } from "./bloodPressure.js";
24
- export type { BloodPressureData } from "./bloodPressure.js";
25
-
26
- export { transformSkinTemp } from "./skinTemp.js";
27
- export type { SkinTempData } from "./skinTemp.js";
28
-
29
- export { transformUserMetrics } from "./userMetrics.js";
30
- export type { UserMetricsData } from "./userMetrics.js";
31
-
32
- export { transformHRV } from "./hrv.js";
33
- export type { HRVData } from "./hrv.js";
34
-
35
- export { transformStressDetails } from "./stressDetails.js";
36
- export type { StressDetailsData } from "./stressDetails.js";
37
-
38
- export { transformPulseOx } from "./pulseOx.js";
39
- export type { PulseOxData } from "./pulseOx.js";
40
-
41
- export { transformRespiration } from "./respiration.js";
42
- export type { RespirationData } from "./respiration.js";
43
-
44
- // ── Enum Maps ────────────────────────────────────────────────────────────────
45
- export { mapActivityType } from "./maps/activity-type.js";
46
- export { mapSleepLevel } from "./maps/sleep-level.js";
47
-
48
- // ── API Client ───────────────────────────────────────────────────────────────
49
- export { GarminClient, GarminApiError } from "./client.js";
50
- export type { GarminClientOptions, TimeRangeParams } from "./client.js";
51
-
52
- // ── OAuth 2.0 PKCE Helpers ───────────────────────────────────────────────────
53
- export {
54
- generateCodeVerifier,
55
- generateCodeChallenge,
56
- generateState,
57
- buildAuthUrl,
58
- exchangeCode,
59
- refreshToken,
60
- } from "./auth.js";
61
- export type {
62
- BuildAuthUrlOptions,
63
- ExchangeCodeOptions,
64
- RefreshTokenOptions,
65
- } from "./auth.js";
66
-
67
- // ── Sync Helpers ─────────────────────────────────────────────────────────────
68
- export {
69
- syncAll,
70
- syncActivities,
71
- syncDailies,
72
- syncSleep,
73
- syncBody,
74
- syncMenstruation,
75
- syncBloodPressures,
76
- syncSkinTemp,
77
- syncUserMetrics,
78
- syncHRV,
79
- syncStressDetails,
80
- syncPulseOx,
81
- syncRespiration,
82
- } from "./sync.js";
83
- export type {
84
- SyncOptions,
85
- SyncResult,
86
- SyncAllResult,
87
- } from "./sync.js";
88
-
89
- // ── Types ────────────────────────────────────────────────────────────────────
90
- export type {
91
- // Wellness API types (aliases for generated spec types)
92
- GarminActivity,
93
- GarminActivityDetail,
94
- GarminDaily,
95
- GarminSleep,
96
- GarminBodyComposition,
97
- GarminMenstrualCycle,
98
- GarminUserMetrics,
99
- GarminStressDetail,
100
- GarminSkinTemperature,
101
- GarminRespiration,
102
- GarminPulseOx,
103
- GarminHRVSummary,
104
- GarminHealthSnapshot,
105
- GarminEpoch,
106
- GarminBloodPressure,
107
- GarminMoveIQEvent,
108
- GarminSolar,
109
- GarminSample,
110
- GarminLap,
111
- GarminTimeRange,
112
- GarminSleepScoreItem,
113
- GarminNap,
114
- // Extended types (spec + undocumented fields)
115
- GarminDailyExtended,
116
- GarminSleepExtended,
117
- GarminActivityExtended,
118
- // Backward compatibility aliases
119
- GarminDailySummary,
120
- GarminMenstrualCycleData,
121
- GarminSleepLevel,
122
- GarminActivityLap,
123
- GarminActivitySample,
124
- // Training API types
125
- GarminWorkout,
126
- GarminWorkoutStep,
127
- GarminWorkoutRepeatStep,
128
- GarminWorkoutSegment,
129
- GarminWorkoutSchedule,
130
- GarminWorkoutSport,
131
- // OAuth
132
- GarminOAuth2TokenResponse,
133
- // Webhook payloads
134
- GarminWebhookActivityPayload,
135
- GarminWebhookDailyPayload,
136
- GarminWebhookSleepPayload,
137
- GarminWebhookBodyPayload,
138
- GarminWebhookBloodPressurePayload,
139
- GarminWebhookSkinTempPayload,
140
- GarminWebhookUserMetricsPayload,
141
- GarminWebhookHRVPayload,
142
- GarminWebhookStressDetailPayload,
143
- GarminWebhookPulseOxPayload,
144
- GarminWebhookRespirationPayload,
145
- } from "./types.js";
@@ -1,78 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { mapActivityType } from "./activity-type.js";
3
-
4
- describe("mapActivityType", () => {
5
- it("maps running types to Terra Running (8)", () => {
6
- expect(mapActivityType("RUNNING")).toBe(8);
7
- expect(mapActivityType("INDOOR_RUNNING")).toBe(8);
8
- expect(mapActivityType("TRAIL_RUNNING")).toBe(8);
9
- expect(mapActivityType("TREADMILL_RUNNING")).toBe(8);
10
- });
11
-
12
- it("maps cycling types to Terra Biking (1)", () => {
13
- expect(mapActivityType("CYCLING")).toBe(1);
14
- expect(mapActivityType("INDOOR_CYCLING")).toBe(1);
15
- expect(mapActivityType("MOUNTAIN_BIKING")).toBe(1);
16
- expect(mapActivityType("GRAVEL_CYCLING")).toBe(1);
17
- expect(mapActivityType("VIRTUAL_RIDE")).toBe(1);
18
- });
19
-
20
- it("maps WALKING to Terra Walking (7)", () => {
21
- expect(mapActivityType("WALKING")).toBe(7);
22
- });
23
-
24
- it("maps HIKING to Terra Hiking (35)", () => {
25
- expect(mapActivityType("HIKING")).toBe(35);
26
- });
27
-
28
- it("maps swimming types to Terra Swimming (82)", () => {
29
- expect(mapActivityType("SWIMMING")).toBe(82);
30
- expect(mapActivityType("OPEN_WATER_SWIMMING")).toBe(82);
31
- expect(mapActivityType("LAP_SWIMMING")).toBe(82);
32
- expect(mapActivityType("POOL_SWIMMING")).toBe(82);
33
- });
34
-
35
- it("maps snow sports correctly", () => {
36
- expect(mapActivityType("ALPINE_SKIING")).toBe(66);
37
- expect(mapActivityType("CROSS_COUNTRY_SKIING")).toBe(67);
38
- expect(mapActivityType("SNOWBOARDING")).toBe(73);
39
- expect(mapActivityType("SNOWSHOEING")).toBe(74);
40
- });
41
-
42
- it("maps water sports correctly", () => {
43
- expect(mapActivityType("ROWING")).toBe(53);
44
- expect(mapActivityType("INDOOR_ROWING")).toBe(53);
45
- expect(mapActivityType("KAYAKING")).toBe(40);
46
- expect(mapActivityType("SAILING")).toBe(59);
47
- expect(mapActivityType("SURFING")).toBe(81);
48
- expect(mapActivityType("KITESURFING")).toBe(41);
49
- });
50
-
51
- it("maps racket sports correctly", () => {
52
- expect(mapActivityType("TENNIS")).toBe(87);
53
- expect(mapActivityType("TABLE_TENNIS")).toBe(85);
54
- expect(mapActivityType("BADMINTON")).toBe(10);
55
- expect(mapActivityType("SQUASH")).toBe(76);
56
- });
57
-
58
- it("maps gym/fitness activities correctly", () => {
59
- expect(mapActivityType("STRENGTH_TRAINING")).toBe(80);
60
- expect(mapActivityType("CROSSFIT")).toBe(113);
61
- expect(mapActivityType("YOGA")).toBe(100);
62
- expect(mapActivityType("PILATES")).toBe(49);
63
- expect(mapActivityType("HIIT")).toBe(114);
64
- expect(mapActivityType("ELLIPTICAL")).toBe(25);
65
- expect(mapActivityType("STAIR_CLIMBING")).toBe(78);
66
- });
67
-
68
- it("maps team sports correctly", () => {
69
- expect(mapActivityType("SOCCER")).toBe(29);
70
- expect(mapActivityType("BASKETBALL")).toBe(11);
71
- expect(mapActivityType("VOLLEYBALL")).toBe(94);
72
- });
73
-
74
- it("returns Terra Other (108) for unknown types", () => {
75
- expect(mapActivityType("UNKNOWN_SPORT" as never)).toBe(108);
76
- expect(mapActivityType("" as never)).toBe(108);
77
- });
78
- });
@@ -1,44 +0,0 @@
1
- // ─── Menstruation Transformer ────────────────────────────────────────────────
2
- // Transforms Garmin menstrual cycle data into the Soma Menstruation schema shape.
3
-
4
- import type { GarminMenstrualCycle } from "./types.js";
5
-
6
- export type MenstruationData = ReturnType<typeof transformMenstruation>;
7
-
8
- /**
9
- * Transform a Garmin menstrual cycle record into a Soma Menstruation document shape.
10
- *
11
- * @param data - The Garmin menstrual cycle data from the Health API
12
- * @returns Soma Menstruation fields (without connectionId/userId)
13
- */
14
- export function transformMenstruation(data: GarminMenstrualCycle) {
15
- // Spec uses periodStartDate (date string like "2021-01-04")
16
- const dateStr = data.periodStartDate;
17
- const startTime = dateStr
18
- ? `${dateStr}T00:00:00.000Z`
19
- : undefined;
20
- const endTime = dateStr
21
- ? `${dateStr}T23:59:59.999Z`
22
- : undefined;
23
-
24
- return {
25
- metadata: {
26
- start_time: startTime,
27
- end_time: endTime,
28
- },
29
-
30
- menstruation_data: {
31
- day_in_cycle: data.dayInCycle,
32
- // Spec has currentPhaseType (string) replacing deprecated currentPhase (int)
33
- current_phase: data.currentPhaseType?.toLowerCase(),
34
- length_of_current_phase_days: data.lengthOfCurrentPhase,
35
- days_until_next_phase: data.daysUntilNextPhase,
36
- period_length_days: data.periodLength,
37
- predicted_cycle_length_days: data.predictedCycleLength,
38
- cycle_length_days: data.cycleLength,
39
- is_predicted_cycle: data.isPredictedCycle != null
40
- ? String(data.isPredictedCycle)
41
- : undefined,
42
- },
43
- };
44
- }
@@ -1,45 +0,0 @@
1
- // ─── Pulse Ox Transformer ────────────────────────────────────────────────────
2
- // Transforms Garmin pulse ox data into fields that enrich a Soma Daily record.
3
-
4
- import type { GarminPulseOx } from "./types.js";
5
-
6
- export type PulseOxData = ReturnType<typeof transformPulseOx>;
7
-
8
- /**
9
- * Transform a Garmin pulse ox record into oxygen data fields for a Soma Daily.
10
- *
11
- * This produces a partial daily shape that can be merged into a matching
12
- * daily record by date.
13
- *
14
- * @param pulseOx - The Garmin pulse ox data from the Health API
15
- * @returns Partial Soma Daily oxygen_data fields
16
- */
17
- export function transformPulseOx(pulseOx: GarminPulseOx) {
18
- const hasSamples =
19
- pulseOx.timeOffsetSpo2Values != null &&
20
- Object.keys(pulseOx.timeOffsetSpo2Values).length > 0;
21
-
22
- if (!hasSamples) {
23
- return {
24
- calendar_date: pulseOx.calendarDate,
25
- oxygen_data: undefined,
26
- };
27
- }
28
-
29
- const startTime = pulseOx.startTimeInSeconds ?? 0;
30
- const samples = Object.entries(pulseOx.timeOffsetSpo2Values!).map(
31
- ([offset, percentage]) => ({
32
- timestamp: new Date(
33
- (startTime + parseInt(offset, 10)) * 1000,
34
- ).toISOString(),
35
- percentage,
36
- }),
37
- );
38
-
39
- return {
40
- calendar_date: pulseOx.calendarDate,
41
- oxygen_data: {
42
- saturation_samples: samples.length > 0 ? samples : undefined,
43
- },
44
- };
45
- }
@@ -1,55 +0,0 @@
1
- // ─── Respiration Transformer ─────────────────────────────────────────────────
2
- // Transforms Garmin respiration data into fields that enrich a Soma Daily record.
3
-
4
- import type { GarminRespiration } from "./types.js";
5
-
6
- export type RespirationData = ReturnType<typeof transformRespiration>;
7
-
8
- /**
9
- * Transform a Garmin respiration record into respiration data fields for a Soma Daily.
10
- *
11
- * This produces a partial daily shape that can be merged into a matching
12
- * daily record by date.
13
- *
14
- * @param resp - The Garmin respiration data from the Health API
15
- * @returns Partial Soma Daily respiration_data fields
16
- */
17
- export function transformRespiration(resp: GarminRespiration) {
18
- const hasSamples =
19
- resp.timeOffsetEpochToBreaths != null &&
20
- Object.keys(resp.timeOffsetEpochToBreaths).length > 0;
21
-
22
- if (!hasSamples) {
23
- return {
24
- calendar_date: undefined,
25
- respiration_data: undefined,
26
- };
27
- }
28
-
29
- const startTime = resp.startTimeInSeconds ?? 0;
30
- const samples = Object.entries(resp.timeOffsetEpochToBreaths!).map(
31
- ([offset, breaths_per_min]) => ({
32
- timestamp: new Date(
33
- (startTime + parseInt(offset, 10)) * 1000,
34
- ).toISOString(),
35
- breaths_per_min,
36
- }),
37
- );
38
-
39
- // Compute summary stats from samples
40
- const values = samples.map((s) => s.breaths_per_min);
41
- const avg = values.reduce((sum, v) => sum + v, 0) / values.length;
42
-
43
- return {
44
- // Respiration endpoint doesn't have calendarDate, derive from startTime
45
- calendar_date: new Date(startTime * 1000).toISOString().split("T")[0],
46
- respiration_data: {
47
- breaths_data: {
48
- avg_breaths_per_min: Math.round(avg * 10) / 10,
49
- min_breaths_per_min: Math.min(...values),
50
- max_breaths_per_min: Math.max(...values),
51
- samples: samples.length > 0 ? samples : undefined,
52
- },
53
- },
54
- };
55
- }
@@ -1,42 +0,0 @@
1
- // ─── Skin Temperature Transformer ────────────────────────────────────────────
2
- // Transforms Garmin skin temperature data into the Soma Body schema shape.
3
-
4
- import type { GarminSkinTemperature } from "./types.js";
5
-
6
- export type SkinTempData = ReturnType<typeof transformSkinTemp>;
7
-
8
- /**
9
- * Transform a Garmin skin temperature record into a Soma Body document shape.
10
- *
11
- * @param skinTemp - The Garmin skin temperature data from the Health API
12
- * @returns Soma Body fields (without connectionId/userId)
13
- */
14
- export function transformSkinTemp(skinTemp: GarminSkinTemperature) {
15
- const startMs = (skinTemp.startTimeInSeconds ?? 0) * 1000;
16
- const endMs = startMs + (skinTemp.durationInSeconds ?? 0) * 1000;
17
- const startTime = new Date(startMs).toISOString();
18
- const endTime = new Date(endMs).toISOString();
19
-
20
- if (skinTemp.avgDeviationCelsius == null) {
21
- return {
22
- metadata: { start_time: startTime, end_time: endTime },
23
- temperature_data: undefined,
24
- };
25
- }
26
-
27
- return {
28
- metadata: {
29
- start_time: startTime,
30
- end_time: endTime,
31
- },
32
-
33
- temperature_data: {
34
- skin_temperature_samples: [
35
- {
36
- timestamp: startTime,
37
- temperature_celsius: skinTemp.avgDeviationCelsius,
38
- },
39
- ],
40
- },
41
- };
42
- }