Shovel Expression Language Standard Library
The Shovel Expression Language Standard Library enumerates the functions and effects known to the Shovel Expression Interpreter.
Constants
Function | Effect |
---|---|
true | Boolean True |
false | Boolean False |
null | JSON Null |
emptyJsonObject | {} |
emptyJsonArray | [] |
Functions
Function | Effect | Syntax | Parameters | Return Value | Runtime Errors |
---|---|---|---|---|---|
if | Implementation of the if/then/else construction as a shovel function | if(condition, ifTrue, ifFalse) | condition - The boolean expression to evaluate ifTrue - The expression returned if condition is true ifFalse - The expression returned if condition is false | The ifTrue argument if condition evaluates to true or the ifFalse argument if condition evaluates to false | |
isNull | Evaluates to a boolean based on whether the argument is null | isNull(val) | val - some value | True if val is null, false otherwise. | |
eqString | Evaluates to a boolean value based on equivalence of the values of the left and the right strings. To be used for string types only. | eqString(lhs, rhs) | lhs - left string rhs - right string | True if lhs argument and rhs arguments have equal values or false otherwise. | |
eqNumber | Evaluates to a boolean value based on equivalence of the values of the left and the right numbers. To be used for number types only. | eqNumber(lhs, rhs) | lhs - left number rhs - right number | True if lhs argument and rhs arguments have equal values or false otherwise. | |
lt | Evaluates to a boolean value based on the value of the left operand being less than the value of the right operand. Works for numeric types only. | lt(lhs, rhs) | lhs - left operand rhs - right operand | True if value of lhs operand is less than the value of rhs or false otherwise. | |
gt | Evaluates to a boolean value based on the value of the left operand being greater than the value of the right operand. Works for numeric types only. | gt(lhs, rhs) | lhs - left operand rhs - right operand | True if value of lhs operand is greater than the value of rhs or false otherwise. | |
le | Evaluates to a boolean value based on the value of the left operand being less than or equal to the value of the right operand. Works for numeric types only. | le(lhs, rhs) | lhs - left operand rhs - right operand | True if value of lhs operand is less than or equal to the value of rhs or false otherwise. | |
ge | Evaluates to a boolean value based on the value of the left operand being greater than or equal to the value of the right operand. Works for numeric types only. | ge(lhs, rhs) | lhs - left operand rhs - right operand | True if value of lhs operand is greater than or equal to the value of rhs or false otherwise. | |
and | Implements the boolean and operation. | and(lhs, rhs) | lhs - left operand rhs - right operand | True if both lhs and rhs are true | |
or | Implements the boolean or operation. | or(lhs, rhs) | lhs - left operand rhs - right operand | True if either lhs and rhs are true. | |
xor | Implements the boolean exclusive or operation. | xor(lhs, rhs) | lhs - left operand rhs - right operand | True if one argument is true and the other is false. | |
not | Implements boolean negation | not(op1) | op1 - Singular boolean argument | True if op1 is false False if op1 is true | |
startsWith | Evaluates to a boolean value if a string starts with a given prefix. Works for string types only. | startsWith(string, prefix) | string - the string to check against prefix - the prefix to be looked up in the string | True if string starts with the given prefix or false otherwise. | |
endsWith | Evaluates to a boolean value if a string ends with a given suffix. Works for string types only. | endsWith(string, suffix) | string - the string to check against suffix - the suffix to be looked up in the string | True if string ends with the given suffix or false otherwise. Works for string types only. | |
contains | Evaluates to a boolean value if a string contains the given sequence of characters. Works for string types only. | contains(string, seq) | string - the string to check against seq - the sequence of characters to be looked up in the string | True if string contains the given sequence of characters or false otherwise. Works for string types only. | |
getElemAt | Evaluates to a single field array element, within an array, at the specified element index. Works for array types only. | getElemAt(arr, idx) //where arr == atField(fieldReference, expression) | arr - evaluated field reference to an array idx - the index of the array element to be returned | Returns the array element found | |
size | Evaluates to an integer value representing the size of an array. Works for array types only. | size(arr) //where arr == atField(fieldReference, expression) | arr - evaluated field reference to an array | Returns the size of the array as an Int | |
sum | Sums the passed-in list of int/decimal values. Nulls are treated as 0. | sum(arr) // where arr == readField(...) | arr - evaluated field reference to an array | Returns the sum of the array as int if all elements are ints, or as decimal if at least one element is decimal | |
add | Adds the two provided values. | add(a, b) // where a and b are both numeric | a, b - Numerics (both int and decimal are valid) either bare or as a string (e.g. 3.14 or “3.14” are equally valid) | Returns a+b | |
subtract | Subtracts the two provided values. | subtract(a, b) // where a and b are both numeric | a, b - Numerics (both int and decimal are valid) either bare or as a string (e.g. 3.14 or “3.14” are equally valid) | Returns a-b | |
multiply | Multiplies the two provided values. | multiply(a, b) // where a and b are both numeric | a, b - Numerics (both int and decimal are valid) either bare or as a string (e.g. 3.14 or “3.14” are equally valid) | Returns a*b | |
divide | Divides the two provided values. | divide(a, b) // where a and b are both numeric | a, b - Numerics (both int and decimal are valid) either bare or as a string (e.g. 3.14 or “3.14” are equally valid) | Returns a/b. Error if b is zero. | |
floor | Truncates a decimal value to significant digits. | floor(a, b) // where a is a decimal, b is an integer | a - Decimal either bare or as a string (e.g. 3.14 or “3.14” are equally valid) b - Integer either bare or as a string (e.g. 3 or “3” are equally valid) | Returns a truncated with b number of significant digits | |
round | Rounds a decimal value to significant digits. 0-4 down, 5-9 up | round(a, b) // where a is a decimal, b is an integer | a - Decimal either bare or as a string (e.g. 3.14 or “3.14” are equally valid) b - Integer either bare or as a string (e.g. 3 or “3” are equally valid) | Returns a rounded with b number of significant digits | |
strSHA256 | Hashes a String using SHA-256. The same string will always have the same hash code. The hash code cannot be “de-hashed” to return the original string. | strSHA256(str) // where str is a String | str - String that needs to be hashed | Returns the 256 bit hash code of the string. | |
getContext | Returns the current runtime context. May be modified by use of atField. | getContext() | None | Returns the current runtime context. By default, this is the entire standard runtime, including all documents. This may be modified by nesting the call to getContext inside of atField. | |
identity | Returns its single argument without modification. | identity(a) | a - A value to return | The argument a, unchanged. | |
atFieldRead | Evaluates the provided expression with the context document shifted to the requested field. References to getContext() within expression will see the context from the perspective of that field. | atField(fieldReference, expression) | fieldReference - The field to shift the document context down into. use getField to produce a value appropriate for this parameter. expression - The expression to evaluate with the context shifted to the requested field | The expression, wrapped as appropriate for the requested field: If the field involves object key navigation (almost all fields do), the expression will not be evaluated if no such key exists. Instead, atFieldRead will return JSON Null. If the field involves array traversal, the expression will be evaluated multiple times, once for each element in the array. atFieldRead will in this case return an array containing each evaluation. If the field involves nested arrays, atFieldRead will, in turn, return nested arrays. | UnknownField - If the requested field is not known to the runtime system. (It is not an error for a field to be known to the runtime, but not present in the document.) |
atFieldModify | Returns the document context modified by replacing the requested field by the provided expression. References to getContext() within expression will see the context from the perspective of that field.Note that this does not modify the context in place. atFieldModify only returns a new, modified context. | atFieldModify(fieldReference, expression) | fieldReference - The field to shift the document context down into. use getField to produce a value appropriate for this parameter. expression - The expression to replace the value at the specified field with. | The document context, modified by replacing the specified field with the expression. If the field does not exist, the document context is returned unchanged. | UnknownField - If the requested field is not known to the runtime system. (It is not an error for a field to be known to the runtime, but not present in the document.) |
atFieldZip | Returns the document context modified by combining the values referenced by the field reference to the values returned by the array expression using the combine expression. The array expression must contain at least as many values as referenced by the field reference with one exception. If the array expression returns an array with one element, the values referenced by the field reference will all be mapped to the single value returned by the array expression. References to getContext() within either expression will see the context from the perspective of that field. References to zipVal() are only allowed within the combine expression and will return the value at the current index into the array from the array expression. Note that this does not modify the context in place. atFieldZip only returns a new, modified context. | atFieldZip(fieldReference, arrayExpression, combineExpression) | fieldReference - The field to shift the document context down into. use getField to produce a value appropriate for this parameter. arrayExpression - An expression which evaluates to a list of JSON combineExpression - an expression which may make use of the current value getContext() and the current value from arrayExpression zipVal(), the result of this expression will go into the current index into the fieldReference | The document context, modified by zipping the results of the expression into the field reference using the combine expression. If the field does not exist, the document context is returned unchanged. | |
zipVal | Companion to atFieldZip, returns the current value from the source array within an atFieldZip expression. This expression may not be used in any other context. | The current value being applied within the atFieldZip expression If not being used in the right context, an error is returned. | |||
readField | Reads the requested field and returns it, preserving any intermediate arrays. | readField(fieldReference) | fieldReference - The field to retrieve from the document context | The requested field, preserving any intermediate arrays. If the field cannot be found, null will be returned instead where the field searching failed. For fields within arrays, this decision is made for each element, so if an array contains some objects with matching keys and some without, the elements for which there were no matching keys would contain null. Finding the field can also fail if the field indicates an array traversal flagged to only return one value. Such traversals are treated in the same manner as object keys that are missing, and so null will be substituted instead. | |
readFieldOrElse | Reads the requested field and returns it, preserving any intermediate arrays. Unlike readField, readFieldOrElse allows the caller to choose the default value to return. | readFieldOrElse(fieldReference, defaultValue) | fieldReference - The field to retrieve from the document context defaultValue - The value to return if a key is missing from an object that the field required, or if an array has no elements matching an array traversal, but the field indicated that there must be one matching value. | The requested field, preserving any intermediate arrays. If the field cannot be found, defaultValue will be returned instead where the field searching failed. For fields within arrays, this decision is made for each element, so if an array contains some objects with matching keys and some without, the elements for which there were no matching keys would contain defaultValue. Finding the field can also fail if the field indicates an array traversal flagged to only return one value. Such traversals are treated in the same manner as object keys that are missing, and so defaultValue will be substituted instead. | |
upsertJsonKey | Puts or updates a key/value pair in a JSON object. | upsertJsonKey(jsonObject, key, value) | jsonObject: JSON - JSON object to insert the key and value into key: String - the key value: JSON - the value | Returns the jsonObject modified such that the key now has the specified value. overwrites if the key is present in the context. | jsonObject cannot be interpreted as a JSON objectkey cannot be coerced into a string |
removeJsonKey | Removes a JSON object by key. | removeJsonKey(jsonObject, key) | jsonObject: JSON- JSON object with the key to remove key: String - the key of the object | Returns the jsonObject modified such that the JSON object with that key is removed. If key is not present, the jsonObject is returned. | jsonObject cannot be interpreted as a JSON object key cannot be coerced into a string |
insertIntoArray | Inserts an element at a specific position in the JSON array located at the current context. Requires the current document context to be a JSON array. | insertIntoArray(contextObject, index, value) | contextObject: JSON - JSON object to insert the key and value into index: Int - the index to insert the value at. Supports negative indexing. Out of bounds indexes will result in the value being either prepended (negative index) or appended (positive index) value: JSON - the value | Returns the context with the value added to the array at the specified index. | Context cannot be interpreted as an array Index cannot be coerced to an integer |
insertIntoLoop | Inserts an X12 object (segment or loop) into the target array. Requires that the value as well as all elements in the target array contain a position key that maps to an integer. | insertIntoLoop(targetArray, value) | targetArray: JSON - the JSON Array of an X12 Loop value: JSON - the X12 Value, either a Loop or a Segment | Returns the target array with the value added to the array such that the elements in the array are sorted in increasing order of position. | Context cannot be interpreted as an array Value or element in the target array do not have a key/value pair forposition |
batchInsertIntoLoop | Inserts N X12 objects (segments or loops) into the target array. Requires that the values as well as all elements in the target array contain a position key that maps to an integer. Effectively identical to insertIntoLoop but it supports an array of values, instead of a single. At the moment it’s expected that ALL elements in the values array have the same position value. | batchInsertIntoLoop(targetArray, values) | targetArray: JSON - the JSON Array of an X12 Loop values: JSON - list of X12 Values, either Loops or Segments | Returns the target array with the values added to the array such that the elements in the array are sorted in increasing order of position. | Context cannot be interpreted as an array Value or element in the target array do not have a key/value pair forposition |
dataFromStr | Convenience function. Receives a string and parses to JSON, throwing an exception if the string doesn’t represent valid JSON. Primary use will likely be adding entire loops/segments that aren’t present elsewhere in the doc to copy from. | dataFromStr(string) | string - The string to parse as JSON (both {} and [] work) | JSON that’s ready to be consumed by other Shovel functions. e.g. upsertJsonKey(dataFromStr(...), "foo", "bar") | If the value does not represent JSON as a string. |
concat | Concatenate two strings. Will coerce scalar JSON values (Null, Boolean, or Number) to String if required. | concat(first, second) | first - The first string to concatenate second - The second string to concatenate | The first and second strings, concatenated. | If first or second cannot be coerced to a string. |
formatDateTime | Function that formats a timestamp in milliseconds into a specified format in the timezone specified by the third argument. Uses DateTimeFormatter.ofPattern and ZoneId.of | formatDateTime(timestamp, format, timezone) | timestamp - The time to format, as milliseconds since epoch, UTC format - A format specification (see DateTimeFormatter.ofPattern) to use to format the timestamp timezone - The timezone in which to display the time in a format valid to ZoneId.of (Prefer region-based zone IDs like America/Vancouver to specific zones like PST as the region-based zone IDs will adjust for Daylight Saving Time.) | A formatted time as a JSON String | generic - If given an invalid format or timezone |
createDateTime | Creates a timestamp in milliseconds from a specified string with a given format in the timezone specified by the third argument. Uses DateTimeFormatterBuilder.appendPattern and ZoneId.of | createDateTime(stringDate, format, timezone) | stringDate - A string representing the date. I.e. 2021-03-31 format - A format specification (see DateTimeFormatterBuilder.appendPattern) to use to format the timestamp timezone - The timezone in which to display the time in a format valid to ZoneId.of (Prefer region-based zone IDs like America/Vancouver to specific zones like PST as the region-based zone IDs will adjust for Daylight Saving Time.) | The current time in the UTC timezone, measured as milliseconds since epoch. | generic - If given an invalid format or timezone |
dateTimePlus | Adds an amount to the first argument (a timestamp in milliseconds) with amount being specified in the second argument and a temporal unit in the third argument in the timezone specified by the fourth argument. Uses ChronoUnit.valueOf and ZoneId.of | dateTimePlus(timestamp, amount, temporalUnit, timezone) | timestamp - The time to format, as milliseconds since epoch, UTC amount - A long representing the amount to be added temporalUnit - The unit of time to be added (days, months, etc.) as in ChronoUnit.valueOf timezone - The timezone in which to display the time in a format valid to ZoneId.of (Prefer region-based zone IDs like America/Vancouver to specific zones like PST as the region-based zone IDs will adjust for Daylight Saving Time.) | The current time in the UTC timezone, measured as milliseconds since epoch. | generic - If given an invalid format or timezone |
leftString | Returns a sub string consisting of a specified number of leading characters | leftString(string, num) | string - the string to sub string num - the number of leading characters of string to return | String, containing num leading characters. | |
rightString | Returns a sub string consisting of a specified number of trailing characters | rightString(string, num) | string - the string to sub string num - the number of trailing characters of string to return | String, containing num trailing characters. | |
stringReplace | Returns a string after replacing one set of characters with another | stringReplace(string, regex, replacement) | string - the string to operate on regex - the pattern to replace. Note that only the first incident (from left to right) will be replacedre placement - the string to put in place of the characters matched | String, with the replacement done (if a match was found) or unchanged (if no match was found) | |
subString | Returns a sub string, specified by the start and end indices. NOTE THE FOLLOWING ASSUMPTIONS MADE: empty string in → empty string out startIndex > length or < 0 → startIndex = 0 endIndex > length or < startIndex → endIndex = length This means that if you pass invalid indices, you may get the whole string back.We opted to make these assumptions rather than outright failing, so the flow designer can determine what action to take if the output value doesn’t match what was expected. | subString(string, startIndex, endIndex) | string - the string to sub stringstart Index - 0-based index of the first character (inclusive)end Index - 0-based index of the last character (exclusive) | Subset of the original string, as defined by startIndex and endIndex. Note the details in the description above for behaviour in non-happy-path scenarios (e.g. invalid indices). | |
anyOf | Returns true if any of the elements in an array is true, else false | anyOf(array) | array - boolean array | boolean. | |
allOf | Returns true if all of the elements in an array are true, else false | allOf(array) | array - boolean array | boolean. | |
in | Returns true if value is an element of an array | in(value, array) | value - value to check array - array where to check | boolean. |
Effects
Effects are requests of the outside world to provide information not immediately available to the runtime.
Effects may not declare parameters.
Function | Syntax | Return Value |
---|---|---|
currentTime | currentTime() | The current time in the UTC timezone, measured as milliseconds since epoch. |
randomUUID | randomUUID() | A new random UUID as generated by java.util.UUID.randomUUID() |