UNPKG

react-klasha

Version:

This is an reactJS library for implementing klasha payment gateway

526 lines (525 loc) 24.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.writeCordovaAndroidManifest = exports.getCordovaPreferences = exports.getIncompatibleCordovaPlugins = exports.checkPluginDependencies = exports.logCordovaManualSteps = exports.getCordovaPlugins = exports.handleCordovaPluginsJS = exports.autoGenerateConfig = exports.removePluginFiles = exports.createEmptyCordovaJS = exports.copyCordovaJS = exports.copyPluginsJS = exports.generateCordovaPluginsJSFile = void 0; const tslib_1 = require("tslib"); const utils_fs_1 = require("@ionic/utils-fs"); const path_1 = require("path"); const plist_1 = tslib_1.__importDefault(require("plist")); const prompts_1 = tslib_1.__importDefault(require("prompts")); const common_1 = require("./android/common"); const colors_1 = tslib_1.__importDefault(require("./colors")); const errors_1 = require("./errors"); const common_2 = require("./ios/common"); const log_1 = require("./log"); const plugin_1 = require("./plugin"); const node_1 = require("./util/node"); const term_1 = require("./util/term"); const xml_1 = require("./util/xml"); /** * Build the root cordova_plugins.js file referencing each Plugin JS file. */ function generateCordovaPluginsJSFile(config, plugins, platform) { const pluginModules = []; const pluginExports = []; plugins.map(p => { const pluginId = p.xml.$.id; const jsModules = plugin_1.getJSModules(p, platform); jsModules.map((jsModule) => { const clobbers = []; const merges = []; let clobbersModule = ''; let mergesModule = ''; let runsModule = ''; let clobberKey = ''; let mergeKey = ''; if (jsModule.clobbers) { jsModule.clobbers.map((clobber) => { clobbers.push(clobber.$.target); clobberKey = clobber.$.target; }); clobbersModule = `, "clobbers": [ "${clobbers.join('",\n "')}" ]`; } if (jsModule.merges) { jsModule.merges.map((merge) => { merges.push(merge.$.target); mergeKey = merge.$.target; }); mergesModule = `, "merges": [ "${merges.join('",\n "')}" ]`; } if (jsModule.runs) { runsModule = ',\n "runs": true'; } const pluginModule = { clobber: clobberKey, merge: mergeKey, // mimics Cordova's module name logic if the name attr is missing pluginContent: `{ "id": "${pluginId + '.' + (jsModule.$.name || jsModule.$.src.match(/([^/]+)\.js/)[1])}", "file": "plugins/${pluginId}/${jsModule.$.src}", "pluginId": "${pluginId}"${clobbersModule}${mergesModule}${runsModule} }`, }; pluginModules.push(pluginModule); }); pluginExports.push(`"${pluginId}": "${p.xml.$.version}"`); }); return ` cordova.define('cordova/plugin_list', function(require, exports, module) { module.exports = [ ${pluginModules .sort((a, b) => a.clobber && b.clobber // Clobbers in alpha order ? a.clobber.localeCompare(b.clobber) : a.clobber || b.clobber // Clobbers before anything else ? b.clobber.localeCompare(a.clobber) : a.merge.localeCompare(b.merge)) .map(e => e.pluginContent) .join(',\n ')} ]; module.exports.metadata = // TOP OF METADATA { ${pluginExports.join(',\n ')} }; // BOTTOM OF METADATA }); `; } exports.generateCordovaPluginsJSFile = generateCordovaPluginsJSFile; /** * Build the plugins/* files for each Cordova plugin installed. */ async function copyPluginsJS(config, cordovaPlugins, platform) { const webDir = await getWebDir(config, platform); const pluginsDir = path_1.join(webDir, 'plugins'); const cordovaPluginsJSFile = path_1.join(webDir, 'cordova_plugins.js'); await removePluginFiles(config, platform); await Promise.all(cordovaPlugins.map(async (p) => { const pluginId = p.xml.$.id; const pluginDir = path_1.join(pluginsDir, pluginId, 'www'); await utils_fs_1.ensureDir(pluginDir); const jsModules = plugin_1.getJSModules(p, platform); await Promise.all(jsModules.map(async (jsModule) => { const filePath = path_1.join(webDir, 'plugins', pluginId, jsModule.$.src); await utils_fs_1.copy(path_1.join(p.rootPath, jsModule.$.src), filePath); let data = await utils_fs_1.readFile(filePath, { encoding: 'utf-8' }); data = data.trim(); // mimics Cordova's module name logic if the name attr is missing const name = pluginId + '.' + (jsModule.$.name || path_1.basename(jsModule.$.src, path_1.extname(jsModule.$.src))); data = `cordova.define("${name}", function(require, exports, module) { \n${data}\n});`; data = data.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script\s*>/gi, ''); await utils_fs_1.writeFile(filePath, data, { encoding: 'utf-8' }); })); const assets = plugin_1.getAssets(p, platform); await Promise.all(assets.map(async (asset) => { const filePath = path_1.join(webDir, asset.$.target); await utils_fs_1.copy(path_1.join(p.rootPath, asset.$.src), filePath); })); })); await utils_fs_1.writeFile(cordovaPluginsJSFile, generateCordovaPluginsJSFile(config, cordovaPlugins, platform)); } exports.copyPluginsJS = copyPluginsJS; async function copyCordovaJS(config, platform) { const cordovaPath = node_1.resolveNode(config.app.rootDir, '@capacitor/core', 'cordova.js'); if (!cordovaPath) { errors_1.fatal(`Unable to find ${colors_1.default.strong('node_modules/@capacitor/core/cordova.js')}.\n` + `Are you sure ${colors_1.default.strong('@capacitor/core')} is installed?`); } return utils_fs_1.copy(cordovaPath, path_1.join(await getWebDir(config, platform), 'cordova.js')); } exports.copyCordovaJS = copyCordovaJS; async function createEmptyCordovaJS(config, platform) { const webDir = await getWebDir(config, platform); await utils_fs_1.writeFile(path_1.join(webDir, 'cordova.js'), ''); await utils_fs_1.writeFile(path_1.join(webDir, 'cordova_plugins.js'), ''); } exports.createEmptyCordovaJS = createEmptyCordovaJS; async function removePluginFiles(config, platform) { const webDir = await getWebDir(config, platform); const pluginsDir = path_1.join(webDir, 'plugins'); const cordovaPluginsJSFile = path_1.join(webDir, 'cordova_plugins.js'); await utils_fs_1.remove(pluginsDir); await utils_fs_1.remove(cordovaPluginsJSFile); } exports.removePluginFiles = removePluginFiles; async function autoGenerateConfig(config, cordovaPlugins, platform) { var _a, _b; let xmlDir = path_1.join(config.android.resDirAbs, 'xml'); const fileName = 'config.xml'; if (platform === 'ios') { xmlDir = config.ios.nativeTargetDirAbs; } await utils_fs_1.ensureDir(xmlDir); const cordovaConfigXMLFile = path_1.join(xmlDir, fileName); await utils_fs_1.remove(cordovaConfigXMLFile); const pluginEntries = []; cordovaPlugins.map(p => { const currentPlatform = plugin_1.getPluginPlatform(p, platform); if (currentPlatform) { const configFiles = currentPlatform['config-file']; if (configFiles) { const configXMLEntries = configFiles.filter(function (item) { var _a; return (_a = item.$) === null || _a === void 0 ? void 0 : _a.target.includes(fileName); }); configXMLEntries.map((entry) => { if (entry.feature) { const feature = { feature: entry.feature }; pluginEntries.push(feature); } }); } } }); const pluginEntriesString = await Promise.all(pluginEntries.map(async (item) => { const xmlString = await xml_1.writeXML(item); return xmlString; })); let pluginPreferencesString = []; if ((_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.cordova) === null || _b === void 0 ? void 0 : _b.preferences) { pluginPreferencesString = await Promise.all(Object.entries(config.app.extConfig.cordova.preferences).map(async ([key, value]) => { return ` <preference name="${key}" value="${value}" />`; })); } const content = `<?xml version='1.0' encoding='utf-8'?> <widget version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0"> <access origin="*" /> ${pluginEntriesString.join('')} ${pluginPreferencesString.join('')} </widget>`; await utils_fs_1.writeFile(cordovaConfigXMLFile, content); } exports.autoGenerateConfig = autoGenerateConfig; async function getWebDir(config, platform) { if (platform === 'ios') { return config.ios.webDirAbs; } if (platform === 'android') { return config.android.webDirAbs; } return ''; } async function handleCordovaPluginsJS(cordovaPlugins, config, platform) { const webDir = await getWebDir(config, platform); await utils_fs_1.mkdirp(webDir); if (cordovaPlugins.length > 0) { plugin_1.printPlugins(cordovaPlugins, platform, 'cordova'); await copyCordovaJS(config, platform); await copyPluginsJS(config, cordovaPlugins, platform); } else { await removePluginFiles(config, platform); await createEmptyCordovaJS(config, platform); } await autoGenerateConfig(config, cordovaPlugins, platform); } exports.handleCordovaPluginsJS = handleCordovaPluginsJS; async function getCordovaPlugins(config, platform) { const allPlugins = await plugin_1.getPlugins(config, platform); let plugins = []; if (platform === config.ios.name) { plugins = await common_2.getIOSPlugins(allPlugins); } else if (platform === config.android.name) { plugins = await common_1.getAndroidPlugins(allPlugins); } return plugins.filter(p => plugin_1.getPluginType(p, platform) === 1 /* Cordova */); } exports.getCordovaPlugins = getCordovaPlugins; async function logCordovaManualSteps(cordovaPlugins, config, platform) { cordovaPlugins.map(p => { const editConfig = plugin_1.getPlatformElement(p, platform, 'edit-config'); const configFile = plugin_1.getPlatformElement(p, platform, 'config-file'); editConfig.concat(configFile).map(async (configElement) => { if (configElement.$ && !configElement.$.target.includes('config.xml')) { if (platform === config.ios.name) { if (configElement.$.target.includes('Info.plist')) { logiOSPlist(configElement, config, p); } } } }); }); } exports.logCordovaManualSteps = logCordovaManualSteps; async function logiOSPlist(configElement, config, plugin) { const plistPath = path_1.resolve(config.ios.nativeTargetDirAbs, 'Info.plist'); const xmlMeta = await xml_1.readXML(plistPath); const data = await utils_fs_1.readFile(plistPath, { encoding: 'utf-8' }); const plistData = plist_1.default.parse(data); const dict = xmlMeta.plist.dict.pop(); if (!dict.key.includes(configElement.$.parent)) { let xml = buildConfigFileXml(configElement); xml = `<key>${configElement.$.parent}</key>${getConfigFileTagContent(xml)}`; log_1.logger.warn(`Configuration required for ${colors_1.default.strong(plugin.id)}.\n` + `Add the following to Info.plist:\n` + xml); } else if (configElement.array || configElement.dict) { if (configElement.array && configElement.array.length > 0 && configElement.array[0].string) { let xml = ''; configElement.array[0].string.map((element) => { const d = plistData[configElement.$.parent]; if (Array.isArray(d) && !d.includes(element)) { xml = xml.concat(`<string>${element}</string>\n`); } }); if (xml.length > 0) { log_1.logger.warn(`Configuration required for ${colors_1.default.strong(plugin.id)}.\n` + `Add the following in the existing ${colors_1.default.strong(configElement.$.parent)} array of your Info.plist:\n` + xml); } } else { logPossibleMissingItem(configElement, plugin); } } } function logPossibleMissingItem(configElement, plugin) { let xml = buildConfigFileXml(configElement); xml = getConfigFileTagContent(xml); xml = removeOuterTags(xml); log_1.logger.warn(`Configuration might be missing for ${colors_1.default.strong(plugin.id)}.\n` + `Add the following to the existing ${colors_1.default.strong(configElement.$.parent)} entry of Info.plist:\n` + xml); } function buildConfigFileXml(configElement) { return xml_1.buildXmlElement(configElement, 'config-file'); } function getConfigFileTagContent(str) { return str.replace(/<config-file.+">|<\/config-file>/g, ''); } function removeOuterTags(str) { const start = str.indexOf('>') + 1; const end = str.lastIndexOf('<'); return str.substring(start, end); } async function checkPluginDependencies(plugins, platform) { const pluginDeps = new Map(); const cordovaPlugins = plugins.filter(p => plugin_1.getPluginType(p, platform) === 1 /* Cordova */); const incompatible = plugins.filter(p => plugin_1.getPluginType(p, platform) === 2 /* Incompatible */); await Promise.all(cordovaPlugins.map(async (p) => { let allDependencies = []; allDependencies = allDependencies.concat(plugin_1.getPlatformElement(p, platform, 'dependency')); if (p.xml['dependency']) { allDependencies = allDependencies.concat(p.xml['dependency']); } allDependencies = allDependencies.filter((dep) => !getIncompatibleCordovaPlugins(platform).includes(dep.$.id) && incompatible.filter(p => p.id === dep.$.id || p.xml.$.id === dep.$.id) .length === 0); if (allDependencies) { await Promise.all(allDependencies.map(async (dep) => { var _a; let plugin = dep.$.id; let version = dep.$.version; if (plugin.includes('@') && plugin.indexOf('@') !== 0) { [plugin, version] = plugin.split('@'); } if (cordovaPlugins.filter(p => p.id === plugin || p.xml.$.id === plugin).length === 0) { if ((_a = dep.$.url) === null || _a === void 0 ? void 0 : _a.startsWith('http')) { plugin = dep.$.url; version = dep.$.commit; } const deps = pluginDeps.get(p.id) || []; deps.push(`${plugin}${version ? colors_1.default.weak(` (${version})`) : ''}`); pluginDeps.set(p.id, deps); } })); } })); if (pluginDeps.size > 0) { let msg = `${colors_1.default.failure(colors_1.default.strong('Plugins are missing dependencies.'))}\n` + `Cordova plugin dependencies must be installed in your project (e.g. w/ ${colors_1.default.input('npm install')}).\n`; for (const [plugin, deps] of pluginDeps.entries()) { msg += `\n ${colors_1.default.strong(plugin)} is missing dependencies:\n` + deps.map(d => ` - ${d}`).join('\n'); } log_1.logger.warn(`${msg}\n`); } } exports.checkPluginDependencies = checkPluginDependencies; function getIncompatibleCordovaPlugins(platform) { const pluginList = [ 'cordova-plugin-splashscreen', 'cordova-plugin-ionic-webview', 'cordova-plugin-crosswalk-webview', 'cordova-plugin-wkwebview-engine', 'cordova-plugin-console', 'cordova-plugin-music-controls', 'cordova-plugin-add-swift-support', 'cordova-plugin-ionic-keyboard', 'cordova-plugin-braintree', '@ionic-enterprise/filesystem', '@ionic-enterprise/keyboard', '@ionic-enterprise/splashscreen', 'cordova-support-google-services', ]; if (platform === 'ios') { pluginList.push('cordova-plugin-statusbar', '@ionic-enterprise/statusbar'); } if (platform === 'android') { pluginList.push('cordova-plugin-compat'); } return pluginList; } exports.getIncompatibleCordovaPlugins = getIncompatibleCordovaPlugins; async function getCordovaPreferences(config) { var _a, _b, _c, _d, _e; const configXml = path_1.join(config.app.rootDir, 'config.xml'); let cordova = {}; if (await utils_fs_1.pathExists(configXml)) { cordova.preferences = {}; const xmlMeta = await xml_1.readXML(configXml); if (xmlMeta.widget.preference) { xmlMeta.widget.preference.map((pref) => { cordova.preferences[pref.$.name] = pref.$.value; }); } } if (cordova.preferences && Object.keys(cordova.preferences).length > 0) { if (term_1.isInteractive()) { const answers = await log_1.logPrompt(`${colors_1.default.strong(`Cordovaaa preferences can be automatically ported to ${colors_1.default.strong(config.app.extConfigName)}.`)}\n` + `Keep in mind: Not all values can be automatically migrated from ${colors_1.default.strong('config.xml')}. There may be more work to do.\n` + `More info: ${colors_1.default.strong('https://capacitorjs.com/docs/cordova/migrating-from-cordova-to-capacitor')}`, { type: 'confirm', name: 'confirm', message: `Migrate Cordova preferences from config.xml?`, initial: true, }); if (answers.confirm) { if ((_b = (_a = config.app.extConfig) === null || _a === void 0 ? void 0 : _a.cordova) === null || _b === void 0 ? void 0 : _b.preferences) { const answers = await prompts_1.default([ { type: 'confirm', name: 'confirm', message: `${config.app.extConfigName} already contains Cordova preferences. Overwrite?`, }, ], { onCancel: () => process.exit(1) }); if (!answers.confirm) { cordova = (_c = config.app.extConfig) === null || _c === void 0 ? void 0 : _c.cordova; } } } else { cordova = (_d = config.app.extConfig) === null || _d === void 0 ? void 0 : _d.cordova; } } } else { cordova = (_e = config.app.extConfig) === null || _e === void 0 ? void 0 : _e.cordova; } return cordova; } exports.getCordovaPreferences = getCordovaPreferences; async function writeCordovaAndroidManifest(cordovaPlugins, config, platform) { var _a; const manifestPath = path_1.join(config.android.cordovaPluginsDirAbs, 'src', 'main', 'AndroidManifest.xml'); const rootXMLEntries = []; const applicationXMLEntries = []; const applicationXMLAttributes = []; let prefsArray = []; cordovaPlugins.map(async (p) => { const editConfig = plugin_1.getPlatformElement(p, platform, 'edit-config'); const configFile = plugin_1.getPlatformElement(p, platform, 'config-file'); prefsArray = prefsArray.concat(plugin_1.getAllElements(p, platform, 'preference')); editConfig.concat(configFile).map(async (configElement) => { var _a, _b; if (configElement.$ && (((_a = configElement.$.target) === null || _a === void 0 ? void 0 : _a.includes('AndroidManifest.xml')) || ((_b = configElement.$.file) === null || _b === void 0 ? void 0 : _b.includes('AndroidManifest.xml')))) { const keys = Object.keys(configElement).filter(k => k !== '$'); keys.map(k => { configElement[k].map((e) => { const xmlElement = xml_1.buildXmlElement(e, k); const pathParts = getPathParts(configElement.$.parent || configElement.$.target); if (pathParts.length > 1) { if (pathParts.pop() === 'application') { if (configElement.$.mode && configElement.$.mode === 'merge' && xmlElement.startsWith('<application')) { Object.keys(e.$).map((ek) => { applicationXMLAttributes.push(`${ek}="${e.$[ek]}"`); }); } else if (!applicationXMLEntries.includes(xmlElement) && !contains(applicationXMLEntries, xmlElement, k)) { applicationXMLEntries.push(xmlElement); } } else { log_1.logger.warn(`Configuration required for ${colors_1.default.strong(p.id)}.\n` + `Add the following to AndroidManifest.xml:\n` + xmlElement); } } else { if (!rootXMLEntries.includes(xmlElement) && !contains(rootXMLEntries, xmlElement, k)) { rootXMLEntries.push(xmlElement); } } }); }); } }); }); const cleartextString = 'android:usesCleartextTraffic="true"'; const cleartext = ((_a = config.app.extConfig.server) === null || _a === void 0 ? void 0 : _a.cleartext) && !applicationXMLAttributes.includes(cleartextString) ? cleartextString : ''; let content = `<?xml version='1.0' encoding='utf-8'?> <manifest package="capacitor.android.plugins" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:amazon="http://schemas.amazon.com/apk/res/android"> <application ${applicationXMLAttributes.join('\n')} ${cleartext}> ${applicationXMLEntries.join('\n')} </application> ${rootXMLEntries.join('\n')} </manifest>`; content = content.replace(new RegExp('$PACKAGE_NAME'.replace('$', '\\$&'), 'g'), '${applicationId}'); for (const preference of prefsArray) { content = content.replace(new RegExp(('$' + preference.$.name).replace('$', '\\$&'), 'g'), preference.$.default); } if (await utils_fs_1.pathExists(manifestPath)) { await utils_fs_1.writeFile(manifestPath, content); } } exports.writeCordovaAndroidManifest = writeCordovaAndroidManifest; function getPathParts(path) { const rootPath = 'manifest'; path = path.replace('/*', rootPath); const parts = path.split('/').filter(part => part !== ''); if (parts.length > 1 || parts.includes(rootPath)) { return parts; } return [rootPath, path]; } function contains(entries, obj, k) { const element = xml_1.parseXML(obj); for (const entry of entries) { const current = xml_1.parseXML(entry); if (element && current && current[k] && element[k] && current[k].$ && element[k].$ && element[k].$['android:name'] === current[k].$['android:name']) { return true; } } return false; }