node-internalBinding-fs.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. const fs = require('fs');
  2. const {versionGteLt} = require('../dist/util');
  3. // In node's core, this is implemented in C
  4. // https://github.com/nodejs/node/blob/v15.3.0/src/node_file.cc#L891-L985
  5. /**
  6. * @param {string} path
  7. * @returns {[] | [string, boolean]}
  8. */
  9. function internalModuleReadJSON(path) {
  10. let string
  11. try {
  12. string = fs.readFileSync(path, 'utf8')
  13. } catch (e) {
  14. if (e.code === 'ENOENT') return []
  15. throw e
  16. }
  17. // Node's implementation checks for the presence of relevant keys: main, name, type, exports, imports
  18. // Node does this for performance to skip unnecessary parsing.
  19. // This would slow us down and, based on our usage, we can skip it.
  20. const containsKeys = true
  21. return [string, containsKeys]
  22. }
  23. // In node's core, this is implemented in C
  24. // https://github.com/nodejs/node/blob/63e7dc1e5c71b70c80ed9eda230991edb00811e2/src/node_file.cc#L987-L1005
  25. /**
  26. * @param {string} path
  27. * @returns {number} 0 = file, 1 = dir, negative = error
  28. */
  29. function internalModuleStat(path) {
  30. const stat = fs.statSync(path, { throwIfNoEntry: false });
  31. if(!stat) return -1;
  32. if(stat.isFile()) return 0;
  33. if(stat.isDirectory()) return 1;
  34. }
  35. /**
  36. * @param {string} path
  37. * @returns {number} 0 = file, 1 = dir, negative = error
  38. */
  39. function internalModuleStatInefficient(path) {
  40. try {
  41. const stat = fs.statSync(path);
  42. if(stat.isFile()) return 0;
  43. if(stat.isDirectory()) return 1;
  44. } catch(e) {
  45. return -e.errno || -1;
  46. }
  47. }
  48. const statSupportsThrowIfNoEntry = versionGteLt(process.versions.node, '15.3.0') ||
  49. versionGteLt(process.versions.node, '14.17.0', '15.0.0');
  50. module.exports = {
  51. internalModuleReadJSON,
  52. internalModuleStat: statSupportsThrowIfNoEntry ? internalModuleStat : internalModuleStatInefficient
  53. };