@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,64 @@
1
+ // ─── Pulse Ox Transformer ────────────────────────────────────────────────────
2
+ // Transforms a Garmin Pulse Ox push item into the Soma Daily schema shape.
3
+ //
4
+ // Pulse Ox summaries contain SpO2 (blood oxygen saturation) readings
5
+ // throughout the day. We map these into the Daily model's oxygen_data field.
6
+
7
+ import type { SomaDaily } from "../../validators/daily.js";
8
+ import type { ClientDailySpo2Acclimation } from "../types/wellnessApi/types.gen.js";
9
+
10
+ /**
11
+ * Transform a Garmin Pulse Ox push item into a Soma Daily document shape.
12
+ *
13
+ * Pulse Ox summaries are ingested into the `daily` table via `ingestDaily`,
14
+ * keyed by `metadata.start_time + metadata.end_time`.
15
+ *
16
+ * Returns `null` when no meaningful data is present.
17
+ */
18
+ export function transformPulseOx(pulseOx: ClientDailySpo2Acclimation): SomaDaily | null {
19
+ const startMs = (pulseOx.startTimeInSeconds ?? 0) * 1000;
20
+ const endMs =
21
+ startMs + (pulseOx.durationInSeconds ?? 0) * 1000;
22
+
23
+ const oxygenData = buildOxygenData(pulseOx);
24
+
25
+ if (oxygenData == null) {
26
+ return null;
27
+ }
28
+
29
+ return {
30
+ metadata: {
31
+ start_time: new Date(startMs).toISOString(),
32
+ end_time: new Date(endMs).toISOString(),
33
+ upload_type: 1, // Automatic
34
+ },
35
+
36
+ oxygen_data: oxygenData,
37
+ };
38
+ }
39
+
40
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
41
+
42
+ function buildOxygenData(pulseOx: ClientDailySpo2Acclimation) {
43
+ const hasSamples =
44
+ pulseOx.timeOffsetSpo2Values != null &&
45
+ Object.keys(pulseOx.timeOffsetSpo2Values).length > 0;
46
+
47
+ if (!hasSamples) {
48
+ return undefined;
49
+ }
50
+
51
+ const startTime = pulseOx.startTimeInSeconds ?? 0;
52
+ const samples = Object.entries(pulseOx.timeOffsetSpo2Values ?? {}).map(
53
+ ([offset, percentage]) => ({
54
+ timestamp: new Date(
55
+ (startTime + parseInt(offset, 10)) * 1000,
56
+ ).toISOString(),
57
+ percentage,
58
+ }),
59
+ );
60
+
61
+ return {
62
+ saturation_samples: samples.length > 0 ? samples : undefined,
63
+ };
64
+ }
@@ -0,0 +1,73 @@
1
+ // ─── Respiration Transformer ─────────────────────────────────────────────────
2
+ // Transforms a Garmin Respiration push item into the Soma Daily schema shape.
3
+ //
4
+ // Respiration summaries contain breathing rate readings throughout the day.
5
+ // We map these into the Daily model's respiration_data field.
6
+
7
+ import type { SomaDaily } from "../../validators/daily.js";
8
+ import type { ClientRespiration } from "../types/wellnessApi/types.gen.js";
9
+
10
+ /**
11
+ * Transform a Garmin Respiration push item into a Soma Daily document shape.
12
+ *
13
+ * Respiration summaries are ingested into the `daily` table via `ingestDaily`,
14
+ * keyed by `metadata.start_time + metadata.end_time`.
15
+ *
16
+ * Returns `null` when no meaningful data is present.
17
+ */
18
+ export function transformRespiration(resp: ClientRespiration): SomaDaily | null {
19
+ const startMs = (resp.startTimeInSeconds ?? 0) * 1000;
20
+ const endMs =
21
+ startMs + (resp.durationInSeconds ?? 0) * 1000;
22
+
23
+ const respirationData = buildRespirationData(resp);
24
+
25
+ if (respirationData == null) {
26
+ return null;
27
+ }
28
+
29
+ return {
30
+ metadata: {
31
+ start_time: new Date(startMs).toISOString(),
32
+ end_time: new Date(endMs).toISOString(),
33
+ upload_type: 1, // Automatic
34
+ },
35
+
36
+ respiration_data: respirationData,
37
+ };
38
+ }
39
+
40
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
41
+
42
+ function buildRespirationData(resp: ClientRespiration) {
43
+ const hasSamples =
44
+ resp.timeOffsetEpochToBreaths != null &&
45
+ Object.keys(resp.timeOffsetEpochToBreaths).length > 0;
46
+
47
+ if (!hasSamples) {
48
+ return undefined;
49
+ }
50
+
51
+ const startTime = resp.startTimeInSeconds ?? 0;
52
+ const samples = Object.entries(resp.timeOffsetEpochToBreaths ?? {}).map(
53
+ ([offset, breaths_per_min]) => ({
54
+ timestamp: new Date(
55
+ (startTime + parseInt(offset, 10)) * 1000,
56
+ ).toISOString(),
57
+ breaths_per_min,
58
+ }),
59
+ );
60
+
61
+ // Compute summary stats from samples
62
+ const values = samples.map((s) => s.breaths_per_min);
63
+ const avg = values.reduce((sum, v) => sum + v, 0) / values.length;
64
+
65
+ return {
66
+ breaths_data: {
67
+ avg_breaths_per_min: Math.round(avg * 10) / 10,
68
+ min_breaths_per_min: Math.min(...values),
69
+ max_breaths_per_min: Math.max(...values),
70
+ samples: samples.length > 0 ? samples : undefined,
71
+ },
72
+ };
73
+ }
@@ -0,0 +1,44 @@
1
+ // ─── Skin Temperature Transformer ────────────────────────────────────────────
2
+ // Transforms a Garmin Skin Temperature push item into the Soma Body schema shape.
3
+ //
4
+ // Skin temperature summaries contain the average deviation of the user's
5
+ // skin temperature during their sleep window. We map this into the Body
6
+ // model's temperature_data.skin_temperature_samples field.
7
+
8
+ import type { SomaBody } from "../../validators/body.js";
9
+ import type { ClientSkinTemp } from "../types/wellnessApi/types.gen.js";
10
+
11
+ /**
12
+ * Transform a Garmin Skin Temperature push item into a Soma Body document shape.
13
+ *
14
+ * Skin temperature records are ingested into the `body` table via `ingestBody`,
15
+ * keyed by `metadata.start_time + metadata.end_time`.
16
+ *
17
+ * Returns `null` when no meaningful temperature data is present.
18
+ */
19
+ export function transformSkinTemperature(skinTemp: ClientSkinTemp): SomaBody | null {
20
+ const startMs = (skinTemp.startTimeInSeconds ?? 0) * 1000;
21
+ const endMs = startMs + (skinTemp.durationInSeconds ?? 0) * 1000;
22
+ const startTime = new Date(startMs).toISOString();
23
+ const endTime = new Date(endMs).toISOString();
24
+
25
+ if (skinTemp.avgDeviationCelsius == null) {
26
+ return null;
27
+ }
28
+
29
+ return {
30
+ metadata: {
31
+ start_time: startTime,
32
+ end_time: endTime,
33
+ },
34
+
35
+ temperature_data: {
36
+ skin_temperature_samples: [
37
+ {
38
+ timestamp: startTime,
39
+ temperature_celsius: skinTemp.avgDeviationCelsius,
40
+ },
41
+ ],
42
+ },
43
+ };
44
+ }
@@ -0,0 +1,159 @@
1
+ // ─── Sleeps Transformer ──────────────────────────────────────────────────────
2
+ // Transforms a Garmin sleep summary push item into the Soma Sleep schema shape.
3
+
4
+ import { mapSleepLevel } from "./maps/sleepLevel.js";
5
+ import type { ClientSleep } from "../types/wellnessApi/types.gen.js";
6
+
7
+ type TimeRange = {
8
+ startTimeInSeconds?: number;
9
+ endTimeInSeconds?: number;
10
+ };
11
+
12
+ /**
13
+ * Transform a Garmin sleep summary push item into a Soma Sleep document shape.
14
+ *
15
+ * Sleep summaries are ingested into the `sleep` table via `ingestSleep`,
16
+ * keyed by `metadata.summary_id`.
17
+ *
18
+ * The returned object is ready to be spread into an `ingestSleep` call
19
+ * alongside `connectionId` and `userId`.
20
+ */
21
+ export function transformSleeps(sleep: ClientSleep) {
22
+ const startMs = (sleep.startTimeInSeconds ?? 0) * 1000;
23
+ const endMs =
24
+ startMs +
25
+ ((sleep.durationInSeconds ?? 0) + (sleep.awakeDurationInSeconds ?? 0)) *
26
+ 1000;
27
+
28
+ const uploadTypeMap: Record<string, number> = {
29
+ ENHANCED_FINAL: 2,
30
+ ENHANCED_TENTATIVE: 4,
31
+ AUTO_FINAL: 2,
32
+ AUTO_TENTATIVE: 4,
33
+ AUTO_MANUAL: 2,
34
+ MANUAL: 1,
35
+ DEVICE: 2,
36
+ OFF_WRIST: 0,
37
+ };
38
+
39
+ return {
40
+ metadata: {
41
+ summary_id: sleep.summaryId,
42
+ start_time: new Date(startMs).toISOString(),
43
+ end_time: new Date(endMs).toISOString(),
44
+ upload_type: uploadTypeMap[sleep.validation ?? ""] ?? 0,
45
+ },
46
+
47
+ sleep_durations_data: buildSleepDurationsData(sleep),
48
+
49
+ respiration_data: buildRespirationData(sleep),
50
+
51
+ scores: buildScoresData(sleep),
52
+ };
53
+ }
54
+
55
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
56
+
57
+ function buildSleepDurationsData(sleep: ClientSleep) {
58
+ const totalAsleep =
59
+ (sleep.deepSleepDurationInSeconds ?? 0) +
60
+ (sleep.lightSleepDurationInSeconds ?? 0) +
61
+ (sleep.remSleepInSeconds ?? 0);
62
+
63
+ return {
64
+ asleep: {
65
+ duration_asleep_state_seconds: totalAsleep || undefined,
66
+ duration_deep_sleep_state_seconds: sleep.deepSleepDurationInSeconds,
67
+ duration_light_sleep_state_seconds: sleep.lightSleepDurationInSeconds,
68
+ duration_REM_sleep_state_seconds: sleep.remSleepInSeconds,
69
+ },
70
+ awake: {
71
+ duration_awake_state_seconds: sleep.awakeDurationInSeconds,
72
+ },
73
+ other: {
74
+ duration_in_bed_seconds: sleep.durationInSeconds,
75
+ duration_unmeasurable_sleep_seconds: sleep.unmeasurableSleepInSeconds,
76
+ },
77
+ hypnogram_samples: buildHypnogramSamples(sleep),
78
+ };
79
+ }
80
+
81
+ function buildHypnogramSamples(sleep: ClientSleep) {
82
+ if (!sleep.sleepLevelsMap) return undefined;
83
+
84
+ const samples: Array<{ timestamp: string; level: number }> = [];
85
+
86
+ for (const [stage, levels] of Object.entries(sleep.sleepLevelsMap)) {
87
+ if (!levels) continue;
88
+ const terraLevel = mapSleepLevel(stage);
89
+
90
+ for (const level of levels as TimeRange[]) {
91
+ if (level.startTimeInSeconds == null) continue;
92
+ samples.push({
93
+ timestamp: new Date(level.startTimeInSeconds * 1000).toISOString(),
94
+ level: terraLevel,
95
+ });
96
+ }
97
+ }
98
+
99
+ samples.sort(
100
+ (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime(),
101
+ );
102
+
103
+ return samples.length > 0 ? samples : undefined;
104
+ }
105
+
106
+ function buildRespirationData(sleep: ClientSleep) {
107
+ const hasBreathSamples =
108
+ sleep.timeOffsetSleepRespiration != null &&
109
+ Object.keys(sleep.timeOffsetSleepRespiration).length > 0;
110
+ const hasSpO2Samples =
111
+ sleep.timeOffsetSleepSpo2 != null &&
112
+ Object.keys(sleep.timeOffsetSleepSpo2).length > 0;
113
+
114
+ if (!hasBreathSamples && !hasSpO2Samples) {
115
+ return undefined;
116
+ }
117
+
118
+ const startTime = sleep.startTimeInSeconds ?? 0;
119
+
120
+ const breathSamples = hasBreathSamples
121
+ ? Object.entries(sleep.timeOffsetSleepRespiration ?? {}).map(
122
+ ([offset, rate]) => ({
123
+ timestamp: new Date(
124
+ (startTime + parseInt(offset, 10)) * 1000,
125
+ ).toISOString(),
126
+ breaths_per_min: rate,
127
+ }),
128
+ )
129
+ : undefined;
130
+
131
+ const spo2Samples = hasSpO2Samples
132
+ ? Object.entries(sleep.timeOffsetSleepSpo2 ?? {}).map(([offset, pct]) => ({
133
+ timestamp: new Date(
134
+ (startTime + parseInt(offset, 10)) * 1000,
135
+ ).toISOString(),
136
+ percentage: pct,
137
+ }))
138
+ : undefined;
139
+
140
+ return {
141
+ breaths_data:
142
+ breathSamples && breathSamples.length > 0
143
+ ? { samples: breathSamples }
144
+ : undefined,
145
+ oxygen_saturation_data:
146
+ spo2Samples && spo2Samples.length > 0
147
+ ? { samples: spo2Samples }
148
+ : undefined,
149
+ };
150
+ }
151
+
152
+ function buildScoresData(sleep: ClientSleep) {
153
+ const overallScore = sleep.overallSleepScore?.value;
154
+ if (overallScore == null) return undefined;
155
+
156
+ return {
157
+ sleep: overallScore,
158
+ };
159
+ }
@@ -0,0 +1,78 @@
1
+ // ─── Stress Details Transformer ──────────────────────────────────────────────
2
+ // Transforms a Garmin Stress Details push item into the Soma Daily schema shape.
3
+ //
4
+ // Stress details summaries contain 3-minute stress level averages and body
5
+ // battery values throughout the day. We map these into the Daily model's
6
+ // stress_data field.
7
+
8
+ import type { SomaDaily } from "../../validators/daily.js";
9
+ import type { ClientStress } from "../types/wellnessApi/types.gen.js";
10
+
11
+ /**
12
+ * Transform a Garmin Stress Details push item into a Soma Daily document shape.
13
+ *
14
+ * Stress records are ingested into the `daily` table via `ingestDaily`,
15
+ * keyed by `metadata.start_time + metadata.end_time`.
16
+ *
17
+ * Returns `null` when no meaningful stress data is present.
18
+ */
19
+ export function transformStress(stress: ClientStress): SomaDaily | null {
20
+ const hasSummary =
21
+ stress.averageStressLevel != null || stress.maxStressLevel != null;
22
+ const hasStressSamples =
23
+ stress.timeOffsetStressLevelValues != null &&
24
+ Object.keys(stress.timeOffsetStressLevelValues).length > 0;
25
+ const hasBodyBatterySamples =
26
+ stress.timeOffsetBodyBatteryValues != null &&
27
+ Object.keys(stress.timeOffsetBodyBatteryValues).length > 0;
28
+
29
+ if (!hasSummary && !hasStressSamples && !hasBodyBatterySamples) {
30
+ return null;
31
+ }
32
+
33
+ const startSeconds = stress.startTimeInSeconds ?? 0;
34
+ const durationSeconds = stress.durationInSeconds ?? 86400;
35
+ const startTime = new Date(startSeconds * 1000).toISOString();
36
+ const endTime = new Date((startSeconds + durationSeconds) * 1000).toISOString();
37
+
38
+ const stressSamples = hasStressSamples
39
+ ? Object.entries(stress.timeOffsetStressLevelValues ?? {}).map(
40
+ ([offset, level]) => ({
41
+ timestamp: new Date(
42
+ (startSeconds + parseInt(offset, 10)) * 1000,
43
+ ).toISOString(),
44
+ level,
45
+ }),
46
+ )
47
+ : undefined;
48
+
49
+ const bodyBatterySamples = hasBodyBatterySamples
50
+ ? Object.entries(stress.timeOffsetBodyBatteryValues ?? {}).map(
51
+ ([offset, level]) => ({
52
+ timestamp: new Date(
53
+ (startSeconds + parseInt(offset, 10)) * 1000,
54
+ ).toISOString(),
55
+ level,
56
+ }),
57
+ )
58
+ : undefined;
59
+
60
+ return {
61
+ metadata: {
62
+ start_time: startTime,
63
+ end_time: endTime,
64
+ upload_type: 1,
65
+ },
66
+
67
+ stress_data: {
68
+ avg_stress_level: stress.averageStressLevel,
69
+ max_stress_level: stress.maxStressLevel,
70
+ samples:
71
+ stressSamples && stressSamples.length > 0 ? stressSamples : undefined,
72
+ body_battery_samples:
73
+ bodyBatterySamples && bodyBatterySamples.length > 0
74
+ ? bodyBatterySamples
75
+ : undefined,
76
+ },
77
+ };
78
+ }
@@ -0,0 +1,56 @@
1
+ // ─── User Metrics Transformer ────────────────────────────────────────────────
2
+ // Transforms a Garmin User Metrics push item into the Soma Body schema shape.
3
+ //
4
+ // User Metrics summaries contain VO2 Max, VO2 Max Cycling, fitness age, and
5
+ // an enhanced flag. We map these into the Body model's oxygen_data and
6
+ // measurements_data fields.
7
+
8
+ import type { SomaBody } from "../../validators/body.js";
9
+ import type { ClientUserMetrics } from "../types/wellnessApi/types.gen.js";
10
+
11
+ /**
12
+ * Transform a Garmin User Metrics push item into a Soma Body document shape.
13
+ *
14
+ * User metrics records are ingested into the `body` table via `ingestBody`,
15
+ * keyed by `metadata.start_time + metadata.end_time`.
16
+ *
17
+ * Returns `null` when no meaningful metrics data is present.
18
+ */
19
+ export function transformUserMetrics(metrics: ClientUserMetrics): SomaBody | null {
20
+ const dateStr = metrics.calendarDate;
21
+ const startTime = dateStr
22
+ ? `${dateStr}T00:00:00.000Z`
23
+ : new Date(0).toISOString();
24
+ const endTime = dateStr
25
+ ? `${dateStr}T23:59:59.999Z`
26
+ : new Date(0).toISOString();
27
+
28
+ const hasVo2 = metrics.vo2Max != null || metrics.vo2MaxCycling != null;
29
+ const hasFitnessAge = metrics.fitnessAge != null;
30
+
31
+ if (!hasVo2 && !hasFitnessAge) {
32
+ return null;
33
+ }
34
+
35
+ return {
36
+ metadata: {
37
+ start_time: startTime,
38
+ end_time: endTime,
39
+ },
40
+
41
+ oxygen_data: hasVo2
42
+ ? { vo2max_ml_per_min_per_kg: metrics.vo2Max ?? metrics.vo2MaxCycling }
43
+ : undefined,
44
+
45
+ measurements_data: hasFitnessAge
46
+ ? {
47
+ measurements: [
48
+ {
49
+ measurement_time: startTime,
50
+ estimated_fitness_age: String(metrics.fitnessAge),
51
+ },
52
+ ],
53
+ }
54
+ : undefined,
55
+ };
56
+ }