Skip to content

Instantly share code, notes, and snippets.

@Grax32
Last active October 9, 2023 11:34
Show Gist options
  • Select an option

  • Save Grax32/6c1833ad774805462ba2f1d034ed99c3 to your computer and use it in GitHub Desktop.

Select an option

Save Grax32/6c1833ad774805462ba2f1d034ed99c3 to your computer and use it in GitHub Desktop.
Auto-Close JSON
/*
Provided that the beginning of the JSON document is present in the fragment, this function will automatically close JSON fragments.
*/
function jsonCloser(src) {
const openChars = [];
let inQuotedString = false;
for (let i = 0; i < src.length; i++) {
const thisChar = src[i];
if (inQuotedString) {
switch (thisChar) {
case '\\':
i++;
break;
case '"':
inQuotedString = false;
break;
}
}
else {
switch (thisChar) {
case '{':
case '[':
openChars.push(thisChar);
break;
case '}':
if (openChars.pop() !== '{') {
throw new Error('Invalid JSON');
}
break;
case ']':
if (openChars.pop() !== '[') {
throw new Error('Invalid JSON');
}
break;
case '"':
inQuotedString = true;
break;
}
}
}
if (inQuotedString) {
src += '-autoclose"';
}
if (openChars[openChars.length - 1] === '{') {
const startBlock = src.lastIndexOf('{');
// get segment of string from start of block to end of string, replace escaped quotes with empty string
const segment = src.substring(startBlock).replace('\\"', '').split('"');
// if segment has 3 elements, it means there is a key with no value
if (segment.length === 3) {
if (segment[2].trim() === ':') {
src += '"auto-property"';
}
else {
src += ': "auto-property"';
}
}
}
function popChar() {
let openChar = openChars.pop();
if (openChar) {
const closeChar = openChar === '{' ? '}' : ']';
src += closeChar;
return true;
}
else {
return false;
}
}
while (popChar()) { }
return src;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment