@herb-tools/core 0.5.0 → 0.6.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.
@@ -4,56 +4,6 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Herb = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- const expectedFunctions = [
8
- "parse",
9
- "lex",
10
- "parseFile",
11
- "lexFile",
12
- "extractRuby",
13
- "extractHTML",
14
- "version",
15
- ];
16
- // NOTE: This function should never be called and is only for type checking
17
- // so we can make sure `expectedFunctions` matches the functions defined
18
- // in `LibHerbBackendFunctions` and the other way around.
19
- //
20
- function _TYPECHECK() {
21
- const checkFunctionsExist = true;
22
- const checkInterfaceComplete = true;
23
- return { checkFunctionsExist, checkInterfaceComplete };
24
- }
25
- function isLibHerbBackend(object, libherbpath = "unknown") {
26
- for (const expectedFunction of expectedFunctions) {
27
- if (object[expectedFunction] === undefined) {
28
- throw new Error(`Libherb at "${libherbpath}" doesn't expose function "${expectedFunction}".`);
29
- }
30
- if (typeof object[expectedFunction] !== "function") {
31
- throw new Error(`Libherb at "${libherbpath}" has "${expectedFunction}" but it's not a function.`);
32
- }
33
- }
34
- return true;
35
- }
36
- function ensureLibHerbBackend(object, libherbpath = "unknown") {
37
- isLibHerbBackend(object, libherbpath);
38
- return object;
39
- }
40
-
41
- /**
42
- * Converts a Diagnostic to Monaco/VSCode-compatible MonacoDiagnostic format
43
- */
44
- function toMonacoDiagnostic(diagnostic) {
45
- const { message, location } = diagnostic;
46
- const severity = diagnostic.severity === "hint" ? "info" : diagnostic.severity;
47
- return {
48
- line: location.start.line,
49
- column: location.start.column,
50
- endLine: location.end.line,
51
- endColumn: location.end.column,
52
- message,
53
- severity
54
- };
55
- }
56
-
57
7
  class Position {
58
8
  line;
59
9
  column;
@@ -185,7 +135,7 @@
185
135
  }
186
136
 
187
137
  // NOTE: This file is generated by the templates/template.rb script and should not
188
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.5.0/templates/javascript/packages/core/src/errors.ts.erb
138
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.0/templates/javascript/packages/core/src/errors.ts.erb
189
139
  class HerbError {
190
140
  type;
191
141
  message;
@@ -626,12 +576,6 @@
626
576
  }
627
577
  }
628
578
 
629
- var name = "@herb-tools/core";
630
- var version = "0.5.0";
631
- var packageJSON = {
632
- name: name,
633
- version: version};
634
-
635
579
  function ensureString(object) {
636
580
  if (typeof object === "string") {
637
581
  return object;
@@ -647,139 +591,8 @@
647
591
  return decoder.decode(new Uint8Array(bytes));
648
592
  }
649
593
 
650
- class Result {
651
- source;
652
- warnings;
653
- errors;
654
- constructor(source, warnings = [], errors = []) {
655
- this.source = source;
656
- this.warnings = warnings || [];
657
- this.errors = errors || [];
658
- }
659
- /**
660
- * Determines if the parsing was successful.
661
- * @returns `true` if there are no errors, otherwise `false`.
662
- */
663
- get successful() {
664
- return this.errors.length === 0;
665
- }
666
- /**
667
- * Determines if the parsing failed.
668
- * @returns `true` if there are errors, otherwise `false`.
669
- */
670
- get failed() {
671
- return this.errors.length > 0;
672
- }
673
- }
674
-
675
- class TokenList {
676
- list;
677
- static from(list) {
678
- return new TokenList(list.map((token) => Token.from(token)));
679
- }
680
- constructor(list) {
681
- this.list = list;
682
- }
683
- get length() {
684
- return this.list.length;
685
- }
686
- get tokens() {
687
- return this.list;
688
- }
689
- [Symbol.iterator]() {
690
- return this.list[Symbol.iterator]();
691
- }
692
- at(index) {
693
- return this.list.at(index);
694
- }
695
- forEach(callback) {
696
- this.list.forEach(callback);
697
- }
698
- map(callback) {
699
- return this.list.map(callback);
700
- }
701
- filter(predicate) {
702
- return this.list.filter(predicate);
703
- }
704
- __getobj__() {
705
- return this.list;
706
- }
707
- inspect() {
708
- return this.list.map((token) => token.inspect()).join("\n") + "\n";
709
- }
710
- toString() {
711
- return this.inspect();
712
- }
713
- }
714
-
715
- class HerbWarning {
716
- message;
717
- location;
718
- static from(warning) {
719
- return new HerbWarning(warning.message, Location.from(warning.location));
720
- }
721
- constructor(message, location) {
722
- this.message = message;
723
- this.location = location;
724
- }
725
- }
726
-
727
- /**
728
- * Represents the result of a lexical analysis, extending the base `Result` class.
729
- * It contains the token list, source code, warnings, and errors.
730
- */
731
- class LexResult extends Result {
732
- /** The list of tokens generated from the source code. */
733
- value;
734
- /**
735
- * Creates a `LexResult` instance from a serialized result.
736
- * @param result - The serialized lexical result containing tokens, source, warnings, and errors.
737
- * @returns A new `LexResult` instance.
738
- */
739
- static from(result) {
740
- return new LexResult(TokenList.from(result.tokens || []), result.source, result.warnings.map((warning) => HerbWarning.from(warning)), result.errors.map((error) => HerbError.from(error)));
741
- }
742
- /**
743
- * Constructs a new `LexResult`.
744
- * @param value - The list of tokens.
745
- * @param source - The source code that was lexed.
746
- * @param warnings - An array of warnings encountered during lexing.
747
- * @param errors - An array of errors encountered during lexing.
748
- */
749
- constructor(value, source, warnings = [], errors = []) {
750
- super(source, warnings, errors);
751
- this.value = value;
752
- }
753
- /**
754
- * Determines if the lexing was successful.
755
- * @returns `true` if there are no errors, otherwise `false`.
756
- */
757
- get successful() {
758
- return this.errors.length === 0;
759
- }
760
- /**
761
- * Determines if the lexing failed.
762
- * @returns `true` if there are errors, otherwise `false`.
763
- */
764
- get failed() {
765
- return this.errors.length > 0;
766
- }
767
- /**
768
- * Converts the `LexResult` to a JSON representation.
769
- * @returns An object containing the token list, source, warnings, and errors.
770
- */
771
- toJSON() {
772
- return {
773
- value: this.value,
774
- source: this.source,
775
- warnings: this.warnings,
776
- errors: this.errors,
777
- };
778
- }
779
- }
780
-
781
594
  // NOTE: This file is generated by the templates/template.rb script and should not
782
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.5.0/templates/javascript/packages/core/src/nodes.ts.erb
595
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.0/templates/javascript/packages/core/src/nodes.ts.erb
783
596
  class Node {
784
597
  type;
785
598
  location;
@@ -884,7 +697,6 @@
884
697
  output += `@ DocumentNode ${this.location.treeInspectWithLabel()}\n`;
885
698
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
886
699
  output += `└── children: ${this.inspectArray(this.children, " ")}`;
887
- // output += "\n";
888
700
  return output;
889
701
  }
890
702
  }
@@ -928,7 +740,6 @@
928
740
  output += `@ LiteralNode ${this.location.treeInspectWithLabel()}\n`;
929
741
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
930
742
  output += `└── content: ${this.content ? JSON.stringify(this.content) : "∅"}\n`;
931
- // output += "\n";
932
743
  return output;
933
744
  }
934
745
  }
@@ -995,13 +806,13 @@
995
806
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
996
807
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
997
808
  output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
998
- // output += "\n";
999
809
  return output;
1000
810
  }
1001
811
  }
1002
812
  class HTMLCloseTagNode extends Node {
1003
813
  tag_opening;
1004
814
  tag_name;
815
+ children;
1005
816
  tag_closing;
1006
817
  static from(data) {
1007
818
  return new HTMLCloseTagNode({
@@ -1010,6 +821,7 @@
1010
821
  errors: (data.errors || []).map(error => HerbError.from(error)),
1011
822
  tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1012
823
  tag_name: data.tag_name ? Token.from(data.tag_name) : null,
824
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1013
825
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1014
826
  });
1015
827
  }
@@ -1017,13 +829,16 @@
1017
829
  super(props.type, props.location, props.errors);
1018
830
  this.tag_opening = props.tag_opening;
1019
831
  this.tag_name = props.tag_name;
832
+ this.children = props.children;
1020
833
  this.tag_closing = props.tag_closing;
1021
834
  }
1022
835
  accept(visitor) {
1023
836
  visitor.visitHTMLCloseTagNode(this);
1024
837
  }
1025
838
  childNodes() {
1026
- return [];
839
+ return [
840
+ ...this.children,
841
+ ];
1027
842
  }
1028
843
  compactChildNodes() {
1029
844
  return this.childNodes().filter(node => node !== null && node !== undefined);
@@ -1031,6 +846,7 @@
1031
846
  recursiveErrors() {
1032
847
  return [
1033
848
  ...this.errors,
849
+ ...this.children.map(node => node.recursiveErrors()),
1034
850
  ].flat();
1035
851
  }
1036
852
  toJSON() {
@@ -1039,6 +855,7 @@
1039
855
  type: "AST_HTML_CLOSE_TAG_NODE",
1040
856
  tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1041
857
  tag_name: this.tag_name ? this.tag_name.toJSON() : null,
858
+ children: this.children.map(node => node.toJSON()),
1042
859
  tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1043
860
  };
1044
861
  }
@@ -1048,75 +865,8 @@
1048
865
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1049
866
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1050
867
  output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
868
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1051
869
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1052
- // output += "\n";
1053
- return output;
1054
- }
1055
- }
1056
- class HTMLSelfCloseTagNode extends Node {
1057
- tag_opening;
1058
- tag_name;
1059
- attributes;
1060
- tag_closing;
1061
- is_void;
1062
- static from(data) {
1063
- return new HTMLSelfCloseTagNode({
1064
- type: data.type,
1065
- location: Location.from(data.location),
1066
- errors: (data.errors || []).map(error => HerbError.from(error)),
1067
- tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1068
- tag_name: data.tag_name ? Token.from(data.tag_name) : null,
1069
- attributes: (data.attributes || []).map(node => fromSerializedNode(node)),
1070
- tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1071
- is_void: data.is_void,
1072
- });
1073
- }
1074
- constructor(props) {
1075
- super(props.type, props.location, props.errors);
1076
- this.tag_opening = props.tag_opening;
1077
- this.tag_name = props.tag_name;
1078
- this.attributes = props.attributes;
1079
- this.tag_closing = props.tag_closing;
1080
- this.is_void = props.is_void;
1081
- }
1082
- accept(visitor) {
1083
- visitor.visitHTMLSelfCloseTagNode(this);
1084
- }
1085
- childNodes() {
1086
- return [
1087
- ...this.attributes,
1088
- ];
1089
- }
1090
- compactChildNodes() {
1091
- return this.childNodes().filter(node => node !== null && node !== undefined);
1092
- }
1093
- recursiveErrors() {
1094
- return [
1095
- ...this.errors,
1096
- ...this.attributes.map(node => node.recursiveErrors()),
1097
- ].flat();
1098
- }
1099
- toJSON() {
1100
- return {
1101
- ...super.toJSON(),
1102
- type: "AST_HTML_SELF_CLOSE_TAG_NODE",
1103
- tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1104
- tag_name: this.tag_name ? this.tag_name.toJSON() : null,
1105
- attributes: this.attributes.map(node => node.toJSON()),
1106
- tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1107
- is_void: this.is_void,
1108
- };
1109
- }
1110
- treeInspect() {
1111
- let output = "";
1112
- output += `@ HTMLSelfCloseTagNode ${this.location.treeInspectWithLabel()}\n`;
1113
- output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1114
- output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1115
- output += `├── tag_name: ${this.tag_name ? this.tag_name.treeInspect() : "∅"}\n`;
1116
- output += `├── attributes: ${this.inspectArray(this.attributes, "│ ")}`;
1117
- output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1118
- output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
1119
- // output += "\n";
1120
870
  return output;
1121
871
  }
1122
872
  }
