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