diff --git a/configs/jsactions/rollup.config.mjs b/configs/jsactions/rollup.config.mjs index 29e99997c..d8691fac1 100644 --- a/configs/jsactions/rollup.config.mjs +++ b/configs/jsactions/rollup.config.mjs @@ -34,12 +34,7 @@ export default async args => { types: ["mendix-client", "react-native"], allowSyntheticDefaultImports: true, compilerOptions: { - newLine: "CRLF", - // `react-native-nitro-geolocation` ships no compiled JS; its entry points are `.tsx` - // (`main: "src/index"`, `browser: "src/index.web.tsx"`). The TS plugin therefore needs - // `jsx` set to parse those `.tsx` files, otherwise the build fails with - // `TS6142: Module ... was resolved to '.../src/index.tsx', but '--jsx' is not set`. - jsx: "react-native" + newLine: "CRLF" } }); @@ -97,6 +92,16 @@ export default async args => { overwrite: true } ); + } else if (args.configProject === "nanoflowcommons") { + // `invariant` is being used silently by @react-native-community/geolocation; it is not listed as a dependency nor peerDependency. + // https://github.dev/react-native-geolocation/react-native-geolocation/blob/1786929f2be581da91082ff857c2393da5e597b3/js/implementation.native.js#L13 + await copyAsync( + dirname(require.resolve("invariant")), + join(outDir, "node_modules", "invariant"), + { + overwrite: true + } + ); } // this is helpful to copy the files and folders to a test project path for dev/testing purposes. diff --git a/packages/jsActions/nanoflow-actions-native/CHANGELOG.md b/packages/jsActions/nanoflow-actions-native/CHANGELOG.md index ed85ea401..832ce71f5 100644 --- a/packages/jsActions/nanoflow-actions-native/CHANGELOG.md +++ b/packages/jsActions/nanoflow-actions-native/CHANGELOG.md @@ -6,8 +6,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] -- Migrated the geolocation actions from `@react-native-community/geolocation` to `react-native-nitro-geolocation`. - ## [7.3.0] Nanoflow Commons - 2026-9-2 ### Fixed diff --git a/packages/jsActions/nanoflow-actions-native/package.json b/packages/jsActions/nanoflow-actions-native/package.json index aab00c76f..2d6d2ee2a 100644 --- a/packages/jsActions/nanoflow-actions-native/package.json +++ b/packages/jsActions/nanoflow-actions-native/package.json @@ -1,7 +1,7 @@ { "name": "nanoflow-actions-native", "moduleName": "Nanoflow Commons", - "version": "7.3.1", + "version": "7.3.0", "license": "Apache-2.0", "copyright": "© Mendix Technology BV 2022. All rights reserved.", "repository": { @@ -27,9 +27,9 @@ }, "dependencies": { "@react-native-async-storage/async-storage": "2.2.0", + "@react-native-community/geolocation": "3.4.0", + "invariant": "^2.2.4", "js-base64": "~3.7.2", - "react-native-nitro-geolocation": "1.4.3", - "react-native-nitro-modules": "0.36.1", "react-native-permissions": "5.5.1", "react-native-geocoder": "0.5.0" }, diff --git a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts index d9ca95e21..b333c81d4 100644 --- a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts +++ b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocation.ts @@ -6,7 +6,14 @@ // - the code between BEGIN EXTRA CODE and END EXTRA CODE // Other code you write will be lost the next time you deploy the project. import { Big } from "big.js"; -import { getCurrentPosition, GeolocationResponse, LocationRequestOptions } from "react-native-nitro-geolocation"; +import Geolocation, { + GeolocationError, + GeolocationOptions, + GeolocationResponse +} from "@react-native-community/geolocation"; + +import type { Platform, NativeModules } from "react-native"; +import type { GeoError, GeoPosition, GeoOptions } from "../../typings/Geolocation"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -32,114 +39,94 @@ export async function GetCurrentLocation( ): Promise { // BEGIN USER CODE - const isReactNative = navigator && navigator.product === "ReactNative"; - const isWeb = navigator && navigator.geolocation; + let reactNativeModule: { NativeModules: typeof NativeModules; Platform: typeof Platform } | undefined; + let geolocationModule: typeof import("@react-native-community/geolocation").default | Geolocation; - if (!isReactNative && !isWeb) { - return Promise.reject(new Error("Geolocation module could not be found")); - } + if (navigator && navigator.product === "ReactNative") { + reactNativeModule = require("react-native"); - // We keep a manual web branch (backed by `navigator.geolocation`) rather than relying on the - // library's web entry, because it is not guaranteed that the Mendix web client resolves the - // package's `browser`/`exports` condition. If that is ever confirmed, this branch can be dropped. - const options = buildLocationOptions(timeout, maximumAge, highAccuracy); - try { - let position: GeolocationResponse; + if (!reactNativeModule) { + return Promise.reject(new Error("React Native module could not be found")); + } - if (isReactNative) { - position = await getCurrentPosition(options); + if (reactNativeModule.NativeModules.RNFusedLocation) { + geolocationModule = (await import("@react-native-community/geolocation")).default; + } else if (reactNativeModule.NativeModules.RNCGeolocation) { + geolocationModule = Geolocation; } else { - position = await new Promise((resolve, reject) => { - navigator.geolocation.getCurrentPosition( - pos => resolve(normalizeWebPosition(pos)), - err => reject(err), - { - timeout: options.timeout, - maximumAge: options.maximumAge, - enableHighAccuracy: highAccuracy ?? false - } - ); - }); + return Promise.reject(new Error("Geolocation module could not be found")); } + } else if (navigator && navigator.geolocation) { + geolocationModule = navigator.geolocation; + } else { + return Promise.reject(new Error("Geolocation module could not be found")); + } + + return new Promise((resolve, reject) => { + const options = getOptions(); + geolocationModule?.getCurrentPosition(onSuccess, onError, options); - return new Promise((resolve, reject) => { + function onSuccess(position: GeolocationResponse | GeoPosition): void { mx.data.create({ entity: "NanoflowCommons.Geolocation", callback: mxObject => { - resolve(mapPositionToMxObject(mxObject, position)); + const geolocation = mapPositionToMxObject(mxObject, position); + resolve(geolocation); }, error: () => reject(new Error("Could not create 'NanoflowCommons.Geolocation' object to store location")) }); - }); - } catch (error: any) { - const message = error?.message ?? String(error); - return Promise.reject(new Error(`Could not get current location: ${message}`)); - } - - function buildLocationOptions( - timeout: Big | undefined, - maximumAge: Big | undefined, - highAccuracy: boolean | undefined - ): LocationRequestOptions { - let timeoutNumber = timeout ? timeout.toNumber() : undefined; - const maximumAgeNumber = maximumAge ? maximumAge.toNumber() : undefined; + } - // If the timeout is 0 or undefined (empty), it causes a crash on iOS. - // If the timeout is undefined (empty); we set timeout to 30 sec (default timeout) - // If the timeout is 0; we set timeout to 1 hour (no timeout) - if (isReactNative && require("react-native").Platform.OS === "ios") { - if (timeoutNumber === undefined) { - timeoutNumber = 30000; - } else if (timeoutNumber === 0) { - timeoutNumber = 3600000; - } + function onError(error: GeolocationError | GeoError): void { + return reject(new Error(error.message)); } - return { - timeout: timeoutNumber, - maximumAge: maximumAgeNumber, - accuracy: highAccuracy ? { android: "high", ios: "best" } : { android: "balanced", ios: "hundredMeters" } - }; - } + function getOptions(): GeolocationOptions | GeoOptions { + let timeoutNumber = timeout && Number(timeout.toString()); + const maximumAgeNumber = maximumAge && Number(maximumAge.toString()); - // NOTE: `normalizeWebPosition` is duplicated verbatim in `GetCurrentLocationMinimumAccuracy.ts`. - // The Mendix action model does not allow sharing code across action files, so if you change this - // function, keep the copy in the other action in sync. - function normalizeWebPosition(pos: GeolocationPosition): GeolocationResponse { - return { - coords: { - latitude: pos.coords.latitude, - longitude: pos.coords.longitude, - altitude: pos.coords.altitude ?? null, - accuracy: pos.coords.accuracy, - altitudeAccuracy: pos.coords.altitudeAccuracy ?? null, - heading: pos.coords.heading ?? null, - speed: pos.coords.speed ?? null - }, - timestamp: pos.timestamp - }; - } + // If the timeout is 0 or undefined (empty), it causes a crash on iOS. + // If the timeout is undefined (empty); we set timeout to 30 sec (default timeout) + // If the timeout is 0; we set timeout to 1 hour (no timeout) + if (reactNativeModule?.Platform.OS === "ios") { + if (timeoutNumber === undefined) { + timeoutNumber = 30000; + } else if (timeoutNumber === 0) { + timeoutNumber = 3600000; + } + } - function mapPositionToMxObject(mxObject: mendix.lib.MxObject, pos: GeolocationResponse): mendix.lib.MxObject { - mxObject.set("Timestamp", new Date(pos.timestamp)); - mxObject.set("Latitude", new Big(pos.coords.latitude.toFixed(8))); - mxObject.set("Longitude", new Big(pos.coords.longitude.toFixed(8))); - mxObject.set("Accuracy", new Big(pos.coords.accuracy.toFixed(8))); - if (pos.coords.altitude != null) { - mxObject.set("Altitude", new Big(pos.coords.altitude.toFixed(8))); + return { + timeout: timeoutNumber, + maximumAge: maximumAgeNumber, + enableHighAccuracy: highAccuracy + }; } - if (pos.coords.altitudeAccuracy != null && pos.coords.altitudeAccuracy !== -1) { - mxObject.set("AltitudeAccuracy", new Big(pos.coords.altitudeAccuracy.toFixed(8))); - } - if (pos.coords.heading != null && pos.coords.heading !== -1) { - mxObject.set("Heading", new Big(pos.coords.heading.toFixed(8))); - } - if (pos.coords.speed != null && pos.coords.speed !== -1) { - mxObject.set("Speed", new Big(pos.coords.speed.toFixed(8))); + + function mapPositionToMxObject( + mxObject: mendix.lib.MxObject, + position: GeolocationResponse | GeoPosition + ): mendix.lib.MxObject { + mxObject.set("Timestamp", new Date(position.timestamp)); + mxObject.set("Latitude", new Big(position.coords.latitude.toFixed(8))); + mxObject.set("Longitude", new Big(position.coords.longitude.toFixed(8))); + mxObject.set("Accuracy", new Big(position.coords.accuracy.toFixed(8))); + if (position.coords.altitude != null) { + mxObject.set("Altitude", new Big(position.coords.altitude.toFixed(8))); + } + if (position.coords.altitudeAccuracy != null && position.coords.altitudeAccuracy !== -1) { + mxObject.set("AltitudeAccuracy", new Big(position.coords.altitudeAccuracy.toFixed(8))); + } + if (position.coords.heading != null && position.coords.heading !== -1) { + mxObject.set("Heading", new Big(position.coords.heading.toFixed(8))); + } + if (position.coords.speed != null && position.coords.speed !== -1) { + mxObject.set("Speed", new Big(position.coords.speed.toFixed(8))); + } + return mxObject; } - return mxObject; - } + }); // END USER CODE } diff --git a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts index b1419bf0e..13679925f 100644 --- a/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts +++ b/packages/jsActions/nanoflow-actions-native/src/geolocation/GetCurrentLocationMinimumAccuracy.ts @@ -6,7 +6,14 @@ // - the code between BEGIN EXTRA CODE and END EXTRA CODE // Other code you write will be lost the next time you deploy the project. import { Big } from "big.js"; -import { watchPosition, unwatch, GeolocationResponse, LocationRequestOptions } from "react-native-nitro-geolocation"; +import Geolocation, { + GeolocationError, + GeolocationOptions, + GeolocationResponse +} from "@react-native-community/geolocation"; + +import type { Platform, NativeModules } from "react-native"; +import type { GeoError, GeoPosition, GeoOptions } from "../../typings/Geolocation"; // BEGIN EXTRA CODE // END EXTRA CODE @@ -36,50 +43,62 @@ export async function GetCurrentLocationMinimumAccuracy( ): Promise { // BEGIN USER CODE - const isReactNative = navigator && navigator.product === "ReactNative"; - const isWeb = navigator && navigator.geolocation; + let reactNativeModule: { NativeModules: typeof NativeModules; Platform: typeof Platform } | undefined; + let geolocationModule: typeof import("@react-native-community/geolocation").default | Geolocation; + + if (navigator && navigator.product === "ReactNative") { + reactNativeModule = require("react-native"); + + if (!reactNativeModule) { + return Promise.reject(new Error("React Native module could not be found")); + } - if (!isReactNative && !isWeb) { + if (reactNativeModule.NativeModules.RNFusedLocation) { + geolocationModule = (await import("@react-native-community/geolocation")).default; + } else if (reactNativeModule.NativeModules.RNCGeolocation) { + geolocationModule = Geolocation; + } else { + return Promise.reject(new Error("Geolocation module could not be found")); + } + } else if (navigator && navigator.geolocation) { + geolocationModule = navigator.geolocation; + } else { return Promise.reject(new Error("Geolocation module could not be found")); } return new Promise((resolve, reject) => { - const options = buildLocationOptions(timeout, maximumAge, highAccuracy); - let lastAccruedPosition: GeolocationResponse | undefined; - - // Derive the watchdog timeout from the same clamped value used for the location layer, - // so the two never disagree. `new Big(0)` is truthy, so we must not test `timeout` - // directly here or a configured `0` would fire the watchdog on the next tick. - const timeoutMs = options.timeout ?? 30000; - const timeoutId = setTimeout(onTimeout, timeoutMs); + if (!geolocationModule) { + return reject(new Error("Geolocation module could not be found")); + } - let clearWatch: () => void; + const options = getOptions(); - if (isReactNative) { - const token = watchPosition(onSuccess, onError, options); - clearWatch = () => unwatch(token); - } else { - // Workaround: browsers may ignore maximumAge on watchPosition unless getCurrentPosition is called first. - // https://stackoverflow.com/questions/3397585/navigator-geolocation-getcurrentposition-sometimes-works-sometimes-doesnt - navigator.geolocation.getCurrentPosition( + // This action is only required while running in PWA or hybrid. + if (navigator && (!navigator.product || navigator.product !== "ReactNative")) { + // This ensures the browser will not ignore the maximumAge https://stackoverflow.com/questions/3397585/navigator-geolocation-getcurrentposition-sometimes-works-sometimes-doesnt/31916631#31916631 + geolocationModule.getCurrentPosition( () => {}, + () => {}, {} ); - const watchId = navigator.geolocation.watchPosition( - pos => onSuccess(normalizeWebPosition(pos)), - err => onError({ code: err.code, message: err.message }), - { - timeout: options.timeout, - maximumAge: options.maximumAge, - enableHighAccuracy: highAccuracy ?? false - } - ); - clearWatch = () => navigator.geolocation.clearWatch(watchId); + } + + const timeoutId = setTimeout(onTimeout, Number(timeout)); + const watchId: number = geolocationModule.watchPosition(onSuccess, onError, options); + let lastAccruedPosition: GeolocationResponse | GeoPosition; + + function createGeolocationObject(position: GeolocationResponse | GeoPosition): void { + mx.data.create({ + entity: "NanoflowCommons.Geolocation", + callback: mxObject => resolve(mapPositionToMxObject(mxObject, position)), + error: () => + reject(new Error("Could not create 'NanoflowCommons.Geolocation' object to store location")) + }); } function onTimeout(): void { - clearWatch(); + geolocationModule?.clearWatch(watchId); if (lastAccruedPosition) { createGeolocationObject(lastAccruedPosition); @@ -88,10 +107,10 @@ export async function GetCurrentLocationMinimumAccuracy( } } - function onSuccess(position: GeolocationResponse): void { + function onSuccess(position: GeolocationResponse | GeoPosition): void { if (!minimumAccuracy || Number(minimumAccuracy) >= position.coords.accuracy) { clearTimeout(timeoutId); - clearWatch(); + geolocationModule?.clearWatch(watchId); createGeolocationObject(position); } else { if (!lastAccruedPosition || position.coords.accuracy < lastAccruedPosition.coords.accuracy) { @@ -100,92 +119,55 @@ export async function GetCurrentLocationMinimumAccuracy( } } - function onError(error: { code: number; message: string }): void { - clearTimeout(timeoutId); - clearWatch(); - - // Best effort within a timeout: if we already captured a usable (though not yet - // minimum-accuracy) fix, return it instead of failing on a transient error such as - // POSITION_UNAVAILABLE. Mirrors the onTimeout fallback. - if (lastAccruedPosition) { - createGeolocationObject(lastAccruedPosition); - } else { - reject(new Error(error.message)); - } + function onError(error: GeolocationError | GeoError): void { + return reject(new Error(error.message)); } - function createGeolocationObject(position: GeolocationResponse): void { - mx.data.create({ - entity: "NanoflowCommons.Geolocation", - callback: mxObject => resolve(mapPositionToMxObject(mxObject, position)), - error: () => - reject(new Error("Could not create 'NanoflowCommons.Geolocation' object to store location")) - }); - } - }); + function getOptions(): GeolocationOptions | GeoOptions { + let timeoutNumber = timeout && Number(timeout.toString()); + const maximumAgeNumber = maximumAge && Number(maximumAge.toString()); + + // If the timeout is 0 or undefined (empty), it causes a crash on iOS. + // If the timeout is undefined (empty); we set timeout to 30 sec (default timeout) + // If the timeout is 0; we set timeout to 1 hour (no timeout) + if (reactNativeModule?.Platform.OS === "ios") { + if (timeoutNumber === undefined) { + timeoutNumber = 30000; + } else if (timeoutNumber === 0) { + timeoutNumber = 3600000; + } + } - function buildLocationOptions( - timeout: Big | undefined, - maximumAge: Big | undefined, - highAccuracy: boolean | undefined - ): LocationRequestOptions { - let timeoutNumber = timeout ? timeout.toNumber() : undefined; - const maximumAgeNumber = maximumAge ? maximumAge.toNumber() : undefined; - - // Normalize the timeout so the watchdog and the location layer always agree, on every platform: - // - undefined (empty) -> 30 sec (default timeout) - // - 0 -> 1 hour (treated as "no timeout") - // A timeout of 0 or undefined also crashes on iOS, and on web `timeout: 0` means - // "fail immediately with TIMEOUT" on every update, so it must never reach the location layer. - if (timeoutNumber === undefined) { - timeoutNumber = 30000; - } else if (timeoutNumber === 0) { - timeoutNumber = 3600000; + return { + timeout: timeoutNumber, + maximumAge: maximumAgeNumber, + enableHighAccuracy: highAccuracy + }; } - return { - timeout: timeoutNumber, - maximumAge: maximumAgeNumber, - accuracy: highAccuracy ? { android: "high", ios: "best" } : { android: "balanced", ios: "hundredMeters" } - }; - } - // NOTE: `normalizeWebPosition` is duplicated verbatim in `GetCurrentLocation.ts`. - // The Mendix action model does not allow sharing code across action files, so if you change this - // function, keep the copy in the other action in sync. - function normalizeWebPosition(pos: GeolocationPosition): GeolocationResponse { - return { - coords: { - latitude: pos.coords.latitude, - longitude: pos.coords.longitude, - altitude: pos.coords.altitude ?? null, - accuracy: pos.coords.accuracy, - altitudeAccuracy: pos.coords.altitudeAccuracy ?? null, - heading: pos.coords.heading ?? null, - speed: pos.coords.speed ?? null - }, - timestamp: pos.timestamp - }; - } - - function mapPositionToMxObject(mxObject: mendix.lib.MxObject, pos: GeolocationResponse): mendix.lib.MxObject { - mxObject.set("Timestamp", new Date(pos.timestamp)); - mxObject.set("Latitude", new Big(pos.coords.latitude.toFixed(8))); - mxObject.set("Longitude", new Big(pos.coords.longitude.toFixed(8))); - mxObject.set("Accuracy", new Big(pos.coords.accuracy.toFixed(8))); - if (pos.coords.altitude != null) { - mxObject.set("Altitude", new Big(pos.coords.altitude.toFixed(8))); - } - if (pos.coords.altitudeAccuracy != null && pos.coords.altitudeAccuracy !== -1) { - mxObject.set("AltitudeAccuracy", new Big(pos.coords.altitudeAccuracy.toFixed(8))); - } - if (pos.coords.heading != null && pos.coords.heading !== -1) { - mxObject.set("Heading", new Big(pos.coords.heading.toFixed(8))); - } - if (pos.coords.speed != null && pos.coords.speed !== -1) { - mxObject.set("Speed", new Big(pos.coords.speed.toFixed(8))); + function mapPositionToMxObject( + mxObject: mendix.lib.MxObject, + position: GeolocationResponse | GeoPosition + ): mendix.lib.MxObject { + mxObject.set("Timestamp", new Date(position.timestamp)); + mxObject.set("Latitude", new Big(position.coords.latitude.toFixed(8))); + mxObject.set("Longitude", new Big(position.coords.longitude.toFixed(8))); + mxObject.set("Accuracy", new Big(position.coords.accuracy.toFixed(8))); + if (position.coords.altitude != null) { + mxObject.set("Altitude", new Big(position.coords.altitude.toFixed(8))); + } + if (position.coords.altitudeAccuracy != null && position.coords.altitudeAccuracy !== -1) { + mxObject.set("AltitudeAccuracy", new Big(position.coords.altitudeAccuracy.toFixed(8))); + } + if (position.coords.heading != null && position.coords.heading !== -1) { + mxObject.set("Heading", new Big(position.coords.heading.toFixed(8))); + } + if (position.coords.speed != null && position.coords.speed !== -1) { + mxObject.set("Speed", new Big(position.coords.speed.toFixed(8))); + } + return mxObject; } - return mxObject; - } + }); // END USER CODE } diff --git a/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts b/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts new file mode 100644 index 000000000..c92f243d4 --- /dev/null +++ b/packages/jsActions/nanoflow-actions-native/typings/Geolocation.d.ts @@ -0,0 +1,22 @@ +import type { + AuthorizationLevel, + AuthorizationResult, + GeoError, + GeoPosition, + GeoOptions, + getCurrentPosition, + requestAuthorization, + watchPosition, + clearWatch, + stopObserving +} from "@react-native-community/geolocation"; + +type GeolocationServiceStatic = { + getCurrentPosition: typeof getCurrentPosition; + requestAuthorization: typeof requestAuthorization; + watchPosition: typeof watchPosition; + clearWatch: typeof clearWatch; + stopObserving: typeof stopObserving; +}; + +export type { GeolocationServiceStatic, AuthorizationLevel, AuthorizationResult, GeoError, GeoPosition, GeoOptions }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4b75dbbe..0c9a5ba2e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -195,18 +195,18 @@ importers: '@react-native-async-storage/async-storage': specifier: 2.2.0 version: 2.2.0(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3)) + '@react-native-community/geolocation': + specifier: 3.4.0 + version: 3.4.0(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3) + invariant: + specifier: ^2.2.4 + version: 2.2.4 js-base64: specifier: ~3.7.2 version: 3.7.8 react-native-geocoder: specifier: 0.5.0 version: 0.5.0 - react-native-nitro-geolocation: - specifier: 1.4.3 - version: 1.4.3(react-native-nitro-modules@0.36.1(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3))(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3) - react-native-nitro-modules: - specifier: 0.36.1 - version: 0.36.1(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3) react-native-permissions: specifier: 5.5.1 version: 5.5.1(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3) @@ -2163,6 +2163,13 @@ packages: peerDependencies: react-native: 0.84.1 + '@react-native-community/geolocation@3.4.0': + resolution: {integrity: sha512-bzZH89/cwmpkPMKKveoC72C4JH0yF4St5Ceg/ZM9pA1SqX9MlRIrIrrOGZ/+yi++xAvFDiYfihtn9TvXWU9/rA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: 19.2.3 + react-native: 0.84.1 + '@react-native-community/netinfo@11.5.2': resolution: {integrity: sha512-/g0m65BtX9HU+bPiCH2517bOHpEIUsGrWFXDzi1a5nNKn5KujQgm04WhL7/OSXWKHyrT8VVtUoJA0XKRxueBpQ==} peerDependencies: @@ -6485,19 +6492,6 @@ packages: react: 19.2.3 react-native: 0.84.1 - react-native-nitro-geolocation@1.4.3: - resolution: {integrity: sha512-8r09M6fjf7krCXRuF3RskuJpcxE8dvwQtRJnlrk+U3tO4v+ltyXhRRGmAMlO2Y/PEv1II8sgnIgil58RaLPI4A==} - peerDependencies: - react: 19.2.3 - react-native: 0.84.1 - react-native-nitro-modules: '*' - - react-native-nitro-modules@0.36.1: - resolution: {integrity: sha512-kBv/VvKqAmkXAvP1DxJMC9b/fRhh7JdSO4EUnPP46hJjrIFeFR8AwKm8mYaKZEuF014M/TVdv2vomVUW0umsQQ==} - peerDependencies: - react: 19.2.3 - react-native: 0.84.1 - react-native-notify-kit@10.4.7: resolution: {integrity: sha512-G5w2H8/TGBncNRZO0In0wu99JIKnUTOAXwTlBwiRDqBXCUIgmIqQIqcinz7LliMoqGhO2TJOwK4avARmcPorBw==} hasBin: true @@ -9512,6 +9506,11 @@ snapshots: dependencies: react-native: 0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3) + '@react-native-community/geolocation@3.4.0(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3)': + dependencies: + react: 19.2.3 + react-native: 0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3) + '@react-native-community/netinfo@11.5.2(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3)': dependencies: react: 19.2.3 @@ -14651,17 +14650,6 @@ snapshots: react-native: 0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3) react-native-animatable: 1.3.3 - react-native-nitro-geolocation@1.4.3(react-native-nitro-modules@0.36.1(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3))(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3): - dependencies: - react: 19.2.3 - react-native: 0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3) - react-native-nitro-modules: 0.36.1(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3) - - react-native-nitro-modules@0.36.1(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3))(react@19.2.3): - dependencies: - react: 19.2.3 - react-native: 0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3) - react-native-notify-kit@10.4.7(react-native@0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3)): dependencies: react-native: 0.84.1(@babel/core@7.29.7)(@react-native/metro-config@0.86.1(@babel/core@7.29.7))(@types/react@19.2.17)(react@19.2.3)