@swaggerexpert/jsonpath 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -8
- package/cjs/grammar.cjs +17 -17
- package/cjs/parse/index.cjs +6 -3
- package/cjs/parse/translators/CSTTranslator.cjs +8 -0
- package/es/grammar.mjs +17 -17
- package/es/parse/index.mjs +6 -3
- package/es/parse/translators/CSTTranslator.mjs +8 -0
- package/package.json +1 -1
- package/types/index.d.ts +2 -1
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ The development of this library contributed to the identification and formal sub
|
|
|
34
34
|
- [Installation](#installation)
|
|
35
35
|
- [Usage](#usage)
|
|
36
36
|
- [Parsing](#parsing)
|
|
37
|
+
- [Normalized paths](#normalized-paths)
|
|
37
38
|
- [Translators](#translators)
|
|
38
39
|
- [CST](#cst-translator)
|
|
39
40
|
- [XML](#xml-translator)
|
|
@@ -70,14 +71,6 @@ import { parse } from '@swaggerexpert/jsonpath';
|
|
|
70
71
|
const parseResult = parse('$.store.book[0].title');
|
|
71
72
|
```
|
|
72
73
|
|
|
73
|
-
or
|
|
74
|
-
|
|
75
|
-
```js
|
|
76
|
-
import { parse, CSTTranslator } from '@swaggerexpert/jsonpath';
|
|
77
|
-
|
|
78
|
-
const parseResult = parse('$.store.book[0].title', { translator: new CSTTranslator() });
|
|
79
|
-
```
|
|
80
|
-
|
|
81
74
|
**parseResult** variable has the following shape:
|
|
82
75
|
|
|
83
76
|
```
|
|
@@ -91,6 +84,31 @@ const parseResult = parse('$.store.book[0].title', { translator: new CSTTranslat
|
|
|
91
84
|
|
|
92
85
|
[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.
|
|
93
86
|
|
|
87
|
+
|
|
88
|
+
##### Normalized paths
|
|
89
|
+
|
|
90
|
+
[comment]: <> (SPDX-FileCopyrightText: Copyright (c) 2024 IETF Trust and the persons identified as the document authors. All rights reserved.)
|
|
91
|
+
[comment]: <> (SPDX-License-Identifier: BSD-3-Clause)
|
|
92
|
+
|
|
93
|
+
[Normalized Path](https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths) is a JSONPath query with restricted syntax.
|
|
94
|
+
A Normalized Path represents the identity of a node in a specific value.
|
|
95
|
+
There is precisely one Normalized Path identifying any particular node in a value.
|
|
96
|
+
Normalized Paths provide a predictable format that simplifies testing and post-processing of nodelists, e.g., to remove duplicate nodes.
|
|
97
|
+
Normalized Paths use the canonical bracket notation, rather than dot notation.
|
|
98
|
+
Single 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.
|
|
99
|
+
|
|
100
|
+
Parsing in normalized path mode can be enabled by setting `normalized` option to `true`.
|
|
101
|
+
|
|
102
|
+
```js
|
|
103
|
+
import { parse } from '@swaggerexpert/jsonpath';
|
|
104
|
+
|
|
105
|
+
parse("$['a']", { normalized: true });
|
|
106
|
+
parse("$[1]", { normalized: true });
|
|
107
|
+
parse("$[2]", { normalized: true });
|
|
108
|
+
parse("$['a']['b'][1]", { normalized: true });
|
|
109
|
+
parse("$['\\u000b']", { normalized: true });
|
|
110
|
+
```
|
|
111
|
+
|
|
94
112
|
##### Translators
|
|
95
113
|
|
|
96
114
|
`@swaggerexpert/jsonpath` provides several translators to convert the parse result into different tree representations.
|
package/cjs/grammar.cjs
CHANGED
|
@@ -16,9 +16,9 @@ function grammar() {
|
|
|
16
16
|
// ALT = 41
|
|
17
17
|
// CAT = 60
|
|
18
18
|
// REP = 32
|
|
19
|
-
// RNM =
|
|
20
|
-
// TLS =
|
|
21
|
-
// TBS =
|
|
19
|
+
// RNM = 178
|
|
20
|
+
// TLS = 64
|
|
21
|
+
// TBS = 28
|
|
22
22
|
// TRG = 20
|
|
23
23
|
// --- SABNF superset opcodes
|
|
24
24
|
// UDT = 0
|
|
@@ -2247,17 +2247,17 @@ function grammar() {
|
|
|
2247
2247
|
children: [1, 2, 3]
|
|
2248
2248
|
}; // CAT
|
|
2249
2249
|
this.rules[69].opcodes[1] = {
|
|
2250
|
-
type:
|
|
2251
|
-
|
|
2252
|
-
}; //
|
|
2250
|
+
type: 4,
|
|
2251
|
+
index: 80
|
|
2252
|
+
}; // RNM(left-bracket)
|
|
2253
2253
|
this.rules[69].opcodes[2] = {
|
|
2254
2254
|
type: 4,
|
|
2255
2255
|
index: 70
|
|
2256
2256
|
}; // RNM(normal-selector)
|
|
2257
2257
|
this.rules[69].opcodes[3] = {
|
|
2258
|
-
type:
|
|
2259
|
-
|
|
2260
|
-
}; //
|
|
2258
|
+
type: 4,
|
|
2259
|
+
index: 81
|
|
2260
|
+
}; // RNM(right-bracket)
|
|
2261
2261
|
|
|
2262
2262
|
/* normal-selector */
|
|
2263
2263
|
this.rules[70].opcodes = [];
|
|
@@ -2281,9 +2281,9 @@ function grammar() {
|
|
|
2281
2281
|
children: [1, 2, 4]
|
|
2282
2282
|
}; // CAT
|
|
2283
2283
|
this.rules[71].opcodes[1] = {
|
|
2284
|
-
type:
|
|
2285
|
-
|
|
2286
|
-
}; //
|
|
2284
|
+
type: 4,
|
|
2285
|
+
index: 87
|
|
2286
|
+
}; // RNM(squote)
|
|
2287
2287
|
this.rules[71].opcodes[2] = {
|
|
2288
2288
|
type: 3,
|
|
2289
2289
|
min: 0,
|
|
@@ -2294,9 +2294,9 @@ function grammar() {
|
|
|
2294
2294
|
index: 72
|
|
2295
2295
|
}; // RNM(normal-single-quoted)
|
|
2296
2296
|
this.rules[71].opcodes[4] = {
|
|
2297
|
-
type:
|
|
2298
|
-
|
|
2299
|
-
}; //
|
|
2297
|
+
type: 4,
|
|
2298
|
+
index: 87
|
|
2299
|
+
}; // RNM(squote)
|
|
2300
2300
|
|
|
2301
2301
|
/* normal-single-quoted */
|
|
2302
2302
|
this.rules[72].opcodes = [];
|
|
@@ -2784,9 +2784,9 @@ function grammar() {
|
|
|
2784
2784
|
str += "\n";
|
|
2785
2785
|
str += "; https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths\n";
|
|
2786
2786
|
str += "normalized-path = root-identifier *(normal-index-segment)\n";
|
|
2787
|
-
str += "normal-index-segment =
|
|
2787
|
+
str += "normal-index-segment = left-bracket normal-selector right-bracket ; MODIFICATION: surrogate text rule used\n";
|
|
2788
2788
|
str += "normal-selector = normal-name-selector / normal-index-selector\n";
|
|
2789
|
-
str += "normal-name-selector =
|
|
2789
|
+
str += "normal-name-selector = squote *normal-single-quoted squote ; 'string', MODIFICATION: surrogate text rule used\n";
|
|
2790
2790
|
str += "normal-single-quoted = normal-unescaped /\n";
|
|
2791
2791
|
str += " ESC normal-escapable\n";
|
|
2792
2792
|
str += "normal-unescaped = ; omit %x0-1F control codes\n";
|
package/cjs/parse/index.cjs
CHANGED
|
@@ -9,9 +9,11 @@ var _JSONPathParseError = _interopRequireDefault(require("../errors/JSONPathPars
|
|
|
9
9
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
10
|
const grammar = new _grammar.default();
|
|
11
11
|
const parse = (jsonPath, {
|
|
12
|
-
|
|
12
|
+
normalized = false,
|
|
13
13
|
stats = false,
|
|
14
|
-
trace = false
|
|
14
|
+
trace = false,
|
|
15
|
+
translator = new _CSTTranslator.default(),
|
|
16
|
+
test = 3
|
|
15
17
|
} = {}) => {
|
|
16
18
|
if (typeof jsonPath !== 'string') {
|
|
17
19
|
throw new TypeError('JSONPath must be a string');
|
|
@@ -22,7 +24,8 @@ const parse = (jsonPath, {
|
|
|
22
24
|
if (translator) parser.ast = translator;
|
|
23
25
|
if (stats) parser.stats = new _apgLite.Stats();
|
|
24
26
|
if (trace) parser.trace = new _apgLite.Trace();
|
|
25
|
-
const
|
|
27
|
+
const startRule = normalized ? 'normalized-path' : 'jsonpath-query';
|
|
28
|
+
const result = parser.parse(grammar, startRule, jsonPath);
|
|
26
29
|
return {
|
|
27
30
|
result,
|
|
28
31
|
tree: (_parser$ast = parser.ast) == null ? void 0 : _parser$ast.getTree(),
|
|
@@ -82,6 +82,14 @@ class CSTTranslator extends _apgLite.Ast {
|
|
|
82
82
|
// https://www.rfc-editor.org/rfc/rfc9535#section-2.5.2.1
|
|
83
83
|
this.callbacks['descendant-segment'] = (0, _cst.default)('descendant-segment');
|
|
84
84
|
|
|
85
|
+
// https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths
|
|
86
|
+
this.callbacks['normalized-path'] = (0, _cst.default)('normalized-path');
|
|
87
|
+
this.callbacks['normal-index-segment'] = (0, _cst.default)('normal-index-segment');
|
|
88
|
+
this.callbacks['normal-selector'] = (0, _cst.default)('normal-selector');
|
|
89
|
+
this.callbacks['normal-name-selector'] = (0, _cst.default)('normal-name-selector');
|
|
90
|
+
this.callbacks['normal-index-selector'] = (0, _cst.default)('normal-index-selector');
|
|
91
|
+
this.callbacks['normal-single-quoted'] = (0, _cst.default)('normal-single-quoted');
|
|
92
|
+
|
|
85
93
|
// Surrogate named rules
|
|
86
94
|
this.callbacks['dot-prefix'] = (0, _cst.default)('text');
|
|
87
95
|
this.callbacks['double-dot-prefix'] = (0, _cst.default)('text');
|
package/es/grammar.mjs
CHANGED
|
@@ -12,9 +12,9 @@ export default function grammar() {
|
|
|
12
12
|
// ALT = 41
|
|
13
13
|
// CAT = 60
|
|
14
14
|
// REP = 32
|
|
15
|
-
// RNM =
|
|
16
|
-
// TLS =
|
|
17
|
-
// TBS =
|
|
15
|
+
// RNM = 178
|
|
16
|
+
// TLS = 64
|
|
17
|
+
// TBS = 28
|
|
18
18
|
// TRG = 20
|
|
19
19
|
// --- SABNF superset opcodes
|
|
20
20
|
// UDT = 0
|
|
@@ -2243,17 +2243,17 @@ export default function grammar() {
|
|
|
2243
2243
|
children: [1, 2, 3]
|
|
2244
2244
|
}; // CAT
|
|
2245
2245
|
this.rules[69].opcodes[1] = {
|
|
2246
|
-
type:
|
|
2247
|
-
|
|
2248
|
-
}; //
|
|
2246
|
+
type: 4,
|
|
2247
|
+
index: 80
|
|
2248
|
+
}; // RNM(left-bracket)
|
|
2249
2249
|
this.rules[69].opcodes[2] = {
|
|
2250
2250
|
type: 4,
|
|
2251
2251
|
index: 70
|
|
2252
2252
|
}; // RNM(normal-selector)
|
|
2253
2253
|
this.rules[69].opcodes[3] = {
|
|
2254
|
-
type:
|
|
2255
|
-
|
|
2256
|
-
}; //
|
|
2254
|
+
type: 4,
|
|
2255
|
+
index: 81
|
|
2256
|
+
}; // RNM(right-bracket)
|
|
2257
2257
|
|
|
2258
2258
|
/* normal-selector */
|
|
2259
2259
|
this.rules[70].opcodes = [];
|
|
@@ -2277,9 +2277,9 @@ export default function grammar() {
|
|
|
2277
2277
|
children: [1, 2, 4]
|
|
2278
2278
|
}; // CAT
|
|
2279
2279
|
this.rules[71].opcodes[1] = {
|
|
2280
|
-
type:
|
|
2281
|
-
|
|
2282
|
-
}; //
|
|
2280
|
+
type: 4,
|
|
2281
|
+
index: 87
|
|
2282
|
+
}; // RNM(squote)
|
|
2283
2283
|
this.rules[71].opcodes[2] = {
|
|
2284
2284
|
type: 3,
|
|
2285
2285
|
min: 0,
|
|
@@ -2290,9 +2290,9 @@ export default function grammar() {
|
|
|
2290
2290
|
index: 72
|
|
2291
2291
|
}; // RNM(normal-single-quoted)
|
|
2292
2292
|
this.rules[71].opcodes[4] = {
|
|
2293
|
-
type:
|
|
2294
|
-
|
|
2295
|
-
}; //
|
|
2293
|
+
type: 4,
|
|
2294
|
+
index: 87
|
|
2295
|
+
}; // RNM(squote)
|
|
2296
2296
|
|
|
2297
2297
|
/* normal-single-quoted */
|
|
2298
2298
|
this.rules[72].opcodes = [];
|
|
@@ -2780,9 +2780,9 @@ export default function grammar() {
|
|
|
2780
2780
|
str += "\n";
|
|
2781
2781
|
str += "; https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths\n";
|
|
2782
2782
|
str += "normalized-path = root-identifier *(normal-index-segment)\n";
|
|
2783
|
-
str += "normal-index-segment =
|
|
2783
|
+
str += "normal-index-segment = left-bracket normal-selector right-bracket ; MODIFICATION: surrogate text rule used\n";
|
|
2784
2784
|
str += "normal-selector = normal-name-selector / normal-index-selector\n";
|
|
2785
|
-
str += "normal-name-selector =
|
|
2785
|
+
str += "normal-name-selector = squote *normal-single-quoted squote ; 'string', MODIFICATION: surrogate text rule used\n";
|
|
2786
2786
|
str += "normal-single-quoted = normal-unescaped /\n";
|
|
2787
2787
|
str += " ESC normal-escapable\n";
|
|
2788
2788
|
str += "normal-unescaped = ; omit %x0-1F control codes\n";
|
package/es/parse/index.mjs
CHANGED
|
@@ -4,9 +4,11 @@ import CSTTranslator from "./translators/CSTTranslator.mjs";
|
|
|
4
4
|
import JSONPathParseError from "../errors/JSONPathParseError.mjs";
|
|
5
5
|
const grammar = new Grammar();
|
|
6
6
|
const parse = (jsonPath, {
|
|
7
|
-
|
|
7
|
+
normalized = false,
|
|
8
8
|
stats = false,
|
|
9
|
-
trace = false
|
|
9
|
+
trace = false,
|
|
10
|
+
translator = new CSTTranslator(),
|
|
11
|
+
test = 3
|
|
10
12
|
} = {}) => {
|
|
11
13
|
if (typeof jsonPath !== 'string') {
|
|
12
14
|
throw new TypeError('JSONPath must be a string');
|
|
@@ -17,7 +19,8 @@ const parse = (jsonPath, {
|
|
|
17
19
|
if (translator) parser.ast = translator;
|
|
18
20
|
if (stats) parser.stats = new Stats();
|
|
19
21
|
if (trace) parser.trace = new Trace();
|
|
20
|
-
const
|
|
22
|
+
const startRule = normalized ? 'normalized-path' : 'jsonpath-query';
|
|
23
|
+
const result = parser.parse(grammar, startRule, jsonPath);
|
|
21
24
|
return {
|
|
22
25
|
result,
|
|
23
26
|
tree: (_parser$ast = parser.ast) === null || _parser$ast === void 0 ? void 0 : _parser$ast.getTree(),
|
|
@@ -77,6 +77,14 @@ class CSTTranslator extends AST {
|
|
|
77
77
|
// https://www.rfc-editor.org/rfc/rfc9535#section-2.5.2.1
|
|
78
78
|
this.callbacks['descendant-segment'] = cstCallback('descendant-segment');
|
|
79
79
|
|
|
80
|
+
// https://www.rfc-editor.org/rfc/rfc9535#name-normalized-paths
|
|
81
|
+
this.callbacks['normalized-path'] = cstCallback('normalized-path');
|
|
82
|
+
this.callbacks['normal-index-segment'] = cstCallback('normal-index-segment');
|
|
83
|
+
this.callbacks['normal-selector'] = cstCallback('normal-selector');
|
|
84
|
+
this.callbacks['normal-name-selector'] = cstCallback('normal-name-selector');
|
|
85
|
+
this.callbacks['normal-index-selector'] = cstCallback('normal-index-selector');
|
|
86
|
+
this.callbacks['normal-single-quoted'] = cstCallback('normal-single-quoted');
|
|
87
|
+
|
|
80
88
|
// Surrogate named rules
|
|
81
89
|
this.callbacks['dot-prefix'] = cstCallback('text');
|
|
82
90
|
this.callbacks['double-dot-prefix'] = cstCallback('text');
|
package/package.json
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
export function parse(jsonpath: string, options?: ParseOptions): ParseResult;
|
|
5
5
|
|
|
6
6
|
export interface ParseOptions {
|
|
7
|
-
readonly
|
|
7
|
+
readonly normalized?: boolean;
|
|
8
8
|
readonly stats?: boolean;
|
|
9
9
|
readonly trace?: boolean;
|
|
10
|
+
readonly translator?: Translator | null;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export interface Translator<TTree = unknown> {
|