jse-eval
Version:
JavaScript expression parsing and evaluation.
3 lines (2 loc) • 9.6 kB
JavaScript
import e from"jsep";export{default as jsep,default as parse}from"jsep";function t(){return t=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},t.apply(this,arguments)}class n{static addUnaryOp(t,r){e.addUnaryOp(t),n.unops[t]=r}static addBinaryOp(t,r,s,i){let a,o,l;"function"==typeof r?l=r:(a=r,"function"==typeof s?l=s:(o=s,l=i)),e.addBinaryOp(t,a||1,o),n.binops[t]=l}static addEvaluator(e,t){n.evaluators[e]=t}static registerPlugin(...e){e.forEach(e=>{e.init&&n.parse.plugins.register(e),e.initEval&&e.initEval.call(n,n)})}static eval(e,t){return new n(t).eval(e)}static async evalAsync(e,t){return new n(t,!0).eval(e)}static compile(e){return n.eval.bind(null,n.jsep(e))}static compileAsync(e){return n.evalAsync.bind(null,n.jsep(e))}static evalExpr(e,t){return n.compile(e)(t)}static evalExprAsync(e,t){return n.compileAsync(e)(t)}constructor(e,t){this.context=void 0,this.isAsync=void 0,this.context=e,this.isAsync=t}eval(e,t=(e=>e)){const r=n.evaluators[e.type]||n.evaluators.default;if(!r)throw new Error(`unknown node type: ${JSON.stringify(e,null,2)}`);return this.evalSyncAsync(r.bind(this)(e,this.context),n=>(e._value=n,t(n)))}evalSyncAsync(e,t){return this.isAsync?Promise.resolve(e).then(t):t(e)}evalArrayExpression(e){return this.evalArray(e.elements)}evalArray(e){const t=e.map(e=>this.eval(e)),n=t=>t.reduce((t,n,r)=>"SpreadElement"===e[r].type?[...t,...n]:(t.push(n),t),[]);return this.isAsync?Promise.all(t).then(n):n(t)}evalBinaryExpression(e){if("||"===e.operator)return this.eval(e.left,t=>t||this.eval(e.right));if("&&"===e.operator)return this.eval(e.left,t=>t&&this.eval(e.right));const t=[this.eval(e.left),this.eval(e.right)],r=([t,r])=>n.binops[e.operator](t,r);return this.isAsync?Promise.all(t).then(r):r(t)}evalCompoundExpression(e){return this.isAsync?e.body.reduce((e,t)=>e.then(()=>this.eval(t)),Promise.resolve()):e.body.map(e=>this.eval(e))[e.body.length-1]}evalCallExpression(e){return this.evalSyncAsync(this.evalCall(e.callee),([t,n])=>this.evalSyncAsync(this.evalArray(e.arguments),r=>t.apply(n===e.callee?this.context:n,r)))}evalCall(e){return"MemberExpression"===e.type?this.evalSyncAsync(this.evaluateMember(e),([t,r])=>n.validateFnAndCall(r,t,e)):this.eval(e,t=>n.validateFnAndCall(t,e))}evalConditionalExpression(e){return this.eval(e.test,t=>this.eval(t?e.consequent:e.alternate))}evalIdentifier(e){return this.context[e.name]}static evalLiteral(e){return e.value}evalMemberExpression(e){return this.evalSyncAsync(this.evaluateMember(e),([,e])=>e)}evaluateMember(e){return this.eval(e.object,t=>this.evalSyncAsync(e.computed?this.eval(e.property):e.property.name,n=>{if(/^__proto__|prototype|constructor$/.test(n))throw Error(`Access to member "${n}" disallowed.`);return[t,(e.optional?t||{}:t)[n],n]}))}evalThisExpression(){return this.context}evalUnaryExpression(e){return this.eval(e.argument,t=>n.unops[e.operator](t))}evalArrowFunctionExpression(e){return this.isAsync!==e.async?n[e.async?"evalAsync":"eval"](e,this.context):(...t)=>{const r=this.evalArrowContext(e,t);return n[e.async?"evalAsync":"eval"](e.body,r)}}evalArrowContext(e,n){const r=t({},this.context);return(e.params||[]).forEach((e,s)=>{if("AssignmentExpression"===e.type&&(void 0===n[s]&&(n[s]=this.eval(e.right)),e=e.left),"Identifier"===e.type)r[e.name]=n[s];else if("ArrayExpression"===e.type)e.elements.forEach((e,t)=>{let i=n[s][t];if("AssignmentExpression"===e.type&&(void 0===i&&(i=this.eval(e.right)),e=e.left),"Identifier"!==e.type)throw new Error("Unexpected arrow function argument");r[e.name]=i});else if("ObjectExpression"===e.type){const i=[];e.properties.forEach(e=>{let a,o=e;if("AssignmentExpression"===o.type&&(o=o.left),"Property"===o.type)a="Identifier"===o.key.type?o.key.name:this.eval(o.key).toString();else if("Identifier"===o.type)a=o.name;else{if("SpreadElement"!==o.type||"Identifier"!==o.argument.type)throw new Error("Unexpected arrow function argument");a=o.argument.name}let l=n[s][a];"SpreadElement"===o.type?(l=t({},n[s]),i.forEach(e=>{delete l[e]})):void 0===l&&"AssignmentExpression"===e.type&&(l=this.eval(e.right)),r[a]=l,i.push(a)})}else{if("SpreadElement"!==e.type||"Identifier"!==e.argument.type)throw new Error("Unexpected arrow function argument");r[e.argument.name]=n.slice(s)}}),r}evalAssignmentExpression(e){return this.evalSyncAsync(this.getContextAndKey(e.left),([t,r])=>this.eval(e.right,s=>n.assignOps[e.operator](t,r,s)))}evalUpdateExpression(e){return this.evalSyncAsync(this.getContextAndKey(e.argument),([t,r])=>n.evalUpdateOperation(e,t,r))}evalAwaitExpression(e){return n.evalAsync(e.argument,this.context)}static evalUpdateOperation(e,t,n){return e.prefix?"++"===e.operator?++t[n]:--t[n]:"++"===e.operator?t[n]++:t[n]--}getContextAndKey(e){if("MemberExpression"===e.type)return this.evalSyncAsync(this.evaluateMember(e),([e,,t])=>[e,t]);if("Identifier"===e.type)return[this.context,e.name];if("ConditionalExpression"===e.type)return this.eval(e.test,t=>this.getContextAndKey(t?e.consequent:e.alternate));throw new Error("Invalid Member Key")}evalNewExpression(e){return this.evalSyncAsync(this.evalCall(e.callee),([t])=>this.evalSyncAsync(this.evalArray(e.arguments),r=>n.construct(t,r,e)))}evalObjectExpression(e){const t={},r=e.properties.map(e=>{if("SpreadElement"===e.type)Object.assign(t,n.eval(e.argument,this.context));else if("Property"===e.type)return this.evalSyncAsync("Identifier"===e.key.type?e.key.name:this.eval(e.key),n=>this.eval(e.shorthand?e.key:e.value,e=>{t[n]=e}))});return this.isAsync?Promise.all(r).then(()=>t):t}evalSpreadElement(e){return this.eval(e.argument)}evalTaggedTemplateExpression(e){const t=[this.evalCall(e.tag),this.evalSyncAsync(this.evalArray(e.quasi.expressions),t=>[e.quasi.quasis.map(e=>e.value.cooked),...t])],n=([[e,t],n])=>e.apply(t,n);return this.isAsync?Promise.all(t).then(n):n(t)}evalTemplateLiteral(e){return this.evalSyncAsync(this.evalArray(e.expressions),t=>e.quasis.reduce((e,n,r)=>(e+=n.value.cooked,n.tail||(e+=t[r]),e),""))}static construct(e,t,r){try{return new(Function.prototype.bind.apply(e,[null].concat(t)))}catch(e){throw new Error(`${n.nodeFunctionName(r.callee)} is not a constructor`)}}static validateFnAndCall(e,t,r){if("function"!=typeof e){if(!e&&r&&r.optional)return[()=>{},t];const s=n.nodeFunctionName(r||t);throw new Error(`'${s}' is not a function`)}return[e,t]}static nodeFunctionName(e){return e&&(e.name||e.property&&e.property.name)}}n.jsep=e,n.parse=e,n.evaluate=n.eval,n.evaluators={ArrayExpression:n.prototype.evalArrayExpression,LogicalExpression:n.prototype.evalBinaryExpression,BinaryExpression:n.prototype.evalBinaryExpression,CallExpression:n.prototype.evalCallExpression,Compound:n.prototype.evalCompoundExpression,ConditionalExpression:n.prototype.evalConditionalExpression,Identifier:n.prototype.evalIdentifier,Literal:n.evalLiteral,OptionalMemberExpression:n.prototype.evalMemberExpression,MemberExpression:n.prototype.evalMemberExpression,ThisExpression:n.prototype.evalThisExpression,UnaryExpression:n.prototype.evalUnaryExpression,ArrowFunctionExpression:n.prototype.evalArrowFunctionExpression,AssignmentExpression:n.prototype.evalAssignmentExpression,UpdateExpression:n.prototype.evalUpdateExpression,AwaitExpression:n.prototype.evalAwaitExpression,NewExpression:n.prototype.evalNewExpression,ObjectExpression:n.prototype.evalObjectExpression,SpreadElement:n.prototype.evalSpreadElement,TaggedTemplateExpression:n.prototype.evalTaggedTemplateExpression,TemplateLiteral:n.prototype.evalTemplateLiteral},n.DEFAULT_PRECEDENCE={"||":1,"&&":2,"|":3,"^":4,"&":5,"==":6,"!=":6,"===":6,"!==":6,"<":7,">":7,"<=":7,">=":7,"<<":8,">>":8,">>>":8,"+":9,"-":9,"*":10,"/":10,"%":10},n.binops={"||":function(e,t){return e||t},"&&":function(e,t){return e&&t},"|":function(e,t){return e|t},"^":function(e,t){return e^t},"&":function(e,t){return e&t},"==":function(e,t){return e==t},"!=":function(e,t){return e!=t},"===":function(e,t){return e===t},"!==":function(e,t){return e!==t},"<":function(e,t){return e<t},">":function(e,t){return e>t},"<=":function(e,t){return e<=t},">=":function(e,t){return e>=t},"<<":function(e,t){return e<<t},">>":function(e,t){return e>>t},">>>":function(e,t){return e>>>t},"+":function(e,t){return e+t},"-":function(e,t){return e-t},"*":function(e,t){return e*t},"/":function(e,t){return e/t},"%":function(e,t){return e%t}},n.unops={"-":function(e){return-e},"+":function(e){return+e},"~":function(e){return~e},"!":function(e){return!e}},n.assignOps={"=":function(e,t,n){return e[t]=n},"*=":function(e,t,n){return e[t]*=n},"**=":function(e,t,n){return e[t]**=n},"/=":function(e,t,n){return e[t]/=n},"%=":function(e,t,n){return e[t]%=n},"+=":function(e,t,n){return e[t]+=n},"-=":function(e,t,n){return e[t]-=n},"<<=":function(e,t,n){return e[t]<<=n},">>=":function(e,t,n){return e[t]>>=n},">>>=":function(e,t,n){return e[t]>>>=n},"&=":function(e,t,n){return e[t]&=n},"^=":function(e,t,n){return e[t]^=n},"|=":function(e,t,n){return e[t]|=n}};const r=n.DEFAULT_PRECEDENCE,s=n.evaluators,i=n.binops,a=n.unops,o=n.assignOps,l=n.addUnaryOp,p=n.addBinaryOp,u=n.addEvaluator,c=n.registerPlugin,y=n.eval,v=n.evalAsync,h=n.compile,f=n.compileAsync,d=n.evalExpr,E=n.evalExprAsync;export{r as DEFAULT_PRECEDENCE,p as addBinaryOp,u as addEvaluator,l as addUnaryOp,o as assignOps,i as binops,h as compile,f as compileAsync,n as default,v as evalAsync,d as evalExpr,E as evalExprAsync,y as evaluate,s as evaluators,c as registerPlugin,a as unops};
//# sourceMappingURL=jse-eval.modern.js.map