UNPKG

smartech-base-expo-plugin

Version:

Smartech Base Expo SDK's React Native Plugin For React Native Projects.

209 lines (181 loc) 8.98 kB
import { ConfigPlugin, withInfoPlist, withAppDelegate, withEntitlementsPlist } from "@expo/config-plugins"; import { promises as fs } from 'fs'; import path from 'path'; import fSystem from 'fs'; import { ExpoConfig } from "@expo/config-types"; import { SmartechBaseProps } from "./smartechBaseProps"; import { appdelegateSnippet, smartechBaseSnippet } from "./iosConstants"; import { Helper } from "./helper"; // Set custom entitlements plist const modifyEntitlementsPlist: ConfigPlugin<SmartechBaseProps> = (config, props) => { return withEntitlementsPlist(config, async (newConfig) => { newConfig.modResults = { ...newConfig.modResults, "com.apple.security.application-groups": [`group.${props.ios.groupIdentifier}`], }; return newConfig; }); }; // Set custom info plist const modifyInfoPlist: ConfigPlugin<SmartechBaseProps> = (config, props) => { return withInfoPlist(config, (newConfig) => { newConfig.modResults = { ...newConfig.modResults, SmartechKeys: { SmartechAppGroup: `group.${props.ios.groupIdentifier}`, SmartechAppId: props.ios.appId, SmartechAutoFetchLocation: props.ios.autoFetchLocation, SmartechUseAdvId: props.ios.useAdvID, }, ...(props.ios.smartechNudges.smartechNudgesEnabled && { HanselKeys: { HanselAppId: props.ios.smartechNudges.appId, HanselAppKey: props.ios.smartechNudges.appKey, } }) }; return newConfig; }); }; const addHanselURLScheme: ConfigPlugin<SmartechBaseProps> = (config, props) => { return withInfoPlist(config, (newConfig) => { const modResults = newConfig.modResults; const existingURLTypes = newConfig.modResults.CFBundleURLTypes || []; if (!props.ios.smartechNudges.smartechNudgesEnabled || !props.ios.smartechNudges.addTestDevice) { return newConfig; } if (props.ios.smartechNudges?.testDeviceURLName == undefined || props.ios.smartechNudges?.testDeviceURLSchema == undefined) { console.log(`Smartech Nudge Url scheme ${props.ios.smartechNudges?.testDeviceURLName} and ${props.ios.smartechNudges?.testDeviceURLSchema}`); return newConfig } const newEntry = { CFBundleTypeRole: "Editor", CFBundleURLName: props.ios.smartechNudges.testDeviceURLName, CFBundleURLSchemes: [props.ios.smartechNudges.testDeviceURLSchema || ""], }; const isNewEntryAlreadyAdded = existingURLTypes.some((entry) => { return ( entry.CFBundleURLName === newEntry.CFBundleURLName && entry.CFBundleURLSchemes.includes(newEntry.CFBundleURLSchemes[0]) ); }); if (!isNewEntryAlreadyAdded) { existingURLTypes.push(newEntry); modResults.CFBundleURLTypes = existingURLTypes; } return newConfig; }); } const addSmartechHeaderMod: ConfigPlugin<SmartechBaseProps> = (config, props) => { return withAppDelegate(config, async (config) => { const { platformProjectRoot, projectName } = config.modRequest; if (projectName && platformProjectRoot) { try { const appDelegateHeaderPath = path.join(platformProjectRoot, projectName, appdelegateSnippet.fileName); const appDelegateHeaderContents = await fs.readFile(appDelegateHeaderPath, 'utf-8'); // Add Smartech header snipper if not already present. if (!appDelegateHeaderContents.includes(appdelegateSnippet.smartechHeaderSnippet)) { const modifiedAppDelegateHeaderContents = `${appDelegateHeaderContents}\n${appdelegateSnippet.smartechHeaderSnippet}`; await fs.writeFile(appDelegateHeaderPath, modifiedAppDelegateHeaderContents, 'utf-8'); } else { console.log(`${appdelegateSnippet.smartechHeaderSnippet} is already added.`) } } catch (error) { console.error('Error modifying AppDelegate.h:', error); } } return config; }); }; const addSmartechHanseleHeaderMod: ConfigPlugin<SmartechBaseProps> = (config, props) => { return withAppDelegate(config, async (config) => { const { platformProjectRoot, projectName } = config.modRequest; if (platformProjectRoot && projectName) { try { const appDelegateHeaderPath = path.join(platformProjectRoot, projectName, appdelegateSnippet.fileName); const appDelegateHeaderContents = await fs.readFile(appDelegateHeaderPath, 'utf-8'); // Add Hansel header snippet if Hansel is enabled and not already present if (props.ios.smartechNudges.smartechNudgesEnabled && !appDelegateHeaderContents.includes(appdelegateSnippet.hanselHeaderSnippet)) { const modifiedAppDelegateHeaderContents = `${appDelegateHeaderContents}\n${appdelegateSnippet.hanselHeaderSnippet}`; await fs.writeFile(appDelegateHeaderPath, modifiedAppDelegateHeaderContents, 'utf-8'); } else { console.log(`${appdelegateSnippet.hanselHeaderSnippet} is already added or status of SmartechNudge: ${props.ios.smartechNudges.smartechNudgesEnabled}`); } } catch (error) { console.error('Error modifying AppDelegate.h:', error); } } return config; }); }; // Set custom AppDelegate contents modifications const setCustomAppDelegateContentsMod: ConfigPlugin<SmartechBaseProps> = (config: ExpoConfig, props) => { return withAppDelegate(config, (cfg) => { const { modResults } = cfg; const { contents } = modResults; const appDelegatePath = cfg.modResults.path const smartechInitContent = addSmartechInitCode(contents, props); const updatedContent = Helper.Ios.addDeepLinkHandler(smartechInitContent, props); fSystem.writeFileSync(appDelegatePath, updatedContent, 'utf-8'); modResults.contents = updatedContent; return cfg; }); }; // Helper function to modify AppDelegate contents const addSmartechInitCode = (contents: string, props: SmartechBaseProps): string => { const lines = contents.split("\n"); const didLaunchIndex = lines.findIndex(line => smartechBaseSnippet.regexPattern.test(line)); if (didLaunchIndex === -1) { return contents; } // Prepare the lines to insert const sdkLines: string[] = [ smartechBaseSnippet.smartechInit, ...(props.ios.isLogEnabled ? [smartechBaseSnippet.debugLevel] : []), smartechBaseSnippet.trackAppInstallUpdateBySmartech, ...((props.ios.smartechNudges.smartechNudgesEnabled && props.ios.smartechNudges.isLogEnabled )? [smartechBaseSnippet.hanselLogSnippet] : []), ]; // Add the snippets before and after the `didFinishLaunching` index const resultLines = [ ...lines.slice(0, didLaunchIndex + 2), ...sdkLines, ...lines.slice(didLaunchIndex + 2), ]; return resultLines.join("\n"); }; // Set custom AppDelegate contents modifications const modifyAppDelegateWithLinker: ConfigPlugin<SmartechBaseProps> = (config: ExpoConfig, props) => { if (!props.ios.smartechNudges.smartechNudgesEnabled || !props.ios.smartechNudges.addTestDevice) { return config; } return withAppDelegate(config, (config) => { const { modResults } = config; let { contents } = modResults; const codeBlock = `BOOL handleBySmartech = [[Smartech sharedInstance] application:application openURL:url options:options]; if(!handleBySmartech) { return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; } return YES;`; const lines = contents.split("\n"); if (contents.includes("openURL:")) { const modifiedContents = contents.replace( "return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options];",`${codeBlock}`); modResults.contents = modifiedContents; } return config; }); }; export const withNetcoreiOS: ConfigPlugin<SmartechBaseProps> = (config, props) => { config = modifyEntitlementsPlist(config, props); config = modifyInfoPlist(config, props); config = addHanselURLScheme(config, props); config = addSmartechHeaderMod(config, props); config = addSmartechHanseleHeaderMod(config, props); config = setCustomAppDelegateContentsMod(config, props); config = modifyAppDelegateWithLinker(config, props); return config; }