Repositorio del curso CCOM4030 el semestre B91 del proyecto Artesanías con el Instituto de Cultura

PlatformJson.js 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. /*
  2. * Licensed under the Apache License, Version 2.0 (the "License");
  3. * you may not use this file except in compliance with the License.
  4. * You may obtain a copy of the License at
  5. *
  6. * http://www.apache.org/licenses/LICENSE-2.0
  7. *
  8. * Unless required by applicable law or agreed to in writing,
  9. * software distributed under the License is distributed on an
  10. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  11. * KIND, either express or implied. See the License for the
  12. * specific language governing permissions and limitations
  13. * under the License.
  14. *
  15. */
  16. var fs = require('fs-extra');
  17. var path = require('path');
  18. var endent = require('endent');
  19. var mungeutil = require('./ConfigChanges/munge-util');
  20. function PlatformJson (filePath, platform, root) {
  21. this.filePath = filePath;
  22. this.platform = platform;
  23. this.root = fix_munge(root || {});
  24. }
  25. PlatformJson.load = function (plugins_dir, platform) {
  26. var filePath = path.join(plugins_dir, platform + '.json');
  27. var root = null;
  28. if (fs.existsSync(filePath)) {
  29. root = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
  30. }
  31. return new PlatformJson(filePath, platform, root);
  32. };
  33. PlatformJson.prototype.save = function () {
  34. fs.outputJsonSync(this.filePath, this.root, { spaces: 2 });
  35. };
  36. /**
  37. * Indicates whether the specified plugin is installed as a top-level (not as
  38. * dependency to others)
  39. * @method function
  40. * @param {String} pluginId A plugin id to check for.
  41. * @return {Boolean} true if plugin installed as top-level, otherwise false.
  42. */
  43. PlatformJson.prototype.isPluginTopLevel = function (pluginId) {
  44. return this.root.installed_plugins[pluginId];
  45. };
  46. /**
  47. * Indicates whether the specified plugin is installed as a dependency to other
  48. * plugin.
  49. * @method function
  50. * @param {String} pluginId A plugin id to check for.
  51. * @return {Boolean} true if plugin installed as a dependency, otherwise false.
  52. */
  53. PlatformJson.prototype.isPluginDependent = function (pluginId) {
  54. return this.root.dependent_plugins[pluginId];
  55. };
  56. /**
  57. * Indicates whether plugin is installed either as top-level or as dependency.
  58. * @method function
  59. * @param {String} pluginId A plugin id to check for.
  60. * @return {Boolean} true if plugin installed, otherwise false.
  61. */
  62. PlatformJson.prototype.isPluginInstalled = function (pluginId) {
  63. return this.isPluginTopLevel(pluginId) ||
  64. this.isPluginDependent(pluginId);
  65. };
  66. PlatformJson.prototype.addPlugin = function (pluginId, variables, isTopLevel) {
  67. var pluginsList = isTopLevel ?
  68. this.root.installed_plugins :
  69. this.root.dependent_plugins;
  70. pluginsList[pluginId] = variables;
  71. return this;
  72. };
  73. /**
  74. * @chaining
  75. * Generates and adds metadata for provided plugin into associated <platform>.json file
  76. *
  77. * @param {PluginInfo} pluginInfo A pluginInfo instance to add metadata from
  78. * @returns {this} Current PlatformJson instance to allow calls chaining
  79. */
  80. PlatformJson.prototype.addPluginMetadata = function (pluginInfo) {
  81. var installedModules = this.root.modules || [];
  82. var installedPaths = installedModules.map(function (installedModule) {
  83. return installedModule.file;
  84. });
  85. var modulesToInstall = pluginInfo.getJsModules(this.platform)
  86. .map(function (module) {
  87. return new ModuleMetadata(pluginInfo.id, module);
  88. })
  89. .filter(function (metadata) {
  90. // Filter out modules which are already added to metadata
  91. return !installedPaths.includes(metadata.file);
  92. });
  93. this.root.modules = installedModules.concat(modulesToInstall);
  94. this.root.plugin_metadata = this.root.plugin_metadata || {};
  95. this.root.plugin_metadata[pluginInfo.id] = pluginInfo.version;
  96. return this;
  97. };
  98. PlatformJson.prototype.removePlugin = function (pluginId, isTopLevel) {
  99. var pluginsList = isTopLevel ?
  100. this.root.installed_plugins :
  101. this.root.dependent_plugins;
  102. delete pluginsList[pluginId];
  103. return this;
  104. };
  105. /**
  106. * @chaining
  107. * Removes metadata for provided plugin from associated file
  108. *
  109. * @param {PluginInfo} pluginInfo A PluginInfo instance to which modules' metadata
  110. * we need to remove
  111. *
  112. * @returns {this} Current PlatformJson instance to allow calls chaining
  113. */
  114. PlatformJson.prototype.removePluginMetadata = function (pluginInfo) {
  115. var modulesToRemove = pluginInfo.getJsModules(this.platform)
  116. .map(function (jsModule) {
  117. return ['plugins', pluginInfo.id, jsModule.src].join('/');
  118. });
  119. var installedModules = this.root.modules || [];
  120. this.root.modules = installedModules
  121. .filter(function (installedModule) {
  122. // Leave only those metadatas which 'file' is not in removed modules
  123. return !modulesToRemove.includes(installedModule.file);
  124. });
  125. if (this.root.plugin_metadata) {
  126. delete this.root.plugin_metadata[pluginInfo.id];
  127. }
  128. return this;
  129. };
  130. PlatformJson.prototype.addInstalledPluginToPrepareQueue = function (pluginDirName, vars, is_top_level, force) {
  131. this.root.prepare_queue.installed.push({ 'plugin': pluginDirName, 'vars': vars, 'topLevel': is_top_level, 'force': force });
  132. };
  133. PlatformJson.prototype.addUninstalledPluginToPrepareQueue = function (pluginId, is_top_level) {
  134. this.root.prepare_queue.uninstalled.push({ 'plugin': pluginId, 'id': pluginId, 'topLevel': is_top_level });
  135. };
  136. /**
  137. * Moves plugin, specified by id to top-level plugins. If plugin is top-level
  138. * already, then does nothing.
  139. * @method function
  140. * @param {String} pluginId A plugin id to make top-level.
  141. * @return {PlatformJson} PlatformJson instance.
  142. */
  143. PlatformJson.prototype.makeTopLevel = function (pluginId) {
  144. var plugin = this.root.dependent_plugins[pluginId];
  145. if (plugin) {
  146. delete this.root.dependent_plugins[pluginId];
  147. this.root.installed_plugins[pluginId] = plugin;
  148. }
  149. return this;
  150. };
  151. /**
  152. * Generates a metadata for all installed plugins and js modules. The resultant
  153. * string is ready to be written to 'cordova_plugins.js'
  154. *
  155. * @returns {String} cordova_plugins.js contents
  156. */
  157. PlatformJson.prototype.generateMetadata = function () {
  158. const stringify = o => JSON.stringify(o, null, 2);
  159. return endent`
  160. cordova.define('cordova/plugin_list', function(require, exports, module) {
  161. module.exports = ${stringify(this.root.modules)};
  162. module.exports.metadata = ${stringify(this.root.plugin_metadata)};
  163. });
  164. `;
  165. };
  166. /**
  167. * @chaining
  168. * Generates and then saves metadata to specified file. Doesn't check if file exists.
  169. *
  170. * @param {String} destination File metadata will be written to
  171. * @return {PlatformJson} PlatformJson instance
  172. */
  173. PlatformJson.prototype.generateAndSaveMetadata = function (destination) {
  174. fs.outputFileSync(destination, this.generateMetadata());
  175. return this;
  176. };
  177. // convert a munge from the old format ([file][parent][xml] = count) to the current one
  178. function fix_munge (root) {
  179. root.prepare_queue = root.prepare_queue || { installed: [], uninstalled: [] };
  180. root.config_munge = root.config_munge || { files: {} };
  181. root.installed_plugins = root.installed_plugins || {};
  182. root.dependent_plugins = root.dependent_plugins || {};
  183. var munge = root.config_munge;
  184. if (!munge.files) {
  185. var new_munge = { files: {} };
  186. for (var file in munge) {
  187. for (var selector in munge[file]) {
  188. for (var xml_child in munge[file][selector]) {
  189. var val = parseInt(munge[file][selector][xml_child]);
  190. for (var i = 0; i < val; i++) {
  191. mungeutil.deep_add(new_munge, [file, selector, { xml: xml_child, count: val }]);
  192. }
  193. }
  194. }
  195. }
  196. root.config_munge = new_munge;
  197. }
  198. return root;
  199. }
  200. /**
  201. * @constructor
  202. * @class ModuleMetadata
  203. *
  204. * Creates a ModuleMetadata object that represents module entry in 'cordova_plugins.js'
  205. * file at run time
  206. *
  207. * @param {String} pluginId Plugin id where this module installed from
  208. * @param (JsModule|Object) jsModule A js-module entry from PluginInfo class to generate metadata for
  209. */
  210. function ModuleMetadata (pluginId, jsModule) {
  211. if (!pluginId) throw new TypeError('pluginId argument must be a valid plugin id');
  212. if (!jsModule.src && !jsModule.name) throw new TypeError('jsModule argument must contain src or/and name properties');
  213. this.id = pluginId + '.' + (jsModule.name || jsModule.src.match(/([^\/]+)\.js/)[1]); /* eslint no-useless-escape: 0 */
  214. this.file = ['plugins', pluginId, jsModule.src].join('/');
  215. this.pluginId = pluginId;
  216. if (jsModule.clobbers && jsModule.clobbers.length > 0) {
  217. this.clobbers = jsModule.clobbers.map(function (o) { return o.target; });
  218. }
  219. if (jsModule.merges && jsModule.merges.length > 0) {
  220. this.merges = jsModule.merges.map(function (o) { return o.target; });
  221. }
  222. if (jsModule.runs) {
  223. this.runs = true;
  224. }
  225. }
  226. module.exports = PlatformJson;