index.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. 'use strict';
  2. const singleComment = Symbol('singleComment');
  3. const multiComment = Symbol('multiComment');
  4. const stripWithoutWhitespace = () => '';
  5. const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/\S/g, ' ');
  6. const isEscaped = (jsonString, quotePosition) => {
  7. let index = quotePosition - 1;
  8. let backslashCount = 0;
  9. while (jsonString[index] === '\\') {
  10. index -= 1;
  11. backslashCount += 1;
  12. }
  13. return Boolean(backslashCount % 2);
  14. };
  15. module.exports = (jsonString, options = {}) => {
  16. if (typeof jsonString !== 'string') {
  17. throw new TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``);
  18. }
  19. const strip = options.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace;
  20. let insideString = false;
  21. let insideComment = false;
  22. let offset = 0;
  23. let result = '';
  24. for (let i = 0; i < jsonString.length; i++) {
  25. const currentCharacter = jsonString[i];
  26. const nextCharacter = jsonString[i + 1];
  27. if (!insideComment && currentCharacter === '"') {
  28. const escaped = isEscaped(jsonString, i);
  29. if (!escaped) {
  30. insideString = !insideString;
  31. }
  32. }
  33. if (insideString) {
  34. continue;
  35. }
  36. if (!insideComment && currentCharacter + nextCharacter === '//') {
  37. result += jsonString.slice(offset, i);
  38. offset = i;
  39. insideComment = singleComment;
  40. i++;
  41. } else if (insideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
  42. i++;
  43. insideComment = false;
  44. result += strip(jsonString, offset, i);
  45. offset = i;
  46. continue;
  47. } else if (insideComment === singleComment && currentCharacter === '\n') {
  48. insideComment = false;
  49. result += strip(jsonString, offset, i);
  50. offset = i;
  51. } else if (!insideComment && currentCharacter + nextCharacter === '/*') {
  52. result += jsonString.slice(offset, i);
  53. offset = i;
  54. insideComment = multiComment;
  55. i++;
  56. continue;
  57. } else if (insideComment === multiComment && currentCharacter + nextCharacter === '*/') {
  58. i++;
  59. insideComment = false;
  60. result += strip(jsonString, offset, i + 1);
  61. offset = i + 1;
  62. continue;
  63. }
  64. }
  65. return result + (insideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));
  66. };