@speclynx/apidom-traverse 3.2.1 → 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.
- package/CHANGELOG.md +12 -0
- package/README.md +24 -13
- package/dist/apidom-traverse.browser.js +24 -22
- package/dist/apidom-traverse.browser.min.js +1 -1
- package/package.json +6 -6
- package/types/apidom-traverse.d.ts +19 -13
- package/src/Path.cjs +0 -336
- package/src/Path.mjs +0 -332
- package/src/index.cjs +0 -43
- package/src/index.mjs +0 -19
- package/src/operations/filter.cjs +0 -21
- package/src/operations/filter.mjs +0 -17
- package/src/operations/find-at-offset.cjs +0 -45
- package/src/operations/find-at-offset.mjs +0 -40
- package/src/operations/find.cjs +0 -22
- package/src/operations/find.mjs +0 -18
- package/src/operations/for-each.cjs +0 -37
- package/src/operations/for-each.mjs +0 -31
- package/src/operations/parents.cjs +0 -21
- package/src/operations/parents.mjs +0 -17
- package/src/operations/reject.cjs +0 -14
- package/src/operations/reject.mjs +0 -9
- package/src/operations/some.cjs +0 -14
- package/src/operations/some.mjs +0 -9
- package/src/traversal.cjs +0 -313
- package/src/traversal.mjs +0 -305
- package/src/visitors.cjs +0 -420
- package/src/visitors.mjs +0 -407
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [4.0.0](https://github.com/speclynx/apidom/compare/v3.2.1...v4.0.0) (2026-03-11)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
- **traverse:** all traverse operations work on Path and not Element ([#153](https://github.com/speclynx/apidom/issues/153)) ([67d244c](https://github.com/speclynx/apidom/commit/67d244cfd3e77f6a9db704cede50ba8e45d10b11))
|
|
11
|
+
|
|
12
|
+
### BREAKING CHANGES
|
|
13
|
+
|
|
14
|
+
- **traverse:** This is a breaking change as operation callbacks
|
|
15
|
+
now accept Path instead of Element. By accepting Path, full
|
|
16
|
+
context of traversal is exposed to consumer instead of just Element.
|
|
17
|
+
|
|
6
18
|
## [3.2.1](https://github.com/speclynx/apidom/compare/v3.2.0...v3.2.1) (2026-03-09)
|
|
7
19
|
|
|
8
20
|
**Note:** Version bump only for package @speclynx/apidom-traverse
|
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ All operations use **data-first** signatures: the element comes before the predi
|
|
|
58
58
|
|
|
59
59
|
### filter
|
|
60
60
|
|
|
61
|
-
Finds all elements
|
|
61
|
+
Finds all paths whose elements match the predicate.
|
|
62
62
|
|
|
63
63
|
```js
|
|
64
64
|
import { ObjectElement, isNumberElement } from '@speclynx/apidom-datamodel';
|
|
@@ -66,12 +66,14 @@ import { filter } from '@speclynx/apidom-traverse';
|
|
|
66
66
|
|
|
67
67
|
const element = new ObjectElement({ a: 'b', c: 2 });
|
|
68
68
|
|
|
69
|
-
filter(element, isNumberElement); // => [NumberElement<2
|
|
69
|
+
const paths = filter(element, (path) => isNumberElement(path.node)); // => [Path<NumberElement<2>>]
|
|
70
|
+
paths[0].node; // => NumberElement<2>
|
|
71
|
+
paths[0].formatPath(); // => '/c'
|
|
70
72
|
```
|
|
71
73
|
|
|
72
74
|
### find
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
Finds first path whose element satisfies the provided predicate.
|
|
75
77
|
|
|
76
78
|
```js
|
|
77
79
|
import { ObjectElement, isNumberElement } from '@speclynx/apidom-datamodel';
|
|
@@ -79,24 +81,29 @@ import { find } from '@speclynx/apidom-traverse';
|
|
|
79
81
|
|
|
80
82
|
const element = new ObjectElement({ a: 'b', c: 2 });
|
|
81
83
|
|
|
82
|
-
find(element, isNumberElement); // => NumberElement<2
|
|
84
|
+
const path = find(element, (path) => isNumberElement(path.node)); // => Path<NumberElement<2>>
|
|
85
|
+
path.node; // => NumberElement<2>
|
|
86
|
+
path.formatPath(); // => '/c'
|
|
83
87
|
```
|
|
84
88
|
|
|
85
89
|
### findAtOffset
|
|
86
90
|
|
|
87
|
-
ApiDOM nodes can be associated with source maps. This function finds the most inner node at the given offset.
|
|
91
|
+
ApiDOM nodes can be associated with source maps. This function finds the path of the most inner node at the given offset.
|
|
88
92
|
If includeRightBound is set, also finds nodes that end at the given offset.
|
|
89
93
|
|
|
90
94
|
```js
|
|
91
95
|
import { findAtOffset } from '@speclynx/apidom-traverse';
|
|
92
96
|
|
|
93
|
-
findAtOffset(elementWithSourceMaps, 3); // =>
|
|
97
|
+
const path = findAtOffset(elementWithSourceMaps, 3); // => Path of most inner node at offset 3
|
|
98
|
+
path.node; // => the element at that offset
|
|
99
|
+
path.formatPath(); // => JSON Pointer to the element
|
|
100
|
+
|
|
94
101
|
findAtOffset(elementWithSourceMaps, { offset: 3, includeRightBound: true });
|
|
95
102
|
```
|
|
96
103
|
|
|
97
104
|
### reject
|
|
98
105
|
|
|
99
|
-
Complement of [filter](#filter). Finds all elements NOT
|
|
106
|
+
Complement of [filter](#filter). Finds all paths whose elements do NOT match the predicate.
|
|
100
107
|
|
|
101
108
|
```js
|
|
102
109
|
import { ArrayElement, isNumberElement } from '@speclynx/apidom-datamodel';
|
|
@@ -104,12 +111,13 @@ import { reject } from '@speclynx/apidom-traverse';
|
|
|
104
111
|
|
|
105
112
|
const element = new ArrayElement([1, 'a']);
|
|
106
113
|
|
|
107
|
-
reject(element, isNumberElement); // => [ArrayElement
|
|
114
|
+
const paths = reject(element, (path) => isNumberElement(path.node)); // => [Path<ArrayElement>, Path<StringElement<'a'>>]
|
|
115
|
+
paths.map((p) => p.node); // => [ArrayElement, StringElement<'a'>]
|
|
108
116
|
```
|
|
109
117
|
|
|
110
118
|
### some
|
|
111
119
|
|
|
112
|
-
Tests whether at least one element passes the predicate.
|
|
120
|
+
Tests whether at least one path's element passes the predicate.
|
|
113
121
|
|
|
114
122
|
```js
|
|
115
123
|
import { ArrayElement, isNumberElement } from '@speclynx/apidom-datamodel';
|
|
@@ -117,12 +125,12 @@ import { some } from '@speclynx/apidom-traverse';
|
|
|
117
125
|
|
|
118
126
|
const element = new ArrayElement([1, 'a']);
|
|
119
127
|
|
|
120
|
-
some(element, isNumberElement); // => true
|
|
128
|
+
some(element, (path) => isNumberElement(path.node)); // => true
|
|
121
129
|
```
|
|
122
130
|
|
|
123
131
|
### forEach
|
|
124
132
|
|
|
125
|
-
Executes the callback on this element and all
|
|
133
|
+
Executes the callback on this element's path and all descendant paths.
|
|
126
134
|
|
|
127
135
|
```js
|
|
128
136
|
import { ArrayElement } from '@speclynx/apidom-datamodel';
|
|
@@ -130,7 +138,7 @@ import { forEach } from '@speclynx/apidom-traverse';
|
|
|
130
138
|
|
|
131
139
|
const element = new ArrayElement([1, 'a']);
|
|
132
140
|
|
|
133
|
-
forEach(element, console.dir); // => prints ArrayElement, NumberElement, StringElement
|
|
141
|
+
forEach(element, (path) => console.dir(path.node)); // => prints ArrayElement, NumberElement, StringElement
|
|
134
142
|
```
|
|
135
143
|
|
|
136
144
|
The execution of the callback can be controlled further by providing a predicate.
|
|
@@ -141,7 +149,10 @@ import { forEach } from '@speclynx/apidom-traverse';
|
|
|
141
149
|
|
|
142
150
|
const element = new ArrayElement([1, 'a']);
|
|
143
151
|
|
|
144
|
-
forEach(element, {
|
|
152
|
+
forEach(element, {
|
|
153
|
+
callback: (path) => console.dir(path.node),
|
|
154
|
+
predicate: (path) => isNumberElement(path.node),
|
|
155
|
+
}); // => prints NumberElement<1>
|
|
145
156
|
```
|
|
146
157
|
|
|
147
158
|
### parents
|
|
@@ -170,7 +170,9 @@ class Path {
|
|
|
170
170
|
*
|
|
171
171
|
* @example
|
|
172
172
|
* // For a path to $.paths['/pets'].get in an OpenAPI document:
|
|
173
|
+
* ```
|
|
173
174
|
* path.getPathKeys(); // => ['paths', '/pets', 'get']
|
|
175
|
+
* ```
|
|
174
176
|
*/
|
|
175
177
|
getPathKeys() {
|
|
176
178
|
const keys = [];
|
|
@@ -205,18 +207,22 @@ class Path {
|
|
|
205
207
|
* or Normalized JSONPath like "$['paths']['/pets']['get']['responses']['200']"
|
|
206
208
|
*
|
|
207
209
|
* @example
|
|
210
|
+
* ```
|
|
208
211
|
* // JSON Pointer examples:
|
|
209
212
|
* path.formatPath(); // "" (root)
|
|
210
213
|
* path.formatPath(); // "/info"
|
|
211
214
|
* path.formatPath(); // "/paths/~1pets/get"
|
|
212
215
|
* path.formatPath(); // "/paths/~1users~1{id}/parameters/0"
|
|
216
|
+
* ```
|
|
213
217
|
*
|
|
214
218
|
* @example
|
|
219
|
+
* ```
|
|
215
220
|
* // JSONPath examples:
|
|
216
221
|
* path.formatPath('jsonpath'); // "$" (root)
|
|
217
222
|
* path.formatPath('jsonpath'); // "$['info']"
|
|
218
223
|
* path.formatPath('jsonpath'); // "$['paths']['/pets']['get']"
|
|
219
224
|
* path.formatPath('jsonpath'); // "$['paths']['/users/{id}']['parameters'][0]"
|
|
225
|
+
* ```
|
|
220
226
|
*/
|
|
221
227
|
formatPath(pathFormat = 'jsonpointer') {
|
|
222
228
|
const parts = this.getPathKeys();
|
|
@@ -367,15 +373,15 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
367
373
|
/* harmony import */ var _traversal_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9761);
|
|
368
374
|
|
|
369
375
|
/**
|
|
370
|
-
* Finds all elements
|
|
376
|
+
* Finds all paths whose elements match the predicate.
|
|
371
377
|
* @public
|
|
372
378
|
*/
|
|
373
379
|
const filter = (element, predicate) => {
|
|
374
380
|
const result = [];
|
|
375
381
|
(0,_traversal_ts__WEBPACK_IMPORTED_MODULE_0__.traverse)(element, {
|
|
376
382
|
enter(path) {
|
|
377
|
-
if (predicate(path
|
|
378
|
-
result.push(path
|
|
383
|
+
if (predicate(path)) {
|
|
384
|
+
result.push(path);
|
|
379
385
|
}
|
|
380
386
|
}
|
|
381
387
|
});
|
|
@@ -402,7 +408,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
402
408
|
*/
|
|
403
409
|
|
|
404
410
|
/**
|
|
405
|
-
* Finds the most inner node at the given offset.
|
|
411
|
+
* Finds the path of the most inner node at the given offset.
|
|
406
412
|
* If includeRightBound is set, also finds nodes that end at the given offset.
|
|
407
413
|
* @public
|
|
408
414
|
*/
|
|
@@ -427,7 +433,7 @@ const findAtOffset = (element, options) => {
|
|
|
427
433
|
const endOffset = node.endOffset;
|
|
428
434
|
const isWithinOffsetRange = offset >= startOffset && (offset < endOffset || includeRightBound && offset <= endOffset);
|
|
429
435
|
if (isWithinOffsetRange) {
|
|
430
|
-
result.push(
|
|
436
|
+
result.push(path);
|
|
431
437
|
return; // push to stack and dive in
|
|
432
438
|
}
|
|
433
439
|
path.skip(); // skip entire sub-tree
|
|
@@ -449,15 +455,15 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
449
455
|
/* harmony import */ var _traversal_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9761);
|
|
450
456
|
|
|
451
457
|
/**
|
|
452
|
-
*
|
|
458
|
+
* Finds first path whose element satisfies the provided predicate.
|
|
453
459
|
* @public
|
|
454
460
|
*/
|
|
455
461
|
const find = (element, predicate) => {
|
|
456
462
|
let result;
|
|
457
463
|
(0,_traversal_ts__WEBPACK_IMPORTED_MODULE_0__.traverse)(element, {
|
|
458
464
|
enter(path) {
|
|
459
|
-
if (predicate(path
|
|
460
|
-
result = path
|
|
465
|
+
if (predicate(path)) {
|
|
466
|
+
result = path;
|
|
461
467
|
path.stop();
|
|
462
468
|
}
|
|
463
469
|
}
|
|
@@ -475,9 +481,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
475
481
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
476
482
|
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
477
483
|
/* harmony export */ });
|
|
478
|
-
/* harmony import */ var
|
|
479
|
-
/* harmony import */ var _traversal_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9761);
|
|
480
|
-
|
|
484
|
+
/* harmony import */ var _traversal_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9761);
|
|
481
485
|
|
|
482
486
|
|
|
483
487
|
/**
|
|
@@ -489,7 +493,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
489
493
|
*/
|
|
490
494
|
|
|
491
495
|
/**
|
|
492
|
-
* Executes the callback on this element and all
|
|
496
|
+
* Executes the callback on this element's path and all descendant paths.
|
|
493
497
|
* @public
|
|
494
498
|
*/
|
|
495
499
|
const forEach = (element, options) => {
|
|
@@ -497,15 +501,15 @@ const forEach = (element, options) => {
|
|
|
497
501
|
let predicate;
|
|
498
502
|
if (typeof options === 'function') {
|
|
499
503
|
callback = options;
|
|
500
|
-
predicate =
|
|
504
|
+
predicate = () => true;
|
|
501
505
|
} else {
|
|
502
506
|
callback = options.callback ?? (() => {});
|
|
503
|
-
predicate = options.predicate ??
|
|
507
|
+
predicate = options.predicate ?? (() => true);
|
|
504
508
|
}
|
|
505
|
-
(0,
|
|
509
|
+
(0,_traversal_ts__WEBPACK_IMPORTED_MODULE_0__.traverse)(element, {
|
|
506
510
|
enter(path) {
|
|
507
|
-
if (predicate(path
|
|
508
|
-
callback(path
|
|
511
|
+
if (predicate(path)) {
|
|
512
|
+
callback(path);
|
|
509
513
|
}
|
|
510
514
|
}
|
|
511
515
|
});
|
|
@@ -551,13 +555,12 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
551
555
|
/* harmony export */ });
|
|
552
556
|
/* harmony import */ var _filter_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(706);
|
|
553
557
|
|
|
554
|
-
|
|
555
558
|
/**
|
|
556
|
-
* Complement of filter. Finds all elements NOT
|
|
559
|
+
* Complement of filter. Finds all paths whose elements do NOT match the predicate.
|
|
557
560
|
* @public
|
|
558
561
|
*/
|
|
559
562
|
const reject = (element, predicate) => {
|
|
560
|
-
return (0,_filter_ts__WEBPACK_IMPORTED_MODULE_0__["default"])(element,
|
|
563
|
+
return (0,_filter_ts__WEBPACK_IMPORTED_MODULE_0__["default"])(element, path => !predicate(path));
|
|
561
564
|
};
|
|
562
565
|
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (reject);
|
|
563
566
|
|
|
@@ -572,9 +575,8 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
572
575
|
/* harmony export */ });
|
|
573
576
|
/* harmony import */ var _find_ts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9068);
|
|
574
577
|
|
|
575
|
-
|
|
576
578
|
/**
|
|
577
|
-
* Tests whether at least one element passes the predicate.
|
|
579
|
+
* Tests whether at least one path's element passes the predicate.
|
|
578
580
|
* @public
|
|
579
581
|
*/
|
|
580
582
|
const some = (element, predicate) => {
|