55 lines
1.2 KiB
TypeScript
55 lines
1.2 KiB
TypeScript
|
export function parseJsObject(str: string, offset = 0) {
|
||
|
let i = offset
|
||
|
const len = str.length
|
||
|
let start = -1
|
||
|
let end = -1
|
||
|
|
||
|
const depth = {
|
||
|
'{': 0,
|
||
|
'[': 0,
|
||
|
}
|
||
|
|
||
|
const possibleQuotes = {
|
||
|
'"': true,
|
||
|
'\'': true,
|
||
|
'`': true,
|
||
|
}
|
||
|
let inQuote: string | null = null
|
||
|
let escapeNextQuote = false
|
||
|
|
||
|
while (i < len) {
|
||
|
const char = str[i]
|
||
|
if (char in possibleQuotes && !escapeNextQuote) {
|
||
|
if (inQuote === null) {
|
||
|
inQuote = char
|
||
|
} else if (char === inQuote) {
|
||
|
inQuote = null
|
||
|
}
|
||
|
} else if (inQuote != null) {
|
||
|
escapeNextQuote = char === '\\' && !escapeNextQuote
|
||
|
} else if (inQuote == null && char in depth) {
|
||
|
if (start === -1) {
|
||
|
start = i
|
||
|
}
|
||
|
depth[char] += 1
|
||
|
} else if (inQuote == null && (
|
||
|
char === '}' || char === ']'
|
||
|
)) {
|
||
|
if (char === '}') depth['{'] -= 1
|
||
|
if (char === ']') depth['['] -= 1
|
||
|
|
||
|
if (depth['{'] === 0 && depth['['] === 0) {
|
||
|
end = i + 1
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
i += 1
|
||
|
}
|
||
|
|
||
|
if (start === -1 && end === -1) return null
|
||
|
if (depth['{'] !== 0 || depth['['] !== 0) throw new SyntaxError('Mismatched brackets')
|
||
|
if (inQuote) throw new SyntaxError('Unclosed string')
|
||
|
|
||
|
return str.substring(start, end)
|
||
|
}
|