Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/jonschlinkert/eval-estree-expression
Safely evaluate JavaScript (estree) expressions, sync and async.
https://github.com/jonschlinkert/eval-estree-expression
ast babel babeljs context escodegen esprima estree eval evaluate evaluate-expressions evaluation evaluator expression expression-evaluator parse parser
Last synced: 2 months ago
JSON representation
Safely evaluate JavaScript (estree) expressions, sync and async.
- Host: GitHub
- URL: https://github.com/jonschlinkert/eval-estree-expression
- Owner: jonschlinkert
- License: mit
- Created: 2021-09-06T06:15:00.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2024-09-07T16:51:00.000Z (3 months ago)
- Last Synced: 2024-09-29T06:21:40.431Z (2 months ago)
- Topics: ast, babel, babeljs, context, escodegen, esprima, estree, eval, evaluate, evaluate-expressions, evaluation, evaluator, expression, expression-evaluator, parse, parser
- Language: JavaScript
- Homepage:
- Size: 112 KB
- Stars: 45
- Watchers: 4
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Funding: .github/funding.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-javascript - eval-estree-expression
- awesome-javascript - eval-estree-expression
README
# eval-estree-expression [![NPM version](https://img.shields.io/npm/v/eval-estree-expression.svg?style=flat)](https://www.npmjs.com/package/eval-estree-expression) [![NPM monthly downloads](https://img.shields.io/npm/dm/eval-estree-expression.svg?style=flat)](https://npmjs.org/package/eval-estree-expression) [![NPM total downloads](https://img.shields.io/npm/dt/eval-estree-expression.svg?style=flat)](https://npmjs.org/package/eval-estree-expression) [![Tests](https://github.com/jonschlinkert/eval-estree-expression/actions/workflows/main.yml/badge.svg)](https://github.com/jonschlinkert/eval-estree-expression/actions/workflows/main.yml)
> Safely evaluate JavaScript (estree) expressions, sync and async.
Please consider following this project's author, [Jon Schlinkert](https://github.com/jonschlinkert), and consider starring the project to show your :heart: and support.
- [Install](#install)
- [Usage](#usage)
* [Usage with Babel](#usage-with-babel)
* [Usage with Esprima](#usage-with-esprima)
- [API](#api)
* [.evaluate](#evaluate)
* [.evaluate.sync](#evaluatesync)
* [.variables](#variables)
- [Options](#options)
* [booleanLogicalOperators](#booleanlogicaloperators)
* [functions](#functions)
* [generate](#generate)
* [regexOperator](#regexoperator)
* [strict](#strict)
* [withMembers](#withmembers)
- [Examples](#examples)
* [Operators](#operators)
- [About](#about)_(TOC generated by [verb](https://github.com/verbose/verb) using [markdown-toc](https://github.com/jonschlinkert/markdown-toc))_
## Install
Install with [npm](https://www.npmjs.com/):
```sh
$ npm install --save eval-estree-expression
```## Usage
Requires [Node.js](https://nodejs.org/en/download/) version 14 or greater.
Evaluates an [estree](https://github.com/estree/estree) expression from [@babel/parser][], [esprima](http://esprima.org), [acorn](https://github.com/acornjs/acorn), or any other library that parses and returns a valid `estree` expression.
```js
const { evaluate } = require('eval-estree-expression');evaluate(expressionTree[, context]); // async
evaluate.sync(expressionTree[, context]); // sync
```See the [unit tests](./test) for hundreds of additional usage examples.
**Params**
The `evaluate` function takes the following arguments:
* `expressionTree` **{object}** - a valid [estree](https://github.com/estree/estree) expression AST.
* `context` **{object}** - a data object with values to replace variables in expressions### Usage with Babel
Most of the examples in this document assume the following setup code is used:
```js
const { evaluate } = require('eval-estree-expression');
const { parseExpression } = require('@babel/parser');// parse your JavaScript expression
const ast = parseExpression('1 + 2');// evaluate synchronously
console.log(evaluate.sync(ast)); //=> 3// or asynchronously
console.log(await evaluate(ast)); //=> 3
```### Usage with Esprima
[Esprima][esprimar] doesn't have a "parseExpression" method like @babel/parser, so you'll need to return the expression from the AST, like so:
```js
const { parse } = require('esprima');
const { evaluate } = require('eval-estree-expression');
const ast = parse('[1, 2, 3].map(n => n * x);').body[0].expression;// evaluate synchronously
console.log(evaluate.sync(ast)); // =>, [2, 4, 6]// or asynchronously
console.log(await evaluate(ast)); // =>, [2, 4, 6]
```## API
### .evaluate
Evaluate expresssions asynchronously.
```js
console.log(await evaluate(parse('1 + 2'))); //=> 3
console.log(await evaluate(parse('5 * 2'))); //=> 10
console.log(await evaluate(parse('1 > 2'))); //=> false
console.log(await evaluate(parse('1 < 2'))); //=> true// with context object
console.log(await evaluate(parse('page.title === "home"'), { page: { title: 'home' } })); //=> true
```### .evaluate.sync
Evaluate expresssions synchronously.
```js
console.log(evaluate.sync(parse('1 + 2'))); //=> 3
console.log(evaluate.sync(parse('5 * 2'))); //=> 10
console.log(evaluate.sync(parse('1 > 2'))); //=> false
console.log(evaluate.sync(parse('1 < 2'))); //=> true// with context object
console.log(evaluate.sync(parse('page.title === "home"'), { page: { title: 'home' } })); //=> true
```### .variables
Get an array of variables from an expression:
```js
const { parseExpression } = require('@babel/parser');
const { variables } = require('eval-estree-expression');console.log(variables(parseExpression('x * (y * 3) + z.y.x'))); //=> ['x', 'y', 'z']
console.log(variables(parseExpression('(a || b) ? c + d : e * f'))); //=> ['a', 'b', 'c', 'd', 'e', 'f']```
## Options
### booleanLogicalOperators
Type: `boolean`
Default: `undefined`Force logical operators to return a boolean result.
```js
console.log(await evaluate(parse('a && b'), { a: undefined, b: true })); //=> undefined
console.log(await evaluate(parse('a && b'), { a: undefined, b: false })); //=> undefined
console.log(await evaluate(parse('a || b'), { a: false, b: null })); //=> null
console.log(await evaluate(parse('a || b'), { a: false, b: undefined })); //=> undefined//
// With booleanLogicalOperators enabled
//const options = {
booleanLogicalOperators: true
};console.log(await evaluate(parse('a || b'), { a: false, b: null }, options)); //=> false
console.log(await evaluate(parse('a && b'), { a: undefined, b: true }, options)); //=> false
console.log(await evaluate(parse('a && b'), { a: undefined, b: false }, options)); //=> false
console.log(await evaluate(parse('a || b'), { a: false, b: undefined }, options)); //=> false
```### functions
Type: `boolean`
Default: `false`Allow function calls to be evaluated. This is unsafe, please enable this option at your own risk.
**Example**
```js
const { parse } = require('esprima');
const { generate } = require('escodegen');
const { evaluate } = require('eval-estree-expression');const options = {
functions: true
};// works with native methods
console.log(evaluate.sync(parse('/([a-z]+)/.exec(" foo ")'), { x: 2 }, options));
//=> [ 'foo', 'foo', index: 1, input: ' foo ', groups: undefined ]// and functions defined on the context
console.log(evaluate.sync('a.upper("b")', { a: { upper: v => v.toUpperCase() } }, options);
//=> 'B'
```However, this does NOT support function expressions or function statements.
To enable function statements and expressions (not just function calls) to be evaluated, you must also use the [generate](#generate) option.### generate
Type: `boolean`
Default: `undefined`Enable support for function statements and expressions by enabling the [functions](#functions) option AND by passing the `.generate()` function from the [escodegen](http://github.com/estools/escodegen) library.
**Example**
```js
const escodegen = require('escodegen');
const { parse } = require('esprima');
const { evaluate } = require('eval-estree-expression');const options = {
functions: true,
generate: escodegen.generate
};console.log(await evaluate(parse('[1, 2, 3].map(n => n * x);'), { x: 2 }, options))); // =>, [2, 4, 6]
```### regexOperator
Type: `boolean`
Default: `true`Enable the `=~` regex operator to support testing values without using functions (example `name =~ /^a.*c$/`).
**Why is this needed?**
In expressions, if you wish to test a value using a regular expression, you have two options:
1. Enable function support so that you can use methods like `.test()` and `.match()`, or
2. Use this option, which uses a special syntax to match against regular expressions _without evaluating an functions_.In other words, instead of having to do this:
```js
console.log(evaluate.sync(parse('/^ab+c$/ig.test("abbbbbc")'), {}, { functions: true }));
```You can do this:
```js
console.log(evaluate.sync(parse('name =~ /^a.*c$/'), { name: 'abc' }));
console.log(evaluate.sync(parse('name =~ regex'), { name: 'abc', regex: /^a.*c$/ }));
```### strict
Type: `boolean`
Default: `false`Throw an error when variables are undefined.
### withMembers
Type: `boolean`
Default: `undefined`Used with the [variables](#variables) method to return nested variables (e.g. variables with dot notation, like `foo.bar.baz`).
## Examples
### Operators
Supports all JavaScript operators with the exception of assignment operators (`=`, `+=`, etc):
```js
// Arithmetic operators
evaluate('a + b');
evaluate('a - b');
evaluate('a / b');
evaluate('a * b');
evaluate('a % b');
evaluate('a ** b');// Relational operators
evaluate('a instanceof b');
evaluate('a < b');
evaluate('a > b');
evaluate('a <= b');
evaluate('a >= b');// Equality operators
evaluate('a !== b');
evaluate('a === b');
evaluate('a != b');
evaluate('a == b');// Bitwise shift operators
evaluate('a << b');
evaluate('a >> b');
evaluate('a >>> b');// Binary bitwise operators
evaluate('a & b');
evaluate('a | b');
evaluate('a ^ b');// Binary logical operators
evaluate('a && b'); // Logical AND.
evaluate('a || b'); // Logical OR.
evaluate('a ?? b'); // Nullish Coalescing Operator.
```## About
Contributing
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new).
Running Tests
Running and reviewing unit tests is a great way to get familiarized with a library and its API. You can install dependencies and run tests with the following command:
```sh
$ npm install && npm test
```Building docs
_(This project's readme.md is generated by [verb](https://github.com/verbose/verb-generate-readme), please don't edit the readme directly. Any changes to the readme must be made in the [.verb.md](.verb.md) readme template.)_
To generate the readme, run the following command:
```sh
$ npm install -g verbose/verb#dev verb-generate-readme && verb
```### Related projects
You might also be interested in these projects:
[whence](https://www.npmjs.com/package/whence): Add context awareness to your apps and frameworks by safely evaluating user-defined conditional expressions. Useful… [more](https://github.com/jonschlinkert/whence) | [homepage](https://github.com/jonschlinkert/whence "Add context awareness to your apps and frameworks by safely evaluating user-defined conditional expressions. Useful for evaluating expressions in config files, prompts, key bindings, completions, templates, and many other user cases.")
### Contributors
| **Commits** | **Contributor** |
| --- | --- |
| 30 | [jonschlinkert](https://github.com/jonschlinkert) |
| 1 | [6utt3rfly](https://github.com/6utt3rfly) |### Author
**Jon Schlinkert**
* [GitHub Profile](https://github.com/jonschlinkert)
* [Twitter Profile](https://twitter.com/jonschlinkert)
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert)### License
Copyright © 2021, [Jon Schlinkert](https://github.com/jonschlinkert).
Released under the [MIT License](LICENSE).***
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.8.0, on September 25, 2021._