123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- /*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-
- var fs = require('fs-extra');
- var path = require('path');
- var endent = require('endent');
- var mungeutil = require('./ConfigChanges/munge-util');
-
- function PlatformJson (filePath, platform, root) {
- this.filePath = filePath;
- this.platform = platform;
- this.root = fix_munge(root || {});
- }
-
- PlatformJson.load = function (plugins_dir, platform) {
- var filePath = path.join(plugins_dir, platform + '.json');
- var root = null;
- if (fs.existsSync(filePath)) {
- root = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
- }
- return new PlatformJson(filePath, platform, root);
- };
-
- PlatformJson.prototype.save = function () {
- fs.outputJsonSync(this.filePath, this.root, { spaces: 2 });
- };
-
- /**
- * Indicates whether the specified plugin is installed as a top-level (not as
- * dependency to others)
- * @method function
- * @param {String} pluginId A plugin id to check for.
- * @return {Boolean} true if plugin installed as top-level, otherwise false.
- */
- PlatformJson.prototype.isPluginTopLevel = function (pluginId) {
- return this.root.installed_plugins[pluginId];
- };
-
- /**
- * Indicates whether the specified plugin is installed as a dependency to other
- * plugin.
- * @method function
- * @param {String} pluginId A plugin id to check for.
- * @return {Boolean} true if plugin installed as a dependency, otherwise false.
- */
- PlatformJson.prototype.isPluginDependent = function (pluginId) {
- return this.root.dependent_plugins[pluginId];
- };
-
- /**
- * Indicates whether plugin is installed either as top-level or as dependency.
- * @method function
- * @param {String} pluginId A plugin id to check for.
- * @return {Boolean} true if plugin installed, otherwise false.
- */
- PlatformJson.prototype.isPluginInstalled = function (pluginId) {
- return this.isPluginTopLevel(pluginId) ||
- this.isPluginDependent(pluginId);
- };
-
- PlatformJson.prototype.addPlugin = function (pluginId, variables, isTopLevel) {
- var pluginsList = isTopLevel ?
- this.root.installed_plugins :
- this.root.dependent_plugins;
-
- pluginsList[pluginId] = variables;
-
- return this;
- };
-
- /**
- * @chaining
- * Generates and adds metadata for provided plugin into associated <platform>.json file
- *
- * @param {PluginInfo} pluginInfo A pluginInfo instance to add metadata from
- * @returns {this} Current PlatformJson instance to allow calls chaining
- */
- PlatformJson.prototype.addPluginMetadata = function (pluginInfo) {
-
- var installedModules = this.root.modules || [];
-
- var installedPaths = installedModules.map(function (installedModule) {
- return installedModule.file;
- });
-
- var modulesToInstall = pluginInfo.getJsModules(this.platform)
- .map(function (module) {
- return new ModuleMetadata(pluginInfo.id, module);
- })
- .filter(function (metadata) {
- // Filter out modules which are already added to metadata
- return !installedPaths.includes(metadata.file);
- });
-
- this.root.modules = installedModules.concat(modulesToInstall);
-
- this.root.plugin_metadata = this.root.plugin_metadata || {};
- this.root.plugin_metadata[pluginInfo.id] = pluginInfo.version;
-
- return this;
- };
-
- PlatformJson.prototype.removePlugin = function (pluginId, isTopLevel) {
- var pluginsList = isTopLevel ?
- this.root.installed_plugins :
- this.root.dependent_plugins;
-
- delete pluginsList[pluginId];
-
- return this;
- };
-
- /**
- * @chaining
- * Removes metadata for provided plugin from associated file
- *
- * @param {PluginInfo} pluginInfo A PluginInfo instance to which modules' metadata
- * we need to remove
- *
- * @returns {this} Current PlatformJson instance to allow calls chaining
- */
- PlatformJson.prototype.removePluginMetadata = function (pluginInfo) {
- var modulesToRemove = pluginInfo.getJsModules(this.platform)
- .map(function (jsModule) {
- return ['plugins', pluginInfo.id, jsModule.src].join('/');
- });
-
- var installedModules = this.root.modules || [];
- this.root.modules = installedModules
- .filter(function (installedModule) {
- // Leave only those metadatas which 'file' is not in removed modules
- return !modulesToRemove.includes(installedModule.file);
- });
-
- if (this.root.plugin_metadata) {
- delete this.root.plugin_metadata[pluginInfo.id];
- }
-
- return this;
- };
-
- PlatformJson.prototype.addInstalledPluginToPrepareQueue = function (pluginDirName, vars, is_top_level, force) {
- this.root.prepare_queue.installed.push({ 'plugin': pluginDirName, 'vars': vars, 'topLevel': is_top_level, 'force': force });
- };
-
- PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function (pluginId, is_top_level) {
- this.root.prepare_queue.uninstalled.push({ 'plugin': pluginId, 'id': pluginId, 'topLevel': is_top_level });
- };
-
- /**
- * Moves plugin, specified by id to top-level plugins. If plugin is top-level
- * already, then does nothing.
- * @method function
- * @param {String} pluginId A plugin id to make top-level.
- * @return {PlatformJson} PlatformJson instance.
- */
- PlatformJson.prototype.makeTopLevel = function (pluginId) {
- var plugin = this.root.dependent_plugins[pluginId];
- if (plugin) {
- delete this.root.dependent_plugins[pluginId];
- this.root.installed_plugins[pluginId] = plugin;
- }
- return this;
- };
-
- /**
- * Generates a metadata for all installed plugins and js modules. The resultant
- * string is ready to be written to 'cordova_plugins.js'
- *
- * @returns {String} cordova_plugins.js contents
- */
- PlatformJson.prototype.generateMetadata = function () {
- const stringify = o => JSON.stringify(o, null, 2);
- return endent`
- cordova.define('cordova/plugin_list', function(require, exports, module) {
- module.exports = ${stringify(this.root.modules)};
- module.exports.metadata = ${stringify(this.root.plugin_metadata)};
- });
- `;
- };
-
- /**
- * @chaining
- * Generates and then saves metadata to specified file. Doesn't check if file exists.
- *
- * @param {String} destination File metadata will be written to
- * @return {PlatformJson} PlatformJson instance
- */
- PlatformJson.prototype.generateAndSaveMetadata = function (destination) {
- fs.outputFileSync(destination, this.generateMetadata());
-
- return this;
- };
-
- // convert a munge from the old format ([file][parent][xml] = count) to the current one
- function fix_munge (root) {
- root.prepare_queue = root.prepare_queue || { installed: [], uninstalled: [] };
- root.config_munge = root.config_munge || { files: {} };
- root.installed_plugins = root.installed_plugins || {};
- root.dependent_plugins = root.dependent_plugins || {};
-
- var munge = root.config_munge;
- if (!munge.files) {
- var new_munge = { files: {} };
- for (var file in munge) {
- for (var selector in munge[file]) {
- for (var xml_child in munge[file][selector]) {
- var val = parseInt(munge[file][selector][xml_child]);
- for (var i = 0; i < val; i++) {
- mungeutil.deep_add(new_munge, [file, selector, { xml: xml_child, count: val }]);
- }
- }
- }
- }
- root.config_munge = new_munge;
- }
-
- return root;
- }
-
- /**
- * @constructor
- * @class ModuleMetadata
- *
- * Creates a ModuleMetadata object that represents module entry in 'cordova_plugins.js'
- * file at run time
- *
- * @param {String} pluginId Plugin id where this module installed from
- * @param (JsModule|Object) jsModule A js-module entry from PluginInfo class to generate metadata for
- */
- function ModuleMetadata (pluginId, jsModule) {
-
- if (!pluginId) throw new TypeError('pluginId argument must be a valid plugin id');
- if (!jsModule.src && !jsModule.name) throw new TypeError('jsModule argument must contain src or/and name properties');
-
- this.id = pluginId + '.' + (jsModule.name || jsModule.src.match(/([^\/]+)\.js/)[1]); /* eslint no-useless-escape: 0 */
- this.file = ['plugins', pluginId, jsModule.src].join('/');
- this.pluginId = pluginId;
-
- if (jsModule.clobbers && jsModule.clobbers.length > 0) {
- this.clobbers = jsModule.clobbers.map(function (o) { return o.target; });
- }
- if (jsModule.merges && jsModule.merges.length > 0) {
- this.merges = jsModule.merges.map(function (o) { return o.target; });
- }
- if (jsModule.runs) {
- this.runs = true;
- }
- }
-
- module.exports = PlatformJson;
|