@tryterra/react-native 0.0.0-stage → 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.
- package/LICENSE +21 -0
- package/README.md +142 -2
- package/TerraReactNative.podspec +48 -0
- package/android/build.gradle +87 -0
- package/android/src/bridgeCore/kotlin/README.md +1 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/BridgeBootstrap.kt +133 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/BridgeHost.kt +32 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/Conversions.kt +557 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/LauncherSlots.kt +41 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/ReadConversions.kt +250 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/Rejections.kt +150 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/StreamRegistry.kt +77 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridge.kt +86 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridgeOpsImpl.kt +300 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TerraBridgeStreamsImpl.kt +50 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/TokenBroker.kt +198 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeErrors.kt +217 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeOps.kt +582 -0
- package/android/src/bridgeCore/kotlin/co/tryterra/sdk/bridge/generated/BridgeTypes.kt +1569 -0
- package/android/src/healthConnectOnly/kotlin/co/tryterra/sdk/reactnative/TerraStores.kt +11 -0
- package/android/src/main/AndroidManifest.xml +24 -0
- package/android/src/main/java/co/tryterra/sdk/reactnative/TerraBridgeModule.kt +96 -0
- package/android/src/main/java/co/tryterra/sdk/reactnative/TerraReactNativePackage.kt +26 -0
- package/android/src/main/java/co/tryterra/sdk/reactnative/TerraStartup.kt +46 -0
- package/android/src/samsung/kotlin/co/tryterra/sdk/reactnative/TerraStores.kt +13 -0
- package/docs/availability.md +396 -0
- package/frameworks/TerraSDK.xcframework/Info.plist +48 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Info.plist +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.abi.json +82672 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.package.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.private.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios.swiftinterface +2163 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/PrivacyInfo.xcprivacy +96 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/TerraSDK.framework/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Info.plist +20 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/DWARF/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/TerraSDK.yml +6594 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Info.plist +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.abi.json +82672 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.package.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/arm64-apple-ios-simulator.swiftinterface +2163 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.abi.json +82672 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.package.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +2186 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/Modules/TerraSDK.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +2163 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/PrivacyInfo.xcprivacy +96 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/TerraSDK.framework/_CodeSignature/CodeResources +223 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Info.plist +20 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/DWARF/TerraSDK +0 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/aarch64/TerraSDK.yml +6595 -0
- package/frameworks/TerraSDK.xcframework/ios-arm64_x86_64-simulator/dSYMs/TerraSDK.framework.dSYM/Contents/Resources/Relocations/x86_64/TerraSDK.yml +6513 -0
- package/ios/TerraBridgeCore/BridgeBootstrap.swift +89 -0
- package/ios/TerraBridgeCore/BridgeHost.swift +13 -0
- package/ios/TerraBridgeCore/Conversions+Reads.swift +259 -0
- package/ios/TerraBridgeCore/Conversions.swift +594 -0
- package/ios/TerraBridgeCore/Generated/BridgeErrors.swift +179 -0
- package/ios/TerraBridgeCore/Generated/BridgeOps.swift +967 -0
- package/ios/TerraBridgeCore/Generated/BridgeTypes.swift +2050 -0
- package/ios/TerraBridgeCore/Locked.swift +15 -0
- package/ios/TerraBridgeCore/README.md +1 -0
- package/ios/TerraBridgeCore/Rejections.swift +130 -0
- package/ios/TerraBridgeCore/RuntimeAttachment.swift +60 -0
- package/ios/TerraBridgeCore/StreamRegistry.swift +59 -0
- package/ios/TerraBridgeCore/TerraBridge.swift +122 -0
- package/ios/TerraBridgeCore/TerraBridgeOpsImpl.swift +318 -0
- package/ios/TerraBridgeCore/TerraBridgeStreamsImpl.swift +60 -0
- package/ios/TerraBridgeCore/TokenBroker.swift +147 -0
- package/ios/TerraBridgeModule.mm +79 -0
- package/ios/TerraBridgeModuleImpl.swift +49 -0
- package/ios/TerraReactNative.swift +19 -0
- package/lib/EndUser.d.ts +12 -0
- package/lib/EndUser.js +13 -0
- package/lib/NativeTerraBridge.d.ts +23 -0
- package/lib/NativeTerraBridge.js +13 -0
- package/lib/Terra.d.ts +223 -0
- package/lib/Terra.js +336 -0
- package/lib/TerraError.d.ts +42 -0
- package/lib/TerraError.js +95 -0
- package/lib/createTerra.d.ts +8 -0
- package/lib/createTerra.js +19 -0
- package/lib/generated/client.d.ts +128 -0
- package/lib/generated/client.js +256 -0
- package/lib/generated/codecs.d.ts +219 -0
- package/lib/generated/codecs.js +2066 -0
- package/lib/generated/errors.d.ts +13 -0
- package/lib/generated/errors.js +68 -0
- package/lib/generated/ops.d.ts +13 -0
- package/lib/generated/ops.js +161 -0
- package/lib/generated/streams.d.ts +23 -0
- package/lib/generated/streams.js +58 -0
- package/lib/generated/types.d.ts +794 -0
- package/lib/generated/types.js +224 -0
- package/lib/index.d.ts +29 -0
- package/lib/index.js +55 -0
- package/package.json +71 -4
- package/src/EndUser.ts +15 -0
- package/src/NativeTerraBridge.ts +27 -0
- package/src/Terra.ts +592 -0
- package/src/TerraError.ts +116 -0
- package/src/createTerra.ts +18 -0
- package/src/generated/client.ts +315 -0
- package/src/generated/codecs.ts +1989 -0
- package/src/generated/errors.ts +113 -0
- package/src/generated/ops.ts +233 -0
- package/src/generated/streams.ts +74 -0
- package/src/generated/types.ts +1222 -0
- package/src/index.ts +54 -0
|
@@ -0,0 +1,1569 @@
|
|
|
1
|
+
// Generated from surface/terra-surface.json by surface/gen. Do not edit by hand.
|
|
2
|
+
// Regenerate with: node surface/gen/src/cli.ts generate
|
|
3
|
+
|
|
4
|
+
package co.tryterra.sdk.bridge.generated
|
|
5
|
+
|
|
6
|
+
import kotlinx.serialization.ExperimentalSerializationApi
|
|
7
|
+
import kotlinx.serialization.SerializationException
|
|
8
|
+
import kotlinx.serialization.KSerializer
|
|
9
|
+
import kotlinx.serialization.SerialName
|
|
10
|
+
import kotlinx.serialization.Serializable
|
|
11
|
+
import kotlinx.serialization.builtins.ListSerializer
|
|
12
|
+
import kotlinx.serialization.descriptors.SerialDescriptor
|
|
13
|
+
import kotlinx.serialization.encoding.Decoder
|
|
14
|
+
import kotlinx.serialization.encoding.Encoder
|
|
15
|
+
import kotlinx.serialization.json.JsonClassDiscriminator
|
|
16
|
+
import kotlinx.serialization.json.JsonObject
|
|
17
|
+
import kotlinx.serialization.json.JsonPrimitive
|
|
18
|
+
import kotlinx.serialization.json.booleanOrNull
|
|
19
|
+
import kotlinx.serialization.json.doubleOrNull
|
|
20
|
+
import kotlinx.serialization.json.longOrNull
|
|
21
|
+
import java.time.Instant
|
|
22
|
+
import java.time.ZoneOffset
|
|
23
|
+
import java.time.format.DateTimeFormatter
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The one spelling of an instant on the wire: UTC, and always exactly three fractional digits.
|
|
27
|
+
*
|
|
28
|
+
* `Instant.toString()` is not it: it omits the fractional part when it is zero and prints nine
|
|
29
|
+
* digits when it is not, so the same moment would produce different bytes here and in Swift.
|
|
30
|
+
* The DTOs carry instants as String, so this is the only place the format is decided, and the
|
|
31
|
+
* hand-written ops implementation must go through it rather than formatting its own.
|
|
32
|
+
*/
|
|
33
|
+
public object BridgeInstant {
|
|
34
|
+
private val formatter: DateTimeFormatter =
|
|
35
|
+
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").withZone(ZoneOffset.UTC)
|
|
36
|
+
|
|
37
|
+
public fun format(instant: Instant): String = formatter.format(instant)
|
|
38
|
+
|
|
39
|
+
/** Tolerant on the way in: a peer that omitted the fractional part is still understood. */
|
|
40
|
+
public fun parse(text: String): Instant = Instant.parse(text)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** A health store the SDK can link. One connection per source per device. */
|
|
44
|
+
@Serializable
|
|
45
|
+
public enum class Source {
|
|
46
|
+
@SerialName("health")
|
|
47
|
+
HEALTH,
|
|
48
|
+
/**
|
|
49
|
+
* Samsung Health, through the terra-android-samsung add-on. Connect, disconnect, permissions
|
|
50
|
+
* and diagnostics take it; reads, writes and change streams are Health Connect's.
|
|
51
|
+
*
|
|
52
|
+
* Available on android only.
|
|
53
|
+
*/
|
|
54
|
+
@SerialName("samsungHealth")
|
|
55
|
+
SAMSUNG_HEALTH,
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** The unit permissions are asked for and changes are reported against. */
|
|
59
|
+
@Serializable
|
|
60
|
+
public enum class DataCategory {
|
|
61
|
+
@SerialName("activity")
|
|
62
|
+
ACTIVITY,
|
|
63
|
+
@SerialName("body")
|
|
64
|
+
BODY,
|
|
65
|
+
@SerialName("daily")
|
|
66
|
+
DAILY,
|
|
67
|
+
@SerialName("sleep")
|
|
68
|
+
SLEEP,
|
|
69
|
+
@SerialName("nutrition")
|
|
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,
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@Serializable
|
|
87
|
+
public enum class PermissionStatus {
|
|
88
|
+
@SerialName("granted")
|
|
89
|
+
GRANTED,
|
|
90
|
+
@SerialName("denied")
|
|
91
|
+
DENIED,
|
|
92
|
+
@SerialName("notDetermined")
|
|
93
|
+
NOT_DETERMINED,
|
|
94
|
+
/**
|
|
95
|
+
* A read grant HealthKit will not report. Not an error: it is the documented answer for reads
|
|
96
|
+
* on iOS.
|
|
97
|
+
*/
|
|
98
|
+
@SerialName("notDisclosed")
|
|
99
|
+
NOT_DISCLOSED,
|
|
100
|
+
@SerialName("unsupported")
|
|
101
|
+
UNSUPPORTED,
|
|
102
|
+
/**
|
|
103
|
+
* Android answers unsupported where Apple would answer unavailable.
|
|
104
|
+
*
|
|
105
|
+
* Available on ios only.
|
|
106
|
+
*/
|
|
107
|
+
@SerialName("unavailable")
|
|
108
|
+
UNAVAILABLE,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@Serializable
|
|
112
|
+
public enum class MotionContext {
|
|
113
|
+
@SerialName("unknown")
|
|
114
|
+
UNKNOWN,
|
|
115
|
+
@SerialName("sedentary")
|
|
116
|
+
SEDENTARY,
|
|
117
|
+
@SerialName("active")
|
|
118
|
+
ACTIVE,
|
|
119
|
+
}
|
|
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
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Why background delivery is restricted. Android discloses which; Apple reports the state
|
|
276
|
+
* without a reason.
|
|
277
|
+
*
|
|
278
|
+
* Available on android only.
|
|
279
|
+
*/
|
|
280
|
+
@Serializable
|
|
281
|
+
public enum class BackgroundRestrictionReason {
|
|
282
|
+
@SerialName("oemRestricted")
|
|
283
|
+
OEM_RESTRICTED,
|
|
284
|
+
@SerialName("backgroundReadDenied")
|
|
285
|
+
BACKGROUND_READ_DENIED,
|
|
286
|
+
@SerialName("healthConnectFeatureUnavailable")
|
|
287
|
+
HEALTH_CONNECT_FEATURE_UNAVAILABLE,
|
|
288
|
+
@SerialName("storeFeatureUnavailable")
|
|
289
|
+
STORE_FEATURE_UNAVAILABLE,
|
|
290
|
+
@SerialName("ticksNotRunning")
|
|
291
|
+
TICKS_NOT_RUNNING,
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
@Serializable
|
|
295
|
+
public enum class DiagnosticsReason {
|
|
296
|
+
@SerialName("uploadFailed")
|
|
297
|
+
UPLOAD_FAILED,
|
|
298
|
+
@SerialName("backfillAbandoned")
|
|
299
|
+
BACKFILL_ABANDONED,
|
|
300
|
+
@SerialName("backgroundObservationUnavailable")
|
|
301
|
+
BACKGROUND_OBSERVATION_UNAVAILABLE,
|
|
302
|
+
@SerialName("backgroundRestricted")
|
|
303
|
+
BACKGROUND_RESTRICTED,
|
|
304
|
+
@SerialName("backgroundRefreshUnscheduled")
|
|
305
|
+
BACKGROUND_REFRESH_UNSCHEDULED,
|
|
306
|
+
@SerialName("quiet")
|
|
307
|
+
QUIET,
|
|
308
|
+
@SerialName("requested")
|
|
309
|
+
REQUESTED,
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
@Serializable
|
|
313
|
+
public enum class DeviceKeyRevokeOutcome {
|
|
314
|
+
@SerialName("revoked")
|
|
315
|
+
REVOKED,
|
|
316
|
+
@SerialName("alreadyRevoked")
|
|
317
|
+
ALREADY_REVOKED,
|
|
318
|
+
@SerialName("routeAbsent")
|
|
319
|
+
ROUTE_ABSENT,
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* The redacted error name an event carries. Deliberately not TerraErrorCode: an event names
|
|
324
|
+
* the failure without the detail bag, because a support report leaves the device.
|
|
325
|
+
*/
|
|
326
|
+
@Serializable
|
|
327
|
+
public enum class FailureCode {
|
|
328
|
+
@SerialName("healthDataUnavailable")
|
|
329
|
+
HEALTH_DATA_UNAVAILABLE,
|
|
330
|
+
@SerialName("notConnected")
|
|
331
|
+
NOT_CONNECTED,
|
|
332
|
+
@SerialName("tokenUnavailable")
|
|
333
|
+
TOKEN_UNAVAILABLE,
|
|
334
|
+
@SerialName("tokenRejected")
|
|
335
|
+
TOKEN_REJECTED,
|
|
336
|
+
@SerialName("tokenProviderFailed")
|
|
337
|
+
TOKEN_PROVIDER_FAILED,
|
|
338
|
+
@SerialName("offline")
|
|
339
|
+
OFFLINE,
|
|
340
|
+
@SerialName("timedOut")
|
|
341
|
+
TIMED_OUT,
|
|
342
|
+
@SerialName("serverError")
|
|
343
|
+
SERVER_ERROR,
|
|
344
|
+
@SerialName("transport")
|
|
345
|
+
TRANSPORT,
|
|
346
|
+
@SerialName("malformedResponse")
|
|
347
|
+
MALFORMED_RESPONSE,
|
|
348
|
+
@SerialName("userLimitReached")
|
|
349
|
+
USER_LIMIT_REACHED,
|
|
350
|
+
@SerialName("upgradeRequired")
|
|
351
|
+
UPGRADE_REQUIRED,
|
|
352
|
+
@SerialName("platform")
|
|
353
|
+
PLATFORM,
|
|
354
|
+
@SerialName("deviceKeyUnavailable")
|
|
355
|
+
DEVICE_KEY_UNAVAILABLE,
|
|
356
|
+
@SerialName("signatureRejected")
|
|
357
|
+
SIGNATURE_REJECTED,
|
|
358
|
+
@SerialName("linkRevoked")
|
|
359
|
+
LINK_REVOKED,
|
|
360
|
+
@SerialName("linkConflict")
|
|
361
|
+
LINK_CONFLICT,
|
|
362
|
+
@SerialName("clockSkewed")
|
|
363
|
+
CLOCK_SKEWED,
|
|
364
|
+
@SerialName("devIDMismatch")
|
|
365
|
+
DEV_IDMISMATCH,
|
|
366
|
+
@SerialName("syncAlreadyRunning")
|
|
367
|
+
SYNC_ALREADY_RUNNING,
|
|
368
|
+
@SerialName("linkAlreadyRunning")
|
|
369
|
+
LINK_ALREADY_RUNNING,
|
|
370
|
+
@SerialName("storeLocked")
|
|
371
|
+
STORE_LOCKED,
|
|
372
|
+
@SerialName("storeUnreadable")
|
|
373
|
+
STORE_UNREADABLE,
|
|
374
|
+
@SerialName("deadlineExceeded")
|
|
375
|
+
DEADLINE_EXCEEDED,
|
|
376
|
+
@SerialName("permissionDenied")
|
|
377
|
+
PERMISSION_DENIED,
|
|
378
|
+
@SerialName("authorizationNotDetermined")
|
|
379
|
+
AUTHORIZATION_NOT_DETERMINED,
|
|
380
|
+
@SerialName("sampleNotFound")
|
|
381
|
+
SAMPLE_NOT_FOUND,
|
|
382
|
+
@SerialName("rollbackIncomplete")
|
|
383
|
+
ROLLBACK_INCOMPLETE,
|
|
384
|
+
@SerialName("distanceNotAttributable")
|
|
385
|
+
DISTANCE_NOT_ATTRIBUTABLE,
|
|
386
|
+
@SerialName("bloodPressureIncomplete")
|
|
387
|
+
BLOOD_PRESSURE_INCOMPLETE,
|
|
388
|
+
@SerialName("authorizationUnavailableInExtension")
|
|
389
|
+
AUTHORIZATION_UNAVAILABLE_IN_EXTENSION,
|
|
390
|
+
@SerialName("routeAwaitingConverter")
|
|
391
|
+
ROUTE_AWAITING_CONVERTER,
|
|
392
|
+
/** Available on android only. */
|
|
393
|
+
@SerialName("readQuotaExceeded")
|
|
394
|
+
READ_QUOTA_EXCEEDED,
|
|
395
|
+
/**
|
|
396
|
+
* Apple's FailureCode carries it; Android's does not, because there is no Android
|
|
397
|
+
* planned-workout model.
|
|
398
|
+
*
|
|
399
|
+
* Available on ios only.
|
|
400
|
+
*/
|
|
401
|
+
@SerialName("plannedWorkoutUnnamed")
|
|
402
|
+
PLANNED_WORKOUT_UNNAMED,
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Whether Terra's plans can be put on the person's Apple Watch. unsupported before iOS 17 or
|
|
407
|
+
* where WorkoutKit cannot schedule.
|
|
408
|
+
*
|
|
409
|
+
* Available on ios only.
|
|
410
|
+
*/
|
|
411
|
+
@Serializable
|
|
412
|
+
public enum class WorkoutSchedulingStatus {
|
|
413
|
+
@SerialName("unsupported")
|
|
414
|
+
UNSUPPORTED,
|
|
415
|
+
@SerialName("notDetermined")
|
|
416
|
+
NOT_DETERMINED,
|
|
417
|
+
@SerialName("denied")
|
|
418
|
+
DENIED,
|
|
419
|
+
@SerialName("authorized")
|
|
420
|
+
AUTHORIZED,
|
|
421
|
+
}
|
|
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
|
+
|
|
596
|
+
/**
|
|
597
|
+
* The person a connect is for. A stored link is restored only for the person it was made for;
|
|
598
|
+
* anybody else gets a fresh link. Never sent to Terra as identity.
|
|
599
|
+
*/
|
|
600
|
+
@Serializable
|
|
601
|
+
@OptIn(ExperimentalSerializationApi::class)
|
|
602
|
+
@JsonClassDiscriminator("kind")
|
|
603
|
+
public sealed interface EndUser {
|
|
604
|
+
/** The app's id for this person: the same value its backend puts in the token. */
|
|
605
|
+
@Serializable
|
|
606
|
+
@SerialName("reference")
|
|
607
|
+
public data class Reference(public val id: String) : EndUser
|
|
608
|
+
/** No reference: one link per install. */
|
|
609
|
+
@Serializable
|
|
610
|
+
@SerialName("anonymous")
|
|
611
|
+
public data object Anonymous : EndUser
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
/** A half-open window [start, end). Resolved against the device's calendar natively. */
|
|
615
|
+
@Serializable
|
|
616
|
+
@OptIn(ExperimentalSerializationApi::class)
|
|
617
|
+
@JsonClassDiscriminator("kind")
|
|
618
|
+
public sealed interface TimeRange {
|
|
619
|
+
@Serializable
|
|
620
|
+
@SerialName("lastHours")
|
|
621
|
+
public data class LastHours(public val hours: Int) : TimeRange
|
|
622
|
+
@Serializable
|
|
623
|
+
@SerialName("lastDays")
|
|
624
|
+
public data class LastDays(public val days: Int) : TimeRange
|
|
625
|
+
@Serializable
|
|
626
|
+
@SerialName("today")
|
|
627
|
+
public data object Today : TimeRange
|
|
628
|
+
@Serializable
|
|
629
|
+
@SerialName("between")
|
|
630
|
+
public data class Between(public val start: String, public val end: String) : TimeRange
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
@Serializable
|
|
634
|
+
@OptIn(ExperimentalSerializationApi::class)
|
|
635
|
+
@JsonClassDiscriminator("kind")
|
|
636
|
+
public sealed interface SleepStage {
|
|
637
|
+
@Serializable
|
|
638
|
+
@SerialName("inBed")
|
|
639
|
+
public data object InBed : SleepStage
|
|
640
|
+
@Serializable
|
|
641
|
+
@SerialName("awake")
|
|
642
|
+
public data object Awake : SleepStage
|
|
643
|
+
@Serializable
|
|
644
|
+
@SerialName("asleep")
|
|
645
|
+
public data object Asleep : SleepStage
|
|
646
|
+
@Serializable
|
|
647
|
+
@SerialName("light")
|
|
648
|
+
public data object Light : SleepStage
|
|
649
|
+
@Serializable
|
|
650
|
+
@SerialName("deep")
|
|
651
|
+
public data object Deep : SleepStage
|
|
652
|
+
@Serializable
|
|
653
|
+
@SerialName("rem")
|
|
654
|
+
public data object Rem : SleepStage
|
|
655
|
+
/**
|
|
656
|
+
* A stage the store reported that neither SDK maps. The raw value is carried so an app can log
|
|
657
|
+
* it.
|
|
658
|
+
*/
|
|
659
|
+
@Serializable
|
|
660
|
+
@SerialName("unknown")
|
|
661
|
+
public data class Unknown(public val raw: String) : SleepStage
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
@Serializable
|
|
665
|
+
@OptIn(ExperimentalSerializationApi::class)
|
|
666
|
+
@JsonClassDiscriminator("kind")
|
|
667
|
+
public sealed interface WorkoutActivity {
|
|
668
|
+
@Serializable
|
|
669
|
+
@SerialName("running")
|
|
670
|
+
public data object Running : WorkoutActivity
|
|
671
|
+
@Serializable
|
|
672
|
+
@SerialName("walking")
|
|
673
|
+
public data object Walking : WorkoutActivity
|
|
674
|
+
@Serializable
|
|
675
|
+
@SerialName("cycling")
|
|
676
|
+
public data object Cycling : WorkoutActivity
|
|
677
|
+
@Serializable
|
|
678
|
+
@SerialName("swimming")
|
|
679
|
+
public data object Swimming : WorkoutActivity
|
|
680
|
+
@Serializable
|
|
681
|
+
@SerialName("strengthTraining")
|
|
682
|
+
public data object StrengthTraining : WorkoutActivity
|
|
683
|
+
@Serializable
|
|
684
|
+
@SerialName("other")
|
|
685
|
+
public data class Other(public val label: String) : WorkoutActivity
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* What the SDK believes about delivery right now. Wire spelling matches DiagnosticsWire.state
|
|
690
|
+
* and Apple's DiagnosticsState Encodable.
|
|
691
|
+
*/
|
|
692
|
+
@Serializable
|
|
693
|
+
@OptIn(ExperimentalSerializationApi::class)
|
|
694
|
+
@JsonClassDiscriminator("state")
|
|
695
|
+
public sealed interface DiagnosticsState {
|
|
696
|
+
@Serializable
|
|
697
|
+
@SerialName("healthy")
|
|
698
|
+
public data object Healthy : DiagnosticsState
|
|
699
|
+
@Serializable
|
|
700
|
+
@SerialName("quiet")
|
|
701
|
+
public data class Quiet(public val since: String) : DiagnosticsState
|
|
702
|
+
@Serializable
|
|
703
|
+
@SerialName("backgroundRestricted")
|
|
704
|
+
public data class BackgroundRestricted(public val reason: BackgroundRestrictionReason? = null) : DiagnosticsState
|
|
705
|
+
@Serializable
|
|
706
|
+
@SerialName("backgroundRefreshUnscheduled")
|
|
707
|
+
public data object BackgroundRefreshUnscheduled : DiagnosticsState
|
|
708
|
+
@Serializable
|
|
709
|
+
@SerialName("pendingRetry")
|
|
710
|
+
public data object PendingRetry : DiagnosticsState
|
|
711
|
+
@Serializable
|
|
712
|
+
@SerialName("linkRevoked")
|
|
713
|
+
public data object LinkRevoked : DiagnosticsState
|
|
714
|
+
/**
|
|
715
|
+
* Apple reports the mismatch as a state. Android raises dev_id_mismatch and has no state for
|
|
716
|
+
* it.
|
|
717
|
+
*
|
|
718
|
+
* Available on ios only.
|
|
719
|
+
*/
|
|
720
|
+
@Serializable
|
|
721
|
+
@SerialName("devIDMismatch")
|
|
722
|
+
public data object DevIDMismatch : DiagnosticsState
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* What a subscription delivers. A stream can fail or finish, and without saying so the
|
|
727
|
+
* framework layer has to invent a convention for both - two of those, one per wrapper, is a
|
|
728
|
+
* contract nobody wrote down.
|
|
729
|
+
*/
|
|
730
|
+
@Serializable
|
|
731
|
+
@OptIn(ExperimentalSerializationApi::class)
|
|
732
|
+
@JsonClassDiscriminator("kind")
|
|
733
|
+
public sealed interface StreamMessage {
|
|
734
|
+
@Serializable
|
|
735
|
+
@SerialName("data")
|
|
736
|
+
public data class Data(public val element: JsonObject) : StreamMessage
|
|
737
|
+
/** The stream failed. The subscription is over; the id will deliver nothing more. */
|
|
738
|
+
@Serializable
|
|
739
|
+
@SerialName("error")
|
|
740
|
+
public data class Error(public val error: TerraErrorPayload) : StreamMessage
|
|
741
|
+
/** The stream ended on its own. The host should drop the subscription rather than unsubscribe. */
|
|
742
|
+
@Serializable
|
|
743
|
+
@SerialName("complete")
|
|
744
|
+
public data object Complete : StreamMessage
|
|
745
|
+
}
|
|
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
|
+
|
|
843
|
+
public object DataCategorySetSerializer : KSerializer<List<DataCategory>> {
|
|
844
|
+
private val list = ListSerializer(DataCategory.serializer())
|
|
845
|
+
override val descriptor: SerialDescriptor = list.descriptor
|
|
846
|
+
|
|
847
|
+
override fun serialize(encoder: Encoder, value: List<DataCategory>): Unit = list.serialize(encoder, canonical(value))
|
|
848
|
+
|
|
849
|
+
override fun deserialize(decoder: Decoder): List<DataCategory> = canonical(list.deserialize(decoder))
|
|
850
|
+
|
|
851
|
+
private fun canonical(value: List<DataCategory>): List<DataCategory> =
|
|
852
|
+
value.distinct().sortedBy { DataCategory.serializer().descriptor.getElementName(it.ordinal) }
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
/** Who recorded a sample. The only stable handle an app has for filtering by app or device. */
|
|
856
|
+
@Serializable
|
|
857
|
+
public data class SampleSource(
|
|
858
|
+
public val name: String,
|
|
859
|
+
public val bundleId: String,
|
|
860
|
+
public val productType: String? = null,
|
|
861
|
+
public val deviceType: String? = null,
|
|
862
|
+
)
|
|
863
|
+
|
|
864
|
+
/**
|
|
865
|
+
* A link record. A value, not a handle: Apple's Connection carries sync and disconnect
|
|
866
|
+
* methods, and an object with behaviour cannot cross the bridge, so those are ops on the
|
|
867
|
+
* client.
|
|
868
|
+
*/
|
|
869
|
+
@Serializable
|
|
870
|
+
public data class Connection(
|
|
871
|
+
public val source: Source,
|
|
872
|
+
public val userId: String,
|
|
873
|
+
/**
|
|
874
|
+
* Android's StoredConnection carries the store-side id. Apple's Connection does not.
|
|
875
|
+
*
|
|
876
|
+
* Available on android only.
|
|
877
|
+
*/
|
|
878
|
+
public val providerUserId: String? = null,
|
|
879
|
+
)
|
|
880
|
+
|
|
881
|
+
@Serializable
|
|
882
|
+
public data class HeartRateSample(
|
|
883
|
+
public val id: String,
|
|
884
|
+
public val time: String,
|
|
885
|
+
public val beatsPerMinute: Double,
|
|
886
|
+
public val source: SampleSource,
|
|
887
|
+
public val motionContext: MotionContext? = null,
|
|
888
|
+
public val userEntered: Boolean,
|
|
889
|
+
public val timeZone: String? = null,
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
/**
|
|
893
|
+
* A step total over an interval. Apple derives the id from the source and start; Android
|
|
894
|
+
* carries a RecordId when it has one, so the id is optional on the wire.
|
|
895
|
+
*/
|
|
896
|
+
@Serializable
|
|
897
|
+
public data class StepCount(
|
|
898
|
+
public val id: String? = null,
|
|
899
|
+
public val start: String,
|
|
900
|
+
public val end: String,
|
|
901
|
+
public val steps: Int,
|
|
902
|
+
public val source: SampleSource,
|
|
903
|
+
public val userEntered: Boolean,
|
|
904
|
+
public val timeZone: String? = null,
|
|
905
|
+
)
|
|
906
|
+
|
|
907
|
+
@Serializable
|
|
908
|
+
public data class SleepSegment(
|
|
909
|
+
public val id: String,
|
|
910
|
+
public val start: String,
|
|
911
|
+
public val end: String,
|
|
912
|
+
public val stage: SleepStage,
|
|
913
|
+
public val source: SampleSource,
|
|
914
|
+
public val userEntered: Boolean,
|
|
915
|
+
public val timeZone: String? = null,
|
|
916
|
+
)
|
|
917
|
+
|
|
918
|
+
/**
|
|
919
|
+
* indoor is optional because Health Connect does not always record it; Apple always has an
|
|
920
|
+
* answer.
|
|
921
|
+
*/
|
|
922
|
+
@Serializable
|
|
923
|
+
public data class Workout(
|
|
924
|
+
public val id: String,
|
|
925
|
+
public val start: String,
|
|
926
|
+
public val end: String,
|
|
927
|
+
public val activity: WorkoutActivity,
|
|
928
|
+
public val activityTypeCode: Int,
|
|
929
|
+
public val indoor: Boolean? = null,
|
|
930
|
+
public val activeEnergyKilocalories: Double? = null,
|
|
931
|
+
public val distanceMeters: Double? = null,
|
|
932
|
+
public val source: SampleSource,
|
|
933
|
+
public val userEntered: Boolean,
|
|
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,
|
|
983
|
+
)
|
|
984
|
+
|
|
985
|
+
/** A day whose data changed. Carries no health value by construction. */
|
|
986
|
+
@Serializable
|
|
987
|
+
public data class HealthChange(
|
|
988
|
+
public val category: DataCategory,
|
|
989
|
+
public val day: String,
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
@Serializable
|
|
993
|
+
public data class WorkoutScope(
|
|
994
|
+
public val activity: WorkoutActivity,
|
|
995
|
+
public val energy: Boolean,
|
|
996
|
+
public val distance: Boolean,
|
|
997
|
+
)
|
|
998
|
+
|
|
999
|
+
/**
|
|
1000
|
+
* Lists rather than sets: JSON has no set, so the category lists are marked `set` and every
|
|
1001
|
+
* generated codec de-duplicates and sorts them, so two orderings compare equal.
|
|
1002
|
+
*/
|
|
1003
|
+
@Serializable
|
|
1004
|
+
public data class HealthAccess(
|
|
1005
|
+
@Serializable(with = DataCategorySetSerializer::class) public val read: List<DataCategory>,
|
|
1006
|
+
@Serializable(with = DataCategorySetSerializer::class) public val write: List<DataCategory>,
|
|
1007
|
+
public val workouts: List<WorkoutScope>,
|
|
1008
|
+
)
|
|
1009
|
+
|
|
1010
|
+
@Serializable
|
|
1011
|
+
public data class HeartRateEntry(
|
|
1012
|
+
public val time: String,
|
|
1013
|
+
public val beatsPerMinute: Double,
|
|
1014
|
+
public val recordId: String? = null,
|
|
1015
|
+
)
|
|
1016
|
+
|
|
1017
|
+
@Serializable
|
|
1018
|
+
public data class StepEntry(
|
|
1019
|
+
public val start: String,
|
|
1020
|
+
public val end: String,
|
|
1021
|
+
public val steps: Int,
|
|
1022
|
+
public val recordId: String? = null,
|
|
1023
|
+
)
|
|
1024
|
+
|
|
1025
|
+
@Serializable
|
|
1026
|
+
public data class SleepEntry(
|
|
1027
|
+
public val start: String,
|
|
1028
|
+
public val end: String,
|
|
1029
|
+
public val stage: SleepStage,
|
|
1030
|
+
public val recordId: String? = null,
|
|
1031
|
+
)
|
|
1032
|
+
|
|
1033
|
+
@Serializable
|
|
1034
|
+
public data class WorkoutEntry(
|
|
1035
|
+
public val start: String,
|
|
1036
|
+
public val end: String,
|
|
1037
|
+
public val activity: WorkoutActivity,
|
|
1038
|
+
public val totalEnergyKilocalories: Double? = null,
|
|
1039
|
+
public val totalDistanceMeters: Double? = null,
|
|
1040
|
+
public val recordId: String? = null,
|
|
1041
|
+
)
|
|
1042
|
+
|
|
1043
|
+
@Serializable
|
|
1044
|
+
public data class BodyEntry(
|
|
1045
|
+
public val time: String,
|
|
1046
|
+
public val bodyMassKilograms: Double? = null,
|
|
1047
|
+
public val bodyFatPercent: Double? = null,
|
|
1048
|
+
public val bodyMassIndex: Double? = null,
|
|
1049
|
+
public val heightMeters: Double? = null,
|
|
1050
|
+
public val leanBodyMassKilograms: Double? = null,
|
|
1051
|
+
public val bodyTemperatureCelsius: Double? = null,
|
|
1052
|
+
public val oxygenSaturationPercent: Double? = null,
|
|
1053
|
+
public val bloodGlucoseMilligramsPerDeciliter: Double? = null,
|
|
1054
|
+
public val bloodPressureSystolicMillimetersOfMercury: Double? = null,
|
|
1055
|
+
public val bloodPressureDiastolicMillimetersOfMercury: Double? = null,
|
|
1056
|
+
public val recordId: String? = null,
|
|
1057
|
+
)
|
|
1058
|
+
|
|
1059
|
+
/**
|
|
1060
|
+
* Every field optional and every unit in the name, matching NutritionEntry.Nutrients on both
|
|
1061
|
+
* platforms field for field.
|
|
1062
|
+
*/
|
|
1063
|
+
@Serializable
|
|
1064
|
+
public data class Nutrients(
|
|
1065
|
+
public val energyKilocalories: Double? = null,
|
|
1066
|
+
public val proteinGrams: Double? = null,
|
|
1067
|
+
public val carbohydratesGrams: Double? = null,
|
|
1068
|
+
public val fiberGrams: Double? = null,
|
|
1069
|
+
public val sugarGrams: Double? = null,
|
|
1070
|
+
public val fatTotalGrams: Double? = null,
|
|
1071
|
+
public val fatSaturatedGrams: Double? = null,
|
|
1072
|
+
public val fatMonounsaturatedGrams: Double? = null,
|
|
1073
|
+
public val fatPolyunsaturatedGrams: Double? = null,
|
|
1074
|
+
public val cholesterolMilligrams: Double? = null,
|
|
1075
|
+
public val sodiumMilligrams: Double? = null,
|
|
1076
|
+
public val potassiumMilligrams: Double? = null,
|
|
1077
|
+
public val calciumMilligrams: Double? = null,
|
|
1078
|
+
public val ironMilligrams: Double? = null,
|
|
1079
|
+
public val magnesiumMilligrams: Double? = null,
|
|
1080
|
+
public val zincMilligrams: Double? = null,
|
|
1081
|
+
public val waterLiters: Double? = null,
|
|
1082
|
+
public val caffeineMilligrams: Double? = null,
|
|
1083
|
+
public val vitaminAMicrograms: Double? = null,
|
|
1084
|
+
public val vitaminCMilligrams: Double? = null,
|
|
1085
|
+
public val vitaminDMicrograms: Double? = null,
|
|
1086
|
+
public val vitaminEMilligrams: Double? = null,
|
|
1087
|
+
public val vitaminKMicrograms: Double? = null,
|
|
1088
|
+
public val vitaminB6Milligrams: Double? = null,
|
|
1089
|
+
public val vitaminB12Micrograms: Double? = null,
|
|
1090
|
+
public val folateMicrograms: Double? = null,
|
|
1091
|
+
public val thiaminMilligrams: Double? = null,
|
|
1092
|
+
public val riboflavinMilligrams: Double? = null,
|
|
1093
|
+
public val niacinMilligrams: Double? = null,
|
|
1094
|
+
public val biotinMicrograms: Double? = null,
|
|
1095
|
+
public val pantothenicAcidMilligrams: Double? = null,
|
|
1096
|
+
public val phosphorusMilligrams: Double? = null,
|
|
1097
|
+
public val iodineMicrograms: Double? = null,
|
|
1098
|
+
public val chromiumMicrograms: Double? = null,
|
|
1099
|
+
public val copperMilligrams: Double? = null,
|
|
1100
|
+
public val manganeseMilligrams: Double? = null,
|
|
1101
|
+
public val molybdenumMicrograms: Double? = null,
|
|
1102
|
+
public val seleniumMicrograms: Double? = null,
|
|
1103
|
+
public val chlorideMilligrams: Double? = null,
|
|
1104
|
+
)
|
|
1105
|
+
|
|
1106
|
+
@Serializable
|
|
1107
|
+
public data class NutritionEntry(
|
|
1108
|
+
public val start: String,
|
|
1109
|
+
public val end: String,
|
|
1110
|
+
public val name: String? = null,
|
|
1111
|
+
public val nutrients: Nutrients,
|
|
1112
|
+
public val recordId: String? = null,
|
|
1113
|
+
)
|
|
1114
|
+
|
|
1115
|
+
/**
|
|
1116
|
+
* An error carried as a value rather than thrown, inside a sync result. The same shape the
|
|
1117
|
+
* bridge rejects a promise with.
|
|
1118
|
+
*/
|
|
1119
|
+
@Serializable
|
|
1120
|
+
public data class TerraErrorPayload(
|
|
1121
|
+
public val code: String,
|
|
1122
|
+
public val retryable: Boolean,
|
|
1123
|
+
public val message: String,
|
|
1124
|
+
public val source: Source? = null,
|
|
1125
|
+
public val details: JsonObject? = null,
|
|
1126
|
+
)
|
|
1127
|
+
|
|
1128
|
+
/** Available on ios only. */
|
|
1129
|
+
@Serializable
|
|
1130
|
+
public data class PlannedWorkout(
|
|
1131
|
+
public val id: String? = null,
|
|
1132
|
+
public val plannedOn: String? = null,
|
|
1133
|
+
public val activity: WorkoutActivity? = null,
|
|
1134
|
+
public val title: String? = null,
|
|
1135
|
+
public val completedAt: String? = null,
|
|
1136
|
+
)
|
|
1137
|
+
|
|
1138
|
+
/**
|
|
1139
|
+
* The flat object both SDKs already emit: `at`, `event`, and whatever keys that kind carries.
|
|
1140
|
+
* Carried through unchanged rather than reshaped, because reshaping it would be a hand-written
|
|
1141
|
+
* second contract on each platform that no vector could pin - and the encoding it would be
|
|
1142
|
+
* translating is one DiagnosticsWire and Apple's Encodable already agree on, and that
|
|
1143
|
+
* EventPrivacyTest already guards against carrying a health value.
|
|
1144
|
+
*/
|
|
1145
|
+
public typealias TerraEvent = JsonObject
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* The redacted report, carried as the wire object DiagnosticsWire.report and Apple's
|
|
1149
|
+
* SupportReport.json already produce.
|
|
1150
|
+
*/
|
|
1151
|
+
@Serializable
|
|
1152
|
+
public data class SupportReport(
|
|
1153
|
+
public val sdkVersion: String,
|
|
1154
|
+
public val generatedAt: String,
|
|
1155
|
+
public val state: DiagnosticsState,
|
|
1156
|
+
public val lastDelivery: String? = null,
|
|
1157
|
+
public val isConnected: Boolean,
|
|
1158
|
+
public val requestedCategories: List<String>,
|
|
1159
|
+
public val requestedWrites: List<String>,
|
|
1160
|
+
public val requestedWorkouts: List<String>,
|
|
1161
|
+
public val recentEvents: List<TerraEvent>,
|
|
1162
|
+
)
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* What the JS side needs to know about the native client it is attaching to. bootstrapped
|
|
1166
|
+
* false is a host setup bug, and the wrapper says so with the exact line to add.
|
|
1167
|
+
*/
|
|
1168
|
+
@Serializable
|
|
1169
|
+
public data class BootstrapState(
|
|
1170
|
+
public val bootstrapped: Boolean,
|
|
1171
|
+
public val devId: String? = null,
|
|
1172
|
+
public val platform: String,
|
|
1173
|
+
public val sdkVersion: String,
|
|
1174
|
+
public val backgroundRegistered: Boolean,
|
|
1175
|
+
)
|
|
1176
|
+
|
|
1177
|
+
/**
|
|
1178
|
+
* The broker asking JS for a link token. Answered by token.resolve or token.reject with the
|
|
1179
|
+
* same requestId.
|
|
1180
|
+
*/
|
|
1181
|
+
@Serializable
|
|
1182
|
+
public data class TokenRequest(
|
|
1183
|
+
public val requestId: String,
|
|
1184
|
+
)
|
|
1185
|
+
|
|
1186
|
+
/** No request fields, or no response value. */
|
|
1187
|
+
@Serializable
|
|
1188
|
+
public class Empty
|
|
1189
|
+
|
|
1190
|
+
@Serializable
|
|
1191
|
+
public data class SourceRequest(
|
|
1192
|
+
public val source: Source? = null,
|
|
1193
|
+
)
|
|
1194
|
+
|
|
1195
|
+
@Serializable
|
|
1196
|
+
public data class RangeRequest(
|
|
1197
|
+
public val range: TimeRange,
|
|
1198
|
+
)
|
|
1199
|
+
|
|
1200
|
+
@Serializable
|
|
1201
|
+
public data class CategoryRequest(
|
|
1202
|
+
public val category: DataCategory,
|
|
1203
|
+
public val source: Source? = null,
|
|
1204
|
+
)
|
|
1205
|
+
|
|
1206
|
+
@Serializable
|
|
1207
|
+
public data class RecordIdRequest(
|
|
1208
|
+
public val id: String,
|
|
1209
|
+
)
|
|
1210
|
+
|
|
1211
|
+
@Serializable
|
|
1212
|
+
public data class ConnectRequest(
|
|
1213
|
+
public val source: Source? = null,
|
|
1214
|
+
public val endUser: EndUser,
|
|
1215
|
+
/**
|
|
1216
|
+
* A grant already in hand, from a QR code or a deep link. Absent means the token provider is
|
|
1217
|
+
* asked.
|
|
1218
|
+
*/
|
|
1219
|
+
public val token: String? = null,
|
|
1220
|
+
)
|
|
1221
|
+
|
|
1222
|
+
@Serializable
|
|
1223
|
+
public data class PermissionRequest(
|
|
1224
|
+
@Serializable(with = DataCategorySetSerializer::class) public val read: List<DataCategory>,
|
|
1225
|
+
@Serializable(with = DataCategorySetSerializer::class) public val write: List<DataCategory>,
|
|
1226
|
+
public val workouts: List<WorkoutScope>,
|
|
1227
|
+
public val source: Source? = null,
|
|
1228
|
+
)
|
|
1229
|
+
|
|
1230
|
+
/**
|
|
1231
|
+
* What the sheet granted. Android answers with the access this call obtained; HealthKit will
|
|
1232
|
+
* not report read grants, so Apple answers nothing at all.
|
|
1233
|
+
*/
|
|
1234
|
+
@Serializable
|
|
1235
|
+
public data class PermissionGrant(
|
|
1236
|
+
/** Available on android only. */
|
|
1237
|
+
public val granted: HealthAccess? = null,
|
|
1238
|
+
)
|
|
1239
|
+
|
|
1240
|
+
@Serializable
|
|
1241
|
+
public data class TokenResolveRequest(
|
|
1242
|
+
public val requestId: String,
|
|
1243
|
+
public val token: String,
|
|
1244
|
+
)
|
|
1245
|
+
|
|
1246
|
+
@Serializable
|
|
1247
|
+
public data class TokenRejectRequest(
|
|
1248
|
+
public val requestId: String,
|
|
1249
|
+
public val message: String,
|
|
1250
|
+
)
|
|
1251
|
+
|
|
1252
|
+
@Serializable
|
|
1253
|
+
public data class TokenProviderRequest(
|
|
1254
|
+
public val present: Boolean,
|
|
1255
|
+
public val timeoutMs: Int,
|
|
1256
|
+
)
|
|
1257
|
+
|
|
1258
|
+
/** Available on ios only. */
|
|
1259
|
+
@Serializable
|
|
1260
|
+
public data class MarkCompleteRequest(
|
|
1261
|
+
public val id: String? = null,
|
|
1262
|
+
public val at: String? = null,
|
|
1263
|
+
)
|
|
1264
|
+
|
|
1265
|
+
@Serializable
|
|
1266
|
+
public data class BoolResult(
|
|
1267
|
+
public val value: Boolean,
|
|
1268
|
+
)
|
|
1269
|
+
|
|
1270
|
+
@Serializable
|
|
1271
|
+
public data class StatusResult(
|
|
1272
|
+
public val status: PermissionStatus,
|
|
1273
|
+
)
|
|
1274
|
+
|
|
1275
|
+
/** Available on android only. */
|
|
1276
|
+
@Serializable
|
|
1277
|
+
public data class StatusesResult(
|
|
1278
|
+
public val statuses: Map<DataCategory, PermissionStatus>,
|
|
1279
|
+
)
|
|
1280
|
+
|
|
1281
|
+
@Serializable
|
|
1282
|
+
public data class RecordIdList(
|
|
1283
|
+
public val ids: List<String>,
|
|
1284
|
+
)
|
|
1285
|
+
|
|
1286
|
+
@Serializable
|
|
1287
|
+
public data class ConnectionList(
|
|
1288
|
+
public val connections: List<Connection>,
|
|
1289
|
+
)
|
|
1290
|
+
|
|
1291
|
+
@Serializable
|
|
1292
|
+
public data class HeartRateList(
|
|
1293
|
+
public val samples: List<HeartRateSample>,
|
|
1294
|
+
)
|
|
1295
|
+
|
|
1296
|
+
@Serializable
|
|
1297
|
+
public data class StepCountList(
|
|
1298
|
+
public val samples: List<StepCount>,
|
|
1299
|
+
)
|
|
1300
|
+
|
|
1301
|
+
@Serializable
|
|
1302
|
+
public data class SleepSegmentList(
|
|
1303
|
+
public val samples: List<SleepSegment>,
|
|
1304
|
+
)
|
|
1305
|
+
|
|
1306
|
+
@Serializable
|
|
1307
|
+
public data class WorkoutList(
|
|
1308
|
+
public val samples: List<Workout>,
|
|
1309
|
+
)
|
|
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
|
+
|
|
1354
|
+
/** Available on ios only. */
|
|
1355
|
+
@Serializable
|
|
1356
|
+
public data class PlannedWorkoutList(
|
|
1357
|
+
public val workouts: List<PlannedWorkout>? = null,
|
|
1358
|
+
)
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Once authorized, every sync run keeps the Watch schedule in step with Terra.
|
|
1362
|
+
*
|
|
1363
|
+
* Available on ios only.
|
|
1364
|
+
*/
|
|
1365
|
+
@Serializable
|
|
1366
|
+
public data class WorkoutScheduling(
|
|
1367
|
+
public val status: WorkoutSchedulingStatus? = null,
|
|
1368
|
+
)
|
|
1369
|
+
|
|
1370
|
+
@Serializable
|
|
1371
|
+
public data class LastDeliveryResult(
|
|
1372
|
+
public val at: String? = null,
|
|
1373
|
+
)
|
|
1374
|
+
|
|
1375
|
+
@Serializable
|
|
1376
|
+
public data class HeartRateEntryList(
|
|
1377
|
+
public val entries: List<HeartRateEntry>,
|
|
1378
|
+
)
|
|
1379
|
+
|
|
1380
|
+
@Serializable
|
|
1381
|
+
public data class BodyEntryList(
|
|
1382
|
+
public val entries: List<BodyEntry>,
|
|
1383
|
+
)
|
|
1384
|
+
|
|
1385
|
+
@Serializable
|
|
1386
|
+
public data class StepEntryList(
|
|
1387
|
+
public val entries: List<StepEntry>,
|
|
1388
|
+
)
|
|
1389
|
+
|
|
1390
|
+
@Serializable
|
|
1391
|
+
public data class SleepEntryList(
|
|
1392
|
+
public val entries: List<SleepEntry>,
|
|
1393
|
+
)
|
|
1394
|
+
|
|
1395
|
+
@Serializable
|
|
1396
|
+
public data class WorkoutEntryList(
|
|
1397
|
+
public val entries: List<WorkoutEntry>,
|
|
1398
|
+
)
|
|
1399
|
+
|
|
1400
|
+
@Serializable
|
|
1401
|
+
public data class NutritionEntryList(
|
|
1402
|
+
public val entries: List<NutritionEntry>,
|
|
1403
|
+
)
|
|
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
|
+
|
|
1551
|
+
public object TerraEventEnvelope {
|
|
1552
|
+
public fun validate(value: TerraEvent) {
|
|
1553
|
+
if ((value["at"] as? JsonPrimitive)?.isString != true) {
|
|
1554
|
+
throw SerializationException("TerraEvent.at is not a string")
|
|
1555
|
+
}
|
|
1556
|
+
if ((value["event"] as? JsonPrimitive)?.isString != true) {
|
|
1557
|
+
throw SerializationException("TerraEvent.event is not a string")
|
|
1558
|
+
}
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
public object SupportReportEnvelope {
|
|
1563
|
+
public fun validate(value: SupportReport) {
|
|
1564
|
+
for (level0 in value.recentEvents) {
|
|
1565
|
+
TerraEventEnvelope.validate(level0)
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
}
|
|
1569
|
+
|