Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

jsonrepair

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jsonrepair - npm Package Compare versions

Comparing version 3.8.1 to 3.9.0

85

lib/cjs/regular/jsonrepair.js

@@ -83,3 +83,3 @@ "use strict";

parseWhitespaceAndSkipComments();
const processed = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString();
const processed = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString(false) || parseRegex();
parseWhitespaceAndSkipComments();

@@ -202,3 +202,3 @@ return processed;

skipEllipsis();
const processedKey = parseString() || parseUnquotedString();
const processedKey = parseString() || parseUnquotedString(true);
if (!processedKey) {

@@ -317,3 +317,3 @@ if (text.charCodeAt(i) === _stringUtils.codeClosingBrace || text.charCodeAt(i) === _stringUtils.codeOpeningBrace || text.charCodeAt(i) === _stringUtils.codeClosingBracket || text.charCodeAt(i) === _stringUtils.codeOpeningBracket || text[i] === undefined) {

// repair: wrap the output inside array brackets
output = "[\n".concat(output, "\n]");
output = `[\n${output}\n]`;
}

@@ -399,4 +399,4 @@

// repair unescaped quote
str = "".concat(str.substring(0, oQuote), "\\").concat(str.substring(oQuote));
} else if (stopAtDelimiter && (0, _stringUtils.isDelimiter)(text[i])) {
str = `${str.substring(0, oQuote)}\\${str.substring(oQuote)}`;
} else if (stopAtDelimiter && (0, _stringUtils.isUnquotedStringDelimiter)(text[i])) {
// we're in the mode to stop the string at the first delimiter

@@ -443,3 +443,3 @@ // because there is an end quote missing

// repair unescaped double quote
str += "\\".concat(char);
str += `\\${char}`;
i++;

@@ -558,3 +558,3 @@ } else if ((0, _stringUtils.isControlCharacter)(code)) {

const hasInvalidLeadingZero = /^0\d/.test(num);
output += hasInvalidLeadingZero ? "\"".concat(num, "\"") : num;
output += hasInvalidLeadingZero ? `"${num}"` : num;
return true;

@@ -588,14 +588,18 @@ }

