• Stars
    star
    1,042
  • Rank 42,681 (Top 0.9 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 10 years ago
  • Updated about 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A simple, safe, JavaScript Filter Expression compiler for end-users

Filtrex

A simple, safe, JavaScript expression engine, allowing end-users to enter arbitrary expressions without p0wning you.

category == "meal" and (calories * weight > 2000.0 or subcategory in ("cake", "pie"))

Why?

There are many cases where you want a user to be able enter an arbitrary expression through a user interface. e.g.

  • Plot a chart (example)
  • Filter/searching across items using multiple fields (example)
  • Colorize items based on values (example)
  • Implement a browser based spreadsheet

Sure, you could do that with JavaScript and eval(), but I'm sure I don't have to tell you how stupid that would be.

Filtrex defines a really simple expression language that should be familiar to anyone who's ever used a spreadsheet and compile it into a JavaScript function at runtime.

Features

  • Simple! End user expression language looks like this transactions <= 5 and abs(profit) > 20.5
  • Fast! Expressions get compiled into JavaScript functions, offering the same performance as if it had been hand coded. e.g. function(item) { return item.transactions <=5 && Math.abs(item.profit) > 20.5; }
  • Safe! You as the developer have control of which data can be accessed and the functions that can be called. Expressions cannot escape the sandbox.
  • Pluggable! Add your own data and functions.
  • Predictable! Because users can't define loops or recursive functions, you know you won't be left hanging.

Get it

10 second tutorial

// Input from user (e.g. search filter)
var expression = 'transactions <= 5 and abs(profit) > 20.5';

// Compile expression to executable function
var myfilter = compileExpression(expression);

// Execute function
myfilter({transactions: 3, profit:-40.5}); // returns 1
myfilter({transactions: 3, profit:-14.5}); // returns 0

Under the hood, the above expression gets compiled to a clean and fast JavaScript function, looking something like this:

// Resulting function
function(item) {
  return item.transactions <= 5 && Math.abs(item.profit) > 20.5;
}

Expressions

There are only 2 types: numbers and strings. Numbers may be floating point or integers. Boolean logic is applied on the truthy value of values (e.g. any non-zero number is true, any non-empty string is true, otherwise false).

Values Description
43, -1.234 Numbers
"hello" String
foo, a.b.c, 'foo-bar' External data variable defined by application (may be numbers or strings)
Numeric arithmetic Description
x + y Add
x - y Subtract
x * y Multiply
x / y Divide
x % y Modulo
x ^ y Power
Comparisons Description
x == y Equals
x < y Less than
x <= y Less than or equal to
x > y Greater than
x >= y Greater than or equal to
x ~= y Regular expression match
x in (a, b, c) Equivalent to (x == a or x == b or x == c)
x not in (a, b, c) Equivalent to (x != a and x != b and x != c)
Boolean logic Description
x or y Boolean or
x and y Boolean and
not x Boolean not
x ? y : z If boolean x, value y, else z
( x ) Explicity operator precedence
Built-in functions Description
abs(x) Absolute value
ceil(x) Round floating point up
floor(x) Round floating point down
log(x) Natural logarithm
max(a, b, c...) Max value (variable length of args)
min(a, b, c...) Min value (variable length of args)
random() Random floating point from 0.0 to 1.0
round(x) Round floating point
sqrt(x) Square root

Operator precedence follows that of any sane language.

Adding custom functions

When integrating in to your application, you can add your own custom functions.

// Custom function: Return string length.
function strlen(s) {
  return s.length;
}

// Compile expression to executable function
var myfilter = compileExpression(
                    'strlen(firstname) > 5',
                    {strlen:strlen}); // custom functions

myfilter({firstname:'Joe'});    // returns 0
myfilter({firstname:'Joseph'}); // returns 1

FAQ

Why the name?

Because it was originally built for FILTeR EXpressions.

What's Jison?

Jison is bundled with Filtrex – it's a JavaScript parser generator that does the underlying hard work of understanding the expression. It's based on Flex and Bison.

License?

MIT

Unit tests?

Here: Source, Results

What happens if the expression is malformed?

Calling compileExpression() with a malformed expression will throw an exception. You can catch that and display feedback to the user. A good UI pattern is to attempt to compile on each keystroke and continuously indicate whether the expression is valid.

Contributors

  • @joewalnes Joe Walnes – the author of this repository
  • @msantos Michael Santos – quoted symbols, regex matches and numerous fixes
  • @alexgorbatchev Alex Gorbatchev – NPM package and housekeeping
  • @m93a Michal Grňo – critical fixes of security bug

Like this? Want other thingies?

  • websocketd – Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets.
  • ReconnectingWebSocket – Simplest way to add some robustness to your WebSocket connections.
  • Smoothie Charts – JavaScript charts for streaming data.
  • Visit The Igloo Lab to see and subscribe to other thingies I make.

And follow @joewalnes!

More Repositories

1

websocketd

Turn any program that uses STDIN/STDOUT into a WebSocket server. Like inetd, but for WebSockets.
Go
17,086
star
2

reconnecting-websocket

A small decorator for the JavaScript WebSocket API that automatically reconnects
JavaScript
4,168
star
3

smoothie

Smoothie Charts: smooooooth JavaScript charts for realtime streaming data
JavaScript
2,230
star
4

web-vmstats

Prettify vmstats in your browser
JavaScript
1,009
star
5

gcode-viewer

A web-based 3D GCode viewer to help understand 3D printer models.
JavaScript
246
star
6

jstinytest

Tiniest simplest unit testing library for JavaScript
JavaScript
204
star
7

greendots

Write with those green dots on your GitHub profile
Python
184
star
8

tinytest

A tiny unit-testing framework for C
C
170
star
9

jquery-simple-context-menu

A really simple, good looking jQuery context menu
JavaScript
102
star
10

port-sharding

Example of Linux SO_REUSEPORT
Python
90
star
11

go-getter

Like 'go get' but with pinned package versions. A tiny shell script.
Shell
86
star
12

toybrick

OpenSCAD program to generate toy bricks compatible with existing systems
OpenSCAD
85
star
13

node-ldapauth

LDAP authentication library for Node.JS
C++
69
star
14

resisto.rs

No frills resistor color code tool
HTML
67
star
15

webconnect

JavaScript APIs to allow web-apps to connect to hardware devices.
JavaScript
52
star
16

pi-crust

Connect things to your Raspberry Pi
Eagle
47
star
17

idea-community

IntelliJ IDEA Community edition - my hacks
Java
33
star
18

crunchicorn

Simplifying the web toolchain
JavaScript
32
star
19

verifysignature

Sample of standalone portable C to verify Ed25519 public-key signature
C
21
star
20

hackerspace-globe

Mashup: View HackerSpace status on a WebGL Globe
JavaScript
14
star
21

raspberry-play

Playing with the Raspberry Pi
JavaScript
14
star
22

quick2wire-fritzomatic

A tool to quickly generate Fritzing components.
JavaScript
9
star
23

flashprance

A lightweight communication protocol to send data from your computer/phone to an embedded device by flashing the screen
C++
9
star
24

arduino-play

Playing with Arduino and AVR hardware
C
7
star
25

webbit-easyremote

Simple bidirectional JavaServer<->JavaScriptBrowser remoting, based on WebSockets and Webbit
JavaScript
6
star
26

webbit

Webbit Server: Moved....
5
star
27

webbit-asyncio

Event based asynchronous Java IO library - built on libeio
C
5
star
28

msp430-shiftbrite

C / C++ library to allow MSP430 microcontroller to talk to ShiftBrite RGB module
C++
5
star
29

esper-console

Web based Esper console
JavaScript
3
star
30

thor-gui

A web based GUI for Thor
JavaScript
2
star
31

3d-printing

Thingies I've designed for 3D printing
2
star
32

webbit-sitemesh

SiteMesh 3 for Webbit
Java
2
star
33

graphviz2

Joe's modifications to AT&T's GraphViz/Dot
C
2
star
34

c-stuff

C
1
star
35

vim

.vim
Vim Script
1
star
36

pi-plate-clip

Makes the Adafruit's Raspberry Pi Plate just a liiiiittle bit stronger.
1
star
37

openscad-tutorial

A tutorial for OpenSCAD.
1
star
38

test

1
star
39

sitemesh-resources

Additional resources to support SiteMesh project.
1
star
40

domain-watcher

Watches a domain name and notifies me when it's status changes
1
star
41

msp430-rgb-color-cycle

A quick cheap circuit for color cycling an RGB LED using an MSP430 microcontroller.
1
star
42

atx-psu-breakout

Fork of the ATX PSU breakout board from Dangerous Prototypes.
1
star