find-package-json.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. 'use strict';
  2. var path = require('path')
  3. , fs = require('fs');
  4. /**
  5. * Attempt to somewhat safely parse the JSON.
  6. *
  7. * @param {String} data JSON blob that needs to be parsed.
  8. * @returns {Object|false} Parsed JSON or false.
  9. * @api private
  10. */
  11. function parse(data) {
  12. data = data.toString('utf-8');
  13. //
  14. // Remove a possible UTF-8 BOM (byte order marker) as this can lead to parse
  15. // values when passed in to the JSON.parse.
  16. //
  17. if (data.charCodeAt(0) === 0xFEFF) data = data.slice(1);
  18. try { return JSON.parse(data); }
  19. catch (e) { return false; }
  20. }
  21. /**
  22. * Find package.json files.
  23. *
  24. * @param {String|Object} root The root directory we should start searching in.
  25. * @returns {Object} Iterator interface.
  26. * @api public
  27. */
  28. module.exports = function find(root) {
  29. root = root || process.cwd();
  30. if (typeof root !== "string") {
  31. if (typeof root === "object" && typeof root.filename === 'string') {
  32. root = root.filename;
  33. } else {
  34. throw new Error("Must pass a filename string or a module object to finder");
  35. }
  36. }
  37. return {
  38. /**
  39. * Return the parsed package.json that we find in a parent folder.
  40. *
  41. * @returns {Object} Value, filename and indication if the iteration is done.
  42. * @api public
  43. */
  44. next: function next() {
  45. if (root.match(/^(\w:\\|\/)$/)) return {
  46. value: undefined,
  47. filename: undefined,
  48. done: true
  49. };
  50. var file = path.join(root, 'package.json')
  51. , data;
  52. root = path.resolve(root, '..');
  53. if (fs.existsSync(file) && (data = parse(fs.readFileSync(file)))) {
  54. data.__path = file;
  55. return {
  56. value: data,
  57. filename: file,
  58. done: false
  59. };
  60. }
  61. return next();
  62. }
  63. };
  64. };