@@ -1131,10 +881,10 @@
1131
881
  type: data.type,
1132
882
  location: Location.from(data.location),
1133
883
  errors: (data.errors || []).map(error => HerbError.from(error)),
1134
- open_tag: data.open_tag ? fromSerializedNode(data.open_tag) : null,
884
+ open_tag: data.open_tag ? fromSerializedNode((data.open_tag)) : null,
1135
885
  tag_name: data.tag_name ? Token.from(data.tag_name) : null,
1136
886
  body: (data.body || []).map(node => fromSerializedNode(node)),
1137
- close_tag: data.close_tag ? fromSerializedNode(data.close_tag) : null,
887
+ close_tag: data.close_tag ? fromSerializedNode((data.close_tag)) : null,
1138
888
  is_void: data.is_void,
1139
889
  });
1140
890
  }
@@ -1187,7 +937,6 @@
1187
937
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
1188
938
  output += `├── close_tag: ${this.inspectNode(this.close_tag, "│ ")}`;
1189
939
  output += `└── is_void: ${typeof this.is_void === 'boolean' ? String(this.is_void) : "∅"}\n`;
1190
- // output += "\n";
1191
940
  return output;
1192
941
  }
1193
942
  }
@@ -1249,29 +998,30 @@
1249
998
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1250
999
  output += `├── close_quote: ${this.close_quote ? this.close_quote.treeInspect() : "∅"}\n`;
1251
1000
  output += `└── quoted: ${typeof this.quoted === 'boolean' ? String(this.quoted) : "∅"}\n`;
1252
- // output += "\n";
1253
1001
  return output;
1254
1002
  }
1255
1003
  }
1256
1004
  class HTMLAttributeNameNode extends Node {
1257
- name;
1005
+ children;
1258
1006
  static from(data) {
1259
1007
  return new HTMLAttributeNameNode({
1260
1008
  type: data.type,
1261
1009
  location: Location.from(data.location),
1262
1010
  errors: (data.errors || []).map(error => HerbError.from(error)),
1263
- name: data.name ? Token.from(data.name) : null,
1011
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1264
1012
  });
1265
1013
  }
1266
1014
  constructor(props) {
1267
1015
  super(props.type, props.location, props.errors);
1268
- this.name = props.name;
1016
+ this.children = props.children;
1269
1017
  }
1270
1018
  accept(visitor) {
1271
1019
  visitor.visitHTMLAttributeNameNode(this);
1272
1020
  }
1273
1021
  childNodes() {
1274
- return [];
1022
+ return [
1023
+ ...this.children,
1024
+ ];
1275
1025
  }
1276
1026
  compactChildNodes() {
1277
1027
  return this.childNodes().filter(node => node !== null && node !== undefined);
@@ -1279,21 +1029,21 @@
1279
1029
  recursiveErrors() {
1280
1030
  return [
1281
1031
  ...this.errors,
1032
+ ...this.children.map(node => node.recursiveErrors()),
1282
1033
  ].flat();
1283
1034
  }
1284
1035
  toJSON() {
1285
1036
  return {
1286
1037
  ...super.toJSON(),
1287
1038
  type: "AST_HTML_ATTRIBUTE_NAME_NODE",
1288
- name: this.name ? this.name.toJSON() : null,
1039
+ children: this.children.map(node => node.toJSON()),
1289
1040
  };
1290
1041
  }
1291
1042
  treeInspect() {
1292
1043
  let output = "";
1293
1044
  output += `@ HTMLAttributeNameNode ${this.location.treeInspectWithLabel()}\n`;
1294
1045
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1295
- output += `└── name: ${this.name ? this.name.treeInspect() : ""}\n`;
1296
- // output += "\n";
1046
+ output += `└── children: ${this.inspectArray(this.children, " ")}`;
1297
1047
  return output;
1298
1048
  }
1299
1049
  }
@@ -1306,9 +1056,9 @@
1306
1056
  type: data.type,
1307
1057
  location: Location.from(data.location),
1308
1058
  errors: (data.errors || []).map(error => HerbError.from(error)),
1309
- name: data.name ? fromSerializedNode(data.name) : null,
1059
+ name: data.name ? fromSerializedNode((data.name)) : null,
1310
1060
  equals: data.equals ? Token.from(data.equals) : null,
1311
- value: data.value ? fromSerializedNode(data.value) : null,
1061
+ value: data.value ? fromSerializedNode((data.value)) : null,
1312
1062
  });
1313
1063
  }
1314
1064
  constructor(props) {
@@ -1352,7 +1102,6 @@
1352
1102
  output += `├── name: ${this.inspectNode(this.name, "│ ")}`;
1353
1103
  output += `├── equals: ${this.equals ? this.equals.treeInspect() : "∅"}\n`;
1354
1104
  output += `└── value: ${this.inspectNode(this.value, " ")}`;
1355
- // output += "\n";
1356
1105
  return output;
1357
1106
  }
1358
1107
  }
@@ -1396,7 +1145,6 @@
1396
1145
  output += `@ HTMLTextNode ${this.location.treeInspectWithLabel()}\n`;
1397
1146
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1398
1147
  output += `└── content: ${this.content ? JSON.stringify(this.content) : "∅"}\n`;
1399
- // output += "\n";
1400
1148
  return output;
1401
1149
  }
1402
1150
  }
@@ -1453,7 +1201,6 @@
1453
1201
  output += `├── comment_start: ${this.comment_start ? this.comment_start.treeInspect() : "∅"}\n`;
1454
1202
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1455
1203
  output += `└── comment_end: ${this.comment_end ? this.comment_end.treeInspect() : "∅"}\n`;
1456
- // output += "\n";
1457
1204
  return output;
1458
1205
  }
1459
1206
  }
@@ -1510,7 +1257,118 @@
1510
1257
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1511
1258
  output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1512
1259
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1513
- // output += "\n";
1260
+ return output;
1261
+ }
1262
+ }
1263
+ class XMLDeclarationNode extends Node {
1264
+ tag_opening;
1265
+ children;
1266
+ tag_closing;
1267
+ static from(data) {
1268
+ return new XMLDeclarationNode({
1269
+ type: data.type,
1270
+ location: Location.from(data.location),
1271
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1272
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1273
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1274
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1275
+ });
1276
+ }
1277
+ constructor(props) {
1278
+ super(props.type, props.location, props.errors);
1279
+ this.tag_opening = props.tag_opening;
1280
+ this.children = props.children;
1281
+ this.tag_closing = props.tag_closing;
1282
+ }
1283
+ accept(visitor) {
1284
+ visitor.visitXMLDeclarationNode(this);
1285
+ }
1286
+ childNodes() {
1287
+ return [
1288
+ ...this.children,
1289
+ ];
1290
+ }
1291
+ compactChildNodes() {
1292
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1293
+ }
1294
+ recursiveErrors() {
1295
+ return [
1296
+ ...this.errors,
1297
+ ...this.children.map(node => node.recursiveErrors()),
1298
+ ].flat();
1299
+ }
1300
+ toJSON() {
1301
+ return {
1302
+ ...super.toJSON(),
1303
+ type: "AST_XML_DECLARATION_NODE",
1304
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1305
+ children: this.children.map(node => node.toJSON()),
1306
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1307
+ };
1308
+ }
1309
+ treeInspect() {
1310
+ let output = "";
1311
+ output += `@ XMLDeclarationNode ${this.location.treeInspectWithLabel()}\n`;
1312
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1313
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1314
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1315
+ output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1316
+ return output;
1317
+ }
1318
+ }
1319
+ class CDATANode extends Node {
1320
+ tag_opening;
1321
+ children;
1322
+ tag_closing;
1323
+ static from(data) {
1324
+ return new CDATANode({
1325
+ type: data.type,
1326
+ location: Location.from(data.location),
1327
+ errors: (data.errors || []).map(error => HerbError.from(error)),
1328
+ tag_opening: data.tag_opening ? Token.from(data.tag_opening) : null,
1329
+ children: (data.children || []).map(node => fromSerializedNode(node)),
1330
+ tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1331
+ });
1332
+ }
1333
+ constructor(props) {
1334
+ super(props.type, props.location, props.errors);
1335
+ this.tag_opening = props.tag_opening;
1336
+ this.children = props.children;
1337
+ this.tag_closing = props.tag_closing;
1338
+ }
1339
+ accept(visitor) {
1340
+ visitor.visitCDATANode(this);
1341
+ }
1342
+ childNodes() {
1343
+ return [
1344
+ ...this.children,
1345
+ ];
1346
+ }
1347
+ compactChildNodes() {
1348
+ return this.childNodes().filter(node => node !== null && node !== undefined);
1349
+ }
1350
+ recursiveErrors() {
1351
+ return [
1352
+ ...this.errors,
1353
+ ...this.children.map(node => node.recursiveErrors()),
1354
+ ].flat();
1355
+ }
1356
+ toJSON() {
1357
+ return {
1358
+ ...super.toJSON(),
1359
+ type: "AST_CDATA_NODE",
1360
+ tag_opening: this.tag_opening ? this.tag_opening.toJSON() : null,
1361
+ children: this.children.map(node => node.toJSON()),
1362
+ tag_closing: this.tag_closing ? this.tag_closing.toJSON() : null,
1363
+ };
1364
+ }
1365
+ treeInspect() {
1366
+ let output = "";
1367
+ output += `@ CDATANode ${this.location.treeInspectWithLabel()}\n`;
1368
+ output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1369
+ output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1370
+ output += `├── children: ${this.inspectArray(this.children, "│ ")}`;
1371
+ output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1514
1372
  return output;
1515
1373
  }
1516
1374
  }
@@ -1554,7 +1412,6 @@
1554
1412
  output += `@ WhitespaceNode ${this.location.treeInspectWithLabel()}\n`;
1555
1413
  output += `├── errors: ${this.inspectArray(this.errors, "│ ")}`;
1556
1414
  output += `└── value: ${this.value ? this.value.treeInspect() : "∅"}\n`;
1557
- // output += "\n";
1558
1415
  return output;
1559
1416
  }
1560
1417
  }
@@ -1623,7 +1480,6 @@
1623
1480
  // no-op for analyzed_ruby
1624
1481
  output += `├── parsed: ${typeof this.parsed === 'boolean' ? String(this.parsed) : "∅"}\n`;
1625
1482
  output += `└── valid: ${typeof this.valid === 'boolean' ? String(this.valid) : "∅"}\n`;
1626
- // output += "\n";
1627
1483
  return output;
1628
1484
  }
1629
1485
  }
@@ -1677,7 +1533,6 @@
1677
1533
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
1678
1534
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1679
1535
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1680
- // output += "\n";
1681
1536
  return output;
1682
1537
  }
1683
1538
  }
@@ -1739,7 +1594,6 @@
1739
1594
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1740
1595
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1741
1596
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
1742
- // output += "\n";
1743
1597
  return output;
1744
1598
  }
1745
1599
  }
@@ -1759,8 +1613,8 @@
1759
1613
  content: data.content ? Token.from(data.content) : null,
1760
1614
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1761
1615
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
1762
- subsequent: data.subsequent ? fromSerializedNode(data.subsequent) : null,
1763
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
1616
+ subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
1617
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1764
1618
  });
