index.js 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var _fs
  2. try {
  3. _fs = require('graceful-fs')
  4. } catch (_) {
  5. _fs = require('fs')
  6. }
  7. function readFile (file, options, callback) {
  8. if (callback == null) {
  9. callback = options
  10. options = {}
  11. }
  12. if (typeof options === 'string') {
  13. options = {encoding: options}
  14. }
  15. options = options || {}
  16. var fs = options.fs || _fs
  17. var shouldThrow = true
  18. if ('throws' in options) {
  19. shouldThrow = options.throws
  20. }
  21. fs.readFile(file, options, function (err, data) {
  22. if (err) return callback(err)
  23. data = stripBom(data)
  24. var obj
  25. try {
  26. obj = JSON.parse(data, options ? options.reviver : null)
  27. } catch (err2) {
  28. if (shouldThrow) {
  29. err2.message = file + ': ' + err2.message
  30. return callback(err2)
  31. } else {
  32. return callback(null, null)
  33. }
  34. }
  35. callback(null, obj)
  36. })
  37. }
  38. function readFileSync (file, options) {
  39. options = options || {}
  40. if (typeof options === 'string') {
  41. options = {encoding: options}
  42. }
  43. var fs = options.fs || _fs
  44. var shouldThrow = true
  45. if ('throws' in options) {
  46. shouldThrow = options.throws
  47. }
  48. try {
  49. var content = fs.readFileSync(file, options)
  50. content = stripBom(content)
  51. return JSON.parse(content, options.reviver)
  52. } catch (err) {
  53. if (shouldThrow) {
  54. err.message = file + ': ' + err.message
  55. throw err
  56. } else {
  57. return null
  58. }
  59. }
  60. }
  61. function stringify (obj, options) {
  62. var spaces
  63. var EOL = '\n'
  64. if (typeof options === 'object' && options !== null) {
  65. if (options.spaces) {
  66. spaces = options.spaces
  67. }
  68. if (options.EOL) {
  69. EOL = options.EOL
  70. }
  71. }
  72. var str = JSON.stringify(obj, options ? options.replacer : null, spaces)
  73. return str.replace(/\n/g, EOL) + EOL
  74. }
  75. function writeFile (file, obj, options, callback) {
  76. if (callback == null) {
  77. callback = options
  78. options = {}
  79. }
  80. options = options || {}
  81. var fs = options.fs || _fs
  82. var str = ''
  83. try {
  84. str = stringify(obj, options)
  85. } catch (err) {
  86. // Need to return whether a callback was passed or not
  87. if (callback) callback(err, null)
  88. return
  89. }
  90. fs.writeFile(file, str, options, callback)
  91. }
  92. function writeFileSync (file, obj, options) {
  93. options = options || {}
  94. var fs = options.fs || _fs
  95. var str = stringify(obj, options)
  96. // not sure if fs.writeFileSync returns anything, but just in case
  97. return fs.writeFileSync(file, str, options)
  98. }
  99. function stripBom (content) {
  100. // we do this because JSON.parse would convert it to a utf8 string if encoding wasn't specified
  101. if (Buffer.isBuffer(content)) content = content.toString('utf8')
  102. content = content.replace(/^\uFEFF/, '')
  103. return content
  104. }
  105. var jsonfile = {
  106. readFile: readFile,
  107. readFileSync: readFileSync,
  108. writeFile: writeFile,
  109. writeFileSync: writeFileSync
  110. }
  111. module.exports = jsonfile