index.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. 'use strict';
  2. const through = require('through2');
  3. const deepAssign = require('deep-assign');
  4. const Mode = require('stat-mode');
  5. const defaultMode = 0o777 & (~process.umask());
  6. function normalize(mode) {
  7. let called = false;
  8. const newMode = {
  9. owner: {},
  10. group: {},
  11. others: {}
  12. };
  13. ['read', 'write', 'execute'].forEach(key => {
  14. if (typeof mode[key] === 'boolean') {
  15. newMode.owner[key] = mode[key];
  16. newMode.group[key] = mode[key];
  17. newMode.others[key] = mode[key];
  18. called = true;
  19. }
  20. });
  21. return called ? newMode : mode;
  22. }
  23. module.exports = (mode, dirMode) => {
  24. if (mode !== null && mode !== undefined && typeof mode !== 'number' && typeof mode !== 'object') {
  25. throw new TypeError('Expected mode to be null/undefined/number/Object');
  26. }
  27. if (dirMode === true) {
  28. dirMode = mode;
  29. }
  30. if (dirMode !== null && dirMode !== undefined && typeof dirMode !== 'number' && typeof dirMode !== 'object') {
  31. throw new TypeError('Expected dirMode to be null/undefined/true/number/Object');
  32. }
  33. return through.obj((file, enc, cb) => {
  34. let curMode = mode;
  35. if (file.isNull() && file.stat && file.stat.isDirectory()) {
  36. curMode = dirMode;
  37. }
  38. if (curMode === undefined || curMode === null) {
  39. cb(null, file);
  40. return;
  41. }
  42. file.stat = file.stat || {};
  43. file.stat.mode = file.stat.mode || defaultMode;
  44. if (typeof curMode === 'object') {
  45. const statMode = new Mode(file.stat);
  46. deepAssign(statMode, normalize(curMode));
  47. file.stat.mode = statMode.stat.mode;
  48. } else {
  49. file.stat.mode = curMode;
  50. }
  51. cb(null, file);
  52. });
  53. };