cbon
Version:
Common Bracket Object Notation
1,213 lines (1,196 loc) • 41.8 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.cbon = {}));
}(this, (function (exports) { 'use strict';
class Token {
}
class TEOF extends Token {
constructor(range) {
super();
this.range = range;
}
}
class TComment extends Token {
}
class TLineComment extends TComment {
constructor(range, items) {
super();
this.items = items;
this.range = range;
}
}
class TBlockComment extends TComment {
constructor(range, items) {
super();
this.items = items;
this.range = range;
}
}
class TWord extends Token {
constructor(range, val) {
super();
this.val = val;
this.range = range;
}
}
class TStr extends Token {
constructor(range, val, col) {
super();
this.val = val;
this.col = col;
this.range = range;
}
}
class TSymbol extends Token {
constructor(range, val) {
super();
this.val = val;
this.range = range;
}
}
class TSComma extends TSymbol {
}
class TSSplit extends TSymbol {
}
class TSArrStart extends TSymbol {
}
class TSArrEnd extends TSymbol {
}
class TSObjStart extends TSymbol {
}
class TSObjEnd extends TSymbol {
}
function makeTSymbol(range, val) {
switch (val) {
case ',': return new TSComma(range, val);
case ':':
case '=': return new TSSplit(range, val);
case '[': return new TSArrStart(range, val);
case ']': return new TSArrEnd(range, val);
case '{': return new TSObjStart(range, val);
case '}': return new TSObjEnd(range, val);
}
}
function MakeCommentItem(items) {
return items.map(i => i instanceof TLineComment ? new LineComment(i.range, i.items) : i instanceof TBlockComment ? new BlockComment(i.range, i.items) : i);
}
class Unit {
}
class Comment extends Unit {
}
class LineComment extends Comment {
constructor(range, items) {
super();
this.items = MakeCommentItem(items);
this.range = range;
}
}
class BlockComment extends Comment {
constructor(range, items) {
super();
this.items = MakeCommentItem(items);
this.range = range;
}
}
class Comma extends Unit {
constructor(range) {
super();
this.range = range;
}
}
class Null extends Unit {
constructor(range) {
super();
this.range = range;
}
}
class Str extends Unit {
constructor(range, val, col) {
super();
this.val = val;
this.col = col;
this.range = range;
}
}
class Num extends Unit {
constructor(range, val) {
super();
this.val = val;
this.range = range;
}
}
class Bool extends Unit {
constructor(range, val) {
super();
this.val = val;
this.range = range;
}
}
class Key {
constructor(range, key) {
this.key = key;
this.range = range;
}
}
class Split {
constructor(range, type) {
this.type = type;
this.range = range;
}
}
class KeyVal {
constructor(key, val, split) {
this.key = key;
this.val = val;
this.split = split;
}
}
class Block extends Unit {
constructor(begin, end, items) {
super();
this.items = items;
this.begin = begin;
this.end = end;
}
}
class Arr extends Unit {
constructor(begin, end, items) {
super();
this.items = items;
this.begin = begin;
this.end = end;
}
}
class Docs extends Unit {
constructor(items) {
super();
this.items = items;
}
}
function isVoid(v) {
return v == null;
}
function getErrorsMsgs(errors) {
return errors.flatMap(e => [`${e.msg}`, ` at ${e.range.from.line + 1}:${e.range.from.char + 1} to ${e.range.to.line + 1}:${e.range.to.char + 1}`]);
}
/** == queueMicrotask */
function next_micro_tick() {
return new Promise(res => res());
}
function getIterator(iter) {
return iter[Symbol.asyncIterator] != null ? iter[Symbol.asyncIterator]() : iter[Symbol.iterator]();
}
class TkPos {
constructor(count, char, line) {
this.count = count;
this.char = char;
this.line = line;
}
}
class TkRange {
constructor(from, to) {
this.from = from;
this.to = to;
}
}
const ReDo = Symbol('ReDo');
class WhenError extends Error {
constructor(err) {
super();
this.err = err;
}
}
class State {
constructor(show_all_err) {
this.count = 0;
this.char = 0;
this.line = 0;
this.states = [];
this.lines = [];
this.errors = [];
this.queue = [];
this.show_all_err = show_all_err;
}
push(unit) {
this.states.push(unit);
}
pop() {
return this.states.pop();
}
call(c) {
const r = this.states[this.states.length - 1](c);
if (!isVoid(r)) {
if (r === ReDo) {
this.queue.push(() => this.call(c));
}
else {
const { fn, ignoreFirst } = r;
this.push(fn);
if (!ignoreFirst)
this.queue.push(() => this.call(c));
}
}
}
get pos() {
return new TkPos(this.count, this.char, this.line);
}
get lastPos() {
const np = new TkPos(this.count, this.char, this.line);
np.count--;
if (np.char === 0) {
np.line--;
np.char = this.lines[np.line];
}
else
np.char--;
return np;
}
}
class Context {
constructor(state) {
this.state = state;
}
end() {
this.state.pop();
}
call(f, ...p) {
return {
fn: f(new Context(this.state), ...p),
ignoreFirst: false
};
}
callNoFirst(f, ...p) {
return {
fn: f(new Context(this.state), ...p),
ignoreFirst: true
};
}
flag() {
this.last_flag = this.state.pos;
}
range(last = false) {
var _a;
const n = last ? this.state.lastPos : this.state.pos;
return new TkRange((_a = this.last_flag, (_a !== null && _a !== void 0 ? _a : n)), n);
}
error(range, msg) {
if (!this.state.show_all_err)
throw new WhenError({ range, msg });
this.state.errors.push({ range, msg });
}
}
const _continue = Symbol('continue');
const _break = Symbol('break');
function AlwaysFalse() { return false; }
function parser(code, config = { show_all_err: false, async: false, cancel: AlwaysFalse }) {
var _a, _b, _c, _d, _e, _f;
const cancel = (_b = (_a = config) === null || _a === void 0 ? void 0 : _a.cancel, (_b !== null && _b !== void 0 ? _b : AlwaysFalse));
const state = new State((_d = (_c = config) === null || _c === void 0 ? void 0 : _c.show_all_err, (_d !== null && _d !== void 0 ? _d : false)));
let rootAst;
state.push(root(new Context(state), (d) => {
rootAst = d;
}));
let finish = false;
const iter = getIterator(code);
function* main() {
if (state.queue.length != 0) {
state.queue.pop()();
return _continue;
}
if (finish)
return _break;
const c = yield iter.next();
if (c.done === true) {
finish = true;
return _continue;
}
state.call(c.value);
}
const loop = (_f = (_e = config) === null || _e === void 0 ? void 0 : _e.async, (_f !== null && _f !== void 0 ? _f : false)) ? async function () {
while (true) {
if (await cancel())
break;
await next_micro_tick();
const g = main();
let y = g.next();
if (!y.done) {
y = g.next(await y.value);
}
const s = y.value;
if (s === _continue)
continue;
if (s === _break)
break;
}
return state.errors.length !== 0 ? { err: state.errors, val: rootAst } : { err: state.errors, val: rootAst };
} : function () {
while (true) {
if (cancel())
break;
const g = main();
let y = g.next();
if (!y.done) {
y = g.next(y.value);
}
const s = y.value;
if (s === _continue)
continue;
if (s === _break)
break;
}
return state.errors.length !== 0 ? { err: state.errors, val: rootAst } : { err: state.errors, val: rootAst };
};
return loop();
}
function root(ctx, finish) {
const items = [];
return (t) => {
if (t instanceof TEOF) {
finish(new Docs(items));
}
else if (t instanceof TSObjStart) {
return ctx.callNoFirst(block, t, b => items.push(b));
}
else if (t instanceof TSArrStart) {
return ctx.callNoFirst(arr, t, a => items.push(a));
}
else if (t instanceof TLineComment) {
items.push(new LineComment(t.range, t.items));
}
else if (t instanceof TBlockComment) {
items.push(new BlockComment(t.range, t.items));
}
else {
ctx.error(t.range, 'File root must have no content other than a document');
}
};
}
function block(ctx, begin, finish) {
const items = [];
return (t) => {
if (t instanceof TEOF) {
ctx.error(t.range, 'Block is not closed');
ctx.end();
finish(new Block(begin.range, t.range, items));
return ReDo;
}
else if (t instanceof TSComma) {
items.push(new Comma(t.range));
}
else if (t instanceof TSObjEnd) {
ctx.end();
finish(new Block(begin.range, t.range, items));
}
else if (t instanceof TSObjStart) {
ctx.error(t.range, 'Block content must start with a key');
return ctx.callNoFirst(block, t, _ => { });
}
else if (t instanceof TSArrStart) {
ctx.error(t.range, 'Block content must start with a key');
return ctx.callNoFirst(arr, t, _ => { });
}
else if (t instanceof TStr || t instanceof TWord) {
return ctx.callNoFirst(key, t, kv => items.push(kv));
}
else if (t instanceof TSArrEnd) {
ctx.error(t.range, 'No Array here');
}
else {
ctx.error(t.range, 'Block content must start with a key');
}
};
}
function arr(ctx, begin, finish) {
const items = [];
return (t) => {
if (t instanceof TEOF) {
ctx.error(t.range, 'Array is not closed');
ctx.end();
finish(new Arr(begin.range, t.range, items));
return ReDo;
}
else if (t instanceof TSComma) {
items.push(new Comma(t.range));
}
else if (t instanceof TSArrEnd) {
ctx.end();
finish(new Arr(begin.range, t.range, items));
}
else if (t instanceof TSObjEnd) {
ctx.error(t.range, 'No Block here');
}
else if (t instanceof TSSplit) {
ctx.error(t.range, 'Array cant have key');
}
else {
return ctx.call(val, u => items.push(u));
}
};
}
function key(ctx, k, finish) {
return (t) => {
if (t instanceof TEOF) {
ctx.error(t.range, 'There should be a key value here');
ctx.end();
return ReDo;
}
else if (t instanceof TSComma) {
ctx.error(t.range, 'There should be a key value here');
ctx.end();
return ReDo;
}
else if (t instanceof TSSplit) {
ctx.end();
return ctx.callNoFirst(val, u => {
const sp = new Split(t.range, t.val);
const kv = new KeyVal(new Key(k.range, k instanceof TStr ? new Str(k.range, k.val, k.col) : k.val), u, sp);
finish(kv);
});
}
else {
ctx.end();
return ctx.call(val, u => {
const kv = new KeyVal(new Key(k.range, k instanceof TStr ? new Str(k.range, k.val, k.col) : k.val), u);
finish(kv);
});
}
};
}
function val(ctx, finish) {
return (t) => {
if (t instanceof TEOF) {
ctx.error(t.range, 'There should be a value here');
ctx.end();
return ReDo;
}
else if (t instanceof TStr) {
ctx.end();
finish(new Str(t.range, t.val, t.col));
}
else if (t instanceof TWord) {
ctx.end();
return ctx.call(word, t, u => {
finish(u);
});
}
else if (t instanceof TSComma || t instanceof TSSplit || t instanceof TSArrEnd || t instanceof TSObjEnd) {
ctx.error(t.range, 'There should be a value here');
ctx.end();
return ReDo;
}
else if (t instanceof TSObjStart) {
ctx.end();
return ctx.callNoFirst(block, t, b => {
finish(b);
});
}
else if (t instanceof TSArrStart) {
ctx.end();
return ctx.callNoFirst(arr, t, a => {
finish(a);
});
}
else {
//todo
ctx.end();
}
};
}
const reg_Num = /(0x[\da-fA-F_]+)|(([\-]?([\d\_])+)\.([\-]?([\d\_])+([eE]([\-]?)\d+)?))|(([\-]?([\d\_])+)\.([eE]([\-]?)\d+)?)|([\-]?\.(([\d\_])+([eE]([\-]?)\d+)?))|(([\-]?([\d\_])+([eE]([\-]?)\d+)?))/i;
function word(ctx, w, finish) {
return (t) => {
ctx.end();
if (w.val === 'true') {
finish(new Bool(w.range, true));
}
else if (w.val === 'false') {
finish(new Bool(w.range, false));
}
else if (w.val === 'null') {
finish(new Null(w.range));
}
else if (reg_Num.test(w.val)) {
finish(new Num(w.range, Number(w.val.replace('_', ''))));
}
else {
finish(new Str(w.range, w.val, null));
}
};
}
class RecursiveCtx {
get(_, result) {
return result;
}
call(fn, ...args) {
return () => fn(this, ...args);
}
}
function doRecursive(fn, ...args) {
var _a, _b;
const ctx = new RecursiveCtx;
const gens = [fn(ctx, ...args)];
let v = undefined;
while (gens.length > 0) {
const gen = gens[gens.length - 1];
const now = gen.next(v);
v = undefined;
if (now.done) {
gens.pop();
v = now.value;
}
else {
const ngen = (_b = (_a = now).value) === null || _b === void 0 ? void 0 : _b.call(_a);
if (ngen != null) {
gens.push(ngen);
}
}
}
return v;
}
async function doRecursiveAsync(fn, ...args) {
var _a, _b;
const ctx = new RecursiveCtx;
const gens = [fn(ctx, ...args)];
let v = undefined;
do {
const gen = gens[gens.length - 1];
const now = await gen.next(v);
v = undefined;
if (now.done) {
gens.pop();
v = now.value;
}
else {
const ngen = (_b = (_a = now).value) === null || _b === void 0 ? void 0 : _b.call(_a);
if (ngen != null) {
gens.push(ngen);
}
}
} while (gens.length > 0 ? (await next_micro_tick(), true) : false);
return v;
}
function toJsObj(doc, config = { async: false }) {
var _a;
return ((_a = config) === null || _a === void 0 ? void 0 : _a.async) ? doRecursiveAsync(root$1, doc) : doRecursive(root$1, doc);
}
function* root$1(ctx, doc) {
const cs = [];
for (const u of doc.items) {
if (u instanceof Block) {
cs.push(yield ctx.call(block$1, u));
}
else if (u instanceof Arr) {
cs.push(yield ctx.call(arr$1, u));
}
}
return cs;
}
function* unit(ctx, u) {
if (u instanceof Block)
return yield ctx.call(block$1, u);
else if (u instanceof Arr)
return yield ctx.call(arr$1, u);
else if (u instanceof Num)
return u.val;
else if (u instanceof Str)
return u.val;
else if (u instanceof Bool)
return u.val;
else if (u instanceof Null)
return null;
else
return undefined;
}
function key$1(k) {
return k.key instanceof Str ? k.key.val : k.key;
}
function* block$1(ctx, b) {
const kvs = [];
for (const kv of b.items) {
if (kv instanceof Comma)
continue;
const v = yield ctx.call(unit, kv.val);
if (v !== undefined)
kvs.push([key$1(kv.key), v]);
}
return Object.fromEntries(kvs);
}
function* arr$1(ctx, a) {
const ars = [];
for (const u of a.items) {
const v = yield ctx.call(unit, u);
if (v !== undefined)
ars.push(v);
}
return ars;
}
const EOF = Symbol('EOF');
const reg_Space = /\s/;
function tokenizer(code, config = { show_all_err: false, iterable: false, async: false, cancel: AlwaysFalse }) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
const cancel = (_b = (_a = config) === null || _a === void 0 ? void 0 : _a.cancel, (_b !== null && _b !== void 0 ? _b : AlwaysFalse));
const state = new State((_d = (_c = config) === null || _c === void 0 ? void 0 : _c.show_all_err, (_d !== null && _d !== void 0 ? _d : false)));
const tokens = [];
state.push(root$2(new Context(state), t => {
tokens.push(t);
}));
let last = null;
let finish = false;
const iter = code[Symbol.iterator]();
function main() {
if (state.queue.length != 0) {
state.queue.pop()();
return _continue;
}
let c;
if (finish)
c = EOF;
else {
const r = iter.next();
if (r.done === true) {
finish = true;
return _continue;
}
else
c = r.value;
}
state.call(c);
if (finish)
return _break;
state.count++;
if (c === '\n') {
if (last !== '\r') {
state.lines[state.line] = state.char;
state.line++;
state.char = 0;
}
last = null;
}
else if (c === '\r') {
state.lines[state.line] = state.char;
state.line++;
state.char = 0;
last = '\r';
}
else {
state.char++;
last = null;
}
}
const loop = (_f = (_e = config) === null || _e === void 0 ? void 0 : _e.iterable, (_f !== null && _f !== void 0 ? _f : false)) ? (_h = (_g = config) === null || _g === void 0 ? void 0 : _g.async, (_h !== null && _h !== void 0 ? _h : false)) ? async function* () {
let finish = false;
while (true) {
if (await cancel())
break;
await next_micro_tick();
if (tokens.length !== 0) {
yield tokens.shift();
}
if (finish)
break;
const s = main();
if (s === _continue)
continue;
if (s === _break) {
finish = true;
continue;
}
}
yield new TEOF(new TkRange(state.pos, state.pos));
if (state.errors.length !== 0)
return state.errors;
} : function* () {
let finish = false;
while (true) {
if (cancel())
break;
if (tokens.length !== 0) {
yield tokens.shift();
}
if (finish)
break;
const s = main();
if (s === _continue)
continue;
if (s === _break) {
finish = true;
continue;
}
}
yield new TEOF(new TkRange(state.pos, state.pos));
if (state.errors.length !== 0)
return state.errors;
} : (_k = (_j = config) === null || _j === void 0 ? void 0 : _j.async, (_k !== null && _k !== void 0 ? _k : false)) ? async function () {
while (true) {
if (await cancel())
break;
await next_micro_tick();
const s = main();
if (s === _continue)
continue;
if (s === _break)
break;
}
tokens.push(new TEOF(new TkRange(state.pos, state.pos)));
return state.errors.length !== 0 ? { err: state.errors, val: tokens } : { val: tokens };
} : function () {
while (true) {
if (cancel())
break;
const s = main();
if (s === _continue)
continue;
if (s === _break)
break;
}
tokens.push(new TEOF(new TkRange(state.pos, state.pos)));
return state.errors.length !== 0 ? { err: state.errors, val: tokens } : { val: tokens };
};
return loop();
}
function root$2(ctx, push) {
return (c) => {
if (c === EOF) {
ctx.end();
}
else if (reg_Space.test(c)) {
return;
}
else if (c === ',' || c === ':' || c === '=' || c === '[' || c === ']' || c === '{' || c === '}') {
ctx.flag();
push(makeTSymbol(ctx.range(), c));
}
else if (c === '"' || c === "'") {
return ctx.callNoFirst(str, c, push);
}
else if (c === '/' || c === '#') {
return ctx.callNoFirst(comment, c, push);
}
else {
return ctx.call(word$1, push);
}
};
}
function str(ctx, first, push) {
const chars = [];
ctx.flag();
return (c) => {
if (c === EOF) {
ctx.error(ctx.range(), 'String is not closed');
ctx.end();
return ReDo;
}
else if (c === '"' || c === "'") {
if (c === first) {
const s = new TStr(ctx.range(), chars.join(''), first);
ctx.end();
push(s);
}
else {
chars.push(c);
}
}
else if (c === '\\') {
return ctx.callNoFirst(escape, c => chars.push(c));
}
else {
chars.push(c);
}
};
}
const hex_digits = /[0-9a-fA-F]/i;
function escape(ctx, push) {
let onUnicode = false;
let chars = [];
let block = false;
ctx.flag();
return (c) => {
if (onUnicode) {
if (c === EOF) {
ctx.error(ctx.range(), 'Unicode escape is not finish');
ctx.end();
return ReDo;
}
else if (hex_digits.test(c)) {
chars.push(c);
if (!block && chars.length === 4) {
ctx.end();
push(String.fromCodePoint(Number(`0x${chars.join('')}`)));
}
}
else if (c === '{') {
if (chars.length !== 0 || block) {
ctx.error(ctx.range(), 'Unicode escape is not finish');
ctx.end();
return ReDo;
}
block = true;
}
else if (c === '}') {
ctx.end();
if (!block) {
ctx.error(ctx.range(), 'Not in Unicode escape block');
return;
}
else if (chars.length === 0 || chars.length > 6) {
ctx.error(ctx.range(), 'Invalid Unicode escape sequence');
return;
}
push(String.fromCodePoint(Number(`0x${chars.join('')}`)));
}
else {
ctx.error(ctx.range(), 'Unicode escape is not finish');
ctx.end();
return ReDo;
}
}
else {
if (c === 'u') {
onUnicode = true;
}
else {
ctx.end();
if (c === EOF) {
return ReDo;
}
else {
push(c === 'n' ? '\n' : c === 'r' ? '\r' : c === 't' ? '\t' : c === '\\' ? '\\' : c === '"' ? '"' : c === "'" ? "'" : c === '0' ? '\0' : c === 'b' ? '\b' : c === 'f' ? '\f' : c === 'v' ? '\v' : c);
}
}
}
};
}
function word$1(ctx, push) {
const chars = [];
ctx.flag();
return (c) => {
if (c === EOF || reg_Space.test(c) || c === '"' || c === "'" || c === ',' || c === ':' || c === '=' || c === '[' || c === ']' || c === '{' || c === '}') {
push(new TWord(ctx.range(true), chars.join('')));
ctx.end();
return ReDo;
}
else if (c === '/' || c === '#') {
push(new TWord(ctx.range(true), chars.join('')));
ctx.end();
return ctx.callNoFirst(comment, c, push);
}
else {
chars.push(c);
}
};
}
const comment_noerr = comment;
function comment(ctx, first, finish, nocc = false) {
ctx.flag();
const flag = ctx.last_flag;
return (c) => {
ctx.end();
if (first === '/') {
if (c === '/') {
return ctx.callNoFirst(line_comment, first, flag, finish);
}
else if (c === '*') {
return ctx.callNoFirst(block_comment, first, flag, finish);
}
else {
if (nocc) {
finish(c);
return ReDo;
}
else
ctx.error(ctx.range(), 'Line Comment need two /');
return ctx.call(line_comment, first, flag, finish);
}
}
else {
if (c === '*') {
return ctx.callNoFirst(block_comment, first, flag, finish);
}
else {
if (nocc) {
finish(c);
return ReDo;
}
return ctx.call(line_comment, first, flag, finish);
}
}
};
}
function line_comment(ctx, first, flag, finish) {
const chars = [];
const items = [];
ctx.last_flag = flag;
return (c) => {
if (c === EOF || c === '\n' || c === '\r') {
if (chars.length > 0)
items.push(chars.join(''));
ctx.end();
finish(new TLineComment(ctx.range(), items));
return ReDo;
}
else if (c === '/' || c === '#') {
if (chars.length > 0)
items.push(chars.join(''));
chars.length = 0;
return ctx.callNoFirst(comment, c, cm => {
items.push(cm);
});
}
else {
chars.push(c);
}
};
}
function block_comment(ctx, first, flag, finish) {
const chars = [];
const items = [];
let star = false;
ctx.last_flag = flag;
let redo_end = false;
return (c) => {
if (redo_end) {
ctx.end();
return ReDo;
}
if (c === EOF) {
if (star)
chars.push('*');
if (chars.length > 0)
items.push(chars.join(''));
ctx.end();
finish(new TBlockComment(ctx.range(), items));
ctx.flag();
ctx.error(ctx.range(), 'Block Comment is not close');
return ReDo;
}
else if (c === '*') {
if (star)
chars.push('*');
else
star = true;
}
else if (c === '/' || c === '#') {
if (star) {
star = false;
if (c === first) {
return ctx.callNoFirst(comment_noerr, c, w => {
if (w instanceof TLineComment || w instanceof TBlockComment) {
if (chars.length > 0)
items.push(chars.join(''));
chars.length = 0;
items.push(w);
}
else {
if (chars.length > 0)
items.push(chars.join(''));
chars.length = 0;
redo_end = true;
finish(new TBlockComment(ctx.range(), items));
}
}, true);
}
else {
chars.push('*');
chars.push(c);
}
}
else {
return ctx.callNoFirst(comment_noerr, c, w => {
if (w === EOF) {
chars.push(c);
}
else if (w instanceof TLineComment || w instanceof TBlockComment) {
if (chars.length > 0)
items.push(chars.join(''));
chars.length = 0;
items.push(w);
}
else {
chars.push(c);
chars.push(w);
}
}, true);
}
}
else {
if (star)
chars.push('*');
star = false;
chars.push(c);
}
};
}
const DefaultFormat = {
string: "'",
splitter: null,
comma: false,
comma_when_only_one_line: true,
split_before_brackets: false,
strict_string: false,
strict_key: false,
tab: ' ',
tab_count: 2
};
const MinFormat = {
...DefaultFormat,
comma_when_only_one_line: false,
};
const JsonFormat = {
...DefaultFormat,
string: '"',
splitter: ':',
comma: true,
split_before_brackets: true,
strict_string: true,
strict_key: true,
};
function styleFormat(style) {
return style === 'min' ? MinFormat : DefaultFormat;
}
function stringify(val, config) {
var _a, _b, _c, _d;
const style = (_b = (_a = config) === null || _a === void 0 ? void 0 : _a.style, (_b !== null && _b !== void 0 ? _b : null));
const format = { ...styleFormat(style), ...(_d = (_c = config) === null || _c === void 0 ? void 0 : _c.format, (_d !== null && _d !== void 0 ? _d : {})) };
const obj_ref_pool = new Set();
return _stringify(val, style === 'beautify', format, obj_ref_pool);
}
const reg_quote_s = /'/ug;
const reg_quote_d = /d/ug;
const reg_not_word = /["'\s]|true|false|null/u;
const reg_first_num = /[\d\-\+]/u;
function is_word(val) {
return is_key(val) && !reg_first_num.test(val[0]);
}
function is_key(val) {
return val.length > 0 && !reg_not_word.test(val);
}
function _stringify(val, beautify, format, obj_ref_pool) {
var _a;
//todo beautify
const { string, comma, splitter } = format;
if (typeof val === 'string') {
if (is_word(val))
return val;
const nv = val.replace(string === '"' ? reg_quote_d : reg_quote_s, `\\${string}`);
return `${string}${nv}${string}`;
}
else if (typeof val === 'number' || typeof val === 'bigint' || typeof val === 'boolean') {
return `${val}`;
}
else if (val == null)
return `null`;
else if (typeof val === 'object') {
if (obj_ref_pool.has(val)) {
throw TypeError('Converting circular structure to CBON');
}
obj_ref_pool.add(val);
const getfn = (_a = val['toCBON'], (_a !== null && _a !== void 0 ? _a : val['toJSON']));
if (typeof getfn === 'function')
return getfn();
if (val instanceof Array) {
const outmap = val.map(v => {
const r = _stringify(v, beautify, format, obj_ref_pool);
if (r === undefined)
return `null`;
else
return r;
});
const str = outmap.join(comma ? ',' : ' ');
obj_ref_pool.delete(val);
return `[${str}]`;
}
else {
const kvs = [];
for (const k in val) {
const v = val[k];
const r = _stringify(v, beautify, format, obj_ref_pool);
if (r !== undefined) {
kvs.push([is_key(k) ? k : `${string}${k}${string}`, r]);
}
}
const str = kvs.map(kv => kv.join((splitter !== null && splitter !== void 0 ? splitter : ' '))).join(comma ? ',' : ' ');
obj_ref_pool.delete(val);
return `{${str}}`;
}
}
else {
return void 0;
}
}
function parser$1(code, config) {
var _a, _b, _c, _d, _e, _f, _g;
const cancel = (_b = (_a = config) === null || _a === void 0 ? void 0 : _a.cancel, (_b !== null && _b !== void 0 ? _b : AlwaysFalse));
const show_all_err = (_d = (_c = config) === null || _c === void 0 ? void 0 : _c.show_all_err, (_d !== null && _d !== void 0 ? _d : false));
const async = (_f = (_e = config) === null || _e === void 0 ? void 0 : _e.async, (_f !== null && _f !== void 0 ? _f : false));
let isCancel = false;
const errmsg = [];
let root;
function* main(cancel) {
var _a, _b;
try {
const r = yield parser(yield tokenizer(code, {
show_all_err,
iterable: true,
async,
cancel
}), {
show_all_err,
async,
cancel
});
if (r.err != null) {
errmsg.push(...getErrorsMsgs(r.err));
}
root = r.val;
}
catch (e) {
if (e instanceof WhenError) {
errmsg.push(e.err.msg);
}
else
throw e;
}
if (errmsg.length !== 0) {
throw new SyntaxError(`\n ${errmsg.join('\n ')}\n`);
}
if (yield /** is cancel */)
return null;
const o = yield toJsObj(root, { async });
if (_b = (_a = config) === null || _a === void 0 ? void 0 : _a.alwaysDocs, (_b !== null && _b !== void 0 ? _b : false))
return o;
if (o.length == 1) {
return o[0];
}
else
return o;
}
const def = ((_g = config) === null || _g === void 0 ? void 0 : _g.async) ? async function () {
async function Cancel() {
if (!isCancel)
isCancel = await cancel();
return isCancel;
}
const g = main(Cancel);
g.next(await g.next(await g.next().value).value);
return g.next(await g.next(await Cancel()).value).value;
} : function () {
function Cancel() {
if (!isCancel)
isCancel = cancel();
return isCancel;
}
const g = main(Cancel);
g.next(g.next(g.next().value).value);
return g.next(g.next(Cancel()).value).value;
};
return def();
}
exports.DefaultFormat = DefaultFormat;
exports.JsonFormat = JsonFormat;
exports.MinFormat = MinFormat;
exports.parser = parser$1;
exports.stringify = stringify;
exports.styleFormat = styleFormat;
Object.defineProperty(exports, '__esModule', { value: true });
})));