LetsFlow
  • Introduction
  • Tutorial
    • The basics
    • A handshake
    • A conversation
    • A proper introduction
    • Group meeting
    • Quote
  • Cookbook
  • ENGINE
    • Installation
    • Authentication
    • API
    • Services
      • Configuration
      • Messaging
        • ZeroMQ
        • AMQP 0-9-1
        • Webhook
      • Engine service
  • Integration
    • Frontend
      • React
      • Angular
      • Vue
      • Svelte
    • Backend
  • Reference
    • Scenario
      • Actor
      • Action
        • Update instruction
      • State
        • Transition
          • Log
        • Notify
      • Data function
    • Schema
    • Process
      • Current state
      • Previous log
      • Prediction
      • Events
        • Instantiate event
        • Action event
        • Timeout event
  • Libraries
    • Core library
    • JMESPath
    • Test suite
      • Given
      • When
      • Then
        • Assert state
        • Assert actor
        • Assert variable
        • Assert service
        • Assert event
      • Customize
  • Advanced topics
    • Deep integration
    • Decentralized workflows
    • Custom JMESPath functions
    • Custom YAML tags
Powered by GitBook
On this page
  • Installation
  • Usage
  • Extension to the original specs
  • Custom functions
  • Root value access
  • Number literals
  • Additional Functions
  • if
  • range
  • to_object
  • json_serialize
  • json_parse
  • sha256
  • sha512
  • uuid
  • regex_test
  • regex_match
  • regex_match_all
  • regex_replace

Was this helpful?

  1. Libraries

JMESPath

PreviousCore libraryNextTest suite

Last updated 3 months ago

Was this helpful?

is a TypeScript implementation of the spec with additional functionality for LetsFlow workflows.

JMESPath is a query language for JSON. It takes a JSON document as input and transforms it into another JSON document given a JMESPath expression.

It's important to know and understand how to use JMESPath expressions to unlock the full potential of LetsFlow. It's highly recommended that you follow the JMESPath Tutorial.


This LetsFlow fork of JMESPath extends the original specs, adding the following functionality;

Additionally, it adds the following functions:

Installation

yarn add @letsflow/jmespath

Usage

search(data: JSONValue, expression: string): JSONValue

import { search } from '@letsflow/jmespath';

search(
  { foo: { bar: { baz: [0, 1, 2, 3, 4] } } },
  "foo.bar.baz[2]"
);

// OUTPUTS: 2

Extension to the original specs

The LetsFlow fork of JMESPath adds the following functionality, which is not in the original specs.

Custom functions

registerFunction(functionName: string, customFunction: RuntimeFunction, signature: InputSignature[]): void

Extend the list of built-in JMESpath expressions with your own functions.

import {search, registerFunction, TYPE_NUMBER} from '@letsflow/jmespath'

search({ foo: 60, bar: 10 }, 'divide(foo, bar)')
// THROWS ERROR: Error: Unknown function: divide()

registerFunction(
  'divide', // FUNCTION NAME
  (resolvedArgs) => {   // CUSTOM FUNCTION
    const [dividend, divisor] = resolvedArgs;
    return dividend / divisor;
  },
  [{ types: [TYPE_NUMBER] }, { types: [TYPE_NUMBER] }] //SIGNATURE
);

search({ foo: 60, bar: 10 }, 'divide(foo, bar)');

// OUTPUTS: 6

Optional arguments are supported by setting {..., optional: true} in argument signatures

  registerFunction(
    'divide',
    (resolvedArgs) => {
      const [dividend, divisor] = resolvedArgs;
      return dividend / divisor ?? 1; //OPTIONAL DIVISOR THAT DEFAULTS TO 1
    },
    [{ types: [TYPE_NUMBER] }, { types: [TYPE_NUMBER], optional: true }] //SIGNATURE
  );

  search({ foo: 60, bar: 10 }, 'divide(foo)');
  
  // OUTPUTS: 60

Root value access

Use $ to access the document root.

search({foo: { bar: 999 }, baz: [1, 2, 3]}, '$.baz[*].[@, $.foo.bar]')
// [ [ 1, 999 ], [ 2, 999 ], [ 3, 999 ] ]

Number literals

Numbers in the root scope are treated as number literals. This means that you don't need to quote numbers with backticks.

search([{"bar": 1}, {"bar": 10}], '[?bar==10]')
// [{"bar": 10}]

You can also use numbers in arithmetic operations

search({}, '16 + 26'); // 42

Additional Functions

if

Syntax:

if(condition, thenValue, elseValue?)

Description: Returns thenValue if condition is true, otherwise returns elseValue. If elseValue is not provided, it defaults to null.

Example:

if(@ > 10, "large", "small")

range

Syntax:

range(start, end, prefix?)

