You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.6 KiB

4 years ago
  1. 'use strict'
  2. // This is adapted from https://github.com/normalize/mz
  3. // Copyright (c) 2014-2016 Jonathan Ong me@jongleberry.com and Contributors
  4. const u = require('universalify').fromCallback
  5. const fs = require('graceful-fs')
  6. const api = [
  7. 'access',
  8. 'appendFile',
  9. 'chmod',
  10. 'chown',
  11. 'close',
  12. 'copyFile',
  13. 'fchmod',
  14. 'fchown',
  15. 'fdatasync',
  16. 'fstat',
  17. 'fsync',
  18. 'ftruncate',
  19. 'futimes',
  20. 'lchown',
  21. 'lchmod',
  22. 'link',
  23. 'lstat',
  24. 'mkdir',
  25. 'mkdtemp',
  26. 'open',
  27. 'readFile',
  28. 'readdir',
  29. 'readlink',
  30. 'realpath',
  31. 'rename',
  32. 'rmdir',
  33. 'stat',
  34. 'symlink',
  35. 'truncate',
  36. 'unlink',
  37. 'utimes',
  38. 'writeFile'
  39. ].filter(key => {
  40. // Some commands are not available on some systems. Ex:
  41. // fs.copyFile was added in Node.js v8.5.0
  42. // fs.mkdtemp was added in Node.js v5.10.0
  43. // fs.lchown is not available on at least some Linux
  44. return typeof fs[key] === 'function'
  45. })
  46. // Export all keys:
  47. Object.keys(fs).forEach(key => {
  48. if (key === 'promises') {
  49. // fs.promises is a getter property that triggers ExperimentalWarning
  50. // Don't re-export it here, the getter is defined in "lib/index.js"
  51. return
  52. }
  53. exports[key] = fs[key]
  54. })
  55. // Universalify async methods:
  56. api.forEach(method => {
  57. exports[method] = u(fs[method])
  58. })
  59. // We differ from mz/fs in that we still ship the old, broken, fs.exists()
  60. // since we are a drop-in replacement for the native module
  61. exports.exists = function (filename, callback) {
  62. if (typeof callback === 'function') {
  63. return fs.exists(filename, callback)
  64. }
  65. return new Promise(resolve => {
  66. return fs.exists(filename, resolve)
  67. })
  68. }
  69. // fs.read() & fs.write need special treatment due to multiple callback args
  70. exports.read = function (fd, buffer, offset, length, position, callback) {
  71. if (typeof callback === 'function') {
  72. return fs.read(fd, buffer, offset, length, position, callback)
  73. }
  74. return new Promise((resolve, reject) => {
  75. fs.read(fd, buffer, offset, length, position, (err, bytesRead, buffer) => {
  76. if (err) return reject(err)
  77. resolve({ bytesRead, buffer })
  78. })
  79. })
  80. }
  81. // Function signature can be
  82. // fs.write(fd, buffer[, offset[, length[, position]]], callback)
  83. // OR
  84. // fs.write(fd, string[, position[, encoding]], callback)
  85. // We need to handle both cases, so we use ...args
  86. exports.write = function (fd, buffer, ...args) {
  87. if (typeof args[args.length - 1] === 'function') {
  88. return fs.write(fd, buffer, ...args)
  89. }
  90. return new Promise((resolve, reject) => {
  91. fs.write(fd, buffer, ...args, (err, bytesWritten, buffer) => {
  92. if (err) return reject(err)
  93. resolve({ bytesWritten, buffer })
  94. })
  95. })
  96. }