UNPKG

@jsonjoy.com/json-expression

Version:

High-performance JSON Pointer implementation

171 lines (170 loc) 5.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.objectOperators = void 0; const tslib_1 = require("tslib"); const util = tslib_1.__importStar(require("../util")); const codegen_steps_1 = require("../codegen-steps"); const validateSetOperandCount = (count) => { if (count < 3) { throw new Error('Not enough operands for "o.set".'); } if (count % 2 !== 0) { throw new Error('Invalid number of operands for "o.set" operand.'); } }; const validateDelOperandCount = (count) => { if (count < 3) { throw new Error('Not enough operands for "o.del".'); } }; exports.objectOperators = [ [ 'keys', [], 1, (expr, ctx) => { const operand = ctx.eval(expr[1], ctx); return util.keys(operand); }, (ctx) => { ctx.link(util.keys, 'keys'); const js = `keys(${ctx.operands[0]})`; return new codegen_steps_1.Expression(js); }, ], [ 'values', [], 1, (expr, ctx) => { const operand = ctx.eval(expr[1], ctx); return util.values(operand); }, (ctx) => { ctx.link(util.values, 'values'); const js = `values(${ctx.operands[0]})`; return new codegen_steps_1.Expression(js); }, ], [ 'entries', [], 1, (expr, ctx) => { const operand = ctx.eval(expr[1], ctx); return util.entries(operand); }, (ctx) => { ctx.link(util.entries, 'entries'); const js = `entries(${ctx.operands[0]})`; return new codegen_steps_1.Expression(js); }, ], [ 'o.set', [], -1, /** * Set one or more properties on an object. * * ``` * ['o.set', {}, * 'a', 1, * 'b', ['+', 2, 3], * ] * ``` * * Results in: * * ``` * { * a: 1, * b: 5, * } * ``` */ (expr, ctx) => { let i = 1; const length = expr.length; validateSetOperandCount(length); const doc = util.asObj(ctx.eval(expr[i++], ctx)); while (i < length) { const prop = util.str(ctx.eval(expr[i++], ctx)); if (prop === '__proto__') throw new Error('PROTO_KEY'); const value = ctx.eval(expr[i++], ctx); doc[prop] = value; } return doc; }, (ctx) => { const length = ctx.operands.length; validateSetOperandCount(length + 1); let i = 0; let curr = ctx.operands[i++]; if (curr instanceof codegen_steps_1.Literal) { curr = new codegen_steps_1.Literal(util.asObj(curr.val)); } else if (curr instanceof codegen_steps_1.Expression) { ctx.link(util.asObj, 'asObj'); curr = new codegen_steps_1.Expression(`asObj(${curr})`); } ctx.link(util.str, 'str'); ctx.link(util.objSetRaw, 'objSetRaw'); while (i < length) { let prop = ctx.operands[i++]; if (prop instanceof codegen_steps_1.Literal) { prop = new codegen_steps_1.Literal(util.str(prop.val)); } else if (prop instanceof codegen_steps_1.Expression) { prop = new codegen_steps_1.Expression(`str(${prop})`); } const value = ctx.operands[i++]; curr = new codegen_steps_1.Expression(`objSetRaw(${curr}, ${prop}, ${value})`); } return curr; }, ], [ 'o.del', [], -1, /** * Delete one or more properties from an object. * * ``` * ['o.del', {}, 'prop1', 'prop2'] * ``` */ (expr, ctx) => { let i = 1; const length = expr.length; validateDelOperandCount(length); const doc = util.asObj(ctx.eval(expr[i++], ctx)); while (i < length) { const prop = util.str(ctx.eval(expr[i++], ctx)); delete doc[prop]; } return doc; }, (ctx) => { const length = ctx.operands.length; validateDelOperandCount(length + 1); let i = 0; let curr = ctx.operands[i++]; ctx.link(util.str, 'str'); ctx.link(util.objDelRaw, 'objDelRaw'); while (i < length) { let prop = ctx.operands[i++]; if (prop instanceof codegen_steps_1.Literal) { prop = new codegen_steps_1.Literal(util.str(prop.val)); } else if (prop instanceof codegen_steps_1.Expression) { prop = new codegen_steps_1.Expression(`str(${prop})`); } curr = new codegen_steps_1.Expression(`objDelRaw(${curr}, ${prop})`); } return curr; }, ], ];