UNPKG

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