@stryke/json
Version:
A package containing JSON parsing/stringify utilities used by Storm Software.
87 lines (85 loc) • 3.27 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
let _stryke_types_base = require("@stryke/types/base");
//#region src/utils/strip-comments.ts
const singleComment = Symbol("singleComment");
const multiComment = Symbol("multiComment");
function stripWithoutWhitespace() {
return "";
}
function stripWithWhitespace(value, start, end) {
return value.slice(start, end).replace(/\S/g, " ");
}
function isEscaped(value, quotePosition) {
let index = quotePosition - 1;
let backslashCount = 0;
while (value[index] === "\\") {
index -= 1;
backslashCount += 1;
}
return Boolean(backslashCount % 2);
}
function stripComments(value, { whitespace = true, trailingCommas = false } = {}) {
if (typeof value !== "string") throw new TypeError(`Expected argument \`jsonString\` to be a \`string\`, got \`${typeof value}\``);
const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;
let isInsideString = false;
let isInsideComment = false;
let offset = 0;
let buffer = "";
let result = "";
let commaIndex = -1;
for (let index = 0; index < value.length; index++) {
const currentCharacter = value[index];
const nextCharacter = value[index + 1];
if (!isInsideComment && currentCharacter === "\"") {
if (!isEscaped(value, index)) isInsideString = !isInsideString;
}
if (isInsideString) continue;
if (!isInsideComment && currentCharacter + (nextCharacter ?? _stryke_types_base.EMPTY_STRING) === "//") {
buffer += value.slice(offset, index);
offset = index;
isInsideComment = singleComment;
index++;
} else if (isInsideComment === singleComment && currentCharacter + (nextCharacter ?? _stryke_types_base.EMPTY_STRING) === "\r\n") {
index++;
isInsideComment = false;
buffer += strip(value, offset, index);
offset = index;
} else if (isInsideComment === singleComment && currentCharacter === "\n") {
isInsideComment = false;
buffer += strip(value, offset, index);
offset = index;
} else if (!isInsideComment && currentCharacter + (nextCharacter ?? _stryke_types_base.EMPTY_STRING) === "/*") {
buffer += value.slice(offset, index);
offset = index;
isInsideComment = multiComment;
index++;
} else if (isInsideComment === multiComment && currentCharacter + (nextCharacter ?? _stryke_types_base.EMPTY_STRING) === "*/") {
index++;
isInsideComment = false;
buffer += strip(value, offset, index + 1);
offset = index + 1;
} else if (trailingCommas && !isInsideComment) {
if (commaIndex !== -1) {
if (currentCharacter === "}" || currentCharacter === "]") {
buffer += value.slice(offset, index);
result += strip(buffer, 0, 1) + buffer.slice(1);
buffer = "";
offset = index;
commaIndex = -1;
} else if (currentCharacter !== " " && currentCharacter !== " " && currentCharacter !== "\r" && currentCharacter !== "\n") {
buffer += value.slice(offset, index);
offset = index;
commaIndex = -1;
}
} else if (currentCharacter === ",") {
result += buffer + value.slice(offset, index);
buffer = "";
offset = index;
commaIndex = index;
}
}
}
return result + buffer + (isInsideComment ? strip(value.slice(offset)) : value.slice(offset));
}
//#endregion
exports.stripComments = stripComments;