• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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};
78