@kingstinct/react-native-healthkit 9.0.11 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/ios/CorrelationTypeModule.swift +1 -0
- package/ios/Helpers.swift +50 -6
- package/ios/QuantityTypeModule.swift +61 -53
- package/ios/WorkoutsModule.swift +10 -9
- package/lib/commonjs/healthkit.js +4 -2
- package/lib/module/healthkit.js +4 -2
- package/lib/typescript/healthkit.d.ts +5 -5
- package/lib/typescript/healthkit.ios.d.ts +2 -2
- package/lib/typescript/specs/WorkoutsModule.nitro.d.ts +1 -1
- package/lib/typescript/types/CorrelationType.d.ts +1 -0
- package/lib/typescript/types/QuantityType.d.ts +2 -0
- package/lib/typescript/types/QueryOptions.d.ts +4 -0
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.cpp +4 -4
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Bridge.hpp +86 -24
- package/nitrogen/generated/ios/ReactNativeHealthkit-Swift-Cxx-Umbrella.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridCategoryTypeModuleSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridCoreModuleSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridHeartbeatSeriesModuleSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridQuantityTypeModuleSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridStateOfMindModuleSpecSwift.hpp +3 -0
- package/nitrogen/generated/ios/c++/HybridWorkoutsModuleSpecSwift.hpp +9 -6
- package/nitrogen/generated/ios/swift/CorrelationSample.swift +13 -2
- package/nitrogen/generated/ios/swift/Func_void_std__shared_ptr_margelo__nitro__healthkit__HybridWorkoutProxySpec_.swift +50 -0
- package/nitrogen/generated/ios/swift/HybridWorkoutsModuleSpec.swift +1 -1
- package/nitrogen/generated/ios/swift/HybridWorkoutsModuleSpec_cxx.swift +10 -7
- package/nitrogen/generated/ios/swift/PredicateWithMetadataKey.swift +94 -2
- package/nitrogen/generated/ios/swift/PredicateWithMetadataOperator.swift +48 -0
- package/nitrogen/generated/ios/swift/QueryStatisticsResponse.swift +59 -1
- package/nitrogen/generated/ios/swift/Variant_String_Double_Bool_Date.swift +18 -0
- package/nitrogen/generated/shared/c++/CorrelationSample.hpp +6 -1
- package/nitrogen/generated/shared/c++/HybridWorkoutsModuleSpec.hpp +5 -6
- package/nitrogen/generated/shared/c++/PredicateWithMetadataKey.hpp +16 -3
- package/nitrogen/generated/shared/c++/PredicateWithMetadataOperator.hpp +86 -0
- package/nitrogen/generated/shared/c++/QueryStatisticsResponse.hpp +11 -2
- package/package.json +1 -1
- package/src/healthkit.ts +7 -2
- package/src/hooks/queryStatisticsForQuantity.test.ts +32 -0
- package/src/specs/WorkoutsModule.nitro.ts +1 -1
- package/src/types/CorrelationType.ts +1 -0
- package/src/types/QuantityType.ts +2 -0
- package/src/types/QueryOptions.ts +10 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +0 -46
|
@@ -18,7 +18,7 @@ public extension QueryStatisticsResponse {
|
|
|
18
18
|
/**
|
|
19
19
|
* Create a new instance of `QueryStatisticsResponse`.
|
|
20
20
|
*/
|
|
21
|
-
init(averageQuantity: Quantity?, maximumQuantity: Quantity?, minimumQuantity: Quantity?, sumQuantity: Quantity?, mostRecentQuantity: Quantity?, mostRecentQuantityDateInterval: QuantityDateInterval?, duration: Quantity?) {
|
|
21
|
+
init(averageQuantity: Quantity?, maximumQuantity: Quantity?, minimumQuantity: Quantity?, sumQuantity: Quantity?, mostRecentQuantity: Quantity?, mostRecentQuantityDateInterval: QuantityDateInterval?, duration: Quantity?, startDate: Date?, endDate: Date?) {
|
|
22
22
|
self.init({ () -> bridge.std__optional_Quantity_ in
|
|
23
23
|
if let __unwrappedValue = averageQuantity {
|
|
24
24
|
return bridge.create_std__optional_Quantity_(__unwrappedValue)
|
|
@@ -61,6 +61,18 @@ public extension QueryStatisticsResponse {
|
|
|
61
61
|
} else {
|
|
62
62
|
return .init()
|
|
63
63
|
}
|
|
64
|
+
}(), { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
|
|
65
|
+
if let __unwrappedValue = startDate {
|
|
66
|
+
return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
|
|
67
|
+
} else {
|
|
68
|
+
return .init()
|
|
69
|
+
}
|
|
70
|
+
}(), { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
|
|
71
|
+
if let __unwrappedValue = endDate {
|
|
72
|
+
return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
|
|
73
|
+
} else {
|
|
74
|
+
return .init()
|
|
75
|
+
}
|
|
64
76
|
}())
|
|
65
77
|
}
|
|
66
78
|
|
|
@@ -224,4 +236,50 @@ public extension QueryStatisticsResponse {
|
|
|
224
236
|
}()
|
|
225
237
|
}
|
|
226
238
|
}
|
|
239
|
+
|
|
240
|
+
var startDate: Date? {
|
|
241
|
+
@inline(__always)
|
|
242
|
+
get {
|
|
243
|
+
return { () -> Date? in
|
|
244
|
+
if let __unwrapped = self.__startDate.value {
|
|
245
|
+
return Date(fromChrono: __unwrapped)
|
|
246
|
+
} else {
|
|
247
|
+
return nil
|
|
248
|
+
}
|
|
249
|
+
}()
|
|
250
|
+
}
|
|
251
|
+
@inline(__always)
|
|
252
|
+
set {
|
|
253
|
+
self.__startDate = { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
|
|
254
|
+
if let __unwrappedValue = newValue {
|
|
255
|
+
return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
|
|
256
|
+
} else {
|
|
257
|
+
return .init()
|
|
258
|
+
}
|
|
259
|
+
}()
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
var endDate: Date? {
|
|
264
|
+
@inline(__always)
|
|
265
|
+
get {
|
|
266
|
+
return { () -> Date? in
|
|
267
|
+
if let __unwrapped = self.__endDate.value {
|
|
268
|
+
return Date(fromChrono: __unwrapped)
|
|
269
|
+
} else {
|
|
270
|
+
return nil
|
|
271
|
+
}
|
|
272
|
+
}()
|
|
273
|
+
}
|
|
274
|
+
@inline(__always)
|
|
275
|
+
set {
|
|
276
|
+
self.__endDate = { () -> bridge.std__optional_std__chrono__system_clock__time_point_ in
|
|
277
|
+
if let __unwrappedValue = newValue {
|
|
278
|
+
return bridge.create_std__optional_std__chrono__system_clock__time_point_(__unwrappedValue.toCpp())
|
|
279
|
+
} else {
|
|
280
|
+
return .init()
|
|
281
|
+
}
|
|
282
|
+
}()
|
|
283
|
+
}
|
|
284
|
+
}
|
|
227
285
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// Variant_String_Double_Bool_Date.swift
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* An Swift enum with associated values representing a Variant/Union type.
|
|
10
|
+
* JS type: `string | number | boolean | date`
|
|
11
|
+
*/
|
|
12
|
+
@frozen
|
|
13
|
+
public indirect enum Variant_String_Double_Bool_Date {
|
|
14
|
+
case first(String)
|
|
15
|
+
case second(Double)
|
|
16
|
+
case third(Bool)
|
|
17
|
+
case fourth(Date)
|
|
18
|
+
}
|
|
@@ -27,6 +27,7 @@ namespace margelo::nitro::healthkit { struct QuantitySample; }
|
|
|
27
27
|
// Forward declaration of `AnyMap` to properly resolve imports.
|
|
28
28
|
namespace NitroModules { class AnyMap; }
|
|
29
29
|
|
|
30
|
+
#include <string>
|
|
30
31
|
#include "CorrelationTypeIdentifier.hpp"
|
|
31
32
|
#include <vector>
|
|
32
33
|
#include <variant>
|
|
@@ -42,6 +43,7 @@ namespace margelo::nitro::healthkit {
|
|
|
42
43
|
*/
|
|
43
44
|
struct CorrelationSample {
|
|
44
45
|
public:
|
|
46
|
+
std::string uuid SWIFT_PRIVATE;
|
|
45
47
|
CorrelationTypeIdentifier correlationType SWIFT_PRIVATE;
|
|
46
48
|
std::vector<std::variant<CategorySample, QuantitySample>> objects SWIFT_PRIVATE;
|
|
47
49
|
std::shared_ptr<AnyMap> metadata SWIFT_PRIVATE;
|
|
@@ -50,7 +52,7 @@ namespace margelo::nitro::healthkit {
|
|
|
50
52
|
|
|
51
53
|
public:
|
|
52
54
|
CorrelationSample() = default;
|
|
53
|
-
explicit CorrelationSample(CorrelationTypeIdentifier correlationType, std::vector<std::variant<CategorySample, QuantitySample>> objects, std::shared_ptr<AnyMap> metadata, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate): correlationType(correlationType), objects(objects), metadata(metadata), startDate(startDate), endDate(endDate) {}
|
|
55
|
+
explicit CorrelationSample(std::string uuid, CorrelationTypeIdentifier correlationType, std::vector<std::variant<CategorySample, QuantitySample>> objects, std::shared_ptr<AnyMap> metadata, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate): uuid(uuid), correlationType(correlationType), objects(objects), metadata(metadata), startDate(startDate), endDate(endDate) {}
|
|
54
56
|
};
|
|
55
57
|
|
|
56
58
|
} // namespace margelo::nitro::healthkit
|
|
@@ -65,6 +67,7 @@ namespace margelo::nitro {
|
|
|
65
67
|
static inline CorrelationSample fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
66
68
|
jsi::Object obj = arg.asObject(runtime);
|
|
67
69
|
return CorrelationSample(
|
|
70
|
+
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "uuid")),
|
|
68
71
|
JSIConverter<CorrelationTypeIdentifier>::fromJSI(runtime, obj.getProperty(runtime, "correlationType")),
|
|
69
72
|
JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::fromJSI(runtime, obj.getProperty(runtime, "objects")),
|
|
70
73
|
JSIConverter<std::shared_ptr<AnyMap>>::fromJSI(runtime, obj.getProperty(runtime, "metadata")),
|
|
@@ -74,6 +77,7 @@ namespace margelo::nitro {
|
|
|
74
77
|
}
|
|
75
78
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const CorrelationSample& arg) {
|
|
76
79
|
jsi::Object obj(runtime);
|
|
80
|
+
obj.setProperty(runtime, "uuid", JSIConverter<std::string>::toJSI(runtime, arg.uuid));
|
|
77
81
|
obj.setProperty(runtime, "correlationType", JSIConverter<CorrelationTypeIdentifier>::toJSI(runtime, arg.correlationType));
|
|
78
82
|
obj.setProperty(runtime, "objects", JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::toJSI(runtime, arg.objects));
|
|
79
83
|
obj.setProperty(runtime, "metadata", JSIConverter<std::shared_ptr<AnyMap>>::toJSI(runtime, arg.metadata));
|
|
@@ -86,6 +90,7 @@ namespace margelo::nitro {
|
|
|
86
90
|
return false;
|
|
87
91
|
}
|
|
88
92
|
jsi::Object obj = value.getObject(runtime);
|
|
93
|
+
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "uuid"))) return false;
|
|
89
94
|
if (!JSIConverter<CorrelationTypeIdentifier>::canConvert(runtime, obj.getProperty(runtime, "correlationType"))) return false;
|
|
90
95
|
if (!JSIConverter<std::vector<std::variant<CategorySample, QuantitySample>>>::canConvert(runtime, obj.getProperty(runtime, "objects"))) return false;
|
|
91
96
|
if (!JSIConverter<std::shared_ptr<AnyMap>>::canConvert(runtime, obj.getProperty(runtime, "metadata"))) return false;
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
14
|
#endif
|
|
15
15
|
|
|
16
|
+
// Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
|
|
17
|
+
namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
|
|
16
18
|
// Forward declaration of `WorkoutActivityType` to properly resolve imports.
|
|
17
19
|
namespace margelo::nitro::healthkit { enum class WorkoutActivityType; }
|
|
18
20
|
// Forward declaration of `QuantitySampleForSaving` to properly resolve imports.
|
|
@@ -25,15 +27,14 @@ namespace NitroModules { class AnyMap; }
|
|
|
25
27
|
namespace margelo::nitro::healthkit { struct QueryWorkoutSamplesWithAnchorResponse; }
|
|
26
28
|
// Forward declaration of `WorkoutQueryOptionsWithAnchor` to properly resolve imports.
|
|
27
29
|
namespace margelo::nitro::healthkit { struct WorkoutQueryOptionsWithAnchor; }
|
|
28
|
-
// Forward declaration of `HybridWorkoutProxySpec` to properly resolve imports.
|
|
29
|
-
namespace margelo::nitro::healthkit { class HybridWorkoutProxySpec; }
|
|
30
30
|
// Forward declaration of `WorkoutQueryOptions` to properly resolve imports.
|
|
31
31
|
namespace margelo::nitro::healthkit { struct WorkoutQueryOptions; }
|
|
32
32
|
// Forward declaration of `WorkoutConfiguration` to properly resolve imports.
|
|
33
33
|
namespace margelo::nitro::healthkit { struct WorkoutConfiguration; }
|
|
34
34
|
|
|
35
35
|
#include <NitroModules/Promise.hpp>
|
|
36
|
-
#include <
|
|
36
|
+
#include <memory>
|
|
37
|
+
#include "HybridWorkoutProxySpec.hpp"
|
|
37
38
|
#include "WorkoutActivityType.hpp"
|
|
38
39
|
#include <vector>
|
|
39
40
|
#include "QuantitySampleForSaving.hpp"
|
|
@@ -42,8 +43,6 @@ namespace margelo::nitro::healthkit { struct WorkoutConfiguration; }
|
|
|
42
43
|
#include <NitroModules/AnyMap.hpp>
|
|
43
44
|
#include "QueryWorkoutSamplesWithAnchorResponse.hpp"
|
|
44
45
|
#include "WorkoutQueryOptionsWithAnchor.hpp"
|
|
45
|
-
#include <memory>
|
|
46
|
-
#include "HybridWorkoutProxySpec.hpp"
|
|
47
46
|
#include "WorkoutQueryOptions.hpp"
|
|
48
47
|
#include "WorkoutConfiguration.hpp"
|
|
49
48
|
|
|
@@ -78,7 +77,7 @@ namespace margelo::nitro::healthkit {
|
|
|
78
77
|
|
|
79
78
|
public:
|
|
80
79
|
// Methods
|
|
81
|
-
virtual std::shared_ptr<Promise<std::
|
|
80
|
+
virtual std::shared_ptr<Promise<std::shared_ptr<margelo::nitro::healthkit::HybridWorkoutProxySpec>>> saveWorkoutSample(WorkoutActivityType workoutActivityType, const std::vector<QuantitySampleForSaving>& quantities, std::chrono::system_clock::time_point startDate, std::chrono::system_clock::time_point endDate, const WorkoutTotals& totals, const std::shared_ptr<AnyMap>& metadata) = 0;
|
|
82
81
|
virtual std::shared_ptr<Promise<QueryWorkoutSamplesWithAnchorResponse>> queryWorkoutSamplesWithAnchor(const WorkoutQueryOptionsWithAnchor& options) = 0;
|
|
83
82
|
virtual std::shared_ptr<Promise<std::vector<std::shared_ptr<margelo::nitro::healthkit::HybridWorkoutProxySpec>>>> queryWorkoutSamples(const WorkoutQueryOptions& options) = 0;
|
|
84
83
|
virtual std::shared_ptr<Promise<bool>> startWatchAppWithWorkoutConfiguration(const WorkoutConfiguration& workoutConfiguration) = 0;
|
|
@@ -18,9 +18,14 @@
|
|
|
18
18
|
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
19
|
#endif
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
// Forward declaration of `PredicateWithMetadataOperator` to properly resolve imports.
|
|
22
|
+
namespace margelo::nitro::healthkit { enum class PredicateWithMetadataOperator; }
|
|
22
23
|
|
|
23
24
|
#include <string>
|
|
25
|
+
#include <optional>
|
|
26
|
+
#include "PredicateWithMetadataOperator.hpp"
|
|
27
|
+
#include <variant>
|
|
28
|
+
#include <chrono>
|
|
24
29
|
|
|
25
30
|
namespace margelo::nitro::healthkit {
|
|
26
31
|
|
|
@@ -30,10 +35,12 @@ namespace margelo::nitro::healthkit {
|
|
|
30
35
|
struct PredicateWithMetadataKey {
|
|
31
36
|
public:
|
|
32
37
|
std::string withMetadataKey SWIFT_PRIVATE;
|
|
38
|
+
std::optional<PredicateWithMetadataOperator> operatorType SWIFT_PRIVATE;
|
|
39
|
+
std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> value SWIFT_PRIVATE;
|
|
33
40
|
|
|
34
41
|
public:
|
|
35
42
|
PredicateWithMetadataKey() = default;
|
|
36
|
-
explicit PredicateWithMetadataKey(std::string withMetadataKey): withMetadataKey(withMetadataKey) {}
|
|
43
|
+
explicit PredicateWithMetadataKey(std::string withMetadataKey, std::optional<PredicateWithMetadataOperator> operatorType, std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>> value): withMetadataKey(withMetadataKey), operatorType(operatorType), value(value) {}
|
|
37
44
|
};
|
|
38
45
|
|
|
39
46
|
} // namespace margelo::nitro::healthkit
|
|
@@ -48,12 +55,16 @@ namespace margelo::nitro {
|
|
|
48
55
|
static inline PredicateWithMetadataKey fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
49
56
|
jsi::Object obj = arg.asObject(runtime);
|
|
50
57
|
return PredicateWithMetadataKey(
|
|
51
|
-
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "withMetadataKey"))
|
|
58
|
+
JSIConverter<std::string>::fromJSI(runtime, obj.getProperty(runtime, "withMetadataKey")),
|
|
59
|
+
JSIConverter<std::optional<PredicateWithMetadataOperator>>::fromJSI(runtime, obj.getProperty(runtime, "operatorType")),
|
|
60
|
+
JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::fromJSI(runtime, obj.getProperty(runtime, "value"))
|
|
52
61
|
);
|
|
53
62
|
}
|
|
54
63
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const PredicateWithMetadataKey& arg) {
|
|
55
64
|
jsi::Object obj(runtime);
|
|
56
65
|
obj.setProperty(runtime, "withMetadataKey", JSIConverter<std::string>::toJSI(runtime, arg.withMetadataKey));
|
|
66
|
+
obj.setProperty(runtime, "operatorType", JSIConverter<std::optional<PredicateWithMetadataOperator>>::toJSI(runtime, arg.operatorType));
|
|
67
|
+
obj.setProperty(runtime, "value", JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::toJSI(runtime, arg.value));
|
|
57
68
|
return obj;
|
|
58
69
|
}
|
|
59
70
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -62,6 +73,8 @@ namespace margelo::nitro {
|
|
|
62
73
|
}
|
|
63
74
|
jsi::Object obj = value.getObject(runtime);
|
|
64
75
|
if (!JSIConverter<std::string>::canConvert(runtime, obj.getProperty(runtime, "withMetadataKey"))) return false;
|
|
76
|
+
if (!JSIConverter<std::optional<PredicateWithMetadataOperator>>::canConvert(runtime, obj.getProperty(runtime, "operatorType"))) return false;
|
|
77
|
+
if (!JSIConverter<std::optional<std::variant<std::string, double, bool, std::chrono::system_clock::time_point>>>::canConvert(runtime, obj.getProperty(runtime, "value"))) return false;
|
|
65
78
|
return true;
|
|
66
79
|
}
|
|
67
80
|
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// PredicateWithMetadataOperator.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/NitroHash.hpp>)
|
|
11
|
+
#include <NitroModules/NitroHash.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
#if __has_include(<NitroModules/JSIConverter.hpp>)
|
|
16
|
+
#include <NitroModules/JSIConverter.hpp>
|
|
17
|
+
#else
|
|
18
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
19
|
+
#endif
|
|
20
|
+
#if __has_include(<NitroModules/NitroDefines.hpp>)
|
|
21
|
+
#include <NitroModules/NitroDefines.hpp>
|
|
22
|
+
#else
|
|
23
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
24
|
+
#endif
|
|
25
|
+
|
|
26
|
+
namespace margelo::nitro::healthkit {
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An enum which can be represented as a JavaScript union (PredicateWithMetadataOperator).
|
|
30
|
+
*/
|
|
31
|
+
enum class PredicateWithMetadataOperator {
|
|
32
|
+
EQUALTO SWIFT_NAME(equalto) = 0,
|
|
33
|
+
NOTEQUALTO SWIFT_NAME(notequalto) = 1,
|
|
34
|
+
GREATERTHAN SWIFT_NAME(greaterthan) = 2,
|
|
35
|
+
LESSTHAN SWIFT_NAME(lessthan) = 3,
|
|
36
|
+
} CLOSED_ENUM;
|
|
37
|
+
|
|
38
|
+
} // namespace margelo::nitro::healthkit
|
|
39
|
+
|
|
40
|
+
namespace margelo::nitro {
|
|
41
|
+
|
|
42
|
+
using namespace margelo::nitro::healthkit;
|
|
43
|
+
|
|
44
|
+
// C++ PredicateWithMetadataOperator <> JS PredicateWithMetadataOperator (union)
|
|
45
|
+
template <>
|
|
46
|
+
struct JSIConverter<PredicateWithMetadataOperator> final {
|
|
47
|
+
static inline PredicateWithMetadataOperator fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
|
|
48
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, arg);
|
|
49
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
50
|
+
case hashString("equalTo"): return PredicateWithMetadataOperator::EQUALTO;
|
|
51
|
+
case hashString("notEqualTo"): return PredicateWithMetadataOperator::NOTEQUALTO;
|
|
52
|
+
case hashString("greaterThan"): return PredicateWithMetadataOperator::GREATERTHAN;
|
|
53
|
+
case hashString("lessThan"): return PredicateWithMetadataOperator::LESSTHAN;
|
|
54
|
+
default: [[unlikely]]
|
|
55
|
+
throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum PredicateWithMetadataOperator - invalid value!");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
static inline jsi::Value toJSI(jsi::Runtime& runtime, PredicateWithMetadataOperator arg) {
|
|
59
|
+
switch (arg) {
|
|
60
|
+
case PredicateWithMetadataOperator::EQUALTO: return JSIConverter<std::string>::toJSI(runtime, "equalTo");
|
|
61
|
+
case PredicateWithMetadataOperator::NOTEQUALTO: return JSIConverter<std::string>::toJSI(runtime, "notEqualTo");
|
|
62
|
+
case PredicateWithMetadataOperator::GREATERTHAN: return JSIConverter<std::string>::toJSI(runtime, "greaterThan");
|
|
63
|
+
case PredicateWithMetadataOperator::LESSTHAN: return JSIConverter<std::string>::toJSI(runtime, "lessThan");
|
|
64
|
+
default: [[unlikely]]
|
|
65
|
+
throw std::invalid_argument("Cannot convert PredicateWithMetadataOperator to JS - invalid value: "
|
|
66
|
+
+ std::to_string(static_cast<int>(arg)) + "!");
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
70
|
+
if (!value.isString()) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
std::string unionValue = JSIConverter<std::string>::fromJSI(runtime, value);
|
|
74
|
+
switch (hashString(unionValue.c_str(), unionValue.size())) {
|
|
75
|
+
case hashString("equalTo"):
|
|
76
|
+
case hashString("notEqualTo"):
|
|
77
|
+
case hashString("greaterThan"):
|
|
78
|
+
case hashString("lessThan"):
|
|
79
|
+
return true;
|
|
80
|
+
default:
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
} // namespace margelo::nitro
|
|
@@ -26,6 +26,7 @@ namespace margelo::nitro::healthkit { struct QuantityDateInterval; }
|
|
|
26
26
|
#include <optional>
|
|
27
27
|
#include "Quantity.hpp"
|
|
28
28
|
#include "QuantityDateInterval.hpp"
|
|
29
|
+
#include <chrono>
|
|
29
30
|
|
|
30
31
|
namespace margelo::nitro::healthkit {
|
|
31
32
|
|
|
@@ -41,10 +42,12 @@ namespace margelo::nitro::healthkit {
|
|
|
41
42
|
std::optional<Quantity> mostRecentQuantity SWIFT_PRIVATE;
|
|
42
43
|
std::optional<QuantityDateInterval> mostRecentQuantityDateInterval SWIFT_PRIVATE;
|
|
43
44
|
std::optional<Quantity> duration SWIFT_PRIVATE;
|
|
45
|
+
std::optional<std::chrono::system_clock::time_point> startDate SWIFT_PRIVATE;
|
|
46
|
+
std::optional<std::chrono::system_clock::time_point> endDate SWIFT_PRIVATE;
|
|
44
47
|
|
|
45
48
|
public:
|
|
46
49
|
QueryStatisticsResponse() = default;
|
|
47
|
-
explicit QueryStatisticsResponse(std::optional<Quantity> averageQuantity, std::optional<Quantity> maximumQuantity, std::optional<Quantity> minimumQuantity, std::optional<Quantity> sumQuantity, std::optional<Quantity> mostRecentQuantity, std::optional<QuantityDateInterval> mostRecentQuantityDateInterval, std::optional<Quantity> duration): averageQuantity(averageQuantity), maximumQuantity(maximumQuantity), minimumQuantity(minimumQuantity), sumQuantity(sumQuantity), mostRecentQuantity(mostRecentQuantity), mostRecentQuantityDateInterval(mostRecentQuantityDateInterval), duration(duration) {}
|
|
50
|
+
explicit QueryStatisticsResponse(std::optional<Quantity> averageQuantity, std::optional<Quantity> maximumQuantity, std::optional<Quantity> minimumQuantity, std::optional<Quantity> sumQuantity, std::optional<Quantity> mostRecentQuantity, std::optional<QuantityDateInterval> mostRecentQuantityDateInterval, std::optional<Quantity> duration, std::optional<std::chrono::system_clock::time_point> startDate, std::optional<std::chrono::system_clock::time_point> endDate): averageQuantity(averageQuantity), maximumQuantity(maximumQuantity), minimumQuantity(minimumQuantity), sumQuantity(sumQuantity), mostRecentQuantity(mostRecentQuantity), mostRecentQuantityDateInterval(mostRecentQuantityDateInterval), duration(duration), startDate(startDate), endDate(endDate) {}
|
|
48
51
|
};
|
|
49
52
|
|
|
50
53
|
} // namespace margelo::nitro::healthkit
|
|
@@ -65,7 +68,9 @@ namespace margelo::nitro {
|
|
|
65
68
|
JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "sumQuantity")),
|
|
66
69
|
JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "mostRecentQuantity")),
|
|
67
70
|
JSIConverter<std::optional<QuantityDateInterval>>::fromJSI(runtime, obj.getProperty(runtime, "mostRecentQuantityDateInterval")),
|
|
68
|
-
JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "duration"))
|
|
71
|
+
JSIConverter<std::optional<Quantity>>::fromJSI(runtime, obj.getProperty(runtime, "duration")),
|
|
72
|
+
JSIConverter<std::optional<std::chrono::system_clock::time_point>>::fromJSI(runtime, obj.getProperty(runtime, "startDate")),
|
|
73
|
+
JSIConverter<std::optional<std::chrono::system_clock::time_point>>::fromJSI(runtime, obj.getProperty(runtime, "endDate"))
|
|
69
74
|
);
|
|
70
75
|
}
|
|
71
76
|
static inline jsi::Value toJSI(jsi::Runtime& runtime, const QueryStatisticsResponse& arg) {
|
|
@@ -77,6 +82,8 @@ namespace margelo::nitro {
|
|
|
77
82
|
obj.setProperty(runtime, "mostRecentQuantity", JSIConverter<std::optional<Quantity>>::toJSI(runtime, arg.mostRecentQuantity));
|
|
78
83
|
obj.setProperty(runtime, "mostRecentQuantityDateInterval", JSIConverter<std::optional<QuantityDateInterval>>::toJSI(runtime, arg.mostRecentQuantityDateInterval));
|
|
79
84
|
obj.setProperty(runtime, "duration", JSIConverter<std::optional<Quantity>>::toJSI(runtime, arg.duration));
|
|
85
|
+
obj.setProperty(runtime, "startDate", JSIConverter<std::optional<std::chrono::system_clock::time_point>>::toJSI(runtime, arg.startDate));
|
|
86
|
+
obj.setProperty(runtime, "endDate", JSIConverter<std::optional<std::chrono::system_clock::time_point>>::toJSI(runtime, arg.endDate));
|
|
80
87
|
return obj;
|
|
81
88
|
}
|
|
82
89
|
static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
|
|
@@ -91,6 +98,8 @@ namespace margelo::nitro {
|
|
|
91
98
|
if (!JSIConverter<std::optional<Quantity>>::canConvert(runtime, obj.getProperty(runtime, "mostRecentQuantity"))) return false;
|
|
92
99
|
if (!JSIConverter<std::optional<QuantityDateInterval>>::canConvert(runtime, obj.getProperty(runtime, "mostRecentQuantityDateInterval"))) return false;
|
|
93
100
|
if (!JSIConverter<std::optional<Quantity>>::canConvert(runtime, obj.getProperty(runtime, "duration"))) return false;
|
|
101
|
+
if (!JSIConverter<std::optional<std::chrono::system_clock::time_point>>::canConvert(runtime, obj.getProperty(runtime, "startDate"))) return false;
|
|
102
|
+
if (!JSIConverter<std::optional<std::chrono::system_clock::time_point>>::canConvert(runtime, obj.getProperty(runtime, "endDate"))) return false;
|
|
94
103
|
return true;
|
|
95
104
|
}
|
|
96
105
|
};
|
package/package.json
CHANGED
package/src/healthkit.ts
CHANGED
|
@@ -21,7 +21,10 @@ import {
|
|
|
21
21
|
WheelchairUse,
|
|
22
22
|
} from './types/Characteristics'
|
|
23
23
|
import type { QuantitySample } from './types/QuantitySample'
|
|
24
|
-
import type {
|
|
24
|
+
import type {
|
|
25
|
+
QueryOptionsWithAnchor,
|
|
26
|
+
QueryOptionsWithSortOrder,
|
|
27
|
+
} from './types/QueryOptions'
|
|
25
28
|
|
|
26
29
|
export * from './types'
|
|
27
30
|
|
|
@@ -174,6 +177,7 @@ export const isQuantityCompatibleWithUnit = UnavailableFnFromModule(
|
|
|
174
177
|
// CategoryTypeModule functions
|
|
175
178
|
export function queryCategorySamples<T extends CategoryTypeIdentifier>(
|
|
176
179
|
_categoryTypeIdentifier: T,
|
|
180
|
+
_options?: QueryOptionsWithSortOrder,
|
|
177
181
|
): Promise<CategorySampleTyped<T>[]> {
|
|
178
182
|
if (Platform.OS !== 'ios' && !hasWarned) {
|
|
179
183
|
console.warn(notAvailableError)
|
|
@@ -242,7 +246,8 @@ export const queryWorkoutSamplesWithAnchor = UnavailableFnFromModule(
|
|
|
242
246
|
)
|
|
243
247
|
export const saveWorkoutSample = UnavailableFnFromModule(
|
|
244
248
|
'saveWorkoutSample',
|
|
245
|
-
|
|
249
|
+
// biome-ignore lint/suspicious/noExplicitAny: it works
|
|
250
|
+
Promise.resolve(undefined as any as WorkoutProxy),
|
|
246
251
|
)
|
|
247
252
|
export const startWatchApp = UnavailableFnFromModule(
|
|
248
253
|
'startWatchApp',
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test case to verify that queryStatisticsForQuantity resolves when no data is present
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, expect, test } from 'bun:test'
|
|
6
|
+
import type { QueryStatisticsResponse } from '../types/QuantityType'
|
|
7
|
+
|
|
8
|
+
describe('queryStatisticsForQuantity', () => {
|
|
9
|
+
test('should resolve with empty response when no data is present', async () => {
|
|
10
|
+
// This test would normally require running on iOS simulator or device
|
|
11
|
+
// For now, we're just testing the TypeScript interface
|
|
12
|
+
|
|
13
|
+
const mockEmptyResponse: QueryStatisticsResponse = {}
|
|
14
|
+
|
|
15
|
+
// Verify that empty response is properly typed
|
|
16
|
+
expect(mockEmptyResponse.averageQuantity).toBeUndefined()
|
|
17
|
+
expect(mockEmptyResponse.sumQuantity).toBeUndefined()
|
|
18
|
+
expect(mockEmptyResponse.startDate).toBeUndefined()
|
|
19
|
+
expect(mockEmptyResponse.endDate).toBeUndefined()
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
test('should handle date range with no data', async () => {
|
|
23
|
+
// This is more of a documentation of the expected behavior
|
|
24
|
+
// The query should resolve with an empty response object
|
|
25
|
+
// when there's no data in the specified timeframe
|
|
26
|
+
const expectedResult: QueryStatisticsResponse = {
|
|
27
|
+
// All properties should be undefined for empty result
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
expect(expectedResult).toBeDefined()
|
|
31
|
+
})
|
|
32
|
+
})
|
|
@@ -18,7 +18,7 @@ export interface WorkoutsModule extends HybridObject<{ ios: 'swift' }> {
|
|
|
18
18
|
endDate: Date,
|
|
19
19
|
totals: WorkoutTotals,
|
|
20
20
|
metadata: AnyMap,
|
|
21
|
-
): Promise<
|
|
21
|
+
): Promise<WorkoutProxy>
|
|
22
22
|
|
|
23
23
|
queryWorkoutSamplesWithAnchor(
|
|
24
24
|
options: WorkoutQueryOptionsWithAnchor,
|
|
@@ -13,6 +13,7 @@ export type CorrelationTypeIdentifier =
|
|
|
13
13
|
type CorrelationObject = CategorySample | QuantitySample
|
|
14
14
|
|
|
15
15
|
export interface CorrelationSample {
|
|
16
|
+
readonly uuid: string
|
|
16
17
|
readonly correlationType: CorrelationTypeIdentifier
|
|
17
18
|
readonly objects: readonly CorrelationObject[]
|
|
18
19
|
readonly metadata: AnyMap
|
|
@@ -28,6 +28,8 @@ export interface QueryStatisticsResponse {
|
|
|
28
28
|
readonly mostRecentQuantity?: Quantity
|
|
29
29
|
readonly mostRecentQuantityDateInterval?: QuantityDateInterval
|
|
30
30
|
readonly duration?: Quantity
|
|
31
|
+
readonly startDate?: Date
|
|
32
|
+
readonly endDate?: Date
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export interface QuantitySamplesWithAnchorResponse {
|
|
@@ -15,8 +15,18 @@ type PredicateWithStartAndEnd = {
|
|
|
15
15
|
readonly strictStartDate?: boolean
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
type PredicateWithMetadataOperator =
|
|
19
|
+
| 'equalTo'
|
|
20
|
+
| 'notEqualTo'
|
|
21
|
+
| 'greaterThan'
|
|
22
|
+
| 'lessThan'
|
|
23
|
+
|
|
24
|
+
type PredicateWithMetadataValue = string | number | Date | boolean
|
|
25
|
+
|
|
18
26
|
type PredicateWithMetadataKey = {
|
|
19
27
|
readonly withMetadataKey: string
|
|
28
|
+
readonly operatorType?: PredicateWithMetadataOperator
|
|
29
|
+
readonly value?: PredicateWithMetadataValue
|
|
20
30
|
}
|
|
21
31
|
|
|
22
32
|
export type FilterForSamplesAnd = {
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
///
|
|
2
|
-
/// Func_void_std__string.swift
|
|
3
|
-
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
-
/// https://github.com/mrousavy/nitro
|
|
5
|
-
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
-
///
|
|
7
|
-
|
|
8
|
-
import NitroModules
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Wraps a Swift `(_ value: String) -> Void` as a class.
|
|
12
|
-
* This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
|
|
13
|
-
*/
|
|
14
|
-
public final class Func_void_std__string {
|
|
15
|
-
public typealias bridge = margelo.nitro.healthkit.bridge.swift
|
|
16
|
-
|
|
17
|
-
private let closure: (_ value: String) -> Void
|
|
18
|
-
|
|
19
|
-
public init(_ closure: @escaping (_ value: String) -> Void) {
|
|
20
|
-
self.closure = closure
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
@inline(__always)
|
|
24
|
-
public func call(value: std.string) -> Void {
|
|
25
|
-
self.closure(String(value))
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Casts this instance to a retained unsafe raw pointer.
|
|
30
|
-
* This acquires one additional strong reference on the object!
|
|
31
|
-
*/
|
|
32
|
-
@inline(__always)
|
|
33
|
-
public func toUnsafe() -> UnsafeMutableRawPointer {
|
|
34
|
-
return Unmanaged.passRetained(self).toOpaque()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Casts an unsafe pointer to a `Func_void_std__string`.
|
|
39
|
-
* The pointer has to be a retained opaque `Unmanaged<Func_void_std__string>`.
|
|
40
|
-
* This removes one strong reference from the object!
|
|
41
|
-
*/
|
|
42
|
-
@inline(__always)
|
|
43
|
-
public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_std__string {
|
|
44
|
-
return Unmanaged<Func_void_std__string>.fromOpaque(pointer).takeRetainedValue()
|
|
45
|
-
}
|
|
46
|
-
}
|