@swaggerexpert/jsonpath 3.2.4 → 4.0.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.
Files changed (84) hide show
  1. package/README.md +225 -18
  2. package/cjs/errors/JSONNormalizedPathError.cjs +8 -0
  3. package/cjs/errors/JSONPathError.cjs +1 -1
  4. package/cjs/errors/{JSONPathCompileError.cjs → JSONPathEvaluateError.cjs} +2 -2
  5. package/cjs/evaluate/evaluators/comparable.cjs +44 -0
  6. package/cjs/evaluate/evaluators/comparison-expr.cjs +37 -0
  7. package/cjs/evaluate/evaluators/filter-query.cjs +182 -0
  8. package/cjs/evaluate/evaluators/function-expr.cjs +106 -0
  9. package/cjs/evaluate/evaluators/literal.cjs +25 -0
  10. package/cjs/evaluate/evaluators/logical-expr.cjs +96 -0
  11. package/cjs/evaluate/evaluators/singular-query.cjs +103 -0
  12. package/cjs/evaluate/functions/count.cjs +35 -0
  13. package/cjs/evaluate/functions/index.cjs +15 -0
  14. package/cjs/evaluate/functions/length.cjs +42 -0
  15. package/cjs/evaluate/functions/match.cjs +49 -0
  16. package/cjs/evaluate/functions/search.cjs +49 -0
  17. package/cjs/evaluate/functions/value.cjs +36 -0
  18. package/cjs/evaluate/index.cjs +182 -0
  19. package/cjs/evaluate/realms/EvaluationRealm.cjs +154 -0
  20. package/cjs/evaluate/realms/json/index.cjs +246 -0
  21. package/cjs/evaluate/utils/guards.cjs +129 -0
  22. package/cjs/evaluate/utils/i-regexp.cjs +118 -0
  23. package/cjs/evaluate/visitors/bracketed-selection.cjs +35 -0
  24. package/cjs/evaluate/visitors/filter-selector.cjs +43 -0
  25. package/cjs/evaluate/visitors/index-selector.cjs +55 -0
  26. package/cjs/evaluate/visitors/name-selector.cjs +38 -0
  27. package/cjs/evaluate/visitors/segment.cjs +99 -0
  28. package/cjs/evaluate/visitors/selector.cjs +47 -0
  29. package/cjs/evaluate/visitors/slice-selector.cjs +115 -0
  30. package/cjs/evaluate/visitors/wildcard-selector.cjs +32 -0
  31. package/cjs/index.cjs +16 -7
  32. package/cjs/normalized-path.cjs +145 -0
  33. package/cjs/parse/callbacks/cst.cjs +2 -4
  34. package/cjs/parse/index.cjs +3 -1
  35. package/cjs/parse/translators/ASTTranslator/index.cjs +1 -1
  36. package/cjs/parse/translators/ASTTranslator/transformers.cjs +246 -5
  37. package/cjs/parse/translators/CSTOptimizedTranslator.cjs +1 -3
  38. package/cjs/parse/translators/CSTTranslator.cjs +1 -2
  39. package/cjs/test/index.cjs +4 -2
  40. package/es/errors/JSONNormalizedPathError.mjs +3 -0
  41. package/es/errors/JSONPathError.mjs +1 -1
  42. package/es/errors/JSONPathEvaluateError.mjs +3 -0
  43. package/es/evaluate/evaluators/comparable.mjs +38 -0
  44. package/es/evaluate/evaluators/comparison-expr.mjs +31 -0
  45. package/es/evaluate/evaluators/filter-query.mjs +175 -0
  46. package/es/evaluate/evaluators/function-expr.mjs +99 -0
  47. package/es/evaluate/evaluators/literal.mjs +21 -0
  48. package/es/evaluate/evaluators/logical-expr.mjs +89 -0
  49. package/es/evaluate/evaluators/singular-query.mjs +97 -0
  50. package/es/evaluate/functions/count.mjs +30 -0
  51. package/es/evaluate/functions/index.mjs +13 -0
  52. package/es/evaluate/functions/length.mjs +37 -0
  53. package/es/evaluate/functions/match.mjs +44 -0
  54. package/es/evaluate/functions/search.mjs +44 -0
  55. package/es/evaluate/functions/value.mjs +31 -0
  56. package/es/evaluate/index.mjs +174 -0
  57. package/es/evaluate/realms/EvaluationRealm.mjs +148 -0
  58. package/es/evaluate/realms/json/index.mjs +240 -0
  59. package/es/evaluate/utils/guards.mjs +114 -0
  60. package/es/evaluate/utils/i-regexp.mjs +113 -0
  61. package/es/evaluate/visitors/bracketed-selection.mjs +29 -0
  62. package/es/evaluate/visitors/filter-selector.mjs +37 -0
  63. package/es/evaluate/visitors/index-selector.mjs +51 -0
  64. package/es/evaluate/visitors/name-selector.mjs +34 -0
  65. package/es/evaluate/visitors/segment.mjs +91 -0
  66. package/es/evaluate/visitors/selector.mjs +41 -0
  67. package/es/evaluate/visitors/slice-selector.mjs +111 -0
  68. package/es/evaluate/visitors/wildcard-selector.mjs +28 -0
  69. package/es/index.mjs +7 -3
  70. package/es/normalized-path.mjs +136 -0
  71. package/es/parse/callbacks/cst.mjs +2 -4
  72. package/es/parse/index.mjs +3 -1
  73. package/es/parse/translators/ASTTranslator/index.mjs +1 -1
  74. package/es/parse/translators/ASTTranslator/transformers.mjs +246 -5
  75. package/es/parse/translators/CSTOptimizedTranslator.mjs +1 -3
  76. package/es/parse/translators/CSTTranslator.mjs +1 -2
  77. package/es/test/index.mjs +4 -2
  78. package/package.json +4 -2
  79. package/types/index.d.ts +135 -8
  80. package/cjs/compile.cjs +0 -50
  81. package/cjs/escape.cjs +0 -59
  82. package/es/compile.mjs +0 -45
  83. package/es/errors/JSONPathCompileError.mjs +0 -3
  84. package/es/escape.mjs +0 -55
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.constructRegex = void 0;
5
+ /**
6
+ * I-Regexp (RFC 9485) utilities for JSONPath match() and search() functions.
7
+ *
8
+ * @see https://www.rfc-editor.org/rfc/rfc9485 - I-Regexp specification
9
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.1 - match() function
10
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.4.2 - search() function
11
+ */
12
+
13
+ const regexpCache = new Map();
14
+
15
+ /**
16
+ * Validate and transform I-Regexp pattern to ECMAScript regex pattern.
17
+ * Returns null if pattern contains non-I-Regexp features:
18
+ * - Backreferences (\1, \2, etc.)
19
+ * - Lookahead/lookbehind assertions
20
+ * - Named capture groups
21
+ * - Word boundaries outside character classes
22
+ *
23
+ * Transforms `.` to `[^\n\r]` outside character classes (I-Regexp semantics).
24
+ *
25
+ * @param {string} pattern
26
+ * @returns {string | null} - Transformed pattern or null if invalid
27
+ */
28
+ const transformIRegexp = pattern => {
29
+ let result = '';
30
+ let inCharClass = false;
31
+ let i = 0;
32
+ while (i < pattern.length) {
33
+ const ch = pattern[i];
34
+
35
+ // Handle escape sequences
36
+ if (ch === '\\' && i + 1 < pattern.length) {
37
+ const next = pattern[i + 1];
38
+
39
+ // Reject backreferences (\1-\9)
40
+ if (next >= '1' && next <= '9') return null;
41
+
42
+ // Reject word boundaries outside character classes
43
+ if (!inCharClass && (next === 'b' || next === 'B')) return null;
44
+ result += ch + next;
45
+ i += 2;
46
+ continue;
47
+ }
48
+
49
+ // Track character class boundaries
50
+ if (ch === '[' && !inCharClass) {
51
+ inCharClass = true;
52
+ result += ch;
53
+ i += 1;
54
+ continue;
55
+ }
56
+ if (ch === ']' && inCharClass) {
57
+ inCharClass = false;
58
+ result += ch;
59
+ i += 1;
60
+ continue;
61
+ }
62
+
63
+ // Check for lookahead/lookbehind/named groups: (?=, (?!, (?<=, (?<!, (?<name>
64
+ if (ch === '(' && i + 2 < pattern.length && pattern[i + 1] === '?') {
65
+ const next2 = pattern[i + 2];
66
+ // Reject lookahead (?= (?!
67
+ if (next2 === '=' || next2 === '!') return null;
68
+ // Check for lookbehind or named groups
69
+ if (next2 === '<' && i + 3 < pattern.length) {
70
+ const next3 = pattern[i + 3];
71
+ // Reject lookbehind (?<= (?<!
72
+ if (next3 === '=' || next3 === '!') return null;
73
+ // Reject named capture groups (?<name>
74
+ if (/[a-zA-Z]/.test(next3)) return null;
75
+ }
76
+ }
77
+
78
+ // Transform `.` to `[^\n\r]` outside character classes
79
+ if (ch === '.' && !inCharClass) {
80
+ result += '[^\\n\\r]';
81
+ i += 1;
82
+ continue;
83
+ }
84
+ result += ch;
85
+ i += 1;
86
+ }
87
+ return result;
88
+ };
89
+
90
+ /**
91
+ * Construct a RegExp from I-Regexp pattern.
92
+ * Validates the pattern, transforms it, and caches the result.
93
+ *
94
+ * @param {string} pattern - I-Regexp pattern
95
+ * @param {boolean} [anchor=false] - If true, anchor pattern with ^(?:...)$
96
+ * @returns {RegExp | null} - Compiled regex or null if invalid
97
+ */
98
+ const constructRegex = (pattern, anchor = false) => {
99
+ const cacheKey = anchor ? `anchored:${pattern}` : `unanchored:${pattern}`;
100
+ if (regexpCache.has(cacheKey)) {
101
+ return regexpCache.get(cacheKey);
102
+ }
103
+ const transformed = transformIRegexp(pattern);
104
+ if (transformed === null) {
105
+ regexpCache.set(cacheKey, null);
106
+ return null;
107
+ }
108
+ try {
109
+ const finalPattern = anchor ? `^(?:${transformed})$` : transformed;
110
+ const regex = new RegExp(finalPattern, 'u');
111
+ regexpCache.set(cacheKey, regex);
112
+ return regex;
113
+ } catch {
114
+ regexpCache.set(cacheKey, null);
115
+ return null;
116
+ }
117
+ };
118
+ exports.constructRegex = constructRegex;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _selector = _interopRequireDefault(require("./selector.cjs"));
6
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
+ /**
8
+ * Bracketed selection visitor.
9
+ *
10
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.5.1
11
+ *
12
+ * A bracketed selection contains one or more selectors.
13
+ * Each selector's results are concatenated.
14
+ */
15
+
16
+ /**
17
+ * Visit a bracketed selection.
18
+ *
19
+ * @param {object} ctx - Evaluation context
20
+ * @param {unknown} value - Current value
21
+ * @param {object} node - AST node
22
+ * @param {object[]} node.selectors - Array of selector AST nodes
23
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
24
+ */
25
+ const visitBracketedSelection = (ctx, value, node, emit) => {
26
+ const {
27
+ selectors
28
+ } = node;
29
+
30
+ // Visit each selector and emit its results
31
+ for (const selector of selectors) {
32
+ (0, _selector.default)(ctx, value, selector, emit);
33
+ }
34
+ };
35
+ var _default = exports.default = visitBracketedSelection;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _logicalExpr = _interopRequireDefault(require("../evaluators/logical-expr.cjs"));
6
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
7
+ /**
8
+ * Filter selector visitor.
9
+ *
10
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.5
11
+ *
12
+ * A filter selector [?expr] selects all children where the expression is true.
13
+ * For arrays: tests each element
14
+ * For objects: tests each member value
15
+ */
16
+
17
+ /**
18
+ * Visit a filter selector.
19
+ *
20
+ * @param {object} ctx - Evaluation context
21
+ * @param {object} ctx.realm - Data realm
22
+ * @param {object} ctx.root - Root value ($)
23
+ * @param {unknown} value - Current value
24
+ * @param {object} node - AST node
25
+ * @param {object} node.expression - Logical expression to evaluate
26
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
27
+ */
28
+ const visitFilterSelector = (ctx, value, node, emit) => {
29
+ const {
30
+ realm,
31
+ root
32
+ } = ctx;
33
+ const {
34
+ expression
35
+ } = node;
36
+ for (const [key, child] of realm.entries(value)) {
37
+ const result = (0, _logicalExpr.default)(ctx, root, child, expression);
38
+ if (result) {
39
+ emit(child, key);
40
+ }
41
+ }
42
+ };
43
+ var _default = exports.default = visitFilterSelector;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ /**
6
+ * Index selector visitor.
7
+ *
8
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.3
9
+ *
10
+ * An index selector selects at most one element from an array.
11
+ * Supports negative indices (count from end).
12
+ */
13
+
14
+ /**
15
+ * Normalize an array index.
16
+ * Negative indices count from the end.
17
+ *
18
+ * @param {number} index - The index (may be negative)
19
+ * @param {number} length - Array length
20
+ * @returns {number} - Normalized index (non-negative or out of bounds)
21
+ */
22
+ const normalizeIndex = (index, length) => {
23
+ if (index >= 0) return index;
24
+ return length + index;
25
+ };
26
+
27
+ /**
28
+ * Visit an index selector.
29
+ *
30
+ * @param {object} ctx - Evaluation context
31
+ * @param {object} ctx.realm - Data realm
32
+ * @param {unknown} value - Current value
33
+ * @param {object} node - AST node
34
+ * @param {number} node.value - Index to select
35
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
36
+ */
37
+ const visitIndexSelector = (ctx, value, node, emit) => {
38
+ const {
39
+ realm
40
+ } = ctx;
41
+ const {
42
+ value: index
43
+ } = node;
44
+ if (!realm.isArray(value)) return;
45
+ const length = realm.getLength(value);
46
+ const normalizedIndex = normalizeIndex(index, length);
47
+
48
+ // Check bounds
49
+ if (normalizedIndex >= 0 && normalizedIndex < length) {
50
+ const selected = realm.getElement(value, normalizedIndex);
51
+ emit(selected, normalizedIndex);
52
+ }
53
+ // If out of bounds, yield nothing
54
+ };
55
+ var _default = exports.default = visitIndexSelector;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ /**
6
+ * Name selector visitor.
7
+ *
8
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.1
9
+ *
10
+ * A name selector selects at most one member value from an object.
11
+ * If the object has the specified member, yield its value.
12
+ * If not, yield nothing.
13
+ */
14
+
15
+ /**
16
+ * Visit a name selector.
17
+ *
18
+ * @param {object} ctx - Evaluation context
19
+ * @param {object} ctx.realm - Data realm
20
+ * @param {unknown} value - Current value
21
+ * @param {object} node - AST node
22
+ * @param {string} node.value - Property name to select
23
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
24
+ */
25
+ const visitNameSelector = (ctx, value, node, emit) => {
26
+ const {
27
+ realm
28
+ } = ctx;
29
+ const {
30
+ value: name
31
+ } = node;
32
+ if (realm.isObject(value) && realm.hasProperty(value, name)) {
33
+ const selected = realm.getProperty(value, name);
34
+ emit(selected, name);
35
+ }
36
+ // If not an object or property doesn't exist, yield nothing
37
+ };
38
+ var _default = exports.default = visitNameSelector;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.visitDescendantSegment = exports.visitChildSegment = exports.default = void 0;
5
+ var _selector = _interopRequireDefault(require("./selector.cjs"));
6
+ var _bracketedSelection = _interopRequireDefault(require("./bracketed-selection.cjs"));
7
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
8
+ /**
9
+ * Segment visitor dispatcher.
10
+ *
11
+ * Handles ChildSegment and DescendantSegment types.
12
+ *
13
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.5
14
+ */
15
+
16
+ /**
17
+ * Visit a segment's selector.
18
+ *
19
+ * @param {object} ctx - Evaluation context
20
+ * @param {unknown} value - Current value
21
+ * @param {object} selector - Selector AST node
22
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
23
+ */
24
+ const visitSegmentSelector = (ctx, value, selector, emit) => {
25
+ switch (selector.type) {
26
+ case 'BracketedSelection':
27
+ (0, _bracketedSelection.default)(ctx, value, selector, emit);
28
+ break;
29
+ case 'NameSelector':
30
+ case 'WildcardSelector':
31
+ case 'IndexSelector':
32
+ case 'SliceSelector':
33
+ case 'FilterSelector':
34
+ (0, _selector.default)(ctx, value, selector, emit);
35
+ break;
36
+ default:
37
+ break;
38
+ }
39
+ };
40
+
41
+ /**
42
+ * Visit a child segment.
43
+ * Applies selector to current value.
44
+ *
45
+ * @param {object} ctx - Evaluation context
46
+ * @param {unknown} value - Current value
47
+ * @param {object} node - ChildSegment AST node
48
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
49
+ */
50
+ const visitChildSegment = (ctx, value, node, emit) => {
51
+ const {
52
+ selector
53
+ } = node;
54
+ visitSegmentSelector(ctx, value, selector, emit);
55
+ };
56
+
57
+ /**
58
+ * Visit a descendant segment.
59
+ * Applies selector to current value and all descendants.
60
+ *
61
+ * Note: This is used by exec.js which handles the recursive descent
62
+ * by pushing descendants onto the stack. This function only applies
63
+ * the selector at the current level.
64
+ *
65
+ * @param {object} ctx - Evaluation context
66
+ * @param {unknown} value - Current value
67
+ * @param {object} node - DescendantSegment AST node
68
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
69
+ */
70
+ exports.visitChildSegment = visitChildSegment;
71
+ const visitDescendantSegment = (ctx, value, node, emit) => {
72
+ const {
73
+ selector
74
+ } = node;
75
+ visitSegmentSelector(ctx, value, selector, emit);
76
+ };
77
+
78
+ /**
79
+ * Visit a segment and emit selected values.
80
+ *
81
+ * @param {object} ctx - Evaluation context
82
+ * @param {unknown} value - Current value
83
+ * @param {object} node - Segment AST node
84
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
85
+ */
86
+ exports.visitDescendantSegment = visitDescendantSegment;
87
+ const visitSegment = (ctx, value, node, emit) => {
88
+ switch (node.type) {
89
+ case 'ChildSegment':
90
+ visitChildSegment(ctx, value, node, emit);
91
+ break;
92
+ case 'DescendantSegment':
93
+ visitDescendantSegment(ctx, value, node, emit);
94
+ break;
95
+ default:
96
+ break;
97
+ }
98
+ };
99
+ var _default = exports.default = visitSegment;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _nameSelector = _interopRequireDefault(require("./name-selector.cjs"));
6
+ var _indexSelector = _interopRequireDefault(require("./index-selector.cjs"));
7
+ var _wildcardSelector = _interopRequireDefault(require("./wildcard-selector.cjs"));
8
+ var _sliceSelector = _interopRequireDefault(require("./slice-selector.cjs"));
9
+ var _filterSelector = _interopRequireDefault(require("./filter-selector.cjs"));
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ /**
12
+ * Selector visitor dispatcher.
13
+ *
14
+ * Routes to the appropriate selector visitor based on AST node type.
15
+ */
16
+
17
+ /**
18
+ * Visit a selector and emit selected values.
19
+ *
20
+ * @param {object} ctx - Evaluation context
21
+ * @param {unknown} value - Current value
22
+ * @param {object} node - Selector AST node
23
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
24
+ */
25
+ const visitSelector = (ctx, value, node, emit) => {
26
+ switch (node.type) {
27
+ case 'NameSelector':
28
+ (0, _nameSelector.default)(ctx, value, node, emit);
29
+ break;
30
+ case 'IndexSelector':
31
+ (0, _indexSelector.default)(ctx, value, node, emit);
32
+ break;
33
+ case 'WildcardSelector':
34
+ (0, _wildcardSelector.default)(ctx, value, node, emit);
35
+ break;
36
+ case 'SliceSelector':
37
+ (0, _sliceSelector.default)(ctx, value, node, emit);
38
+ break;
39
+ case 'FilterSelector':
40
+ (0, _filterSelector.default)(ctx, value, node, emit);
41
+ break;
42
+ default:
43
+ // Unknown selector type, yield nothing
44
+ break;
45
+ }
46
+ };
47
+ var _default = exports.default = visitSelector;
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ /**
6
+ * Slice selector visitor.
7
+ *
8
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.4
9
+ *
10
+ * A slice selector [start:end:step] selects elements from an array.
11
+ * - start: first index (default 0 for positive step, len-1 for negative)
12
+ * - end: upper bound (default len for positive step, -len-1 for negative)
13
+ * - step: step size (default 1, must not be 0)
14
+ */
15
+
16
+ /**
17
+ * Normalize a slice bound according to RFC 9535.
18
+ * @param {number} index - The bound value
19
+ * @param {number} length - Array length
20
+ * @returns {number} - Normalized bound
21
+ */
22
+ const normalizeBound = (index, length) => {
23
+ if (index >= 0) {
24
+ return Math.min(index, length);
25
+ }
26
+ return Math.max(length + index, 0);
27
+ };
28
+
29
+ /**
30
+ * Get slice bounds and step according to RFC 9535 Section 2.3.4.2.
31
+ *
32
+ * @param {number | null} start
33
+ * @param {number | null} end
34
+ * @param {number | null} step
35
+ * @param {number} length - Array length
36
+ * @returns {{ lower: number, upper: number, step: number } | null}
37
+ */
38
+ const getSliceBounds = (start, end, step, length) => {
39
+ // Default step is 1
40
+ const actualStep = step ?? 1;
41
+
42
+ // Step of 0 is not allowed
43
+ if (actualStep === 0) return null;
44
+ let lower;
45
+ let upper;
46
+ if (actualStep > 0) {
47
+ // Forward iteration
48
+ const defaultStart = 0;
49
+ const defaultEnd = length;
50
+ const normalizedStart = start !== null ? normalizeBound(start, length) : defaultStart;
51
+ const normalizedEnd = end !== null ? normalizeBound(end, length) : defaultEnd;
52
+ lower = Math.max(normalizedStart, 0);
53
+ upper = Math.min(normalizedEnd, length);
54
+ } else {
55
+ // Backward iteration
56
+ const defaultStart = length - 1;
57
+ const defaultEnd = -length - 1;
58
+ const normalizedStart = start !== null ? start >= 0 ? Math.min(start, length - 1) : Math.max(length + start, -1) : defaultStart;
59
+ const normalizedEnd = end !== null ? end >= 0 ? Math.min(end, length - 1) : Math.max(length + end, -1) : defaultEnd;
60
+ upper = Math.min(normalizedStart, length - 1);
61
+ lower = Math.max(normalizedEnd, -1);
62
+ }
63
+ return {
64
+ lower,
65
+ upper,
66
+ step: actualStep
67
+ };
68
+ };
69
+
70
+ /**
71
+ * Visit a slice selector.
72
+ *
73
+ * @param {object} ctx - Evaluation context
74
+ * @param {object} ctx.realm - Data realm
75
+ * @param {unknown} value - Current value
76
+ * @param {object} node - AST node
77
+ * @param {number | null} node.start - Start index
78
+ * @param {number | null} node.end - End index
79
+ * @param {number | null} node.step - Step
80
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
81
+ */
82
+ const visitSliceSelector = (ctx, value, node, emit) => {
83
+ const {
84
+ realm
85
+ } = ctx;
86
+ const {
87
+ start,
88
+ end,
89
+ step
90
+ } = node;
91
+ if (!realm.isArray(value)) return;
92
+ const length = realm.getLength(value);
93
+ const bounds = getSliceBounds(start, end, step, length);
94
+ if (bounds === null) return; // step was 0
95
+
96
+ const {
97
+ lower,
98
+ upper,
99
+ step: actualStep
100
+ } = bounds;
101
+ if (actualStep > 0) {
102
+ // Forward iteration
103
+ for (let i = lower; i < upper; i += actualStep) {
104
+ const selected = realm.getElement(value, i);
105
+ emit(selected, i);
106
+ }
107
+ } else {
108
+ // Backward iteration
109
+ for (let i = upper; i > lower; i += actualStep) {
110
+ const selected = realm.getElement(value, i);
111
+ emit(selected, i);
112
+ }
113
+ }
114
+ };
115
+ var _default = exports.default = visitSliceSelector;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ /**
6
+ * Wildcard selector visitor.
7
+ *
8
+ * @see https://www.rfc-editor.org/rfc/rfc9535#section-2.3.2
9
+ *
10
+ * A wildcard selector selects all children of a value:
11
+ * - For arrays: all elements
12
+ * - For objects: all member values
13
+ */
14
+
15
+ /**
16
+ * Visit a wildcard selector.
17
+ *
18
+ * @param {object} ctx - Evaluation context
19
+ * @param {object} ctx.realm - Data realm
20
+ * @param {unknown} value - Current value
21
+ * @param {object} node - AST node (unused for wildcard)
22
+ * @param {(value: unknown, segment: string | number) => void} emit - Callback to emit selected value
23
+ */
24
+ const visitWildcardSelector = (ctx, value, node, emit) => {
25
+ const {
26
+ realm
27
+ } = ctx;
28
+ for (const [key, child] of realm.entries(value)) {
29
+ emit(child, key);
30
+ }
31
+ };
32
+ var _default = exports.default = visitWildcardSelector;
package/cjs/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  exports.__esModule = true;
4
- exports.test = exports.parse = exports.escape = exports.compile = exports.XMLTranslator = exports.Trace = exports.JSONPathParseError = exports.JSONPathError = exports.JSONPathCompileError = exports.Grammar = exports.CSTTranslator = exports.CSTOptimizedTranslator = exports.ASTTranslator = void 0;
4
+ exports.test = exports.parse = exports.functions = exports.evaluate = exports.XMLTranslator = exports.Trace = exports.NormalizedPath = exports.JSONPathParseError = exports.JSONPathEvaluateError = exports.JSONPathError = exports.JSONNormalizedPathError = exports.JSONEvaluationRealm = exports.Grammar = exports.EvaluationRealm = exports.CSTTranslator = exports.CSTOptimizedTranslator = exports.ASTTranslator = void 0;
5
5
  var _grammar = _interopRequireDefault(require("./grammar.cjs"));
