parseJson.js 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. /*
  2. MIT License http://www.opensource.org/licenses/mit-license.php
  3. */
  4. "use strict";
  5. const memoize = require("./memoize");
  6. const getJSONParseError = memoize(() => require("../errors/JSONParseError"));
  7. /** @import { JsonValue } from "../util/fs" */
  8. // Inspired by https://github.com/npm/json-parse-even-better-errors
  9. // Remove byte order marker. This catches EF BB BF (the UTF-8 BOM)
  10. // because the buffer-to-string conversion in `fs.readFileSync()`
  11. // translates it to FEFF, the UTF-16 BOM.
  12. /**
  13. * @param {string | Buffer} txt text
  14. * @returns {string} text without BOM
  15. */
  16. const stripBOM = (txt) => String(txt).replace(/^\uFEFF/, "");
  17. /**
  18. * @template [R=JsonValue]
  19. * @callback ParseJsonFn
  20. * @param {string} raw text
  21. * @param {(this: EXPECTED_ANY, key: string, value: EXPECTED_ANY) => EXPECTED_ANY=} reviver reviver
  22. * @returns {R} parsed JSON
  23. */
  24. /** @type {ParseJsonFn} */
  25. const parseJson = (raw, reviver) => {
  26. const txt = stripBOM(raw);
  27. try {
  28. return JSON.parse(txt, reviver);
  29. } catch (err) {
  30. throw new (getJSONParseError())(/** @type {Error} */ (err), raw, txt);
  31. }
  32. };
  33. module.exports = parseJson;