UNPKG

cordova-plugin-purchase-braintree

Version:

A Cordova plugin for the Braintree mobile payment processing SDK with 3D secure and Data Collecting.

125 lines (103 loc) 6.72 kB
const fs = require('fs'); const https = require('https'); const { execSync, exec } = require('child_process'); const IOS_FRAMEWORKS_PATH = 'plugins/cordova-plugin-purchase-braintree/lib/ios'; const TEMP_PATH = '.downloads/cordova-plugin-purchase-braintree'; const BRAINTREE_IOS_VERSION = '5.27.0'; const BRAINTREE_IOS_RELEASE_URL = `https://github.com/braintree/braintree_ios/releases/download/${BRAINTREE_IOS_VERSION}/Braintree.xcframework.zip`; const BRAINTREE_IOS_REPO_ARCHIVE_URL = `https://github.com/braintree/braintree_ios/archive/refs/tags/${BRAINTREE_IOS_VERSION}.zip`; const PAYPALCHECKOUT_IOS_VERSION = '0.110.0'; const PAYPALCHECKOUT_IOS_RELEASE_URL = `https://github.com/paypal/paypalcheckout-ios/releases/download/${PAYPALCHECKOUT_IOS_VERSION}/PayPalCheckout.xcframework.zip`; const CARDINAL_MOBILE_VERSION = '2.2.5-3'; // https://assets.braintreegateway.com/mobile/ios/carthage-frameworks/cardinal-mobile/CardinalMobile.json" const CARDINAL_MOBILE_URL = `https://assets.braintreegateway.com/mobile/ios/carthage-frameworks/cardinal-mobile/CardinalMobile.${CARDINAL_MOBILE_VERSION}.xcframework.zip`; // To be executed before installing a plugin (to the platforms). module.exports = async function (context) { // clean up old download directory if (!fs.existsSync(`${TEMP_PATH}/${BRAINTREE_IOS_VERSION}`)) { execSync(`rm -fr "${TEMP_PATH}"`); } if (fs.existsSync(IOS_FRAMEWORKS_PATH + '/BraintreeCore.xcframework/Info.plist') && fs.existsSync(IOS_FRAMEWORKS_PATH + '/CardinalMobile.xcframework/Info.plist')) { // frameworks already installed. return; } if (!fs.existsSync(TEMP_PATH)) { // 0- Create temporary directory fs.mkdirSync(TEMP_PATH, { recursive: true }); execSync(`echo "Temporary files for cordova-plugin-purchase-braintree" >"${TEMP_PATH}/README"`); } // 1a- Download the XCFramework release from github if (!fs.existsSync(`${TEMP_PATH}/Braintree.xcframework.zip`)) { console.log("Downloading Braintree SDK version " + BRAINTREE_IOS_VERSION + ", from " + BRAINTREE_IOS_RELEASE_URL); await download(BRAINTREE_IOS_RELEASE_URL, `${TEMP_PATH}/Braintree.xcframework.zip`); } // 1b- Download PayPalCheckout if (!fs.existsSync(`${TEMP_PATH}/PayPalCheckout.xcframework.zip`)) { console.log("Downloading PayPalCheckout SDK version " + PAYPALCHECKOUT_IOS_VERSION + ", from " + PAYPALCHECKOUT_IOS_RELEASE_URL); await download(PAYPALCHECKOUT_IOS_RELEASE_URL, `${TEMP_PATH}/PayPalCheckout.xcframework.zip`); } // 1c- Download braintree_ios repository (it contains additional frameworks that are required) if (!fs.existsSync(`${TEMP_PATH}/Braintree-Repo.zip`)) { console.log("Downloading Braintree repository version " + BRAINTREE_IOS_VERSION + ", from " + BRAINTREE_IOS_REPO_ARCHIVE_URL); await download(BRAINTREE_IOS_REPO_ARCHIVE_URL, `${TEMP_PATH}/Braintree-Repo.zip`); } // 2- Create "frameworks" directory if (!fs.existsSync(IOS_FRAMEWORKS_PATH)) { fs.mkdirSync(IOS_FRAMEWORKS_PATH, { recursive: true }); } execSync(`touch "${TEMP_PATH}/${BRAINTREE_IOS_VERSION}"`); // 3- Extract console.log("Extracting Braintree SDK..."); execSync(`unzip -o "${TEMP_PATH}/Braintree.xcframework.zip" -d "${TEMP_PATH}"`); execSync(`unzip -o "${TEMP_PATH}/Braintree-Repo.zip" -d "${TEMP_PATH}"`); execSync(`rsync -a "${TEMP_PATH}/Carthage/Build/" "${IOS_FRAMEWORKS_PATH}"`); console.log("Adding PayPalCheckout SDK as a top-level dependency..."); // fixing "Invalid Bundle. The bundle at '/Frameworks/BraintreePayPalNativeCheckout.framework' contains disallowed nested bundles." // PayPalCheckout is removed as a nested framework, now installed as a top-level dependency execSync(`unzip -o "${TEMP_PATH}/PayPalCheckout.xcframework.zip" -d "${TEMP_PATH}"`); execSync(`rsync -a --delete "${TEMP_PATH}/PayPalCheckout.xcframework" "${IOS_FRAMEWORKS_PATH}/"`); execSync(`rm -fr "${TEMP_PATH}/PayPalCheckout.xcframework"`); execSync(`rm -fr "${IOS_FRAMEWORKS_PATH}/BraintreePayPalNativeCheckout.xcframework/ios-arm64/BraintreePayPalNativeCheckout.framework/Frameworks"`); execSync(`rm -fr "${IOS_FRAMEWORKS_PATH}/BraintreePayPalNativeCheckout.xcframework/ios-arm64_x86_64-simulator/BraintreePayPalNativeCheckout.framework/Frameworks"`); // execSync(`rsync -a "${TEMP_PATH}/CardinalMobile.${CARDINAL_MOBILE_VERSION}.xcframework/" "${IOS_FRAMEWORKS_PATH}/CardinalMobile.xcframework"`); execSync(`rsync -a --delete "${TEMP_PATH}/braintree_ios-${BRAINTREE_IOS_VERSION}/Frameworks/XCFrameworks/PPRiskMagnes.xcframework" "${IOS_FRAMEWORKS_PATH}/"`); execSync(`rsync -a --delete "${TEMP_PATH}/braintree_ios-${BRAINTREE_IOS_VERSION}/Frameworks/XCFrameworks/CardinalMobile.xcframework" "${IOS_FRAMEWORKS_PATH}/"`); execSync(`rsync -a --delete "${TEMP_PATH}/braintree_ios-${BRAINTREE_IOS_VERSION}/Frameworks/XCFrameworks/KountDataCollector.xcframework" "${IOS_FRAMEWORKS_PATH}/"`); // 4- Cleanup // execSync(`rm -fr "${TEMP_PATH}"`); } /** * Download a resource from `url` to `dest`. * @param {string} url - Valid URL to attempt download of resource * @param {string} dest - Valid path to save the file. * @returns {Promise<void>} - Returns asynchronously when successfully completed download */ function download(url, dest) { return new Promise((resolve, reject) => { // Check file does not exist yet before hitting network fs.access(dest, fs.constants.F_OK, (err) => { if (err === null) reject('File already exists'); const request = https.get(url, response => { if (response.statusCode === 200) { const file = fs.createWriteStream(dest, { flags: 'wx' }); file.on('finish', () => resolve()); file.on('error', err => { file.close(); if (err.code === 'EEXIST') reject('File already exists'); else fs.unlink(dest, () => reject(err.message)); // Delete temp file }); response.pipe(file); } else if (response.statusCode === 302 || response.statusCode === 301) { //Recursively follow redirects, only a 200 will resolve. download(response.headers.location, dest).then(() => resolve()); } else { reject(`Server responded with ${response.statusCode}: ${response.statusMessage}`); } }); request.on('error', err => { reject(err.message); }); }); }); }