@react-native-firebase/app-check 19.0.1 → 19.1.1

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.
@@ -0,0 +1,46 @@
1
+ // This AppDelegate template is modified to have RCTBridge
2
+ // created in some non-standard way or not created at all.
3
+ // This should trigger the fallback regex in iOS AppDelegate Expo plugin.
4
+
5
+ // some parts omitted to be short
6
+
7
+ #import "AppDelegate.h"
8
+
9
+ #import <React/RCTBridge.h>
10
+ #import <React/RCTBundleURLProvider.h>
11
+ #import <React/RCTRootView.h>
12
+ #import <React/RCTLinkingManager.h>
13
+ #import <React/RCTConvert.h>
14
+
15
+ @implementation AppDelegate
16
+
17
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
18
+ {
19
+
20
+ // The generated code should appear above ^^^
21
+ #if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
22
+ InitializeFlipper(application);
23
+ #endif
24
+
25
+ // the line below is malfolmed not to be matched by the Expo plugin regex
26
+ // RCTBridge* briddge = [RCTBridge new];
27
+ RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:briddge moduleName:@"main" initialProperties:nil];
28
+ id rootViewBackgroundColor = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"RCTRootViewBackgroundColor"];
29
+ if (rootViewBackgroundColor != nil) {
30
+ rootView.backgroundColor = [RCTConvert UIColor:rootViewBackgroundColor];
31
+ } else {
32
+ rootView.backgroundColor = [UIColor whiteColor];
33
+ }
34
+
35
+ self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
36
+ UIViewController *rootViewController = [UIViewController new];
37
+ rootViewController.view = rootView;
38
+ self.window.rootViewController = rootViewController;
39
+ [self.window makeKeyAndVisible];
40
+
41
+ [super application:application didFinishLaunchingWithOptions:launchOptions];
42
+
43
+ return YES;
44
+ }
45
+
46
+ @end
@@ -0,0 +1,102 @@
1
+ // This AppDelegate prebuild template is used in Expo SDK 42 and older
2
+ // It expects the old react-native-unimodules architecture (UM* prefix)
3
+
4
+ #import "AppDelegate.h"
5
+
6
+ #import <React/RCTBridge.h>
7
+ #import <React/RCTBundleURLProvider.h>
8
+ #import <React/RCTRootView.h>
9
+ #import <React/RCTLinkingManager.h>
10
+
11
+ #import <UMCore/UMModuleRegistry.h>
12
+ #import <UMReactNativeAdapter/UMNativeModulesProxy.h>
13
+ #import <UMReactNativeAdapter/UMModuleRegistryAdapter.h>
14
+ #import <EXSplashScreen/EXSplashScreenService.h>
15
+ #import <UMCore/UMModuleRegistryProvider.h>
16
+
17
+ #if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
18
+ #import <FlipperKit/FlipperClient.h>
19
+ #import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
20
+ #import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
21
+ #import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
22
+ #import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
23
+ #import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
24
+
25
+ static void InitializeFlipper(UIApplication *application) {
26
+ FlipperClient *client = [FlipperClient sharedClient];
27
+ SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
28
+ [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
29
+ [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
30
+ [client addPlugin:[FlipperKitReactPlugin new]];
31
+ [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
32
+ [client start];
33
+ }
34
+ #endif
35
+
36
+ @interface AppDelegate () <RCTBridgeDelegate>
37
+
38
+ @property (nonatomic, strong) UMModuleRegistryAdapter *moduleRegistryAdapter;
39
+ @property (nonatomic, strong) NSDictionary *launchOptions;
40
+
41
+ @end
42
+
43
+ @implementation AppDelegate
44
+
45
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
46
+ {
47
+ #if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
48
+ InitializeFlipper(application);
49
+ #endif
50
+
51
+ self.moduleRegistryAdapter = [[UMModuleRegistryAdapter alloc] initWithModuleRegistryProvider:[[UMModuleRegistryProvider alloc] init]];
52
+ self.launchOptions = launchOptions;
53
+ self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
54
+ #ifdef DEBUG
55
+ [self initializeReactNativeApp];
56
+ #else
57
+ EXUpdatesAppController *controller = [EXUpdatesAppController sharedInstance];
58
+ controller.delegate = self;
59
+ [controller startAndShowLaunchScreen:self.window];
60
+ #endif
61
+
62
+ [super application:application didFinishLaunchingWithOptions:launchOptions];
63
+
64
+ return YES;
65
+ }
66
+
67
+ - (RCTBridge *)initializeReactNativeApp
68
+ {
69
+ RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:self.launchOptions];
70
+ RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
71
+ rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
72
+
73
+ UIViewController *rootViewController = [UIViewController new];
74
+ rootViewController.view = rootView;
75
+ self.window.rootViewController = rootViewController;
76
+ [self.window makeKeyAndVisible];
77
+
78
+ return bridge;
79
+ }
80
+
81
+ - (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
82
+ {
83
+ NSArray<id<RCTBridgeModule>> *extraModules = [_moduleRegistryAdapter extraModulesForBridge:bridge];
84
+ // If you'd like to export some custom RCTBridgeModules that are not Expo modules, add them here!
85
+ return extraModules;
86
+ }
87
+
88
+ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
89
+ #ifdef DEBUG
90
+ return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
91
+ #else
92
+ return [[EXUpdatesAppController sharedInstance] launchAssetUrl];
93
+ #endif
94
+ }
95
+
96
+ - (void)appController:(EXUpdatesAppController *)appController didStartWithSuccess:(BOOL)success {
97
+ appController.bridge = [self initializeReactNativeApp];
98
+ EXSplashScreenService *splashScreenService = (EXSplashScreenService *)[UMModuleRegistryProvider getSingletonModuleForClass:[EXSplashScreenService class]];
99
+ [splashScreenService showSplashScreenFor:self.window.rootViewController];
100
+ }
101
+
102
+ @end
@@ -0,0 +1,79 @@
1
+ // This AppDelegate prebuild template is used in Expo SDK 44+
2
+ // It has the RCTBridge to be created by Expo ReactDelegate
3
+
4
+ #import "AppDelegate.h"
5
+
6
+ #import <React/RCTBridge.h>
7
+ #import <React/RCTBundleURLProvider.h>
8
+ #import <React/RCTRootView.h>
9
+ #import <React/RCTLinkingManager.h>
10
+ #import <React/RCTConvert.h>
11
+
12
+ #if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
13
+ #import <FlipperKit/FlipperClient.h>
14
+ #import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
15
+ #import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h>
16
+ #import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h>
17
+ #import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h>
18
+ #import <FlipperKitReactPlugin/FlipperKitReactPlugin.h>
19
+
20
+ static void InitializeFlipper(UIApplication *application) {
21
+ FlipperClient *client = [FlipperClient sharedClient];
22
+ SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
23
+ [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]];
24
+ [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]];
25
+ [client addPlugin:[FlipperKitReactPlugin new]];
26
+ [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
27
+ [client start];
28
+ }
29
+ #endif
30
+
31
+ @implementation AppDelegate
32
+
33
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
34
+ {
35
+ #if defined(FB_SONARKIT_ENABLED) && __has_include(<FlipperKit/FlipperClient.h>)
36
+ InitializeFlipper(application);
37
+ #endif
38
+
39
+ RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
40
+ RCTRootView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
41
+ rootView.backgroundColor = [UIColor whiteColor];
42
+ self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
43
+ UIViewController *rootViewController = [self.reactDelegate createRootViewController];
44
+ rootViewController.view = rootView;
45
+ self.window.rootViewController = rootViewController;
46
+ [self.window makeKeyAndVisible];
47
+
48
+ [super application:application didFinishLaunchingWithOptions:launchOptions];
49
+
50
+ return YES;
51
+ }
52
+
53
+ - (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
54
+ {
55
+ // If you'd like to export some custom RCTBridgeModules, add them here!
56
+ return @[];
57
+ }
58
+
59
+ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge {
60
+ #ifdef DEBUG
61
+ return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
62
+ #else
63
+ return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
64
+ #endif
65
+ }
66
+
67
+ // Linking API
68
+ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
69
+ return [RCTLinkingManager application:application openURL:url options:options];
70
+ }
71
+
72
+ // Universal Links
73
+ - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
74
+ return [RCTLinkingManager application:application
75
+ continueUserActivity:userActivity
76
+ restorationHandler:restorationHandler];
77
+ }
78
+
79
+ @end
@@ -0,0 +1,129 @@
1
+ // RN 0.68.1, Expo SDK 45 template
2
+ // The main difference between this and the SDK 44 one is that this is
3
+ // using React Native 0.68 and is written in Objective-C++
4
+
5
+ #import "AppDelegate.h"
6
+
7
+ #import <React/RCTBridge.h>
8
+ #import <React/RCTBundleURLProvider.h>
9
+ #import <React/RCTRootView.h>
10
+ #import <React/RCTLinkingManager.h>
11
+ #import <React/RCTConvert.h>
12
+
13
+ #import <React/RCTAppSetupUtils.h>
14
+
15
+ #if RCT_NEW_ARCH_ENABLED
16
+ #import <React/CoreModulesPlugins.h>
17
+ #import <React/RCTCxxBridgeDelegate.h>
18
+ #import <React/RCTFabricSurfaceHostingProxyRootView.h>
19
+ #import <React/RCTSurfacePresenter.h>
20
+ #import <React/RCTSurfacePresenterBridgeAdapter.h>
21
+ #import <ReactCommon/RCTTurboModuleManager.h>
22
+
23
+ #import <react/config/ReactNativeConfig.h>
24
+
25
+ @interface AppDelegate () <RCTCxxBridgeDelegate, RCTTurboModuleManagerDelegate> {
26
+ RCTTurboModuleManager *_turboModuleManager;
27
+ RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
28
+ std::shared_ptr<const facebook::react::ReactNativeConfig> _reactNativeConfig;
29
+ facebook::react::ContextContainer::Shared _contextContainer;
30
+ }
31
+ @end
32
+ #endif
33
+
34
+ @implementation AppDelegate
35
+
36
+ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
37
+ {
38
+ RCTAppSetupPrepareApp(application);
39
+
40
+ RCTBridge *bridge = [self.reactDelegate createBridgeWithDelegate:self launchOptions:launchOptions];
41
+
42
+ #if RCT_NEW_ARCH_ENABLED
43
+ _contextContainer = std::make_shared<facebook::react::ContextContainer const>();
44
+ _reactNativeConfig = std::make_shared<facebook::react::EmptyReactNativeConfig const>();
45
+ _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
46
+ _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
47
+ bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
48
+ #endif
49
+
50
+ UIView *rootView = [self.reactDelegate createRootViewWithBridge:bridge moduleName:@"main" initialProperties:nil];
51
+
52
+ rootView.backgroundColor = [UIColor whiteColor];
53
+ self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
54
+ UIViewController *rootViewController = [self.reactDelegate createRootViewController];
55
+ rootViewController.view = rootView;
56
+ self.window.rootViewController = rootViewController;
57
+ [self.window makeKeyAndVisible];
58
+
59
+ [super application:application didFinishLaunchingWithOptions:launchOptions];
60
+
61
+ return YES;
62
+ }
63
+
64
+ - (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
65
+ {
66
+ // If you'd like to export some custom RCTBridgeModules, add them here!
67
+ return @[];
68
+ }
69
+
70
+ - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
71
+ {
72
+ #if DEBUG
73
+ return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
74
+ #else
75
+ return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
76
+ #endif
77
+ }
78
+
79
+ // Linking API
80
+ - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
81
+ return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];
82
+ }
83
+
84
+ // Universal Links
85
+ - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
86
+ BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
87
+ return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result;
88
+ }
89
+
90
+ #if RCT_NEW_ARCH_ENABLED
91
+
92
+ #pragma mark - RCTCxxBridgeDelegate
93
+
94
+ - (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge
95
+ {
96
+ _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
97
+ delegate:self
98
+ jsInvoker:bridge.jsCallInvoker];
99
+ return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
100
+ }
101
+
102
+ #pragma mark RCTTurboModuleManagerDelegate
103
+
104
+ - (Class)getModuleClassFromName:(const char *)name
105
+ {
106
+ return RCTCoreModulesClassProvider(name);
107
+ }
108
+
109
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
110
+ jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
111
+ {
112
+ return nullptr;
113
+ }
114
+
115
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
116
+ initParams:
117
+ (const facebook::react::ObjCTurboModule::InitParams &)params
118
+ {
119
+ return nullptr;
120
+ }
121
+
122
+ - (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass
123
+ {
124
+ return RCTAppSetupDefaultModuleFromClass(moduleClass);
125
+ }
126
+
127
+ #endif
128
+
129
+ @end
@@ -0,0 +1,107 @@
1
+ import { IOSConfig } from '@expo/config-plugins';
2
+ import { AppDelegateProjectFile } from '@expo/config-plugins/build/ios/Paths';
3
+ import { beforeEach, describe, expect, it, jest } from '@jest/globals';
4
+ import fs from 'fs/promises';
5
+ import path from 'path';
6
+
7
+ import { modifyAppDelegateAsync, modifyObjcAppDelegate } from '../src/ios/appDelegate';
8
+
9
+ describe('Config Plugin iOS Tests', function () {
10
+ beforeEach(function () {
11
+ jest.resetAllMocks();
12
+ });
13
+
14
+ it('tests changes made to old AppDelegate.m (SDK 42)', async function () {
15
+ const appDelegate = await fs.readFile(path.join(__dirname, './fixtures/AppDelegate_sdk42.m'), {
16
+ encoding: 'utf8',
17
+ });
18
+ const result = modifyObjcAppDelegate(appDelegate);
19
+ expect(result).toMatchSnapshot();
20
+ });
21
+
22
+ it('tests changes made to AppDelegate.m (SDK 43)', async function () {
23
+ const appDelegate = await fs.readFile(
24
+ path.join(__dirname, './fixtures/AppDelegate_bare_sdk43.m'),
25
+ {
26
+ encoding: 'utf8',
27
+ },
28
+ );
29
+ const result = modifyObjcAppDelegate(appDelegate);
30
+ expect(result).toMatchSnapshot();
31
+ });
32
+
33
+ it('tests changes made to AppDelegate.m with Expo ReactDelegate support (SDK 44+)', async function () {
34
+ const appDelegate = await fs.readFile(path.join(__dirname, './fixtures/AppDelegate_sdk44.m'), {
35
+ encoding: 'utf8',
36
+ });
37
+ const result = modifyObjcAppDelegate(appDelegate);
38
+ expect(result).toMatchSnapshot();
39
+ });
40
+
41
+ it('tests changes made to AppDelegate.m with fallback regex (if the original one fails)', async function () {
42
+ const appDelegate = await fs.readFile(
43
+ path.join(__dirname, './fixtures/AppDelegate_fallback.m'),
44
+ {
45
+ encoding: 'utf8',
46
+ },
47
+ );
48
+ const result = modifyObjcAppDelegate(appDelegate);
49
+ expect(result).toMatchSnapshot();
50
+ });
51
+
52
+ it('works with AppDelegate.mm (RN 0.68+)', async function () {
53
+ const appDelegate = await fs.readFile(path.join(__dirname, './fixtures/AppDelegate_sdk45.mm'), {
54
+ encoding: 'utf8',
55
+ });
56
+ const result = modifyObjcAppDelegate(appDelegate);
57
+ expect(result).toMatchSnapshot();
58
+ });
59
+
60
+ it('detects Objective-C++ AppDelegate.mm', async function () {
61
+ jest.spyOn(fs, 'writeFile').mockImplementation(async () => {});
62
+
63
+ const appDelegatePath = path.join(__dirname, './fixtures/AppDelegate_sdk45.mm');
64
+ const appDelegateFileInfo = IOSConfig.Paths.getFileInfo(
65
+ appDelegatePath,
66
+ ) as AppDelegateProjectFile;
67
+
68
+ await modifyAppDelegateAsync(appDelegateFileInfo);
69
+
70
+ // expect file contents to be modified
71
+ expect(fs.writeFile).toHaveBeenCalledWith(
72
+ appDelegateFileInfo.path,
73
+ expect.not.stringContaining(appDelegateFileInfo.contents),
74
+ );
75
+ });
76
+
77
+ it("doesn't support Swift AppDelegate", async function () {
78
+ jest.spyOn(fs, 'writeFile').mockImplementation(async () => {});
79
+
80
+ const appDelegateFileInfo: AppDelegateProjectFile = {
81
+ path: '.',
82
+ language: 'swift',
83
+ contents: 'some dummy content',
84
+ };
85
+
86
+ await expect(modifyAppDelegateAsync(appDelegateFileInfo)).rejects.toThrow();
87
+ expect(fs.writeFile).not.toHaveBeenCalled();
88
+ });
89
+
90
+ it('does not add the firebase import multiple times', async function () {
91
+ const singleImport = '#import "AppDelegate.h"\n#import <RNFBAppCheckModule.h>';
92
+ const doubleImport = singleImport + '\n#import <RNFBAppCheckModule.h>';
93
+
94
+ const appDelegate = await fs.readFile(path.join(__dirname, './fixtures/AppDelegate_sdk45.mm'), {
95
+ encoding: 'utf8',
96
+ });
97
+ expect(appDelegate).not.toContain(singleImport);
98
+
99
+ const onceModifiedAppDelegate = modifyObjcAppDelegate(appDelegate);
100
+ expect(onceModifiedAppDelegate).toContain(singleImport);
101
+ expect(onceModifiedAppDelegate).not.toContain(doubleImport);
102
+
103
+ const twiceModifiedAppDelegate = modifyObjcAppDelegate(onceModifiedAppDelegate);
104
+ expect(twiceModifiedAppDelegate).toContain(singleImport);
105
+ expect(twiceModifiedAppDelegate).not.toContain(doubleImport);
106
+ });
107
+ });
@@ -0,0 +1,3 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ declare const _default: ConfigPlugin<void>;
3
+ export default _default;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_plugins_1 = require("@expo/config-plugins");
4
+ const ios_1 = require("./ios");
5
+ /**
6
+ * A config plugin for configuring `@react-native-firebase/app-check`
7
+ */
8
+ const withRnFirebaseAppCheck = config => {
9
+ return (0, config_plugins_1.withPlugins)(config, [
10
+ // iOS
11
+ ios_1.withFirebaseAppDelegate,
12
+ ]);
13
+ };
14
+ const pak = require('@react-native-firebase/app-check/package.json');
15
+ exports.default = (0, config_plugins_1.createRunOncePlugin)(withRnFirebaseAppCheck, pak.name, pak.version);
@@ -0,0 +1,5 @@
1
+ import { ConfigPlugin } from '@expo/config-plugins';
2
+ import { AppDelegateProjectFile } from '@expo/config-plugins/build/ios/Paths';
3
+ export declare function modifyObjcAppDelegate(contents: string): string;
4
+ export declare function modifyAppDelegateAsync(appDelegateFileInfo: AppDelegateProjectFile): Promise<void>;
5
+ export declare const withFirebaseAppDelegate: ConfigPlugin;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.withFirebaseAppDelegate = exports.modifyAppDelegateAsync = exports.modifyObjcAppDelegate = void 0;
7
+ const config_plugins_1 = require("@expo/config-plugins");
8
+ const generateCode_1 = require("@expo/config-plugins/build/utils/generateCode");
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const methodInvocationBlock = `[RNFBAppCheckModule sharedInstance];`;
11
+ // https://regex101.com/r/mPgaq6/1
12
+ const methodInvocationLineMatcher = /(?:self\.moduleName\s*=\s*@\"([^"]*)\";)|(?:(self\.|_)(\w+)\s?=\s?\[\[UMModuleRegistryAdapter alloc\])|(?:RCTBridge\s?\*\s?(\w+)\s?=\s?\[(\[RCTBridge alloc\]|self\.reactDelegate))/g;
13
+ // https://regex101.com/r/nHrTa9/1/
14
+ // if the above regex fails, we can use this one as a fallback:
15
+ const fallbackInvocationLineMatcher = /-\s*\(BOOL\)\s*application:\s*\(UIApplication\s*\*\s*\)\s*\w+\s+didFinishLaunchingWithOptions:/g;
16
+ function modifyObjcAppDelegate(contents) {
17
+ // Add import
18
+ if (!contents.includes('#import <RNFBAppCheckModule.h>')) {
19
+ contents = contents.replace(/#import "AppDelegate.h"/g, `#import "AppDelegate.h"
20
+ #import <RNFBAppCheckModule.h>`);
21
+ }
22
+ // To avoid potential issues with existing changes from older plugin versions
23
+ if (contents.includes(methodInvocationBlock)) {
24
+ return contents;
25
+ }
26
+ if (!methodInvocationLineMatcher.test(contents) &&
27
+ !fallbackInvocationLineMatcher.test(contents)) {
28
+ config_plugins_1.WarningAggregator.addWarningIOS('@react-native-firebase/app-check', 'Unable to determine correct Firebase insertion point in AppDelegate.m. Skipping Firebase addition.');
29
+ return contents;
30
+ }
31
+ // Add invocation
32
+ try {
33
+ return (0, generateCode_1.mergeContents)({
34
+ tag: '@react-native-firebase/app-check-didFinishLaunchingWithOptions',
35
+ src: contents,
36
+ newSrc: methodInvocationBlock,
37
+ anchor: methodInvocationLineMatcher,
38
+ offset: 0, // new line will be inserted right above matched anchor
39
+ comment: '//',
40
+ }).contents;
41
+ }
42
+ catch (e) {
43
+ // tests if the opening `{` is in the new line
44
+ const multilineMatcher = new RegExp(fallbackInvocationLineMatcher.source + '.+\\n*{');
45
+ const isHeaderMultiline = multilineMatcher.test(contents);
46
+ // we fallback to another regex if the first one fails
47
+ return (0, generateCode_1.mergeContents)({
48
+ tag: '@react-native-firebase/app-didFinishLaunchingWithOptions-fallback',
49
+ src: contents,
50
+ newSrc: methodInvocationBlock,
51
+ anchor: fallbackInvocationLineMatcher,
52
+ // new line will be inserted right below matched anchor
53
+ // or two lines, if the `{` is in the new line
54
+ offset: isHeaderMultiline ? 2 : 1,
55
+ comment: '//',
56
+ }).contents;
57
+ }
58
+ }
59
+ exports.modifyObjcAppDelegate = modifyObjcAppDelegate;
60
+ async function modifyAppDelegateAsync(appDelegateFileInfo) {
61
+ const { language, path, contents } = appDelegateFileInfo;
62
+ if (['objc', 'objcpp'].includes(language)) {
63
+ const newContents = modifyObjcAppDelegate(contents);
64
+ await fs_1.default.promises.writeFile(path, newContents);
65
+ }
66
+ else {
67
+ // TODO: Support Swift
68
+ throw new Error(`Cannot add Firebase code to AppDelegate of language "${language}"`);
69
+ }
70
+ }
71
+ exports.modifyAppDelegateAsync = modifyAppDelegateAsync;
72
+ const withFirebaseAppDelegate = config => {
73
+ return (0, config_plugins_1.withDangerousMod)(config, [
74
+ 'ios',
75
+ async (config) => {
76
+ const fileInfo = config_plugins_1.IOSConfig.Paths.getAppDelegate(config.modRequest.projectRoot);
77
+ await modifyAppDelegateAsync(fileInfo);
78
+ return config;
79
+ },
80
+ ]);
81
+ };
82
+ exports.withFirebaseAppDelegate = withFirebaseAppDelegate;
@@ -0,0 +1,2 @@
1
+ import { withFirebaseAppDelegate } from './appDelegate';
2
+ export { withFirebaseAppDelegate };
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withFirebaseAppDelegate = void 0;
4
+ const appDelegate_1 = require("./appDelegate");
5
+ Object.defineProperty(exports, "withFirebaseAppDelegate", { enumerable: true, get: function () { return appDelegate_1.withFirebaseAppDelegate; } });
@@ -0,0 +1,15 @@
1
+ import { ConfigPlugin, createRunOncePlugin, withPlugins } from '@expo/config-plugins';
2
+ import { withFirebaseAppDelegate } from './ios';
3
+
4
+ /**
5
+ * A config plugin for configuring `@react-native-firebase/app-check`
6
+ */
7
+ const withRnFirebaseAppCheck: ConfigPlugin = config => {
8
+ return withPlugins(config, [
9
+ // iOS
10
+ withFirebaseAppDelegate,
11
+ ]);
12
+ };
13
+
14
+ const pak = require('@react-native-firebase/app-check/package.json');
15
+ export default createRunOncePlugin(withRnFirebaseAppCheck, pak.name, pak.version);