@swaggerexpert/jsonpath 3.2.3 → 3.2.5
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/cjs/apg-lite.cjs +1221 -0
- package/cjs/compile.cjs +50 -0
- package/cjs/errors/JSONPathCompileError.cjs +8 -0
- package/cjs/errors/JSONPathError.cjs +44 -0
- package/cjs/errors/JSONPathParseError.cjs +8 -0
- package/cjs/escape.cjs +59 -0
- package/cjs/grammar.cjs +2839 -0
- package/cjs/index.cjs +31 -0
- package/cjs/parse/callbacks/cst.cjs +49 -0
- package/cjs/parse/index.cjs +41 -0
- package/cjs/parse/trace/Expectations.cjs +10 -0
- package/cjs/parse/trace/Trace.cjs +35 -0
- package/cjs/parse/translators/ASTTranslator/decoders.cjs +83 -0
- package/cjs/parse/translators/ASTTranslator/index.cjs +15 -0
- package/cjs/parse/translators/ASTTranslator/transformers.cjs +411 -0
- package/cjs/parse/translators/CSTOptimizedTranslator.cjs +39 -0
- package/cjs/parse/translators/CSTTranslator.cjs +118 -0
- package/cjs/parse/translators/XMLTranslator.cjs +12 -0
- package/cjs/test/index.cjs +25 -0
- package/es/compile.mjs +45 -0
- package/es/errors/JSONPathCompileError.mjs +3 -0
- package/es/errors/JSONPathError.mjs +40 -0
- package/es/errors/JSONPathParseError.mjs +3 -0
- package/es/escape.mjs +55 -0
- package/es/grammar.mjs +2835 -0
- package/es/index.mjs +13 -0
- package/es/parse/callbacks/cst.mjs +44 -0
- package/es/parse/index.mjs +36 -0
- package/es/parse/trace/Expectations.mjs +6 -0
- package/es/parse/trace/Trace.mjs +30 -0
- package/es/parse/translators/ASTTranslator/decoders.mjs +75 -0
- package/es/parse/translators/ASTTranslator/index.mjs +9 -0
- package/es/parse/translators/ASTTranslator/transformers.mjs +405 -0
- package/es/parse/translators/CSTOptimizedTranslator.mjs +34 -0
- package/es/parse/translators/CSTTranslator.mjs +113 -0
- package/es/parse/translators/XMLTranslator.mjs +7 -0
- package/es/test/index.mjs +20 -0
- package/package.json +1 -1
- package/types/index.d.ts +24 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _CSTTranslator = _interopRequireDefault(require("./CSTTranslator.cjs"));
|
|
6
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
class CSTOptimizedTranslator extends _CSTTranslator.default {
|
|
8
|
+
collapsibleTypes = ['single-quoted', 'double-quoted', 'normal-single-quoted'];
|
|
9
|
+
droppableTypes = ['text', 'segments', 'singular-query-segments'];
|
|
10
|
+
constructor({
|
|
11
|
+
collapsibleTypes,
|
|
12
|
+
droppableTypes
|
|
13
|
+
} = {}) {
|
|
14
|
+
super();
|
|
15
|
+
if (Array.isArray(collapsibleTypes)) {
|
|
16
|
+
this.collapsibleTypes = collapsibleTypes;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(droppableTypes)) {
|
|
19
|
+
this.droppableTypes = droppableTypes;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
getTree() {
|
|
23
|
+
const options = {
|
|
24
|
+
optimize: true,
|
|
25
|
+
collapsibleTypes: this.collapsibleTypes,
|
|
26
|
+
droppableTypes: this.droppableTypes
|
|
27
|
+
};
|
|
28
|
+
const data = {
|
|
29
|
+
stack: [],
|
|
30
|
+
root: null,
|
|
31
|
+
options
|
|
32
|
+
};
|
|
33
|
+
this.translate(data);
|
|
34
|
+
delete data.stack;
|
|
35
|
+
delete data.options;
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
var _default = exports.default = CSTOptimizedTranslator;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _apgLite = require("../../apg-lite.cjs");
|
|
6
|
+
var _cst = _interopRequireDefault(require("../callbacks/cst.cjs"));
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
class CSTTranslator extends _apgLite.Ast {
|
|
9
|
+
constructor() {
|
|
10
|
+
super();
|
|
11
|
+
|
|
12
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.1.1
|
|
13
|
+
this.callbacks['jsonpath-query'] = (0, _cst.default)('jsonpath-query');
|
|
14
|
+
this.callbacks['segments'] = (0, _cst.default)('segments');
|
|
15
|
+
this.callbacks['B'] = (0, _cst.default)('text');
|
|
16
|
+
this.callbacks['S'] = (0, _cst.default)('text');
|
|
17
|
+
|
|
18
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.2.1
|
|
19
|
+
this.callbacks['root-identifier'] = (0, _cst.default)('root-identifier');
|
|
20
|
+
|
|
21
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.3
|
|
22
|
+
this.callbacks['selector'] = (0, _cst.default)('selector');
|
|
23
|
+
|
|
24
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.3.1.1
|
|
25
|
+
this.callbacks['name-selector'] = (0, _cst.default)('name-selector');
|
|
26
|
+
this.callbacks['string-literal'] = (0, _cst.default)('string-literal');
|
|
27
|
+
this.callbacks['double-quoted'] = (0, _cst.default)('double-quoted');
|
|
28
|
+
this.callbacks['single-quoted'] = (0, _cst.default)('single-quoted');
|
|
29
|
+
|
|
30
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.3.2.1
|
|
31
|
+
this.callbacks['wildcard-selector'] = (0, _cst.default)('wildcard-selector');
|
|
32
|
+
|
|
33
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.3.3.1
|
|
34
|
+
this.callbacks['index-selector'] = (0, _cst.default)('index-selector');
|
|
35
|
+
|
|
36
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.3.4.1
|
|
37
|
+
this.callbacks['slice-selector'] = (0, _cst.default)('slice-selector');
|
|
38
|
+
this.callbacks['start'] = (0, _cst.default)('start');
|
|
39
|
+
this.callbacks['end'] = (0, _cst.default)('end');
|
|
40
|
+
this.callbacks['step'] = (0, _cst.default)('step');
|
|
41
|
+
|
|
42
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.3.5.1
|
|
43
|
+
this.callbacks['filter-selector'] = (0, _cst.default)('filter-selector');
|
|
44
|
+
this.callbacks['logical-expr'] = (0, _cst.default)('logical-expr');
|
|
45
|
+
this.callbacks['logical-or-expr'] = (0, _cst.default)('logical-or-expr');
|
|
46
|
+
this.callbacks['logical-and-expr'] = (0, _cst.default)('logical-and-expr');
|
|
47
|
+
this.callbacks['basic-expr'] = (0, _cst.default)('basic-expr');
|
|
48
|
+
this.callbacks['paren-expr'] = (0, _cst.default)('paren-expr');
|
|
49
|
+
this.callbacks['logical-not-op'] = (0, _cst.default)('logical-not-op');
|
|
50
|
+
this.callbacks['test-expr'] = (0, _cst.default)('test-expr');
|
|
51
|
+
this.callbacks['filter-query'] = (0, _cst.default)('filter-query');
|
|
52
|
+
this.callbacks['rel-query'] = (0, _cst.default)('rel-query');
|
|
53
|
+
this.callbacks['current-node-identifier'] = (0, _cst.default)('current-node-identifier');
|
|
54
|
+
this.callbacks['comparison-expr'] = (0, _cst.default)('comparison-expr');
|
|
55
|
+
this.callbacks['literal'] = (0, _cst.default)('literal');
|
|
56
|
+
this.callbacks['comparable'] = (0, _cst.default)('comparable');
|
|
57
|
+
this.callbacks['comparison-op'] = (0, _cst.default)('comparison-op');
|
|
58
|
+
this.callbacks['singular-query'] = (0, _cst.default)('singular-query');
|
|
59
|
+
this.callbacks['rel-singular-query'] = (0, _cst.default)('rel-singular-query');
|
|
60
|
+
this.callbacks['abs-singular-query'] = (0, _cst.default)('abs-singular-query');
|
|
61
|
+
this.callbacks['singular-query-segments'] = (0, _cst.default)('singular-query-segments');
|
|
62
|
+
this.callbacks['name-segment'] = (0, _cst.default)('name-segment');
|
|
63
|
+
this.callbacks['index-segment'] = (0, _cst.default)('index-segment');
|
|
64
|
+
this.callbacks['number'] = (0, _cst.default)('number');
|
|
65
|
+
this.callbacks['true'] = (0, _cst.default)('true');
|
|
66
|
+
this.callbacks['false'] = (0, _cst.default)('false');
|
|
67
|
+
this.callbacks['null'] = (0, _cst.default)('null');
|
|
68
|
+
|
|
69
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.4
|
|
70
|
+
this.callbacks['function-name'] = (0, _cst.default)('function-name');
|
|
71
|
+
this.callbacks['function-expr'] = (0, _cst.default)('function-expr');
|
|
72
|
+
this.callbacks['function-argument'] = (0, _cst.default)('function-argument');
|
|
73
|
+
|
|
74
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.5
|
|
75
|
+
this.callbacks['segment'] = (0, _cst.default)('segment');
|
|
76
|
+
|
|
77
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.5.1.1
|
|
78
|
+
this.callbacks['child-segment'] = (0, _cst.default)('child-segment');
|
|
79
|
+
this.callbacks['bracketed-selection'] = (0, _cst.default)('bracketed-selection');
|
|
80
|
+
this.callbacks['member-name-shorthand'] = (0, _cst.default)('member-name-shorthand');
|
|
81
|
+
|
|
82
|
+
// https://www.rfc-editor.org/rfc/rfc9535#section-2.5.2.1
|
|
83
|
+
this.callbacks['descendant-segment'] = (0, _cst.default)('descendant-segment');
|
|
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
|
+
|
|
93
|
+
// Surrogate named rules
|
|
94
|
+
this.callbacks['dot-prefix'] = (0, _cst.default)('text');
|
|
95
|
+
this.callbacks['double-dot-prefix'] = (0, _cst.default)('text');
|
|
96
|
+
this.callbacks['left-bracket'] = (0, _cst.default)('text');
|
|
97
|
+
this.callbacks['right-bracket'] = (0, _cst.default)('text');
|
|
98
|
+
this.callbacks['comma'] = (0, _cst.default)('text');
|
|
99
|
+
this.callbacks['colon'] = (0, _cst.default)('text');
|
|
100
|
+
this.callbacks['dquote'] = (0, _cst.default)('text');
|
|
101
|
+
this.callbacks['squote'] = (0, _cst.default)('text');
|
|
102
|
+
this.callbacks['questionmark'] = (0, _cst.default)('text');
|
|
103
|
+
this.callbacks['disjunction'] = (0, _cst.default)('text');
|
|
104
|
+
this.callbacks['conjunction'] = (0, _cst.default)('text');
|
|
105
|
+
this.callbacks['left-paren'] = (0, _cst.default)('text');
|
|
106
|
+
this.callbacks['right-paren'] = (0, _cst.default)('text');
|
|
107
|
+
}
|
|
108
|
+
getTree() {
|
|
109
|
+
const data = {
|
|
110
|
+
stack: [],
|
|
111
|
+
root: null
|
|
112
|
+
};
|
|
113
|
+
this.translate(data);
|
|
114
|
+
delete data.stack;
|
|
115
|
+
return data;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
var _default = exports.default = CSTTranslator;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _CSTTranslator = _interopRequireDefault(require("./CSTTranslator.cjs"));
|
|
6
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
class XMLTranslator extends _CSTTranslator.default {
|
|
8
|
+
getTree() {
|
|
9
|
+
return this.toXml();
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
var _default = exports.default = XMLTranslator;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _index = _interopRequireDefault(require("../parse/index.cjs"));
|
|
6
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
const test = (jsonPath, {
|
|
8
|
+
normalized = false
|
|
9
|
+
} = {}) => {
|
|
10
|
+
if (typeof jsonPath !== 'string') return false;
|
|
11
|
+
try {
|
|
12
|
+
const {
|
|
13
|
+
result
|
|
14
|
+
} = (0, _index.default)(jsonPath, {
|
|
15
|
+
normalized,
|
|
16
|
+
stats: false,
|
|
17
|
+
trace: false,
|
|
18
|
+
translator: null
|
|
19
|
+
});
|
|
20
|
+
return result.success;
|
|
21
|
+
} catch {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var _default = exports.default = test;
|
package/es/compile.mjs
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import escape from "./escape.mjs";
|
|
2
|
+
import JSONPathCompileError from "./errors/JSONPathCompileError.mjs";
|
|
3
|
+
/**
|
|
4
|
+
* Compiles an array of selectors into a normalized JSONPath.
|
|
5
|
+
* Follows RFC 9535 Section 2.7 normalized path format.
|
|
6
|
+
*
|
|
7
|
+
* @param {Array<string|number>} selectors - Array of name selectors (strings) or index selectors (numbers)
|
|
8
|
+
* @returns {string} A normalized JSONPath string
|
|
9
|
+
* @throws {JSONPathCompileError} If selectors is not an array or contains invalid selector types
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* compile(['a', 'b', 1]) // returns "$['a']['b'][1]"
|
|
13
|
+
* compile([]) // returns "$"
|
|
14
|
+
* compile(['foo', 0, 'bar']) // returns "$['foo'][0]['bar']"
|
|
15
|
+
*/
|
|
16
|
+
const compile = selectors => {
|
|
17
|
+
if (!Array.isArray(selectors)) {
|
|
18
|
+
throw new JSONPathCompileError(`Selectors must be an array, got: ${typeof selectors}`, {
|
|
19
|
+
selectors
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const segments = selectors.map(selector => {
|
|
24
|
+
if (typeof selector === 'string') {
|
|
25
|
+
// Name selector: escape and wrap in single quotes
|
|
26
|
+
return `['${escape(selector)}']`;
|
|
27
|
+
}
|
|
28
|
+
if (typeof selector === 'number') {
|
|
29
|
+
// Index selector: must be a non-negative safe integer (RFC 9535 Section 2.1)
|
|
30
|
+
if (!Number.isSafeInteger(selector) || selector < 0) {
|
|
31
|
+
throw new TypeError(`Index selector must be a non-negative safe integer, got: ${selector}`);
|
|
32
|
+
}
|
|
33
|
+
return `[${selector}]`;
|
|
34
|
+
}
|
|
35
|
+
throw new TypeError(`Selector must be a string or non-negative integer, got: ${typeof selector}`);
|
|
36
|
+
});
|
|
37
|
+
return `$${segments.join('')}`;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
throw new JSONPathCompileError('Failed to compile normalized JSONPath', {
|
|
40
|
+
cause: error,
|
|
41
|
+
selectors
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export default compile;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
class JSONPathError extends Error {
|
|
2
|
+
constructor(message, options = undefined) {
|
|
3
|
+
super(message, options);
|
|
4
|
+
this.name = this.constructor.name;
|
|
5
|
+
if (typeof message === 'string') {
|
|
6
|
+
this.message = message;
|
|
7
|
+
}
|
|
8
|
+
if (typeof Error.captureStackTrace === 'function') {
|
|
9
|
+
Error.captureStackTrace(this, this.constructor);
|
|
10
|
+
} else {
|
|
11
|
+
this.stack = new Error(message).stack;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This needs to stay here until our minimum supported version of Node.js is >= 16.9.0.
|
|
16
|
+
* Node.js is >= 16.9.0 supports error causes natively.
|
|
17
|
+
*/
|
|
18
|
+
if (options != null && typeof options === 'object' && Object.prototype.hasOwnProperty.call(options, 'cause') && !('cause' in this)) {
|
|
19
|
+
const {
|
|
20
|
+
cause
|
|
21
|
+
} = options;
|
|
22
|
+
this.cause = cause;
|
|
23
|
+
if (cause instanceof Error && 'stack' in cause) {
|
|
24
|
+
this.stack = `${this.stack}\nCAUSE: ${cause.stack}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Allows to assign arbitrary properties to the error object.
|
|
30
|
+
*/
|
|
31
|
+
if (options != null && typeof options === 'object') {
|
|
32
|
+
const {
|
|
33
|
+
cause,
|
|
34
|
+
...causelessOptions
|
|
35
|
+
} = options;
|
|
36
|
+
Object.assign(this, causelessOptions);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export default JSONPathError;
|
package/es/escape.mjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Escapes a string for use in a normalized JSONPath name selector.
|
|
3
|
+
* Follows RFC 9535 Section 2.7 escaping rules for single-quoted strings.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} selector - The string to escape
|
|
6
|
+
* @returns {string} The escaped string (without surrounding quotes)
|
|
7
|
+
*/
|
|
8
|
+
const escape = selector => {
|
|
9
|
+
if (typeof selector !== 'string') {
|
|
10
|
+
throw new TypeError('Selector must be a string');
|
|
11
|
+
}
|
|
12
|
+
let escaped = '';
|
|
13
|
+
for (const char of selector) {
|
|
14
|
+
const codePoint = char.codePointAt(0);
|
|
15
|
+
switch (codePoint) {
|
|
16
|
+
case 0x08:
|
|
17
|
+
// backspace
|
|
18
|
+
escaped += '\\b';
|
|
19
|
+
break;
|
|
20
|
+
case 0x09:
|
|
21
|
+
// horizontal tab
|
|
22
|
+
escaped += '\\t';
|
|
23
|
+
break;
|
|
24
|
+
case 0x0a:
|
|
25
|
+
// line feed
|
|
26
|
+
escaped += '\\n';
|
|
27
|
+
break;
|
|
28
|
+
case 0x0c:
|
|
29
|
+
// form feed
|
|
30
|
+
escaped += '\\f';
|
|
31
|
+
break;
|
|
32
|
+
case 0x0d:
|
|
33
|
+
// carriage return
|
|
34
|
+
escaped += '\\r';
|
|
35
|
+
break;
|
|
36
|
+
case 0x27:
|
|
37
|
+
// apostrophe '
|
|
38
|
+
escaped += "\\'";
|
|
39
|
+
break;
|
|
40
|
+
case 0x5c:
|
|
41
|
+
// backslash \
|
|
42
|
+
escaped += '\\\\';
|
|
43
|
+
break;
|
|
44
|
+
default:
|
|
45
|
+
// Other control characters (U+0000-U+001F except those handled above)
|
|
46
|
+
if (codePoint <= 0x1f) {
|
|
47
|
+
escaped += `\\u${codePoint.toString(16).padStart(4, '0')}`;
|
|
48
|
+
} else {
|
|
49
|
+
escaped += char;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return escaped;
|
|
54
|
+
};
|
|
55
|
+
export default escape;
|