1765
1619
  }
1766
1620
  constructor(props) {
@@ -1815,7 +1669,6 @@
1815
1669
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
1816
1670
  output += `├── subsequent: ${this.inspectNode(this.subsequent, "│ ")}`;
1817
1671
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1818
- // output += "\n";
1819
1672
  return output;
1820
1673
  }
1821
1674
  }
@@ -1834,7 +1687,7 @@
1834
1687
  content: data.content ? Token.from(data.content) : null,
1835
1688
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1836
1689
  body: (data.body || []).map(node => fromSerializedNode(node)),
1837
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
1690
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1838
1691
  });
1839
1692
  }
1840
1693
  constructor(props) {
@@ -1884,7 +1737,6 @@
1884
1737
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1885
1738
  output += `├── body: ${this.inspectArray(this.body, "│ ")}`;
1886
1739
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
1887
- // output += "\n";
1888
1740
  return output;
1889
1741
  }
1890
1742
  }
@@ -1946,7 +1798,6 @@
1946
1798
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
1947
1799
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
1948
1800
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
1949
- // output += "\n";
1950
1801
  return output;
1951
1802
  }
1952
1803
  }
@@ -1968,8 +1819,8 @@
1968
1819
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
1969
1820
  children: (data.children || []).map(node => fromSerializedNode(node)),
1970
1821
  conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
1971
- else_clause: data.else_clause ? fromSerializedNode(data.else_clause) : null,
1972
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
1822
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
1823
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
1973
1824
  });
1974
1825
  }
1975
1826
  constructor(props) {
@@ -2029,7 +1880,6 @@
2029
1880
  output += `├── conditions: ${this.inspectArray(this.conditions, "│ ")}`;
2030
1881
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2031
1882
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2032
- // output += "\n";
2033
1883
  return output;
2034
1884
  }
2035
1885
  }
@@ -2051,8 +1901,8 @@
2051
1901
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2052
1902
  children: (data.children || []).map(node => fromSerializedNode(node)),
2053
1903
  conditions: (data.conditions || []).map(node => fromSerializedNode(node)),
2054
- else_clause: data.else_clause ? fromSerializedNode(data.else_clause) : null,
2055
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
1904
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
1905
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2056
1906
  });
2057
1907
  }
2058
1908
  constructor(props) {
@@ -2112,7 +1962,6 @@
2112
1962
  output += `├── conditions: ${this.inspectArray(this.conditions, "│ ")}`;
2113
1963
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2114
1964
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2115
- // output += "\n";
2116
1965
  return output;
2117
1966
  }
2118
1967
  }
@@ -2131,7 +1980,7 @@
2131
1980
  content: data.content ? Token.from(data.content) : null,
2132
1981
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2133
1982
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2134
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
1983
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2135
1984
  });
2136
1985
  }
2137
1986
  constructor(props) {
@@ -2181,7 +2030,6 @@
2181
2030
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2182
2031
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2183
2032
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2184
- // output += "\n";
2185
2033
  return output;
2186
2034
  }
2187
2035
  }
@@ -2200,7 +2048,7 @@
2200
2048
  content: data.content ? Token.from(data.content) : null,
2201
2049
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2202
2050
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2203
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
2051
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2204
2052
  });
2205
2053
  }
2206
2054
  constructor(props) {
@@ -2250,7 +2098,6 @@
2250
2098
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2251
2099
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2252
2100
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2253
- // output += "\n";
2254
2101
  return output;
2255
2102
  }
2256
2103
  }
@@ -2269,7 +2116,7 @@
2269
2116
  content: data.content ? Token.from(data.content) : null,
2270
2117
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2271
2118
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2272
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
2119
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2273
2120
  });
2274
2121
  }
2275
2122
  constructor(props) {
@@ -2319,7 +2166,6 @@
2319
2166
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2320
2167
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2321
2168
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2322
- // output += "\n";
2323
2169
  return output;
2324
2170
  }
2325
2171
  }
@@ -2338,7 +2184,7 @@
2338
2184
  content: data.content ? Token.from(data.content) : null,
2339
2185
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2340
2186
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2341
- subsequent: data.subsequent ? fromSerializedNode(data.subsequent) : null,
2187
+ subsequent: data.subsequent ? fromSerializedNode((data.subsequent)) : null,
2342
2188
  });
2343
2189
  }
2344
2190
  constructor(props) {
@@ -2388,7 +2234,6 @@
2388
2234
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2389
2235
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2390
2236
  output += `└── subsequent: ${this.inspectNode(this.subsequent, " ")}`;
2391
- // output += "\n";
2392
2237
  return output;
2393
2238
  }
2394
2239
  }
@@ -2450,7 +2295,6 @@
2450
2295
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2451
2296
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2452
2297
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
2453
- // output += "\n";
2454
2298
  return output;
2455
2299
  }
2456
2300
  }
@@ -2472,10 +2316,10 @@
2472
2316
  content: data.content ? Token.from(data.content) : null,
2473
2317
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2474
2318
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2475
- rescue_clause: data.rescue_clause ? fromSerializedNode(data.rescue_clause) : null,
2476
- else_clause: data.else_clause ? fromSerializedNode(data.else_clause) : null,
2477
- ensure_clause: data.ensure_clause ? fromSerializedNode(data.ensure_clause) : null,
2478
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
2319
+ rescue_clause: data.rescue_clause ? fromSerializedNode((data.rescue_clause)) : null,
2320
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2321
+ ensure_clause: data.ensure_clause ? fromSerializedNode((data.ensure_clause)) : null,
2322
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2479
2323
  });
2480
2324
  }
2481
2325
  constructor(props) {
@@ -2540,7 +2384,6 @@
2540
2384
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2541
2385
  output += `├── ensure_clause: ${this.inspectNode(this.ensure_clause, "│ ")}`;
2542
2386
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2543
- // output += "\n";
2544
2387
  return output;
2545
2388
  }
2546
2389
  }
@@ -2560,8 +2403,8 @@
2560
2403
  content: data.content ? Token.from(data.content) : null,
2561
2404
  tag_closing: data.tag_closing ? Token.from(data.tag_closing) : null,
2562
2405
  statements: (data.statements || []).map(node => fromSerializedNode(node)),
2563
- else_clause: data.else_clause ? fromSerializedNode(data.else_clause) : null,
2564
- end_node: data.end_node ? fromSerializedNode(data.end_node) : null,
2406
+ else_clause: data.else_clause ? fromSerializedNode((data.else_clause)) : null,
2407
+ end_node: data.end_node ? fromSerializedNode((data.end_node)) : null,
2565
2408
  });
2566
2409
  }
2567
2410
  constructor(props) {
@@ -2616,7 +2459,6 @@
2616
2459
  output += `├── statements: ${this.inspectArray(this.statements, "│ ")}`;
2617
2460
  output += `├── else_clause: ${this.inspectNode(this.else_clause, "│ ")}`;
2618
2461
  output += `└── end_node: ${this.inspectNode(this.end_node, " ")}`;
2619
- // output += "\n";
2620
2462
  return output;
2621
2463
  }
2622
2464
  }
@@ -2670,7 +2512,6 @@
2670
2512
  output += `├── tag_opening: ${this.tag_opening ? this.tag_opening.treeInspect() : "∅"}\n`;
