MacroHealth Internal

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()