@tryterra/react-native 2.1.0 → 2.2.1

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 (59) hide show
  1. package/README.md +31 -0
  2. package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/Conversions.kt +103 -14
  3. package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/ReadConversions.kt +250 -0
  4. package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridgeOpsImpl.kt +47 -5
  5. package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridgeStreamsImpl.kt +1 -3
  6. package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeOps.kt +89 -0
  7. package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeTypes.kt +672 -0
  8. package/docs/availability.md +154 -4
  9. package/frameworks/TerraSDK.xcframework/Info.plist +5 -5
  10. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Info.plist +0 -0
  11. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.abi.json +1385 -226
  12. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.package.swiftinterface +37 -1
  13. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +37 -1
  14. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  15. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.swiftinterface +37 -1
  16. package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/TerraSDK +0 -0
  17. package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Info.plist +2 -2
  18. package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/DWARF/TerraSDK +0 -0
  19. package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/TerraSDK.yml +6589 -6468
  20. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Info.plist +0 -0
  21. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +1385 -226
  22. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.package.swiftinterface +37 -1
  23. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +37 -1
  24. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  25. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +37 -1
  26. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +1385 -226
  27. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.package.swiftinterface +37 -1
  28. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +37 -1
  29. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  30. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +37 -1
  31. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/TerraSDK +0 -0
  32. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/_CodeSignature/CodeResources +21 -21
  33. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Info.plist +2 -2
  34. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/DWARF/TerraSDK +0 -0
  35. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/TerraSDK.yml +6590 -6469
  36. package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/TerraSDK.yml +6508 -6387
  37. package/ios/TerraBridgeCore/Conversions+Reads.swift +259 -0
  38. package/ios/TerraBridgeCore/Conversions.swift +129 -2
  39. package/ios/TerraBridgeCore/Generated/BridgeOps.swift +172 -0
  40. package/ios/TerraBridgeCore/Generated/BridgeTypes.swift +734 -1
  41. package/ios/TerraBridgeCore/TerraBridgeOpsImpl.swift +64 -0
  42. package/lib/Terra.d.ts +74 -5
  43. package/lib/Terra.js +69 -13
  44. package/lib/generated/client.d.ts +37 -1
  45. package/lib/generated/client.js +60 -0
  46. package/lib/generated/codecs.d.ts +85 -1
  47. package/lib/generated/codecs.js +710 -2
  48. package/lib/generated/ops.d.ts +1 -1
  49. package/lib/generated/ops.js +24 -0
  50. package/lib/generated/types.d.ts +314 -1
  51. package/lib/generated/types.js +133 -1
  52. package/lib/index.d.ts +1 -1
  53. package/package.json +3 -3
  54. package/src/Terra.ts +146 -16
  55. package/src/generated/client.ts +74 -2
  56. package/src/generated/codecs.ts +705 -3
  57. package/src/generated/ops.ts +36 -0
  58. package/src/generated/types.ts +556 -1
  59. package/src/index.ts +2 -0
@@ -68,6 +68,19 @@ public enum class DataCategory {
68
68
  SLEEP,
69
69
  @SerialName("nutrition")
70
70
  NUTRITION,
71
+ /**
72
+ * Read-only on both platforms: menstruation.flow reads it and neither SDK has a write route
73
+ * for it.
74
+ */
75
+ @SerialName("menstruation")
76
+ MENSTRUATION,
77
+ /**
78
+ * HealthKit's characteristics; Health Connect has no counterpart.
79
+ *
80
+ * Available on ios only.
81
+ */
82
+ @SerialName("athlete")
83
+ ATHLETE,
71
84
  }
72
85
 
73
86
  @Serializable
@@ -105,6 +118,159 @@ public enum class MotionContext {
105
118
  ACTIVE,
106
119
  }
107
120
 