2671
2513
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2672
2514
  output += `└── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2673
- // output += "\n";
2674
2515
  return output;
2675
2516
  }
2676
2517
  }
@@ -2732,7 +2573,6 @@
2732
2573
  output += `├── content: ${this.content ? this.content.treeInspect() : "∅"}\n`;
2733
2574
  output += `├── tag_closing: ${this.tag_closing ? this.tag_closing.treeInspect() : "∅"}\n`;
2734
2575
  output += `└── statements: ${this.inspectArray(this.statements, " ")}`;
2735
- // output += "\n";
2736
2576
  return output;
2737
2577
  }
2738
2578
  }
@@ -2742,7 +2582,6 @@
2742
2582
  case "AST_LITERAL_NODE": return LiteralNode.from(node);
2743
2583
  case "AST_HTML_OPEN_TAG_NODE": return HTMLOpenTagNode.from(node);
2744
2584
  case "AST_HTML_CLOSE_TAG_NODE": return HTMLCloseTagNode.from(node);
2745
- case "AST_HTML_SELF_CLOSE_TAG_NODE": return HTMLSelfCloseTagNode.from(node);
2746
2585
  case "AST_HTML_ELEMENT_NODE": return HTMLElementNode.from(node);
2747
2586
  case "AST_HTML_ATTRIBUTE_VALUE_NODE": return HTMLAttributeValueNode.from(node);
2748
2587
  case "AST_HTML_ATTRIBUTE_NAME_NODE": return HTMLAttributeNameNode.from(node);
@@ -2750,6 +2589,8 @@
2750
2589
  case "AST_HTML_TEXT_NODE": return HTMLTextNode.from(node);
2751
2590
  case "AST_HTML_COMMENT_NODE": return HTMLCommentNode.from(node);
2752
2591
  case "AST_HTML_DOCTYPE_NODE": return HTMLDoctypeNode.from(node);
2592
+ case "AST_XML_DECLARATION_NODE": return XMLDeclarationNode.from(node);
2593
+ case "AST_CDATA_NODE": return CDATANode.from(node);
2753
2594
  case "AST_WHITESPACE_NODE": return WhitespaceNode.from(node);
2754
2595
  case "AST_ERB_CONTENT_NODE": return ERBContentNode.from(node);
2755
2596
  case "AST_ERB_END_NODE": return ERBEndNode.from(node);
@@ -2791,8 +2632,42 @@
2791
2632
  ERBYieldNode,
2792
2633
  ERBInNode,
2793
2634
  ];
2794
- function isERBNode(node) {
2795
- return node.constructor.name.startsWith("ERB");
2635
+
2636
+ class Result {
2637
+ source;
2638
+ warnings;
2639
+ errors;
2640
+ constructor(source, warnings = [], errors = []) {
2641
+ this.source = source;
2642
+ this.warnings = warnings || [];
2643
+ this.errors = errors || [];
2644
+ }
2645
+ /**
2646
+ * Determines if the parsing was successful.
2647
+ * @returns `true` if there are no errors, otherwise `false`.
2648
+ */
2649
+ get successful() {
2650
+ return this.errors.length === 0;
2651
+ }
2652
+ /**
2653
+ * Determines if the parsing failed.
2654
+ * @returns `true` if there are errors, otherwise `false`.
2655
+ */
2656
+ get failed() {
2657
+ return this.errors.length > 0;
2658
+ }
2659
+ }
2660
+
2661
+ class HerbWarning {
2662
+ message;
2663
+ location;
2664
+ static from(warning) {
2665
+ return new HerbWarning(warning.message, Location.from(warning.location));
2666
+ }
2667
+ constructor(message, location) {
2668
+ this.message = message;
2669
+ this.location = location;
2670
+ }
2796
2671
  }
2797
2672
 
2798
2673
  /**
@@ -2862,125 +2737,1038 @@
2862
2737
  }
2863
2738
  }
2864
2739
 
2740
+ // NOTE: This file is generated by the templates/template.rb script and should not
2741
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.0/templates/javascript/packages/core/src/node-type-guards.ts.erb
2865
2742
  /**
2866
- * The main Herb parser interface, providing methods to lex and parse input.
2743
+ * Type guard functions for AST nodes.
2744
+ * These functions provide type checking by combining both instanceof
2745
+ * checks and type string comparisons for maximum reliability across different
2746
+ * runtime scenarios (e.g., serialized/deserialized nodes).
2867
2747
  */
2868
- class HerbBackend {
2869
- /** The backend instance handling lexing and parsing. */
2870
- backend = undefined;
2871
- backendPromise;
2872
- /**
2873
- * Creates a new Herb instance.
2874
- * @param backendPromise - A promise resolving to a `LibHerbBackend` implementation for lexing and parsing.
2875
- * @throws Error if no valid backend is provided.
2876
- */
2877
- constructor(backendPromise) {
2878
- if (!backendPromise) {
2879
- throw new Error("No LibHerb backend provided");
2880
- }
2881
- this.backendPromise = backendPromise;
2882
- }
2883
- /**
2884
- * Loads the backend by resolving the backend promise.
2885
- * @returns A promise containing the resolved `HerbBackend` instance after loading it.
2886
- */
2887
- async load() {
2888
- const backend = await this.backendPromise();
2889
- this.backend = backend;
2890
- return this;
2891
- }
2892
- /**
2893
- * Lexes the given source string into a `LexResult`.
2894
- * @param source - The source code to lex.
2895
- * @returns A `LexResult` instance.
2896
- * @throws Error if the backend is not loaded.
2897
- */
2898
- lex(source) {
2899
- this.ensureBackend();
2900
- return LexResult.from(this.backend.lex(ensureString(source)));
2901
- }
2902
- /**
2903
- * Lexes a file.
2904
- * @param path - The file path to lex.
2905
- * @returns A `LexResult` instance.
2906
- * @throws Error if the backend is not loaded.
2907
- */
2908
- lexFile(path) {
2909
- this.ensureBackend();
2910
- return LexResult.from(this.backend.lexFile(ensureString(path)));
2911
- }
2912
- /**
2913
- * Parses the given source string into a `ParseResult`.
2914
- * @param source - The source code to parse.
2915
- * @returns A `ParseResult` instance.
2916
- * @throws Error if the backend is not loaded.
2917
- */
2918
- parse(source) {
2919
- this.ensureBackend();
2920
- return ParseResult.from(this.backend.parse(ensureString(source)));
2921
- }
2922
- /**
2923
- * Parses a file.
2924
- * @param path - The file path to parse.
2925
- * @returns A `ParseResult` instance.
2926
- * @throws Error if the backend is not loaded.
2927
- */
2928
- parseFile(path) {
2929
- this.ensureBackend();
2930
- return ParseResult.from(this.backend.parseFile(ensureString(path)));
2931
- }
2932
- /**
2933
- * Extracts embedded Ruby code from the given source.
2934
- * @param source - The source code to extract Ruby from.
2935
- * @returns The extracted Ruby code as a string.
2936
- * @throws Error if the backend is not loaded.
2937
- */
2938
- extractRuby(source) {
2939
- this.ensureBackend();
2940
- return this.backend.extractRuby(ensureString(source));
2941
- }
2942
- /**
2943
- * Extracts HTML from the given source.
2944
- * @param source - The source code to extract HTML from.
2945
- * @returns The extracted HTML as a string.
2946
- * @throws Error if the backend is not loaded.
2947
- */
2948
- extractHTML(source) {
2949
- this.ensureBackend();
2950
- return this.backend.extractHTML(ensureString(source));
2951
- }
2952
- /**
2953
- * Gets the Herb version information, including the core and backend versions.
2954
- * @returns A version string containing backend, core, and libherb versions.
2955
- * @throws Error if the backend is not loaded.
2956
- */
2957
- get version() {
2958
- this.ensureBackend();
2959
- const backend = this.backendVersion();
2960
- const core = `${packageJSON.name}@${packageJSON.version}`;
2961
- const libherb = this.backend.version();
2962
- return `${backend}, ${core}, ${libherb}`;
2963
- }
2964
- /**
2965
- * Ensures that the backend is loaded.
2966
- * @throws Error if the backend is not loaded.
2967
- */
2968
- ensureBackend() {
2969
- if (!this.isLoaded) {
2970
- throw new Error("Herb backend is not loaded. Call `await Herb.load()` first.");
2971
- }
2972
- }
2973
- /**
2974
- * Checks if the backend is loaded.
2975
- * @returns True if the backend is loaded, false otherwise.
2976
- */
2977
- get isLoaded() {
2748
+ /**
2749
+ * Checks if a node is a DocumentNode
2750
+ */
2751
+ function isDocumentNode(node) {
2752
+ return node instanceof DocumentNode || node.type === "AST_DOCUMENT_NODE";
2753
+ }
2754
+ /**
2755
+ * Checks if a node is a LiteralNode
2756
+ */
2757
+ function isLiteralNode(node) {
2758
+ return node instanceof LiteralNode || node.type === "AST_LITERAL_NODE";
2759
+ }
2760
+ /**
2761
+ * Checks if a node is a HTMLOpenTagNode
2762
+ */
2763
+ function isHTMLOpenTagNode(node) {
2764
+ return node instanceof HTMLOpenTagNode || node.type === "AST_HTML_OPEN_TAG_NODE";
2765
+ }
2766
+ /**
2767
+ * Checks if a node is a HTMLCloseTagNode
2768
+ */
2769
+ function isHTMLCloseTagNode(node) {
2770
+ return node instanceof HTMLCloseTagNode || node.type === "AST_HTML_CLOSE_TAG_NODE";
2771
+ }
2772
+ /**
2773
+ * Checks if a node is a HTMLElementNode
2774
+ */
2775
+ function isHTMLElementNode(node) {
2776
+ return node instanceof HTMLElementNode || node.type === "AST_HTML_ELEMENT_NODE";
2777
+ }
2778
+ /**
2779
+ * Checks if a node is a HTMLAttributeValueNode
2780
+ */
2781
+ function isHTMLAttributeValueNode(node) {
2782
+ return node instanceof HTMLAttributeValueNode || node.type === "AST_HTML_ATTRIBUTE_VALUE_NODE";
2783
+ }
2784
+ /**
2785
+ * Checks if a node is a HTMLAttributeNameNode
2786
+ */
2787
+ function isHTMLAttributeNameNode(node) {
2788
+ return node instanceof HTMLAttributeNameNode || node.type === "AST_HTML_ATTRIBUTE_NAME_NODE";
2789
+ }
2790
+ /**
2791
+ * Checks if a node is a HTMLAttributeNode
2792
+ */
2793
+ function isHTMLAttributeNode(node) {
2794
+ return node instanceof HTMLAttributeNode || node.type === "AST_HTML_ATTRIBUTE_NODE";
2795
+ }
2796
+ /**
2797
+ * Checks if a node is a HTMLTextNode
2798
+ */
2799
+ function isHTMLTextNode(node) {
2800
+ return node instanceof HTMLTextNode || node.type === "AST_HTML_TEXT_NODE";
2801
+ }
2802
+ /**
2803
+ * Checks if a node is a HTMLCommentNode
2804
+ */
2805
+ function isHTMLCommentNode(node) {
2806
+ return node instanceof HTMLCommentNode || node.type === "AST_HTML_COMMENT_NODE";
2807
+ }
2808
+ /**
2809
+ * Checks if a node is a HTMLDoctypeNode
2810
+ */
2811
+ function isHTMLDoctypeNode(node) {
2812
+ return node instanceof HTMLDoctypeNode || node.type === "AST_HTML_DOCTYPE_NODE";
2813
+ }
2814
+ /**
2815
+ * Checks if a node is a XMLDeclarationNode
2816
+ */
2817
+ function isXMLDeclarationNode(node) {
2818
+ return node instanceof XMLDeclarationNode || node.type === "AST_XML_DECLARATION_NODE";
2819
+ }
2820
+ /**
2821
+ * Checks if a node is a CDATANode
2822
+ */
2823
+ function isCDATANode(node) {
2824
+ return node instanceof CDATANode || node.type === "AST_CDATA_NODE";
2825
+ }
2826
+ /**
2827
+ * Checks if a node is a WhitespaceNode
2828
+ */
2829
+ function isWhitespaceNode(node) {
2830
+ return node instanceof WhitespaceNode || node.type === "AST_WHITESPACE_NODE";
2831
+ }
2832
+ /**
2833
+ * Checks if a node is a ERBContentNode
2834
+ */
2835
+ function isERBContentNode(node) {
2836
+ return node instanceof ERBContentNode || node.type === "AST_ERB_CONTENT_NODE";
2837
+ }
2838
+ /**
2839
+ * Checks if a node is a ERBEndNode
2840
+ */
2841
+ function isERBEndNode(node) {
2842
+ return node instanceof ERBEndNode || node.type === "AST_ERB_END_NODE";
2843
+ }
2844
+ /**
2845
+ * Checks if a node is a ERBElseNode
2846
+ */
2847
+ function isERBElseNode(node) {
2848
+ return node instanceof ERBElseNode || node.type === "AST_ERB_ELSE_NODE";
2849
+ }
2850
+ /**
2851
+ * Checks if a node is a ERBIfNode
2852
+ */
2853
+ function isERBIfNode(node) {
2854
+ return node instanceof ERBIfNode || node.type === "AST_ERB_IF_NODE";
2855
+ }
2856
+ /**
2857
+ * Checks if a node is a ERBBlockNode
2858
+ */
2859
+ function isERBBlockNode(node) {
2860
+ return node instanceof ERBBlockNode || node.type === "AST_ERB_BLOCK_NODE";
2861
+ }
2862
+ /**
2863
+ * Checks if a node is a ERBWhenNode
2864
+ */
2865
+ function isERBWhenNode(node) {
2866
+ return node instanceof ERBWhenNode || node.type === "AST_ERB_WHEN_NODE";
2867
+ }
2868
+ /**
2869
+ * Checks if a node is a ERBCaseNode
2870
+ */
2871
+ function isERBCaseNode(node) {
2872
+ return node instanceof ERBCaseNode || node.type === "AST_ERB_CASE_NODE";
2873
+ }
2874
+ /**
2875
+ * Checks if a node is a ERBCaseMatchNode
2876
+ */
2877
+ function isERBCaseMatchNode(node) {
2878
+ return node instanceof ERBCaseMatchNode || node.type === "AST_ERB_CASE_MATCH_NODE";
2879
+ }
2880
+ /**
2881
+ * Checks if a node is a ERBWhileNode
2882
+ */
2883
+ function isERBWhileNode(node) {
2884
+ return node instanceof ERBWhileNode || node.type === "AST_ERB_WHILE_NODE";
2885
+ }
2886
+ /**
2887
+ * Checks if a node is a ERBUntilNode
2888
+ */
2889
+ function isERBUntilNode(node) {
2890
+ return node instanceof ERBUntilNode || node.type === "AST_ERB_UNTIL_NODE";
2891
+ }
2892
+ /**
2893
+ * Checks if a node is a ERBForNode
2894
+ */
2895
+ function isERBForNode(node) {
2896
+ return node instanceof ERBForNode || node.type === "AST_ERB_FOR_NODE";
2897
+ }
2898
+ /**
2899
+ * Checks if a node is a ERBRescueNode
2900
+ */
2901
+ function isERBRescueNode(node) {
2902
+ return node instanceof ERBRescueNode || node.type === "AST_ERB_RESCUE_NODE";
2903
+ }
2904
+ /**
2905
+ * Checks if a node is a ERBEnsureNode
2906
+ */
2907
+ function isERBEnsureNode(node) {
2908
+ return node instanceof ERBEnsureNode || node.type === "AST_ERB_ENSURE_NODE";
2909
+ }
2910
+ /**
2911
+ * Checks if a node is a ERBBeginNode
2912
+ */
2913
+ function isERBBeginNode(node) {
2914
+ return node instanceof ERBBeginNode || node.type === "AST_ERB_BEGIN_NODE";
2915
+ }
2916
+ /**
2917
+ * Checks if a node is a ERBUnlessNode
2918
+ */
2919
+ function isERBUnlessNode(node) {
2920
+ return node instanceof ERBUnlessNode || node.type === "AST_ERB_UNLESS_NODE";
2921
+ }
2922
+ /**
2923
+ * Checks if a node is a ERBYieldNode
2924
+ */
2925
+ function isERBYieldNode(node) {
2926
+ return node instanceof ERBYieldNode || node.type === "AST_ERB_YIELD_NODE";
2927
+ }
2928
+ /**
2929
+ * Checks if a node is a ERBInNode
2930
+ */
2931
+ function isERBInNode(node) {
2932
+ return node instanceof ERBInNode || node.type === "AST_ERB_IN_NODE";
2933
+ }
2934
+ /**
2935
+ * Convenience type guards for common node categories
2936
+ */
2937
+ /**
2938
+ * Checks if a node is any HTML node type
2939
+ */
2940
+ function isHTMLNode(node) {
2941
+ return isHTMLOpenTagNode(node) ||
2942
+ isHTMLCloseTagNode(node) ||
2943
+ isHTMLElementNode(node) ||
2944
+ isHTMLAttributeValueNode(node) ||
2945
+ isHTMLAttributeNameNode(node) ||
2946
+ isHTMLAttributeNode(node) ||
2947
+ isHTMLTextNode(node) ||
2948
+ isHTMLCommentNode(node) ||
2949
+ isHTMLDoctypeNode(node);
2950
+ }
2951
+ /**
2952
+ * Checks if a node is any ERB node type
2953
+ */
2954
+ function isERBNode(node) {
2955
+ return isERBContentNode(node) ||
2956
+ isERBEndNode(node) ||
2957
+ isERBElseNode(node) ||
2958
+ isERBIfNode(node) ||
2959
+ isERBBlockNode(node) ||
2960
+ isERBWhenNode(node) ||
2961
+ isERBCaseNode(node) ||
2962
+ isERBCaseMatchNode(node) ||
2963
+ isERBWhileNode(node) ||
2964
+ isERBUntilNode(node) ||
2965
+ isERBForNode(node) ||
2966
+ isERBRescueNode(node) ||
2967
+ isERBEnsureNode(node) ||
2968
+ isERBBeginNode(node) ||
2969
+ isERBUnlessNode(node) ||
2970
+ isERBYieldNode(node) ||
2971
+ isERBInNode(node);
2972
+ }
2973
+ /**
2974
+ * Map of node classes to their corresponding type guard functions
2975
+ *
2976
+ * @example
2977
+ * const guard = NODE_TYPE_GUARDS[HTMLTextNode]
2978
+ *
2979
+ * if (guard(node)) {
2980
+ * // node is HTMLTextNode
2981
+ * }
2982
+ */
2983
+ const NODE_TYPE_GUARDS = new Map([
2984
+ [DocumentNode, isDocumentNode],
2985
+ [LiteralNode, isLiteralNode],
2986
+ [HTMLOpenTagNode, isHTMLOpenTagNode],
2987
+ [HTMLCloseTagNode, isHTMLCloseTagNode],
2988
+ [HTMLElementNode, isHTMLElementNode],
2989
+ [HTMLAttributeValueNode, isHTMLAttributeValueNode],
2990
+ [HTMLAttributeNameNode, isHTMLAttributeNameNode],
2991
+ [HTMLAttributeNode, isHTMLAttributeNode],
2992
+ [HTMLTextNode, isHTMLTextNode],
2993
+ [HTMLCommentNode, isHTMLCommentNode],
2994
+ [HTMLDoctypeNode, isHTMLDoctypeNode],
2995
+ [XMLDeclarationNode, isXMLDeclarationNode],
2996
+ [CDATANode, isCDATANode],
2997
+ [WhitespaceNode, isWhitespaceNode],
2998
+ [ERBContentNode, isERBContentNode],
2999
+ [ERBEndNode, isERBEndNode],
3000
+ [ERBElseNode, isERBElseNode],
3001
+ [ERBIfNode, isERBIfNode],
3002
+ [ERBBlockNode, isERBBlockNode],
3003
+ [ERBWhenNode, isERBWhenNode],
3004
+ [ERBCaseNode, isERBCaseNode],
3005
+ [ERBCaseMatchNode, isERBCaseMatchNode],
3006
+ [ERBWhileNode, isERBWhileNode],
3007
+ [ERBUntilNode, isERBUntilNode],
3008
+ [ERBForNode, isERBForNode],
3009
+ [ERBRescueNode, isERBRescueNode],
3010
+ [ERBEnsureNode, isERBEnsureNode],
3011
+ [ERBBeginNode, isERBBeginNode],
3012
+ [ERBUnlessNode, isERBUnlessNode],
3013
+ [ERBYieldNode, isERBYieldNode],
3014
+ [ERBInNode, isERBInNode],
3015
+ ]);
3016
+ /**
3017
+ * Map of AST node type strings to their corresponding type guard functions
3018
+ *
3019
+ * @example
3020
+ * const guard = AST_TYPE_GUARDS["AST_HTML_TEXT_NODE"]
3021
+ *
3022
+ * if (guard(node)) {
3023
+ * // node is HTMLTextNode
3024
+ * }
3025
+ */
3026
+ const AST_TYPE_GUARDS = new Map([
3027
+ ["AST_DOCUMENT_NODE", isDocumentNode],
3028
+ ["AST_LITERAL_NODE", isLiteralNode],
3029
+ ["AST_HTML_OPEN_TAG_NODE", isHTMLOpenTagNode],
3030
+ ["AST_HTML_CLOSE_TAG_NODE", isHTMLCloseTagNode],
3031
+ ["AST_HTML_ELEMENT_NODE", isHTMLElementNode],
3032
+ ["AST_HTML_ATTRIBUTE_VALUE_NODE", isHTMLAttributeValueNode],
3033
+ ["AST_HTML_ATTRIBUTE_NAME_NODE", isHTMLAttributeNameNode],
3034
+ ["AST_HTML_ATTRIBUTE_NODE", isHTMLAttributeNode],
3035
+ ["AST_HTML_TEXT_NODE", isHTMLTextNode],
3036
+ ["AST_HTML_COMMENT_NODE", isHTMLCommentNode],
3037
+ ["AST_HTML_DOCTYPE_NODE", isHTMLDoctypeNode],
3038
+ ["AST_XML_DECLARATION_NODE", isXMLDeclarationNode],
3039
+ ["AST_CDATA_NODE", isCDATANode],
3040
+ ["AST_WHITESPACE_NODE", isWhitespaceNode],
3041
+ ["AST_ERB_CONTENT_NODE", isERBContentNode],
3042
+ ["AST_ERB_END_NODE", isERBEndNode],
3043
+ ["AST_ERB_ELSE_NODE", isERBElseNode],
3044
+ ["AST_ERB_IF_NODE", isERBIfNode],
3045
+ ["AST_ERB_BLOCK_NODE", isERBBlockNode],
3046
+ ["AST_ERB_WHEN_NODE", isERBWhenNode],
3047
+ ["AST_ERB_CASE_NODE", isERBCaseNode],
3048
+ ["AST_ERB_CASE_MATCH_NODE", isERBCaseMatchNode],
3049
+ ["AST_ERB_WHILE_NODE", isERBWhileNode],
3050
+ ["AST_ERB_UNTIL_NODE", isERBUntilNode],
3051
+ ["AST_ERB_FOR_NODE", isERBForNode],
3052
+ ["AST_ERB_RESCUE_NODE", isERBRescueNode],
3053
+ ["AST_ERB_ENSURE_NODE", isERBEnsureNode],
3054
+ ["AST_ERB_BEGIN_NODE", isERBBeginNode],
3055
+ ["AST_ERB_UNLESS_NODE", isERBUnlessNode],
3056
+ ["AST_ERB_YIELD_NODE", isERBYieldNode],
3057
+ ["AST_ERB_IN_NODE", isERBInNode],
3058
+ ]);
3059
+ /**
3060
+ * Checks if a node matches any of the provided type identifiers with proper type narrowing
3061
+ * Supports AST type strings, node classes, or type guard functions
3062
+ *
3063
+ * @example
3064
+ * if (isAnyOf(node, "AST_HTML_TEXT_NODE", "AST_LITERAL_NODE")) {
3065
+ * // node is narrowed to HTMLTextNode | LiteralNode
3066
+ * }
3067
+ *
3068
+ * @example
3069
+ * if (isAnyOf(node, HTMLTextNode, LiteralNode)) {
3070
+ * // node is narrowed to HTMLTextNode | LiteralNode
3071
+ * }
3072
+ */
3073
+ function isAnyOf(node, ...types) {
3074
+ return types.some(type => {
3075
+ if (typeof type === 'string') {
3076
+ return isNode(node, type);
3077
+ }
3078
+ else if (typeof type === 'function' && type.prototype && type.prototype.constructor === type && NODE_TYPE_GUARDS.has(type)) {
3079
+ return isNode(node, type);
3080
+ }
3081
+ else if (typeof type === 'function') {
3082
+ return type(node);
3083
+ }
3084
+ else {
3085
+ return false;
3086
+ }
3087
+ });
3088
+ }
3089
+ /**
3090
+ * Checks if a node does NOT match any of the provided type identifiers
3091
+ * Supports AST type strings, node classes, or type guard functions
3092
+ * This is the logical inverse of isAnyOf
3093
+ *
3094
+ * @example
3095
+ * if (isNoneOf(node, "AST_HTML_TEXT_NODE", "AST_LITERAL_NODE")) {
3096
+ * // node is neither HTMLTextNode nor LiteralNode
3097
+ * }
3098
+ *
3099
+ * @example
3100
+ * if (isNoneOf(node, HTMLTextNode, LiteralNode)) {
3101
+ * // node is neither HTMLTextNode nor LiteralNode
3102
+ * }
3103
+ *
3104
+ * @example
3105
+ * if (isNoneOf(node, isHTMLTextNode, isLiteralNode)) {
3106
+ * // node is neither HTMLTextNode nor LiteralNode
3107
+ * }
3108
+ */
3109
+ function isNoneOf(node, ...types) {
3110
+ return !isAnyOf(node, ...types);
3111
+ }
3112
+ function areAllOfType(nodes, ...types) {
3113
+ return nodes.every(node => isAnyOf(node, ...types));
3114
+ }
3115
+ function filterNodes(nodes, ...types) {
3116
+ if (!nodes)
3117
+ return [];
3118
+ return nodes.filter(node => isAnyOf(node, ...types));
3119
+ }
3120
+ function isNode(node, type) {
3121
+ if (typeof type === 'string') {
3122
+ const guard = AST_TYPE_GUARDS.get(type);
3123
+ return guard ? guard(node) : false;
3124
+ }
3125
+ else if (typeof type === 'function') {
3126
+ const guard = NODE_TYPE_GUARDS.get(type);
3127
+ return guard ? guard(node) : false;
3128
+ }
3129
+ else {
3130
+ return false;
3131
+ }
3132
+ }
3133
+ function isToken(object) {
3134
+ return (object instanceof Token) || (object?.constructor?.name === "Token" && "value" in object) || object.type?.startsWith('TOKEN_');
3135
+ }
3136
+ function isParseResult(object) {
3137
+ return (object instanceof ParseResult) || (object?.constructor?.name === "ParseResult" && "value" in object);
3138
+ }
3139
+ /**
3140
+ * Checks if a node has children (contains other nodes)
3141
+ */
3142
+ function hasChildren(node) {
3143
+ return isDocumentNode(node) ||
3144
+ isHTMLOpenTagNode(node) ||
3145
+ isHTMLCloseTagNode(node) ||
3146
+ isHTMLElementNode(node) ||
3147
+ isHTMLAttributeValueNode(node) ||
3148
+ isHTMLAttributeNameNode(node) ||
3149
+ isHTMLCommentNode(node) ||
3150
+ isHTMLDoctypeNode(node) ||
3151
+ isERBElseNode(node) ||
3152
+ isERBIfNode(node) ||
3153
+ isERBBlockNode(node) ||
3154
+ isERBWhenNode(node) ||
3155
+ isERBCaseNode(node) ||
3156
+ isERBCaseMatchNode(node) ||
3157
+ isERBWhileNode(node) ||
3158
+ isERBUntilNode(node) ||
3159
+ isERBForNode(node) ||
3160
+ isERBRescueNode(node) ||
3161
+ isERBEnsureNode(node) ||
3162
+ isERBBeginNode(node) ||
3163
+ isERBUnlessNode(node) ||
3164
+ isERBInNode(node);
3165
+ }
3166
+ /**
3167
+ * Filter functions for extracting specific node types from arrays
3168
+ */
3169
+ /**
3170
+ * Filters an array of nodes to only include DocumentNode nodes
3171
+ */
3172
+ function filterDocumentNodes(nodes) {
3173
+ return nodes.filter(isDocumentNode);
3174
+ }
3175
+ /**
3176
+ * Filters an array of nodes to only include LiteralNode nodes
3177
+ */
3178
+ function filterLiteralNodes(nodes) {
3179
+ return nodes.filter(isLiteralNode);
3180
+ }
3181
+ /**
3182
+ * Filters an array of nodes to only include HTMLOpenTagNode nodes
3183
+ */
3184
+ function filterHTMLOpenTagNodes(nodes) {
3185
+ return nodes.filter(isHTMLOpenTagNode);
3186
+ }
3187
+ /**
3188
+ * Filters an array of nodes to only include HTMLCloseTagNode nodes
3189
+ */
3190
+ function filterHTMLCloseTagNodes(nodes) {
3191
+ return nodes.filter(isHTMLCloseTagNode);
3192
+ }
3193
+ /**
3194
+ * Filters an array of nodes to only include HTMLElementNode nodes
3195
+ */
3196
+ function filterHTMLElementNodes(nodes) {
3197
+ return nodes.filter(isHTMLElementNode);
3198
+ }
3199
+ /**
3200
+ * Filters an array of nodes to only include HTMLAttributeValueNode nodes
3201
+ */
3202
+ function filterHTMLAttributeValueNodes(nodes) {
3203
+ return nodes.filter(isHTMLAttributeValueNode);
3204
+ }
3205
+ /**
3206
+ * Filters an array of nodes to only include HTMLAttributeNameNode nodes
3207
+ */
3208
+ function filterHTMLAttributeNameNodes(nodes) {
3209
+ return nodes.filter(isHTMLAttributeNameNode);
3210
+ }
3211
+ /**
3212
+ * Filters an array of nodes to only include HTMLAttributeNode nodes
3213
+ */
3214
+ function filterHTMLAttributeNodes(nodes) {
3215
+ return nodes.filter(isHTMLAttributeNode);
3216
+ }
3217
+ /**
3218
+ * Filters an array of nodes to only include HTMLTextNode nodes
3219
+ */
3220
+ function filterHTMLTextNodes(nodes) {
3221
+ return nodes.filter(isHTMLTextNode);
3222
+ }
3223
+ /**
3224
+ * Filters an array of nodes to only include HTMLCommentNode nodes
3225
+ */
3226
+ function filterHTMLCommentNodes(nodes) {
3227
+ return nodes.filter(isHTMLCommentNode);
3228
+ }
3229
+ /**
3230
+ * Filters an array of nodes to only include HTMLDoctypeNode nodes
3231
+ */
3232
+ function filterHTMLDoctypeNodes(nodes) {
3233
+ return nodes.filter(isHTMLDoctypeNode);
3234
+ }
3235
+ /**
3236
+ * Filters an array of nodes to only include XMLDeclarationNode nodes
3237
+ */
3238
+ function filterXMLDeclarationNodes(nodes) {
3239
+ return nodes.filter(isXMLDeclarationNode);
3240
+ }
3241
+ /**
3242
+ * Filters an array of nodes to only include CDATANode nodes
3243
+ */
3244
+ function filterCDATANodes(nodes) {
3245
+ return nodes.filter(isCDATANode);
3246
+ }
3247
+ /**
3248
+ * Filters an array of nodes to only include WhitespaceNode nodes
3249
+ */
3250
+ function filterWhitespaceNodes(nodes) {
3251
+ return nodes.filter(isWhitespaceNode);
3252
+ }
3253
+ /**
3254
+ * Filters an array of nodes to only include ERBContentNode nodes
3255
+ */
3256
+ function filterERBContentNodes(nodes) {
3257
+ return nodes.filter(isERBContentNode);
3258
+ }
3259
+ /**
3260
+ * Filters an array of nodes to only include ERBEndNode nodes
3261
+ */
3262
+ function filterERBEndNodes(nodes) {
3263
+ return nodes.filter(isERBEndNode);
3264
+ }
3265
+ /**
3266
+ * Filters an array of nodes to only include ERBElseNode nodes
3267
+ */
3268
+ function filterERBElseNodes(nodes) {
3269
+ return nodes.filter(isERBElseNode);
3270
+ }
3271
+ /**
3272
+ * Filters an array of nodes to only include ERBIfNode nodes
3273
+ */
3274
+ function filterERBIfNodes(nodes) {
3275
+ return nodes.filter(isERBIfNode);
3276
+ }
3277
+ /**
3278
+ * Filters an array of nodes to only include ERBBlockNode nodes
3279
+ */
3280
+ function filterERBBlockNodes(nodes) {
3281
+ return nodes.filter(isERBBlockNode);
3282
+ }
3283
+ /**
3284
+ * Filters an array of nodes to only include ERBWhenNode nodes
3285
+ */
3286
+ function filterERBWhenNodes(nodes) {
3287
+ return nodes.filter(isERBWhenNode);
3288
+ }
3289
+ /**
3290
+ * Filters an array of nodes to only include ERBCaseNode nodes
3291
+ */
3292
+ function filterERBCaseNodes(nodes) {
3293
+ return nodes.filter(isERBCaseNode);
3294
+ }
3295
+ /**
3296
+ * Filters an array of nodes to only include ERBCaseMatchNode nodes
3297
+ */
3298
+ function filterERBCaseMatchNodes(nodes) {
3299
+ return nodes.filter(isERBCaseMatchNode);
3300
+ }
3301
+ /**
3302
+ * Filters an array of nodes to only include ERBWhileNode nodes
3303
+ */
3304
+ function filterERBWhileNodes(nodes) {
3305
+ return nodes.filter(isERBWhileNode);
3306
+ }
3307
+ /**
3308
+ * Filters an array of nodes to only include ERBUntilNode nodes
3309
+ */
3310
+ function filterERBUntilNodes(nodes) {
3311
+ return nodes.filter(isERBUntilNode);
3312
+ }
3313
+ /**
3314
+ * Filters an array of nodes to only include ERBForNode nodes
3315
+ */
3316
+ function filterERBForNodes(nodes) {
3317
+ return nodes.filter(isERBForNode);
3318
+ }
3319
+ /**
3320
+ * Filters an array of nodes to only include ERBRescueNode nodes
3321
+ */
3322
+ function filterERBRescueNodes(nodes) {
3323
+ return nodes.filter(isERBRescueNode);
3324
+ }
3325
+ /**
3326
+ * Filters an array of nodes to only include ERBEnsureNode nodes
3327
+ */
3328
+ function filterERBEnsureNodes(nodes) {
3329
+ return nodes.filter(isERBEnsureNode);
3330
+ }
3331
+ /**
3332
+ * Filters an array of nodes to only include ERBBeginNode nodes
3333
+ */
3334
+ function filterERBBeginNodes(nodes) {
3335
+ return nodes.filter(isERBBeginNode);
3336
+ }
3337
+ /**
3338
+ * Filters an array of nodes to only include ERBUnlessNode nodes
3339
+ */
3340
+ function filterERBUnlessNodes(nodes) {
3341
+ return nodes.filter(isERBUnlessNode);
3342
+ }
3343
+ /**
3344
+ * Filters an array of nodes to only include ERBYieldNode nodes
3345
+ */
3346
+ function filterERBYieldNodes(nodes) {
3347
+ return nodes.filter(isERBYieldNode);
3348
+ }
3349
+ /**
3350
+ * Filters an array of nodes to only include ERBInNode nodes
3351
+ */
3352
+ function filterERBInNodes(nodes) {
3353
+ return nodes.filter(isERBInNode);
3354
+ }
3355
+
3356
+ /**
3357
+ * Checks if a node is an ERB output node (generates content: <%= %> or <%== %>)
3358
+ */
3359
+ function isERBOutputNode(node) {
3360
+ return isNode(node, ERBContentNode) && ["<%=", "<%=="].includes(node.tag_opening?.value);
3361
+ }
3362
+ /**
3363
+ * Checks if a node is a non-output ERB node (control flow: <% %>)
3364
+ */
3365
+ function isERBControlFlowNode(node) {
3366
+ return isAnyOf(node, ERBIfNode, ERBUnlessNode, ERBBlockNode, ERBCaseNode, ERBCaseMatchNode, ERBWhileNode, ERBForNode, ERBBeginNode);
3367
+ }
3368
+ /**
3369
+ * Checks if an array of nodes contains any ERB content nodes
3370
+ */
3371
+ function hasERBContent(nodes) {
3372
+ return nodes.some(isERBContentNode);
3373
+ }
3374
+ /**
3375
+ * Checks if an array of nodes contains any ERB output nodes (dynamic content)
3376
+ */
3377
+ function hasERBOutput(nodes) {
3378
+ return nodes.some(isERBOutputNode);
3379
+ }
3380
+ /**
3381
+ * Extracts a static string from an array of literal nodes
3382
+ * Returns null if any node is not a literal node
3383
+ */
3384
+ function getStaticStringFromNodes(nodes) {
3385
+ if (!areAllOfType(nodes, LiteralNode)) {
3386
+ return null;
3387
+ }
3388
+ return nodes.map(node => node.content).join("");
3389
+ }
3390
+ /**
3391
+ * Extracts static content from nodes, including mixed literal/ERB content
3392
+ * Returns the concatenated literal content, or null if no literal nodes exist
3393
+ */
3394
+ function getStaticContentFromNodes(nodes) {
3395
+ const literalNodes = filterLiteralNodes(nodes);
3396
+ if (literalNodes.length === 0) {
3397
+ return null;
3398
+ }
3399
+ return literalNodes.map(node => node.content).join("");
3400
+ }
3401
+ /**
3402
+ * Checks if nodes contain any literal content (for static validation)
3403
+ */
3404
+ function hasStaticContent(nodes) {
3405
+ return nodes.some(isLiteralNode);
3406
+ }
3407
+ /**
3408
+ * Checks if nodes are effectively static (only literals and non-output ERB)
3409
+ * Non-output ERB like <% if %> doesn't affect static validation
3410
+ */
3411
+ function isEffectivelyStatic(nodes) {
3412
+ return !hasERBOutput(nodes);
3413
+ }
3414
+ /**
3415
+ * Gets static-validatable content from nodes (ignores control ERB, includes literals)
3416
+ * Returns concatenated literal content for validation, or null if contains output ERB
3417
+ */
3418
+ function getValidatableStaticContent(nodes) {
3419
+ if (hasERBOutput(nodes)) {
3420
+ return null;
3421
+ }
3422
+ return filterLiteralNodes(nodes).map(node => node.content).join("");
3423
+ }
3424
+ /**
3425
+ * Extracts a combined string from nodes, including ERB content
3426
+ * For ERB nodes, includes the full tag syntax (e.g., "<%= foo %>")
3427
+ * This is useful for debugging or displaying the full attribute name
3428
+ */
3429
+ function getCombinedStringFromNodes(nodes) {
3430
+ return nodes.map(node => {
3431
+ if (isLiteralNode(node)) {
3432
+ return node.content;
3433
+ }
3434
+ else if (isERBContentNode(node)) {
3435
+ const opening = node.tag_opening?.value || "";
3436
+ const content = node.content?.value || "";
3437
+ const closing = node.tag_closing?.value || "";
3438
+ return `${opening}${content}${closing}`;
3439
+ }
3440
+ else {
3441
+ // For other node types, return a placeholder or empty string
3442
+ return `[${node.type}]`;
3443
+ }
3444
+ }).join("");
3445
+ }
3446
+ /**
3447
+ * Checks if an HTML attribute name node has a static (literal-only) name
3448
+ */
3449
+ function hasStaticAttributeName(attributeNameNode) {
3450
+ if (!attributeNameNode.children) {
3451
+ return false;
3452
+ }
3453
+ return areAllOfType(attributeNameNode.children, LiteralNode);
3454
+ }
3455
+ /**
3456
+ * Checks if an HTML attribute name node has dynamic content (contains ERB)
3457
+ */
3458
+ function hasDynamicAttributeName(attributeNameNode) {
3459
+ if (!attributeNameNode.children) {
3460
+ return false;
3461
+ }
3462
+ return hasERBContent(attributeNameNode.children);
3463
+ }
3464
+ /**
3465
+ * Gets the static string value of an HTML attribute name node
3466
+ * Returns null if the attribute name contains dynamic content (ERB)
3467
+ */
3468
+ function getStaticAttributeName(attributeNameNode) {
3469
+ if (!attributeNameNode.children) {
3470
+ return null;
3471
+ }
3472
+ return getStaticStringFromNodes(attributeNameNode.children);
3473
+ }
3474
+ /**
3475
+ * Gets the combined string representation of an HTML attribute name node
3476
+ * This includes both static and dynamic content, useful for debugging
3477
+ */
3478
+ function getCombinedAttributeName(attributeNameNode) {
3479
+ if (!attributeNameNode.children) {
3480
+ return "";
3481
+ }
3482
+ return getCombinedStringFromNodes(attributeNameNode.children);
3483
+ }
3484
+ /**
3485
+ * Gets the tag name of an HTML element node
3486
+ */
3487
+ function getTagName(node) {
3488
+ return node.tag_name?.value ?? "";
3489
+ }
3490
+ /**
3491
+ * Check if a node is a comment (HTML comment or ERB comment)
3492
+ */
3493
+ function isCommentNode(node) {
3494
+ return isNode(node, HTMLCommentNode) || (isERBNode(node) && !isERBControlFlowNode(node));
3495
+ }
3496
+
3497
+ const expectedFunctions = [
3498
+ "parse",
3499
+ "lex",
3500
+ "parseFile",
3501
+ "lexFile",
3502
+ "extractRuby",
3503
+ "extractHTML",
3504
+ "version",
3505
+ ];
3506
+ // NOTE: This function should never be called and is only for type checking
3507
+ // so we can make sure `expectedFunctions` matches the functions defined
3508
+ // in `LibHerbBackendFunctions` and the other way around.
3509
+ //
3510
+ function _TYPECHECK() {
3511
+ const checkFunctionsExist = true;
3512
+ const checkInterfaceComplete = true;
3513
+ return { checkFunctionsExist, checkInterfaceComplete };
3514
+ }
3515
+ function isLibHerbBackend(object, libherbpath = "unknown") {
3516
+ for (const expectedFunction of expectedFunctions) {
3517
+ if (object[expectedFunction] === undefined) {
3518
+ throw new Error(`Libherb at "${libherbpath}" doesn't expose function "${expectedFunction}".`);
3519
+ }
3520
+ if (typeof object[expectedFunction] !== "function") {
3521
+ throw new Error(`Libherb at "${libherbpath}" has "${expectedFunction}" but it's not a function.`);
3522
+ }
3523
+ }
3524
+ return true;
3525
+ }
3526
+ function ensureLibHerbBackend(object, libherbpath = "unknown") {
3527
+ isLibHerbBackend(object, libherbpath);
3528
+ return object;
3529
+ }
3530
+
3531
+ /**
3532
+ * Converts a Diagnostic to Monaco/VSCode-compatible MonacoDiagnostic format
3533
+ */
3534
+ function toMonacoDiagnostic(diagnostic) {
3535
+ const { message, location } = diagnostic;
3536
+ const severity = diagnostic.severity === "hint" ? "info" : diagnostic.severity;
3537
+ return {
3538
+ line: location.start.line,
3539
+ column: location.start.column,
3540
+ endLine: location.end.line,
3541
+ endColumn: location.end.column,
3542
+ message,
3543
+ severity
3544
+ };
3545
+ }
3546
+
3547
+ var name = "@herb-tools/core";
3548
+ var version = "0.6.0";
3549
+ var packageJSON = {
3550
+ name: name,
3551
+ version: version};
3552
+
3553
+ class TokenList {
3554
+ list;
3555
+ static from(list) {
3556
+ return new TokenList(list.map((token) => Token.from(token)));
3557
+ }
3558
+ constructor(list) {
3559
+ this.list = list;
3560
+ }
3561
+ get length() {
3562
+ return this.list.length;
3563
+ }
3564
+ get tokens() {
3565
+ return this.list;
3566
+ }
3567
+ [Symbol.iterator]() {
3568
+ return this.list[Symbol.iterator]();
3569
+ }
3570
+ at(index) {
3571
+ return this.list.at(index);
3572
+ }
3573
+ forEach(callback) {
3574
+ this.list.forEach(callback);
3575
+ }
3576
+ map(callback) {
3577
+ return this.list.map(callback);
3578
+ }
3579
+ filter(predicate) {
3580
+ return this.list.filter(predicate);
3581
+ }
3582
+ __getobj__() {
3583
+ return this.list;
3584
+ }
3585
+ inspect() {
3586
+ return this.list.map((token) => token.inspect()).join("\n") + "\n";
3587
+ }
3588
+ toString() {
3589
+ return this.inspect();
3590
+ }
3591
+ }
3592
+
3593
+ /**
3594
+ * Represents the result of a lexical analysis, extending the base `Result` class.
3595
+ * It contains the token list, source code, warnings, and errors.
3596
+ */
3597
+ class LexResult extends Result {
3598
+ /** The list of tokens generated from the source code. */
3599
+ value;
3600
+ /**
3601
+ * Creates a `LexResult` instance from a serialized result.
3602
+ * @param result - The serialized lexical result containing tokens, source, warnings, and errors.
3603
+ * @returns A new `LexResult` instance.
3604
+ */
3605
+ static from(result) {
3606
+ return new LexResult(TokenList.from(result.tokens || []), result.source, result.warnings.map((warning) => HerbWarning.from(warning)), result.errors.map((error) => HerbError.from(error)));
3607
+ }
3608
+ /**
3609
+ * Constructs a new `LexResult`.
3610
+ * @param value - The list of tokens.
3611
+ * @param source - The source code that was lexed.
3612
+ * @param warnings - An array of warnings encountered during lexing.
3613
+ * @param errors - An array of errors encountered during lexing.
3614
+ */
3615
+ constructor(value, source, warnings = [], errors = []) {
3616
+ super(source, warnings, errors);
3617
+ this.value = value;
3618
+ }
3619
+ /**
3620
+ * Determines if the lexing was successful.
3621
+ * @returns `true` if there are no errors, otherwise `false`.
3622
+ */
3623
+ get successful() {
3624
+ return this.errors.length === 0;
3625
+ }
3626
+ /**
3627
+ * Determines if the lexing failed.
3628
+ * @returns `true` if there are errors, otherwise `false`.
3629
+ */
3630
+ get failed() {
3631
+ return this.errors.length > 0;
3632
+ }
3633
+ /**
3634
+ * Converts the `LexResult` to a JSON representation.
3635
+ * @returns An object containing the token list, source, warnings, and errors.
3636
+ */
3637
+ toJSON() {
3638
+ return {
3639
+ value: this.value,
3640
+ source: this.source,
3641
+ warnings: this.warnings,
3642
+ errors: this.errors,
3643
+ };
3644
+ }
3645
+ }
3646
+
3647
+ const DEFAULT_PARSER_OPTIONS = {
3648
+ track_whitespace: false,
3649
+ };
3650
+
3651
+ /**
3652
+ * The main Herb parser interface, providing methods to lex and parse input.
3653
+ */
3654
+ class HerbBackend {
3655
+ /** The backend instance handling lexing and parsing. */
3656
+ backend = undefined;
3657
+ backendPromise;
3658
+ /**
3659
+ * Creates a new Herb instance.
3660
+ * @param backendPromise - A promise resolving to a `LibHerbBackend` implementation for lexing and parsing.
3661
+ * @throws Error if no valid backend is provided.
3662
+ */
3663
+ constructor(backendPromise) {
3664
+ if (!backendPromise) {
3665
+ throw new Error("No LibHerb backend provided");
3666
+ }
3667
+ this.backendPromise = backendPromise;
3668
+ }
3669
+ /**
3670
+ * Loads the backend by resolving the backend promise.
3671
+ * @returns A promise containing the resolved `HerbBackend` instance after loading it.
3672
+ */
3673
+ async load() {
3674
+ const backend = await this.backendPromise();
3675
+ this.backend = backend;
3676
+ return this;
3677
+ }
3678
+ /**
3679
+ * Lexes the given source string into a `LexResult`.
3680
+ * @param source - The source code to lex.
3681
+ * @returns A `LexResult` instance.
3682
+ * @throws Error if the backend is not loaded.
3683
+ */
3684
+ lex(source) {
3685
+ this.ensureBackend();
3686
+ return LexResult.from(this.backend.lex(ensureString(source)));
3687
+ }
3688
+ /**
3689
+ * Lexes a file.
3690
+ * @param path - The file path to lex.
3691
+ * @returns A `LexResult` instance.
3692
+ * @throws Error if the backend is not loaded.
3693
+ */
3694
+ lexFile(path) {
3695
+ this.ensureBackend();
3696
+ return LexResult.from(this.backend.lexFile(ensureString(path)));
3697
+ }
3698
+ /**
3699
+ * Parses the given source string into a `ParseResult`.
3700
+ * @param source - The source code to parse.
3701
+ * @param options - Optional parsing options.
3702
+ * @returns A `ParseResult` instance.
3703
+ * @throws Error if the backend is not loaded.
3704
+ */
3705
+ parse(source, options) {
3706
+ this.ensureBackend();
3707
+ const mergedOptions = { ...DEFAULT_PARSER_OPTIONS, ...options };
3708
+ return ParseResult.from(this.backend.parse(ensureString(source), mergedOptions));
3709
+ }
3710
+ /**
3711
+ * Parses a file.
3712
+ * @param path - The file path to parse.
3713
+ * @returns A `ParseResult` instance.
3714
+ * @throws Error if the backend is not loaded.
3715
+ */
3716
+ parseFile(path) {
3717
+ this.ensureBackend();
3718
+ return ParseResult.from(this.backend.parseFile(ensureString(path)));
3719
+ }
3720
+ /**
3721
+ * Extracts embedded Ruby code from the given source.
3722
+ * @param source - The source code to extract Ruby from.
3723
+ * @returns The extracted Ruby code as a string.
3724
+ * @throws Error if the backend is not loaded.
3725
+ */
3726
+ extractRuby(source) {
3727
+ this.ensureBackend();
3728
+ return this.backend.extractRuby(ensureString(source));
3729
+ }
3730
+ /**
3731
+ * Extracts HTML from the given source.
3732
+ * @param source - The source code to extract HTML from.
3733
+ * @returns The extracted HTML as a string.
3734
+ * @throws Error if the backend is not loaded.
3735
+ */
3736
+ extractHTML(source) {
3737
+ this.ensureBackend();
3738
+ return this.backend.extractHTML(ensureString(source));
3739
+ }
3740
+ /**
3741
+ * Gets the Herb version information, including the core and backend versions.
3742
+ * @returns A version string containing backend, core, and libherb versions.
3743
+ * @throws Error if the backend is not loaded.
3744
+ */
3745
+ get version() {
3746
+ this.ensureBackend();
3747
+ const backend = this.backendVersion();
3748
+ const core = `${packageJSON.name}@${packageJSON.version}`;
3749
+ const libherb = this.backend.version();
3750
+ return `${backend}, ${core}, ${libherb}`;
3751
+ }
3752
+ /**
3753
+ * Ensures that the backend is loaded.
3754
+ * @throws Error if the backend is not loaded.
3755
+ */
3756
+ ensureBackend() {
3757
+ if (!this.isLoaded) {
3758
+ throw new Error("Herb backend is not loaded. Call `await Herb.load()` first.");
3759
+ }
3760
+ }
3761
+ /**
3762
+ * Checks if the backend is loaded.
3763
+ * @returns True if the backend is loaded, false otherwise.
3764
+ */
3765
+ get isLoaded() {
2978
3766
  return this.backend !== undefined;
2979
3767
  }
2980
3768
  }
