UNPKG

@stryke/json

Version:

A package containing JSON parsing/stringify utilities used by Storm Software.

1 lines 6.38 kB
{"version":3,"file":"strip-comments.mjs","names":[],"sources":["../../src/utils/strip-comments.ts"],"sourcesContent":["/* -------------------------------------------------------------------\n\n 🗲 Storm Software - Stryke\n\n This code was released as part of the Stryke project. Stryke\n is maintained by Storm Software under the Apache-2.0 license, and is\n free for commercial and private use. For more information, please visit\n our licensing page at https://stormsoftware.com/licenses/projects/stryke.\n\n Website: https://stormsoftware.com\n Repository: https://github.com/storm-software/stryke\n Documentation: https://docs.stormsoftware.com/projects/stryke\n Contact: https://stormsoftware.com/contact\n\n SPDX-License-Identifier: Apache-2.0\n\n ------------------------------------------------------------------- */\n\nimport { EMPTY_STRING } from \"@stryke/types/base\";\n\nconst singleComment = Symbol(\"singleComment\");\nconst multiComment = Symbol(\"multiComment\");\n\nfunction stripWithoutWhitespace() {\n return \"\";\n}\nfunction stripWithWhitespace(value: string, start?: number, end?: number) {\n return value.slice(start, end).replace(/\\S/g, \" \");\n}\n\nfunction isEscaped(value: string, quotePosition: number) {\n let index = quotePosition - 1;\n let backslashCount = 0;\n while (value[index] === \"\\\\\") {\n index -= 1;\n backslashCount += 1;\n }\n\n return Boolean(backslashCount % 2);\n}\n\nexport function stripComments(\n value: string,\n { whitespace = true, trailingCommas = false } = {}\n) {\n if (typeof value !== \"string\") {\n throw new TypeError(\n `Expected argument \\`jsonString\\` to be a \\`string\\`, got \\`${typeof value}\\``\n );\n }\n\n const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;\n let isInsideString: boolean | symbol = false;\n let isInsideComment: boolean | symbol = false;\n let offset = 0;\n let buffer = \"\";\n let result = \"\";\n let commaIndex = -1;\n for (let index = 0; index < value.length; index++) {\n const currentCharacter = value[index];\n const nextCharacter = value[index + 1];\n if (!isInsideComment && currentCharacter === '\"') {\n const escaped = isEscaped(value, index);\n if (!escaped) {\n isInsideString = !isInsideString;\n }\n }\n if (isInsideString) {\n continue;\n }\n if (\n !isInsideComment &&\n currentCharacter + (nextCharacter ?? EMPTY_STRING) === \"//\"\n ) {\n buffer += value.slice(offset, index);\n offset = index;\n isInsideComment = singleComment;\n index++;\n } else if (\n isInsideComment === singleComment &&\n currentCharacter + (nextCharacter ?? EMPTY_STRING) === \"\\r\\n\"\n ) {\n index++;\n isInsideComment = false;\n buffer += strip(value, offset, index);\n offset = index;\n } else if (isInsideComment === singleComment && currentCharacter === \"\\n\") {\n isInsideComment = false;\n buffer += strip(value, offset, index);\n offset = index;\n } else if (\n !isInsideComment &&\n currentCharacter + (nextCharacter ?? EMPTY_STRING) === \"/*\"\n ) {\n buffer += value.slice(offset, index);\n offset = index;\n isInsideComment = multiComment;\n index++;\n } else if (\n isInsideComment === multiComment &&\n currentCharacter + (nextCharacter ?? EMPTY_STRING) === \"*/\"\n ) {\n index++;\n isInsideComment = false;\n buffer += strip(value, offset, index + 1);\n offset = index + 1;\n } else if (trailingCommas && !isInsideComment) {\n if (commaIndex !== -1) {\n if (currentCharacter === \"}\" || currentCharacter === \"]\") {\n buffer += value.slice(offset, index);\n result += strip(buffer, 0, 1) + buffer.slice(1);\n buffer = \"\";\n offset = index;\n commaIndex = -1;\n } else if (\n currentCharacter !== \" \" &&\n currentCharacter !== \"\t\" &&\n currentCharacter !== \"\\r\" &&\n currentCharacter !== \"\\n\"\n ) {\n buffer += value.slice(offset, index);\n offset = index;\n commaIndex = -1;\n }\n } else if (currentCharacter === \",\") {\n result += buffer + value.slice(offset, index);\n buffer = \"\";\n offset = index;\n commaIndex = index;\n }\n }\n }\n\n return (\n result +\n buffer +\n (isInsideComment ? strip(value.slice(offset)) : value.slice(offset))\n );\n}\n"],"mappings":";;;AAoBA,MAAM,gBAAgB,OAAO,gBAAgB;AAC7C,MAAM,eAAe,OAAO,eAAe;AAE3C,SAAS,yBAAyB;AAChC,QAAO;;AAET,SAAS,oBAAoB,OAAe,OAAgB,KAAc;AACxE,QAAO,MAAM,MAAM,OAAO,IAAI,CAAC,QAAQ,OAAO,IAAI;;AAGpD,SAAS,UAAU,OAAe,eAAuB;CACvD,IAAI,QAAQ,gBAAgB;CAC5B,IAAI,iBAAiB;AACrB,QAAO,MAAM,WAAW,MAAM;AAC5B,WAAS;AACT,oBAAkB;;AAGpB,QAAO,QAAQ,iBAAiB,EAAE;;AAGpC,SAAgB,cACd,OACA,EAAE,aAAa,MAAM,iBAAiB,UAAU,EAAE,EAClD;AACA,KAAI,OAAO,UAAU,SACnB,OAAM,IAAI,UACR,8DAA8D,OAAO,MAAM,IAC5E;CAGH,MAAM,QAAQ,aAAa,sBAAsB;CACjD,IAAI,iBAAmC;CACvC,IAAI,kBAAoC;CACxC,IAAI,SAAS;CACb,IAAI,SAAS;CACb,IAAI,SAAS;CACb,IAAI,aAAa;AACjB,MAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS;EACjD,MAAM,mBAAmB,MAAM;EAC/B,MAAM,gBAAgB,MAAM,QAAQ;AACpC,MAAI,CAAC,mBAAmB,qBAAqB,MAE3C;OAAI,CADY,UAAU,OAAO,MACrB,CACV,kBAAiB,CAAC;;AAGtB,MAAI,eACF;AAEF,MACE,CAAC,mBACD,oBAAoB,iBAAiB,kBAAkB,MACvD;AACA,aAAU,MAAM,MAAM,QAAQ,MAAM;AACpC,YAAS;AACT,qBAAkB;AAClB;aAEA,oBAAoB,iBACpB,oBAAoB,iBAAiB,kBAAkB,QACvD;AACA;AACA,qBAAkB;AAClB,aAAU,MAAM,OAAO,QAAQ,MAAM;AACrC,YAAS;aACA,oBAAoB,iBAAiB,qBAAqB,MAAM;AACzE,qBAAkB;AAClB,aAAU,MAAM,OAAO,QAAQ,MAAM;AACrC,YAAS;aAET,CAAC,mBACD,oBAAoB,iBAAiB,kBAAkB,MACvD;AACA,aAAU,MAAM,MAAM,QAAQ,MAAM;AACpC,YAAS;AACT,qBAAkB;AAClB;aAEA,oBAAoB,gBACpB,oBAAoB,iBAAiB,kBAAkB,MACvD;AACA;AACA,qBAAkB;AAClB,aAAU,MAAM,OAAO,QAAQ,QAAQ,EAAE;AACzC,YAAS,QAAQ;aACR,kBAAkB,CAAC,iBAC5B;OAAI,eAAe,IACjB;QAAI,qBAAqB,OAAO,qBAAqB,KAAK;AACxD,eAAU,MAAM,MAAM,QAAQ,MAAM;AACpC,eAAU,MAAM,QAAQ,GAAG,EAAE,GAAG,OAAO,MAAM,EAAE;AAC/C,cAAS;AACT,cAAS;AACT,kBAAa;eAEb,qBAAqB,OACrB,qBAAqB,OACrB,qBAAqB,QACrB,qBAAqB,MACrB;AACA,eAAU,MAAM,MAAM,QAAQ,MAAM;AACpC,cAAS;AACT,kBAAa;;cAEN,qBAAqB,KAAK;AACnC,cAAU,SAAS,MAAM,MAAM,QAAQ,MAAM;AAC7C,aAAS;AACT,aAAS;AACT,iBAAa;;;;AAKnB,QACE,SACA,UACC,kBAAkB,MAAM,MAAM,MAAM,OAAO,CAAC,GAAG,MAAM,MAAM,OAAO"}