UNPKG

react-native-expo-braintree

Version:

React native and expo wrapper around braintree sdk fro android and ios

243 lines (234 loc) 9.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.withExpoBraintreeAndroidGradle = exports.withExpoBraintreeAndroid = exports.appendContents = exports.addBraintreeLinks = void 0; var _configPlugins = require("@expo/config-plugins"); var _codeMod = require("@expo/config-plugins/build/android/codeMod"); var _generateCode = require("@expo/config-plugins/build/utils/generateCode"); const { getMainActivityOrThrow } = _configPlugins.AndroidConfig.Manifest; const withExpoBraintreeAndroid = (expoConfig, { host, pathPrefix, addFallbackUrlScheme, initialize3DSecure, initializeGooglePay }) => { let newConfig = (0, _configPlugins.withAndroidManifest)(expoConfig, config => { config.modResults = addBraintreeLinks(config.modResults, host, pathPrefix, addFallbackUrlScheme, initialize3DSecure); return config; }); newConfig = (0, _configPlugins.withMainActivity)(expoConfig, config => { const { modResults } = config; const { language } = modResults; const withImports = (0, _codeMod.addImports)(modResults.contents, ['com.expobraintree.ExpoBraintreeModule'], language === 'java'); const newSrc = [` ExpoBraintreeModule.init()${language === 'java' ? ';' : ''}`]; if (initialize3DSecure === 'true') { newSrc.push(` ExpoBraintreeModule.initThreeDSecure(this)${language === 'java' ? ';' : ''}`); } if (initializeGooglePay === 'true') { newSrc.push(` ExpoBraintreeModule.initGooglePay(this)${language === 'java' ? ';' : ''}`); } const withInit = (0, _generateCode.mergeContents)({ src: withImports, comment: ' // add BraintreeModule import', tag: 'braintree-module-init', offset: 1, anchor: /(?<=^.*super\.onCreate.*$)/m, newSrc: newSrc.join('\n') }); return { ...config, modResults: { ...modResults, contents: withInit.contents } }; }); return newConfig; }; // Add new intent filter for App Links // <activity> // ... // <intent-filter android:autoVerify="true"> // <action android:name="android.intent.action.VIEW" /> // <category android:name="android.intent.category.DEFAULT" /> // <category android:name="android.intent.category.BROWSABLE" /> // <data android:scheme="http" /> // <data android:scheme="https" /> // <data android:host="myownpersonaldomain.com" /> // <data android:pathPrefix="/braintree-payments"/> // </intent-filter> // </activity>; // If you provide a fallbackUrlScheme it will also add a new intent filter for that // <activity> // ... // <intent-filter> // <action android:name="android.intent.action.VIEW" /> // <category android:name="android.intent.category.DEFAULT" /> // <category android:name="android.intent.category.BROWSABLE" /> // <data android:scheme="${applicationId}.braintree" /> // </intent-filter> // </activity>; exports.withExpoBraintreeAndroid = withExpoBraintreeAndroid; const addBraintreeLinks = (modResults, host, pathPrefix, addFallbackUrlScheme, initialize3DSecure) => { const mainActivity = getMainActivityOrThrow(modResults); const intentFilters = mainActivity['intent-filter']; // Host is required props for a plugin if (!host) { _configPlugins.WarningAggregator.addWarningAndroid('withExpoBraintree addBraintreeLinks', `No Host provided for withExpoBraintree.android addBraintreeLinks`); } // Check if the intent filter already exists if (hasIntentFilter(intentFilters, host, pathPrefix)) { _configPlugins.WarningAggregator.addWarningAndroid('withExpoBraintree addBraintreeLinks', `withExpoBraintreeAndroid: AndroidManifest not require any changes`); return modResults; } const newIntentFilter = { action: [{ $: { 'android:name': 'android.intent.action.VIEW' } }], category: [{ $: { 'android:name': 'android.intent.category.DEFAULT' } }, { $: { 'android:name': 'android.intent.category.BROWSABLE' } }], data: [{ $: { 'android:scheme': 'http' } }, { $: { 'android:scheme': 'https' } }, { $: { 'android:host': host } }], $: { 'android:autoVerify': 'true' } }; // If there is pathPrefix then we add that if (pathPrefix) { newIntentFilter.data?.push({ $: { 'android:pathPrefix': pathPrefix } }); } const newFallbackUrlSchemeIntentFilter = { action: [{ $: { 'android:name': 'android.intent.action.VIEW' } }], category: [{ $: { 'android:name': 'android.intent.category.DEFAULT' } }, { $: { 'android:name': 'android.intent.category.BROWSABLE' } }], data: [{ $: { 'android:scheme': '${applicationId}.braintree' } }] }; // Add the intent-filter to the main activity mainActivity['intent-filter'] = [...(mainActivity['intent-filter'] || []), newIntentFilter]; // If there is fallbackUrlScheme then we add that if (initialize3DSecure === 'true' || addFallbackUrlScheme === 'true') { // Add the intent-filter to the main activity mainActivity['intent-filter'] = [...(mainActivity['intent-filter'] || []), newFallbackUrlSchemeIntentFilter]; } return modResults; }; /** * Check if an intent-filter with the same data already exists * @param {object} intentFilters - The AndroidManifest intent filters * @param {string} host - The host to check * @param {string} pathPrefix - The pathPrefix to check * @returns {boolean} - Returns true if a matching intent filter is found */ exports.addBraintreeLinks = addBraintreeLinks; function hasIntentFilter(intentFilters, host, pathPrefix) { return intentFilters?.some(filter => { const hasAutoVerify = filter.$ && filter.$['android:autoVerify'] === 'true'; const hasViewAction = filter.action?.some(action => action.$['android:name'] === 'android.intent.action.VIEW'); const hasDefaultCategory = filter.category?.some(category => category.$['android:name'] === 'android.intent.category.DEFAULT'); const hasBrowsableCategory = filter.category?.some(category => category.$['android:name'] === 'android.intent.category.BROWSABLE'); const hasHttpScheme = filter.data?.some(data => data.$['android:scheme'] === 'http'); const hasHttpsScheme = filter.data?.some(data => data.$['android:scheme'] === 'https'); const hasMatchingHost = filter.data?.some(data => data.$['android:host'] === host); const hasMatchingPathPrefix = filter.data?.some(data => data.$['android:pathPrefix'] === pathPrefix); // Check all conditions to ensure it matches the intent filter we want to add return hasAutoVerify && hasViewAction && hasDefaultCategory && hasBrowsableCategory && hasHttpScheme && hasHttpsScheme && hasMatchingHost && (hasMatchingPathPrefix || !pathPrefix); }); } // Because we need the package to be added AFTER the React and Google maven packages, we create a new all projects. // It's ok to have multiple all projects.repositories, so we create a new one since it's cheaper than tokenizing // the existing block to find the correct place to insert our content. const gradle3DSecureBraintreeRepo = [`allprojects {`, ` repositories {`, ` maven {`, ` url "https://cardinalcommerceprod.jfrog.io/artifactory/android"`, ` credentials {`, ` username 'braintree_team_sdk'`, ` password 'AKCp8jQcoDy2hxSWhDAUQKXLDPDx6NYRkqrgFLRc3qDrayg6rrCbJpsKKyMwaykVL8FWusJpp'`, ` }`, ` }`, ` }`, `}`].join('\n'); const withExpoBraintreeAndroidGradle = expoConfig => { return (0, _configPlugins.withProjectBuildGradle)(expoConfig, config => { if (config.modResults.language === 'groovy') { config.modResults.contents = appendContents({ tag: 'expo-braintree-import', src: config.modResults.contents, newSrc: gradle3DSecureBraintreeRepo, comment: '//' }).contents; } else { throw new Error('Cannot add expo-braintree-import maven gradle because the build.gradle is not groovy'); } return config; }); }; exports.withExpoBraintreeAndroidGradle = withExpoBraintreeAndroidGradle; const appendContents = ({ src, newSrc, tag, comment }) => { const header = (0, _generateCode.createGeneratedHeaderComment)(newSrc, tag, comment); if (!src.includes(header)) { // Ensure the old generated contents are removed. const sanitizedTarget = (0, _generateCode.removeGeneratedContents)(src, tag); const contentsToAdd = [ // @something header, // contents newSrc, // @end `${comment} @generated end ${tag}`].join('\n'); return { contents: sanitizedTarget ?? src + contentsToAdd, didMerge: true, didClear: !!sanitizedTarget }; } return { contents: src, didClear: false, didMerge: false }; }; exports.appendContents = appendContents; //# sourceMappingURL=withExpoBraintree.android.js.map