@speclynx/apidom-traverse 1.12.2
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/LICENSES/AFL-3.0.txt +182 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/LICENSES/BSD-3-Clause.txt +26 -0
- package/LICENSES/MIT.txt +9 -0
- package/NOTICE +74 -0
- package/README.md +238 -0
- package/dist/apidom-traverse.browser.js +6900 -0
- package/dist/apidom-traverse.browser.min.js +1 -0
- package/package.json +59 -0
- package/src/Path.cjs +276 -0
- package/src/Path.mjs +271 -0
- package/src/index.cjs +43 -0
- package/src/index.mjs +19 -0
- package/src/operations/filter.cjs +21 -0
- package/src/operations/filter.mjs +17 -0
- package/src/operations/find-at-offset.cjs +45 -0
- package/src/operations/find-at-offset.mjs +40 -0
- package/src/operations/find.cjs +22 -0
- package/src/operations/find.mjs +18 -0
- package/src/operations/for-each.cjs +37 -0
- package/src/operations/for-each.mjs +31 -0
- package/src/operations/parents.cjs +21 -0
- package/src/operations/parents.mjs +17 -0
- package/src/operations/reject.cjs +14 -0
- package/src/operations/reject.mjs +9 -0
- package/src/operations/some.cjs +14 -0
- package/src/operations/some.mjs +9 -0
- package/src/traversal.cjs +313 -0
- package/src/traversal.mjs +305 -0
- package/src/visitors.cjs +420 -0
- package/src/visitors.mjs +407 -0
- package/types/apidom-traverse.d.ts +403 -0
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { Element as Element_2 } from '@speclynx/apidom-datamodel';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default node clone function - creates a shallow clone of ApiDOM Elements.
|
|
5
|
+
* Uses cloneShallow from apidom-datamodel for proper handling of meta/attributes.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare const cloneNode: <TNode>(node: TNode) => TNode;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Finds all elements matching the predicate.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export declare const filter: <T extends Element_2>(element: T, predicate: (element: Element_2) => boolean) => Element_2[];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Find first element that satisfies the provided predicate.
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export declare const find: <T extends Element_2>(element: T, predicate: (element: Element_2) => boolean) => Element_2 | undefined;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Finds the most inner node at the given offset.
|
|
24
|
+
* If includeRightBound is set, also finds nodes that end at the given offset.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare const findAtOffset: <T extends Element_2>(element: T, options: number | FindAtOffsetOptions) => T | undefined;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export declare interface FindAtOffsetOptions {
|
|
33
|
+
offset: number;
|
|
34
|
+
includeRightBound?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Executes the callback on this element and all descendants.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export declare const forEach: <T extends Element_2>(element: T, options: ForEachCallback | ForEachOptions) => void;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare type ForEachCallback = <T extends Element_2>(element: T) => void;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare interface ForEachOptions {
|
|
52
|
+
callback?: ForEachCallback;
|
|
53
|
+
predicate?: (element: Element_2) => boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Default function to get traversable keys for a node.
|
|
58
|
+
* Uses predicates to handle all ApiDOM element types automatically.
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export declare const getNodeKeys: <TNode>(node: TNode) => readonly string[];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Alternative node type getter using primitive type.
|
|
65
|
+
* Returns the base element class name based on the node's primitive type.
|
|
66
|
+
* E.g., ContactElement (primitive='object') -\> "ObjectElement"
|
|
67
|
+
*
|
|
68
|
+
* Use this with `nodeTypeGetter` option when you want polymorphic behavior
|
|
69
|
+
* where specific elements fall back to their primitive type handlers.
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
export declare const getNodePrimitiveType: <TNode>(node: TNode) => string;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Default node type getter - reads the `element` property and converts to Element class name.
|
|
76
|
+
* E.g., "string" -\> "StringElement", "openApi3_1" -\> "OpenApi3_1Element"
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
export declare const getNodeType: <TNode>(node: TNode) => string;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Gets the appropriate visitor function for a node type and phase.
|
|
83
|
+
* Supports pipe-separated type keys like "TypeA|TypeB".
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
export declare const getVisitFn: <TNode>(visitor: object, type: string | undefined, isLeaving: boolean) => VisitorFn<TNode> | null;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Default node predicate - checks if value is an ApiDOM Element.
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
export declare const isNode: <TNode>(value: unknown) => value is TNode;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Sync version of merged visitor.
|
|
96
|
+
* @public
|
|
97
|
+
*/
|
|
98
|
+
export declare interface MergedVisitor<TNode> {
|
|
99
|
+
enter?: VisitorFn<TNode>;
|
|
100
|
+
leave?: VisitorFn<TNode>;
|
|
101
|
+
[key: string]: VisitorFn<TNode> | NodeVisitor<TNode> | undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Async version of merged visitor.
|
|
106
|
+
* @public
|
|
107
|
+
*/
|
|
108
|
+
export declare interface MergedVisitorAsync<TNode> {
|
|
109
|
+
enter?: VisitorFn<TNode>;
|
|
110
|
+
leave?: VisitorFn<TNode>;
|
|
111
|
+
[key: string]: VisitorFn<TNode> | NodeVisitor<TNode> | undefined;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Creates a new visitor instance which delegates to many visitors to run in
|
|
116
|
+
* parallel. Each visitor will be visited for each node before moving on.
|
|
117
|
+
*
|
|
118
|
+
* If a prior visitor edits a node, no following visitors will see that node.
|
|
119
|
+
* `exposeEdits=true` can be used to expose the edited node from the previous visitors.
|
|
120
|
+
* @public
|
|
121
|
+
*/
|
|
122
|
+
export declare const mergeVisitors: <TNode>(visitors: object[], options?: MergeVisitorsOptions<TNode>) => MergedVisitor<TNode>;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Async version of mergeVisitors.
|
|
126
|
+
* @public
|
|
127
|
+
*/
|
|
128
|
+
export declare const mergeVisitorsAsync: <TNode>(visitors: object[], options?: MergeVisitorsOptions<TNode>) => MergedVisitorAsync<TNode>;
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Options for mergeVisitors.
|
|
132
|
+
* @public
|
|
133
|
+
*/
|
|
134
|
+
export declare interface MergeVisitorsOptions<TNode> {
|
|
135
|
+
visitFnGetter?: typeof getVisitFn;
|
|
136
|
+
nodeTypeGetter?: (node: TNode) => string | undefined;
|
|
137
|
+
exposeEdits?: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Default mutation function that handles ApiDOM structures.
|
|
142
|
+
* - MemberElement: sets parent.value
|
|
143
|
+
* - Arrays: sets parent[key]
|
|
144
|
+
* - Objects: sets parent[key] or deletes if null
|
|
145
|
+
* @public
|
|
146
|
+
*/
|
|
147
|
+
export declare const mutateNode: <TNode>(parent: TNode, key: PropertyKey, value: TNode | null) => void;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Enter/leave visitor structure for a specific node type.
|
|
151
|
+
* @public
|
|
152
|
+
*/
|
|
153
|
+
export declare interface NodeVisitor<TNode, TVisitor = unknown> {
|
|
154
|
+
enter?: VisitorFn<TNode, TVisitor>;
|
|
155
|
+
leave?: VisitorFn<TNode, TVisitor>;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Computes upwards edges from every child to its parent.
|
|
160
|
+
* @public
|
|
161
|
+
*/
|
|
162
|
+
export declare const parents: <T extends Element_2>(element: T) => WeakMap<Element_2, Element_2 | undefined>;
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Path represents a node's position in the tree during traversal.
|
|
166
|
+
* Inspired by Babel's NodePath API.
|
|
167
|
+
* @public
|
|
168
|
+
*/
|
|
169
|
+
export declare class Path<TNode = Element_2> {
|
|
170
|
+
#private;
|
|
171
|
+
/**
|
|
172
|
+
* The current AST node.
|
|
173
|
+
*/
|
|
174
|
+
node: TNode;
|
|
175
|
+
/**
|
|
176
|
+
* The key of this node in its parent.
|
|
177
|
+
* `undefined` for the root node.
|
|
178
|
+
*/
|
|
179
|
+
readonly key: PropertyKey | undefined;
|
|
180
|
+
/**
|
|
181
|
+
* The index if this node is in an array.
|
|
182
|
+
* Same as `key` when parent property is an array, `undefined` otherwise.
|
|
183
|
+
*/
|
|
184
|
+
readonly index: number | undefined;
|
|
185
|
+
/**
|
|
186
|
+
* The parent node.
|
|
187
|
+
* `undefined` for the root node.
|
|
188
|
+
*/
|
|
189
|
+
readonly parent: TNode | undefined;
|
|
190
|
+
/**
|
|
191
|
+
* The parent Path.
|
|
192
|
+
* `null` for the root node.
|
|
193
|
+
*/
|
|
194
|
+
readonly parentPath: Path<TNode> | null;
|
|
195
|
+
/**
|
|
196
|
+
* Whether this node is inside an array in the parent.
|
|
197
|
+
*/
|
|
198
|
+
readonly inList: boolean;
|
|
199
|
+
constructor(node: TNode, parent: TNode | undefined, parentPath: Path<TNode> | null, key: PropertyKey | undefined, inList: boolean);
|
|
200
|
+
/**
|
|
201
|
+
* Whether skip() was called on this path.
|
|
202
|
+
*/
|
|
203
|
+
get shouldSkip(): boolean;
|
|
204
|
+
/**
|
|
205
|
+
* Whether stop() was called on this path.
|
|
206
|
+
*/
|
|
207
|
+
get shouldStop(): boolean;
|
|
208
|
+
/**
|
|
209
|
+
* Whether this node was removed.
|
|
210
|
+
*/
|
|
211
|
+
get removed(): boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Returns true if this is the root path.
|
|
214
|
+
*/
|
|
215
|
+
isRoot(): boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Get the depth of this path (0 for root).
|
|
218
|
+
*/
|
|
219
|
+
get depth(): number;
|
|
220
|
+
/**
|
|
221
|
+
* Get all ancestor paths from immediate parent to root.
|
|
222
|
+
*/
|
|
223
|
+
getAncestry(): Path<TNode>[];
|
|
224
|
+
/**
|
|
225
|
+
* Get all ancestor nodes from immediate parent to root.
|
|
226
|
+
*/
|
|
227
|
+
getAncestorNodes(): TNode[];
|
|
228
|
+
/**
|
|
229
|
+
* Get the path from root as an array of keys.
|
|
230
|
+
*/
|
|
231
|
+
getPathKeys(): PropertyKey[];
|
|
232
|
+
/**
|
|
233
|
+
* Find the closest ancestor path that satisfies the predicate.
|
|
234
|
+
*/
|
|
235
|
+
findParent(predicate: (path: Path<TNode>) => boolean): Path<TNode> | null;
|
|
236
|
+
/**
|
|
237
|
+
* Find the closest path (including this one) that satisfies the predicate.
|
|
238
|
+
*/
|
|
239
|
+
find(predicate: (path: Path<TNode>) => boolean): Path<TNode> | null;
|
|
240
|
+
/**
|
|
241
|
+
* Traverse into the current node with a new visitor.
|
|
242
|
+
* Populated by the traversal module to avoid circular imports.
|
|
243
|
+
*/
|
|
244
|
+
traverse: (visitor: any, options?: any) => TNode;
|
|
245
|
+
/**
|
|
246
|
+
* Async version of traverse.
|
|
247
|
+
*/
|
|
248
|
+
traverseAsync: (visitor: any, options?: any) => Promise<TNode>;
|
|
249
|
+
/**
|
|
250
|
+
* Skip traversing the children of this node.
|
|
251
|
+
*/
|
|
252
|
+
skip(): void;
|
|
253
|
+
/**
|
|
254
|
+
* Stop all traversal completely.
|
|
255
|
+
*/
|
|
256
|
+
stop(): void;
|
|
257
|
+
/**
|
|
258
|
+
* Replace this node with a new node.
|
|
259
|
+
*/
|
|
260
|
+
replaceWith(replacement: TNode): void;
|
|
261
|
+
/**
|
|
262
|
+
* Remove this node from the tree.
|
|
263
|
+
*/
|
|
264
|
+
remove(): void;
|
|
265
|
+
/**
|
|
266
|
+
* @internal
|
|
267
|
+
*/
|
|
268
|
+
_getReplacementNode(): TNode | undefined;
|
|
269
|
+
/**
|
|
270
|
+
* @internal
|
|
271
|
+
*/
|
|
272
|
+
_wasReplaced(): boolean;
|
|
273
|
+
/**
|
|
274
|
+
* @internal
|
|
275
|
+
*/
|
|
276
|
+
_reset(): void;
|
|
277
|
+
/**
|
|
278
|
+
* Mark this path as stale (visit completed).
|
|
279
|
+
* @internal
|
|
280
|
+
*/
|
|
281
|
+
_markStale(): void;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Complement of filter. Finds all elements NOT matching the predicate.
|
|
286
|
+
* @public
|
|
287
|
+
*/
|
|
288
|
+
export declare const reject: <T extends Element_2>(element: T, predicate: (element: Element_2) => boolean) => Element_2[];
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Tests whether at least one element passes the predicate.
|
|
292
|
+
* @public
|
|
293
|
+
*/
|
|
294
|
+
export declare const some: <T extends Element_2>(element: T, predicate: (element: Element_2) => boolean) => boolean;
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* traverse() walks through a tree using preorder depth-first traversal, calling
|
|
298
|
+
* the visitor's enter function at each node, and calling leave after visiting
|
|
299
|
+
* that node and all its children.
|
|
300
|
+
*
|
|
301
|
+
* Visitors receive a Path object with:
|
|
302
|
+
* - `path.node` - the current node
|
|
303
|
+
* - `path.parent` - the parent node
|
|
304
|
+
* - `path.key` - key in parent
|
|
305
|
+
* - `path.parentPath` - parent Path (linked list structure)
|
|
306
|
+
* - `path.replaceWith(node)` - replace current node
|
|
307
|
+
* - `path.remove()` - remove current node
|
|
308
|
+
* - `path.skip()` - skip children (enter only)
|
|
309
|
+
* - `path.stop()` - stop all traversal
|
|
310
|
+
*
|
|
311
|
+
* When editing, the original tree is not modified. A new version with changes
|
|
312
|
+
* applied is returned.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```typescript
|
|
316
|
+
* const edited = traverse(ast, {
|
|
317
|
+
* enter(path) {
|
|
318
|
+
* console.log(path.node);
|
|
319
|
+
* if (shouldSkip) path.skip();
|
|
320
|
+
* if (shouldReplace) path.replaceWith(newNode);
|
|
321
|
+
* },
|
|
322
|
+
* leave(path) {
|
|
323
|
+
* if (shouldRemove) path.remove();
|
|
324
|
+
* }
|
|
325
|
+
* });
|
|
326
|
+
* ```
|
|
327
|
+
*
|
|
328
|
+
* Visitor patterns supported:
|
|
329
|
+
* 1. `{ Kind(path) {} }` - enter specific node type
|
|
330
|
+
* 2. `{ Kind: { enter(path) {}, leave(path) {} } }` - enter/leave specific type
|
|
331
|
+
* 3. `{ enter(path) {}, leave(path) {} }` - enter/leave any node
|
|
332
|
+
* 4. `{ enter: { Kind(path) {} }, leave: { Kind(path) {} } }` - parallel style
|
|
333
|
+
*
|
|
334
|
+
* @public
|
|
335
|
+
*/
|
|
336
|
+
export declare const traverse: <TNode>(root: TNode, visitor: object, options?: TraverseOptions<TNode>) => TNode;
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Async version of traverse().
|
|
340
|
+
* @public
|
|
341
|
+
*/
|
|
342
|
+
export declare const traverseAsync: <TNode>(root: TNode, visitor: object, options?: TraverseOptions<TNode>) => Promise<TNode>;
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* SPDX-FileCopyrightText: Copyright (c) GraphQL Contributors
|
|
346
|
+
*
|
|
347
|
+
* SPDX-License-Identifier: MIT
|
|
348
|
+
*/
|
|
349
|
+
/**
|
|
350
|
+
* Options for the traverse function.
|
|
351
|
+
* @public
|
|
352
|
+
*/
|
|
353
|
+
export declare interface TraverseOptions<TNode> {
|
|
354
|
+
/**
|
|
355
|
+
* Map of node types to their traversable keys, or a function that returns keys for a node.
|
|
356
|
+
* Defaults to predicate-based detection for ApiDOM elements.
|
|
357
|
+
*/
|
|
358
|
+
keyMap?: Record<string, readonly string[]> | ((node: TNode) => readonly string[]) | null;
|
|
359
|
+
/**
|
|
360
|
+
* State object to assign to visitor during traversal.
|
|
361
|
+
*/
|
|
362
|
+
state?: Record<string, unknown>;
|
|
363
|
+
/**
|
|
364
|
+
* Function to get the type of a node. Defaults to `node.type`.
|
|
365
|
+
*/
|
|
366
|
+
nodeTypeGetter?: (node: TNode) => string | undefined;
|
|
367
|
+
/**
|
|
368
|
+
* Predicate to check if a value is a valid node.
|
|
369
|
+
*/
|
|
370
|
+
nodePredicate?: (value: unknown) => value is TNode;
|
|
371
|
+
/**
|
|
372
|
+
* Function to clone a node. Used when edits are made in immutable mode.
|
|
373
|
+
*/
|
|
374
|
+
nodeCloneFn?: (node: TNode) => TNode;
|
|
375
|
+
/**
|
|
376
|
+
* Whether to detect and skip cycles. Defaults to true.
|
|
377
|
+
*/
|
|
378
|
+
detectCycles?: boolean;
|
|
379
|
+
/**
|
|
380
|
+
* If true, edits modify the original tree in place.
|
|
381
|
+
* If false (default), creates a new tree with changes applied.
|
|
382
|
+
*/
|
|
383
|
+
mutable?: boolean;
|
|
384
|
+
/**
|
|
385
|
+
* Custom function for applying mutations in mutable mode.
|
|
386
|
+
* Handles ApiDOM structures (MemberElement, arrays) by default.
|
|
387
|
+
*/
|
|
388
|
+
mutationFn?: (parent: TNode, key: PropertyKey, value: TNode | null) => void;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Visitor function signature - receives a Path object.
|
|
393
|
+
* @public
|
|
394
|
+
*/
|
|
395
|
+
export declare type VisitorFn<TNode, TVisitor = unknown> = (this: TVisitor, path: Path<TNode>) => VisitorResult<TNode>;
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Possible return values from a visitor function.
|
|
399
|
+
* @public
|
|
400
|
+
*/
|
|
401
|
+
export declare type VisitorResult<TNode> = void | undefined | TNode | Promise<void | undefined | TNode>;
|
|
402
|
+
|
|
403
|
+
export { }
|