@flomentumsolutions/capacitor-health-extended 0.7.6 → 0.7.7
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/README.md
CHANGED
|
@@ -237,7 +237,7 @@ This setup ensures your WebView will load HTTPS content securely and complies wi
|
|
|
237
237
|
* [`openAppleHealthSettings()`](#openapplehealthsettings)
|
|
238
238
|
* [`openHealthConnectSettings()`](#openhealthconnectsettings)
|
|
239
239
|
* [`showHealthConnectInPlayStore()`](#showhealthconnectinplaystore)
|
|
240
|
-
* [`getCharacteristics()`](#getcharacteristics)
|
|
240
|
+
* [`getCharacteristics(...)`](#getcharacteristics)
|
|
241
241
|
* [`queryAggregated(...)`](#queryaggregated)
|
|
242
242
|
* [`queryWorkouts(...)`](#queryworkouts)
|
|
243
243
|
* [`queryLatestSample(...)`](#querylatestsample)
|
|
@@ -331,6 +331,7 @@ openHealthConnectSettings() => Promise<void>
|
|
|
331
331
|
```
|
|
332
332
|
|
|
333
333
|
Opens the Google Health Connect app
|
|
334
|
+
iOS: Aliases openAppleHealthSettings().
|
|
334
335
|
|
|
335
336
|
--------------------
|
|
336
337
|
|
|
@@ -342,19 +343,22 @@ showHealthConnectInPlayStore() => Promise<void>
|
|
|
342
343
|
```
|
|
343
344
|
|
|
344
345
|
Opens the Google Health Connect app in PlayStore
|
|
346
|
+
iOS: Resolves without action.
|
|
345
347
|
|
|
346
348
|
--------------------
|
|
347
349
|
|
|
348
350
|
|
|
349
|
-
### getCharacteristics()
|
|
351
|
+
### getCharacteristics(...)
|
|
350
352
|
|
|
351
353
|
```typescript
|
|
352
|
-
getCharacteristics(request?: CharacteristicsRequest) => Promise<CharacteristicsResponse>
|
|
354
|
+
getCharacteristics(request?: CharacteristicsRequest | undefined) => Promise<CharacteristicsResponse>
|
|
353
355
|
```
|
|
354
356
|
|
|
355
|
-
iOS only: Reads user characteristics such as biological sex, blood type, date of birth, Fitzpatrick skin type, and wheelchair use.
|
|
357
|
+
iOS only: Reads user characteristics such as biological sex, blood type, date of birth, Fitzpatrick skin type, and wheelchair use.
|
|
356
358
|
Values are null when unavailable or permission was not granted. Android does not expose these characteristics; it returns `platformSupported: false` and a `platformMessage` for UI hints without emitting null values.
|
|
357
359
|
|
|
360
|
+
Passing `fields` lets you request only specific characteristics (e.g., date of birth) to keep permissions scoped narrowly. Defaults to all characteristics when omitted.
|
|
361
|
+
|
|
358
362
|
| Param | Type |
|
|
359
363
|
| ------------- | ------------------------------------------------------------------------- |
|
|
360
364
|
| **`request`** | <code><a href="#characteristicsrequest">CharacteristicsRequest</a></code> |
|
|
@@ -430,6 +434,7 @@ queryWeight() => Promise<QueryLatestSampleResponse>
|
|
|
430
434
|
```
|
|
431
435
|
|
|
432
436
|
Query latest weight sample
|
|
437
|
+
Convenience wrapper around queryLatestSample({ dataType: 'weight' }).
|
|
433
438
|
|
|
434
439
|
**Returns:** <code>Promise<<a href="#querylatestsampleresponse">QueryLatestSampleResponse</a>></code>
|
|
435
440
|
|
|
@@ -443,6 +448,7 @@ queryHeight() => Promise<QueryLatestSampleResponse>
|
|
|
443
448
|
```
|
|
444
449
|
|
|
445
450
|
Query latest height sample
|
|
451
|
+
Convenience wrapper around queryLatestSample({ dataType: 'height' }).
|
|
446
452
|
|
|
447
453
|
**Returns:** <code>Promise<<a href="#querylatestsampleresponse">QueryLatestSampleResponse</a>></code>
|
|
448
454
|
|
|
@@ -456,6 +462,7 @@ queryHeartRate() => Promise<QueryLatestSampleResponse>
|
|
|
456
462
|
```
|
|
457
463
|
|
|
458
464
|
Query latest heart rate sample
|
|
465
|
+
Convenience wrapper around queryLatestSample({ dataType: 'heart-rate' }).
|
|
459
466
|
|
|
460
467
|
**Returns:** <code>Promise<<a href="#querylatestsampleresponse">QueryLatestSampleResponse</a>></code>
|
|
461
468
|
|
|
@@ -469,6 +476,7 @@ querySteps() => Promise<QueryLatestSampleResponse>
|
|
|
469
476
|
```
|
|
470
477
|
|
|
471
478
|
Query latest steps sample
|
|
479
|
+
Convenience wrapper around queryLatestSample({ dataType: 'steps' }).
|
|
472
480
|
|
|
473
481
|
**Returns:** <code>Promise<<a href="#querylatestsampleresponse">QueryLatestSampleResponse</a>></code>
|
|
474
482
|
|
|
@@ -529,13 +537,6 @@ Save user-provided body metrics to the health platform.
|
|
|
529
537
|
| **`permissions`** | <code>HealthPermission[]</code> |
|
|
530
538
|
|
|
531
539
|
|
|
532
|
-
#### CharacteristicsRequest
|
|
533
|
-
|
|
534
|
-
| Prop | Type | Description |
|
|
535
|
-
| ------------ | -------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
536
|
-
| **`fields`** | <code><a href="#characteristicfield">CharacteristicField</a>[]</code> | Characteristics to query; defaults to all when unspecified |
|
|
537
|
-
|
|
538
|
-
|
|
539
540
|
#### CharacteristicsResponse
|
|
540
541
|
|
|
541
542
|
| Prop | Type | Description |
|
|
@@ -549,6 +550,13 @@ Save user-provided body metrics to the health platform.
|
|
|
549
550
|
| **`platformMessage`** | <code>string</code> | Optional platform-specific message; on Android we return a user-facing note explaining that values remain empty unless synced from iOS. |
|
|
550
551
|
|
|
551
552
|
|
|
553
|
+
#### CharacteristicsRequest
|
|
554
|
+
|
|
555
|
+
| Prop | Type | Description |
|
|
556
|
+
| ------------ | ---------------------------------- | ----------------------------------------------------------------------- |
|
|
557
|
+
| **`fields`** | <code>CharacteristicField[]</code> | Characteristics to query. Defaults to all characteristics when omitted. |
|
|
558
|
+
|
|
559
|
+
|
|
552
560
|
#### QueryAggregatedResponse
|
|
553
561
|
|
|
554
562
|
| Prop | Type |
|
|
@@ -695,11 +703,6 @@ Construct a type with a set of properties K of type T
|
|
|
695
703
|
<code>{
|
|
696
704
|
[P in K]: T;
|
|
697
705
|
}</code>
|
|
698
706
|
|
|
699
707
|
|
|
700
|
-
#### CharacteristicField
|
|
701
|
-
|
|
702
|
-
<code>'biologicalSex' | 'bloodType' | 'dateOfBirth' | 'fitzpatrickSkinType' | 'wheelchairUse'</code>
|
|
703
|
-
|
|
704
|
-
|
|
705
708
|
#### HealthPermission
|
|
706
709
|
|
|
707
710
|
<code>'READ_STEPS' | 'READ_WORKOUTS' | 'WRITE_WORKOUTS' | 'READ_ACTIVE_CALORIES' | 'WRITE_ACTIVE_CALORIES' | 'READ_TOTAL_CALORIES' | 'WRITE_TOTAL_CALORIES' | 'READ_DISTANCE' | 'WRITE_DISTANCE' | 'READ_WEIGHT' | 'WRITE_WEIGHT' | 'READ_HEIGHT' | 'WRITE_HEIGHT' | 'READ_HEART_RATE' | 'WRITE_HEART_RATE' | 'READ_RESTING_HEART_RATE' | 'WRITE_RESTING_HEART_RATE' | 'READ_ROUTE' | 'WRITE_ROUTE' | 'READ_MINDFULNESS' | 'READ_HRV' | 'READ_BLOOD_PRESSURE' | 'READ_BASAL_CALORIES' | 'READ_RESPIRATORY_RATE' | 'READ_OXYGEN_SATURATION' | 'READ_BLOOD_GLUCOSE' | 'READ_BODY_TEMPERATURE' | 'READ_BASAL_BODY_TEMPERATURE' | 'READ_BODY_FAT' | 'WRITE_BODY_FAT' | 'READ_FLOORS_CLIMBED' | 'READ_SLEEP' | 'READ_EXERCISE_TIME' | 'READ_BIOLOGICAL_SEX' | 'READ_BLOOD_TYPE' | 'READ_DATE_OF_BIRTH' | 'READ_FITZPATRICK_SKIN_TYPE' | 'READ_WHEELCHAIR_USE'</code>
|
|
@@ -725,6 +728,11 @@ Construct a type with a set of properties K of type T
|
|
|
725
728
|
<code>'wheelchair_user' | 'not_wheelchair_user' | 'not_set' | 'unknown'</code>
|
|
726
729
|
|
|
727
730
|
|
|
731
|
+
#### CharacteristicField
|
|
732
|
+
|
|
733
|
+
<code>'biologicalSex' | 'bloodType' | 'dateOfBirth' | 'fitzpatrickSkinType' | 'wheelchairUse'</code>
|
|
734
|
+
|
|
735
|
+
|
|
728
736
|
#### LatestDataType
|
|
729
737
|
|
|
730
738
|
<code>'steps' | 'active-calories' | 'total-calories' | 'basal-calories' | 'distance' | 'weight' | 'height' | 'heart-rate' | 'resting-heart-rate' | 'respiratory-rate' | 'oxygen-saturation' | 'blood-glucose' | 'body-temperature' | 'basal-body-temperature' | 'body-fat' | 'flights-climbed' | 'exercise-time' | 'distance-cycling' | 'mindfulness' | 'sleep' | 'sleep-rem' | 'hrv' | 'blood-pressure'</code>
|
|
@@ -34,10 +34,12 @@ export interface HealthPlugin {
|
|
|
34
34
|
openAppleHealthSettings(): Promise<void>;
|
|
35
35
|
/**
|
|
36
36
|
* Opens the Google Health Connect app
|
|
37
|
+
* iOS: Aliases openAppleHealthSettings().
|
|
37
38
|
*/
|
|
38
39
|
openHealthConnectSettings(): Promise<void>;
|
|
39
40
|
/**
|
|
40
41
|
* Opens the Google Health Connect app in PlayStore
|
|
42
|
+
* iOS: Resolves without action.
|
|
41
43
|
*/
|
|
42
44
|
showHealthConnectInPlayStore(): Promise<void>;
|
|
43
45
|
/**
|
|
@@ -74,18 +76,22 @@ export interface HealthPlugin {
|
|
|
74
76
|
}): Promise<QueryLatestSampleResponse>;
|
|
75
77
|
/**
|
|
76
78
|
* Query latest weight sample
|
|
79
|
+
* Convenience wrapper around queryLatestSample({ dataType: 'weight' }).
|
|
77
80
|
*/
|
|
78
81
|
queryWeight(): Promise<QueryLatestSampleResponse>;
|
|
79
82
|
/**
|
|
80
83
|
* Query latest height sample
|
|
84
|
+
* Convenience wrapper around queryLatestSample({ dataType: 'height' }).
|
|
81
85
|
*/
|
|
82
86
|
queryHeight(): Promise<QueryLatestSampleResponse>;
|
|
83
87
|
/**
|
|
84
88
|
* Query latest heart rate sample
|
|
89
|
+
* Convenience wrapper around queryLatestSample({ dataType: 'heart-rate' }).
|
|
85
90
|
*/
|
|
86
91
|
queryHeartRate(): Promise<QueryLatestSampleResponse>;
|
|
87
92
|
/**
|
|
88
93
|
* Query latest steps sample
|
|
94
|
+
* Convenience wrapper around queryLatestSample({ dataType: 'steps' }).
|
|
89
95
|
*/
|
|
90
96
|
querySteps(): Promise<QueryLatestSampleResponse>;
|
|
91
97
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface HealthPlugin {\n /**\n * Checks if health API is available.\n * Android: If false is returned, the Google Health Connect app is probably not installed.\n * See showHealthConnectInPlayStore()\n *\n */\n isHealthAvailable(): Promise<{ available: boolean }>;\n\n /**\n * Android only: Returns for each given permission, if it was granted by the underlying health API\n * @param permissions permissions to query\n */\n checkHealthPermissions(permissions: PermissionsRequest): Promise<PermissionResponse>;\n\n /**\n * Requests the permissions from the user.\n *\n * Android: Apps can ask only a few times for permissions, after that the user has to grant them manually in\n * the Health Connect app. See openHealthConnectSettings()\n *\n * iOS: If the permissions are already granted or denied, this method will just return without asking the user. In iOS\n * we can't really detect if a user granted or denied a permission. The return value reflects the assumption that all\n * permissions were granted.\n *\n * @param permissions permissions to request\n */\n requestHealthPermissions(permissions: PermissionsRequest): Promise<PermissionResponse>;\n\n /**\n * Opens the apps settings, which is kind of wrong, because health permissions are configured under:\n * Settings > Apps > (Apple) Health > Access and Devices > [app-name]\n * But we can't go there directly.\n */\n openAppleHealthSettings(): Promise<void>;\n\n /**\n * Opens the Google Health Connect app\n */\n openHealthConnectSettings(): Promise<void>;\n\n /**\n * Opens the Google Health Connect app in PlayStore\n */\n showHealthConnectInPlayStore(): Promise<void>;\n\n /**\n * iOS only: Reads user characteristics such as biological sex, blood type, date of birth, Fitzpatrick skin type, and wheelchair use.\n * Values are null when unavailable or permission was not granted. Android does not expose these characteristics; it returns `platformSupported: false` and a `platformMessage` for UI hints without emitting null values.\n *\n * Passing `fields` lets you request only specific characteristics (e.g., date of birth) to keep permissions scoped narrowly. Defaults to all characteristics when omitted.\n */\n getCharacteristics(request?: CharacteristicsRequest): Promise<CharacteristicsResponse>;\n\n /**\n * Query aggregated data\n * - Blood-pressure aggregates return the systolic average in `value` plus `systolic`, `diastolic`, and `unit`.\n * - `total-calories` is derived as active + basal energy on both iOS and Android for latest samples, aggregated queries, and workouts. We fall back to the platform's total‑calories metric (or active calories) when basal data isn't available or permission is missing. Request both `READ_ACTIVE_CALORIES` and `READ_BASAL_CALORIES` for full totals.\n * - Weight/height aggregation returns the latest sample per day (no averaging).\n * - Android aggregation currently supports daily buckets; unsupported buckets will be rejected.\n * - Android `distance-cycling` aggregates distance recorded during biking exercise sessions (requires distance + workouts permissions).\n * - Daily `bucket: \"day\"` queries use calendar-day boundaries in the device time zone (start-of-day through the next start-of-day) instead of a trailing 24-hour window. For “today,” send `startDate` at today’s start-of-day and `endDate` at now or tomorrow’s start-of-day.\n * @param request\n */\n queryAggregated(request: QueryAggregatedRequest): Promise<QueryAggregatedResponse>;\n\n /**\n * Query workouts\n * @param request\n */\n queryWorkouts(request: QueryWorkoutRequest): Promise<QueryWorkoutResponse>;\n\n /**\n * Query latest sample for a specific data type\n * - Latest sleep sample returns the most recent complete sleep session (asleep states only) from the last ~36 hours; if a longer overnight session exists, shorter naps are ignored.\n * - `sleep-rem` returns REM duration (minutes) for the latest sleep session; requires iOS 16+ sleep stages and Health Connect REM data on Android.\n * @param request\n */\n queryLatestSample(request: { dataType: LatestDataType }): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest weight sample\n */\n queryWeight(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest height sample\n */\n queryHeight(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest heart rate sample\n */\n queryHeartRate(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest steps sample\n */\n querySteps(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Create a workout session with optional totals and route/heart-rate samples.\n * - iOS stores an `HKWorkout` (activityType mapped from `activityType`) with total energy/distance and optional metadata/route/heart-rate samples.\n * - Android stores an `ExerciseSessionRecord` plus `ActiveCaloriesBurnedRecord`, `DistanceRecord`, and `HeartRateRecord` when provided. Routes are attached via `ExerciseRoute`.\n * - Requires matching WRITE_* permissions for the values you include (e.g., WRITE_WORKOUTS + WRITE_ACTIVE_CALORIES + WRITE_DISTANCE + WRITE_HEART_RATE + WRITE_ROUTE).\n */\n saveWorkout(request: SaveWorkoutRequest): Promise<SaveWorkoutResponse>;\n\n /**\n * Save user-provided body metrics to the health platform.\n */\n saveMetrics(request: SaveMetricsRequest): Promise<SaveMetricsResponse>;\n}\n\nexport declare type HealthPermission = 'READ_STEPS' | 'READ_WORKOUTS' | 'WRITE_WORKOUTS' | 'READ_ACTIVE_CALORIES' | 'WRITE_ACTIVE_CALORIES' | 'READ_TOTAL_CALORIES' | 'WRITE_TOTAL_CALORIES' | 'READ_DISTANCE' | 'WRITE_DISTANCE' | 'READ_WEIGHT' | 'WRITE_WEIGHT' | 'READ_HEIGHT' | 'WRITE_HEIGHT' | 'READ_HEART_RATE' | 'WRITE_HEART_RATE' | 'READ_RESTING_HEART_RATE' | 'WRITE_RESTING_HEART_RATE' | 'READ_ROUTE' | 'WRITE_ROUTE' | 'READ_MINDFULNESS' | 'READ_HRV' | 'READ_BLOOD_PRESSURE' | 'READ_BASAL_CALORIES' | 'READ_RESPIRATORY_RATE' | 'READ_OXYGEN_SATURATION' | 'READ_BLOOD_GLUCOSE' | 'READ_BODY_TEMPERATURE' | 'READ_BASAL_BODY_TEMPERATURE' | 'READ_BODY_FAT' | 'WRITE_BODY_FAT' | 'READ_FLOORS_CLIMBED' | 'READ_SLEEP' | 'READ_EXERCISE_TIME' | 'READ_BIOLOGICAL_SEX' | 'READ_BLOOD_TYPE' | 'READ_DATE_OF_BIRTH' | 'READ_FITZPATRICK_SKIN_TYPE' | 'READ_WHEELCHAIR_USE';\n\nexport type LatestDataType =\n | 'steps'\n | 'active-calories'\n | 'total-calories'\n | 'basal-calories'\n | 'distance'\n | 'weight'\n | 'height'\n | 'heart-rate'\n | 'resting-heart-rate'\n | 'respiratory-rate'\n | 'oxygen-saturation'\n | 'blood-glucose'\n | 'body-temperature'\n | 'basal-body-temperature'\n | 'body-fat'\n | 'flights-climbed'\n | 'exercise-time'\n | 'distance-cycling'\n | 'mindfulness'\n | 'sleep'\n | 'sleep-rem'\n | 'hrv'\n | 'blood-pressure';\n\nexport interface PermissionsRequest {\n permissions: HealthPermission[];\n}\n\nexport interface PermissionResponse {\n permissions: Record<HealthPermission, boolean>;\n}\n\nexport interface QueryWorkoutRequest {\n startDate: string;\n endDate: string;\n includeHeartRate: boolean;\n includeRoute: boolean;\n includeSteps: boolean;\n}\n\nexport interface HeartRateSample {\n timestamp: string;\n bpm: number;\n}\n\nexport interface RouteSample {\n timestamp: string;\n lat: number;\n lng: number;\n alt?: number;\n}\n\nexport interface QueryWorkoutResponse {\n workouts: Workout[];\n}\n\nexport type WorkoutActivityType =\n | 'rock-climbing'\n | 'climbing'\n | 'hiking'\n | 'running'\n | 'walking'\n | 'cycling'\n | 'biking'\n | 'strength-training'\n | 'yoga'\n | 'other';\n\nexport interface SaveWorkoutRequest {\n activityType: WorkoutActivityType;\n startDate: string;\n endDate: string;\n calories?: number;\n distance?: number;\n metadata?: Record<string, any>;\n route?: RouteSample[];\n heartRateSamples?: HeartRateSample[];\n}\n\nexport interface SaveWorkoutResponse {\n success: boolean;\n id?: string;\n}\n\nexport interface SaveMetricsRequest {\n weightKg?: number;\n heightCm?: number;\n bodyFatPercent?: number;\n restingHeartRate?: number;\n}\n\nexport interface SaveMetricsResponse {\n success: boolean;\n inserted?: number;\n}\n\nexport interface Workout {\n startDate: string;\n endDate: string;\n workoutType: string;\n sourceName: string;\n id?: string;\n duration: number;\n distance?: number;\n steps?: number;\n calories: number;\n sourceBundleId: string;\n route?: RouteSample[];\n heartRate?: HeartRateSample[];\n}\n\nexport interface QueryAggregatedRequest {\n startDate: string;\n endDate: string;\n dataType:\n | 'steps'\n | 'active-calories'\n | 'total-calories'\n | 'basal-calories'\n | 'distance'\n | 'weight'\n | 'height'\n | 'heart-rate'\n | 'resting-heart-rate'\n | 'respiratory-rate'\n | 'oxygen-saturation'\n | 'blood-glucose'\n | 'body-temperature'\n | 'basal-body-temperature'\n | 'body-fat'\n | 'flights-climbed'\n | 'exercise-time'\n | 'distance-cycling'\n | 'sleep'\n | 'mindfulness'\n | 'hrv'\n | 'blood-pressure';\n bucket: string;\n}\n\nexport interface QueryAggregatedResponse {\n aggregatedData: AggregatedSample[];\n}\n\nexport interface AggregatedSample {\n startDate: string;\n endDate: string;\n value: number;\n systolic?: number;\n diastolic?: number;\n unit?: string;\n}\n\nexport interface QueryLatestSampleResponse {\n value?: number;\n systolic?: number;\n diastolic?: number;\n timestamp: number;\n endTimestamp?: number;\n unit: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CharacteristicsResponse {\n biologicalSex?: HealthBiologicalSex | null;\n bloodType?: HealthBloodType | null;\n dateOfBirth?: string | null;\n fitzpatrickSkinType?: HealthFitzpatrickSkinType | null;\n wheelchairUse?: HealthWheelchairUse | null;\n /**\n * Indicates whether the platform exposes these characteristics via the plugin (true on iOS, false on Android).\n */\n platformSupported?: boolean;\n /**\n * Optional platform-specific message; on Android we return a user-facing note explaining that values remain empty unless synced from iOS.\n */\n platformMessage?: string;\n}\n\nexport type CharacteristicField =\n | 'biologicalSex'\n | 'bloodType'\n | 'dateOfBirth'\n | 'fitzpatrickSkinType'\n | 'wheelchairUse';\n\nexport interface CharacteristicsRequest {\n /**\n * Characteristics to query. Defaults to all characteristics when omitted.\n */\n fields?: CharacteristicField[];\n}\n\nexport type HealthBiologicalSex = 'female' | 'male' | 'other' | 'not_set' | 'unknown';\n\nexport type HealthBloodType =\n | 'a-positive'\n | 'a-negative'\n | 'b-positive'\n | 'b-negative'\n | 'ab-positive'\n | 'ab-negative'\n | 'o-positive'\n | 'o-negative'\n | 'not_set'\n | 'unknown';\n\nexport type HealthFitzpatrickSkinType = 'type1' | 'type2' | 'type3' | 'type4' | 'type5' | 'type6' | 'not_set' | 'unknown';\n\nexport type HealthWheelchairUse = 'wheelchair_user' | 'not_wheelchair_user' | 'not_set' | 'unknown';\n"]}
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface HealthPlugin {\n /**\n * Checks if health API is available.\n * Android: If false is returned, the Google Health Connect app is probably not installed.\n * See showHealthConnectInPlayStore()\n *\n */\n isHealthAvailable(): Promise<{ available: boolean }>;\n\n /**\n * Android only: Returns for each given permission, if it was granted by the underlying health API\n * @param permissions permissions to query\n */\n checkHealthPermissions(permissions: PermissionsRequest): Promise<PermissionResponse>;\n\n /**\n * Requests the permissions from the user.\n *\n * Android: Apps can ask only a few times for permissions, after that the user has to grant them manually in\n * the Health Connect app. See openHealthConnectSettings()\n *\n * iOS: If the permissions are already granted or denied, this method will just return without asking the user. In iOS\n * we can't really detect if a user granted or denied a permission. The return value reflects the assumption that all\n * permissions were granted.\n *\n * @param permissions permissions to request\n */\n requestHealthPermissions(permissions: PermissionsRequest): Promise<PermissionResponse>;\n\n /**\n * Opens the apps settings, which is kind of wrong, because health permissions are configured under:\n * Settings > Apps > (Apple) Health > Access and Devices > [app-name]\n * But we can't go there directly.\n */\n openAppleHealthSettings(): Promise<void>;\n\n /**\n * Opens the Google Health Connect app\n * iOS: Aliases openAppleHealthSettings().\n */\n openHealthConnectSettings(): Promise<void>;\n\n /**\n * Opens the Google Health Connect app in PlayStore\n * iOS: Resolves without action.\n */\n showHealthConnectInPlayStore(): Promise<void>;\n\n /**\n * iOS only: Reads user characteristics such as biological sex, blood type, date of birth, Fitzpatrick skin type, and wheelchair use.\n * Values are null when unavailable or permission was not granted. Android does not expose these characteristics; it returns `platformSupported: false` and a `platformMessage` for UI hints without emitting null values.\n *\n * Passing `fields` lets you request only specific characteristics (e.g., date of birth) to keep permissions scoped narrowly. Defaults to all characteristics when omitted.\n */\n getCharacteristics(request?: CharacteristicsRequest): Promise<CharacteristicsResponse>;\n\n /**\n * Query aggregated data\n * - Blood-pressure aggregates return the systolic average in `value` plus `systolic`, `diastolic`, and `unit`.\n * - `total-calories` is derived as active + basal energy on both iOS and Android for latest samples, aggregated queries, and workouts. We fall back to the platform's total‑calories metric (or active calories) when basal data isn't available or permission is missing. Request both `READ_ACTIVE_CALORIES` and `READ_BASAL_CALORIES` for full totals.\n * - Weight/height aggregation returns the latest sample per day (no averaging).\n * - Android aggregation currently supports daily buckets; unsupported buckets will be rejected.\n * - Android `distance-cycling` aggregates distance recorded during biking exercise sessions (requires distance + workouts permissions).\n * - Daily `bucket: \"day\"` queries use calendar-day boundaries in the device time zone (start-of-day through the next start-of-day) instead of a trailing 24-hour window. For “today,” send `startDate` at today’s start-of-day and `endDate` at now or tomorrow’s start-of-day.\n * @param request\n */\n queryAggregated(request: QueryAggregatedRequest): Promise<QueryAggregatedResponse>;\n\n /**\n * Query workouts\n * @param request\n */\n queryWorkouts(request: QueryWorkoutRequest): Promise<QueryWorkoutResponse>;\n\n /**\n * Query latest sample for a specific data type\n * - Latest sleep sample returns the most recent complete sleep session (asleep states only) from the last ~36 hours; if a longer overnight session exists, shorter naps are ignored.\n * - `sleep-rem` returns REM duration (minutes) for the latest sleep session; requires iOS 16+ sleep stages and Health Connect REM data on Android.\n * @param request\n */\n queryLatestSample(request: { dataType: LatestDataType }): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest weight sample\n * Convenience wrapper around queryLatestSample({ dataType: 'weight' }).\n */\n queryWeight(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest height sample\n * Convenience wrapper around queryLatestSample({ dataType: 'height' }).\n */\n queryHeight(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest heart rate sample\n * Convenience wrapper around queryLatestSample({ dataType: 'heart-rate' }).\n */\n queryHeartRate(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Query latest steps sample\n * Convenience wrapper around queryLatestSample({ dataType: 'steps' }).\n */\n querySteps(): Promise<QueryLatestSampleResponse>;\n\n /**\n * Create a workout session with optional totals and route/heart-rate samples.\n * - iOS stores an `HKWorkout` (activityType mapped from `activityType`) with total energy/distance and optional metadata/route/heart-rate samples.\n * - Android stores an `ExerciseSessionRecord` plus `ActiveCaloriesBurnedRecord`, `DistanceRecord`, and `HeartRateRecord` when provided. Routes are attached via `ExerciseRoute`.\n * - Requires matching WRITE_* permissions for the values you include (e.g., WRITE_WORKOUTS + WRITE_ACTIVE_CALORIES + WRITE_DISTANCE + WRITE_HEART_RATE + WRITE_ROUTE).\n */\n saveWorkout(request: SaveWorkoutRequest): Promise<SaveWorkoutResponse>;\n\n /**\n * Save user-provided body metrics to the health platform.\n */\n saveMetrics(request: SaveMetricsRequest): Promise<SaveMetricsResponse>;\n}\n\nexport declare type HealthPermission = 'READ_STEPS' | 'READ_WORKOUTS' | 'WRITE_WORKOUTS' | 'READ_ACTIVE_CALORIES' | 'WRITE_ACTIVE_CALORIES' | 'READ_TOTAL_CALORIES' | 'WRITE_TOTAL_CALORIES' | 'READ_DISTANCE' | 'WRITE_DISTANCE' | 'READ_WEIGHT' | 'WRITE_WEIGHT' | 'READ_HEIGHT' | 'WRITE_HEIGHT' | 'READ_HEART_RATE' | 'WRITE_HEART_RATE' | 'READ_RESTING_HEART_RATE' | 'WRITE_RESTING_HEART_RATE' | 'READ_ROUTE' | 'WRITE_ROUTE' | 'READ_MINDFULNESS' | 'READ_HRV' | 'READ_BLOOD_PRESSURE' | 'READ_BASAL_CALORIES' | 'READ_RESPIRATORY_RATE' | 'READ_OXYGEN_SATURATION' | 'READ_BLOOD_GLUCOSE' | 'READ_BODY_TEMPERATURE' | 'READ_BASAL_BODY_TEMPERATURE' | 'READ_BODY_FAT' | 'WRITE_BODY_FAT' | 'READ_FLOORS_CLIMBED' | 'READ_SLEEP' | 'READ_EXERCISE_TIME' | 'READ_BIOLOGICAL_SEX' | 'READ_BLOOD_TYPE' | 'READ_DATE_OF_BIRTH' | 'READ_FITZPATRICK_SKIN_TYPE' | 'READ_WHEELCHAIR_USE';\n\nexport type LatestDataType =\n | 'steps'\n | 'active-calories'\n | 'total-calories'\n | 'basal-calories'\n | 'distance'\n | 'weight'\n | 'height'\n | 'heart-rate'\n | 'resting-heart-rate'\n | 'respiratory-rate'\n | 'oxygen-saturation'\n | 'blood-glucose'\n | 'body-temperature'\n | 'basal-body-temperature'\n | 'body-fat'\n | 'flights-climbed'\n | 'exercise-time'\n | 'distance-cycling'\n | 'mindfulness'\n | 'sleep'\n | 'sleep-rem'\n | 'hrv'\n | 'blood-pressure';\n\nexport interface PermissionsRequest {\n permissions: HealthPermission[];\n}\n\nexport interface PermissionResponse {\n permissions: Record<HealthPermission, boolean>;\n}\n\nexport interface QueryWorkoutRequest {\n startDate: string;\n endDate: string;\n includeHeartRate: boolean;\n includeRoute: boolean;\n includeSteps: boolean;\n}\n\nexport interface HeartRateSample {\n timestamp: string;\n bpm: number;\n}\n\nexport interface RouteSample {\n timestamp: string;\n lat: number;\n lng: number;\n alt?: number;\n}\n\nexport interface QueryWorkoutResponse {\n workouts: Workout[];\n}\n\nexport type WorkoutActivityType =\n | 'rock-climbing'\n | 'climbing'\n | 'hiking'\n | 'running'\n | 'walking'\n | 'cycling'\n | 'biking'\n | 'strength-training'\n | 'yoga'\n | 'other';\n\nexport interface SaveWorkoutRequest {\n activityType: WorkoutActivityType;\n startDate: string;\n endDate: string;\n calories?: number;\n distance?: number;\n metadata?: Record<string, any>;\n route?: RouteSample[];\n heartRateSamples?: HeartRateSample[];\n}\n\nexport interface SaveWorkoutResponse {\n success: boolean;\n id?: string;\n}\n\nexport interface SaveMetricsRequest {\n weightKg?: number;\n heightCm?: number;\n bodyFatPercent?: number;\n restingHeartRate?: number;\n}\n\nexport interface SaveMetricsResponse {\n success: boolean;\n inserted?: number;\n}\n\nexport interface Workout {\n startDate: string;\n endDate: string;\n workoutType: string;\n sourceName: string;\n id?: string;\n duration: number;\n distance?: number;\n steps?: number;\n calories: number;\n sourceBundleId: string;\n route?: RouteSample[];\n heartRate?: HeartRateSample[];\n}\n\nexport interface QueryAggregatedRequest {\n startDate: string;\n endDate: string;\n dataType:\n | 'steps'\n | 'active-calories'\n | 'total-calories'\n | 'basal-calories'\n | 'distance'\n | 'weight'\n | 'height'\n | 'heart-rate'\n | 'resting-heart-rate'\n | 'respiratory-rate'\n | 'oxygen-saturation'\n | 'blood-glucose'\n | 'body-temperature'\n | 'basal-body-temperature'\n | 'body-fat'\n | 'flights-climbed'\n | 'exercise-time'\n | 'distance-cycling'\n | 'sleep'\n | 'mindfulness'\n | 'hrv'\n | 'blood-pressure';\n bucket: string;\n}\n\nexport interface QueryAggregatedResponse {\n aggregatedData: AggregatedSample[];\n}\n\nexport interface AggregatedSample {\n startDate: string;\n endDate: string;\n value: number;\n systolic?: number;\n diastolic?: number;\n unit?: string;\n}\n\nexport interface QueryLatestSampleResponse {\n value?: number;\n systolic?: number;\n diastolic?: number;\n timestamp: number;\n endTimestamp?: number;\n unit: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CharacteristicsResponse {\n biologicalSex?: HealthBiologicalSex | null;\n bloodType?: HealthBloodType | null;\n dateOfBirth?: string | null;\n fitzpatrickSkinType?: HealthFitzpatrickSkinType | null;\n wheelchairUse?: HealthWheelchairUse | null;\n /**\n * Indicates whether the platform exposes these characteristics via the plugin (true on iOS, false on Android).\n */\n platformSupported?: boolean;\n /**\n * Optional platform-specific message; on Android we return a user-facing note explaining that values remain empty unless synced from iOS.\n */\n platformMessage?: string;\n}\n\nexport type CharacteristicField =\n | 'biologicalSex'\n | 'bloodType'\n | 'dateOfBirth'\n | 'fitzpatrickSkinType'\n | 'wheelchairUse';\n\nexport interface CharacteristicsRequest {\n /**\n * Characteristics to query. Defaults to all characteristics when omitted.\n */\n fields?: CharacteristicField[];\n}\n\nexport type HealthBiologicalSex = 'female' | 'male' | 'other' | 'not_set' | 'unknown';\n\nexport type HealthBloodType =\n | 'a-positive'\n | 'a-negative'\n | 'b-positive'\n | 'b-negative'\n | 'ab-positive'\n | 'ab-negative'\n | 'o-positive'\n | 'o-negative'\n | 'not_set'\n | 'unknown';\n\nexport type HealthFitzpatrickSkinType = 'type1' | 'type2' | 'type3' | 'type4' | 'type5' | 'type6' | 'not_set' | 'unknown';\n\nexport type HealthWheelchairUse = 'wheelchair_user' | 'not_wheelchair_user' | 'not_set' | 'unknown';\n"]}
|
|
@@ -17,9 +17,15 @@ public class HealthPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
17
17
|
CAPPluginMethod(name: "checkHealthPermissions", returnType: CAPPluginReturnPromise),
|
|
18
18
|
CAPPluginMethod(name: "requestHealthPermissions", returnType: CAPPluginReturnPromise),
|
|
19
19
|
CAPPluginMethod(name: "openAppleHealthSettings", returnType: CAPPluginReturnPromise),
|
|
20
|
+
CAPPluginMethod(name: "openHealthConnectSettings", returnType: CAPPluginReturnPromise),
|
|
21
|
+
CAPPluginMethod(name: "showHealthConnectInPlayStore", returnType: CAPPluginReturnPromise),
|
|
20
22
|
CAPPluginMethod(name: "queryAggregated", returnType: CAPPluginReturnPromise),
|
|
21
23
|
CAPPluginMethod(name: "queryWorkouts", returnType: CAPPluginReturnPromise),
|
|
22
24
|
CAPPluginMethod(name: "queryLatestSample", returnType: CAPPluginReturnPromise),
|
|
25
|
+
CAPPluginMethod(name: "queryWeight", returnType: CAPPluginReturnPromise),
|
|
26
|
+
CAPPluginMethod(name: "queryHeight", returnType: CAPPluginReturnPromise),
|
|
27
|
+
CAPPluginMethod(name: "queryHeartRate", returnType: CAPPluginReturnPromise),
|
|
28
|
+
CAPPluginMethod(name: "querySteps", returnType: CAPPluginReturnPromise),
|
|
23
29
|
CAPPluginMethod(name: "getCharacteristics", returnType: CAPPluginReturnPromise),
|
|
24
30
|
CAPPluginMethod(name: "saveMetrics", returnType: CAPPluginReturnPromise),
|
|
25
31
|
CAPPluginMethod(name: "saveWorkout", returnType: CAPPluginReturnPromise)
|
|
@@ -264,7 +270,27 @@ public class HealthPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
264
270
|
call.reject("Missing data type")
|
|
265
271
|
return
|
|
266
272
|
}
|
|
267
|
-
|
|
273
|
+
|
|
274
|
+
queryLatestSample(for: dataTypeString, call: call)
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
@objc func queryWeight(_ call: CAPPluginCall) {
|
|
278
|
+
queryLatestSample(for: "weight", call: call)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
@objc func queryHeight(_ call: CAPPluginCall) {
|
|
282
|
+
queryLatestSample(for: "height", call: call)
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@objc func queryHeartRate(_ call: CAPPluginCall) {
|
|
286
|
+
queryLatestSample(for: "heart-rate", call: call)
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@objc func querySteps(_ call: CAPPluginCall) {
|
|
290
|
+
queryLatestSample(for: "steps", call: call)
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
private func queryLatestSample(for dataTypeString: String, call: CAPPluginCall) {
|
|
268
294
|
print("⚡️ [HealthPlugin] Querying latest sample for data type: \(dataTypeString)")
|
|
269
295
|
// ---- Special handling for blood‑pressure correlation ----
|
|
270
296
|
if dataTypeString == "blood-pressure" {
|
|
@@ -670,6 +696,14 @@ public class HealthPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
670
696
|
healthStore.execute(query)
|
|
671
697
|
}
|
|
672
698
|
|
|
699
|
+
@objc func openHealthConnectSettings(_ call: CAPPluginCall) {
|
|
700
|
+
openAppleHealthSettings(call)
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
@objc func showHealthConnectInPlayStore(_ call: CAPPluginCall) {
|
|
704
|
+
call.resolve()
|
|
705
|
+
}
|
|
706
|
+
|
|
673
707
|
@objc func openAppleHealthSettings(_ call: CAPPluginCall) {
|
|
674
708
|
if let url = URL(string: UIApplication.openSettingsURLString) {
|
|
675
709
|
DispatchQueue.main.async {
|
package/package.json
CHANGED