2981
3769
 
2982
3770
  // NOTE: This file is generated by the templates/template.rb script and should not
2983
- // be modified manually. See /Users/marcoroth/Development/herb-release-0.5.0/templates/javascript/packages/core/src/visitor.ts.erb
3771
+ // be modified manually. See /Users/marcoroth/Development/herb-release-0.6.0/templates/javascript/packages/core/src/visitor.ts.erb
2984
3772
  class Visitor {
2985
3773
  visit(node) {
2986
3774
  if (!node)
@@ -3005,9 +3793,6 @@
3005
3793
  visitHTMLCloseTagNode(node) {
3006
3794
  this.visitChildNodes(node);
3007
3795
  }
3008
- visitHTMLSelfCloseTagNode(node) {
3009
- this.visitChildNodes(node);
3010
- }
3011
3796
  visitHTMLElementNode(node) {
3012
3797
  this.visitChildNodes(node);
3013
3798
  }
@@ -3029,6 +3814,12 @@
3029
3814
  visitHTMLDoctypeNode(node) {
3030
3815
  this.visitChildNodes(node);
3031
3816
  }
3817
+ visitXMLDeclarationNode(node) {
3818
+ this.visitChildNodes(node);
3819
+ }
3820
+ visitCDATANode(node) {
3821
+ this.visitChildNodes(node);
3822
+ }
3032
3823
  visitWhitespaceNode(node) {
3033
3824
  this.visitChildNodes(node);
3034
3825
  }
@@ -3085,6 +3876,9 @@
3085
3876
  }
3086
3877
  }