121
+ /**
122
+ * On both platforms, wire names strip HKQuantityTypeIdentifierDietary from HealthKit
123
+ * identifiers and lowercase the first letter. Units: kcal for energyConsumed; grams for
124
+ * protein, carbohydrates, the four fats, sugar and fiber; milligrams for everything else,
125
+ * never micrograms.
126
+ */
127
+ @Serializable
128
+ public enum class Nutrient {
129
+ @SerialName("energyConsumed")
130
+ ENERGY_CONSUMED,
131
+ @SerialName("protein")
132
+ PROTEIN,
133
+ @SerialName("carbohydrates")
134
+ CARBOHYDRATES,
135
+ @SerialName("fatTotal")
136
+ FAT_TOTAL,
137
+ @SerialName("fatSaturated")
138
+ FAT_SATURATED,
139
+ @SerialName("fatMonounsaturated")
140
+ FAT_MONOUNSATURATED,
141
+ @SerialName("fatPolyunsaturated")
142
+ FAT_POLYUNSATURATED,
143
+ @SerialName("sugar")
144
+ SUGAR,
145
+ @SerialName("fiber")
146
+ FIBER,
147
+ @SerialName("cholesterol")
148
+ CHOLESTEROL,
149
+ @SerialName("sodium")
150
+ SODIUM,
151
+ @SerialName("potassium")
152
+ POTASSIUM,
153
+ @SerialName("calcium")
154
+ CALCIUM,
155
+ @SerialName("iron")
156
+ IRON,
157
+ @SerialName("magnesium")
158
+ MAGNESIUM,
159
+ @SerialName("zinc")
160
+ ZINC,
161
+ @SerialName("phosphorus")
162
+ PHOSPHORUS,
163
+ @SerialName("iodine")
164
+ IODINE,
165
+ @SerialName("manganese")
166
+ MANGANESE,
167
+ @SerialName("molybdenum")
168
+ MOLYBDENUM,
169
+ @SerialName("selenium")
170
+ SELENIUM,
171
+ @SerialName("copper")
172
+ COPPER,
173
+ @SerialName("chromium")
174
+ CHROMIUM,
175
+ @SerialName("chloride")
176
+ CHLORIDE,
177
+ @SerialName("caffeine")
178
+ CAFFEINE,
179
+ @SerialName("vitaminA")
180
+ VITAMIN_A,
181
+ @SerialName("vitaminC")
182
+ VITAMIN_C,
183
+ @SerialName("vitaminD")
184
+ VITAMIN_D,
185
+ @SerialName("vitaminE")
186
+ VITAMIN_E,
187
+ @SerialName("vitaminK")
188
+ VITAMIN_K,
189
+ @SerialName("vitaminB6")
190
+ VITAMIN_B6,
191
+ @SerialName("vitaminB12")
192
+ VITAMIN_B12,
193
+ @SerialName("thiamin")
194
+ THIAMIN,
195
+ @SerialName("riboflavin")
196
+ RIBOFLAVIN,
197
+ @SerialName("niacin")
198
+ NIACIN,
199
+ @SerialName("folate")
200
+ FOLATE,
201
+ @SerialName("biotin")
202
+ BIOTIN,
203
+ @SerialName("pantothenicAcid")
204
+ PANTOTHENIC_ACID,
205
+ }
206
+
207
+ /**
208
+ * Which meal a quantity was logged against. unknown is the store's explicit answer, not an
209
+ * absence: HealthKit has no meal type at all, so every iOS quantity is unknown.
210
+ */
211
+ @Serializable
212
+ public enum class MealType {
213
+ @SerialName("breakfast")
214
+ BREAKFAST,
215
+ @SerialName("lunch")
216
+ LUNCH,
217
+ @SerialName("dinner")
218
+ DINNER,
219
+ @SerialName("snack")
220
+ SNACK,
221
+ @SerialName("unknown")
222
+ UNKNOWN,
223
+ }
224
+
225
+ /** How heavy a logged day's flow was. */
226
+ @Serializable
227
+ public enum class MenstruationFlow {
228
+ @SerialName("unspecified")
229
+ UNSPECIFIED,
230
+ @SerialName("light")
231
+ LIGHT,
232
+ @SerialName("medium")
233
+ MEDIUM,
234
+ @SerialName("heavy")
235
+ HEAVY,
236
+ /**
237
+ * noFlow avoids ambiguity with Optional.none. Health Connect has no constant for it, so
238
+ * Android never produces it.
239
+ */
240
+ @SerialName("none")
241
+ NO_FLOW,
242
+ }
243
+
244
+ /** Available on ios only. */
245
+ @Serializable
246
+ public enum class BiologicalSex {
247
+ @SerialName("female")
248
+ FEMALE,
249
+ @SerialName("male")
250
+ MALE,
251
+ @SerialName("other")
252
+ OTHER,
253
+ /**
254
+ * The characteristic exists and holds no value, or reading it failed. The store's explicit
255
+ * unknown.
256
+ */
257
+ @SerialName("notSet")
258
+ NOT_SET,
259
+ }
260
+
261
+ /**
262
+ * A move-time user's daily totals are minutes rather than active energy.
263
+ *
264
+ * Available on ios only.
265
+ */
266
+ @Serializable
267
+ public enum class ActivityMoveMode {
268
+ @SerialName("activeEnergy")
269
+ ACTIVE_ENERGY,
270
+ @SerialName("appleMoveTime")
271
+ APPLE_MOVE_TIME,
272
+ }
273
+
108
274
  /**
109
275
  * Why background delivery is restricted. Android discloses which; Apple reports the state
110
276
  * without a reason.
@@ -254,6 +420,179 @@ public enum class WorkoutSchedulingStatus {
254
420
  AUTHORIZED,
255
421
  }
256
422
 
423
+ /**
424
+ * distance* are metres, *EnergyBurned kilocalories, flightsClimbed a count, and
425
+ * appleExerciseTime minutes.
426
+ */
427
+ @Serializable
428
+ public enum class DayTotalMetric {
429
+ @SerialName("distanceWalkingRunning")
430
+ DISTANCE_WALKING_RUNNING,
431
+ /** Health Connect does not split distance by activity, so only Apple ever answers it. */
432
+ @SerialName("distanceCycling")
433
+ DISTANCE_CYCLING,
434
+ @SerialName("distanceSwimming")
435
+ DISTANCE_SWIMMING,
436
+ @SerialName("distanceWheelchair")
437
+ DISTANCE_WHEELCHAIR,
438
+ @SerialName("activeEnergyBurned")
439
+ ACTIVE_ENERGY_BURNED,
440
+ @SerialName("basalEnergyBurned")
441
+ BASAL_ENERGY_BURNED,
442
+ @SerialName("flightsClimbed")
443
+ FLIGHTS_CLIMBED,
444
+ /**
445
+ * The exercise ring, in minutes. Health Connect has no such figure: summing session durations
446
+ * is a different number.
447
+ *
448
+ * Available on ios only.
449
+ */
450
+ @SerialName("appleExerciseTime")
451
+ APPLE_EXERCISE_TIME,
452
+ }
453
+
454
+ /** activeEnergy and basalEnergy are kilocalories, distance metres, floorsClimbed a count. */
455
+ @Serializable
456
+ public enum class IntradayMetric {
457
+ @SerialName("activeEnergy")
458
+ ACTIVE_ENERGY,
459
+ /**
460
+ * Health Connect has no basal energy record; its basal metabolic rate is a body measurement
461
+ * and is not this.
462
+ *
463
+ * Available on ios only.
464
+ */
465
+ @SerialName("basalEnergy")
466
+ BASAL_ENERGY,
467
+ @SerialName("distance")
468
+ DISTANCE,
469
+ @SerialName("floorsClimbed")
470
+ FLOORS_CLIMBED,
471
+ }
472
+
473
+ /** speed is metres per second, power watts, cadence pedal revolutions per minute. */
474
+ @Serializable
475
+ public enum class WorkoutIntensityMetric {
476
+ @SerialName("speed")
477
+ SPEED,
478
+ @SerialName("power")
479
+ POWER,
480
+ @SerialName("cadence")
481
+ CADENCE,
482
+ }
483
+
484
+ /**
485
+ * The body composition figure a measurement carries. weight and leanBodyMass are kilograms,
486
+ * height centimetres, bodyFatPercentage a fraction in 0..1, bmi dimensionless.
487
+ */
488
+ @Serializable
489
+ public enum class BodyMetric {
490
+ @SerialName("weight")
491
+ WEIGHT,
492
+ @SerialName("height")
493
+ HEIGHT,
494
+ @SerialName("bodyFatPercentage")
495
+ BODY_FAT_PERCENTAGE,
496
+ @SerialName("leanBodyMass")
497
+ LEAN_BODY_MASS,
498
+ /**
499
+ * Health Connect has no BMI record.
500
+ *
501
+ * Available on ios only.
502
+ */
503
+ @SerialName("bmi")
504
+ BMI,
505
+ }
506
+
507
+ /** The unit the writing app chose. Never converted on the device. */
508
+ @Serializable
509
+ public enum class BloodGlucoseUnit {
510
+ @SerialName("mg/dL")
511
+ MILLIGRAMS_PER_DECILITRE,
512
+ @SerialName("mmol/L")
513
+ MILLIMOLES_PER_LITRE,
514
+ }
515
+
516
+ /** unknown is the store saying nothing about the meal, distinct from absent. */
517
+ @Serializable
518
+ public enum class GlucoseMealTime {
519
+ @SerialName("preprandial")
520
+ PREPRANDIAL,
521
+ @SerialName("postprandial")
522
+ POSTPRANDIAL,
523
+ @SerialName("unknown")
524
+ UNKNOWN,
525
+ }
526
+
527
+ /** interstitial is a continuous monitor. */
528
+ @Serializable
529
+ public enum class GlucoseSpecimen {
530
+ @SerialName("capillary")
531
+ CAPILLARY,
532
+ @SerialName("interstitial")
533
+ INTERSTITIAL,
534
+ @SerialName("plasma")
535
+ PLASMA,
536
+ @SerialName("serum")
537
+ SERUM,
538
+ @SerialName("tears")
539
+ TEARS,
540
+ @SerialName("wholeBlood")
541
+ WHOLE_BLOOD,
542
+ @SerialName("unknown")
543
+ UNKNOWN,
544
+ }
545
+
546
+ /**
547
+ * body and basal are absolute; wrist and skin are deltas from a baseline and routinely
548
+ * negative.
549
+ */
550
+ @Serializable
551
+ public enum class BodyTemperatureMetric {
552
+ @SerialName("body")
553
+ BODY,
554
+ @SerialName("basal")
555
+ BASAL,
556
+ /**
557
+ * HealthKit's sleeping wrist temperature. Health Connect has no such record.
558
+ *
559
+ * Available on ios only.
560
+ */
561
+ @SerialName("wrist")
562
+ WRIST,
563
+ @SerialName("skin")
564
+ SKIN,
565
+ }
566
+
567
+ /** HealthKit records SDNN only and Health Connect RMSSD only; they are never one series. */
568
+ @Serializable
569
+ public enum class HeartRateVariabilityMetric {
570
+ @SerialName("sdnn")
571
+ SDNN,
572
+ @SerialName("rmssd")
573
+ RMSSD,
574
+ }
575
+
576
+ @Serializable
577
+ public enum class VO2MaxTestType {
578
+ @SerialName("maxExercise")
579
+ MAX_EXERCISE,
580
+ @SerialName("predictedSubMaxExercise")
581
+ PREDICTED_SUB_MAX_EXERCISE,
582
+ @SerialName("predictedNonExercise")
583
+ PREDICTED_NON_EXERCISE,
584
+ }
585
+
586
+ @Serializable
587
+ public enum class MenstrualEventKind {
588
+ @SerialName("intermenstrualBleeding")
589
+ INTERMENSTRUAL_BLEEDING,
590
+ @SerialName("ovulationTest")
591
+ OVULATION_TEST,
592
+ @SerialName("cervicalMucus")
593
+ CERVICAL_MUCUS,
594
+ }
595
+
257
596
  /**
258
597
  * The person a connect is for. A stored link is restored only for the person it was made for;
259
598
  * anybody else gets a fresh link. Never sent to Terra as identity.
@@ -405,6 +744,102 @@ public sealed interface StreamMessage {
405
744
  public data object Complete : StreamMessage
406
745
  }
407
746
 
747
+ /**
748
+ * What a BodyReading measured, with the unit fixed by the variant. Blood glucose alone keeps
749
+ * the writer's unit.
750
+ */
751
+ @Serializable
752
+ @OptIn(ExperimentalSerializationApi::class)
753
+ @JsonClassDiscriminator("type")
754
+ public sealed interface BodyReadingKind {
755
+ @Serializable
756
+ @SerialName("measurement")
757
+ public data class Measurement(public val metric: BodyMetric, public val value: Double) : BodyReadingKind
758
+ /** Millimetres of mercury, both halves of one reading. */
759
+ @Serializable
760
+ @SerialName("bloodPressure")
761
+ public data class BloodPressure(public val systolic: Double, public val diastolic: Double) : BodyReadingKind
762
+ @Serializable
763
+ @SerialName("bloodGlucose")
764
+ public data class BloodGlucose(public val value: Double, public val unit: BloodGlucoseUnit, public val mealTime: GlucoseMealTime? = null, public val specimen: GlucoseSpecimen? = null) : BodyReadingKind
765
+ /** A fraction in 0..1, never a number out of a hundred. */
766
+ @Serializable
767
+ @SerialName("oxygenSaturation")
768
+ public data class OxygenSaturation(public val fraction: Double) : BodyReadingKind
769
+ @Serializable
770
+ @SerialName("temperature")
771
+ public data class Temperature(public val metric: BodyTemperatureMetric, public val celsius: Double) : BodyReadingKind
772
+ @Serializable
773
+ @SerialName("heartRateVariability")
774
+ public data class HeartRateVariability(public val metric: HeartRateVariabilityMetric, public val milliseconds: Double) : BodyReadingKind
775
+ @Serializable
776
+ @SerialName("respiratoryRate")
777
+ public data class RespiratoryRate(public val breathsPerMinute: Double) : BodyReadingKind
778
+ /** Millilitres of oxygen per kilogram per minute. */
779
+ @Serializable
780
+ @SerialName("vo2Max")
781
+ public data class Vo2Max(public val millilitresPerKilogramMinute: Double, public val testType: VO2MaxTestType? = null) : BodyReadingKind
782
+ }
783
+
784
+ /**
785
+ * Apple's store is part of the OS, so it is there or the device cannot have it; Health Connect
786
+ * is an app a person can lack.
787
+ */
788
+ @Serializable
789
+ @OptIn(ExperimentalSerializationApi::class)
790
+ @JsonClassDiscriminator("kind")
791
+ public sealed interface StoreAvailability {
792
+ @Serializable
793
+ @SerialName("available")
794
+ public data object Available : StoreAvailability
795
+ /**
796
+ * No HealthKit on this device: an iPad before iPadOS 17, or a Mac.
797
+ *
798
+ * Available on ios only.
799
+ */
800
+ @Serializable
801
+ @SerialName("unsupportedDevice")
802
+ public data object UnsupportedDevice : StoreAvailability
803
+ /**
804
+ * No Health Connect on Android 13 or below, or no Samsung Health. A Play Store link fixes the
805
+ * first.
806
+ *
807
+ * Available on android only.
808
+ */
809
+ @Serializable
810
+ @SerialName("providerAppMissing")
811
+ public data object ProviderAppMissing : StoreAvailability
812
+ /** Available on android only. */
813
+ @Serializable
814
+ @SerialName("providerAppTooOld")
815
+ public data class ProviderAppTooOld(public val installed: String) : StoreAvailability
816
+ /**
817
+ * The source's add-on artifact is not in the app.
818
+ *
819
+ * Available on android only.
820
+ */
821
+ @Serializable
822
+ @SerialName("moduleMissing")
823
+ public data object ModuleMissing : StoreAvailability
824
+ /**
825
+ * The store's partner policy covers none of the record types. Which ones is in the native
826
+ * report.
827
+ *
828
+ * Available on android only.
829
+ */
830
+ @Serializable
831
+ @SerialName("partnerPolicyMissing")
832
+ public data object PartnerPolicyMissing : StoreAvailability
833
+ /**
834
+ * The provider app lacks a feature the store needs. Which one is in the native report.
835
+ *
836
+ * Available on android only.
837
+ */
838
+ @Serializable
839
+ @SerialName("featureUnavailable")
840
+ public data object FeatureUnavailable : StoreAvailability
841
+ }
842
+
408
843
  public object DataCategorySetSerializer : KSerializer<List<DataCategory>> {
409
844
  private val list = ListSerializer(DataCategory.serializer())
410
845
  override val descriptor: SerialDescriptor = list.descriptor
@@ -497,6 +932,54 @@ public data class Workout(
497
932
  public val source: SampleSource,
498
933
  public val userEntered: Boolean,
499
934
  public val timeZone: String? = null,
935
+ /**
936
+ * ExerciseSessionRecord.title on Android; HKMetadataKeyWorkoutBrandName on Apple, which has no
937
+ * title field.
938
+ */
939
+ public val title: String? = null,
940
+ )
941
+
942
+ /** Quantities of one meal share foodCorrelationId. */
943
+ @Serializable
944
+ public data class DietaryQuantity(
945
+ public val id: String,
946
+ public val nutrient: Nutrient,
947
+ public val value: Double,
948
+ public val start: String,
949
+ public val end: String,
950
+ public val mealType: MealType,
951
+ public val name: String? = null,
952
+ /**
953
+ * HealthKit's food correlation, absent for a loose quantity. Always set on Android, where it
954
+ * is the NutritionRecord's id - the id nutrition.delete takes for a meal this app logged.
955
+ */
956
+ public val foodCorrelationId: String? = null,
957
+ public val source: SampleSource,
958
+ public val userEntered: Boolean,
959
+ public val timeZone: String? = null,
960
+ )
961
+
962
+ /** start and end are the local midnights of that day in timeZone. */
963
+ @Serializable
964
+ public data class MenstruationFlowDay(
965
+ public val id: String,
966
+ public val start: String,
967
+ public val end: String,
968
+ public val flow: MenstruationFlow,
969
+ public val cycleStart: Boolean,
970
+ public val source: SampleSource,
971
+ public val userEntered: Boolean,
972
+ public val timeZone: String? = null,
973
+ )
974
+
975
+ /** Available on ios only. */
976
+ @Serializable
977
+ public data class AthleteProfile(
978
+ public val biologicalSex: BiologicalSex? = null,
979
+ /** A calendar day, as HealthKit stores it, never an instant. */
980
+ public val dateOfBirth: String? = null,
981
+ public val wheelchairUse: Boolean? = null,
982
+ public val activityMoveMode: ActivityMoveMode? = null,
500
983
  )
501
984
 
502
985
  /** A day whose data changed. Carries no health value by construction. */
@@ -825,6 +1308,49 @@ public data class WorkoutList(
825
1308
  public val samples: List<Workout>,
826
1309
  )
827
1310
 
1311
+ @Serializable
1312
+ public data class DietaryQuantityList(
1313
+ public val samples: List<DietaryQuantity>,
1314
+ )
1315
+
1316
+ @Serializable
1317
+ public data class MenstruationFlowDayList(
1318
+ public val samples: List<MenstruationFlowDay>,
1319
+ )
1320
+
1321
+ /** A cycle event logged at an instant. */
1322
+ @Serializable
1323
+ public data class MenstrualEvent(
1324
+ public val id: String,
1325
+ public val kind: MenstrualEventKind,
1326
+ public val time: String,
1327
+ /**
1328
+ * ovulationTest: negative, positive, high, indeterminate or luteinizingHormoneSurge.
1329
+ * cervicalMucus: dry, sticky, creamy, watery, eggWhite or unusual. Absent for
1330
+ * intermenstrualBleeding, which is a flag.
1331
+ */
1332
+ public val value: String? = null,
1333
+ /**
1334
+ * The store's own record type, passed through: OvulationTestRecord on Android,
1335
+ * HKCategoryTypeIdentifierOvulationTestResult on Apple.
1336
+ */
1337
+ public val storeIdentifier: String,
1338
+ public val source: SampleSource,
1339
+ public val userEntered: Boolean,
1340
+ public val timeZone: String? = null,
1341
+ )
1342
+
1343
+ @Serializable
1344
+ public data class MenstrualEventList(
1345
+ public val samples: List<MenstrualEvent>,
1346
+ )
1347
+
1348
+ /** Available on ios only. */
1349
+ @Serializable
1350
+ public data class AthleteProfileResult(
1351
+ public val profile: AthleteProfile? = null,
1352
+ )
1353
+
828
1354
  /** Available on ios only. */
829
1355
  @Serializable
830
1356
  public data class PlannedWorkoutList(
@@ -876,6 +1402,152 @@ public data class NutritionEntryList(
876
1402
  public val entries: List<NutritionEntry>,
877
1403
  )
878
1404
 
1405
+ /**
1406
+ * The store's own total for one local day, from its statistics engine. start and end are that
1407
+ * day's midnights.
1408
+ */
1409
+ @Serializable
1410
+ public data class DayTotal(
1411
+ public val metric: DayTotalMetric,
1412
+ public val start: String,
1413
+ public val end: String,
1414
+ public val value: Double,
1415
+ public val unit: String,
1416
+ public val timeZone: String? = null,
1417
+ )
1418
+
1419
+ /**
1420
+ * One record a day total is made of, as the store holds it. A record crossing midnight is
1421
+ * whole.
1422
+ */
1423
+ @Serializable
1424
+ public data class IntradaySample(
1425
+ public val id: String,
1426
+ public val metric: IntradayMetric,
1427
+ public val start: String,
1428
+ public val end: String,
1429
+ public val value: Double,
1430
+ public val source: SampleSource,
1431
+ public val userEntered: Boolean,
1432
+ public val timeZone: String? = null,
1433
+ )
1434
+
1435
+ /** The store's own resting heart rate for a day, never derived from heart rate readings. */
1436
+ @Serializable
1437
+ public data class RestingHeartRateSample(
1438
+ public val id: String,
1439
+ public val start: String,
1440
+ public val end: String,
1441
+ public val beatsPerMinute: Double,
1442
+ public val source: SampleSource,
1443
+ public val userEntered: Boolean,
1444
+ public val timeZone: String? = null,
1445
+ )
1446
+
1447
+ /** A point reading has start equal to end; skin and wrist temperature span a stretch. */
1448
+ @Serializable
1449
+ public data class BodyReading(
1450
+ public val id: String,
1451
+ public val kind: BodyReadingKind,
1452
+ public val start: String,
1453
+ public val end: String,
1454
+ public val source: SampleSource,
1455
+ public val userEntered: Boolean,
1456
+ public val timeZone: String? = null,
1457
+ )
1458
+
1459
+ @Serializable
1460
+ public data class RoutePoint(
1461
+ public val time: String,
1462
+ public val latitude: Double,
1463
+ public val longitude: Double,
1464
+ )
1465
+
1466
+ /**
1467
+ * The GPS track a workout left, thinned to one point a second and at most 5,000 points. start
1468
+ * and end are the first and last point.
1469
+ */
1470
+ @Serializable
1471
+ public data class WorkoutRoute(
1472
+ public val id: String,
1473
+ public val workoutId: String,
1474
+ public val start: String,
1475
+ public val end: String,
1476
+ public val points: List<RoutePoint>,
1477
+ public val source: SampleSource,
1478
+ public val timeZone: String? = null,
1479
+ )
1480
+
1481
+ /** One speed, power or cadence reading. Android's are instants, so start equals end there. */
1482
+ @Serializable
1483
+ public data class WorkoutIntensitySample(
1484
+ public val id: String,
1485
+ public val metric: WorkoutIntensityMetric,
1486
+ /**
1487
+ * Set on Apple, where HealthKit stores a reading inside its workout. Health Connect stores
1488
+ * them free-standing, so Android leaves it absent rather than guessing by time.
1489
+ */
1490
+ public val workoutId: String? = null,
1491
+ public val start: String,
1492
+ public val end: String,
1493
+ public val value: Double,
1494
+ public val source: SampleSource,
1495
+ public val userEntered: Boolean,
1496
+ public val timeZone: String? = null,
1497
+ )
1498
+
1499
+ /** One drink, in millilitres. */
1500
+ @Serializable
1501
+ public data class HydrationSample(
1502
+ public val id: String,
1503
+ public val start: String,
1504
+ public val end: String,
1505
+ public val millilitres: Double,
1506
+ public val source: SampleSource,
1507
+ public val userEntered: Boolean,
1508
+ public val timeZone: String? = null,
1509
+ )
1510
+
1511
+ @Serializable
1512
+ public data class DayTotalList(
1513
+ public val totals: List<DayTotal>,
1514
+ )
1515
+
1516
+ @Serializable
1517
+ public data class IntradaySampleList(
1518
+ public val samples: List<IntradaySample>,
1519
+ )
1520
+
1521
+ @Serializable
1522
+ public data class RestingHeartRateList(
1523
+ public val samples: List<RestingHeartRateSample>,
1524
+ )
1525
+
1526
+ @Serializable
1527
+ public data class BodyReadingList(
1528
+ public val samples: List<BodyReading>,
1529
+ )
1530
+
1531
+ @Serializable
1532
+ public data class WorkoutRouteList(
1533
+ public val routes: List<WorkoutRoute>,
1534
+ )
1535
+
1536
+ @Serializable
1537
+ public data class WorkoutIntensityList(
1538
+ public val samples: List<WorkoutIntensitySample>,
1539
+ )
1540
+
1541
+ @Serializable
1542
+ public data class HydrationList(
1543
+ public val samples: List<HydrationSample>,
1544
+ )
1545
+
1546
+ @Serializable
1547
+ public data class AvailabilityResult(
1548
+ public val availability: StoreAvailability,
1549
+ )
1550
+
879
1551
  public object TerraEventEnvelope {
880
1552
  public fun validate(value: TerraEvent) {
881
1553
  if ((value["at"] as? JsonPrimitive)?.isString != true) {