@thelacanians/vue-native-cli 0.4.3 → 0.4.4
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/dist/cli.js +34 -17
- package/native/android/README.md +205 -0
- package/native/android/VueNativeCore/build.gradle.kts +100 -0
- package/native/android/VueNativeCore/consumer-rules.pro +12 -0
- package/native/android/VueNativeCore/proguard-rules.pro +33 -0
- package/native/android/VueNativeCore/src/main/AndroidManifest.xml +17 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/ErrorOverlayView.kt +94 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/HotReloadManager.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSPolyfills.kt +652 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/JSRuntime.kt +207 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Bridge/NativeBridge.kt +417 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/ComponentRegistry.kt +76 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActionSheetFactory.kt +78 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VActivityIndicatorFactory.kt +46 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VAlertDialogFactory.kt +84 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VButtonFactory.kt +73 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VCheckboxFactory.kt +93 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VDropdownFactory.kt +125 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VImageFactory.kt +75 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VInputFactory.kt +210 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VKeyboardAvoidingFactory.kt +31 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VListFactory.kt +183 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VModalFactory.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPickerFactory.kt +57 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VPressableFactory.kt +109 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VProgressBarFactory.kt +43 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRadioFactory.kt +103 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRefreshControlFactory.kt +73 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VRootFactory.kt +39 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSafeAreaFactory.kt +48 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VScrollViewFactory.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSectionListFactory.kt +144 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSegmentedControlFactory.kt +77 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSliderFactory.kt +74 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VStatusBarFactory.kt +52 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VSwitchFactory.kt +62 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VTextFactory.kt +53 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VVideoFactory.kt +191 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VViewFactory.kt +48 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/Factories/VWebViewFactory.kt +90 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/NativeComponentFactory.kt +40 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Components/VTextNodeView.kt +23 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/GestureHelper.kt +16 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Helpers/TouchableView.kt +105 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AnimationModule.kt +292 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AppStateModule.kt +41 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AsyncStorageModule.kt +59 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/AudioModule.kt +331 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BackgroundTaskModule.kt +166 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BiometryModule.kt +56 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/BluetoothModule.kt +302 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CalendarModule.kt +198 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/CameraModule.kt +64 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ClipboardModule.kt +36 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ContactsModule.kt +288 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DatabaseModule.kt +229 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/DeviceInfoModule.kt +39 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/FileSystemModule.kt +193 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/GeolocationModule.kt +68 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HapticsModule.kt +61 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/HttpModule.kt +111 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/IAPModule.kt +302 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/KeyboardModule.kt +26 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/LinkingModule.kt +43 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModule.kt +27 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NativeModuleRegistry.kt +92 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NetworkModule.kt +75 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/NotificationsModule.kt +181 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/OTAModule.kt +255 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PerformanceModule.kt +147 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/PermissionsModule.kt +126 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SecureStorageModule.kt +51 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SensorsModule.kt +134 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/ShareModule.kt +36 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/SocialAuthModule.kt +160 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Modules/WebSocketModule.kt +155 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Styling/StyleEngine.kt +802 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/Tags.kt +43 -0
- package/native/android/VueNativeCore/src/main/kotlin/com/vuenative/core/VueNativeActivity.kt +169 -0
- package/native/android/VueNativeCore/src/main/res/values/ids.xml +8 -0
- package/native/android/app/build.gradle.kts +45 -0
- package/native/android/app/proguard-rules.pro +5 -0
- package/native/android/app/src/main/AndroidManifest.xml +25 -0
- package/native/android/app/src/main/assets/.gitkeep +0 -0
- package/native/android/app/src/main/kotlin/com/vuenative/example/counter/MainActivity.kt +14 -0
- package/native/android/app/src/main/res/layout/activity_main.xml +6 -0
- package/native/android/app/src/main/res/values/strings.xml +3 -0
- package/native/android/app/src/main/res/values/themes.xml +9 -0
- package/native/android/app/src/main/res/xml/network_security_config.xml +8 -0
- package/native/android/build.gradle.kts +6 -0
- package/native/android/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/native/android/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/native/android/gradle.properties +4 -0
- package/native/android/gradlew +87 -0
- package/native/android/gradlew.bat +48 -0
- package/native/android/settings.gradle.kts +20 -0
- package/native/ios/VueNativeCore/Package.resolved +23 -0
- package/native/ios/VueNativeCore/Package.swift +32 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/CertificatePinning.swift +132 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/ErrorOverlayView.swift +92 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/HotReloadManager.swift +147 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSPolyfills.swift +711 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/JSRuntime.swift +421 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/NativeBridge.swift +891 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Bridge/VueNativeViewController.swift +88 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/ComponentRegistry.swift +193 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActionSheetFactory.swift +91 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VActivityIndicatorFactory.swift +74 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VAlertDialogFactory.swift +150 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VButtonFactory.swift +93 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VCheckboxFactory.swift +114 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VDropdownFactory.swift +112 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VImageFactory.swift +172 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VInputFactory.swift +357 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VKeyboardAvoidingFactory.swift +99 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VListFactory.swift +250 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VModalFactory.swift +112 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPickerFactory.swift +96 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VPressableFactory.swift +168 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VProgressBarFactory.swift +39 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRadioFactory.swift +167 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VRefreshControlFactory.swift +153 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSafeAreaFactory.swift +56 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VScrollViewFactory.swift +240 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSectionListFactory.swift +248 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSegmentedControlFactory.swift +73 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSliderFactory.swift +63 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VStatusBarFactory.swift +50 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VSwitchFactory.swift +108 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VTextFactory.swift +290 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VVideoFactory.swift +246 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VViewFactory.swift +157 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/Factories/VWebViewFactory.swift +172 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Components/NativeComponentFactory.swift +53 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/GestureWrapper.swift +107 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/TouchableView.swift +136 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Helpers/UIColor+Hex.swift +80 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AnimationModule.swift +291 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AppStateModule.swift +65 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AsyncStorageModule.swift +68 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/AudioModule.swift +366 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BackgroundTaskModule.swift +135 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BiometryModule.swift +61 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/BluetoothModule.swift +387 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CalendarModule.swift +161 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/CameraModule.swift +318 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ClipboardModule.swift +33 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ContactsModule.swift +173 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DatabaseModule.swift +259 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/DeviceInfoModule.swift +34 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/FileSystemModule.swift +233 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/GeolocationModule.swift +147 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/HapticsModule.swift +50 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/IAPModule.swift +194 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/KeyboardModule.swift +31 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/LinkingModule.swift +42 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModule.swift +28 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NativeModuleRegistry.swift +78 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NetworkModule.swift +62 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/NotificationsModule.swift +215 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/OTAModule.swift +281 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PerformanceModule.swift +138 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/PermissionsModule.swift +190 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SecureStorageModule.swift +118 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SensorsModule.swift +103 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/ShareModule.swift +49 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/SocialAuthModule.swift +240 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Modules/WebSocketModule.swift +213 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Resources/vue-native-placeholder.js +8 -0
- package/native/ios/VueNativeCore/Sources/VueNativeCore/Styling/StyleEngine.swift +885 -0
- package/native/ios/VueNativeCore/Tests/VueNativeCoreTests/JSRuntimeTests.swift +362 -0
- package/package.json +3 -2
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
/// Native module providing haptic feedback.
|
|
5
|
+
///
|
|
6
|
+
/// Methods:
|
|
7
|
+
/// - vibrate(style: String) -- trigger impact feedback ("light"|"medium"|"heavy"|"rigid"|"soft")
|
|
8
|
+
/// - notificationFeedback(type: String) -- "success"|"warning"|"error"
|
|
9
|
+
/// - selectionChanged() -- selection change feedback
|
|
10
|
+
final class HapticsModule: NativeModule {
|
|
11
|
+
let moduleName = "Haptics"
|
|
12
|
+
|
|
13
|
+
func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
|
|
14
|
+
DispatchQueue.main.async {
|
|
15
|
+
switch method {
|
|
16
|
+
case "vibrate":
|
|
17
|
+
let style = args.first as? String ?? "medium"
|
|
18
|
+
let feedbackStyle: UIImpactFeedbackGenerator.FeedbackStyle
|
|
19
|
+
switch style {
|
|
20
|
+
case "light": feedbackStyle = .light
|
|
21
|
+
case "heavy": feedbackStyle = .heavy
|
|
22
|
+
case "rigid": feedbackStyle = .rigid
|
|
23
|
+
case "soft": feedbackStyle = .soft
|
|
24
|
+
default: feedbackStyle = .medium
|
|
25
|
+
}
|
|
26
|
+
UIImpactFeedbackGenerator(style: feedbackStyle).impactOccurred()
|
|
27
|
+
callback(nil, nil)
|
|
28
|
+
|
|
29
|
+
case "notificationFeedback":
|
|
30
|
+
let type = args.first as? String ?? "success"
|
|
31
|
+
let feedbackType: UINotificationFeedbackGenerator.FeedbackType
|
|
32
|
+
switch type {
|
|
33
|
+
case "warning": feedbackType = .warning
|
|
34
|
+
case "error": feedbackType = .error
|
|
35
|
+
default: feedbackType = .success
|
|
36
|
+
}
|
|
37
|
+
UINotificationFeedbackGenerator().notificationOccurred(feedbackType)
|
|
38
|
+
callback(nil, nil)
|
|
39
|
+
|
|
40
|
+
case "selectionChanged":
|
|
41
|
+
UISelectionFeedbackGenerator().selectionChanged()
|
|
42
|
+
callback(nil, nil)
|
|
43
|
+
|
|
44
|
+
default:
|
|
45
|
+
callback(nil, "HapticsModule: Unknown method '\(method)'")
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
#endif
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import StoreKit
|
|
3
|
+
|
|
4
|
+
/// Native module for In-App Purchases using StoreKit 2.
|
|
5
|
+
///
|
|
6
|
+
/// Methods:
|
|
7
|
+
/// - initialize() -- set up transaction listener
|
|
8
|
+
/// - getProducts(skus: [String]) -- fetch product info
|
|
9
|
+
/// - purchase(sku: String) -- purchase a product
|
|
10
|
+
/// - restorePurchases() -- restore completed transactions
|
|
11
|
+
/// - getActiveSubscriptions() -- list active auto-renewable subscriptions
|
|
12
|
+
///
|
|
13
|
+
/// Events:
|
|
14
|
+
/// - iap:transactionUpdate { productId, state, transactionId, error? }
|
|
15
|
+
@available(iOS 15.0, *)
|
|
16
|
+
final class IAPModule: NativeModule {
|
|
17
|
+
let moduleName = "IAP"
|
|
18
|
+
private weak var bridge: NativeBridge?
|
|
19
|
+
private var transactionTask: Task<Void, Never>?
|
|
20
|
+
|
|
21
|
+
init(bridge: NativeBridge? = nil) {
|
|
22
|
+
self.bridge = bridge
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
|
|
26
|
+
switch method {
|
|
27
|
+
case "initialize":
|
|
28
|
+
startTransactionListener()
|
|
29
|
+
callback(nil, nil)
|
|
30
|
+
|
|
31
|
+
case "getProducts":
|
|
32
|
+
guard let skus = args.first as? [String] else {
|
|
33
|
+
callback(nil, "getProducts: expected array of SKU strings")
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
Task {
|
|
37
|
+
do {
|
|
38
|
+
let products = try await Product.products(for: Set(skus))
|
|
39
|
+
let result: [[String: Any]] = products.map { product in
|
|
40
|
+
[
|
|
41
|
+
"id": product.id,
|
|
42
|
+
"displayName": product.displayName,
|
|
43
|
+
"description": product.description,
|
|
44
|
+
"price": NSDecimalNumber(decimal: product.price).doubleValue,
|
|
45
|
+
"displayPrice": product.displayPrice,
|
|
46
|
+
"currencyCode": product.priceFormatStyle.currencyCode,
|
|
47
|
+
"type": self.productTypeString(product.type),
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
callback(result, nil)
|
|
51
|
+
} catch {
|
|
52
|
+
callback(nil, "getProducts: \(error.localizedDescription)")
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
case "purchase":
|
|
57
|
+
guard let sku = args.first as? String else {
|
|
58
|
+
callback(nil, "purchase: expected SKU string")
|
|
59
|
+
return
|
|
60
|
+
}
|
|
61
|
+
Task {
|
|
62
|
+
do {
|
|
63
|
+
let products = try await Product.products(for: [sku])
|
|
64
|
+
guard let product = products.first else {
|
|
65
|
+
callback(nil, "purchase: product '\(sku)' not found")
|
|
66
|
+
return
|
|
67
|
+
}
|
|
68
|
+
let result = try await product.purchase()
|
|
69
|
+
switch result {
|
|
70
|
+
case .success(let verification):
|
|
71
|
+
let transaction = try self.checkVerification(verification)
|
|
72
|
+
await transaction.finish()
|
|
73
|
+
let purchaseInfo: [String: Any] = [
|
|
74
|
+
"productId": transaction.productID,
|
|
75
|
+
"transactionId": String(transaction.id),
|
|
76
|
+
"purchaseDate": transaction.purchaseDate.ISO8601Format(),
|
|
77
|
+
]
|
|
78
|
+
callback(purchaseInfo, nil)
|
|
79
|
+
case .userCancelled:
|
|
80
|
+
callback(nil, "purchase: user cancelled")
|
|
81
|
+
case .pending:
|
|
82
|
+
callback(nil, "purchase: transaction pending approval")
|
|
83
|
+
@unknown default:
|
|
84
|
+
callback(nil, "purchase: unknown result")
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
callback(nil, "purchase: \(error.localizedDescription)")
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
case "restorePurchases":
|
|
92
|
+
Task {
|
|
93
|
+
do {
|
|
94
|
+
try await AppStore.sync()
|
|
95
|
+
var restored: [[String: Any]] = []
|
|
96
|
+
for await result in Transaction.currentEntitlements {
|
|
97
|
+
if let transaction = try? self.checkVerification(result) {
|
|
98
|
+
var info: [String: Any] = [
|
|
99
|
+
"productId": transaction.productID,
|
|
100
|
+
"transactionId": String(transaction.id),
|
|
101
|
+
"purchaseDate": transaction.purchaseDate.ISO8601Format(),
|
|
102
|
+
]
|
|
103
|
+
if let expires = transaction.expirationDate {
|
|
104
|
+
info["expiresDate"] = expires.ISO8601Format()
|
|
105
|
+
}
|
|
106
|
+
restored.append(info)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
callback(restored, nil)
|
|
110
|
+
} catch {
|
|
111
|
+
callback(nil, "restorePurchases: \(error.localizedDescription)")
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
case "getActiveSubscriptions":
|
|
116
|
+
Task {
|
|
117
|
+
var active: [[String: Any]] = []
|
|
118
|
+
for await result in Transaction.currentEntitlements {
|
|
119
|
+
if let transaction = try? self.checkVerification(result) {
|
|
120
|
+
guard transaction.productType == .autoRenewable else { continue }
|
|
121
|
+
guard transaction.revocationDate == nil else { continue }
|
|
122
|
+
var info: [String: Any] = [
|
|
123
|
+
"productId": transaction.productID,
|
|
124
|
+
"transactionId": String(transaction.id),
|
|
125
|
+
"purchaseDate": transaction.purchaseDate.ISO8601Format(),
|
|
126
|
+
]
|
|
127
|
+
if let expires = transaction.expirationDate {
|
|
128
|
+
info["expiresDate"] = expires.ISO8601Format()
|
|
129
|
+
}
|
|
130
|
+
active.append(info)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
callback(active, nil)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
default:
|
|
137
|
+
callback(nil, "IAPModule: unknown method '\(method)'")
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// MARK: - Transaction Listener
|
|
142
|
+
|
|
143
|
+
private func startTransactionListener() {
|
|
144
|
+
transactionTask?.cancel()
|
|
145
|
+
transactionTask = Task.detached { [weak self] in
|
|
146
|
+
for await result in Transaction.updates {
|
|
147
|
+
guard let self = self else { return }
|
|
148
|
+
do {
|
|
149
|
+
let transaction = try self.checkVerification(result)
|
|
150
|
+
await transaction.finish()
|
|
151
|
+
let payload: [String: Any] = [
|
|
152
|
+
"productId": transaction.productID,
|
|
153
|
+
"state": "purchased",
|
|
154
|
+
"transactionId": String(transaction.id),
|
|
155
|
+
]
|
|
156
|
+
await MainActor.run {
|
|
157
|
+
self.bridge?.emitGlobalEvent("iap:transactionUpdate", payload: payload)
|
|
158
|
+
}
|
|
159
|
+
} catch {
|
|
160
|
+
let payload: [String: Any] = [
|
|
161
|
+
"productId": "",
|
|
162
|
+
"state": "failed",
|
|
163
|
+
"error": error.localizedDescription,
|
|
164
|
+
]
|
|
165
|
+
await MainActor.run {
|
|
166
|
+
self.bridge?.emitGlobalEvent("iap:transactionUpdate", payload: payload)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// MARK: - Helpers
|
|
174
|
+
|
|
175
|
+
private func checkVerification<T>(_ result: VerificationResult<T>) throws -> T {
|
|
176
|
+
switch result {
|
|
177
|
+
case .unverified(_, let error):
|
|
178
|
+
throw error
|
|
179
|
+
case .verified(let safe):
|
|
180
|
+
return safe
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private func productTypeString(_ type: Product.ProductType) -> String {
|
|
185
|
+
switch type {
|
|
186
|
+
case .consumable: return "consumable"
|
|
187
|
+
case .nonConsumable: return "nonConsumable"
|
|
188
|
+
case .autoRenewable: return "autoRenewable"
|
|
189
|
+
case .nonRenewable: return "nonRenewable"
|
|
190
|
+
default: return "unknown"
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
#endif
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
/// Native module providing keyboard management.
|
|
5
|
+
///
|
|
6
|
+
/// Methods:
|
|
7
|
+
/// - dismiss() -- dismiss the keyboard
|
|
8
|
+
/// - getHeight() -> { height: CGFloat, isVisible: Bool }
|
|
9
|
+
final class KeyboardModule: NativeModule {
|
|
10
|
+
let moduleName = "Keyboard"
|
|
11
|
+
|
|
12
|
+
func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
|
|
13
|
+
DispatchQueue.main.async {
|
|
14
|
+
switch method {
|
|
15
|
+
case "dismiss":
|
|
16
|
+
UIApplication.shared.sendAction(
|
|
17
|
+
#selector(UIResponder.resignFirstResponder),
|
|
18
|
+
to: nil, from: nil, for: nil
|
|
19
|
+
)
|
|
20
|
+
callback(nil, nil)
|
|
21
|
+
|
|
22
|
+
case "getHeight":
|
|
23
|
+
callback(["height": 0.0, "isVisible": false], nil)
|
|
24
|
+
|
|
25
|
+
default:
|
|
26
|
+
callback(nil, "KeyboardModule: Unknown method '\(method)'")
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
#endif
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
final class LinkingModule: NativeModule {
|
|
5
|
+
var moduleName: String { "Linking" }
|
|
6
|
+
|
|
7
|
+
/// The URL that launched the app. Set by the host app's SceneDelegate
|
|
8
|
+
/// or AppDelegate before the JS bundle loads.
|
|
9
|
+
static var initialURL: String?
|
|
10
|
+
|
|
11
|
+
func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
|
|
12
|
+
switch method {
|
|
13
|
+
case "openURL":
|
|
14
|
+
guard let urlString = args.first as? String,
|
|
15
|
+
let url = URL(string: urlString) else {
|
|
16
|
+
callback(nil, "Invalid URL")
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
DispatchQueue.main.async {
|
|
20
|
+
UIApplication.shared.open(url, options: [:]) { success in
|
|
21
|
+
callback(success, success ? nil : "Failed to open URL")
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
case "canOpenURL":
|
|
25
|
+
guard let urlString = args.first as? String,
|
|
26
|
+
let url = URL(string: urlString) else {
|
|
27
|
+
callback(false, nil)
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
DispatchQueue.main.async {
|
|
31
|
+
callback(UIApplication.shared.canOpenURL(url), nil)
|
|
32
|
+
}
|
|
33
|
+
case "getInitialURL":
|
|
34
|
+
callback(LinkingModule.initialURL, nil)
|
|
35
|
+
default:
|
|
36
|
+
callback(nil, "Unknown method: \(method)")
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
func invokeSync(method: String, args: [Any]) -> Any? { nil }
|
|
41
|
+
}
|
|
42
|
+
#endif
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
/// Protocol that all native modules must conform to.
|
|
5
|
+
/// Modules are registered with NativeModuleRegistry and invoked from JS
|
|
6
|
+
/// via NativeBridge's invokeNativeModule / invokeNativeModuleSync operations.
|
|
7
|
+
protocol NativeModule: AnyObject {
|
|
8
|
+
/// The name used to identify this module from JS (e.g. "Haptics", "AsyncStorage").
|
|
9
|
+
var moduleName: String { get }
|
|
10
|
+
|
|
11
|
+
/// Invoke a method asynchronously.
|
|
12
|
+
/// - Parameters:
|
|
13
|
+
/// - method: The method name to invoke.
|
|
14
|
+
/// - args: Arguments passed from JS.
|
|
15
|
+
/// - callback: Called when the method completes. Pass (result, nil) on success,
|
|
16
|
+
/// (nil, errorMessage) on failure.
|
|
17
|
+
func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void)
|
|
18
|
+
|
|
19
|
+
/// Invoke a method synchronously and return the result.
|
|
20
|
+
/// Use sparingly — prefer the async variant.
|
|
21
|
+
func invokeSync(method: String, args: [Any]) -> Any?
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
extension NativeModule {
|
|
25
|
+
/// Default sync implementation: just returns nil.
|
|
26
|
+
func invokeSync(method: String, args: [Any]) -> Any? { return nil }
|
|
27
|
+
}
|
|
28
|
+
#endif
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
/// Singleton registry for all native modules.
|
|
5
|
+
/// Modules are registered by name and looked up when JS invokes them.
|
|
6
|
+
@MainActor
|
|
7
|
+
final class NativeModuleRegistry {
|
|
8
|
+
|
|
9
|
+
static let shared = NativeModuleRegistry()
|
|
10
|
+
|
|
11
|
+
private var modules: [String: NativeModule] = [:]
|
|
12
|
+
|
|
13
|
+
private init() {}
|
|
14
|
+
|
|
15
|
+
// MARK: - Registration
|
|
16
|
+
|
|
17
|
+
func register(_ module: NativeModule) {
|
|
18
|
+
modules[module.moduleName] = module
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/// Register all built-in modules.
|
|
22
|
+
func registerDefaults() {
|
|
23
|
+
register(HapticsModule())
|
|
24
|
+
register(AsyncStorageModule())
|
|
25
|
+
register(ClipboardModule())
|
|
26
|
+
register(DeviceInfoModule())
|
|
27
|
+
register(KeyboardModule())
|
|
28
|
+
register(AnimationModule())
|
|
29
|
+
let bridge = NativeBridge.shared
|
|
30
|
+
register(NetworkModule(bridge: bridge))
|
|
31
|
+
register(AppStateModule(bridge: bridge))
|
|
32
|
+
register(LinkingModule())
|
|
33
|
+
register(ShareModule())
|
|
34
|
+
// Phase 2 modules
|
|
35
|
+
register(PermissionsModule())
|
|
36
|
+
register(GeolocationModule(bridge: bridge))
|
|
37
|
+
register(CameraModule())
|
|
38
|
+
register(NotificationsModule(bridge: bridge))
|
|
39
|
+
register(BiometryModule())
|
|
40
|
+
register(SecureStorageModule())
|
|
41
|
+
register(WebSocketModule(bridge: bridge))
|
|
42
|
+
register(FileSystemModule())
|
|
43
|
+
register(SensorsModule(bridge: bridge))
|
|
44
|
+
register(AudioModule())
|
|
45
|
+
register(DatabaseModule())
|
|
46
|
+
register(PerformanceModule(bridge: bridge))
|
|
47
|
+
if #available(iOS 13.0, *) {
|
|
48
|
+
register(BackgroundTaskModule(bridge: bridge))
|
|
49
|
+
}
|
|
50
|
+
register(OTAModule(bridge: bridge))
|
|
51
|
+
if #available(iOS 15.0, *) {
|
|
52
|
+
register(IAPModule(bridge: bridge))
|
|
53
|
+
}
|
|
54
|
+
register(SocialAuthModule(bridge: bridge))
|
|
55
|
+
register(BluetoothModule(bridge: bridge))
|
|
56
|
+
register(CalendarModule())
|
|
57
|
+
register(ContactsModule())
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// MARK: - Invocation
|
|
61
|
+
|
|
62
|
+
func invoke(module moduleName: String, method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
|
|
63
|
+
guard let module = modules[moduleName] else {
|
|
64
|
+
callback(nil, "Module '\(moduleName)' not found")
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
module.invoke(method: method, args: args, callback: callback)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func invokeSync(module moduleName: String, method: String, args: [Any]) -> Any? {
|
|
71
|
+
guard let module = modules[moduleName] else {
|
|
72
|
+
NSLog("[VueNative] NativeModuleRegistry: Module '\(moduleName)' not found")
|
|
73
|
+
return nil
|
|
74
|
+
}
|
|
75
|
+
return module.invokeSync(method: method, args: args)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
#endif
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#if canImport(UIKit)
|
|
2
|
+
import Network
|
|
3
|
+
import Foundation
|
|
4
|
+
|
|
5
|
+
/// Monitors network connectivity and pushes changes to JS via global events.
|
|
6
|
+
/// Use: NativeBridge.shared.dispatchGlobalEvent("network:change", payload: [...])
|
|
7
|
+
final class NetworkModule: NativeModule {
|
|
8
|
+
var moduleName: String { "Network" }
|
|
9
|
+
|
|
10
|
+
private let monitor = NWPathMonitor()
|
|
11
|
+
private let monitorQueue = DispatchQueue(label: "vue-native.network")
|
|
12
|
+
private weak var bridge: NativeBridge?
|
|
13
|
+
|
|
14
|
+
init(bridge: NativeBridge) {
|
|
15
|
+
self.bridge = bridge
|
|
16
|
+
startMonitoring()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
private func startMonitoring() {
|
|
20
|
+
monitor.pathUpdateHandler = { [weak self] path in
|
|
21
|
+
let isConnected = path.status == .satisfied
|
|
22
|
+
let connectionType: String
|
|
23
|
+
if path.usesInterfaceType(.wifi) {
|
|
24
|
+
connectionType = "wifi"
|
|
25
|
+
} else if path.usesInterfaceType(.cellular) {
|
|
26
|
+
connectionType = "cellular"
|
|
27
|
+
} else if path.usesInterfaceType(.wiredEthernet) {
|
|
28
|
+
connectionType = "ethernet"
|
|
29
|
+
} else {
|
|
30
|
+
connectionType = "none"
|
|
31
|
+
}
|
|
32
|
+
let bridge = self?.bridge
|
|
33
|
+
// dispatchGlobalEvent is @MainActor-isolated — dispatch to main queue
|
|
34
|
+
DispatchQueue.main.async {
|
|
35
|
+
bridge?.dispatchGlobalEvent("network:change", payload: [
|
|
36
|
+
"isConnected": isConnected,
|
|
37
|
+
"connectionType": connectionType
|
|
38
|
+
])
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
monitor.start(queue: monitorQueue)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func invoke(method: String, args: [Any], callback: @escaping (Any?, String?) -> Void) {
|
|
45
|
+
switch method {
|
|
46
|
+
case "getStatus":
|
|
47
|
+
let path = monitor.currentPath
|
|
48
|
+
let isConnected = path.status == .satisfied
|
|
49
|
+
let connectionType: String
|
|
50
|
+
if path.usesInterfaceType(.wifi) { connectionType = "wifi" }
|
|
51
|
+
else if path.usesInterfaceType(.cellular) { connectionType = "cellular" }
|
|
52
|
+
else if path.usesInterfaceType(.wiredEthernet) { connectionType = "ethernet" }
|
|
53
|
+
else { connectionType = "none" }
|
|
54
|
+
callback(["isConnected": isConnected, "connectionType": connectionType], nil)
|
|
55
|
+
default:
|
|
56
|
+
callback(nil, "Unknown method: \(method)")
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
func invokeSync(method: String, args: [Any]) -> Any? { nil }
|
|
61
|
+
}
|
|
62
|
+
#endif
|