137917d47SŁukasz Kosmatyimport { NativeModules } from 'react-native';
237917d47SŁukasz Kosmaty
337917d47SŁukasz Kosmatyimport { ProxyNativeModule } from './NativeModulesProxy.types';
437917d47SŁukasz Kosmaty
537917d47SŁukasz Kosmatyconst NativeProxy = NativeModules.NativeUnimoduleProxy;
637917d47SŁukasz Kosmatyconst modulesConstantsKey = 'modulesConstants';
737917d47SŁukasz Kosmatyconst exportedMethodsKey = 'exportedMethods';
837917d47SŁukasz Kosmaty
937917d47SŁukasz Kosmatyconst NativeModulesProxy: { [moduleName: string]: ProxyNativeModule } = {};
1037917d47SŁukasz Kosmaty
1137917d47SŁukasz Kosmatyif (NativeProxy) {
1235f78160SBartosz Kaszubowski  Object.keys(NativeProxy[exportedMethodsKey]).forEach((moduleName) => {
1337917d47SŁukasz Kosmaty    NativeModulesProxy[moduleName] = NativeProxy[modulesConstantsKey][moduleName] || {};
1435f78160SBartosz Kaszubowski    NativeProxy[exportedMethodsKey][moduleName].forEach((methodInfo) => {
1537917d47SŁukasz Kosmaty      NativeModulesProxy[moduleName][methodInfo.name] = (...args: unknown[]): Promise<any> => {
1637917d47SŁukasz Kosmaty        const { key, argumentsCount } = methodInfo;
1737917d47SŁukasz Kosmaty        if (argumentsCount !== args.length) {
1837917d47SŁukasz Kosmaty          return Promise.reject(
1937917d47SŁukasz Kosmaty            new Error(
2037917d47SŁukasz Kosmaty              `Native method ${moduleName}.${methodInfo.name} expects ${argumentsCount} ${
2137917d47SŁukasz Kosmaty                argumentsCount === 1 ? 'argument' : 'arguments'
2237917d47SŁukasz Kosmaty              } but received ${args.length}`
2337917d47SŁukasz Kosmaty            )
2437917d47SŁukasz Kosmaty          );
2537917d47SŁukasz Kosmaty        }
2637917d47SŁukasz Kosmaty        return NativeProxy.callMethod(moduleName, key, args);
2737917d47SŁukasz Kosmaty      };
2837917d47SŁukasz Kosmaty    });
2937917d47SŁukasz Kosmaty
3037917d47SŁukasz Kosmaty    // These are called by EventEmitter (which is a wrapper for NativeEventEmitter)
3137917d47SŁukasz Kosmaty    // only on iOS and they use iOS-specific native module, EXReactNativeEventEmitter.
3237917d47SŁukasz Kosmaty    //
3337917d47SŁukasz Kosmaty    // On Android only {start,stop}Observing are called on the native module
3437917d47SŁukasz Kosmaty    // and these should be exported as Expo methods.
3537917d47SŁukasz Kosmaty    NativeModulesProxy[moduleName].addListener = (...args) =>
36*70c51132SKudo Chien      NativeModules.EXReactNativeEventEmitter.addProxiedListener(moduleName, ...args);
3737917d47SŁukasz Kosmaty    NativeModulesProxy[moduleName].removeListeners = (...args) =>
38*70c51132SKudo Chien      NativeModules.EXReactNativeEventEmitter.removeProxiedListeners(moduleName, ...args);
3937917d47SŁukasz Kosmaty  });
4037917d47SŁukasz Kosmaty} else {
4137917d47SŁukasz Kosmaty  console.warn(
4237917d47SŁukasz Kosmaty    `The "UMNativeModulesProxy" native module is not exported through NativeModules; verify that @unimodules/react-native-adapter's native code is linked properly`
4337917d47SŁukasz Kosmaty  );
4437917d47SŁukasz Kosmaty}
4537917d47SŁukasz Kosmaty
4637917d47SŁukasz Kosmatyexport default NativeModulesProxy;
47