1import { NativeModules } from 'react-native';
2const LegacyNativeProxy = NativeModules.NativeUnimoduleProxy;
3// Fixes `cannot find name 'global'.` in tests
4// @ts-ignore
5const ExpoNativeProxy = global.expo?.modules?.NativeModulesProxy;
6const modulesConstantsKey = 'modulesConstants';
7const exportedMethodsKey = 'exportedMethods';
8const NativeModulesProxy = {};
9if (LegacyNativeProxy) {
10    // use JSI proxy if available, fallback to legacy RN proxy
11    const NativeProxy = ExpoNativeProxy ?? LegacyNativeProxy;
12    Object.keys(NativeProxy[exportedMethodsKey]).forEach((moduleName) => {
13        // copy constants
14        NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};
15        // copy methods
16        NativeProxy[exportedMethodsKey][moduleName].forEach((methodInfo) => {
17            NativeModulesProxy[moduleName][methodInfo.name] = (...args) => {
18                // Use the new proxy to call methods on legacy modules, if possible.
19                if (ExpoNativeProxy?.callMethod) {
20                    return ExpoNativeProxy.callMethod(moduleName, methodInfo.name, args);
21                }
22                // Otherwise fall back to the legacy proxy.
23                // This is deprecated and might be removed in SDK47 or later.
24                const { key, argumentsCount } = methodInfo;
25                if (argumentsCount !== args.length) {
26                    return Promise.reject(new Error(`Native method ${moduleName}.${methodInfo.name} expects ${argumentsCount} ${argumentsCount === 1 ? 'argument' : 'arguments'} but received ${args.length}`));
27                }
28                return LegacyNativeProxy.callMethod(moduleName, key, args);
29            };
30        });
31        // These are called by EventEmitter (which is a wrapper for NativeEventEmitter)
32        // only on iOS and they use iOS-specific native module, EXReactNativeEventEmitter.
33        //
34        // On Android only {start,stop}Observing are called on the native module
35        // and these should be exported as Expo methods.
36        //
37        // Before the RN 65, addListener/removeListeners weren't called on Android. However, it no longer stays true.
38        // See https://github.com/facebook/react-native/commit/f5502fbda9fe271ff6e1d0da773a3a8ee206a453.
39        // That's why, we check if the `EXReactNativeEventEmitter` exists and only if yes, we use it in the listener implementation.
40        // Otherwise, those methods are NOOP.
41        if (NativeModules.EXReactNativeEventEmitter) {
42            NativeModulesProxy[moduleName].addListener = (...args) => NativeModules.EXReactNativeEventEmitter.addProxiedListener(moduleName, ...args);
43            NativeModulesProxy[moduleName].removeListeners = (...args) => NativeModules.EXReactNativeEventEmitter.removeProxiedListeners(moduleName, ...args);
44        }
45        else {
46            // Fixes on Android:
47            // WARN  `new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.
48            // WARN  `new NativeEventEmitter()` was called with a non-null argument without the required `removeListeners` method.
49            NativeModulesProxy[moduleName].addListener = () => { };
50            NativeModulesProxy[moduleName].removeListeners = () => { };
51        }
52    });
53}
54else {
55    console.warn(`The "EXNativeModulesProxy" native module is not exported through NativeModules; verify that expo-modules-core's native code is linked properly`);
56}
57export default NativeModulesProxy;
58//# sourceMappingURL=NativeModulesProxy.native.js.map