JavaScript implementation of the JSONata query and transformation language.
npm install jsonata
In Node.js:
var jsonata = require("jsonata"); var data = { example: [ {value: 4}, {value: 7}, {value: 13} ] }; var expression = jsonata("$sum(example.value)"); var result = expression.evaluate(data); // returns 24In a browser:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JSONata test</title> <script src="lib/jsonata.js"></script> <script> function greeting() { var json = JSON.parse(document.getElementById('json').value); var result = jsonata('"Hello, " & name').evaluate(json); document.getElementById('greeting').innerHTML = result; } </script> </head> <body> <textarea id="json">{ "name": "Wilbur" }</textarea> <button onclick="greeting()">Click me</button> <p id="greeting"></p> </body> </html>jsonata uses ES2015 features such as generators. For browsers lacking these features, lib/jsonata-es5.js is provided.
Parse a string str as a JSONata expression and return a compiled JSONata expression object.
var expression = jsonata("$sum(example.value)");If the expression is not valid JSONata, an Error is thrown containing information about the nature of the syntax error, for example:
{ code: "S0202", stack: "...", position: 16, token: "}", value: "]", message: "Syntax error: expected ']' got '}'" } expression has three methods:
Run the compiled JSONata expression against object input and return the result as a new object.
var result = expression.evaluate({example: [{value: 4}, {value: 7}, {value: 13}]});input should be a JavaScript value such as would be returned from JSON.parse(). If input could not have been parsed from a JSON string (is circular, contains functions, ...), evaluate's behaviour is not defined. result is a new JavaScript value suitable for JSON.stringify()ing.
bindings, if present, contains variable names and values (including functions) to be bound:
jsonata("$a + $b()").evaluate({}, {a: 4, b: () => 78}); // returns 82expression.evaluate() may throw a run-time Error:
var expression = jsonata("$notafunction()"); // OK, valid JSONata expression.evaluate({}); // ThrowsThe Error contains information about the nature of the run-time error, for example:
{ code: "T1006", stack: "...", position: 14, token: "notafunction", message: "Attempted to invoke a non-function" } If callback(err, value) is supplied, expression.evaluate() returns undefined, the expression is run asynchronously and the Error or result is passed to callback.
jsonata("7 + 12").evaluate({}, {}, (error, result) => { if(error) { console.error(error); return; } console.log("Finished with", result); }); console.log("Started"); // Prints "Started", then "Finished with 19"Permanently binds a value to a name in the expression, similar to how bindings worked above. Modifies expression in place and returns undefined. Useful in a JSONata expression factory.
var expression = jsonata("$a + $b()"); expression.assign("a", 4); expression.assign("b", () => 1); expression.evaluate({}); // 5Note that the bindings argument in the expression.evaluate() call clobbers these values:
expression.evaluate({}, {a: 109}); // 110Permanently binds a function to a name in the expression.
var expression = jsonata("$greet()"); expression.registerFunction("greet", () => "Hello world"); expression.evaluate({}); // "Hello world"You can do this using expression.assign or bindings in expression.evaluate, but expression.registerFunction allows you to specify a function signature. This is a terse string which tells JSONata the expected input argument types and return value type of the function. JSONata raises a run-time error if the actual input argument types do not match (the return value type is not checked yet).
var expression = jsonata("$add(61, 10005)"); expression.registerFunction("add", (a, b) => a + b, "<nn:n>"); expression.evaluate({}); // 10066Function signatures are specified like so:
A function signature is a string of the form <params:return>. params is a sequence of type symbols, each one representing an input argument's type. return is a single type symbol representing the return value type.
Type symbols work as follows:
Simple types:
b- Booleann- numbers- stringl-null
Complex types:
a- arrayo- objectf- function
Union types:
(sao)- string, array or object(o)- same asou- equivalent to(bnsl)i.e. Boolean, number, string ornullj- any JSON type. Equivalent to(bnsloa)i.e. Boolean, number, string,null, object or array, but not functionx- any type. Equivalent to(bnsloaf)
Parametrised types:
a<s>- array of stringsa<x>- array of values of any type
Some examples of signatures of built-in JSONata functions:
$counthas signature<a:n>; it accepts an array and returns a number.$appendhas signature<aa:a>; it accepts two arrays and returns an array.$sumhas signature<a<n>:n>; it accepts an array of numbers and returns a number.$reducehas signature<fa<j>:j>; it accepts a reducer functionfand ana<j>(array of JSON objects) and returns a JSON object.
Each type symbol may also have options applied.
+- one or more arguments of this type- E.g.
$ziphas signature<a+>; it accepts one array, or two arrays, or three arrays, or...
- E.g.
?- optional argument- E.g.
$joinhas signature<a<s>s?:s>; it accepts an array of strings and an optional joiner string which defaults to the empty string. It returns a string.
- E.g.
-- if this argument is missing, use the context value ("focus").- E.g.
$lengthhas signature<s-:n>; it can be called as$length(OrderID)(one argument) but equivalently asOrderID.$length().
- E.g.
- JSONata language documentation
- JSONata tech talk
See the CONTRIBUTING.md for details of how to contribute to this repo.
