@jsonjoy.com/json-expression
Version:
High-performance JSON Pointer implementation
171 lines (170 loc) • 5.3 kB
JavaScript
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;
},
],
];
;