diff --git a/README.md b/README.md index 83ec6c036..a3d32cccf 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,8 @@ Next, add: "@stripe/stripe-react-native", { "merchantIdentifier": string | string [], - "enableGooglePay": boolean + "enableGooglePay": boolean, + "enableGooglePlacesSdk": boolean } ] ], diff --git a/src/plugin/__tests__/fixtures/sample-build.gradle b/src/plugin/__tests__/fixtures/sample-build.gradle new file mode 100644 index 000000000..2f3400b3f --- /dev/null +++ b/src/plugin/__tests__/fixtures/sample-build.gradle @@ -0,0 +1,41 @@ +dependencies { + // The version of react-native is set by the React Native Gradle Plugin + implementation("com.facebook.react:react-android") + + def isGifEnabled = (findProperty('expo.gif.enabled') ?: "") == "true"; + def isWebpEnabled = (findProperty('expo.webp.enabled') ?: "") == "true"; + def isWebpAnimatedEnabled = (findProperty('expo.webp.animated') ?: "") == "true"; + def frescoVersion = rootProject.ext.frescoVersion + + // If your app supports Android versions before Ice Cream Sandwich (API level 14) + if (isGifEnabled || isWebpEnabled) { + implementation("com.facebook.fresco:fresco:${frescoVersion}") + implementation("com.facebook.fresco:imagepipeline-okhttp3:${frescoVersion}") + } + + if (isGifEnabled) { + // For animated gif support + implementation("com.facebook.fresco:animated-gif:${frescoVersion}") + } + + if (isWebpEnabled) { + // For webp support + implementation("com.facebook.fresco:webpsupport:${frescoVersion}") + if (isWebpAnimatedEnabled) { + // Animated webp support + implementation("com.facebook.fresco:animated-webp:${frescoVersion}") + } + } + + debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") + debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { + exclude group:'com.squareup.okhttp3', module:'okhttp' + } + debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") + + if (hermesEnabled.toBoolean()) { + implementation("com.facebook.react:hermes-android") + } else { + implementation jscFlavor + } +} \ No newline at end of file diff --git a/src/plugin/__tests__/withStripe-test.ts b/src/plugin/__tests__/withStripe-test.ts index 9c3625c9a..6d9e1f26d 100644 --- a/src/plugin/__tests__/withStripe-test.ts +++ b/src/plugin/__tests__/withStripe-test.ts @@ -1,7 +1,11 @@ import { AndroidConfig } from '@expo/config-plugins'; import { resolve } from 'path'; -import { setApplePayEntitlement, setGooglePayMetaData } from '../withStripe'; +import { + setApplePayEntitlement, + setGooglePayMetaData, + addGooglePlacesSdk, +} from '../withStripe'; jest.mock( '@stripe/stripe-react-native/package.json', @@ -17,6 +21,7 @@ const { getMainApplicationOrThrow, readAndroidManifestAsync } = const fixturesPath = resolve(__dirname, 'fixtures'); const sampleManifestPath = resolve(fixturesPath, 'sample-AndroidManifest.xml'); +const sampleBuildGradlePath = resolve(fixturesPath, 'sample-build.gradle'); describe('setApplePayEntitlement', () => { it(`sets the apple pay entitlement when none exist`, () => { @@ -109,3 +114,15 @@ describe('setGooglePayMetaData', () => { expect(apiKeyItem).toHaveLength(0); }); }); + +describe('addGooglePlacesSdk', () => { + it(`Properly adds Google Places SDK to build.gradle`, async () => { + let buildGradle = AndroidConfig.Paths.getFileInfo(sampleBuildGradlePath); + buildGradle.contents = addGooglePlacesSdk(buildGradle.contents); + expect( + buildGradle.contents.includes( + 'com.google.android.libraries.places:places:2.6.0' + ) + ).toBe(true); + }); +}); diff --git a/src/plugin/withStripe.ts b/src/plugin/withStripe.ts index 4febd1b15..30b4637d4 100644 --- a/src/plugin/withStripe.ts +++ b/src/plugin/withStripe.ts @@ -5,6 +5,7 @@ import { IOSConfig, withAndroidManifest, withEntitlementsPlist, + withAppBuildGradle, } from '@expo/config-plugins'; const { @@ -22,6 +23,7 @@ type StripePluginProps = { */ merchantIdentifier: string | string[]; enableGooglePay: boolean; + enableGooglePlacesSdk: boolean; }; const withStripe: ConfigPlugin = (config, props) => { @@ -94,9 +96,9 @@ export const withNoopSwiftFile: ConfigPlugin = (config) => { const withStripeAndroid: ConfigPlugin = ( expoConfig, - { enableGooglePay = false } + { enableGooglePay = false, enableGooglePlacesSdk = false } ) => { - return withAndroidManifest(expoConfig, (config) => { + expoConfig = withAndroidManifest(expoConfig, (config) => { config.modResults = setGooglePayMetaData( enableGooglePay, config.modResults @@ -104,6 +106,15 @@ const withStripeAndroid: ConfigPlugin = ( return config; }); + + return withAppBuildGradle(expoConfig, (config) => { + if (enableGooglePlacesSdk) { + config.modResults.contents = addGooglePlacesSdk( + config.modResults.contents + ); + } + return config; + }); }; /** @@ -138,4 +149,34 @@ export function setGooglePayMetaData( return modResults; } +/** + * Adds the following to app/build.gradle: + * + * dependencies { + * implementation 'com.google.android.libraries.places:places:2.6.0' + * ... + * } + */ +export function addGooglePlacesSdk(buildGradle: string) { + const dependency = 'com.google.android.libraries.places:places:2.6.0'; + + if (buildGradle.includes(dependency)) { + return buildGradle; + } + + const impl = `implementation '${dependency}'`; + + if (buildGradle.includes('dependencies {')) { + return buildGradle.replace( + 'dependencies {', + `dependencies { + // Added by @stripe/stripe-react-native + ${impl} + ` + ); + } else { + return buildGradle; + } +} + export default createRunOncePlugin(withStripe, pkg.name, pkg.version);