UNPKG

incomplete-json-parser

Version:

A JSON parser that can parse incomplete JSON strings.

160 lines (159 loc) 5.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ObjectScope = void 0; const array_scope_1 = require("./array.scope"); const literal_scope_1 = require("./literal.scope"); const scope_interface_1 = require("./scope.interface"); const utils_1 = require("./utils"); class ObjectScope extends scope_interface_1.Scope { object = {}; state = "key"; keyScope; valueScope; write(letter) { if (this.finish) { throw new Error("Object already finished"); return false; } if (Object.keys(this.object).length === 0 && this.state === "key" && this.keyScope === undefined && this.valueScope === undefined) { if (letter === "{") return true; } if (this.state === "key") { if (this.keyScope === undefined) { if ((0, utils_1.isWhitespace)(letter)) { return true; } else if (letter === '"') { this.keyScope = new literal_scope_1.LiteralScope(); return this.keyScope.write(letter); } else { throw new Error(`Expected ", got ${letter}`); return false; } } else { const success = this.keyScope.write(letter); const key = this.keyScope.getOrAssume(); if (typeof key === "string") { if (this.keyScope.finish) { this.state = "colons"; } return true; } else { throw new Error(`Key is not a string: ${key}`); return false; } } } else if (this.state === "colons") { if ((0, utils_1.isWhitespace)(letter)) { return true; } else if (letter === ":") { this.state = "value"; this.valueScope = undefined; return true; } else { throw new Error(`Expected colons, got ${letter}`); return false; } } else if (this.state === "value") { if (this.valueScope === undefined) { if ((0, utils_1.isWhitespace)(letter)) { return true; } else if (letter === "{") { this.valueScope = new ObjectScope(); return this.valueScope.write(letter); } else if (letter === "[") { this.valueScope = new array_scope_1.ArrayScope(); return this.valueScope.write(letter); } else { this.valueScope = new literal_scope_1.LiteralScope(); return this.valueScope.write(letter); } } else { const success = this.valueScope.write(letter); if (this.valueScope.finish) { const key = this.keyScope.getOrAssume(); this.object[key] = this.valueScope.getOrAssume(); this.state = "comma"; return true; } else if (success) { return true; } else { if ((0, utils_1.isWhitespace)(letter)) { return true; } else if (letter === ",") { const key = this.keyScope.getOrAssume(); this.object[key] = this.valueScope.getOrAssume(); this.state = "key"; this.keyScope = undefined; this.valueScope = undefined; return true; } else if (letter === "}") { const key = this.keyScope.getOrAssume(); this.object[key] = this.valueScope.getOrAssume(); this.finish = true; return true; } else { throw new Error(`Expected comma, got ${letter}`); } } } } else if (this.state === "comma") { if ((0, utils_1.isWhitespace)(letter)) { return true; } else if (letter === ",") { this.state = "key"; this.keyScope = undefined; this.valueScope = undefined; return true; } else if (letter === "}") { this.finish = true; return true; } else { throw new Error(`Expected comma or }, got "${letter}"`); } } else { throw new Error("Unexpected state"); return false; } } getOrAssume() { const assume = { ...this.object }; if (this.keyScope || this.valueScope) { const key = this.keyScope?.getOrAssume(); const value = this.valueScope?.getOrAssume(); if (typeof key === "string" && key.length > 0) { if (typeof value !== "undefined") assume[key] = value; else assume[key] = null; } } return assume; } } exports.ObjectScope = ObjectScope;