matchdep.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. /*
  2. * matchdep
  3. * https://github.com/tkellen/node-matchdep
  4. *
  5. * Copyright (c) 2012 Tyler Kellen
  6. * Licensed under the MIT license.
  7. */
  8. 'use strict';
  9. var micromatch = require('micromatch');
  10. var findup = require('findup-sync');
  11. var resolve = require('resolve').sync;
  12. var stackTrace = require('stack-trace');
  13. var path = require('path');
  14. // export object
  15. var matchdep = module.exports = {};
  16. // Ensure configuration has the correct properties.
  17. function loadConfig(config, props) {
  18. // The calling module's path. Unfortunately, because modules are cached,
  19. // module.parent is the FIRST calling module parent, not necessarily the
  20. // current one.
  21. var callerPath = path.dirname(stackTrace.get(loadConfig)[1].getFileName());
  22. // If no config defined, resolve to nearest package.json to the calling lib. If not found, throw an error.
  23. if (config == null) {
  24. config = findup('package.json', {cwd: callerPath});
  25. if (config == null) {
  26. throw new Error('No package.json found.');
  27. }
  28. }
  29. // If filename was specified with no path parts, make the path absolute so
  30. // that resolve doesn't look in node_module directories for it.
  31. else if (typeof config === 'string' && !/[\\\/]/.test(config)) {
  32. config = path.join(callerPath, config);
  33. }
  34. // If package is a string, try to require it.
  35. if (typeof config === 'string') {
  36. config = require(resolve(config, {basedir: callerPath}));
  37. }
  38. // If config is not an object yet, something is amiss.
  39. if (typeof config !== 'object') {
  40. throw new Error('Invalid configuration specified.');
  41. }
  42. // For all specified props, populate result object.
  43. var result = {};
  44. props.forEach(function(prop) {
  45. result[prop] = config[prop] ? Object.keys(config[prop]) : [];
  46. });
  47. return result;
  48. }
  49. // What config properties should each method search?
  50. var methods = {
  51. filter: ['dependencies'],
  52. filterDev: ['devDependencies'],
  53. filterPeer: ['peerDependencies'],
  54. filterAll: ['dependencies', 'devDependencies', 'peerDependencies'],
  55. };
  56. // Dynamically generate methods.
  57. Object.keys(methods).forEach(function(method) {
  58. var props = methods[method];
  59. matchdep[method] = function(pattern, config) {
  60. config = loadConfig(config, props);
  61. var search = props.reduce(function(result, prop) {
  62. return result.concat(config[prop]);
  63. }, []);
  64. return micromatch(search, pattern);
  65. };
  66. });