3087
3878
 
3879
+ exports.AST_TYPE_GUARDS = AST_TYPE_GUARDS;
3880
+ exports.CDATANode = CDATANode;
3881
+ exports.DEFAULT_PARSER_OPTIONS = DEFAULT_PARSER_OPTIONS;
3088
3882
  exports.DocumentNode = DocumentNode;
3089
3883
  exports.ERBBeginNode = ERBBeginNode;
3090
3884
  exports.ERBBlockNode = ERBBlockNode;
@@ -3112,7 +3906,6 @@
3112
3906
  exports.HTMLDoctypeNode = HTMLDoctypeNode;
3113
3907
  exports.HTMLElementNode = HTMLElementNode;
3114
3908
  exports.HTMLOpenTagNode = HTMLOpenTagNode;
3115
- exports.HTMLSelfCloseTagNode = HTMLSelfCloseTagNode;
3116
3909
  exports.HTMLTextNode = HTMLTextNode;
3117
3910
  exports.HerbBackend = HerbBackend;
3118
3911
  exports.HerbError = HerbError;
@@ -3122,6 +3915,7 @@
3122
3915
  exports.Location = Location;
3123
3916
  exports.MissingClosingTagError = MissingClosingTagError;
3124
3917
  exports.MissingOpeningTagError = MissingOpeningTagError;
