diff --git a/hooks/afterPrepareHook.js b/hooks/afterPrepareHook.js deleted file mode 100755 index e8f6f638..00000000 --- a/hooks/afterPrepareHook.js +++ /dev/null @@ -1,82 +0,0 @@ -'use strict'; - -/** -Hook is executed at the end of the 'prepare' stage. Usually, when you call 'cordova build'. - -It will inject required preferences in the platform-specific projects, based on -data you have specified in the projects config.xml file. -*/ - -var configParser = require('./lib/configXmlParser.js'), - androidManifestWriter = require('./lib/android/manifestWriter.js'), - -// androidWebHook = require('./lib/android/webSiteHook.js'), -iosProjectEntitlements = require('./lib/ios/projectEntitlements.js'), - iosProjectPreferences = require('./lib/ios/xcodePreferences.js'), - ANDROID = 'android', - IOS = 'ios'; - -module.exports = function (ctx) { - run(ctx); -}; - -/** - * Execute hook. - * - * @param {Object} cordovaContext - cordova context object - */ -function run(cordovaContext) { - var pluginPreferences = configParser.readPreferences(cordovaContext), - platformsList = cordovaContext.opts.platforms; - - // if no preferences are found - exit - if (pluginPreferences == null) { - return; - } - - // if no host is defined - exit - if (pluginPreferences.hosts == null || pluginPreferences.hosts.length == 0) { - console.warn('No host is specified in the config.xml. Universal Links plugin is not going to work.'); - return; - } - - platformsList.forEach(function (platform) { - switch (platform) { - case ANDROID: - { - activateUniversalLinksInAndroid(cordovaContext, pluginPreferences); - break; - } - case IOS: - { - activateUniversalLinksInIos(cordovaContext, pluginPreferences); - break; - } - } - }); -} - -/** - * Activate Deep Links for Android application. - * - * @param {Object} cordovaContext - cordova context object - * @param {Object} pluginPreferences - plugin preferences from the config.xml file. Basically, content from tag. - */ -function activateUniversalLinksInAndroid(cordovaContext, pluginPreferences) { - // inject preferenes into AndroidManifest.xml - androidManifestWriter.writePreferences(cordovaContext, pluginPreferences); -} - -/** - * Activate Universal Links for iOS application. - * - * @param {Object} cordovaContext - cordova context object - * @param {Object} pluginPreferences - plugin preferences from the config.xml file. Basically, content from tag. - */ -function activateUniversalLinksInIos(cordovaContext, pluginPreferences) { - // modify xcode project preferences - iosProjectPreferences.enableAssociativeDomainsCapability(cordovaContext); - - // generate entitlements file - iosProjectEntitlements.generateAssociatedDomainsEntitlements(cordovaContext, pluginPreferences); -} \ No newline at end of file diff --git a/hooks/iosBeforePrepareHook.js b/hooks/iosBeforePrepareHook.js deleted file mode 100755 index 367c9b81..00000000 --- a/hooks/iosBeforePrepareHook.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict'; - -/* -Hook executed before the 'prepare' stage. Only for iOS project. -It will check if project name has changed. If so - it will change the name of the .entitlements file to remove that file duplicates. -If file name has no changed - hook would not do anything. -*/ - -var path = require('path'), - fs = require('fs'), - ConfigXmlHelper = require('./lib/configXmlHelper.js'); - -module.exports = function (ctx) { - run(ctx); -}; - -/** - * Run the hook logic. - * - * @param {Object} ctx - cordova context object - */ -function run(ctx) { - var projectRoot = ctx.opts.projectRoot, - iosProjectFilePath = path.join(projectRoot, 'platforms', 'ios'), - configXmlHelper = new ConfigXmlHelper(ctx), - oldProjectName = getOldProjectName(iosProjectFilePath), - newProjectName = configXmlHelper.getProjectName(); - - // if name has not changed - do nothing - if (oldProjectName.length > 0 && oldProjectName === newProjectName) { - return; - } - - console.log('Project name has changed. Renaming .entitlements file.'); - - // if it does - rename it - var oldEntitlementsFilePath = path.join(iosProjectFilePath, oldProjectName, 'Resources', oldProjectName + '.entitlements'), - newEntitlementsFilePath = path.join(iosProjectFilePath, oldProjectName, 'Resources', newProjectName + '.entitlements'); - - try { - fs.renameSync(oldEntitlementsFilePath, newEntitlementsFilePath); - } catch (err) { - console.warn('Failed to rename .entitlements file.'); - console.warn(err); - } -} - -// region Private API - -/** - * Get old name of the project. - * Name is detected by the name of the .xcodeproj file. - * - * @param {String} projectDir absolute path to ios project directory - * @return {String} old project name - */ -function getOldProjectName(projectDir) { - var files = [], - projectName = ''; - - try { - files = fs.readdirSync(projectDir); - } catch (err) { - return ''; - } - - // find file with .xcodeproj extension, use it as an old project name - files.some(function (fileName) { - if (path.extname(fileName) === '.xcodeproj') { - projectName = path.basename(fileName, '.xcodeproj'); - return true; - } - - return false; - }); - - return projectName; -} - -// endregion \ No newline at end of file diff --git a/hooks/lib/configXmlHelper.js b/hooks/lib/configXmlHelper.js deleted file mode 100755 index fff09866..00000000 --- a/hooks/lib/configXmlHelper.js +++ /dev/null @@ -1,121 +0,0 @@ -'use strict'; - -/* -Helper class to read data from config.xml file. -*/ -(function () { - var path = require('path'), - xmlHelper = require('./xmlHelper.js'), - ANDROID = 'android', - IOS = 'ios', - CONFIG_FILE_NAME = 'config.xml', - context, - projectRoot; - - module.exports = ConfigXmlHelper; - - // region public API - - /** - * Constructor. - * - * @param {Object} cordovaContext - cordova context object - */ - function ConfigXmlHelper(cordovaContext) { - context = cordovaContext; - projectRoot = context.opts.projectRoot; - } - - /** - * Read config.xml data as JSON object. - * - * @return {Object} JSON object with data from config.xml - */ - ConfigXmlHelper.prototype.read = function () { - var filePath = getConfigXmlFilePath(); - - return xmlHelper.readXmlAsJson(filePath); - }; - - /** - * Get package name for the application. Depends on the platform. - * - * @param {String} platform - 'ios' or 'android'; for what platform we need a package name - * @return {String} package/bundle name - */ - ConfigXmlHelper.prototype.getPackageName = function (platform) { - var configFilePath = getConfigXmlFilePath(), - config = getCordovaConfigParser(configFilePath), - packageName; - - switch (platform) { - case ANDROID: - { - packageName = config.android_packageName(); - break; - } - case IOS: - { - packageName = config.ios_CFBundleIdentifier(); - break; - } - } - if (packageName === undefined || packageName.length == 0) { - packageName = config.packageName(); - } - - return packageName; - }; - - /** - * Get name of the current project. - * - * @return {String} name of the project - */ - ConfigXmlHelper.prototype.getProjectName = function () { - return getProjectName(); - }; - - // endregion - - // region Private API - - /** - * Get config parser from cordova library. - * - * @param {String} configFilePath absolute path to the config.xml file - * @return {Object} - */ - function getCordovaConfigParser(configFilePath) { - var ConfigParser; - - // If we are running Cordova 5.4 or abova - use parser from cordova-common. - // Otherwise - from cordova-lib. - try { - ConfigParser = context.requireCordovaModule('cordova-common/src/ConfigParser/ConfigParser'); - } catch (e) { - ConfigParser = context.requireCordovaModule('cordova-lib/src/configparser/ConfigParser'); - } - - return new ConfigParser(configFilePath); - } - - /** - * Get absolute path to the config.xml. - */ - function getConfigXmlFilePath() { - return path.join(projectRoot, CONFIG_FILE_NAME); - } - - /** - * Get project name from config.xml - */ - function getProjectName() { - var configFilePath = getConfigXmlFilePath(), - config = getCordovaConfigParser(configFilePath); - - return config.name(); - } - - // endregion -})(); \ No newline at end of file diff --git a/hooks/lib/configXmlParser.js b/hooks/lib/configXmlParser.js deleted file mode 100755 index 2e10e33c..00000000 --- a/hooks/lib/configXmlParser.js +++ /dev/null @@ -1,133 +0,0 @@ -'use strict'; - -/* -Parser for config.xml file. Read plugin-specific preferences (from tag) as JSON object. -*/ -(function () { - - var path = require('path'), - fs = require('fs'), - xml2js = require('xml2js'), - ConfigXmlHelper = require('./configXmlHelper.js'), - DEFAULT_SCHEME = 'http'; - - module.exports = { - readPreferences: readPreferences - }; - - // region Public API - - /** - * Read plugin preferences from the config.xml file. - * - * @param {Object} cordovaContext - cordova context object - * @return {Array} list of host objects - */ - function readPreferences(cordovaContext) { - // read data from projects root config.xml file - var configXml = new ConfigXmlHelper(cordovaContext).read(); - if (configXml == null) { - console.warn('config.xml not found! Please, check that it exist\'s in your project\'s root directory.'); - return null; - } - - // look for data from the tag - var ulXmlPreferences = configXml.widget['branch-config']; - if (ulXmlPreferences == null || ulXmlPreferences.length == 0) { - console.warn(' tag is not set in the config.xml. Universal Links plugin is not going to work.'); - return null; - } - - var xmlPreferences = ulXmlPreferences[0]; - - // read hosts - var hosts = constructHostsList(xmlPreferences); - - // read ios team ID - var iosTeamId = getTeamIdPreference(xmlPreferences); - - // read Android prefix - var androidPrefix = getAndroidPrefixPreference(xmlPreferences); - - return { - 'hosts': hosts, - 'iosTeamId': iosTeamId, - 'androidPrefix': androidPrefix - }; - } - - // endregion - - // region Private API - - function getTeamIdPreference(xmlPreferences) { - if (xmlPreferences.hasOwnProperty('ios-team-id')) { - return xmlPreferences['ios-team-id'][0]['$']['value']; - } - - return null; - } - - function getAndroidPrefixPreference(xmlPreferences) { - if (xmlPreferences.hasOwnProperty('android-prefix')) { - return xmlPreferences['android-prefix'][0]['$']['value']; - } - - return null; - } - - /** - * Construct list of host objects, defined in xml file. - * - * @param {Object} xmlPreferences - plugin preferences from config.xml as JSON object - * @return {Array} array of JSON objects, where each entry defines host data from config.xml. - */ - function constructHostsList(xmlPreferences) { - var hostsList = []; - - // look for defined hosts - var xmlHostList = xmlPreferences['host']; - if (xmlHostList == null || xmlHostList.length == 0) { - return []; - } - - xmlHostList.forEach(function (xmlElement) { - var host = constructHostEntry(xmlElement); - if (host) { - hostsList.push(host); - } - }); - - return hostsList; - } - - /** - * Construct host object from xml data. - * - * @param {Object} xmlElement - xml data to process. - * @return {Object} host entry as JSON object - */ - function constructHostEntry(xmlElement) { - var host = { - scheme: DEFAULT_SCHEME, - name: '' - }, - hostProperties = xmlElement['$']; - - if (hostProperties == null || hostProperties.length == 0) { - return null; - } - - // read host name - host.name = hostProperties.name; - - // read scheme if defined - if (hostProperties['scheme'] != null) { - host.scheme = hostProperties.scheme; - } - - return host; - } - - // endregion -})(); \ No newline at end of file diff --git a/hooks/lib/ios/projectEntitlements.js b/hooks/lib/ios/projectEntitlements.js deleted file mode 100755 index 19e73436..00000000 --- a/hooks/lib/ios/projectEntitlements.js +++ /dev/null @@ -1,177 +0,0 @@ -'use strict'; - -/* -Script creates entitlements file with the list of hosts, specified in config.xml. -File name is: ProjectName.entitlements -Location: ProjectName/ - -Script only generates content. File it self is included in the xcode project in another hook: xcodePreferences.js. -*/ -(function () { - - var path = require('path'), - fs = require('fs'), - plist = require('plist'), - mkpath = require('mkpath'), - ConfigXmlHelper = require('../configXmlHelper.js'), - ASSOCIATED_DOMAINS = 'com.apple.developer.associated-domains', - context, - projectRoot, - projectName, - entitlementsFilePath; - - module.exports = { - generateAssociatedDomainsEntitlements: generateEntitlements - }; - - // region Public API - - /** - * Generate entitlements file content. - * - * @param {Object} cordovaContext - cordova context object - * @param {Object} pluginPreferences - plugin preferences from config.xml; already parsed - */ - function generateEntitlements(cordovaContext, pluginPreferences) { - context = cordovaContext; - - var currentEntitlements = getEntitlementsFileContent(), - newEntitlements = injectPreferences(currentEntitlements, pluginPreferences); - - saveContentToEntitlementsFile(newEntitlements); - } - - // endregion - - // region Work with entitlements file - - /** - * Save data to entitlements file. - * - * @param {Object} content - data to save; JSON object that will be transformed into xml - */ - function saveContentToEntitlementsFile(content) { - var plistContent = plist.build(content), - filePath = pathToEntitlementsFile(); - - // ensure that file exists - mkpath.sync(path.dirname(filePath)); - - // save it's content - fs.writeFileSync(filePath, plistContent, 'utf8'); - } - - /** - * Read data from existing entitlements file. If none exist - default value is returned - * - * @return {String} entitlements file content - */ - function getEntitlementsFileContent() { - var pathToFile = pathToEntitlementsFile(), - content; - - try { - content = fs.readFileSync(pathToFile, 'utf8'); - } catch (err) { - return defaultEntitlementsFile(); - } - - return plist.parse(content); - } - - /** - * Get content for an empty entitlements file. - * - * @return {String} default entitlements file content - */ - function defaultEntitlementsFile() { - return {}; - } - - /** - * Inject list of hosts into entitlements file. - * - * @param {Object} currentEntitlements - entitlements where to inject preferences - * @param {Object} pluginPreferences - list of hosts from config.xml - * @return {Object} new entitlements content - */ - function injectPreferences(currentEntitlements, pluginPreferences) { - var newEntitlements = currentEntitlements, - content = generateAssociatedDomainsContent(pluginPreferences); - - newEntitlements[ASSOCIATED_DOMAINS] = content; - - return newEntitlements; - } - - /** - * Generate content for associated-domains dictionary in the entitlements file. - * - * @param {Object} pluginPreferences - list of hosts from conig.xml - * @return {Object} associated-domains dictionary content - */ - function generateAssociatedDomainsContent(pluginPreferences) { - var domainsList = [], - link; - - // generate list of host links - pluginPreferences.hosts.forEach(function (host) { - link = domainsListEntryForHost(host); - domainsList.push(link); - }); - - return domainsList; - } - - /** - * Generate domain record for the given host. - * - * @param {Object} host - host entry - * @return {String} record - */ - function domainsListEntryForHost(host) { - return 'applinks:' + host.name; - } - - // endregion - - // region Path helper methods - - /** - * Path to entitlements file. - * - * @return {String} absolute path to entitlements file - */ - function pathToEntitlementsFile() { - if (entitlementsFilePath === undefined) { - entitlementsFilePath = path.join(getProjectRoot(), 'platforms', 'ios', getProjectName(), 'Resources', getProjectName() + '.entitlements'); - } - - return entitlementsFilePath; - } - - /** - * Projects root folder path. - * - * @return {String} absolute path to the projects root - */ - function getProjectRoot() { - return context.opts.projectRoot; - } - - /** - * Name of the project from config.xml - * - * @return {String} project name - */ - function getProjectName() { - if (projectName === undefined) { - var configXmlHelper = new ConfigXmlHelper(context); - projectName = configXmlHelper.getProjectName(); - } - - return projectName; - } - - // endregion -})(); \ No newline at end of file diff --git a/hooks/lib/ios/xcodePreferences.js b/hooks/lib/ios/xcodePreferences.js deleted file mode 100755 index 8fb0a30e..00000000 --- a/hooks/lib/ios/xcodePreferences.js +++ /dev/null @@ -1,220 +0,0 @@ -'use strict'; - -/* -Script activates support for Universal Links in the application by setting proper preferences in the xcode project file. -Which is: -- deployment target set to iOS 9.0 -- .entitlements file added to project PBXGroup and PBXFileReferences section -- path to .entitlements file added to Code Sign Entitlements preference -*/ - -(function () { - - var path = require('path'), - compare = require('node-version-compare'), - ConfigXmlHelper = require('../configXmlHelper.js'), - - // pbxFile = require('xcode/lib/pbxFile'), - IOS_DEPLOYMENT_TARGET = '8.0', - COMMENT_KEY = /_comment$/, - context; - - module.exports = { - enableAssociativeDomainsCapability: enableAssociativeDomainsCapability - }; - - // region Public API - - /** - * Activate associated domains capability for the application. - * - * @param {Object} cordovaContext - cordova context object - */ - function enableAssociativeDomainsCapability(cordovaContext) { - context = cordovaContext; - - var projectFile = loadProjectFile(); - - // adjust preferences - activateAssociativeDomains(projectFile.xcode); - - // add entitlements file to pbxfilereference - addPbxReference(projectFile.xcode); - - // save changes - projectFile.write(); - } - - // endregion - - // region Alter project file preferences - - /** - * Activate associated domains support in the xcode project file: - * - set deployment target to ios 9; - * - add .entitlements file to Code Sign Entitlements preference. - * - * @param {Object} xcodeProject - xcode project preferences; all changes are made in that instance - */ - function activateAssociativeDomains(xcodeProject) { - var configurations = nonComments(xcodeProject.pbxXCBuildConfigurationSection()), - entitlementsFilePath = pathToEntitlementsFile(), - config, - buildSettings, - deploymentTargetIsUpdated; - - for (config in configurations) { - buildSettings = configurations[config].buildSettings; - buildSettings['CODE_SIGN_ENTITLEMENTS'] = '"' + entitlementsFilePath + '"'; - // if deployment target is less then the required one - increase it - if (buildSettings['IPHONEOS_DEPLOYMENT_TARGET']) { - var buildDeploymentTarget = buildSettings['IPHONEOS_DEPLOYMENT_TARGET'].toString(); - if (compare(buildDeploymentTarget, IOS_DEPLOYMENT_TARGET) == -1) { - buildSettings['IPHONEOS_DEPLOYMENT_TARGET'] = IOS_DEPLOYMENT_TARGET; - deploymentTargetIsUpdated = true; - } - } else { - buildSettings['IPHONEOS_DEPLOYMENT_TARGET'] = IOS_DEPLOYMENT_TARGET; - deploymentTargetIsUpdated = true; - } - } - - if (deploymentTargetIsUpdated) { - console.log('IOS project now has deployment target set as: ' + IOS_DEPLOYMENT_TARGET); - } - - console.log('IOS project Code Sign Entitlements now set to: ' + entitlementsFilePath); - } - - // endregion - - // region PBXReference methods - - /** - * Add .entitlemets file into the project. - * - * @param {Object} xcodeProject - xcode project preferences; all changes are made in that instance - */ - function addPbxReference(xcodeProject) { - var fileReferenceSection = nonComments(xcodeProject.pbxFileReferenceSection()), - entitlementsRelativeFilePath = pathToEntitlementsFile(); - - if (isPbxReferenceAlreadySet(fileReferenceSection, entitlementsRelativeFilePath)) { - console.log('Entitlements file is in reference section.'); - return; - } - - console.log('Entitlements file is not in references section, adding it'); - createPbxFileReference(xcodeProject, entitlementsRelativeFilePath); - } - - /** - * Check if .entitlemets file reference already set. - * - * @param {Object} fileReferenceSection - PBXFileReference section - * @param {String} entitlementsRelativeFilePath - relative path to entitlements file - * @return true - if reference is set; otherwise - false - */ - function isPbxReferenceAlreadySet(fileReferenceSection, entitlementsRelativeFilePath) { - var isAlreadyInReferencesSection = false, - uuid, - fileRefEntry; - - for (uuid in fileReferenceSection) { - fileRefEntry = fileReferenceSection[uuid]; - if (fileRefEntry.path && fileRefEntry.path.indexOf(entitlementsRelativeFilePath) > -1) { - isAlreadyInReferencesSection = true; - break; - } - } - - return isAlreadyInReferencesSection; - } - - /** - * Create reference to the entitlements file in the xcode project. - * - * @param {Object} xcodeProject - xcode project preferences; all changes are made in that instance - * @param {String} entitlementsRelativeFilePath - relative path to entitlemets file - */ - function createPbxFileReference(xcodeProject, entitlementsRelativeFilePath) { - // commented for now - // var rootGroup = nonComments(xcodeProject.pbxGroupByName('CustomTemplate')), - // entitlementsPbxFile = new pbxFile(entitlementsRelativeFilePath); - // - // entitlementsPbxFile.fileRef = xcodeProject.generateUuid(), - // entitlementsPbxFile.uuid = xcodeProject.generateUuid(); - // - // xcodeProject.addToPbxFileReferenceSection(entitlementsPbxFile); - // - // rootGroup.children.push({ - // 'value': entitlementsPbxFile.fileRef, - // 'comment': path.basename(entitlementsRelativeFilePath) - // }); - xcodeProject.addResourceFile(path.basename(entitlementsRelativeFilePath)); - } - - // region Xcode project file helpers - - /** - * Load iOS project file from platform specific folder. - * - * @return {Object} projectFile - project file information - */ - function loadProjectFile() { - var platform_ios, projectFile; - - try { - // try pre-5.0 cordova structure - platform_ios = context.requireCordovaModule('cordova-lib/src/plugman/platforms')['ios']; - projectFile = platform_ios.parseProjectFile(iosPlatformPath()); - } catch (e) { - // let's try cordova 5.0 structure - platform_ios = context.requireCordovaModule('cordova-lib/src/plugman/platforms/ios'); - projectFile = platform_ios.parseProjectFile(iosPlatformPath()); - } - - return projectFile; - } - - /** - * Remove comments from the file. - * - * @param {Object} obj - file object - * @return {Object} file object without comments - */ - function nonComments(obj) { - var keys = Object.keys(obj), - newObj = {}; - - for (var i = 0, len = keys.length; i < len; i++) { - if (!COMMENT_KEY.test(keys[i])) { - newObj[keys[i]] = obj[keys[i]]; - } - } - - return newObj; - } - - // endregion - - // region Path helpers - - function iosPlatformPath() { - return path.join(projectRoot(), 'platforms', 'ios'); - } - - function projectRoot() { - return context.opts.projectRoot; - } - - function pathToEntitlementsFile() { - var configXmlHelper = new ConfigXmlHelper(context), - projectName = configXmlHelper.getProjectName(), - fileName = projectName + '.entitlements'; - - return path.join(projectName, 'Resources', fileName); - } - - // endregion -})(); \ No newline at end of file