index.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. 'use strict';
  2. var fs = require('fs');
  3. var path = require('path');
  4. var cpx = require('cpx');
  5. var fsExtra = require('fs-extra');
  6. var makeDir = require('make-dir');
  7. /**
  8. * Execute copy action
  9. *
  10. * @param {Object} command - Command data for given action
  11. * @return {Function|null} - Function that returns a promise or null
  12. */
  13. function copyAction(command, options) {
  14. var verbose = options.verbose;
  15. if (!command.source || !command.destination) {
  16. if (verbose) {
  17. console.log(' - FileManagerPlugin: Warning - copy parameter has to be formated as follows: { source: <string>, destination: <string> }');
  18. }
  19. return null;
  20. }
  21. return function () {
  22. return new Promise(function (resolve, reject) {
  23. // if source is a file, just copyFile()
  24. // if source is a NOT a glob pattern, simply append **/*
  25. var fileRegex = /(\*|\{+|\}+)/g;
  26. var matches = fileRegex.exec(command.source);
  27. if (matches === null) {
  28. fs.lstat(command.source, function (sErr, sStats) {
  29. if (sErr) return reject(sErr);
  30. fs.lstat(command.destination, function (dErr, dStats) {
  31. if (sStats.isFile()) {
  32. var destination = dStats && dStats.isDirectory() ? command.destination + '/' + path.basename(command.source) : command.destination;
  33. if (verbose) {
  34. console.log(' - FileManagerPlugin: Start copy source: ' + command.source + ' to destination: ' + destination);
  35. }
  36. /*
  37. * If the supplied destination is a directory copy inside.
  38. * If the supplied destination is a directory that does not exist yet create it & copy inside
  39. */
  40. var pathInfo = path.parse(destination);
  41. var execCopy = function execCopy(src, dest) {
  42. fsExtra.copy(src, dest, function (err) {
  43. if (err) reject(err);
  44. resolve();
  45. });
  46. };
  47. if (pathInfo.ext === '') {
  48. makeDir(destination).then(function (mPath) {
  49. execCopy(command.source, destination + '/' + path.basename(command.source));
  50. });
  51. } else {
  52. execCopy(command.source, destination);
  53. }
  54. } else {
  55. var sourceDir = command.source + (command.source.substr(-1) !== '/' ? '/' : '') + '**/*';
  56. copyDirectory(sourceDir, command.destination, resolve, reject, options);
  57. }
  58. });
  59. });
  60. } else {
  61. copyDirectory(command.source, command.destination, resolve, reject, options);
  62. }
  63. });
  64. };
  65. }
  66. /**
  67. * Execute copy directory
  68. *
  69. * @param {string} source - source file path
  70. * @param {string} destination - destination file path
  71. * @param {Function} resolve - function used to resolve a Promise
  72. * @param {Function} reject - function used to reject a Promise
  73. * @return {void}
  74. */
  75. function copyDirectory(source, destination, resolve, reject, options) {
  76. var verbose = options.verbose;
  77. /* cpx options */
  78. var cpxOptions = {
  79. clean: false,
  80. includeEmptyDirs: true,
  81. update: false
  82. };
  83. if (verbose) {
  84. console.log(' - FileManagerPlugin: Start copy source file: ' + source + ' to destination file: ' + destination);
  85. }
  86. cpx.copy(source, destination, cpxOptions, function (err) {
  87. if (err && options.verbose) {
  88. console.log(' - FileManagerPlugin: Error - copy failed', err);
  89. reject(err);
  90. }
  91. if (verbose) {
  92. console.log(' - FileManagerPlugin: Finished copy source: ' + source + ' to destination: ' + destination);
  93. }
  94. resolve();
  95. });
  96. }
  97. var fs$1 = require('fs');
  98. var mv = require('mv');
  99. /**
  100. * Execute move action
  101. *
  102. * @param {Object} command - Command data for given action
  103. * @return {Function|null} - Function that returns a promise or null
  104. */
  105. function moveAction(command, options) {
  106. var verbose = options.verbose;
  107. if (!command.source || !command.destination) {
  108. if (verbose) {
  109. console.log(' - FileManagerPlugin: Warning - move parameter has to be formated as follows: { source: <string>, destination: <string> }');
  110. }
  111. return null;
  112. }
  113. if (fs$1.existsSync(command.source)) {
  114. return function () {
  115. return new Promise(function (resolve, reject) {
  116. if (verbose) {
  117. console.log(' - FileManagerPlugin: Start move source: ' + command.source + ' to destination: ' + command.destination);
  118. }
  119. mv(command.source, command.destination, { mkdirp: false }, function (err) {
  120. if (err) {
  121. if (verbose) {
  122. console.log(' - FileManagerPlugin: Error - move failed', err);
  123. }
  124. reject(err);
  125. }
  126. if (verbose) {
  127. console.log(' - FileManagerPlugin: Finished move source: ' + command.source + ' to destination: ' + command.destination);
  128. }
  129. resolve();
  130. });
  131. });
  132. };
  133. } else {
  134. process.emitWarning(' - FileManagerPlugin: Could not move ' + command.source + ': path does not exist');
  135. return null;
  136. }
  137. }
  138. var fs$2 = require('fs');
  139. var rimraf = require('rimraf');
  140. /**
  141. * Execute delete action
  142. *
  143. * @param {Object} command - Command data for given action
  144. * @return {Function|null} - Function that returns a promise or null
  145. */
  146. function deleteAction(command, options) {
  147. var verbose = options.verbose;
  148. return function () {
  149. return new Promise(function (resolve, reject) {
  150. if (verbose) {
  151. console.log(' - FileManagerPlugin: Starting delete path ' + command.source);
  152. }
  153. if (typeof command.source !== 'string') {
  154. if (verbose) {
  155. console.log(' - FileManagerPlugin: Warning - delete parameter has to be type of string. Process canceled.');
  156. }
  157. reject();
  158. }
  159. rimraf(command.source, {}, function (response) {
  160. if (verbose && response === null) {
  161. console.log(' - FileManagerPlugin: Finished delete path ' + command.source);
  162. }
  163. resolve();
  164. });
  165. });
  166. };
  167. }
  168. var makeDir$1 = require('make-dir');
  169. /**
  170. * Execute mkdir action
  171. *
  172. * @param {Object} command - Command data for given action
  173. * @return {Function|null} - Function that returns a promise or null
  174. */
  175. function mkdirAction(command, options) {
  176. var verbose = options.verbose;
  177. return function () {
  178. if (verbose) {
  179. console.log(' - FileManagerPlugin: Creating path ' + command.source);
  180. }
  181. if (typeof command.source !== 'string') {
  182. if (verbose) {
  183. console.log(' - FileManagerPlugin: Warning - mkdir parameter has to be type of string. Process canceled.');
  184. }
  185. return null;
  186. }
  187. return makeDir$1(command.source);
  188. };
  189. }
  190. var fs$3 = require('fs-extra');
  191. var path$1 = require('path');
  192. var archiver = require('archiver');
  193. /**
  194. * Execute mkdir action
  195. *
  196. * @param {Object} command - Command data for given action
  197. * @return {Function|null} - Function that returns a promise or null
  198. */
  199. function archiveAction(command, options) {
  200. var verbose = options.verbose;
  201. return function () {
  202. return new Promise(function (resolve, reject) {
  203. if (!command.source || !command.destination) {
  204. if (verbose) {
  205. console.log(' - FileManagerPlugin: Warning - archive parameter has to be formated as follows: { source: <string>, destination: <string> }');
  206. }
  207. reject();
  208. }
  209. var fileRegex = /(\*|\{+|\}+)/g;
  210. var matches = fileRegex.exec(command.source);
  211. var isGlob = matches !== null;
  212. fs$3.lstat(command.source, function (sErr, sStats) {
  213. var output = fs$3.createWriteStream(command.destination);
  214. var archive = archiver(command.format, command.options);
  215. archive.on('error', function (err) {
  216. return reject(err);
  217. });
  218. archive.pipe(output);
  219. // Exclude destination file from archive
  220. var destFile = path$1.basename(command.destination);
  221. var globOptions = Object.assign({ ignore: destFile }, command.options.globOptions || {});
  222. if (isGlob) archive.glob(command.source, globOptions);else if (sStats.isFile()) archive.file(command.source, { name: path$1.basename(command.source) });else if (sStats.isDirectory()) archive.glob('**/*', {
  223. cwd: command.source,
  224. ignore: destFile
  225. });
  226. archive.finalize().then(function () {
  227. return resolve();
  228. });
  229. });
  230. });
  231. };
  232. }
  233. var classCallCheck = function (instance, Constructor) {
  234. if (!(instance instanceof Constructor)) {
  235. throw new TypeError("Cannot call a class as a function");
  236. }
  237. };
  238. var createClass = function () {
  239. function defineProperties(target, props) {
  240. for (var i = 0; i < props.length; i++) {
  241. var descriptor = props[i];
  242. descriptor.enumerable = descriptor.enumerable || false;
  243. descriptor.configurable = true;
  244. if ("value" in descriptor) descriptor.writable = true;
  245. Object.defineProperty(target, descriptor.key, descriptor);
  246. }
  247. }
  248. return function (Constructor, protoProps, staticProps) {
  249. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  250. if (staticProps) defineProperties(Constructor, staticProps);
  251. return Constructor;
  252. };
  253. }();
  254. var toConsumableArray = function (arr) {
  255. if (Array.isArray(arr)) {
  256. for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  257. return arr2;
  258. } else {
  259. return Array.from(arr);
  260. }
  261. };
  262. var FileManagerPlugin = function () {
  263. function FileManagerPlugin(options) {
  264. classCallCheck(this, FileManagerPlugin);
  265. this.options = this.setOptions(options);
  266. }
  267. createClass(FileManagerPlugin, [{
  268. key: 'setOptions',
  269. value: function setOptions(userOptions) {
  270. var defaultOptions = {
  271. verbose: false,
  272. moveWithMkdirp: false,
  273. onStart: {},
  274. onEnd: {}
  275. };
  276. for (var key in defaultOptions) {
  277. if (userOptions.hasOwnProperty(key)) {
  278. defaultOptions[key] = userOptions[key];
  279. }
  280. }
  281. return defaultOptions;
  282. }
  283. }, {
  284. key: 'checkOptions',
  285. value: function checkOptions(stage) {
  286. var _this = this;
  287. if (this.options.verbose && Object.keys(this.options[stage]).length) {
  288. console.log('FileManagerPlugin: processing ' + stage + ' event');
  289. }
  290. var operationList = [];
  291. if (this.options[stage] && Array.isArray(this.options[stage])) {
  292. this.options[stage].map(function (opts) {
  293. return operationList.push.apply(operationList, toConsumableArray(_this.parseFileOptions(opts, true)));
  294. });
  295. } else {
  296. operationList.push.apply(operationList, toConsumableArray(this.parseFileOptions(this.options[stage])));
  297. }
  298. if (operationList.length) {
  299. operationList.reduce(function (previous, fn) {
  300. return previous.then(function (retVal) {
  301. return fn(retVal);
  302. }).catch(function (err) {
  303. return console.log(err);
  304. });
  305. }, Promise.resolve());
  306. }
  307. }
  308. }, {
  309. key: 'replaceHash',
  310. value: function replaceHash(filename) {
  311. return filename.replace('[hash]', this.fileHash);
  312. }
  313. }, {
  314. key: 'processAction',
  315. value: function processAction(action, params, commandOrder) {
  316. var result = action(params, this.options);
  317. if (result !== null) {
  318. commandOrder.push(result);
  319. }
  320. }
  321. }, {
  322. key: 'parseFileOptions',
  323. value: function parseFileOptions(options) {
  324. var _this2 = this;
  325. var commandOrder = [];
  326. Object.keys(options).forEach(function (actionType) {
  327. var actionOptions = options[actionType];
  328. var actionParams = null;
  329. actionOptions.forEach(function (actionItem) {
  330. switch (actionType) {
  331. case 'copy':
  332. actionParams = Object.assign({ source: _this2.replaceHash(actionItem.source) }, actionItem.destination && { destination: actionItem.destination });
  333. _this2.processAction(copyAction, actionParams, commandOrder);
  334. break;
  335. case 'move':
  336. actionParams = Object.assign({ source: _this2.replaceHash(actionItem.source) }, actionItem.destination && { destination: actionItem.destination });
  337. _this2.processAction(moveAction, actionParams, commandOrder);
  338. break;
  339. case 'delete':
  340. if (!Array.isArray(actionOptions) || typeof actionItem !== 'string') {
  341. throw Error(' - FileManagerPlugin: Fail - delete parameters has to be an array of strings');
  342. }
  343. actionParams = Object.assign({ source: _this2.replaceHash(actionItem) });
  344. _this2.processAction(deleteAction, actionParams, commandOrder);
  345. break;
  346. case 'mkdir':
  347. actionParams = { source: _this2.replaceHash(actionItem) };
  348. _this2.processAction(mkdirAction, actionParams, commandOrder);
  349. break;
  350. case 'archive':
  351. actionParams = {
  352. source: _this2.replaceHash(actionItem.source),
  353. destination: actionItem.destination,
  354. format: actionItem.format ? actionItem.format : 'zip',
  355. options: actionItem.options ? actionItem.options : { zlib: { level: 9 } }
  356. };
  357. _this2.processAction(archiveAction, actionParams, commandOrder);
  358. break;
  359. default:
  360. break;
  361. }
  362. });
  363. });
  364. return commandOrder;
  365. }
  366. }, {
  367. key: 'apply',
  368. value: function apply(compiler) {
  369. var that = this;
  370. var comp = function comp(compilation) {
  371. try {
  372. that.checkOptions('onStart');
  373. } catch (error) {
  374. compilation.errors.push(error);
  375. }
  376. };
  377. var afterEmit = function afterEmit(compilation, cb) {
  378. that.fileHash = compilation.hash;
  379. try {
  380. that.checkOptions('onEnd');
  381. } catch (error) {
  382. compilation.errors.push(error);
  383. }
  384. cb();
  385. };
  386. if (compiler.hooks) {
  387. compiler.hooks.compilation.tap('compilation', comp);
  388. compiler.hooks.afterEmit.tapAsync('afterEmit', afterEmit);
  389. } else {
  390. compiler.plugin('compilation', comp);
  391. compiler.plugin('after-emit', afterEmit);
  392. }
  393. }
  394. }]);
  395. return FileManagerPlugin;
  396. }();
  397. module.exports = FileManagerPlugin;
  398. //# sourceMappingURL=index.js.map