index.js
 1  let _fs
 2  try {
 3    _fs = require('graceful-fs')
 4  } catch (_) {
 5    _fs = require('fs')
 6  }
 7  const universalify = require('universalify')
 8  const { stringify, stripBom } = require('./utils')
 9  
10  async function _readFile (file, options = {}) {
11    if (typeof options === 'string') {
12      options = { encoding: options }
13    }
14  
15    const fs = options.fs || _fs
16  
17    const shouldThrow = 'throws' in options ? options.throws : true
18  
19    let data = await universalify.fromCallback(fs.readFile)(file, options)
20  
21    data = stripBom(data)
22  
23    let obj
24    try {
25      obj = JSON.parse(data, options ? options.reviver : null)
26    } catch (err) {
27      if (shouldThrow) {
28        err.message = `${file}: ${err.message}`
29        throw err
30      } else {
31        return null
32      }
33    }
34  
35    return obj
36  }
37  
38  const readFile = universalify.fromPromise(_readFile)
39  
40  function readFileSync (file, options = {}) {
41    if (typeof options === 'string') {
42      options = { encoding: options }
43    }
44  
45    const fs = options.fs || _fs
46  
47    const shouldThrow = 'throws' in options ? options.throws : true
48  
49    try {
50      let content = fs.readFileSync(file, options)
51      content = stripBom(content)
52      return JSON.parse(content, options.reviver)
53    } catch (err) {
54      if (shouldThrow) {
55        err.message = `${file}: ${err.message}`
56        throw err
57      } else {
58        return null
59      }
60    }
61  }
62  
63  async function _writeFile (file, obj, options = {}) {
64    const fs = options.fs || _fs
65  
66    const str = stringify(obj, options)
67  
68    await universalify.fromCallback(fs.writeFile)(file, str, options)
69  }
70  
71  const writeFile = universalify.fromPromise(_writeFile)
72  
73  function writeFileSync (file, obj, options = {}) {
74    const fs = options.fs || _fs
75  
76    const str = stringify(obj, options)
77    // not sure if fs.writeFileSync returns anything, but just in case
78    return fs.writeFileSync(file, str, options)
79  }
80  
81  const jsonfile = {
82    readFile,
83    readFileSync,
84    writeFile,
85    writeFileSync
86  }
87  
88  module.exports = jsonfile