6
6
  exports.Grammar = _grammar.default;
7
7
  var _index = _interopRequireDefault(require("./parse/index.cjs"));
@@ -18,14 +18,23 @@ var _Trace = _interopRequireDefault(require("./parse/trace/Trace.cjs"));
18
18
  exports.Trace = _Trace.default;
19
19
  var _index3 = _interopRequireDefault(require("./test/index.cjs"));
20
20
  exports.test = _index3.default;
21
- var _compile = _interopRequireDefault(require("./compile.cjs"));
22
- exports.compile = _compile.default;
23
- var _escape = _interopRequireDefault(require("./escape.cjs"));
24
- exports.escape = _escape.default;
21
+ var _NormalizedPath = _interopRequireWildcard(require("./normalized-path.cjs"));
22
+ exports.NormalizedPath = _NormalizedPath;
23
+ var _index4 = _interopRequireDefault(require("./evaluate/index.cjs"));
24
+ exports.evaluate = _index4.default;
25
+ var _functions = _interopRequireWildcard(require("./evaluate/functions/index.cjs"));
26
+ exports.functions = _functions;
27
+ var _EvaluationRealm = _interopRequireDefault(require("./evaluate/realms/EvaluationRealm.cjs"));
28
+ exports.EvaluationRealm = _EvaluationRealm.default;
29
+ var _index6 = _interopRequireDefault(require("./evaluate/realms/json/index.cjs"));
30
+ exports.JSONEvaluationRealm = _index6.default;
25
31
  var _JSONPathError = _interopRequireDefault(require("./errors/JSONPathError.cjs"));
26
32
  exports.JSONPathError = _JSONPathError.default;
27
33
  var _JSONPathParseError = _interopRequireDefault(require("./errors/JSONPathParseError.cjs"));
28
34
  exports.JSONPathParseError = _JSONPathParseError.default;
29
- var _JSONPathCompileError = _interopRequireDefault(require("./errors/JSONPathCompileError.cjs"));
30
- exports.JSONPathCompileError = _JSONPathCompileError.default;
35
+ var _JSONNormalizedPathError = _interopRequireDefault(require("./errors/JSONNormalizedPathError.cjs"));
36
+ exports.JSONNormalizedPathError = _JSONNormalizedPathError.default;
37
+ var _JSONPathEvaluateError = _interopRequireDefault(require("./errors/JSONPathEvaluateError.cjs"));
38
+ exports.JSONPathEvaluateError = _JSONPathEvaluateError.default;
39
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
31
40
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }