Skip to main content

Workflow Engine Operators

Blink’s expressions language is based on expr library. Anything supported by expr also works in Blink.

Expr package uses a specific syntax. In this document, you can find all supported syntaxes.

Supported literals

The package supports:

  • strings - single and double quotes (e.g. "hello", 'hello')
  • numbers - e.g. 103, 2.5, .5
  • arrays - e.g. [1, 2, 3]
  • maps - e.g. {foo: "bar"}
  • booleans - true and false
  • nil - nil

Digit separators

Integer literals may contain digit separators to allow digit grouping into more legible forms.

Example:

10_000_000_000

Accessing public properties

Public properties on structs can be accessed by using the . syntax. If you pass an array into an expression, use the [] syntax to access array keys.

foo.Array[0].Value;

Functions and methods

Functions may be called using () syntax. The . syntax can also be used to call methods on an struct.

price.String();

Supported operators

The package comes with a lot of operators:

Arithmetic operators

  • + (addition)
  • - (subtraction)
  • * (multiplication)
  • / (division)
  • % (modulus)
  • ** (pow)

Example:

life + universe + everything;

Comparison operators

  • == (equal)
  • != (not equal)
  • < (less than)
  • > (greater than)
  • <= (less than or equal to)
  • >= (greater than or equal to)

Logical operators

  • not or !
  • and or &&
  • or or ||

Example:

life < universe || life < everything

String operators

  • + (concatenation)
  • matches (regex match)
  • contains (string contains)
  • startsWith (has prefix)
  • endsWith (has suffix)

To test if a string does not match a regex, use the logical not operator in combination with the matches operator:

not ("foo" matches "^b.+")

You must use parenthesis because the unary operator not has precedence over the binary operator matches.

Example:

"Arthur" + " " + "Dent";

Result will be set to Arthur Dent.

Membership operators

  • in (contain)
  • not in (does not contain)

Example:

user.Group in ["human_resources", "marketing"];
"foo" in { foo: 1, bar: 2 };

Ternary operators

  • foo ? 'yes' : 'no'

Example:

user.Age > 30 ? "mature" : "immature";

Built-in functions

  • len (length of array, map or string)
  • all (will return true if all element satisfies the predicate)
  • none (will return true if all element does NOT satisfies the predicate)
  • any (will return true if any element satisfies the predicate)
  • one (will return true if exactly ONE element satisfies the predicate)
  • filter (filter array by the predicate)
  • map (map all items with the closure)
  • count (returns number of elements what satisfies the predicate)

Examples:

Ensure all tweets are less than 280 chars.

all(Tweets, {.Size < 280})

Ensure there is exactly one winner.

one(Participants, {.Winner})

Closures

  • {...} (closure)

Closures allowed only with builtin functions. To access current item use # symbol.

map(0..9, {# / 2})

If the item of array is struct, it's possible to access fields of struct with omitted # symbol (#.Value becomes .Value).

filter(Tweets, {len(.Value) > 280})

Slices

  • array[:] (slice)

Slices can work with arrays or strings.

Example:

Variable array is [1,2,3,4,5].

array[1:5] == [2,3,4]
array[3:] == [4,5]
array[:4] == [1,2,3]
array[:] == array

Examples:

{{ steps.last.status == 'OK' }}
{{ steps.S1.output + ' ' + steps.S2.output }}
{{ steps.last.output contains "test" }}
{{ len(steps.last.output) }}
{{ steps.last.output[10:14] }}