*/
function parseUnquotedString() {
function parseUnquotedString(isKey) {
// note that the symbol can end with whitespaces: we stop at the next delimiter
// also, note that we allow strings to contain a slash / in order to support repairing regular expressions
const start = i;
while (i < text.length && !(0, _stringUtils.isDelimiterExceptSlash)(text[i]) && !(0, _stringUtils.isQuote)(text.charCodeAt(i))) {
i++;
}
if (i > start) {
if (text.charCodeAt(i) === _stringUtils.codeOpenParenthesis && (0, _stringUtils.isFunctionName)(text.slice(start, i).trim())) {
if (_stringUtils.regexFunctionNameCharStart.test(text[i])) {
while (i < text.length && _stringUtils.regexFunctionNameChar.test(text[i])) {
i++;
}
let j = i;
while ((0, _stringUtils.isWhitespace)(text.charCodeAt(j))) {
j++;
}
if (text[j] === '(') {
// repair a MongoDB function call like NumberLong("2")
// repair a JSONP function call like callback({...});
i++;
i = j + 1;
parseValue();

@@ -611,21 +615,36 @@ if (text.charCodeAt(i) === _stringUtils.codeCloseParenthesis) {

return true;
// biome-ignore lint/style/noUselessElse: <explanation>
} else {
// repair unquoted string
// also, repair undefined into null
}
}
while (i < text.length && !(0, _stringUtils.isUnquotedStringDelimiter)(text[i]) && !(0, _stringUtils.isQuote)(text.charCodeAt(i)) && (!isKey || text[i] !== ':')) {
i++;
}
if (i > start) {
// repair unquoted string
// also, repair undefined into null
// first, go back to prevent getting trailing whitespaces in the string
while ((0, _stringUtils.isWhitespace)(text.charCodeAt(i - 1)) && i > 0) {
i--;
}
const symbol = text.slice(start, i);
output += symbol === 'undefined' ? 'null' : JSON.stringify(symbol);
if (text.charCodeAt(i) === _stringUtils.codeDoubleQuote) {
// we had a missing start quote, but now we encountered the end quote, so we can skip that one
i++;
}
return true;
// first, go back to prevent getting trailing whitespaces in the string
while ((0, _stringUtils.isWhitespace)(text.charCodeAt(i - 1)) && i > 0) {
i--;
}
const symbol = text.slice(start, i);
output += symbol === 'undefined' ? 'null' : JSON.stringify(symbol);
if (text.charCodeAt(i) === _stringUtils.codeDoubleQuote) {
// we had a missing start quote, but now we encountered the end quote, so we can skip that one
i++;
}
return true;
}
}
function parseRegex() {
if (text[i] === '/') {
const start = i;
i++;
while (i < text.length && (text[i] !== '/' || text[i - 1] === '\\')) {
i++;
}
i++;
output += `"${text.substring(start, i)}"`;
return true;
}
}
function prevNonWhitespaceIndex(start) {

@@ -645,9 +664,9 @@ let prev = start;

// change the number more than it needs to make it valid JSON
output += "".concat(text.slice(start, i), "0");
output += `${text.slice(start, i)}0`;
}
function throwInvalidCharacter(char) {
throw new _JSONRepairError.JSONRepairError("Invalid character ".concat(JSON.stringify(char)), i);
throw new _JSONRepairError.JSONRepairError(`Invalid character ${JSON.stringify(char)}`, i);
}
function throwUnexpectedCharacter() {
throw new _JSONRepairError.JSONRepairError("Unexpected character ".concat(JSON.stringify(text[i])), i);
throw new _JSONRepairError.JSONRepairError(`Unexpected character ${JSON.stringify(text[i])}`, i);
}

@@ -665,3 +684,3 @@ function throwUnexpectedEnd() {

const chars = text.slice(i, i + 6);
throw new _JSONRepairError.JSONRepairError("Invalid unicode character \"".concat(chars, "\""), i);
throw new _JSONRepairError.JSONRepairError(`Invalid unicode character "${chars}"`, i);
}

@@ -668,0 +687,0 @@ }

@@ -14,7 +14,7 @@ "use strict";

if (index < offset) {
throw new Error("".concat(indexOutOfRangeMessage, " (index: ").concat(index, ", offset: ").concat(offset, ")"));
throw new Error(`${indexOutOfRangeMessage} (index: ${index}, offset: ${offset})`);
}
if (index >= currentLength) {
if (!closed) {
throw new Error("".concat(indexOutOfRangeMessage, " (index: ").concat(index, ")"));
throw new Error(`${indexOutOfRangeMessage} (index: ${index})`);
}

@@ -21,0 +21,0 @@ }

@@ -39,3 +39,3 @@ "use strict";

if (offset > 0) {
throw new Error("Cannot unshift: ".concat(flushedMessage));
throw new Error(`Cannot unshift: ${flushedMessage}`);
}

@@ -47,3 +47,3 @@ buffer = text + buffer;

if (start < offset) {
throw new Error("Cannot remove: ".concat(flushedMessage));
throw new Error(`Cannot remove: ${flushedMessage}`);
}

@@ -58,3 +58,3 @@ if (end !== undefined) {

if (index < offset) {
throw new Error("Cannot insert: ".concat(flushedMessage));
throw new Error(`Cannot insert: ${flushedMessage}`);
}

@@ -89,3 +89,3 @@ buffer = buffer.substring(0, index - offset) + text + buffer.substring(index - offset);

if (bufferIndex <= 0) {
throw new Error("Cannot insert: ".concat(flushedMessage));
throw new Error(`Cannot insert: ${flushedMessage}`);
}

@@ -92,0 +92,0 @@ buffer = buffer.substring(0, bufferIndex) + textToInsert + buffer.substring(bufferIndex);

@@ -132,3 +132,3 @@ "use strict";

function parseValue() {
return parseObjectStart() || parseArrayStart() || parseString() || parseNumber() || parseKeywords() || parseRepairUnquotedString();
return parseObjectStart() || parseArrayStart() || parseString() || parseNumber() || parseKeywords() || parseRepairUnquotedString() || parseRepairRegex();
}

@@ -164,13 +164,23 @@ function parseObjectStart() {

function parseRepairUnquotedString() {
const unquotedStringEnd = findNextDelimiter();
let j = i;
if (_stringUtils.regexFunctionNameCharStart.test(input.charAt(j))) {
while (!input.isEnd(j) && _stringUtils.regexFunctionNameChar.test(input.charAt(j))) {
j++;
}
let k = j;
while ((0, _stringUtils.isWhitespace)(input.charCodeAt(k))) {
k++;
}
if (input.charCodeAt(k) === _stringUtils.codeOpenParenthesis) {
// repair a MongoDB function call like NumberLong("2")
// repair a JSONP function call like callback({...});
k++;
i = k;
return stack.push(_stack.StackType.functionCall, _stack.Caret.beforeValue);
}
}
const unquotedStringEnd = findNextDelimiter(false, j);
if (unquotedStringEnd !== null) {
const symbol = input.substring(i, unquotedStringEnd);
i = unquotedStringEnd;
if (skipCharacter(_stringUtils.codeOpenParenthesis) && (0, _stringUtils.isFunctionName)(symbol.trim())) {
// A MongoDB function call like NumberLong("2")
// Or a JSONP function call like callback({...});
// we strip the function call
return stack.push(_stack.StackType.functionCall, _stack.Caret.beforeValue);
}
output.push(symbol === 'undefined' ? 'null' : JSON.stringify(symbol));

@@ -185,2 +195,14 @@ if (input.charCodeAt(i) === _stringUtils.codeDoubleQuote) {

}
function parseRepairRegex() {
if (input.charAt(i) === '/') {
const start = i;
i++;
while (!input.isEnd(i) && (input.charAt(i) !== '/' || input.charAt(i - 1) === '\\')) {
i++;
}
i++;
output.push(`"${input.substring(start, i)}"`);
return stack.update(_stack.Caret.afterValue);
}
}
function parseRepairMissingObjectValue() {

@@ -493,3 +515,3 @@ // repair missing object value

output.insertAt(oQuote, '\\');
} else if (stopAtDelimiter && (0, _stringUtils.isDelimiter)(input.charAt(i))) {
} else if (stopAtDelimiter && (0, _stringUtils.isUnquotedStringDelimiter)(input.charAt(i))) {
// we're in the mode to stop the string at the first delimiter

@@ -535,3 +557,3 @@ // because there is an end quote missing

// repair unescaped double quote
output.push("\\".concat(char));
output.push(`\\${char}`);
i++;

@@ -650,3 +672,3 @@ } else if ((0, _stringUtils.isControlCharacter)(code)) {

const hasInvalidLeadingZero = /^0\d/.test(num);
output.push(hasInvalidLeadingZero ? "\"".concat(num, "\"") : num);
output.push(hasInvalidLeadingZero ? `"${num}"` : num);
return stack.update(_stack.Caret.afterValue);

@@ -675,3 +697,3 @@ }

function parseUnquotedKey() {
let end = findNextDelimiter();
let end = findNextDelimiter(true, i);
if (end !== null) {

@@ -693,7 +715,7 @@ // first, go back to prevent getting trailing whitespaces in the string

}
function findNextDelimiter() {
function findNextDelimiter(isKey, start) {
// note that the symbol can end with whitespaces: we stop at the next delimiter
// also, note that we allow strings to contain a slash / in order to support repairing regular expressions
let j = i;
while (!input.isEnd(j) && !(0, _stringUtils.isDelimiterExceptSlash)(input.charAt(j)) && !(0, _stringUtils.isQuote)(input.charCodeAt(j))) {
let j = start;
while (!input.isEnd(j) && !(0, _stringUtils.isUnquotedStringDelimiter)(input.charAt(j)) && !(0, _stringUtils.isQuote)(input.charCodeAt(j)) && (!isKey || input.charAt(j) !== ':')) {
j++;

@@ -717,9 +739,9 @@ }

// change the number more than it needs to make it valid JSON
output.push("".concat(input.substring(start, i), "0"));
output.push(`${input.substring(start, i)}0`);
}
function throwInvalidCharacter(char) {
throw new _JSONRepairError.JSONRepairError("Invalid character ".concat(JSON.stringify(char)), i);
throw new _JSONRepairError.JSONRepairError(`Invalid character ${JSON.stringify(char)}`, i);
}
function throwUnexpectedCharacter() {
throw new _JSONRepairError.JSONRepairError("Unexpected character ".concat(JSON.stringify(input.charAt(i))), i);
throw new _JSONRepairError.JSONRepairError(`Unexpected character ${JSON.stringify(input.charAt(i))}`, i);
}

@@ -737,3 +759,3 @@ function throwUnexpectedEnd() {

const chars = input.substring(i, i + 6);
throw new _JSONRepairError.JSONRepairError("Invalid unicode character \"".concat(chars, "\""), i);
throw new _JSONRepairError.JSONRepairError(`Invalid unicode character "${chars}"`, i);
}

@@ -740,0 +762,0 @@ function atEndOfBlockComment(i) {

@@ -12,4 +12,4 @@ "use strict";

onData: chunk => transform.push(chunk),
bufferSize: options === null || options === void 0 ? void 0 : options.bufferSize,
chunkSize: options === null || options === void 0 ? void 0 : options.chunkSize
bufferSize: options?.bufferSize,
chunkSize: options?.chunkSize
});

@@ -16,0 +16,0 @@ const transform = new _nodeStream.Transform({

@@ -9,3 +9,3 @@ "use strict";

constructor(message, position) {
super("".concat(message, " at position ").concat(position));
super(`${message} at position ${position}`);
this.position = position;

@@ -12,0 +12,0 @@ }

@@ -11,7 +11,5 @@ "use strict";

exports.isDelimiter = isDelimiter;
exports.isDelimiterExceptSlash = isDelimiterExceptSlash;
exports.isDigit = isDigit;
exports.isDoubleQuote = isDoubleQuote;
exports.isDoubleQuoteLike = isDoubleQuoteLike;
exports.isFunctionName = isFunctionName;
exports.isHex = isHex;

@@ -23,4 +21,6 @@ exports.isQuote = isQuote;

exports.isStartOfValue = isStartOfValue;
exports.isUnquotedStringDelimiter = isUnquotedStringDelimiter;
exports.isValidStringCharacter = isValidStringCharacter;
exports.isWhitespace = isWhitespace;
exports.regexFunctionNameCharStart = exports.regexFunctionNameChar = void 0;
exports.removeAtIndex = removeAtIndex;

@@ -85,4 +85,7 @@ exports.stripLastOccurrence = stripLastOccurrence;

const regexDelimiter = /^[,:[\]/{}()\n+]$/;
function isDelimiterExceptSlash(char) {
return isDelimiter(char) && char !== '/';
const regexUnquotedStringDelimiter = /^[,[\]/{}\n+]$/;
const regexFunctionNameCharStart = exports.regexFunctionNameCharStart = /^[a-zA-Z_$]$/;
const regexFunctionNameChar = exports.regexFunctionNameChar = /^[a-zA-Z_$0-9]$/;
function isUnquotedStringDelimiter(char) {
return regexUnquotedStringDelimiter.test(char);
}

@@ -186,5 +189,2 @@ function isStartOfValue(char) {

}
function isFunctionName(text) {
return /^\w+$/.test(text);
}
//# sourceMappingURL=stringUtils.js.map
import { JSONRepairError } from '../utils/JSONRepairError.js';
import { codeAsterisk, codeBackslash, codeCloseParenthesis, codeClosingBrace, codeClosingBracket, codeColon, codeComma, codeDot, codeDoubleQuote, codeLowercaseE, codeMinus, codeNewline, codeOpenParenthesis, codeOpeningBrace, codeOpeningBracket, codePlus, codeSemicolon, codeSlash, codeUppercaseE, endsWithCommaOrNewline, insertBeforeLastWhitespace, isControlCharacter, isDelimiter, isDelimiterExceptSlash, isDigit, isDoubleQuote, isDoubleQuoteLike, isFunctionName, isHex, isQuote, isSingleQuote, isSingleQuoteLike, isSpecialWhitespace, isStartOfValue, isValidStringCharacter, isWhitespace, removeAtIndex, stripLastOccurrence } from '../utils/stringUtils.js';
import { codeAsterisk, codeBackslash, codeCloseParenthesis, codeClosingBrace, codeClosingBracket, codeColon, codeComma, codeDot, codeDoubleQuote, codeLowercaseE, codeMinus, codeNewline, codeOpeningBrace, codeOpeningBracket, codePlus, codeSemicolon, codeSlash, codeUppercaseE, endsWithCommaOrNewline, insertBeforeLastWhitespace, isControlCharacter, isDelimiter, isDigit, isDoubleQuote, isDoubleQuoteLike, isHex, isQuote, isSingleQuote, isSingleQuoteLike, isSpecialWhitespace, isStartOfValue, isUnquotedStringDelimiter, isValidStringCharacter, isWhitespace, regexFunctionNameChar, regexFunctionNameCharStart, removeAtIndex, stripLastOccurrence } from '../utils/stringUtils.js';
const controlCharacters = {

@@ -77,3 +77,3 @@ '\b': '\\b',

parseWhitespaceAndSkipComments();
const processed = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString();
const processed = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString(false) || parseRegex();
parseWhitespaceAndSkipComments();

@@ -196,3 +196,3 @@ return processed;

skipEllipsis();
const processedKey = parseString() || parseUnquotedString();
const processedKey = parseString() || parseUnquotedString(true);
if (!processedKey) {

@@ -311,3 +311,3 @@ if (text.charCodeAt(i) === codeClosingBrace || text.charCodeAt(i) === codeOpeningBrace || text.charCodeAt(i) === codeClosingBracket || text.charCodeAt(i) === codeOpeningBracket || text[i] === undefined) {

// repair: wrap the output inside array brackets
output = "[\n".concat(output, "\n]");
output = `[\n${output}\n]`;
}

@@ -393,4 +393,4 @@

// repair unescaped quote
str = "".concat(str.substring(0, oQuote), "\\").concat(str.substring(oQuote));
} else if (stopAtDelimiter && isDelimiter(text[i])) {
str = `${str.substring(0, oQuote)}\\${str.substring(oQuote)}`;
} else if (stopAtDelimiter && isUnquotedStringDelimiter(text[i])) {
// we're in the mode to stop the string at the first delimiter

@@ -437,3 +437,3 @@ // because there is an end quote missing

// repair unescaped double quote
str += "\\".concat(char);
str += `\\${char}`;
i++;

@@ -552,3 +552,3 @@ } else if (isControlCharacter(code)) {

const hasInvalidLeadingZero = /^0\d/.test(num);
output += hasInvalidLeadingZero ? "\"".concat(num, "\"") : num;
output += hasInvalidLeadingZero ? `"${num}"` : num;
return true;

@@ -582,14 +582,18 @@ }

*/
function parseUnquotedString() {
function parseUnquotedString(isKey) {
// note that the symbol can end with whitespaces: we stop at the next delimiter
// also, note that we allow strings to contain a slash / in order to support repairing regular expressions
const start = i;
while (i < text.length && !isDelimiterExceptSlash(text[i]) && !isQuote(text.charCodeAt(i))) {
i++;
}
if (i > start) {
if (text.charCodeAt(i) === codeOpenParenthesis && isFunctionName(text.slice(start, i).trim())) {
if (regexFunctionNameCharStart.test(text[i])) {
while (i < text.length && regexFunctionNameChar.test(text[i])) {
i++;
}
let j = i;
while (isWhitespace(text.charCodeAt(j))) {
j++;
}
if (text[j] === '(') {
// repair a MongoDB function call like NumberLong("2")
// repair a JSONP function call like callback({...});
i++;
i = j + 1;
parseValue();

@@ -605,21 +609,36 @@ if (text.charCodeAt(i) === codeCloseParenthesis) {

return true;
// biome-ignore lint/style/noUselessElse: <explanation>
} else {
// repair unquoted string
// also, repair undefined into null
}
}
while (i < text.length && !isUnquotedStringDelimiter(text[i]) && !isQuote(text.charCodeAt(i)) && (!isKey || text[i] !== ':')) {
i++;
}
if (i > start) {
// repair unquoted string
// also, repair undefined into null
// first, go back to prevent getting trailing whitespaces in the string
while (isWhitespace(text.charCodeAt(i - 1)) && i > 0) {
i--;
}
const symbol = text.slice(start, i);
output += symbol === 'undefined' ? 'null' : JSON.stringify(symbol);
if (text.charCodeAt(i) === codeDoubleQuote) {
// we had a missing start quote, but now we encountered the end quote, so we can skip that one
i++;
}
return true;
// first, go back to prevent getting trailing whitespaces in the string
while (isWhitespace(text.charCodeAt(i - 1)) && i > 0) {
i--;
}
const symbol = text.slice(start, i);
output += symbol === 'undefined' ? 'null' : JSON.stringify(symbol);
if (text.charCodeAt(i) === codeDoubleQuote) {
// we had a missing start quote, but now we encountered the end quote, so we can skip that one
i++;
}
return true;
}
}
function parseRegex() {
if (text[i] === '/') {
const start = i;
i++;
while (i < text.length && (text[i] !== '/' || text[i - 1] === '\\')) {
i++;
}
i++;
output += `"${text.substring(start, i)}"`;
return true;
}
}
function prevNonWhitespaceIndex(start) {

@@ -639,9 +658,9 @@ let prev = start;

// change the number more than it needs to make it valid JSON
output += "".concat(text.slice(start, i), "0");
output += `${text.slice(start, i)}0`;
}
function throwInvalidCharacter(char) {
throw new JSONRepairError("Invalid character ".concat(JSON.stringify(char)), i);
throw new JSONRepairError(`Invalid character ${JSON.stringify(char)}`, i);
}
function throwUnexpectedCharacter() {
throw new JSONRepairError("Unexpected character ".concat(JSON.stringify(text[i])), i);
throw new JSONRepairError(`Unexpected character ${JSON.stringify(text[i])}`, i);
}

@@ -659,3 +678,3 @@ function throwUnexpectedEnd() {

const chars = text.slice(i, i + 6);
throw new JSONRepairError("Invalid unicode character \"".concat(chars, "\""), i);
throw new JSONRepairError(`Invalid unicode character "${chars}"`, i);
}

@@ -662,0 +681,0 @@ }

@@ -8,7 +8,7 @@ export function createInputBuffer() {

if (index < offset) {
throw new Error("".concat(indexOutOfRangeMessage, " (index: ").concat(index, ", offset: ").concat(offset, ")"));
throw new Error(`${indexOutOfRangeMessage} (index: ${index}, offset: ${offset})`);
}
if (index >= currentLength) {
if (!closed) {
throw new Error("".concat(indexOutOfRangeMessage, " (index: ").concat(index, ")"));
throw new Error(`${indexOutOfRangeMessage} (index: ${index})`);
}

@@ -15,0 +15,0 @@ }

@@ -33,3 +33,3 @@ import { isWhitespace } from '../../utils/stringUtils.js';

if (offset > 0) {
throw new Error("Cannot unshift: ".concat(flushedMessage));
throw new Error(`Cannot unshift: ${flushedMessage}`);
}

@@ -41,3 +41,3 @@ buffer = text + buffer;

if (start < offset) {
throw new Error("Cannot remove: ".concat(flushedMessage));
throw new Error(`Cannot remove: ${flushedMessage}`);
}

@@ -52,3 +52,3 @@ if (end !== undefined) {

if (index < offset) {
throw new Error("Cannot insert: ".concat(flushedMessage));
throw new Error(`Cannot insert: ${flushedMessage}`);
}

@@ -83,3 +83,3 @@ buffer = buffer.substring(0, index - offset) + text + buffer.substring(index - offset);

if (bufferIndex <= 0) {
throw new Error("Cannot insert: ".concat(flushedMessage));
throw new Error(`Cannot insert: ${flushedMessage}`);
}

@@ -86,0 +86,0 @@ buffer = buffer.substring(0, bufferIndex) + textToInsert + buffer.substring(bufferIndex);

import { JSONRepairError } from '../utils/JSONRepairError.js';
import { codeAsterisk, codeBackslash, codeCloseParenthesis, codeClosingBrace, codeClosingBracket, codeColon, codeComma, codeDot, codeDoubleQuote, codeLowercaseE, codeMinus, codeNewline, codeOpenParenthesis, codeOpeningBrace, codeOpeningBracket, codePlus, codeSemicolon, codeSlash, codeUppercaseE, isControlCharacter, isDelimiter, isDelimiterExceptSlash, isDigit, isDoubleQuote, isDoubleQuoteLike, isFunctionName, isHex, isQuote, isSingleQuote, isSingleQuoteLike, isSpecialWhitespace, isStartOfValue, isValidStringCharacter, isWhitespace } from '../utils/stringUtils.js';
import { codeAsterisk, codeBackslash, codeCloseParenthesis, codeClosingBrace, codeClosingBracket, codeColon, codeComma, codeDot, codeDoubleQuote, codeLowercaseE, codeMinus, codeNewline, codeOpenParenthesis, codeOpeningBrace, codeOpeningBracket, codePlus, codeSemicolon, codeSlash, codeUppercaseE, isControlCharacter, isDelimiter, isDigit, isDoubleQuote, isDoubleQuoteLike, isHex, isQuote, isSingleQuote, isSingleQuoteLike, isSpecialWhitespace, isStartOfValue, isUnquotedStringDelimiter, isValidStringCharacter, isWhitespace, regexFunctionNameChar, regexFunctionNameCharStart } from '../utils/stringUtils.js';
import { createInputBuffer } from './buffer/InputBuffer.js';

@@ -126,3 +126,3 @@ import { createOutputBuffer } from './buffer/OutputBuffer.js';

function parseValue() {
return parseObjectStart() || parseArrayStart() || parseString() || parseNumber() || parseKeywords() || parseRepairUnquotedString();
return parseObjectStart() || parseArrayStart() || parseString() || parseNumber() || parseKeywords() || parseRepairUnquotedString() || parseRepairRegex();
}

@@ -158,13 +158,23 @@ function parseObjectStart() {

function parseRepairUnquotedString() {
const unquotedStringEnd = findNextDelimiter();
let j = i;
if (regexFunctionNameCharStart.test(input.charAt(j))) {
while (!input.isEnd(j) && regexFunctionNameChar.test(input.charAt(j))) {
j++;
}
let k = j;
while (isWhitespace(input.charCodeAt(k))) {
k++;
}
if (input.charCodeAt(k) === codeOpenParenthesis) {
// repair a MongoDB function call like NumberLong("2")
// repair a JSONP function call like callback({...});
k++;
i = k;
return stack.push(StackType.functionCall, Caret.beforeValue);
}
}
const unquotedStringEnd = findNextDelimiter(false, j);
if (unquotedStringEnd !== null) {
const symbol = input.substring(i, unquotedStringEnd);
i = unquotedStringEnd;
if (skipCharacter(codeOpenParenthesis) && isFunctionName(symbol.trim())) {
// A MongoDB function call like NumberLong("2")
// Or a JSONP function call like callback({...});
// we strip the function call
return stack.push(StackType.functionCall, Caret.beforeValue);
}
output.push(symbol === 'undefined' ? 'null' : JSON.stringify(symbol));

@@ -179,2 +189,14 @@ if (input.charCodeAt(i) === codeDoubleQuote) {

}
function parseRepairRegex() {
if (input.charAt(i) === '/') {
const start = i;
i++;
while (!input.isEnd(i) && (input.charAt(i) !== '/' || input.charAt(i - 1) === '\\')) {
i++;
}
i++;
output.push(`"${input.substring(start, i)}"`);
return stack.update(Caret.afterValue);
}
}
function parseRepairMissingObjectValue() {

@@ -487,3 +509,3 @@ // repair missing object value

output.insertAt(oQuote, '\\');
} else if (stopAtDelimiter && isDelimiter(input.charAt(i))) {
} else if (stopAtDelimiter && isUnquotedStringDelimiter(input.charAt(i))) {
// we're in the mode to stop the string at the first delimiter

@@ -529,3 +551,3 @@ // because there is an end quote missing

// repair unescaped double quote
output.push("\\".concat(char));
output.push(`\\${char}`);
i++;

@@ -644,3 +666,3 @@ } else if (isControlCharacter(code)) {

const hasInvalidLeadingZero = /^0\d/.test(num);
output.push(hasInvalidLeadingZero ? "\"".concat(num, "\"") : num);
output.push(hasInvalidLeadingZero ? `"${num}"` : num);
return stack.update(Caret.afterValue);

@@ -669,3 +691,3 @@ }

function parseUnquotedKey() {
let end = findNextDelimiter();
let end = findNextDelimiter(true, i);
if (end !== null) {

@@ -687,7 +709,7 @@ // first, go back to prevent getting trailing whitespaces in the string

}
function findNextDelimiter() {
function findNextDelimiter(isKey, start) {
// note that the symbol can end with whitespaces: we stop at the next delimiter
// also, note that we allow strings to contain a slash / in order to support repairing regular expressions
let j = i;
while (!input.isEnd(j) && !isDelimiterExceptSlash(input.charAt(j)) && !isQuote(input.charCodeAt(j))) {
let j = start;
while (!input.isEnd(j) && !isUnquotedStringDelimiter(input.charAt(j)) && !isQuote(input.charCodeAt(j)) && (!isKey || input.charAt(j) !== ':')) {
j++;

@@ -711,9 +733,9 @@ }

// change the number more than it needs to make it valid JSON
output.push("".concat(input.substring(start, i), "0"));
output.push(`${input.substring(start, i)}0`);
}
function throwInvalidCharacter(char) {
throw new JSONRepairError("Invalid character ".concat(JSON.stringify(char)), i);
throw new JSONRepairError(`Invalid character ${JSON.stringify(char)}`, i);
}
function throwUnexpectedCharacter() {
throw new JSONRepairError("Unexpected character ".concat(JSON.stringify(input.charAt(i))), i);
throw new JSONRepairError(`Unexpected character ${JSON.stringify(input.charAt(i))}`, i);
}

@@ -731,3 +753,3 @@ function throwUnexpectedEnd() {

const chars = input.substring(i, i + 6);
throw new JSONRepairError("Invalid unicode character \"".concat(chars, "\""), i);
throw new JSONRepairError(`Invalid unicode character "${chars}"`, i);
}

@@ -734,0 +756,0 @@ function atEndOfBlockComment(i) {

@@ -6,4 +6,4 @@ import { Transform } from 'node:stream';

onData: chunk => transform.push(chunk),
bufferSize: options === null || options === void 0 ? void 0 : options.bufferSize,
chunkSize: options === null || options === void 0 ? void 0 : options.chunkSize
bufferSize: options?.bufferSize,
chunkSize: options?.chunkSize
});

@@ -10,0 +10,0 @@ const transform = new Transform({

export class JSONRepairError extends Error {
constructor(message, position) {
super("".concat(message, " at position ").concat(position));
super(`${message} at position ${position}`);
this.position = position;

@@ -5,0 +5,0 @@ }

@@ -58,4 +58,7 @@ export const codeBackslash = 0x5c; // "\"

const regexDelimiter = /^[,:[\]/{}()\n+]$/;
export function isDelimiterExceptSlash(char) {
return isDelimiter(char) && char !== '/';
const regexUnquotedStringDelimiter = /^[,[\]/{}\n+]$/;
export const regexFunctionNameCharStart = /^[a-zA-Z_$]$/;
export const regexFunctionNameChar = /^[a-zA-Z_$0-9]$/;
export function isUnquotedStringDelimiter(char) {
return regexUnquotedStringDelimiter.test(char);
}

@@ -159,5 +162,2 @@ export function isStartOfValue(char) {

}
export function isFunctionName(text) {
return /^\w+$/.test(text);
}
//# sourceMappingURL=stringUtils.js.map

@@ -36,3 +36,5 @@ export declare const codeBackslash = 92;

export declare function isDelimiter(char: string): boolean;
export declare function isDelimiterExceptSlash(char: string): boolean;
export declare const regexFunctionNameCharStart: RegExp;
export declare const regexFunctionNameChar: RegExp;
export declare function isUnquotedStringDelimiter(char: string): boolean;
export declare function isStartOfValue(char: string): boolean;

@@ -85,3 +87,2 @@ export declare function isControlCharacter(code: number): code is 8 | 10 | 12 | 9 | 13;

export declare function endsWithCommaOrNewline(text: string): boolean;
export declare function isFunctionName(text: string): boolean;
//# sourceMappingURL=stringUtils.d.ts.map

@@ -9,3 +9,3 @@ (function (global, factory) {

constructor(message, position) {
super("".concat(message, " at position ").concat(position));
super(`${message} at position ${position}`);
this.position = position;

@@ -22,3 +22,2 @@ }

const codeClosingBracket = 0x5d; // "]"
const codeOpenParenthesis = 0x28; // "("
const codeCloseParenthesis = 0x29; // ")"

@@ -73,4 +72,7 @@ const codeSpace = 0x20; // " "

const regexDelimiter = /^[,:[\]/{}()\n+]$/;
function isDelimiterExceptSlash(char) {
return isDelimiter(char) && char !== '/';
const regexUnquotedStringDelimiter = /^[,[\]/{}\n+]$/;
const regexFunctionNameCharStart = /^[a-zA-Z_$]$/;
const regexFunctionNameChar = /^[a-zA-Z_$0-9]$/;
function isUnquotedStringDelimiter(char) {
return regexUnquotedStringDelimiter.test(char);
}

@@ -174,5 +176,2 @@ function isStartOfValue(char) {

}
function isFunctionName(text) {
return /^\w+$/.test(text);
}

@@ -253,3 +252,3 @@ const controlCharacters = {

parseWhitespaceAndSkipComments();
const processed = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString();
const processed = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString(false) || parseRegex();
parseWhitespaceAndSkipComments();

@@ -372,3 +371,3 @@ return processed;

skipEllipsis();
const processedKey = parseString() || parseUnquotedString();
const processedKey = parseString() || parseUnquotedString(true);
if (!processedKey) {

@@ -487,3 +486,3 @@ if (text.charCodeAt(i) === codeClosingBrace || text.charCodeAt(i) === codeOpeningBrace || text.charCodeAt(i) === codeClosingBracket || text.charCodeAt(i) === codeOpeningBracket || text[i] === undefined) {

// repair: wrap the output inside array brackets
output = "[\n".concat(output, "\n]");
output = `[\n${output}\n]`;
}

@@ -569,4 +568,4 @@

// repair unescaped quote
str = "".concat(str.substring(0, oQuote), "\\").concat(str.substring(oQuote));
} else if (stopAtDelimiter && isDelimiter(text[i])) {
str = `${str.substring(0, oQuote)}\\${str.substring(oQuote)}`;
} else if (stopAtDelimiter && isUnquotedStringDelimiter(text[i])) {
// we're in the mode to stop the string at the first delimiter

@@ -613,3 +612,3 @@ // because there is an end quote missing

// repair unescaped double quote
str += "\\".concat(char);
str += `\\${char}`;
i++;

@@ -728,3 +727,3 @@ } else if (isControlCharacter(code)) {

const hasInvalidLeadingZero = /^0\d/.test(num);
output += hasInvalidLeadingZero ? "\"".concat(num, "\"") : num;
output += hasInvalidLeadingZero ? `"${num}"` : num;
return true;

@@ -758,14 +757,18 @@ }

*/
function parseUnquotedString() {
function parseUnquotedString(isKey) {
// note that the symbol can end with whitespaces: we stop at the next delimiter
// also, note that we allow strings to contain a slash / in order to support repairing regular expressions
const start = i;
while (i < text.length && !isDelimiterExceptSlash(text[i]) && !isQuote(text.charCodeAt(i))) {
i++;
}
if (i > start) {
if (text.charCodeAt(i) === codeOpenParenthesis && isFunctionName(text.slice(start, i).trim())) {
if (regexFunctionNameCharStart.test(text[i])) {
while (i < text.length && regexFunctionNameChar.test(text[i])) {
i++;
}
let j = i;
while (isWhitespace(text.charCodeAt(j))) {
j++;
}
if (text[j] === '(') {
// repair a MongoDB function call like NumberLong("2")
// repair a JSONP function call like callback({...});
i++;
i = j + 1;
parseValue();

@@ -781,21 +784,36 @@ if (text.charCodeAt(i) === codeCloseParenthesis) {

return true;
// biome-ignore lint/style/noUselessElse: <explanation>
} else {
// repair unquoted string
// also, repair undefined into null
}
}
while (i < text.length && !isUnquotedStringDelimiter(text[i]) && !isQuote(text.charCodeAt(i)) && (!isKey || text[i] !== ':')) {
i++;
}
if (i > start) {
// repair unquoted string
// also, repair undefined into null
// first, go back to prevent getting trailing whitespaces in the string
while (isWhitespace(text.charCodeAt(i - 1)) && i > 0) {
i--;
}
const symbol = text.slice(start, i);
output += symbol === 'undefined' ? 'null' : JSON.stringify(symbol);
if (text.charCodeAt(i) === codeDoubleQuote) {
// we had a missing start quote, but now we encountered the end quote, so we can skip that one
i++;
}
return true;
// first, go back to prevent getting trailing whitespaces in the string
while (isWhitespace(text.charCodeAt(i - 1)) && i > 0) {
i--;
}
const symbol = text.slice(start, i);
output += symbol === 'undefined' ? 'null' : JSON.stringify(symbol);
if (text.charCodeAt(i) === codeDoubleQuote) {
// we had a missing start quote, but now we encountered the end quote, so we can skip that one
i++;
}
return true;
}
}
function parseRegex() {
if (text[i] === '/') {
const start = i;
i++;
while (i < text.length && (text[i] !== '/' || text[i - 1] === '\\')) {
i++;
}
i++;
output += `"${text.substring(start, i)}"`;
return true;
}
}
function prevNonWhitespaceIndex(start) {

@@ -815,9 +833,9 @@ let prev = start;

// change the number more than it needs to make it valid JSON
output += "".concat(text.slice(start, i), "0");
output += `${text.slice(start, i)}0`;
}
function throwInvalidCharacter(char) {
throw new JSONRepairError("Invalid character ".concat(JSON.stringify(char)), i);
throw new JSONRepairError(`Invalid character ${JSON.stringify(char)}`, i);
}
function throwUnexpectedCharacter() {
throw new JSONRepairError("Unexpected character ".concat(JSON.stringify(text[i])), i);
throw new JSONRepairError(`Unexpected character ${JSON.stringify(text[i])}`, i);
}

@@ -835,3 +853,3 @@ function throwUnexpectedEnd() {

const chars = text.slice(i, i + 6);
throw new JSONRepairError("Invalid unicode character \"".concat(chars, "\""), i);
throw new JSONRepairError(`Invalid unicode character "${chars}"`, i);
}

@@ -838,0 +856,0 @@ }

@@ -1,1 +0,3 @@

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).JSONRepair={})}(this,function(t){class x extends Error{constructor(t,e){super("".concat(t," at position ").concat(e)),this.position=e}}let h=125,e=32,y=10,O=9,N=13,J=8,S=12,j=34,r=39,$=48,k=57,d=44,m=65,I=97,T=70,E=102,l=160,R=8192,U=8202,F=8239,q=8287,z=12288,n=8220,o=8221,c=8216,i=8217,a=96,f=180;function B(t){return t>=$&&t<=k}function D(t){return u.test(t)}let u=/^[,:[\]/{}()\n+]$/;function G(t){return s.test(t)||t&&K(t.charCodeAt(0))}let s=/^[[{\w-]$/;function H(t){return t===e||t===y||t===O||t===N}function K(t){return L(t)||P(t)}function L(t){return t===j||t===n||t===o}function M(t){return t===j}function P(t){return t===r||t===c||t===i||t===a||t===f}function Q(t){return t===r}function V(t,e,r){r=2<arguments.length&&void 0!==r&&r,e=t.lastIndexOf(e);return-1!==e?t.substring(0,e)+(r?"":t.substring(e+1)):t}function W(t,e){let r=t.length;if(!H(t.charCodeAt(r-1)))return t+e;for(;H(t.charCodeAt(r-1));)r--;return t.substring(0,r)+e+t.substring(r)}let X={"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t"},Y={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"};t.JSONRepairError=x,t.jsonrepair=function(s){let A=0,C="";if(!c())throw new x("Unexpected end of json string",s.length);var t=i(d);if(t&&g(),G(s[A])&&/[,\n][ \t\r]*$/.test(C)){t||(C=W(C,","));{let t=!0,e=!0;for(;e;)t?t=!1:i(d)||(C=W(C,",")),e=c();e||(C=V(C,","));C="[\n".concat(C,"\n]")}}else t&&(C=V(C,","));for(;s.charCodeAt(A)===h||93===s.charCodeAt(A);)A++,g();if(A>=s.length)return C;throw new x("Unexpected character ".concat(JSON.stringify(s[A])),A);function c(){g();var t=function(){if(123!==s.charCodeAt(A))return!1;{C+="{",A++,g(),v(d)&&g();let e=!0;for(;A<s.length&&s.charCodeAt(A)!==h;){let t;if(e?(t=!0,e=!1):((t=i(d))||(C=W(C,",")),g()),a(),!(b()||f())){s.charCodeAt(A)===h||123===s.charCodeAt(A)||93===s.charCodeAt(A)||91===s.charCodeAt(A)||void 0===s[A]?C=V(C,","):function(){throw new x("Object key expected",A)}();break}g();var r=i(58),n=A>=s.length,o=(r||(G(s[A])||n?C=W(C,":"):u()),c());o||(r||n?C+="null":u())}return s.charCodeAt(A)===h?(C+="}",A++):C=W(C,"}"),!0}}()||function(){if(91!==s.charCodeAt(A))return!1;{C+="[",A++,g(),v(d)&&g();let t=!0;for(;A<s.length&&93!==s.charCodeAt(A);){t?t=!1:i(d)||(C=W(C,",")),a();var e=c();if(!e){C=V(C,",");break}}return 93===s.charCodeAt(A)?(C+="]",A++):C=W(C,"]"),!0}}()||b()||function(){var t=A;if(45===s.charCodeAt(A)){if(A++,n())return o(t),!0;if(!B(s.charCodeAt(A)))return A=t,!1}for(;B(s.charCodeAt(A));)A++;if(46===s.charCodeAt(A)){if(A++,n())return o(t),!0;if(!B(s.charCodeAt(A)))return A=t,!1;for(;B(s.charCodeAt(A));)A++}if(101===s.charCodeAt(A)||69===s.charCodeAt(A)){if(A++,45!==s.charCodeAt(A)&&43!==s.charCodeAt(A)||A++,n())return o(t),!0;if(!B(s.charCodeAt(A)))return A=t,!1;for(;B(s.charCodeAt(A));)A++}var e,r;if(n()){if(A>t)return e=s.slice(t,A),r=/^0\d/.test(e),C+=r?'"'.concat(e,'"'):e,!0}else A=t;return!1}()||r("true","true")||r("false","false")||r("null","null")||r("True","true")||r("False","false")||r("None","null")||f();return g(),t}function g(){A;let t=e();for(;t=(t=function(){if(47===s.charCodeAt(A)&&42===s.charCodeAt(A+1)){for(;A<s.length&&!function(t,e){return"*"===t[e]&&"/"===t[e+1]}(s,A);)A++;A+=2}else{if(47!==s.charCodeAt(A)||47!==s.charCodeAt(A+1))return!1;for(;A<s.length&&s.charCodeAt(A)!==y;)A++}return!0}())&&e(););A}function e(){let t="";for(var e,r;(e=H(s.charCodeAt(A)))||(r=s.charCodeAt(A))===l||r>=R&&r<=U||r===F||r===q||r===z;)t+=e?s[A]:" ",A++;return 0<t.length&&(C+=t,!0)}function i(t){return s.charCodeAt(A)===t&&(C+=s[A],A++,!0)}function v(t){return s.charCodeAt(A)===t&&(A++,!0)}function a(){g(),46===s.charCodeAt(A)&&46===s.charCodeAt(A+1)&&46===s.charCodeAt(A+2)&&(A+=3,g(),v(d))}function b(t){var r,n,o=0<arguments.length&&void 0!==t&&t;let c=92===s.charCodeAt(A);if(c&&(A++,c=!0),K(s.charCodeAt(A))){var i=M(s.charCodeAt(A))?M:Q(s.charCodeAt(A))?Q:P(s.charCodeAt(A))?P:L,a=A,f=C.length;let e='"';for(A++;;){if(A>=s.length)return u=w(A-1),!o&&D(s.charAt(u))?(A=a,C=C.substring(0,f),b(!0)):(e=W(e,'"'),C+=e,!0);if(i(s.charCodeAt(A))){var u=A,h=e.length;if(e+='"',A++,C+=e,g(),o||A>=s.length||D(s.charAt(A))||K(s.charCodeAt(A))||B(s.charCodeAt(A)))return p(),!0;if(D(s.charAt(w(u-1))))return A=a,C=C.substring(0,f),b(!0);C=C.substring(0,f),A=u+1,e="".concat(e.substring(0,h),"\\").concat(e.substring(h))}else{if(o&&D(s[A]))return e=W(e,'"'),C+=e,p(),!0;if(92===s.charCodeAt(A)){h=s.charAt(A+1);if(void 0!==Y[h])e+=s.slice(A,A+2),A+=2;else if("u"===h){let t=2;for(;t<6&&((n=s.charCodeAt(A+t))>=$&&n<=k||n>=m&&n<=T||n>=I&&n<=E);)t++;if(6===t)e+=s.slice(A,A+6),A+=6;else{if(!(A+t>=s.length))throw d=void 0,d=s.slice(A,A+6),new x('Invalid unicode character "'.concat(d,'"'),A);A=s.length}}else e+=h,A+=2}else{var d=s.charAt(A),l=s.charCodeAt(A);if(l===j&&92!==s.charCodeAt(A-1))e+="\\".concat(d);else if((r=l)===y||r===N||r===O||r===J||r===S)e+=X[d];else{if(!(32<=(r=l)&&r<=1114111))throw l=void 0,l=d,new x("Invalid character ".concat(JSON.stringify(l)),A);e+=d}A++}}c&&v(92)}}return!1}function p(){let t=!1;for(g();43===s.charCodeAt(A);){t=!0,A++,g();var e=(C=V(C,'"',!0)).length,r=b();C=r?(r=C,e=e,n=1,r.substring(0,e)+r.substring(e+n)):W(C,'"')}var n;t}function r(t,e){return s.slice(A,A+t.length)===t&&(C+=e,A+=t.length,!0)}function f(){for(var t,e=A;A<s.length&&(!D(t=s[A])||"/"===t)&&!K(s.charCodeAt(A));)A++;if(A>e){if(40===s.charCodeAt(A)&&/^\w+$/.test(s.slice(e,A).trim()))A++,c(),41===s.charCodeAt(A)&&(A++,59===s.charCodeAt(A))&&A++;else{for(;H(s.charCodeAt(A-1))&&0<A;)A--;e=s.slice(e,A);C+="undefined"===e?"null":JSON.stringify(e),s.charCodeAt(A)===j&&A++}return!0}}function w(t){let e=t;for(;0<e&&H(s.charCodeAt(e));)e--;return e}function n(){return A>=s.length||D(s[A])||H(s.charCodeAt(A))}function o(t){C+="".concat(s.slice(t,A),"0")}function u(){throw new x("Colon expected",A)}}});
((t,e)=>{"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).JSONRepair={})})(this,function(t){class $ extends Error{constructor(t,e){super(t+" at position "+e),this.position=e}}let u=125,e=32,x=10,y=9,O=13,N=8,J=12,S=34,r=39,j=48,k=57,d=44,I=65,T=97,m=70,z=102,l=160,E=8192,R=8202,U=8239,Z=8287,_=12288,n=8220,o=8221,i=8216,c=8217,f=96,a=180;function F(t){return t>=j&&t<=k}function q(t){return h.test(t)}let h=/^[,:[\]/{}()\n+]$/,s=/^[,[\]/{}\n+]$/,W=/^[a-zA-Z_$]$/,X=/^[a-zA-Z_$0-9]$/;function B(t){return s.test(t)}function D(t){return A.test(t)||t&&H(t.charCodeAt(0))}let A=/^[[{\w-]$/;function G(t){return t===e||t===x||t===y||t===O}function H(t){return K(t)||M(t)}function K(t){return t===S||t===n||t===o}function L(t){return t===S}function M(t){return t===r||t===i||t===c||t===f||t===a}function P(t){return t===r}function Q(t,e,r){r=2<arguments.length&&void 0!==r&&r,e=t.lastIndexOf(e);return-1!==e?t.substring(0,e)+(r?"":t.substring(e+1)):t}function V(t,e){let r=t.length;if(!G(t.charCodeAt(r-1)))return t+e;for(;G(t.charCodeAt(r-1));)r--;return t.substring(0,r)+e+t.substring(r)}let Y={"\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t"},tt={'"':'"',"\\":"\\","/":"/",b:"\b",f:"\f",n:"\n",r:"\r",t:"\t"};t.JSONRepairError=$,t.jsonrepair=function(s){let A=0,C="";if(!i())throw new $("Unexpected end of json string",s.length);var t=c(d);if(t&&g(),D(s[A])&&/[,\n][ \t\r]*$/.test(C)){t||(C=V(C,","));{let t=!0,e=!0;for(;e;)t?t=!1:c(d)||(C=V(C,",")),e=i();C=`[
${C=e?C:Q(C,",")}
]`}}else t&&(C=Q(C,","));for(;s.charCodeAt(A)===u||93===s.charCodeAt(A);)A++,g();if(A>=s.length)return C;throw new $("Unexpected character "+JSON.stringify(s[A]),A);function i(){g();var t=(()=>{if(123!==s.charCodeAt(A))return!1;{C+="{",A++,g(),b(d)&&g();let e=!0;for(;A<s.length&&s.charCodeAt(A)!==u;){let t;if(e?(t=!0,e=!1):((t=c(d))||(C=V(C,",")),g()),f(),!(v()||a(!0))){s.charCodeAt(A)===u||123===s.charCodeAt(A)||93===s.charCodeAt(A)||91===s.charCodeAt(A)||void 0===s[A]?C=Q(C,","):(()=>{throw new $("Object key expected",A)})();break}g();var r=c(58),n=A>=s.length,o=(r||(D(s[A])||n?C=V(C,":"):h()),i());o||(r||n?C+="null":h())}return s.charCodeAt(A)===u?(C+="}",A++):C=V(C,"}"),!0}})()||(()=>{if(91!==s.charCodeAt(A))return!1;{C+="[",A++,g(),b(d)&&g();let t=!0;for(;A<s.length&&93!==s.charCodeAt(A);){t?t=!1:c(d)||(C=V(C,",")),f();var e=i();if(!e){C=Q(C,",");break}}return 93===s.charCodeAt(A)?(C+="]",A++):C=V(C,"]"),!0}})()||v()||(()=>{var t,e,r=A;if(45===s.charCodeAt(A)){if(A++,n())return o(r),!0;if(!F(s.charCodeAt(A)))return A=r,!1}for(;F(s.charCodeAt(A));)A++;if(46===s.charCodeAt(A)){if(A++,n())return o(r),!0;if(!F(s.charCodeAt(A)))return A=r,!1;for(;F(s.charCodeAt(A));)A++}if(101===s.charCodeAt(A)||69===s.charCodeAt(A)){if(A++,45!==s.charCodeAt(A)&&43!==s.charCodeAt(A)||A++,n())return o(r),!0;if(!F(s.charCodeAt(A)))return A=r,!1;for(;F(s.charCodeAt(A));)A++}if(n()){if(A>r)return t=s.slice(r,A),e=/^0\d/.test(t),C+=e?`"${t}"`:t,!0}else A=r;return!1})()||r("true","true")||r("false","false")||r("null","null")||r("True","true")||r("False","false")||r("None","null")||a(!1)||(()=>{if("/"===s[A]){var t=A;for(A++;A<s.length&&("/"!==s[A]||"\\"===s[A-1]);)A++;return A++,C+=`"${s.substring(t,A)}"`,!0}})();return g(),t}function g(){A;let t=e();for(;t=(t=(()=>{if(47===s.charCodeAt(A)&&42===s.charCodeAt(A+1)){for(;A<s.length&&!((t,e)=>"*"===t[e]&&"/"===t[e+1])(s,A);)A++;A+=2}else{if(47!==s.charCodeAt(A)||47!==s.charCodeAt(A+1))return!1;for(;A<s.length&&s.charCodeAt(A)!==x;)A++}return!0})())&&e(););A}function e(){let t="";for(var e,r;(e=G(s.charCodeAt(A)))||(r=s.charCodeAt(A))===l||r>=E&&r<=R||r===U||r===Z||r===_;)t+=e?s[A]:" ",A++;return 0<t.length&&(C+=t,!0)}function c(t){return s.charCodeAt(A)===t&&(C+=s[A],A++,!0)}function b(t){return s.charCodeAt(A)===t&&(A++,!0)}function f(){g(),46===s.charCodeAt(A)&&46===s.charCodeAt(A+1)&&46===s.charCodeAt(A+2)&&(A+=3,g(),b(d))}function v(t){var r,n,o=0<arguments.length&&void 0!==t&&t;let i=92===s.charCodeAt(A);if(i&&(A++,i=!0),H(s.charCodeAt(A))){var c=L(s.charCodeAt(A))?L:P(s.charCodeAt(A))?P:M(s.charCodeAt(A))?M:K,f=A,a=C.length;let e='"';for(A++;;){if(A>=s.length)return h=w(A-1),!o&&q(s.charAt(h))?(A=f,C=C.substring(0,a),v(!0)):(e=V(e,'"'),C+=e,!0);if(c(s.charCodeAt(A))){var h=A,u=e.length;if(e+='"',A++,C+=e,g(),o||A>=s.length||q(s.charAt(A))||H(s.charCodeAt(A))||F(s.charCodeAt(A)))return p(),!0;if(q(s.charAt(w(h-1))))return A=f,C=C.substring(0,a),v(!0);C=C.substring(0,a),A=h+1,e=e.substring(0,u)+"\\"+e.substring(u)}else{if(o&&B(s[A]))return e=V(e,'"'),C+=e,p(),!0;if(92===s.charCodeAt(A)){u=s.charAt(A+1);if(void 0!==tt[u])e+=s.slice(A,A+2),A+=2;else if("u"===u){let t=2;for(;t<6&&((n=s.charCodeAt(A+t))>=j&&n<=k||n>=I&&n<=m||n>=T&&n<=z);)t++;if(6===t)e+=s.slice(A,A+6),A+=6;else{if(!(A+t>=s.length))throw d=void 0,d=s.slice(A,A+6),new $(`Invalid unicode character "${d}"`,A);A=s.length}}else e+=u,A+=2}else{var d=s.charAt(A),l=s.charCodeAt(A);if(l===S&&92!==s.charCodeAt(A-1))e+="\\"+d;else if((r=l)===x||r===O||r===y||r===N||r===J)e+=Y[d];else{if(!(32<=(r=l)&&r<=1114111))throw l=void 0,l=d,new $("Invalid character "+JSON.stringify(l),A);e+=d}A++}}i&&b(92)}}return!1}function p(){let t=!1;for(g();43===s.charCodeAt(A);){t=!0,A++,g();var e=(C=Q(C,'"',!0)).length,r=v();C=r?(r=C,e=e,n=1,r.substring(0,e)+r.substring(e+n)):V(C,'"')}var n;t}function r(t,e){return s.slice(A,A+t.length)===t&&(C+=e,A+=t.length,!0)}function a(t){var e=A;if(W.test(s[A])){for(;A<s.length&&X.test(s[A]);)A++;let t=A;for(;G(s.charCodeAt(t));)t++;if("("===s[t])return A=t+1,i(),41===s.charCodeAt(A)&&(A++,59===s.charCodeAt(A))&&A++,!0}for(;A<s.length&&!B(s[A])&&!H(s.charCodeAt(A))&&(!t||":"!==s[A]);)A++;if(A>e){for(;G(s.charCodeAt(A-1))&&0<A;)A--;e=s.slice(e,A);return C+="undefined"===e?"null":JSON.stringify(e),s.charCodeAt(A)===S&&A++,!0}}function w(t){let e=t;for(;0<e&&G(s.charCodeAt(e));)e--;return e}function n(){return A>=s.length||q(s[A])||G(s.charCodeAt(A))}function o(t){C+=s.slice(t,A)+"0"}function h(){throw new $("Colon expected",A)}}});
{
"name": "jsonrepair",
"version": "3.8.1",
"version": "3.9.0",
"description": "Repair broken JSON documents",

@@ -70,23 +70,23 @@ "repository": {

"devDependencies": {
"@babel/cli": "7.24.7",
"@babel/core": "7.24.7",
"@babel/plugin-transform-typescript": "7.24.7",
"@babel/preset-env": "7.24.7",
"@babel/preset-typescript": "7.24.7",
"@biomejs/biome": "1.9.1",
"@commitlint/cli": "19.3.0",
"@commitlint/config-conventional": "19.2.2",
"@types/node": "20.14.9",
"@babel/cli": "7.25.7",
"@babel/core": "7.25.8",
"@babel/plugin-transform-typescript": "7.25.7",
"@babel/preset-env": "7.25.8",
"@babel/preset-typescript": "7.25.7",
"@biomejs/biome": "1.9.4",
"@commitlint/cli": "19.5.0",
"@commitlint/config-conventional": "19.5.0",
"@types/node": "22.7.7",
"benchmark": "2.1.4",
"cpy-cli": "5.0.0",
"del-cli": "5.1.0",
"husky": "9.0.11",
"del-cli": "6.0.0",
"husky": "9.1.6",
"npm-run-all": "4.1.5",
"rollup": "4.18.0",
"rollup": "4.24.0",
"standard-version": "9.5.0",
"ts-node": "10.9.2",
"typescript": "5.5.3",
"uglify-js": "3.18.0",
"vitest": "1.6.0"
"typescript": "5.6.3",
"uglify-js": "3.19.3",
"vitest": "2.1.3"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc