Evaluate Expressions
The evaluate expression language allows for data set interaction using custom JavaScript expressions within a crul query. The evaluate command can operate as --type
reducing
or mapping
. For performance reasons, it is best to utilize the default reducing
type. When reducing
, the expression will operate on the entire result set at once, while when mapping
, will operate on the result set one row at a time. The expression will operate in a sandboxed headless browser tab, which has overhead of a new tab per row when operating as a mapping
stage.
The expression language is used with the evaluate
command, as well as in other browser related commands which accept an --expression
flag or argument (see navigate
, open
, etc.).
Expression format​
The evaluate expression format is straightforward. It follows the general pattern for a JavaScript arrow function expression: () => {}
.
evaluate "() => ({date: Date.now()})"
In order to operate on data from the previous stage, you will need to include data
as an argument to the expression: (data) => { return data.length }
devices
|| evaluate "(data) => data.filter(item => item.name.indexOf('iPhone') !== -1)"
In order to include available runtime libraries (outlined below), you will need to add a flag for the library, and an object as the last argument of the expression containing the library name: (data, { _ }) => { ... }
devices
|| evaluate "(data) => _.sampleSize(data, 10)" --lodash
Return format​
crul will transform the output of the evaluate expression into rows. If you return a string/boolean, you will get back a single row containing the response in a column named content
. To return rows, your expression should return an array of objects [{ key: "value1" }, { key: "value2" }]
. The previous return wil create two rows, with a single key
column.
Syntax highlighting​
In order to enable JavaScript syntax highlighting in the crul web query interface, you will need to use the ```javascript () => {}```
syntax around your expression.
devices
|| evaluate ```javascript
(data) => data
```
Advanced features​
The evaluate runtime has access to the following libraries: lodash
, mathjs
, and faker
. You can include each library in the runtime by providing a --lodash
, --mathjs
, or --faker
flag to the evaluate
command.
lodash​
You can use the lodash
library for common data manipulation tasks.
devices
/* sort by viewport.deviceScaleFactor in descending order and by name in ascending order */
|| evaluate "(data) => _.orderBy(data, ['viewport.deviceScaleFactor', 'name'], ['desc', 'asc'])"
--lodash
mathjs​
You can use the mathjs
library for more advanced mathematical expressions than possible through the basic math
command.
devices
|| evaluate "(data, { mathjs }) => {
/* get all the device scale factor values */
const scaleFactors = data.map(item=>item.viewport.deviceScaleFactor);
/* get the std deviation of all scale factors */
return {
standardDeviation: mathjs.std(scaleFactors)
}
}
"
--mathjs
faker​
You can use the faker
library for data set generation.
evaluate ```javascript (data, {faker}) => {
return { "uuid": faker.datatype.uuid() }
}``` --faker