Extend JMESPath with custom functions. Includes all standard JMESPath built-ins plus AWS-specific Powertools functions.
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
}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' }Base Functions class includes all JMESPath built-ins:
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;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;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;funcKeys(arg: JSONObject): string[];
funcValues(arg: JSONObject): JSONValue[];
funcMerge(...args: Array<JSONObject>): JSONObject;funcType(arg: JSONValue): string; // Returns type string
funcToNumber(arg: JSONValue): number | null;
funcToString(arg: JSONValue): string;
funcNotNull(...args: Array<JSONValue>): JSONValue | null;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>;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 ascendingExtend Functions or PowertoolsFunctions to add domain-specific functions. Use @Functions.signature() decorator to enforce argument types and arity.
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'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() }
);
};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() }); // 24class Expression {
visit(value: JSONObject, node?: Node): JSONObject;
}
type JSONArray = Array<JSONValue>;
type JSONObject = JSONArray | JSONValue | object;
type Node = {
type: string;
children: Node[];
value?: JSONValue;
};