3918
+ exports.NODE_TYPE_GUARDS = NODE_TYPE_GUARDS;
3125
3919
  exports.Node = Node;
3126
3920
  exports.ParseResult = ParseResult;
3127
3921
  exports.Position = Position;
@@ -3138,14 +3932,102 @@
3138
3932
  exports.Visitor = Visitor;
3139
3933
  exports.VoidElementClosingTagError = VoidElementClosingTagError;
3140
3934
  exports.WhitespaceNode = WhitespaceNode;
3935
+ exports.XMLDeclarationNode = XMLDeclarationNode;
3141
3936
  exports._TYPECHECK = _TYPECHECK;
3937
+ exports.areAllOfType = areAllOfType;
3142
3938
  exports.convertToUTF8 = convertToUTF8;
3143
3939
  exports.ensureLibHerbBackend = ensureLibHerbBackend;
3144
3940
  exports.ensureString = ensureString;
3941
+ exports.filterCDATANodes = filterCDATANodes;
3942
+ exports.filterDocumentNodes = filterDocumentNodes;
3943
+ exports.filterERBBeginNodes = filterERBBeginNodes;
3944
+ exports.filterERBBlockNodes = filterERBBlockNodes;
3945
+ exports.filterERBCaseMatchNodes = filterERBCaseMatchNodes;
3946
+ exports.filterERBCaseNodes = filterERBCaseNodes;
3947
+ exports.filterERBContentNodes = filterERBContentNodes;
3948
+ exports.filterERBElseNodes = filterERBElseNodes;
3949
+ exports.filterERBEndNodes = filterERBEndNodes;
3950
+ exports.filterERBEnsureNodes = filterERBEnsureNodes;
3951
+ exports.filterERBForNodes = filterERBForNodes;
3952
+ exports.filterERBIfNodes = filterERBIfNodes;
3953
+ exports.filterERBInNodes = filterERBInNodes;
3954
+ exports.filterERBRescueNodes = filterERBRescueNodes;
3955
+ exports.filterERBUnlessNodes = filterERBUnlessNodes;
3956
+ exports.filterERBUntilNodes = filterERBUntilNodes;
3957
+ exports.filterERBWhenNodes = filterERBWhenNodes;
3958
+ exports.filterERBWhileNodes = filterERBWhileNodes;
3959
+ exports.filterERBYieldNodes = filterERBYieldNodes;
3960
+ exports.filterHTMLAttributeNameNodes = filterHTMLAttributeNameNodes;
3961
+ exports.filterHTMLAttributeNodes = filterHTMLAttributeNodes;
3962
+ exports.filterHTMLAttributeValueNodes = filterHTMLAttributeValueNodes;
3963
+ exports.filterHTMLCloseTagNodes = filterHTMLCloseTagNodes;
3964
+ exports.filterHTMLCommentNodes = filterHTMLCommentNodes;
3965
+ exports.filterHTMLDoctypeNodes = filterHTMLDoctypeNodes;
3966
+ exports.filterHTMLElementNodes = filterHTMLElementNodes;
3967
+ exports.filterHTMLOpenTagNodes = filterHTMLOpenTagNodes;
3968
+ exports.filterHTMLTextNodes = filterHTMLTextNodes;
3969
+ exports.filterLiteralNodes = filterLiteralNodes;
3970
+ exports.filterNodes = filterNodes;
3971
+ exports.filterWhitespaceNodes = filterWhitespaceNodes;
3972
+ exports.filterXMLDeclarationNodes = filterXMLDeclarationNodes;
3145
3973
  exports.fromSerializedError = fromSerializedError;
