@aircall/expression-parser

Transforms strings with escaping expression templates, evaluating the expressions and returning a new string or the value evaluated from the expression

Usage no npm install needed!

<script type="module">
  import aircallExpressionParser from 'https://cdn.skypack.dev/@aircall/expression-parser';
</script>

README

expression-parser

Resolves templated expressions in a secure local scope.

resolveExpression function

Arguments:

  • expression: expression templated string
  • context (optional): context from where to resolve expressions
  • options (optional): parser options:
    • passContextToEmptyFunctions?: boolean (default true): Allow to pass the context object into empty functions calls in single expression strings. Anonymous functions are not supported
    • transformArrayNegativeIndex?: boolean (default true): Allow and parse negative indexes correctly

Example:

import { resolveExpression } from '@aircall/expression-parser'

const template = 'Start: ${variable.start}, End ${variable.end}'
const context = {
  start: '09:00',
  end: '12:00',
}

resolveExpression(template, context);
// returns 'Start: 09:00, End 12:00'

There are some use cases in the E2E tests

Default expression handling

Default expressions come in the form of ${<JavaScript code to evaluate>}. The templates are delimited with ${ and } strings and all the JavaScript code inside will be evaluated. If there is more than one expression or there is some text around the template, it will return a string evaluating all of them.

For example, with this context:

{
  content: {
    input: 2,
    id: 'operation',
    executionId: 1234,
  },
  environment: {
    variables: {
      input: 1,
      inputArray: [1, 2, 3],
      inputObject: {
        'spaced name': 'name'
      },
      getInput: (context) => {
        return context.environment.variables.input;
      },
      isBelow: (a, b) => a < b,
    commonVariablePrefix: "a",
    current: 2,
  },
}

The following expressions are supported:

Template Result More information
${environment.variables.input} 1
${environment.variables.inputArray[0]} 1 resolves to first item of the variable input array
${environment.variables.inputArray[-1]} 3 resolves to last item of the variable input array
${environment.variables.inputObject['spaced name']} 'name' resolves to the variable input object property spaced name
${environment.services.getInput()} 1 executes the service function getInput with the context passed as an argument
${environment.services.getInput} Function getInput() returns the service function
${environment.services.isBelow(content.input,2)} false executes the service function isBelow with content.input value and 2
I, ${content.id}, execute with id ${content.executionId} 'I, operation, execute with id 1234' formats a string getting content object values
${true} true
${false} false
${null} null
${undefined} undefined
${<number>} <number> returns the number passed
${() => {}} () => {} returns the lambda function

It is possible to nest multiple expressions if you write them in proper JavaScript code. For example:

Given this context:

{
  environment: {
    variables: {
      a1: (v) => `method a1: ${v}`,
      a2: (v) => `method a2: ${v}`,
      a3: (v) => `method a3: ${v}`,
    },
    commonVariablePrefix: "a",
    current: 2,
  },
};

The expression

 ${environment.variables[`${environment.commonVariablePrefix}${environment.current}`]}

returns the function:

(v) => `method a2: ${v}`