@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.
@@ -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 { }