{"id":26763982,"url":"https://github.com/swaggerexpert/jsonpath","last_synced_at":"2026-04-12T23:57:34.303Z","repository":{"id":284001137,"uuid":"952734423","full_name":"swaggerexpert/jsonpath","owner":"swaggerexpert","description":"RFC 9535 JSONPath parser \u0026 validator","archived":false,"fork":false,"pushed_at":"2025-03-31T13:54:29.000Z","size":287,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T14:56:51.698Z","etag":null,"topics":["jsonpath","parser","rfc9535","validator"],"latest_commit_sha":null,"homepage":"https://www.rfc-editor.org/rfc/rfc9535","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swaggerexpert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["char0n"],"tidelift":"npm/@swaggerexpert%2Fjsonpath","patreon":"char0n","ko_fi":"char0n","liberapay":"char0n","issuehunt":"char0n"}},"created_at":"2025-03-21T19:34:32.000Z","updated_at":"2025-03-31T13:54:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"c084dae9-a836-4aba-bfc0-bb0d78ed2085","html_url":"https://github.com/swaggerexpert/jsonpath","commit_stats":null,"previous_names":["swaggerexpert/jsonpath"],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Fjsonpath","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Fjsonpath/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Fjsonpath/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swaggerexpert%2Fjsonpath/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swaggerexpert","download_url":"https://codeload.github.com/swaggerexpert/jsonpath/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249066514,"owners_count":21207392,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jsonpath","parser","rfc9535","validator"],"created_at":"2025-03-28T19:37:28.650Z","updated_at":"2026-04-12T23:57:34.290Z","avatar_url":"https://github.com/swaggerexpert.png","language":"JavaScript","funding_links":["https://github.com/sponsors/char0n","https://tidelift.com/funding/github/npm/@swaggerexpert%2Fjsonpath","https://patreon.com/char0n","https://ko-fi.com/char0n","https://liberapay.com/char0n","https://issuehunt.io/r/char0n","https://tidelift.com/badges/package/npm/@swaggerexpert%2Fjsonpath","https://tidelift.com/subscription/pkg/npm-.swaggerexpert-jsonpath?utm_source=npm-swaggerexpert-jsonpath\u0026utm_medium=referral\u0026utm_campaign=readme"],"categories":[],"sub_categories":[],"readme":"# @swaggerexpert/jsonpath\n\n[![npmversion](https://img.shields.io/npm/v/%40swaggerexpert%2Fjsonpath?style=flat-square\u0026label=npm%20package\u0026color=%234DC81F\u0026link=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2F%40swaggerexpert%2Fjsonpath)](https://www.npmjs.com/package/@swaggerexpert/jsonpath)\n[![npm](https://img.shields.io/npm/dm/@swaggerexpert/jsonpath)](https://www.npmjs.com/package/@swaggerexpert/jsonpath)\n[![Test workflow](https://github.com/swaggerexpert/jsonpath/actions/workflows/test.yml/badge.svg)](https://github.com/swaggerexpert/jsonpath/actions)\n[![Dependabot enabled](https://img.shields.io/badge/Dependabot-enabled-blue.svg)](https://dependabot.com/)\n[![try on RunKit](https://img.shields.io/badge/try%20on-RunKit-brightgreen.svg?style=flat)](https://npm.runkit.com/@swaggerexpert/jsonpath)\n[![Tidelift](https://tidelift.com/badges/package/npm/@swaggerexpert%2Fjsonpath)](https://tidelift.com/subscription/pkg/npm-.swaggerexpert-jsonpath?utm_source=npm-swaggerexpert-jsonpath\u0026utm_medium=referral\u0026utm_campaign=readme)\n\n`@swaggerexpert/jsonpath` is a **parser**, **validator**, **compiler**, and **evaluator** for [RFC 9535](https://www.rfc-editor.org/rfc/rfc9535) Query Expressions for JSON - **JSONPath**.\n\nThe development of this library contributed to the identification and formal submission of following **erratas** against the RFC 9535:\n- [Errata ID: 8343](https://www.rfc-editor.org/errata/eid8343)\n- [Errata ID: 8352](https://www.rfc-editor.org/errata/eid8352)\n- [Errata ID: 8353](https://www.rfc-editor.org/errata/eid8353)\n- [Errata ID: 8354](https://www.rfc-editor.org/errata/eid8354)\n\nThis library is **100% compliant** with the [JSONPath Compliance Test Suite](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite).\nIt is also included in the [JSONPath Comparison](https://cburgmer.github.io/json-path-comparison/) project,\nexecuting all queries without errors.\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"right\" valign=\"middle\"\u003e\n        \u003cimg src=\"https://raw.githubusercontent.com/swaggerexpert/jsonpath/main/assets/tidelift.webp\" alt=\"Tidelift\" width=\"60\" /\u003e\n      \u003c/td\u003e\n      \u003ctd valign=\"middle\"\u003e\n        \u003ca href=\"https://tidelift.com/subscription/pkg/npm-.swaggerexpert-jsonpath?utm_source=npm-swaggerexpert-jsonpath\u0026utm_medium=referral\u0026utm_campaign=readme\"\u003e\n            Get professionally supported @swaggerexpert/jsonpath with Tidelift Subscription.\n        \u003c/a\u003e\n      \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n## Table of Contents\n\n- [Getting started](#getting-started)\n  - [Installation](#installation)\n  - [Usage](#usage)\n    - [Parsing](#parsing)\n      - [Normalized paths](#normalized-paths)\n      - [Translators](#translators)\n        - [CST](#cst-translator)\n        - [CST Optimized](#cst-optimized-translator)\n        - [AST](#ast-translator)\n        - [XML](#xml-translator)\n      - [Statistics](#statistics)\n      - [Tracing](#tracing)\n    - [Validation](#validation)\n    - [Normalized paths](#normalized-paths-1)\n    - [Evaluation](#evaluation)\n      - [Collecting normalized paths](#collecting-normalized-paths)\n      - [Built-in functions](#built-in-functions)\n      - [Custom functions](#custom-functions)\n      - [Evaluation realms](#evaluation-realms)\n    - [Errors](#errors)\n    - [Grammar](#grammar)\n- [More about JSONPath](#more-about-jsonpath)\n- [Setting up for development](#setting-up-for-development)\n- [License](#license)\n\n## Getting started\n\n### Installation\n\nYou can install `@swaggerexpert/jsonpath` using `npm`:\n\n```sh\n $ npm install @swaggerexpert/jsonpath\n```\n\n### Usage\n\n`@swaggerexpert/jsonpath` supports **parsing**, **validation**, **compilation**, and **evaluation** of JSONPath expressions.\nThe parser and validator are based on a superset of [ABNF](https://www.rfc-editor.org/rfc/rfc5234) ([SABNF](https://cs.github.com/ldthomas/apg-js2/blob/master/SABNF.md))\nand use [apg-lite](https://github.com/ldthomas/apg-lite) parser generator.\n\n#### Parsing\n\nParsing a JSONPath Query expression is as simple as importing the **parse** function and calling it.\n\n```js\nimport { parse } from '@swaggerexpert/jsonpath';\n\nconst parseResult = parse('$.store.book[0].title');\n```\n\n**parseResult** variable has the following shape:\n\n```\n{\n  result: \u003cParseResult['result]\u003e,\n  tree: \u003cParseResult['tree']\u003e,\n  stats: \u003cParseResult['stats']\u003e,\n  trace: \u003cParseResult['trace']\u003e,\n}\n```\n\n[TypeScript typings](https://github.com/swaggerexpert/jsonpath/blob/main/types/index.d.ts) are available for all fields attached to parse result object returned by the `parse` function.\n\n\n##### Normalized paths\n\n[comment]: \u003c\u003e (SPDX-FileCopyrightText: Copyright \u0026#40;c\u0026#41; 2024 IETF Trust and the persons identified as the document authors. All rights reserved.)\n[comment]: \u003c\u003e (SPDX-License-Identifier: BSD-3-Clause)\n\n[Normalized Path](https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths) is a JSONPath query with restricted syntax.\nA Normalized Path represents the identity of a node in a specific value.\nThere is precisely one Normalized Path identifying any particular node in a value.\nNormalized Paths provide a predictable format that simplifies testing and post-processing of nodelists, e.g., to remove duplicate nodes.\nNormalized Paths use the canonical bracket notation, rather than dot notation.\nSingle quotes are used in Normalized Paths to delimit string member names. This reduces the number of characters that need escaping when Normalized Paths appear in strings delimited by double quotes.\n\nParsing in normalized path mode can be enabled by setting `normalized` option to `true`.\n\n```js\nimport { parse } from '@swaggerexpert/jsonpath';\n\nparse(\"$['a']\", { normalized: true });\nparse(\"$[1]\", { normalized: true });\nparse(\"$[2]\", { normalized: true });\nparse(\"$['a']['b'][1]\", { normalized: true });\nparse(\"$['\\\\u000b']\", { normalized: true });\n```\n\n##### Translators\n\n`@swaggerexpert/jsonpath` provides several translators to convert the parse result into different tree representations.\n\n###### CST translator\n\n[Concrete Syntax Tree](https://en.wikipedia.org/wiki/Parse_tree) (Parse tree) representation is available on parse result\nwhen instance of `CSTTranslator` is provided via a `translator` option to the `parse` function.\nCST is suitable to be consumed by other tools like IDEs, editors, etc...\n\n```js\nimport { parse, CSTTranslator } from '@swaggerexpert/jsonpath';\n\nconst { tree: CST } = parse('$.store.book[0].title', { translator: new CSTTranslator() });\n```\n\nCST tree has a shape documented by [TypeScript typings (CSTTree)](https://github.com/swaggerexpert/jsonpath/blob/main/types/index.d.ts).\n\n###### CST Optimized translator\n\nSame as CST, but optimizes the tree for more optimized representation. By default, it collapses\nfragmented `single-quoted`, `double-quoted` or `normal-single-quoted` nodes into a single node.\n`text`, `segments` and `singular-query-segments` nodes, when empty, are removed from the tree.\n\n```js\nimport { parse, CSTOptimizedTranslator } from '@swaggerexpert/jsonpath';\n\nconst { tree: CST } = parse('$.store.book[0].title', { translator: new CSTOptimizedTranslator() });\n```\n\n###### AST translator\n\n**Default translator**. [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) representation is available on parse result\nby default or when instance of `ASTTranslator` is provided via a `translator` option to the `parse` function.\nAST is suitable to be consumed by implementations that need to analyze the structure of the JSONPath expression\nor for building a custom JSONPath evaluation engine.\n\n```js\nimport { parse } from '@swaggerexpert/jsonpath';\n\nconst { tree: AST } = parse('$.store.book[0].title');\n```\n\nor\n\n```js\nimport { parse, ASTTranslator } from '@swaggerexpert/jsonpath';\n\nconst { tree: AST } = parse('$.store.book[0].title', { translator: new ASTTranslator() });\n```\n\nAST tree has a shape documented by [TypeScript typings (ASTTree)](https://github.com/swaggerexpert/jsonpath/blob/main/types/index.d.ts).\n\n###### XML translator\n\n```js\nimport { parse, XMLTranslator } from '@swaggerexpert/jsonpath';\n\nconst { tree: XML } = parse('$.store.book[0].title', { translator: new XMLTranslator() });\n```\n\n##### Statistics\n\n`parse` function returns additional statistical information about the parsing process.\nCollection of the statistics can be enabled by setting `stats` option to `true`.\n\n```js\nimport { parse } from '@swaggerexpert/jsonpath';\n\nconst { stats } = parse('$.store.book[0].title', { stats: true });\n\nstats.displayStats(); // returns operator stats\nstats.displayHits(); // returns rules grouped by hit count\n```\n\n##### Tracing\n\n`parse` function returns additional tracing information about the parsing process.\nTracing can be enabled by setting `trace` option to `true`. Tracing is essential\nfor debugging failed matches or analyzing rule execution flow.\n\n```js\nimport { parse } from '@swaggerexpert/jsonpath';\n\nconst { result, trace } = parse('$fdfadfd', { trace: true });\n\nresult.success; // returns false\ntrace.displayTrace(); // returns trace information\ntrace.inferExpectations(); // returns parser expectations\n```\n\nBy combining information from `result` and `trace`, you can analyze the parsing process in detail\nand generate messages like: `'Syntax error at position 1, expected \"[\", \".\", \"..\"'`. Please see this\n[test file](https://github.com/swaggerexpert/jsonpath/blob/main/test/parse/trace.js) for more information how to achieve that.\n\n#### Validation\n\n`@swaggerexpert/jsonpath` provides a `test` function to validate JSONPath expressions.\n\n```js\nimport { test } from '@swaggerexpert/jsonpath';\n\ntest('$.store.book[0].title'); // =\u003e true\ntest('$$'); // =\u003e false\n```\n\n**Normalized paths** can be validated by setting `normalized` option to `true`.\n\n```js\nimport { test } from '@swaggerexpert/jsonpath';\n\ntest(\"$['a']\", { normalized: true }); // =\u003e true\ntest('$.store.book[0].title', { normalized: true }); // =\u003e false\n```\n\n**Well-typedness validation** is enabled by default and validates the JSONPath expression against [RFC 9535 type system rules](https://www.rfc-editor.org/rfc/rfc9535#section-2.4.9)\n(e.g., function argument types, return type usage). Set `wellTyped` option to `false` to perform syntax-only validation.\n\n```js\nimport { test } from '@swaggerexpert/jsonpath';\n\ntest('$[?length(@.*) \u003c 3]'); // =\u003e false (non-singular query for ValueType parameter)\ntest('$[?length(@.*) \u003c 3]', { wellTyped: false }); // =\u003e true (syntax is valid)\n```\n\n#### Normalized paths\n\nThe `NormalizedPath` namespace provides utilities for working with [Normalized Paths](https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths).\n\n##### NormalizedPath.test\n\nTests if a string is a valid normalized JSONPath. This is a convenience wrapper around `test(path, { normalized: true })`.\n\n```js\nimport { NormalizedPath } from '@swaggerexpert/jsonpath';\n\nNormalizedPath.test(\"$['a']\"); // =\u003e true\nNormalizedPath.test('$[0]'); // =\u003e true\nNormalizedPath.test(\"$['store']['book'][0]['title']\"); // =\u003e true\nNormalizedPath.test('$.a'); // =\u003e false (dot notation not allowed)\nNormalizedPath.test('$[\"a\"]'); // =\u003e false (double quotes not allowed)\nNormalizedPath.test('$[*]'); // =\u003e false (wildcard not allowed)\n```\n\n##### NormalizedPath.from\n\nCreates a normalized path string from a list of selectors. Name selectors are automatically escaped.\n\n```js\nimport { NormalizedPath } from '@swaggerexpert/jsonpath';\n\nNormalizedPath.from(['store', 'book', 0, 'title']); // =\u003e \"$['store']['book'][0]['title']\"\nNormalizedPath.from([\"it's\"]); // =\u003e \"$['it\\\\'s']\"\n```\n\n##### NormalizedPath.to\n\nParses a normalized path string and returns a list of selectors.\n\n```js\nimport { NormalizedPath } from '@swaggerexpert/jsonpath';\n\nNormalizedPath.to(\"$['store']['book'][0]['title']\"); // =\u003e ['store', 'book', 0, 'title']\nNormalizedPath.to(\"$['it\\\\'s']\"); // =\u003e [\"it's\"]\n```\n\n##### NormalizedPath.escape\n\nEscapes special characters in name selectors for use in normalized paths.\nThe apostrophe (`'`) and backslash (`\\`) characters must be escaped.\nControl characters (U+0000 through U+001F) are escaped using specific escape sequences\n(`\\b`, `\\t`, `\\n`, `\\f`, `\\r`) or Unicode escape sequences (`\\uXXXX`).\n\n```js\nimport { NormalizedPath } from '@swaggerexpert/jsonpath';\n\nNormalizedPath.escape(\"it's\"); // =\u003e \"it\\\\'s\"\nNormalizedPath.escape('back\\\\slash'); // =\u003e \"back\\\\\\\\slash\"\nNormalizedPath.escape('line\\nfeed'); // =\u003e \"line\\\\nfeed\"\n```\n\n#### Evaluation\n\nEvaluation is the process of applying a JSONPath expression against a JSON value to produce a nodelist (array of matched values).\nPer [RFC 9535](https://www.rfc-editor.org/rfc/rfc9535#section-2.1), evaluation begins with the root value (`$`) and processes each\nsegment sequentially, producing a nodelist of all matching values.\n\n```js\nimport { evaluate } from '@swaggerexpert/jsonpath';\n\nconst value = {\n  store: {\n    book: [\n      { title: 'A', price: 10 },\n      { title: 'B', price: 20 }\n    ]\n  }\n};\n\nevaluate(value, '$.store.book[*].title'); // =\u003e ['A', 'B']\nevaluate(value, '$.store.book[0]'); // =\u003e [{ title: 'A', price: 10 }]\nevaluate(value, '$.store.book[?@.price \u003e 15]'); // =\u003e [{ title: 'B', price: 20 }]\n```\n\n##### Collecting normalized paths\n\nUse the `callback` option to collect [normalized paths](https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths) alongside matched values:\n\n```js\nimport { evaluate } from '@swaggerexpert/jsonpath';\n\nconst value = { store: { book: [{ title: 'A' }, { title: 'B' }] } };\nconst paths = [];\n\nevaluate(value, '$.store.book[*].title', {\n  callback: (v, path) =\u003e paths.push(path)\n});\n// paths =\u003e [\"$['store']['book'][0]['title']\", \"$['store']['book'][1]['title']\"]\n```\n\n##### Built-in functions\n\nThe evaluation engine includes all [RFC 9535 Section 2.4](https://www.rfc-editor.org/rfc/rfc9535#section-2.4) functions:\n\n| Function | Description |\n|----------|-------------|\n| `length(value)` | Returns the length of a string, array, or object |\n| `count(nodelist)` | Returns the number of nodes in a nodelist |\n| `match(string, regex)` | Tests if a string matches an I-Regexp pattern (full match) |\n| `search(string, regex)` | Tests if a string contains an I-Regexp pattern |\n| `value(nodelist)` | Extracts a single value from a nodelist |\n\n```js\nimport { evaluate } from '@swaggerexpert/jsonpath';\n\nconst value = { items: ['short', 'very long string', 'medium'] };\n\nevaluate(value, '$.items[?length(@) \u003e 5]'); // =\u003e ['very long string', 'medium']\nevaluate(value, '$.items[?match(@, \"^v.*\")]'); // =\u003e ['very long string']\n```\n\n##### Custom functions\n\nExtend or override built-in functions via the `functions` option:\n\n```js\nimport { evaluate, functions } from '@swaggerexpert/jsonpath';\n\nconst customFunctions = {\n  ...functions,\n  min: (ctx, args) =\u003e {\n    const values = args[0];\n    if (!Array.isArray(values)) return undefined;\n    return Math.min(...values);\n  }\n};\n\nconst value = { numbers: [3, 1, 4, 1, 5] };\nevaluate(value, '$[?min($.numbers) == 1]', { functions: customFunctions });\n```\n\n##### Evaluation realms\n\nEvaluation realms provide an abstraction layer for accessing different data structures during JSONPath evaluation.\nBy default, the evaluation engine uses the **JSON Evaluation Realm** which works with plain JavaScript objects and arrays.\n\n###### JSON Evaluation Realm\n\nBy default, the evaluation operates under the **JSON realm**, which assumes that:\n\n- **Arrays** are indexed numerically\n- **Objects** (plain JavaScript objects) are accessed by string keys\n\n```js\nimport { evaluate } from '@swaggerexpert/jsonpath';\n\nconst value = { store: { book: [{ title: 'A' }] } };\nevaluate(value, '$.store.book[*].title'); // =\u003e ['A']\n```\n\nThe default realm can also be specified explicitly:\n\n```js\nimport { evaluate, JSONEvaluationRealm } from '@swaggerexpert/jsonpath';\n\nconst value = { store: { book: [{ title: 'A' }] } };\nevaluate(value, '$.store.book[*].title', { realm: new JSONEvaluationRealm() }); // =\u003e ['A']\n```\n\n###### Custom Evaluation Realms\n\nYou can create custom evaluation realms to work with different data structures (e.g., Immutable.js, ApiDOM elements).\nExtend the `EvaluationRealm` base class and implement the required methods:\n\n| Method | Description |\n|--------|-------------|\n| `isObject(value)` | Check if value is an object (has named properties) |\n| `isArray(value)` | Check if value is an array (has indexed elements) |\n| `isString(value)` | Check if value is a string |\n| `isNumber(value)` | Check if value is a number |\n| `isBoolean(value)` | Check if value is a boolean |\n| `isNull(value)` | Check if value is null |\n| `getString(value)` | Get raw string value for regex operations |\n| `getProperty(value, key)` | Get property by name from object |\n| `hasProperty(value, key)` | Check if object has property |\n| `getElement(value, index)` | Get element by index from array |\n| `getKeys(value)` | Get all keys of object |\n| `getLength(value)` | Get length of string, array, or object |\n| `entries(value)` | Iterate over [key/index, value] pairs |\n| `compare(left, op, right)` | Compare two values using operator (==, !=, \u003c, \u003c=, \u003e, \u003e=) |\n\n```js\nimport { evaluate, EvaluationRealm } from '@swaggerexpert/jsonpath';\n\nclass CustomRealm extends EvaluationRealm {\n  name = 'custom';\n\n  isObject(value) { /* ... */ }\n  isArray(value) { /* ... */ }\n  // ... implement all required methods\n}\n\nconst value = { /* ... */ };\nevaluate(value, '$.path', { realm: new CustomRealm() });\n```\n\n#### Errors\n\n`@swaggerexpert/jsonpath` provides a structured error class hierarchy,\nenabling precise error handling across JSONPath operations, including parsing, compilation, and evaluation.\n\n```js\nimport { JSONPathError, JSONPathParseError, JSONNormalizedPathError, JSONPathEvaluateError } from '@swaggerexpert/jsonpath';\n```\n\n**JSONPathError** is the base class for all JSONPath errors.\n\n#### Grammar\n\nNew grammar instance can be created in following way:\n\n```js\nimport { Grammar } from '@swaggerexpert/jsonpath';\n\nconst grammar = new Grammar();\n```\n\nTo obtain original ABNF (SABNF) grammar as a string:\n\n```js\nimport { Grammar } from '@swaggerexpert/jsonpath';\n\nconst grammar = new Grammar();\n\ngrammar.toString();\n// or\nString(grammar);\n```\n\n## More about JSONPath\n\nJSONPath is defined by the following [ABNF](https://tools.ietf.org/html/rfc5234) syntax\n\n[comment]: \u003c\u003e (SPDX-FileCopyrightText: Copyright \u0026#40;c\u0026#41; 2024 IETF Trust and the persons identified as the document authors. All rights reserved.)\n[comment]: \u003c\u003e (SPDX-License-Identifier: BSD-3-Clause)\n\n```abnf\n; JSONPath: Query Expressions for JSON\n; https://www.rfc-editor.org/rfc/rfc9535\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.1.1\njsonpath-query      = root-identifier segments\nsegments            = *(S segment)\n\nB                   = %x20 /    ; Space\n                      %x09 /    ; Horizontal tab\n                      %x0A /    ; Line feed or New line\n                      %x0D      ; Carriage return\nS                   = *B        ; optional blank space\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.2.1\nroot-identifier     = \"$\"\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.3\nselector            = name-selector /\n                      wildcard-selector /\n                      slice-selector /\n                      index-selector /\n                      filter-selector\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.3.1.1\nname-selector       = string-literal\n\nstring-literal      = dquote *double-quoted dquote /     ; \"string\", MODIFICATION: surrogate text rule used\n                      squote *single-quoted squote      ; 'string', MODIFICATION: surrogate text rule used\n\ndouble-quoted       = unescaped /\n                      %x27      /                    ; '\n                      ESC %x22  /                    ; \\\"\n                      ESC escapable\n\nsingle-quoted       = unescaped /\n                      %x22      /                    ; \"\n                      ESC %x27  /                    ; \\'\n                      ESC escapable\n\nESC                 = %x5C                           ; \\ backslash\n\nunescaped           = %x20-21 /                      ; see RFC 8259\n                         ; omit 0x22 \"\n                      %x23-26 /\n                         ; omit 0x27 '\n                      %x28-5B /\n                         ; omit 0x5C \\\n                      %x5D-D7FF /\n                         ; skip surrogate code points\n                      %xE000-10FFFF\n\nescapable           = %x62 / ; b BS backspace U+0008\n                      %x66 / ; f FF form feed U+000C\n                      %x6E / ; n LF line feed U+000A\n                      %x72 / ; r CR carriage return U+000D\n                      %x74 / ; t HT horizontal tab U+0009\n                      \"/\"  / ; / slash (solidus) U+002F\n                      \"\\\"  / ; \\ backslash (reverse solidus) U+005C\n                      (%x75 hexchar) ;  uXXXX U+XXXX\n\nhexchar             = non-surrogate /\n                      (high-surrogate \"\\\" %x75 low-surrogate)\nnon-surrogate       = ((DIGIT / \"A\"/\"B\"/\"C\" / \"E\"/\"F\") 3HEXDIG) /\n                      (\"D\" %x30-37 2HEXDIG )\nhigh-surrogate      = \"D\" (\"8\"/\"9\"/\"A\"/\"B\") 2HEXDIG\nlow-surrogate       = \"D\" (\"C\"/\"D\"/\"E\"/\"F\") 2HEXDIG\n\nHEXDIG              = DIGIT / \"A\" / \"B\" / \"C\" / \"D\" / \"E\" / \"F\"\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.3.2.1\nwildcard-selector   = \"*\"\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.3.3.1\nindex-selector      = int                        ; decimal integer\n\nint                 = \"0\" /\n                      ([\"-\"] DIGIT1 *DIGIT)      ; - optional\nDIGIT1              = %x31-39                    ; 1-9 non-zero digit\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.3.4.1\nslice-selector      = [start S] colon S [end S] [colon [S step ]] ; MODIFICATION: surrogate text rule used\n\nstart               = int       ; included in selection\nend                 = int       ; not included in selection\nstep                = int       ; default: 1\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.3.5.1\nfilter-selector     = questionmark S logical-expr ; MODIFICATION: surrogate text rule used\n\nlogical-expr        = logical-or-expr\nlogical-or-expr     = logical-and-expr *(S disjunction S logical-and-expr) ; MODIFICATION: surrogate text rule used\n                        ; disjunction\n                        ; binds less tightly than conjunction\nlogical-and-expr    = basic-expr *(S conjunction S basic-expr) ; MODIFICATION: surrogate text rule used\n                        ; conjunction\n                        ; binds more tightly than disjunction\n\nbasic-expr          = paren-expr /\n                      comparison-expr /\n                      test-expr\n\nparen-expr          = [logical-not-op S] left-paren S logical-expr S right-paren ; MODIFICATION: surrogate text rule used\n                                        ; parenthesized expression\nlogical-not-op      = \"!\"               ; logical NOT operator\n\ntest-expr           = [logical-not-op S]\n                      (filter-query / ; existence/non-existence\n                       function-expr) ; LogicalType or NodesType\nfilter-query        = rel-query / jsonpath-query\nrel-query           = current-node-identifier segments\ncurrent-node-identifier = \"@\"\n\ncomparison-expr     = comparable S comparison-op S comparable\nliteral             = number / string-literal /\n                      true / false / null\ncomparable          = singular-query / ; singular query value\n                      function-expr /  ; ValueType\n                      literal\n                      ; MODIFICATION: https://www.rfc-editor.org/errata/eid8352\ncomparison-op       = \"==\" / \"!=\" /\n                      \"\u003c=\" / \"\u003e=\" /\n                      \"\u003c\"  / \"\u003e\"\n\nsingular-query      = rel-singular-query / abs-singular-query\nrel-singular-query  = current-node-identifier singular-query-segments\nabs-singular-query  = root-identifier singular-query-segments\nsingular-query-segments = *(S (name-segment / index-segment))\nname-segment        = (left-bracket name-selector right-bracket) / ; MODIFICATION: surrogate text rule used\n                      (dot-prefix member-name-shorthand) ; MODIFICATION: surrogate text rule used\nindex-segment       = left-bracket index-selector right-bracket ; MODIFICATION: surrogate text rule used\n\nnumber              = (int / \"-0\") [ frac ] [ exp ] ; decimal number\nfrac                = \".\" 1*DIGIT                  ; decimal fraction\nexp                 = \"e\" [ \"-\" / \"+\" ] 1*DIGIT    ; decimal exponent\ntrue                = %x74.72.75.65                ; true\nfalse               = %x66.61.6c.73.65             ; false\nnull                = %x6e.75.6c.6c                ; null\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.4\nfunction-name       = function-name-first *function-name-char\nfunction-name-first = LCALPHA\nfunction-name-char  = function-name-first / \"_\" / DIGIT\nLCALPHA             = %x61-7A  ; \"a\"..\"z\"\n\nfunction-expr       = function-name left-paren S [function-argument ; MODIFICATION: surrogate text rule used\n                         *(S comma S function-argument)] S right-paren ; MODIFICATION: surrogate text rule used\nfunction-argument   = logical-expr / ; MODIFICATION: https://www.rfc-editor.org/errata/eid8343\n                      filter-query / ; (includes singular-query)\n                      function-expr /\n                      literal\n\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.5\nsegment             = child-segment / descendant-segment\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.5.1.1\nchild-segment       = bracketed-selection /\n                      (dot-prefix ; MODIFICATION: surrogate text rule used\n                       (wildcard-selector /\n                        member-name-shorthand))\n\nbracketed-selection = left-bracket S selector *(S comma S selector) S right-bracket\n                    ; MODIFICATION: surrogate text rule used\n\nmember-name-shorthand = name-first *name-char\nname-first          = ALPHA /\n                      \"_\"   /\n                      %x80-D7FF /\n                         ; skip surrogate code points\n                      %xE000-10FFFF\nname-char           = name-first / DIGIT\n\nDIGIT               = %x30-39              ; 0-9\nALPHA               = %x41-5A / %x61-7A    ; A-Z / a-z\n\n; https://www.rfc-editor.org/rfc/rfc9535#section-2.5.2.1\ndescendant-segment  = double-dot-prefix (bracketed-selection / ; MODIFICATION: surrogate text rule used\n                                         wildcard-selector /\n                                         member-name-shorthand)\n\n; https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths\nnormalized-path      = root-identifier *(normal-index-segment)\nnormal-index-segment = left-bracket normal-selector right-bracket ; MODIFICATION: surrogate text rule used\nnormal-selector      = normal-name-selector / normal-index-selector\nnormal-name-selector = squote *normal-single-quoted squote ; 'string', MODIFICATION: surrogate text rule used\nnormal-single-quoted = normal-unescaped /\n                       ESC normal-escapable\nnormal-unescaped     =    ; omit %x0-1F control codes\n                       %x20-26 /\n                          ; omit 0x27 '\n                       %x28-5B /\n                          ; omit 0x5C \\\n                       %x5D-D7FF /\n                          ; skip surrogate code points\n                       %xE000-10FFFF\n\nnormal-escapable     = %x62 / ; b BS backspace U+0008\n                       %x66 / ; f FF form feed U+000C\n                       %x6E / ; n LF line feed U+000A\n                       %x72 / ; r CR carriage return U+000D\n                       %x74 / ; t HT horizontal tab U+0009\n                       \"'\" /  ; ' apostrophe U+0027\n                       \"\\\" /  ; \\ backslash (reverse solidus) U+005C\n                       (%x75 normal-hexchar)\n                                       ; certain values u00xx U+00XX\nnormal-hexchar       = \"0\" \"0\"\n                       (\n                          (\"0\" %x30-37) / ; \"00\"-\"07\"\n                             ; omit U+0008-U+000A BS HT LF\n                          (\"0\" %x62) /    ; \"0b\"\n                             ; omit U+000C-U+000D FF CR\n                          (\"0\" %x65-66) / ; \"0e\"-\"0f\"\n                          (\"1\" normal-HEXDIG)\n                       )\nnormal-HEXDIG        = DIGIT / %x61-66    ; \"0\"-\"9\", \"a\"-\"f\"\nnormal-index-selector = \"0\" / (DIGIT1 *DIGIT)\n                        ; non-negative decimal integer\n\n; Surrogate named rules\ndot-prefix          = \".\"\ndouble-dot-prefix   = \"..\"\nleft-bracket        = \"[\"\nright-bracket       = \"]\"\nleft-paren          = \"(\"\nright-paren         = \")\"\ncomma               = \",\"\ncolon               = \":\"\ndquote              = %x22 ; \"\nsquote              = %x27 ; '\nquestionmark        = \"?\"\ndisjunction         = \"||\"\nconjunction         = \"\u0026\u0026\"\n```\n\n## Setting up for development\n\n```sh\n # Clone with submodules (recommended)\n $ git clone --recurse-submodules https://github.com/swaggerexpert/jsonpath.git\n\n # Or initialize submodules after cloning\n $ git submodule update --init\n\n # Install dependencies\n $ npm install\n```\n\nThe project uses the [JSONPath Compliance Test Suite](https://github.com/jsonpath-standard/jsonpath-compliance-test-suite) as a git submodule for testing.\n\n## License\n\n`@swaggerexpert/jsonpath` is licensed under [Apache 2.0 license](https://github.com/swaggerexpert/jsonpath/blob/main/LICENSE).\n`@swaggerexpert/jsonpath` comes with an explicit [NOTICE](https://github.com/swaggerexpert/jsonpath/blob/main/NOTICE) file\ncontaining additional legal notices and information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaggerexpert%2Fjsonpath","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswaggerexpert%2Fjsonpath","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswaggerexpert%2Fjsonpath/lists"}