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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@zakjan/objectpath

v1.0.3

Published

Expression language for querying JSON objects using ANTLR4

Downloads

7

Readme

ObjectPath

Expression language for querying JSON objects using ANTLR4. It can be easily ported into any target language supported as ANTLR4 runtime. Test usecases are shared to ensure consistent results. Currently implemented in TypeScript, Java.

Usage

JavaScript

Install

npm install @zakjan/objectpath

Use

import { getByPath } from '@zakjan/objectpath';

const data = { items: [{ type: "X", name: "Ben" }] };
const path = "items.find(type == 'X').name";
const result = getByPath(data, path); // -> Ben

Java

Install

Add to pom.xml:

<dependency>
    <groupId>cz.zakjan</groupId>
    <artifactId>objectpath</artifactId>
    <version>x.y.z</version>
</dependency>

Use

import static cz.zakjan.objectpath.GetByPath.getByPath;

Object data = new HashMap<String, Object>() {{
    put("items", new ArrayList<Object>() {{
        add(new HashMap<String, Object>() {{
            put("type", "X");
            put("type", "Ben");
        }});
    }});
}};
String path = "items.find(type == 'X').name";
Object result = getByPath(data, path); // -> Ben

Syntax

The basic syntax is compatible with lodash.get. A simple syntax for simple cases, yet supporting more complex cases.

Supported features (by priority):

  • access expressions
    • root object reference $
    • current object reference @ - default, can be omitted
    • dot access object.field
    • bracket access array[0] array[-1] object['a field']
    • array find array.find(field == 'X') array.find($.rootField == 'X')
    • array filter array.filter(field == 'X') array.filter($.rootField == 'X') array.filter(field == 'X' && array.filter(field == 'Y'))
    • array map array.map(field) array.map(@ * 2)
  • functions
    • toString
    • toNumber
    • join
    • split
    • sum
    • dateTimestampToIsoString - returns date ISO string YYYY-MM-DD'T'HH:mm:ss.SSSX
    • dateIsoStringToTimestamp - accepts any valid date ISO string
  • operators
    • unary + -
    • unary logical NOT !
    • multiplicative * /
    • additive + -
    • equality == !=
    • relational < > <= >=
    • logical AND &&
    • logical OR ||
    • conditional ?:
  • primitives - string, number, boolean, null

See detailed examples in test directory.

Strict equality

Equality operator == uses strict equality, === in JS, Object.equals in Java.

Strict boolean truth table

false, null evaluates to false, everything else evaluates to true. This differs from JS, which evaluates 0, '' also to false.

Logical operators on non-boolean operands

In case of logical operator applied to non-boolean operands, left operand is coerced to boolean for condition check, and the original value of left or right operand is returned. For example falseField || field returns field.

Note that nullish coalescing operator ?? is different from logical OR ||, it applies only if left side evaluates to null.

Optional chaining

Some programming languages have optional chaining operator ?.. This is the default and only mode of operation of this library by design.

Null vs. undefined

In case of non-existing property, null is returned. This is because undefined is a JS-only construct, it even can't be stored in JSON.

Parsing errors

In case of parsing errors, function getByPath silently catches the error and returns null. If you wish to handle the error on your own, call parsePath and getByParsedPath separately.

Why yet another library?

Other libraries are either missing more advanced extracting features or don't have consistent implementation across multiple languages.

JSONPath

  • (blocker) doesn't use array filter result as context for further traversing, see https://github.com/json-path/JsonPath/issues/272
  • (blocker) language-specific implementations are completely separate, they differ slightly in edge cases and path preprocessing is needed to make it behave consistently
  • requires root object reference $ in begining

XPath

  • language-specific implementations are completely separate
  • too different from JS syntax

SpEL

  • language-specific implementations are completely separate

jq

  • only C implementation

lodash.get, JSONata, JSPath, dot-prop, ...

  • missing more advanced features

TODO

  • float/double primitives and operations
  • long operations
  • array slicing array[start:end:step]
  • computed member access object[path]
  • short circuiting - don't evaluate right side of operators if left side is enough
  • complete operator precedence table - JavaScript, Java
  • enable adding custom functions
  • explore if also AST visitor can be generated from an universal language