or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

custom-functions.mdenvelopes.mderrors.mdindex.md
tile.json

custom-functions.mddocs/

Custom Functions

Extend JMESPath with custom functions. Includes all standard JMESPath built-ins plus AWS-specific Powertools functions.

PowertoolsFunctions

AWS Lambda data transformation functions:

class PowertoolsFunctions extends Functions {
  funcPowertoolsBase64(value: string): string;        // Decode base64
  funcPowertoolsBase64Gzip(value: string): string;    // Decode base64 + decompress gzip
  funcPowertoolsJson(value: string): JSONValue;       // Parse JSON string
}

Usage

import { search } from '@aws-lambda-powertools/jmespath';
import { PowertoolsFunctions } from '@aws-lambda-powertools/jmespath/functions';

// Parse JSON
search('powertools_json(body)', { body: '{"foo":"bar"}' }, {
  customFunctions: new PowertoolsFunctions()
}); // { foo: 'bar' }

// Chain functions
import { extractDataFromEnvelope } from '@aws-lambda-powertools/jmespath/envelopes';

extractDataFromEnvelope(
  { payload: 'eyJmb28iOiJiYXIifQ==' },
  'powertools_json(powertools_base64(payload))'
); // { foo: 'bar' }

Standard JMESPath Functions

Base Functions class includes all JMESPath built-ins:

Numeric

funcAbs(args: number): number;
funcAvg(args: Array<number>): number;
funcCeil(args: number): number;
funcFloor(args: number): number;
funcMax(arg: Array<number | string>): number | string | null;
funcMin(arg: Array<number>): number | string | null;
funcSum(args: Array<number>): number;

String

funcContains(haystack: string, needle: string): boolean;
funcEndsWith(str: string, suffix: string): boolean;
funcStartsWith(str: string, prefix: string): boolean;
funcJoin(separator: string, items: Array<string>): string;

Array

funcLength(arg: string | Array<unknown> | Record<string, unknown>): number;
funcReverse(arg: string | Array<unknown>): string | Array<unknown>;
funcSort(arg: Array<string> | Array<number>): Array<unknown>;
funcToArray(arg: JSONArray | Array<JSONValue>): Array<JSONValue> | JSONArray;

Object

funcKeys(arg: JSONObject): string[];
funcValues(arg: JSONObject): JSONValue[];
funcMerge(...args: Array<JSONObject>): JSONObject;

Type Conversion

funcType(arg: JSONValue): string;                    // Returns type string
funcToNumber(arg: JSONValue): number | null;
funcToString(arg: JSONValue): string;
funcNotNull(...args: Array<JSONValue>): JSONValue | null;

Expression Functions

funcMap(expression: Expression, args: JSONArray): JSONArray | Array<unknown>;
funcMaxBy(args: Array<JSONObject>, expression: Expression): JSONObject | null;
funcMinBy(args: Array<JSONObject>, expression: Expression): JSONObject | null;
funcSortBy(args: Array<JSONValue>, expression: Expression): Array<unknown>;

Usage Examples

import { search } from '@aws-lambda-powertools/jmespath';

// Numeric
search('sum([`1`, `2`, `3`])', {}); // 6
search('avg([`10`, `15`, `20`])', {}); // 15

// String
search('contains(`foobar`, `foo`)', {}); // true
search('join(`, `, [`a`, `b`, `c`])', {}); // "a, b, c"

// Array
search('length([`1`, `2`, `3`])', {}); // 3
search('reverse([`1`, `2`, `3`])', {}); // [3, 2, 1]

// Object
search('keys({foo: `bar`, baz: `qux`})', {}); // ["foo", "baz"]
search('merge({a: `1`}, {b: `2`})', {}); // {a: "1", b: "2"}

// Expression functions
const data = [
  { name: 'Alice', age: 30 },
  { name: 'Bob', age: 25 },
  { name: 'Charlie', age: 35 }
];
search('max_by(@, &age)', data); // {name: "Charlie", age: 35}
search('sort_by(@, &age)', data); // sorted by age ascending

Creating Custom Functions

Extend Functions or PowertoolsFunctions to add domain-specific functions. Use @Functions.signature() decorator to enforce argument types and arity.

API

class Functions {
  methods: Set<string>;  // Available function names

  introspectMethods(scope?: Functions): Set<string>;

  static signature(options: FunctionSignatureOptions): FunctionSignatureDecorator;
}

type FunctionSignatureOptions = {
  argumentsSpecs: Array<Array<string>>;  // [['string'], ['number']]
  variadic?: boolean;                    // Accept variable args
};

// Valid types: 'string', 'number', 'array', 'object', 'boolean', 'null', 'any',
// 'array-string', 'array-number', 'expression'

Examples

Extend PowertoolsFunctions

import { fromBase64 } from '@aws-lambda-powertools/commons/utils/base64';
import { extractDataFromEnvelope } from '@aws-lambda-powertools/jmespath/envelopes';
import { PowertoolsFunctions } from '@aws-lambda-powertools/jmespath/functions';
import { brotliDecompressSync } from 'node:zlib';

class CustomFunctions extends PowertoolsFunctions {
  @PowertoolsFunctions.signature({
    argumentsSpecs: [['string']],
    variadic: false,
  })
  public funcDecodeBrotliCompression(value: string): string {
    const encoded = fromBase64(value, 'base64');
    const uncompressed = brotliDecompressSync(encoded);
    return uncompressed.toString();
  }
}

export const handler = async (event: { payload: string }) => {
  const message = extractDataFromEnvelope<string>(
    event,
    'decode_brotli_compression(payload)',
    { customFunctions: new CustomFunctions() }
  );
};

Create Custom Function Set

import { search } from '@aws-lambda-powertools/jmespath';
import { Functions } from '@aws-lambda-powertools/jmespath/functions';

class MathFunctions extends Functions {
  @Functions.signature({
    argumentsSpecs: [['number'], ['number']],
    variadic: false,
  })
  public funcPower(base: number, exponent: number): number {
    return Math.pow(base, exponent);
  }

  @Functions.signature({
    argumentsSpecs: [['number']],
    variadic: false,
  })
  public funcSquareRoot(value: number): number {
    return Math.sqrt(value);
  }

  @Functions.signature({
    argumentsSpecs: [['number']],
    variadic: true,
  })
  public funcMultiply(...values: number[]): number {
    return values.reduce((acc, val) => acc * val, 1);
  }
}

search('power(`2`, `8`)', {}, { customFunctions: new MathFunctions() }); // 256
search('square_root(`16`)', {}, { customFunctions: new MathFunctions() }); // 4
search('multiply(`2`, `3`, `4`)', {}, { customFunctions: new MathFunctions() }); // 24

Types

class Expression {
  visit(value: JSONObject, node?: Node): JSONObject;
}

type JSONArray = Array<JSONValue>;
type JSONObject = JSONArray | JSONValue | object;

type Node = {
  type: string;
  children: Node[];
  value?: JSONValue;
};