You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

72 lines
2.0 KiB

4 years ago
  1. 'use strict';
  2. const fs = require('fs');
  3. const path = require('path');
  4. const fileType = require('file-type');
  5. const globby = require('globby');
  6. const makeDir = require('make-dir');
  7. const pify = require('pify');
  8. const pPipe = require('p-pipe');
  9. const replaceExt = require('replace-ext');
  10. const fsP = pify(fs);
  11. const handleFile = (input, output, options) => fsP.readFile(input).then(data => {
  12. const dest = output ? path.join(output, path.basename(input)) : null;
  13. if (options.plugins && !Array.isArray(options.plugins)) {
  14. throw new TypeError('The `plugins` option should be an `Array`');
  15. }
  16. const pipe = options.plugins.length > 0 ? pPipe(options.plugins)(data) : Promise.resolve(data);
  17. return pipe
  18. .then(buffer => {
  19. const ret = {
  20. data: buffer,
  21. path: (fileType(buffer) && fileType(buffer).ext === 'webp') ? replaceExt(dest, '.webp') : dest
  22. };
  23. if (!dest) {
  24. return ret;
  25. }
  26. return makeDir(path.dirname(ret.path))
  27. .then(() => fsP.writeFile(ret.path, ret.data))
  28. .then(() => ret);
  29. })
  30. .catch(error => {
  31. error.message = `Error in file: ${input}\n\n${error.message}`;
  32. throw error;
  33. });
  34. });
  35. module.exports = (input, output, options) => {
  36. if (!Array.isArray(input)) {
  37. return Promise.reject(new TypeError(`Expected an \`Array\`, got \`${typeof input}\``));
  38. }
  39. if (typeof output === 'object') {
  40. options = output;
  41. output = null;
  42. }
  43. options = Object.assign({plugins: []}, options);
  44. options.plugins = options.use || options.plugins;
  45. return globby(input, {onlyFiles: true}).then(paths => Promise.all(paths.map(x => handleFile(x, output, options))));
  46. };
  47. module.exports.buffer = (input, options) => {
  48. if (!Buffer.isBuffer(input)) {
  49. return Promise.reject(new TypeError(`Expected a \`Buffer\`, got \`${typeof input}\``));
  50. }
  51. options = Object.assign({plugins: []}, options);
  52. options.plugins = options.use || options.plugins;
  53. if (options.plugins.length === 0) {
  54. return Promise.resolve(input);
  55. }
  56. return pPipe(options.plugins)(input);
  57. };