index.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. 'use strict';
  2. var fs = require('fs'),
  3. join = require('path').join,
  4. resolve = require('path').resolve,
  5. dirname = require('path').dirname,
  6. defaultOptions = {
  7. extensions: ['js', 'json', 'coffee'],
  8. recurse: true,
  9. rename: function (name) {
  10. return name;
  11. },
  12. visit: function (obj) {
  13. return obj;
  14. }
  15. };
  16. function checkFileInclusion(path, filename, options) {
  17. return (
  18. // verify file has valid extension
  19. (new RegExp('\\.(' + options.extensions.join('|') + ')$', 'i').test(filename)) &&
  20. // if options.include is a RegExp, evaluate it and make sure the path passes
  21. !(options.include && options.include instanceof RegExp && !options.include.test(path)) &&
  22. // if options.include is a function, evaluate it and make sure the path passes
  23. !(options.include && typeof options.include === 'function' && !options.include(path, filename)) &&
  24. // if options.exclude is a RegExp, evaluate it and make sure the path doesn't pass
  25. !(options.exclude && options.exclude instanceof RegExp && options.exclude.test(path)) &&
  26. // if options.exclude is a function, evaluate it and make sure the path doesn't pass
  27. !(options.exclude && typeof options.exclude === 'function' && options.exclude(path, filename))
  28. );
  29. }
  30. function requireDirectory(m, path, options) {
  31. var retval = {};
  32. // path is optional
  33. if (path && !options && typeof path !== 'string') {
  34. options = path;
  35. path = null;
  36. }
  37. // default options
  38. options = options || {};
  39. for (var prop in defaultOptions) {
  40. if (typeof options[prop] === 'undefined') {
  41. options[prop] = defaultOptions[prop];
  42. }
  43. }
  44. // if no path was passed in, assume the equivelant of __dirname from caller
  45. // otherwise, resolve path relative to the equivalent of __dirname
  46. path = !path ? dirname(m.filename) : resolve(dirname(m.filename), path);
  47. // get the path of each file in specified directory, append to current tree node, recurse
  48. fs.readdirSync(path).forEach(function (filename) {
  49. var joined = join(path, filename),
  50. files,
  51. key,
  52. obj;
  53. if (fs.statSync(joined).isDirectory() && options.recurse) {
  54. // this node is a directory; recurse
  55. files = requireDirectory(m, joined, options);
  56. // exclude empty directories
  57. if (Object.keys(files).length) {
  58. retval[options.rename(filename, joined, filename)] = files;
  59. }
  60. } else {
  61. if (joined !== m.filename && checkFileInclusion(joined, filename, options)) {
  62. // hash node key shouldn't include file extension
  63. key = filename.substring(0, filename.lastIndexOf('.'));
  64. obj = m.require(joined);
  65. retval[options.rename(key, joined, filename)] = options.visit(obj, joined, filename) || obj;
  66. }
  67. }
  68. });
  69. return retval;
  70. }
  71. module.exports = requireDirectory;
  72. module.exports.defaults = defaultOptions;