Description: Generates an array of numbers or prefixed strings from start to end - 1. If prefix is provided, each number is prefixed.

Example:

range(5)                // [0, 1, 2, 3, 4]
range(1, 5)             // [1, 2, 3, 4]
range(1, 5, 'item_')    // ["item_1", "item_2", "item_3", "item_4"]

to_object

Syntax:

to_object(entries)

Description: Converts an array of key-value pairs into an object.

Example:

to_object([['key1', 'value1'], ['key2', 'value2']])
// { "key1": "value1", "key2": "value2" }

[ 'value1', 'value2'] | to_object(zip(range(1, length(@) + 1, 'key'), @))
// { "key1": "value1", "key2": "value2" }

json_serialize

Syntax:

json_serialize(value)

Uses a deterministic version of JSON.stringify to serialize the value.

Description: Serializes a JSON value to a string.

Example:

json_serialize({ key: 'value' })
// "{\"key\":\"value\"}"

json_parse

Syntax:

json_parse(string)

Description: Parses a JSON string into a JSON object.

Example:

json_parse("{\"key\":\"value\"}")
// { "key": "value" }

sha256

Syntax:

sha256(string)

Description: Calculates the SHA-256 hash of a string and returns it as a hexadecimal string.

Example:

sha256('hello')
// "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824"

sha512

Syntax:

sha512(string)

Description: Calculates the SHA-512 hash of a string and returns it as a hexadecimal string.

Example:

sha512('hello')
// "9b71d224bd62f3785d96d46ad3ea3d73319b0c44e59b202205c5d235a0a6caa5a3b36f8c0ab9d45df9215bf07d4d1552c0b1f8bd2671c8a7a3d126f457d79d72"

uuid

Syntax:

uuid(name, namespace?)

Description: Generates a UUID. If name and (optionally) namespace are provided, generates a version 5 UUID; otherwise, generates a version 4 UUID.

Example:

uuid('example') // v5 UUID
uuid('example', '6ba7b810-9dad-11d1-80b4-00c04fd430c8') // v5 UUID with namespace

name must be a string. Use json_serialize() to convert a JSON object to a string.

namespace must be a UUID string. By default, it uses the NIL UUID.

  • NameSpace_DNS: 6ba7b810-9dad-11d1-80b4-00c04fd430c8

  • NameSpace_URL: 6ba7b811-9dad-11d1-80b4-00c04fd430c8

  • NameSpace_OID: 6ba7b812-9dad-11d1-80b4-00c04fd430c8

  • NameSpace_X500: 6ba7b814-9dad-11d1-80b4-00c04fd430c8

You might use a UUID for a URL to create a custom namespace. For example; LetsFlow uses the following logic to create the UUID for processes.

uuid(
  json_serialize(scenario),
  uuid('https://schemas.letsflow.io/v1.0/scenario', '6ba7b811-9dad-11d1-80b4-00c04fd430c8')
) 

regex_test

Syntax:

regex_test(regex, string)

Description: Tests if a string matches a given regular expression.

Example:

regex_test('/^hello/', 'hello world') // true

regex_test('/^hello/', 'HELLO world') // false
regex_test('/^hello/i', 'HELLO world') // true

regex_match

Syntax:

regex_match(regex, string)

Description: Returns the first match of a regular expression in a string as an array.

Example:

regex_match('/hello (\\w+)/', 'hello world')
// ["hello world", "world"]

regex_match('/\\w+/g', 'hello world')
// ["hello", "world"]

regex_match_all

Syntax:

regex_match_all(regex, string)

Description: Returns all matches of a regular expression in a string as an array of arrays.

Example:

regex_match_all('/(\\w+)=(\d+)/g', 'foo=24 bar=99')
// [["foo=24", "foo", "24"], ["bar=99", "bar", "99"]]

regex_replace

Syntax:

regex_replace(regex, replacement, string)

Description: Replaces parts of a string matching a regular expression with a replacement string.

Example:

regex_replace('/world/', 'universe', 'hello world')
// "hello universe"

- Conditional expression

- Generate a range of numbers or prefixed strings

- Convert an array of key-value pairs into an object

- Serialize a JSON value to a string

- Parse a JSON string into a JSON object

- Calculate the SHA-256 hash of a string

- Calculate the SHA-512 hash of a string

- Generate a UUID

- Test if a string matches a regular expression

- Return the first match of a regular expression in a string

- Return all matches of a regular expression in a string

- Replace parts of a string matching a regular expression with a replacement string

The pre-defines four namespaces

UUID RFC
Custom functions
Root value access
Number literals
if
range
to_object
json_serialize
json_parse
sha256
sha512
uuid
regex_test
regex_match
regex_match_all
regex_replace
@letsflow/jmespath
JMESPath
JMESPath Tutorial — JMESPath