npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@letsflow/jmespath

v1.1.5-jasny.1

Published

Typescript implementation of JMESPath with additional functionality for LetsFlow

Downloads

471

Readme

Build

@letsflow/jmespath

@letsflow/jmespath is a TypeScript implementation of the JMESPath spec.

JMESPath is a query language for JSON. It will take a JSON document as input and transform it into another JSON document given a JMESPath expression.

This fork extends the original specs, adding the following functionality;

Additionally, it adds the following functions:

  • if - Conditional expression
  • range - Generate a range of numbers or prefixed strings
  • to_object - Convert an array of key-value pairs into an object
  • json_serialize - Serialize a JSON value to a string
  • json_parse - Parse a JSON string into a JSON object
  • sha256 - Calculate the SHA-256 hash of a string
  • sha512 - Calculate the SHA-512 hash of a string
  • uuid - Generate a UUID v5
  • regex_test - Test if a string matches a regular expression
  • regex_match - Return the first match of a regular expression in a string
  • regex_match_all - Return all matches of a regular expression in a string
  • regex_replace - Replace parts of a string matching a regular expression with a replacement string

INSTALLATION

npm install @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

In the example we gave the search function input data of {foo: {bar: {baz: [0, 1, 2, 3, 4]}}} as well as the JMESPath expression foo.bar.baz[2], and the search function evaluated the expression against the input data to produce the result 2.

The JMESPath language can do a lot more than select an element from a list. Here are a few more examples:

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

const document = {
  foo: {
    bar: {
      baz: [0, 1, 2, 3, 4]
    }
  }
};

search(document, "foo.bar");
// OUTPUTS: { baz: [ 0, 1, 2, 3, 4 ] }
import { search } from '@letsflow/jmespath';

const document = {
  "foo": [
    { "first": "a", "last": "b" },
    { "first": "c", "last": "d" }
  ]
};

search(document, "foo[*].first")
// OUTPUTS: [ 'a', 'c' ]
import { search } from '@letsflow/jmespath';

const document = {
  "foo": [
    { "age": 20 },
    { "age": 25 },
    { "age": 30 },
    { "age": 35 },
    { "age": 40 }
  ]
}

search(document, "foo[?age > `30`]");
// OUTPUTS: [ { age: 35 }, { age: 40 } ]

compile(expression: string): ExpressionNodeTree

You can precompile all your expressions ready for use later on. the compile function takes a JMESPath expression and returns an abstract syntax tree that can be used by the TreeInterpreter function

import { compile, TreeInterpreter } from '@jmespath-community/jmespath';

const ast = compile('foo.bar');

TreeInterpreter.search(ast, { foo: { bar: 'BAZ' } })
// RETURNS: "BAZ"

EXTENSIONS TO ORIGINAL SPEC

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]')

// OUTPUTS:
// [ [ 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]')

// OUTPUTS;
// [{"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")

get

Syntax:

get(object, key, defaultValue?)

Description: Returns the value of a key in an object.

Example:

get({ key: 'value' }, 'key')                 // "value"
get({ key: 'value' }, 'missing')             // null
get({ key: 'value' }, 'missing', 'default')  // "default"

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 version 5 UUID.

UUID v5 is consistent. It creates a UUID based on the SHA hash of the input. This means that any given combination of input and namespace will result in the same UUID, every time.

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.

The UUID RFC pre-defines four namespaces

  • 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

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"

regex_count

Syntax:

regex_count(regex, string)

Description: Counts the number of matches of a regular expression in a string.

Example:

regex_count('/\\w+/g', 'hello world')
// 2

More Resources

The example above only shows a small amount of what a JMESPath expression can do. If you want to take a tour of the language, the best place to go is the JMESPath Tutorial.

The full JMESPath specification can be found on the JMESPath site.