@herb-tools/core 0.6.0 → 0.6.1

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.
@@ -1,5 +1,6 @@
1
- import { HTMLElementNode, HTMLOpenTagNode, HTMLCloseTagNode } from "./nodes.js";
2
- import { Node, ERBContentNode, HTMLAttributeNameNode } from "./nodes.js";
1
+ import { Node, ERBContentNode, HTMLElementNode, HTMLOpenTagNode, HTMLCloseTagNode, HTMLAttributeNameNode } from "./nodes.js";
2
+ import type { Location } from "./location.js";
3
+ import type { Position } from "./position.js";
3
4
  /**
4
5
  * Checks if a node is an ERB output node (generates content: <%= %> or <%== %>)
5
6
  */
@@ -72,3 +73,52 @@ export declare function getTagName(node: HTMLElementNode | HTMLOpenTagNode | HTM
72
73
  * Check if a node is a comment (HTML comment or ERB comment)
73
74
  */
74
75
  export declare function isCommentNode(node: Node): boolean;
76
+ /**
77
+ * Compares two positions to determine if they are equal
78
+ * Returns true if pos1 and pos2 are at the same location
79
+ */
80
+ export declare function isPositionEqual(position1: Position, position2: Position): boolean;
81
+ /**
82
+ * Compares two positions to determine if the first comes after the second
83
+ * Returns true if pos1 comes after pos2 in source order
84
+ * @param inclusive - If true, returns true when positions are equal
85
+ */
86
+ export declare function isPositionAfter(position1: Position, position2: Position, inclusive?: boolean): boolean;
87
+ /**
88
+ * Gets nodes that appear before the specified location in source order
89
+ * Uses line and column positions to determine ordering
90
+ */
91
+ export declare function getNodesBeforeLocation<T extends Node>(nodes: T[], location: Location): T[];
92
+ /**
93
+ * Gets nodes that appear after the specified location in source order
94
+ * Uses line and column positions to determine ordering
95
+ */
96
+ export declare function getNodesAfterLocation<T extends Node>(nodes: T[], location: Location): T[];
97
+ /**
98
+ * Splits nodes into before and after the specified location
99
+ * Returns an object with `before` and `after` arrays
100
+ */
101
+ export declare function splitNodesAroundLocation<T extends Node>(nodes: T[], location: Location): {
102
+ before: T[];
103
+ after: T[];
104
+ };
105
+ /**
106
+ * Splits nodes at a specific position
107
+ * Returns nodes that end before the position and nodes that start after the position
108
+ * More precise than splitNodesAroundLocation as it uses a single position point
109
+ * Uses the same defaults as the individual functions: before=exclusive, after=inclusive
110
+ */
111
+ export declare function splitNodesAroundPosition<T extends Node>(nodes: T[], position: Position): {
112
+ before: T[];
113
+ after: T[];
114
+ };
115
+ /**
116
+ * Gets nodes that end before the specified position
117
+ * @param inclusive - If true, includes nodes that end exactly at the position (default: false, matching half-open interval semantics)
118
+ */
119
+ export declare function getNodesBeforePosition<T extends Node>(nodes: T[], position: Position, inclusive?: boolean): T[];
120
+ /**
121
+ * Gets nodes that start after the specified position
122
+ * @param inclusive - If true, includes nodes that start exactly at the position (default: true, matching typical boundary behavior)
123
+ */
124
+ export declare function getNodesAfterPosition<T extends Node>(nodes: T[], position: Position, inclusive?: boolean): T[];
@@ -164,7 +164,7 @@ export declare const NODE_TYPE_GUARDS: Map<new (...args: any[]) => Node, (node:
164
164
  * // node is HTMLTextNode
165
165
  * }
166
166
  */
167
- export declare const AST_TYPE_GUARDS: Map<string, (node: Node) => boolean>;
167
+ export declare const AST_TYPE_GUARDS: Map<NodeType, (node: Node) => boolean>;
168
168
  type NodeTypeToClass = {
169
169
  "AST_DOCUMENT_NODE": DocumentNode;
170
170
  "AST_LITERAL_NODE": LiteralNode;
@@ -296,8 +296,8 @@ export declare function filterNodes(nodes: Node[] | undefined | null, ...types:
296
296
  * // node is narrowed to HTMLTextNode
297
297
  * }
298
298
  */
299
- export declare function isNode<T extends NodeType>(node: Node, type: T): node is NodeTypeToClass[T];
300
- export declare function isNode<T extends new (...args: any[]) => Node>(node: Node, type: T): node is ClassToInstance<T>;
299
+ export declare function isNode<T extends NodeType>(node: Node | null | undefined, type: T): node is NodeTypeToClass[T];
300
+ export declare function isNode<T extends new (...args: any[]) => Node>(node: Node | null | undefined, type: T): node is ClassToInstance<T>;
301
301
  export declare function isToken(object: any): object is Token;
302
302
  export declare function isParseResult(object: any): object is ParseResult;
303
303
  /**
@@ -20,9 +20,16 @@ export declare abstract class Node implements BaseNodeProps {
20
20
  readonly location: Location;
21
21
  readonly errors: HerbError[];
22
22
  static from(node: SerializedNode): Node;
23
+ static get type(): NodeType;
23
24
  constructor(type: NodeType, location: Location, errors: HerbError[]);
24
25
  toJSON(): SerializedNode;
25
26
  inspect(): string;
27
+ is<T extends Node>(nodeClass: {
28
+ new (...args: any[]): T;
29
+ prototype: T;
30
+ type: NodeType;
31
+ }): this is T;
32
+ isOfType<T extends Node>(type: NodeType): this is T;
26
33
  get isSingleLine(): boolean;
27
34
  abstract treeInspect(indent?: number): string;
28
35
  abstract recursiveErrors(): HerbError[];
@@ -41,6 +48,7 @@ export interface DocumentNodeProps extends BaseNodeProps {
41
48
  }
42
49
  export declare class DocumentNode extends Node {
43
50
  readonly children: Node[];
51
+ static get type(): NodeType;
44
52
  static from(data: SerializedDocumentNode): DocumentNode;
45
53
  constructor(props: DocumentNodeProps);
46
54
  accept(visitor: Visitor): void;
@@ -59,6 +67,7 @@ export interface LiteralNodeProps extends BaseNodeProps {
59
67
  }
60
68
  export declare class LiteralNode extends Node {
61
69
  readonly content: string;
70
+ static get type(): NodeType;
62
71
  static from(data: SerializedLiteralNode): LiteralNode;
63
72
  constructor(props: LiteralNodeProps);
64
73
  accept(visitor: Visitor): void;
@@ -89,6 +98,7 @@ export declare class HTMLOpenTagNode extends Node {
89
98
  readonly tag_closing: Token | null;
90
99
  readonly children: Node[];
91
100
  readonly is_void: boolean;
101
+ static get type(): NodeType;
92
102
  static from(data: SerializedHTMLOpenTagNode): HTMLOpenTagNode;
93
103
  constructor(props: HTMLOpenTagNodeProps);
94
104
  accept(visitor: Visitor): void;
@@ -116,6 +126,7 @@ export declare class HTMLCloseTagNode extends Node {
116
126
  readonly tag_name: Token | null;
117
127
  readonly children: Node[];
118
128
  readonly tag_closing: Token | null;
129
+ static get type(): NodeType;
119
130
  static from(data: SerializedHTMLCloseTagNode): HTMLCloseTagNode;
120
131
  constructor(props: HTMLCloseTagNodeProps);
121
132
  accept(visitor: Visitor): void;
@@ -146,6 +157,7 @@ export declare class HTMLElementNode extends Node {
146
157
  readonly body: Node[];
147
158
  readonly close_tag: HTMLCloseTagNode | null;
148
159
  readonly is_void: boolean;
160
+ static get type(): NodeType;
149
161
  static from(data: SerializedHTMLElementNode): HTMLElementNode;
150
162
  constructor(props: HTMLElementNodeProps);
151
163
  accept(visitor: Visitor): void;
@@ -173,6 +185,7 @@ export declare class HTMLAttributeValueNode extends Node {
173
185
  readonly children: Node[];
174
186
  readonly close_quote: Token | null;
175
187
  readonly quoted: boolean;
188
+ static get type(): NodeType;
176
189
  static from(data: SerializedHTMLAttributeValueNode): HTMLAttributeValueNode;
177
190
  constructor(props: HTMLAttributeValueNodeProps);
178
191
  accept(visitor: Visitor): void;
@@ -191,6 +204,7 @@ export interface HTMLAttributeNameNodeProps extends BaseNodeProps {
191
204
  }
192
205
  export declare class HTMLAttributeNameNode extends Node {
193
206
  readonly children: Node[];
207
+ static get type(): NodeType;
194
208
  static from(data: SerializedHTMLAttributeNameNode): HTMLAttributeNameNode;
195
209
  constructor(props: HTMLAttributeNameNodeProps);
196
210
  accept(visitor: Visitor): void;
@@ -215,6 +229,7 @@ export declare class HTMLAttributeNode extends Node {
215
229
  readonly name: HTMLAttributeNameNode | null;
216
230
  readonly equals: Token | null;
217
231
  readonly value: HTMLAttributeValueNode | null;
232
+ static get type(): NodeType;
218
233
  static from(data: SerializedHTMLAttributeNode): HTMLAttributeNode;
219
234
  constructor(props: HTMLAttributeNodeProps);
220
235
  accept(visitor: Visitor): void;
@@ -233,6 +248,7 @@ export interface HTMLTextNodeProps extends BaseNodeProps {
233
248
  }
234
249
  export declare class HTMLTextNode extends Node {
235
250
  readonly content: string;
251
+ static get type(): NodeType;
236
252
  static from(data: SerializedHTMLTextNode): HTMLTextNode;
237
253
  constructor(props: HTMLTextNodeProps);
238
254
  accept(visitor: Visitor): void;
@@ -257,6 +273,7 @@ export declare class HTMLCommentNode extends Node {
257
273
  readonly comment_start: Token | null;
258
274
  readonly children: Node[];
259
275
  readonly comment_end: Token | null;
276
+ static get type(): NodeType;
260
277
  static from(data: SerializedHTMLCommentNode): HTMLCommentNode;
261
278
  constructor(props: HTMLCommentNodeProps);
262
279
  accept(visitor: Visitor): void;
@@ -281,6 +298,7 @@ export declare class HTMLDoctypeNode extends Node {
281
298
  readonly tag_opening: Token | null;
282
299
  readonly children: Node[];
283
300
  readonly tag_closing: Token | null;
301
+ static get type(): NodeType;
284
302
  static from(data: SerializedHTMLDoctypeNode): HTMLDoctypeNode;
285
303
  constructor(props: HTMLDoctypeNodeProps);
286
304
  accept(visitor: Visitor): void;
@@ -305,6 +323,7 @@ export declare class XMLDeclarationNode extends Node {
305
323
  readonly tag_opening: Token | null;
306
324
  readonly children: Node[];
307
325
  readonly tag_closing: Token | null;
326
+ static get type(): NodeType;
308
327
  static from(data: SerializedXMLDeclarationNode): XMLDeclarationNode;
309
328
  constructor(props: XMLDeclarationNodeProps);
310
329
  accept(visitor: Visitor): void;
@@ -329,6 +348,7 @@ export declare class CDATANode extends Node {
329
348
  readonly tag_opening: Token | null;
330
349
  readonly children: Node[];
331
350
  readonly tag_closing: Token | null;
351
+ static get type(): NodeType;
332
352
  static from(data: SerializedCDATANode): CDATANode;
333
353
  constructor(props: CDATANodeProps);
334
354
  accept(visitor: Visitor): void;
@@ -347,6 +367,7 @@ export interface WhitespaceNodeProps extends BaseNodeProps {
347
367
  }
348
368
  export declare class WhitespaceNode extends Node {
349
369
  readonly value: Token | null;
370
+ static get type(): NodeType;
350
371
  static from(data: SerializedWhitespaceNode): WhitespaceNode;
351
372
  constructor(props: WhitespaceNodeProps);
352
373
  accept(visitor: Visitor): void;
@@ -377,6 +398,7 @@ export declare class ERBContentNode extends Node {
377
398
  readonly tag_closing: Token | null;
378
399
  readonly parsed: boolean;
379
400
  readonly valid: boolean;
401
+ static get type(): NodeType;
380
402
  static from(data: SerializedERBContentNode): ERBContentNode;
381
403
  constructor(props: ERBContentNodeProps);
382
404
  accept(visitor: Visitor): void;
@@ -401,6 +423,7 @@ export declare class ERBEndNode extends Node {
401
423
  readonly tag_opening: Token | null;
402
424
  readonly content: Token | null;
403
425
  readonly tag_closing: Token | null;
426
+ static get type(): NodeType;
404
427
  static from(data: SerializedERBEndNode): ERBEndNode;
405
428
  constructor(props: ERBEndNodeProps);
406
429
  accept(visitor: Visitor): void;
@@ -428,6 +451,7 @@ export declare class ERBElseNode extends Node {
428
451
  readonly content: Token | null;
429
452
  readonly tag_closing: Token | null;
430
453
  readonly statements: Node[];
454
+ static get type(): NodeType;
431
455
  static from(data: SerializedERBElseNode): ERBElseNode;
432
456
  constructor(props: ERBElseNodeProps);
433
457
  accept(visitor: Visitor): void;
@@ -461,6 +485,7 @@ export declare class ERBIfNode extends Node {
461
485
  readonly statements: Node[];
462
486
  readonly subsequent: Node | null;
463
487
  readonly end_node: ERBEndNode | null;
488
+ static get type(): NodeType;
464
489
  static from(data: SerializedERBIfNode): ERBIfNode;
465
490
  constructor(props: ERBIfNodeProps);
466
491
  accept(visitor: Visitor): void;
@@ -491,6 +516,7 @@ export declare class ERBBlockNode extends Node {
491
516
  readonly tag_closing: Token | null;
492
517
  readonly body: Node[];
493
518
  readonly end_node: ERBEndNode | null;
519
+ static get type(): NodeType;
494
520
  static from(data: SerializedERBBlockNode): ERBBlockNode;
495
521
  constructor(props: ERBBlockNodeProps);
496
522
  accept(visitor: Visitor): void;
@@ -518,6 +544,7 @@ export declare class ERBWhenNode extends Node {
518
544
  readonly content: Token | null;
519
545
  readonly tag_closing: Token | null;
520
546
  readonly statements: Node[];
547
+ static get type(): NodeType;
521
548
  static from(data: SerializedERBWhenNode): ERBWhenNode;
522
549
  constructor(props: ERBWhenNodeProps);
523
550
  accept(visitor: Visitor): void;
@@ -554,6 +581,7 @@ export declare class ERBCaseNode extends Node {
554
581
  readonly conditions: Node[];
555
582
  readonly else_clause: ERBElseNode | null;
556
583
  readonly end_node: ERBEndNode | null;
584
+ static get type(): NodeType;
557
585
  static from(data: SerializedERBCaseNode): ERBCaseNode;
558
586
  constructor(props: ERBCaseNodeProps);
559
587
  accept(visitor: Visitor): void;
@@ -590,6 +618,7 @@ export declare class ERBCaseMatchNode extends Node {
590
618
  readonly conditions: Node[];
591
619
  readonly else_clause: ERBElseNode | null;
592
620
  readonly end_node: ERBEndNode | null;
621
+ static get type(): NodeType;
593
622
  static from(data: SerializedERBCaseMatchNode): ERBCaseMatchNode;
594
623
  constructor(props: ERBCaseMatchNodeProps);
595
624
  accept(visitor: Visitor): void;
@@ -620,6 +649,7 @@ export declare class ERBWhileNode extends Node {
620
649
  readonly tag_closing: Token | null;
621
650
  readonly statements: Node[];
622
651
  readonly end_node: ERBEndNode | null;
652
+ static get type(): NodeType;
623
653
  static from(data: SerializedERBWhileNode): ERBWhileNode;
624
654
  constructor(props: ERBWhileNodeProps);
625
655
  accept(visitor: Visitor): void;
@@ -650,6 +680,7 @@ export declare class ERBUntilNode extends Node {
650
680
  readonly tag_closing: Token | null;
651
681
  readonly statements: Node[];
652
682
  readonly end_node: ERBEndNode | null;
683
+ static get type(): NodeType;
653
684
  static from(data: SerializedERBUntilNode): ERBUntilNode;
654
685
  constructor(props: ERBUntilNodeProps);
655
686
  accept(visitor: Visitor): void;
@@ -680,6 +711,7 @@ export declare class ERBForNode extends Node {
680
711
  readonly tag_closing: Token | null;
681
712
  readonly statements: Node[];
682
713
  readonly end_node: ERBEndNode | null;
714
+ static get type(): NodeType;
683
715
  static from(data: SerializedERBForNode): ERBForNode;
684
716
  constructor(props: ERBForNodeProps);
685
717
  accept(visitor: Visitor): void;
@@ -710,6 +742,7 @@ export declare class ERBRescueNode extends Node {
710
742
  readonly tag_closing: Token | null;
711
743
  readonly statements: Node[];
712
744
  readonly subsequent: ERBRescueNode | null;
745
+ static get type(): NodeType;
713
746
  static from(data: SerializedERBRescueNode): ERBRescueNode;
714
747
  constructor(props: ERBRescueNodeProps);
715
748
  accept(visitor: Visitor): void;
@@ -737,6 +770,7 @@ export declare class ERBEnsureNode extends Node {
737
770
  readonly content: Token | null;
738
771
  readonly tag_closing: Token | null;
739
772
  readonly statements: Node[];
773
+ static get type(): NodeType;
740
774
  static from(data: SerializedERBEnsureNode): ERBEnsureNode;
741
775
  constructor(props: ERBEnsureNodeProps);
742
776
  accept(visitor: Visitor): void;
@@ -776,6 +810,7 @@ export declare class ERBBeginNode extends Node {
776
810
  readonly else_clause: ERBElseNode | null;
777
811
  readonly ensure_clause: ERBEnsureNode | null;
778
812
  readonly end_node: ERBEndNode | null;
813
+ static get type(): NodeType;
779
814
  static from(data: SerializedERBBeginNode): ERBBeginNode;
780
815
  constructor(props: ERBBeginNodeProps);
781
816
  accept(visitor: Visitor): void;
@@ -809,6 +844,7 @@ export declare class ERBUnlessNode extends Node {
809
844
  readonly statements: Node[];
810
845
  readonly else_clause: ERBElseNode | null;
811
846
  readonly end_node: ERBEndNode | null;
847
+ static get type(): NodeType;
812
848
  static from(data: SerializedERBUnlessNode): ERBUnlessNode;
813
849
  constructor(props: ERBUnlessNodeProps);
814
850
  accept(visitor: Visitor): void;
@@ -833,6 +869,7 @@ export declare class ERBYieldNode extends Node {
833
869
  readonly tag_opening: Token | null;
834
870
  readonly content: Token | null;
835
871
  readonly tag_closing: Token | null;
872
+ static get type(): NodeType;
836
873
  static from(data: SerializedERBYieldNode): ERBYieldNode;
837
874
  constructor(props: ERBYieldNodeProps);
838
875
  accept(visitor: Visitor): void;
@@ -860,6 +897,7 @@ export declare class ERBInNode extends Node {
860
897
  readonly content: Token | null;
861
898
  readonly tag_closing: Token | null;
862
899
  readonly statements: Node[];
900
+ static get type(): NodeType;
863
901
  static from(data: SerializedERBInNode): ERBInNode;
864
902
  constructor(props: ERBInNodeProps);
865
903
  accept(visitor: Visitor): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herb-tools/core",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Core module exporting shared interfaces, AST node definitions, and common utilities for Herb",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/ast-utils.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import {
2
+ Node,
2
3
  LiteralNode,
4
+ ERBContentNode,
3
5
  ERBIfNode,
4
6
  ERBUnlessNode,
5
7
  ERBBlockNode,
@@ -11,6 +13,7 @@ import {
11
13
  HTMLElementNode,
12
14
  HTMLOpenTagNode,
13
15
  HTMLCloseTagNode,
16
+ HTMLAttributeNameNode,
14
17
  HTMLCommentNode
15
18
  } from "./nodes.js"
16
19
 
@@ -24,7 +27,8 @@ import {
24
27
  filterLiteralNodes
25
28
  } from "./node-type-guards.js"
26
29
 
27
- import { Node, ERBContentNode, HTMLAttributeNameNode } from "./nodes.js"
30
+ import type { Location } from "./location.js"
31
+ import type { Position } from "./position.js"
28
32
 
29
33
  /**
30
34
  * Checks if a node is an ERB output node (generates content: <%= %> or <%== %>)
@@ -189,3 +193,99 @@ export function getTagName(node: HTMLElementNode | HTMLOpenTagNode | HTMLCloseT
189
193
  export function isCommentNode(node: Node): boolean {
190
194
  return isNode(node, HTMLCommentNode) || (isERBNode(node) && !isERBControlFlowNode(node))
191
195
  }
196
+
197
+ /**
198
+ * Compares two positions to determine if the first comes before the second
199
+ * Returns true if pos1 comes before pos2 in source order
200
+ * @param inclusive - If true, returns true when positions are equal
201
+ */
202
+ function isPositionBefore(position1: Position, position2: Position, inclusive = false): boolean {
203
+ if (position1.line < position2.line) return true
204
+ if (position1.line > position2.line) return false
205
+
206
+ return inclusive ? position1.column <= position2.column : position1.column < position2.column
207
+ }
208
+
209
+ /**
210
+ * Compares two positions to determine if they are equal
211
+ * Returns true if pos1 and pos2 are at the same location
212
+ */
213
+ export function isPositionEqual(position1: Position, position2: Position): boolean {
214
+ return position1.line === position2.line && position1.column === position2.column
215
+ }
216
+
217
+ /**
218
+ * Compares two positions to determine if the first comes after the second
219
+ * Returns true if pos1 comes after pos2 in source order
220
+ * @param inclusive - If true, returns true when positions are equal
221
+ */
222
+ export function isPositionAfter(position1: Position, position2: Position, inclusive = false): boolean {
223
+ if (position1.line > position2.line) return true
224
+ if (position1.line < position2.line) return false
225
+
226
+ return inclusive ? position1.column >= position2.column : position1.column > position2.column
227
+ }
228
+
229
+ /**
230
+ * Gets nodes that appear before the specified location in source order
231
+ * Uses line and column positions to determine ordering
232
+ */
233
+ export function getNodesBeforeLocation<T extends Node>(nodes: T[], location: Location): T[] {
234
+ return nodes.filter(node =>
235
+ node.location && isPositionBefore(node.location.end, location.start)
236
+ )
237
+ }
238
+
239
+ /**
240
+ * Gets nodes that appear after the specified location in source order
241
+ * Uses line and column positions to determine ordering
242
+ */
243
+ export function getNodesAfterLocation<T extends Node>(nodes: T[], location: Location): T[] {
244
+ return nodes.filter(node =>
245
+ node.location && isPositionAfter(node.location.start, location.end)
246
+ )
247
+ }
248
+
249
+ /**
250
+ * Splits nodes into before and after the specified location
251
+ * Returns an object with `before` and `after` arrays
252
+ */
253
+ export function splitNodesAroundLocation<T extends Node>(nodes: T[], location: Location): { before: T[], after: T[] } {
254
+ return {
255
+ before: getNodesBeforeLocation(nodes, location),
256
+ after: getNodesAfterLocation(nodes, location)
257
+ }
258
+ }
259
+
260
+ /**
261
+ * Splits nodes at a specific position
262
+ * Returns nodes that end before the position and nodes that start after the position
263
+ * More precise than splitNodesAroundLocation as it uses a single position point
264
+ * Uses the same defaults as the individual functions: before=exclusive, after=inclusive
265
+ */
266
+ export function splitNodesAroundPosition<T extends Node>(nodes: T[], position: Position): { before: T[], after: T[] } {
267
+ return {
268
+ before: getNodesBeforePosition(nodes, position), // uses default: inclusive = false
269
+ after: getNodesAfterPosition(nodes, position) // uses default: inclusive = true
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Gets nodes that end before the specified position
275
+ * @param inclusive - If true, includes nodes that end exactly at the position (default: false, matching half-open interval semantics)
276
+ */
277
+ export function getNodesBeforePosition<T extends Node>(nodes: T[], position: Position, inclusive = false): T[] {
278
+ return nodes.filter(node =>
279
+ node.location && isPositionBefore(node.location.end, position, inclusive)
280
+ )
281
+ }
282
+
283
+ /**
284
+ * Gets nodes that start after the specified position
285
+ * @param inclusive - If true, includes nodes that start exactly at the position (default: true, matching typical boundary behavior)
286
+ */
287
+ export function getNodesAfterPosition<T extends Node>(nodes: T[], position: Position, inclusive = true): T[] {
288
+ return nodes.filter(node =>
289
+ node.location && isPositionAfter(node.location.start, position, inclusive)
290
+ )
291
+ }
package/src/errors.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  // NOTE: This file is generated by the templates/template.rb script and should not
2
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.0/templates/javascript/packages/core/src/errors.ts.erb
2
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.1/templates/javascript/packages/core/src/errors.ts.erb
3
3
 
4
4
  import { Location, SerializedLocation } from "./location.js"
5
5
  import { Token, SerializedToken } from "./token.js"