1*37917d47SŁukasz Kosmatyimport { NativeModules } from 'react-native';
2*37917d47SŁukasz Kosmaty
3*37917d47SŁukasz Kosmatyimport { ProxyNativeModule } from './NativeModulesProxy.types';
4*37917d47SŁukasz Kosmaty
5*37917d47SŁukasz Kosmatyconst NativeProxy = NativeModules.NativeUnimoduleProxy;
6*37917d47SŁukasz Kosmatyconst modulesConstantsKey = 'modulesConstants';
7*37917d47SŁukasz Kosmatyconst exportedMethodsKey = 'exportedMethods';
8*37917d47SŁukasz Kosmaty
9*37917d47SŁukasz Kosmatyconst NativeModulesProxy: { [moduleName: string]: ProxyNativeModule } = {};
10*37917d47SŁukasz Kosmaty
11*37917d47SŁukasz Kosmatyif (NativeProxy) {
12*37917d47SŁukasz Kosmaty  Object.keys(NativeProxy[exportedMethodsKey]).forEach(moduleName => {
13*37917d47SŁukasz Kosmaty    NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};
14*37917d47SŁukasz Kosmaty    NativeProxy[exportedMethodsKey][moduleName].forEach(methodInfo => {
15*37917d47SŁukasz Kosmaty      NativeModulesProxy[moduleName][methodInfo.name] = (...args: unknown[]): Promise<any> => {
16*37917d47SŁukasz Kosmaty        const { key, argumentsCount } = methodInfo;
17*37917d47SŁukasz Kosmaty        if (argumentsCount !== args.length) {
18*37917d47SŁukasz Kosmaty          return Promise.reject(
19*37917d47SŁukasz Kosmaty            new Error(
20*37917d47SŁukasz Kosmaty              `Native method ${moduleName}.${methodInfo.name} expects ${argumentsCount} ${
21*37917d47SŁukasz Kosmaty                argumentsCount === 1 ? 'argument' : 'arguments'
22*37917d47SŁukasz Kosmaty              } but received ${args.length}`
23*37917d47SŁukasz Kosmaty            )
24*37917d47SŁukasz Kosmaty          );
25*37917d47SŁukasz Kosmaty        }
26*37917d47SŁukasz Kosmaty        return NativeProxy.callMethod(moduleName, key, args);
27*37917d47SŁukasz Kosmaty      };
28*37917d47SŁukasz Kosmaty    });
29*37917d47SŁukasz Kosmaty
30*37917d47SŁukasz Kosmaty    // These are called by EventEmitter (which is a wrapper for NativeEventEmitter)
31*37917d47SŁukasz Kosmaty    // only on iOS and they use iOS-specific native module, EXReactNativeEventEmitter.
32*37917d47SŁukasz Kosmaty    //
33*37917d47SŁukasz Kosmaty    // On Android only {start,stop}Observing are called on the native module
34*37917d47SŁukasz Kosmaty    // and these should be exported as Expo methods.
35*37917d47SŁukasz Kosmaty    NativeModulesProxy[moduleName].addListener = (...args) =>
36*37917d47SŁukasz Kosmaty      NativeModules.UMReactNativeEventEmitter.addProxiedListener(moduleName, ...args);
37*37917d47SŁukasz Kosmaty    NativeModulesProxy[moduleName].removeListeners = (...args) =>
38*37917d47SŁukasz Kosmaty      NativeModules.UMReactNativeEventEmitter.removeProxiedListeners(moduleName, ...args);
39*37917d47SŁukasz Kosmaty  });
40*37917d47SŁukasz Kosmaty} else {
41*37917d47SŁukasz Kosmaty  console.warn(
42*37917d47SŁukasz Kosmaty    `The "UMNativeModulesProxy" native module is not exported through NativeModules; verify that @unimodules/react-native-adapter's native code is linked properly`
43*37917d47SŁukasz Kosmaty  );
44*37917d47SŁukasz Kosmaty}
45*37917d47SŁukasz Kosmaty
46*37917d47SŁukasz Kosmatyexport default NativeModulesProxy;
47