3146
3974
  exports.fromSerializedNode = fromSerializedNode;
3975
+ exports.getCombinedAttributeName = getCombinedAttributeName;
3976
+ exports.getCombinedStringFromNodes = getCombinedStringFromNodes;
3977
+ exports.getStaticAttributeName = getStaticAttributeName;
3978
+ exports.getStaticContentFromNodes = getStaticContentFromNodes;
3979
+ exports.getStaticStringFromNodes = getStaticStringFromNodes;
3980
+ exports.getTagName = getTagName;
3981
+ exports.getValidatableStaticContent = getValidatableStaticContent;
3982
+ exports.hasChildren = hasChildren;
3983
+ exports.hasDynamicAttributeName = hasDynamicAttributeName;
3984
+ exports.hasERBContent = hasERBContent;
3985
+ exports.hasERBOutput = hasERBOutput;
3986
+ exports.hasStaticAttributeName = hasStaticAttributeName;
3987
+ exports.hasStaticContent = hasStaticContent;
3988
+ exports.isAnyOf = isAnyOf;
3989
+ exports.isCDATANode = isCDATANode;
3990
+ exports.isCommentNode = isCommentNode;
3991
+ exports.isDocumentNode = isDocumentNode;
3992
+ exports.isERBBeginNode = isERBBeginNode;
3993
+ exports.isERBBlockNode = isERBBlockNode;
3994
+ exports.isERBCaseMatchNode = isERBCaseMatchNode;
3995
+ exports.isERBCaseNode = isERBCaseNode;
3996
+ exports.isERBContentNode = isERBContentNode;
3997
+ exports.isERBControlFlowNode = isERBControlFlowNode;
3998
+ exports.isERBElseNode = isERBElseNode;
3999
+ exports.isERBEndNode = isERBEndNode;
4000
+ exports.isERBEnsureNode = isERBEnsureNode;
4001
+ exports.isERBForNode = isERBForNode;
4002
+ exports.isERBIfNode = isERBIfNode;
4003
+ exports.isERBInNode = isERBInNode;
3147
4004
  exports.isERBNode = isERBNode;
4005
+ exports.isERBOutputNode = isERBOutputNode;
4006
+ exports.isERBRescueNode = isERBRescueNode;
4007
+ exports.isERBUnlessNode = isERBUnlessNode;
4008
+ exports.isERBUntilNode = isERBUntilNode;
4009
+ exports.isERBWhenNode = isERBWhenNode;
4010
+ exports.isERBWhileNode = isERBWhileNode;
4011
+ exports.isERBYieldNode = isERBYieldNode;
4012
+ exports.isEffectivelyStatic = isEffectivelyStatic;
4013
+ exports.isHTMLAttributeNameNode = isHTMLAttributeNameNode;
4014
+ exports.isHTMLAttributeNode = isHTMLAttributeNode;
4015
+ exports.isHTMLAttributeValueNode = isHTMLAttributeValueNode;
4016
+ exports.isHTMLCloseTagNode = isHTMLCloseTagNode;
4017
+ exports.isHTMLCommentNode = isHTMLCommentNode;
4018
+ exports.isHTMLDoctypeNode = isHTMLDoctypeNode;
4019
+ exports.isHTMLElementNode = isHTMLElementNode;
4020
+ exports.isHTMLNode = isHTMLNode;
4021
+ exports.isHTMLOpenTagNode = isHTMLOpenTagNode;
4022
+ exports.isHTMLTextNode = isHTMLTextNode;
3148
4023
  exports.isLibHerbBackend = isLibHerbBackend;
4024
+ exports.isLiteralNode = isLiteralNode;
4025
+ exports.isNode = isNode;
4026
+ exports.isNoneOf = isNoneOf;
4027
+ exports.isParseResult = isParseResult;
4028
+ exports.isToken = isToken;
4029
+ exports.isWhitespaceNode = isWhitespaceNode;
4030
+ exports.isXMLDeclarationNode = isXMLDeclarationNode;
3149
4031
  exports.toMonacoDiagnostic = toMonacoDiagnostic;
3150
4032
 
3151
4033
  }));