Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
#### 2.1.0 Milestone Release

- New syntax (`?:` default operator) supports fallback to RHS if the LHS is Boolean equivalent to false (PR #784)
- New syntax (`??` coalescing operator) supports fallback to RHS if the LHS is non-existent (PR #784)
- Improve regex generation for DateTime parser (PR #728)
- Truncate fractional part of numeric argument of `$pad` function (PR #729)
- Await array elements (PR #747)
- Various documentation fixes and improvements

#### 2.0.6 Maintenance Release

- Protect __evaluate_entry and __evaluate_exit callbacks (PR #700)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jsonata",
"version": "2.0.6",
"version": "2.1.0",
"description": "JSON query and transformation language",
"module": "jsonata.js",
"main": "jsonata.js",
Expand Down
106 changes: 106 additions & 0 deletions website/versioned_docs/version-2.1.0/construction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
id: version-2.1.0-construction
title: Building result structures
sidebar_label: Result Structures
original_id: construction
---

So far, we have discovered how to extract values from a JSON document, and how to manipulate the data using numeric, string and other operators. It is useful to be able to specify how this processed data is presented in the output.

## Array constructors

As previously observed, when a location path matches multiple values in the input document, these values are returned as an array. The values might be objects or arrays, and as such will have their own structure, but the _matched values_ themselves are at the top level in the resultant array.

It is possible to build extra structure into the resultant array by specifying the construction of arrays (or [objects](#object-constructors)) within the location path expression. At any point in a location path where a field reference is expected, a pair of square brackets `[]` can be inserted to specify that the results of the expression within those brackets should be contained within a new array in the output. Commas are used to separate multiple expressions within the array constructor.

Array constructors can also be used within location paths for making multiple selections without the broad brush use of wildcards.

__Examples__

- The four email addresses are returned in a flat array.
<div class="jsonata-ex">
<div>Email.address</div>
<div>[
"[email protected]",
"[email protected]",
"[email protected]",
"[email protected]"
]</div>
</div>

- Each email object generates an array of addresses.
<div class="jsonata-ex">
<div>Email.[address]</div>
<div>[
[ "[email protected]", "[email protected]" ],
[ "[email protected]", "[email protected]" ]
]</div>
</div>

- Selects the `City` value of both `Address` and `Alternative.Address` objects.
<div class="jsonata-ex">
<div>[Address, Other.`Alternative.Address`].City</div>
<div>[ "Winchester", "London" ]</div>
</div>

## Object constructors

In a similar manner to the way arrays can be constructed, JSON objects can also be constructed in the output. At any point in a location path where a field reference is expected, a pair of braces `{}` containing key/value pairs separated by commas, with each key and value separated by a colon: `{key1: value1, key2:value2}`. The keys and values can either be literals or can be expressions. The key must either be a string or an expression that evaluates to a string.

When an object constructor follows an expression that selects multiple values, the object constructor will create a single object that contains a key/value pair for each of those context values. If an array of objects is required (one for each context value), then the object constructor should immediately follow the dot '.' operator.

__Examples__

- Produces an array of objects (one for each phone).
<div class="jsonata-ex">
<div>Phone.{type: number}</div>
<div>[
{ "home": "0203 544 1234" },
{ "office": "01962 001234" },
{ "office": "01962 001235" },
{ "mobile": "077 7700 1234" }
]</div>
</div>

- Combines the key/value pairs into a single object. See [Grouping using object key expression](sorting-grouping.md) for more details.
<div class="jsonata-ex">
<div>Phone{type: number}</div>
<div>{
"home": "0203 544 1234",
"office": [
"01962 001234",
"01962 001235"
],
"mobile": "077 7700 1234"
}</div>
</div>

- Combines the key/value pairs into a single object. In this case, for consistency, all numbers are grouped into arrays. See [Singleton array and value equivalence](predicate.md#singleton-array-and-value-equivalence) for more details.
<div class="jsonata-ex">
<div>Phone{type: number[]}</div>
<div>{
"home": [
"0203 544 1234"
],
"office": [
"01962 001234",
"01962 001235"
],
"mobile": [
"077 7700 1234"
]
}</div>
</div>


## JSON literals

The array and object constructors use the standard JSON syntax for JSON arrays and JSON objects. In addition to this values of the other JSON data types can be entered into an expression using their native JSON syntax:
- strings - `"hello world"`
- numbers - `34.5`
- Booleans - `true` or `false`
- nulls - `null`
- objects - `{"key1": "value1", "key2": "value2"}`
- arrays - `["value1", "value2"]`

__JSONata is a superset of JSON.__ This means that any valid JSON document is also a valid JSONata expression. This property allows you to use a JSON document as a template for the desired output, and then replace parts of it with expressions to insert data into the output from the input document.
175 changes: 175 additions & 0 deletions website/versioned_docs/version-2.1.0/embedding-extending.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
---
id: version-2.1.0-embedding-extending
title: Embedding and Extending JSONata
sidebar_label: Embedding and Extending JSONata
original_id: embedding-extending
---

## API

### jsonata(str)

Parse a string `str` as a JSONata expression and return a compiled JSONata expression object.

```javascript
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:

### expression.evaluate(input[, bindings[, callback]])

Run the compiled JSONata expression against object `input` and return the result as a new object.

```javascript
var result = await 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, contain variable names and values (including functions) to be bound:

```javascript
await jsonata("$a + $b()").evaluate({}, {a: 4, b: () => 78});
// returns 82
```

`expression.evaluate()` may throw a run-time `Error`:

```javascript
var expression = jsonata("$notafunction()"); // OK, valid JSONata
await expression.evaluate({}); // Throws
```

The `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`.

```javascript
await 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"
```

### expression.assign(name, value)

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.

```javascript
var expression = jsonata("$a + $b()");
expression.assign("a", 4);
expression.assign("b", () => 1);

await expression.evaluate({}); // 5
```

Note that the `bindings` argument in the `expression.evaluate()` call clobbers these values:

```javascript
await expression.evaluate({}, {a: 109}); // 110
```

### expression.registerFunction(name, implementation[, signature])

Permanently binds a function to a name in the expression.

```javascript
var expression = jsonata("$greet()");
expression.registerFunction("greet", () => "Hello world");

await 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).

```javascript
var expression = jsonata("$add(61, 10005)");
expression.registerFunction("add", (a, b) => a + b, "<nn:n>");

await expression.evaluate({}); // 10066
```

### Function signature syntax

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` - Boolean
- `n` - number
- `s` - string
- `l` - `null`

Complex types:

- `a` - array
- `o` - object
- `f` - function

Union types:

- `(sao)` - string, array or object
- `(o)` - same as `o`
- `u` - equivalent to `(bnsl)` i.e. Boolean, number, string or `null`
- `j` - any JSON type. Equivalent to `(bnsloa)` i.e. Boolean, number, string, `null`, object or array, but not function
- `x` - any type. Equivalent to `(bnsloaf)`

Parametrised types:

- `a<s>` - array of strings
- `a<x>` - array of values of any type

Some examples of signatures of built-in JSONata functions:

- `$count` has signature `<a:n>`; it accepts an array and returns a number.
- `$append` has signature `<aa:a>`; it accepts two arrays and returns an array.
- `$sum` has signature `<a<n>:n>`; it accepts an array of numbers and returns a number.
- `$reduce` has signature `<fa<j>:j>`; it accepts a reducer function `f` and an `a<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. `$zip` has signature `<a+>`; it accepts one array, or two arrays, or three arrays, or...
- `?` - optional argument
- E.g. `$join` has 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.
- `-` - if this argument is missing, use the context value ("focus").
- E.g. `$length` has signature `<s-:n>`; it can be called as `$length(OrderID)` (one argument) but equivalently as `OrderID.$length()`.

### Writing higher-order function extensions

It is possible to write an extension function that takes one or more functions in its list of arguments and/or returns
a function as its return value.


Loading