Skip to content

Commit

Permalink
Feature: Create Expo managed workflow plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
anthlasserre committed Oct 5, 2023
1 parent dace212 commit d117b9e
Show file tree
Hide file tree
Showing 4 changed files with 340 additions and 7 deletions.
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,37 @@ Drop-in and Components require a [client key][client.key], that should be provid
## Installation

Add `@adyen/react-native` to your react-native project.

```bash
yarn add @adyen/react-native
```

### Expo integration (experimental)

> ❕ Please pay attention that this library is not compatible with ExpoGo. You can use it only with **Expo managed workflow**.
1. Add `@expo/config-plugins` to your project:

```bash
yarn add @expo/config-plugins
```

2. Add `@adyen/react-native` plugin to your `app.json`:

```json
{
"expo": {
"plugins": ["@adyen/react-native"]
}
}
```

> In case you are facing issues with the plugin, please pre-build your app and investigate the files generated:
>
> ```bash
> npx expo prebuild --clean
> ```
### iOS integration
1. run `pod install`
Expand Down
120 changes: 120 additions & 0 deletions app.plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
const {
withAndroidManifest,
withMainActivity,
withAppDelegate,
withDangerousMod,
} = require('@expo/config-plugins');
const { resolve } = require('path');
const { readFileSync, writeFileSync } = require('fs');
const {
mergeContents,
} = require('@expo/config-plugins/build/utils/generateCode');

const withPodsPreprocessingFix = (defaultConfig) => {
return withDangerousMod(defaultConfig, [
'ios',
(config) => {
// Gets project root file from mod request
const { platformProjectRoot } = config.modRequest;
// Gets podfile from project
const podfile = resolve(platformProjectRoot, 'Podfile');
// Opens content of podfile in utf encoding
const contents = readFileSync(podfile, 'utf-8');

// Adds required Pod into Podfile
const addPreprocessing = mergeContents({
tag: 'Add preprocessing fix',
src: contents,
newSrc: `\n installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= ['$(inherited)', '_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION']
end
end`,
anchor: /apply_Xcode_12_5_M1_post_install_workaround/,
offset: 0,
comment: '#',
});

if (!addPreprocessing.didMerge) {
console.log(
"ERROR: Cannot add block to the project's ios/Podfile because it's malformed. Please report this with a copy of your project Podfile."
);
return defaultConfig;
}
writeFileSync(podfile, addPreprocessing.contents);

return config;
},
]);
};

const withAdyenAndroid = (defaultConfig) => {
const configWithMainActivity = withMainActivity(
defaultConfig,
async (config) => {
const mainActivity = config.modResults;
mainActivity.contents = mainActivity.contents.replace(
'import com.facebook.react.ReactRootView;\n',
'import com.facebook.react.ReactRootView;\nimport com.adyenreactnativesdk.AdyenCheckout;\n'
);
mainActivity.contents = mainActivity.contents.replace(
'super.onCreate(null);\n }',
'super.onCreate(null);\n AdyenCheckout.setLauncherActivity(this);\n }'
);
return config;
}
);

const configWithManifest = withAndroidManifest(
configWithMainActivity,
async (config) => {
const mainActivity = config.modResults;
// Add com.adyenreactnativesdk.component.dropin.AdyenCheckoutService service
// after com.facebook.react.HeadlessJsTaskService
mainActivity.manifest.application = [
// @ts-expect-error - manifest is not well typed
{
...mainActivity.manifest.application?.[0],
service: [
{
$: {
'android:name':
'com.adyenreactnativesdk.component.dropin.AdyenCheckoutService',
'android:exported': 'false',
},
},
],
},
];
return config;
}
);

return configWithManifest;
};

const withAdyenIos = (defaultConfig) => {
const appDelegate = withAppDelegate(defaultConfig, async (config) => {
const appDelegate = config.modResults;
appDelegate.contents = appDelegate.contents.replace(
'#import "AppDelegate.h"\n\n',
'#import "AppDelegate.h"\n\n#import <adyen-react-native/ADYRedirectComponent.h>\n'
);
appDelegate.contents = appDelegate.contents.replace(
/\/\/ Linking API.*\n.*\n.*\n}/g,
`// Linking API
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// Adyen SDK
return [ADYRedirectComponent applicationDidOpenURL:url];
}`
);
return config;
});
return appDelegate;
};

module.exports = function (defaultConfig) {
return withPodsPreprocessingFix(
withAdyenIos(withAdyenAndroid(defaultConfig))
);
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"eslint": "^8.0.0",
"eslint-config-prettier": "^8.0.0",
"eslint-plugin-prettier": "^4.0.0",
"@expo/config-plugins": "~7.2.2",
"pod-install": "^0.1.30",
"prettier": "^2.0.5",
"react": "^18.0.0",
Expand Down
Loading

0 comments on commit d117b9e

Please sign in to comment.