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, ' ');
7 const isEscaped = (jsonString, quotePosition) => {
8 let index = quotePosition - 1;
9 let backslashCount = 0;
11 while (jsonString[index] === '\\') {
16 return Boolean(backslashCount % 2);
19 module.exports = (jsonString, options = {}) => {
20 if (typeof jsonString !== 'string') {
21 throw new TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``);
24 const strip = options.whitespace === false ? stripWithoutWhitespace : stripWithWhitespace;
26 let insideString = false;
27 let insideComment = false;
31 for (let i = 0; i < jsonString.length; i++) {
32 const currentCharacter = jsonString[i];
33 const nextCharacter = jsonString[i + 1];
35 if (!insideComment && currentCharacter === '"') {
36 const escaped = isEscaped(jsonString, i);
38 insideString = !insideString;
46 if (!insideComment && currentCharacter + nextCharacter === '//') {
47 result += jsonString.slice(offset, i);
49 insideComment = singleComment;
51 } else if (insideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
53 insideComment = false;
54 result += strip(jsonString, offset, i);
57 } else if (insideComment === singleComment && currentCharacter === '\n') {
58 insideComment = false;
59 result += strip(jsonString, offset, i);
61 } else if (!insideComment && currentCharacter + nextCharacter === '/*') {
62 result += jsonString.slice(offset, i);
64 insideComment = multiComment;
67 } else if (insideComment === multiComment && currentCharacter + nextCharacter === '*/') {
69 insideComment = false;
70 result += strip(jsonString, offset, i + 1);
76 return result + (insideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));