@btc-embedded/cdk-extensions 0.23.3 → 0.23.5

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.
Files changed (135) hide show
  1. package/.jsii +41 -41
  2. package/CHANGELOG.md +14 -0
  3. package/assets/cli/catnip.js +154 -166
  4. package/lib/constructs/EventPipe.js +1 -1
  5. package/lib/constructs/ExportedService.js +1 -1
  6. package/lib/constructs/S3Bucket.js +1 -1
  7. package/lib/constructs/SecureRestApi.js +1 -1
  8. package/lib/constructs/SecureRestApiV2.js +1 -1
  9. package/lib/constructs/api-keys/ApiKeyClientAuthorization.js +1 -1
  10. package/lib/constructs/api-keys/ApiKeyManagement.js +1 -1
  11. package/lib/constructs/api-keys/ApiKeyPreTokenHandler.js +1 -1
  12. package/lib/constructs/api-keys/ApiKeyStore.js +1 -1
  13. package/lib/extensions/ApiGatewayExtension.js +1 -1
  14. package/lib/extensions/ApplicationContainer.js +1 -1
  15. package/lib/extensions/ApplicationLoadBalancerExtension.js +1 -1
  16. package/lib/extensions/ApplicationLoadBalancerExtensionV2.js +1 -1
  17. package/lib/extensions/CloudMapExtension.js +1 -1
  18. package/lib/extensions/DeactivatableServiceExtension.js +1 -1
  19. package/lib/extensions/DeploymentConfigExtension.js +1 -1
  20. package/lib/extensions/DocumentDbAccessExtension.js +1 -1
  21. package/lib/extensions/DomainEventMessagingExtension.js +1 -1
  22. package/lib/extensions/EfsMountExtension.js +1 -1
  23. package/lib/extensions/ExtraContainerExtension.js +1 -1
  24. package/lib/extensions/HTTPApiExtension.js +1 -1
  25. package/lib/extensions/LogExtension.js +1 -1
  26. package/lib/extensions/ModifyContainerDefinitionExtension.js +1 -1
  27. package/lib/extensions/ModifyTaskDefinitionExtension.js +1 -1
  28. package/lib/extensions/OpenIdExtension.js +1 -1
  29. package/lib/extensions/OpenTelemetryExtension.js +1 -1
  30. package/lib/extensions/PostgresDbAccessExtension.js +1 -1
  31. package/lib/extensions/SharedVolumeExtension.js +1 -1
  32. package/lib/extensions/TcpKeepAliveExtension.js +1 -1
  33. package/lib/platform/ApiGateway.js +1 -1
  34. package/lib/platform/ApiGatewayVpcLink.js +2 -2
  35. package/lib/platform/ApplicationLoadBalancer.js +1 -1
  36. package/lib/platform/ApplicationLoadBalancerV2.d.ts +1 -0
  37. package/lib/platform/ApplicationLoadBalancerV2.js +10 -3
  38. package/lib/platform/AuroraPostgresDB.js +5 -4
  39. package/lib/platform/BTCLogGroup.js +1 -1
  40. package/lib/platform/CognitoUserPool.js +2 -2
  41. package/lib/platform/DefaultUserPoolClients.js +1 -1
  42. package/lib/platform/DocumentDB.js +2 -2
  43. package/lib/platform/EcsCluster.js +1 -1
  44. package/lib/platform/EfsFileSystem.js +1 -1
  45. package/lib/platform/HostedZone.js +1 -1
  46. package/lib/platform/PrivateDnsNamespace.js +1 -1
  47. package/lib/platform/ResourceServer.js +1 -1
  48. package/lib/platform/Vpc.js +1 -1
  49. package/lib/platform/VpcV2.js +1 -1
  50. package/lib/stacks/ApplicationStack.js +1 -1
  51. package/lib/utils/BasePlatformStackResolver.js +1 -1
  52. package/lib/utils/StackParameter.js +1 -1
  53. package/node_modules/@nodable/entities/README.md +41 -0
  54. package/node_modules/@nodable/entities/package.json +54 -0
  55. package/node_modules/@nodable/entities/src/EntityDecoder.js +543 -0
  56. package/node_modules/@nodable/entities/src/EntityEncoder.js +194 -0
  57. package/node_modules/@nodable/entities/src/entities.js +1177 -0
  58. package/node_modules/@nodable/entities/src/entityTries.js +49 -0
  59. package/node_modules/@nodable/entities/src/index.d.ts +264 -0
  60. package/node_modules/@nodable/entities/src/index.js +29 -0
  61. package/node_modules/fast-xml-builder/CHANGELOG.md +40 -0
  62. package/node_modules/fast-xml-builder/LICENSE +21 -0
  63. package/node_modules/fast-xml-builder/README.md +74 -0
  64. package/node_modules/fast-xml-builder/lib/fxb.cjs +1 -0
  65. package/node_modules/fast-xml-builder/lib/fxb.d.cts +270 -0
  66. package/node_modules/fast-xml-builder/lib/fxb.min.js +2 -0
  67. package/node_modules/fast-xml-builder/lib/fxb.min.js.map +1 -0
  68. package/node_modules/fast-xml-builder/package.json +81 -0
  69. package/node_modules/fast-xml-builder/src/fxb.d.ts +270 -0
  70. package/node_modules/fast-xml-builder/src/fxb.js +599 -0
  71. package/node_modules/fast-xml-builder/src/ignoreAttributes.js +18 -0
  72. package/node_modules/fast-xml-builder/src/orderedJs2Xml.js +359 -0
  73. package/node_modules/fast-xml-builder/src/util.js +16 -0
  74. package/node_modules/fast-xml-parser/CHANGELOG.md +165 -0
  75. package/node_modules/fast-xml-parser/README.md +21 -44
  76. package/node_modules/fast-xml-parser/lib/fxbuilder.min.js +1 -1
  77. package/node_modules/fast-xml-parser/lib/fxbuilder.min.js.map +1 -1
  78. package/node_modules/fast-xml-parser/lib/fxp.cjs +1 -1
  79. package/node_modules/fast-xml-parser/lib/fxp.d.cts +343 -31
  80. package/node_modules/fast-xml-parser/lib/fxp.min.js +1 -1
  81. package/node_modules/fast-xml-parser/lib/fxp.min.js.map +1 -1
  82. package/node_modules/fast-xml-parser/lib/fxparser.min.js +1 -1
  83. package/node_modules/fast-xml-parser/lib/fxparser.min.js.map +1 -1
  84. package/node_modules/fast-xml-parser/lib/fxvalidator.min.js +1 -1
  85. package/node_modules/fast-xml-parser/lib/fxvalidator.min.js.map +1 -1
  86. package/node_modules/fast-xml-parser/package.json +13 -8
  87. package/node_modules/fast-xml-parser/src/fxp.d.ts +335 -30
  88. package/node_modules/fast-xml-parser/src/fxp.js +1 -1
  89. package/node_modules/fast-xml-parser/src/util.js +18 -25
  90. package/node_modules/fast-xml-parser/src/v6/EntitiesParser.js +89 -87
  91. package/node_modules/fast-xml-parser/src/v6/OptionsBuilder.js +10 -10
  92. package/node_modules/fast-xml-parser/src/v6/OutputBuilders/BaseOutputBuilder.js +23 -23
  93. package/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsArrBuilder.js +29 -29
  94. package/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsMinArrBuilder.js +1 -1
  95. package/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsObjBuilder.js +39 -39
  96. package/node_modules/fast-xml-parser/src/v6/OutputBuilders/ParserOptionsBuilder.js +21 -21
  97. package/node_modules/fast-xml-parser/src/v6/XMLParser.js +22 -22
  98. package/node_modules/fast-xml-parser/src/v6/valueParsers/EntitiesParser.js +85 -85
  99. package/node_modules/fast-xml-parser/src/validator.js +34 -34
  100. package/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js +5 -284
  101. package/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js +335 -293
  102. package/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js +160 -43
  103. package/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js +540 -308
  104. package/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js +26 -26
  105. package/node_modules/fast-xml-parser/src/xmlparser/node2json.js +99 -41
  106. package/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js +10 -10
  107. package/node_modules/path-expression-matcher/LICENSE +21 -0
  108. package/node_modules/path-expression-matcher/README.md +872 -0
  109. package/node_modules/path-expression-matcher/lib/pem.cjs +1 -0
  110. package/node_modules/path-expression-matcher/lib/pem.d.cts +634 -0
  111. package/node_modules/path-expression-matcher/lib/pem.min.js +2 -0
  112. package/node_modules/path-expression-matcher/lib/pem.min.js.map +1 -0
  113. package/node_modules/path-expression-matcher/package.json +78 -0
  114. package/node_modules/path-expression-matcher/src/Expression.js +232 -0
  115. package/node_modules/path-expression-matcher/src/ExpressionSet.js +209 -0
  116. package/node_modules/path-expression-matcher/src/Matcher.js +570 -0
  117. package/node_modules/path-expression-matcher/src/index.d.ts +523 -0
  118. package/node_modules/path-expression-matcher/src/index.js +29 -0
  119. package/node_modules/strnum/CHANGELOG.md +12 -2
  120. package/node_modules/strnum/README.md +1 -0
  121. package/node_modules/strnum/package.json +5 -4
  122. package/node_modules/strnum/strnum.js +99 -65
  123. package/node_modules/xml-naming/README.md +189 -0
  124. package/node_modules/xml-naming/package.json +54 -0
  125. package/node_modules/xml-naming/src/index.d.ts +74 -0
  126. package/node_modules/xml-naming/src/index.js +270 -0
  127. package/package.json +3 -2
  128. package/renovate.json5 +1 -0
  129. package/node_modules/fast-xml-parser/src/xmlbuilder/orderedJs2Xml.js +0 -134
  130. package/node_modules/strnum/.github/SECURITY.md +0 -5
  131. package/node_modules/strnum/.vscode/launch.json +0 -25
  132. package/node_modules/strnum/algo.stflow +0 -84
  133. package/node_modules/strnum/strnum.test.js +0 -173
  134. package/node_modules/strnum/test.js +0 -9
  135. /package/node_modules/{fast-xml-parser/src/xmlbuilder → fast-xml-builder/src}/prettifyJs2Xml.js +0 -0
@@ -1,369 +1,411 @@
1
- import {isName} from '../util.js';
2
-
3
- //TODO: handle comments
4
- export default function readDocType(xmlData, i){
5
-
6
- const entities = {};
7
- if( xmlData[i + 3] === 'O' &&
8
- xmlData[i + 4] === 'C' &&
9
- xmlData[i + 5] === 'T' &&
10
- xmlData[i + 6] === 'Y' &&
11
- xmlData[i + 7] === 'P' &&
12
- xmlData[i + 8] === 'E')
13
- {
14
- i = i+9;
15
- let angleBracketsCount = 1;
16
- let hasBody = false, comment = false;
17
- let exp = "";
18
- for(;i<xmlData.length;i++){
19
- if (xmlData[i] === '<' && !comment) { //Determine the tag type
20
- if( hasBody && hasSeq(xmlData, "!ENTITY",i)){
21
- i += 7;
22
- let entityName, val;
23
- [entityName, val,i] = readEntityExp(xmlData,i+1);
24
- if(val.indexOf("&") === -1) //Parameter entities are not supported
25
- entities[ entityName ] = {
26
- regx : RegExp( `&${entityName};`,"g"),
27
- val: val
28
- };
29
- }
30
- else if( hasBody && hasSeq(xmlData, "!ELEMENT",i)) {
31
- i += 8;//Not supported
32
- const {index} = readElementExp(xmlData,i+1);
33
- i = index;
34
- }else if( hasBody && hasSeq(xmlData, "!ATTLIST",i)){
35
- i += 8;//Not supported
36
- // const {index} = readAttlistExp(xmlData,i+1);
37
- // i = index;
38
- }else if( hasBody && hasSeq(xmlData, "!NOTATION",i)) {
39
- i += 9;//Not supported
40
- const {index} = readNotationExp(xmlData,i+1);
41
- i = index;
42
- }else if( hasSeq(xmlData, "!--",i) ) comment = true;
43
- else throw new Error(`Invalid DOCTYPE`);
44
-
45
- angleBracketsCount++;
46
- exp = "";
47
- } else if (xmlData[i] === '>') { //Read tag content
48
- if(comment){
49
- if( xmlData[i - 1] === "-" && xmlData[i - 2] === "-"){
50
- comment = false;
1
+ import { qName as isName } from 'xml-naming';
2
+
3
+ export default class DocTypeReader {
4
+ constructor(options, xmlVersion) {
5
+ this.suppressValidationErr = !options;
6
+ this.options = options;
7
+ this.xmlVersion = xmlVersion || 1.0;
8
+ }
9
+
10
+ setXmlVersion(xmlVersion = 1.0) {
11
+ this.xmlVersion = xmlVersion;
12
+ }
13
+ readDocType(xmlData, i) {
14
+ const entities = Object.create(null);
15
+ let entityCount = 0;
16
+
17
+ if (xmlData[i + 3] === 'O' &&
18
+ xmlData[i + 4] === 'C' &&
19
+ xmlData[i + 5] === 'T' &&
20
+ xmlData[i + 6] === 'Y' &&
21
+ xmlData[i + 7] === 'P' &&
22
+ xmlData[i + 8] === 'E') {
23
+ i = i + 9;
24
+ let angleBracketsCount = 1;
25
+ let hasBody = false, comment = false;
26
+ let exp = "";
27
+ for (; i < xmlData.length; i++) {
28
+ if (xmlData[i] === '<' && !comment) { //Determine the tag type
29
+ if (hasBody && hasSeq(xmlData, "!ENTITY", i)) {
30
+ i += 7;
31
+ let entityName, val;
32
+ [entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);
33
+ if (val.indexOf("&") === -1) { //Parameter entities are not supported
34
+ if (this.options.enabled !== false &&
35
+ this.options.maxEntityCount != null &&
36
+ entityCount >= this.options.maxEntityCount) {
37
+ throw new Error(
38
+ `Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`
39
+ );
40
+ }
41
+ //const escaped = entityName.replace(/[.\-+*:]/g, '\\.');
42
+ //const escaped = entityName.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
43
+ entities[entityName] = val;
44
+ entityCount++;
45
+ }
46
+ }
47
+ else if (hasBody && hasSeq(xmlData, "!ELEMENT", i)) {
48
+ i += 8;//Not supported
49
+ const { index } = this.readElementExp(xmlData, i + 1);
50
+ i = index;
51
+ } else if (hasBody && hasSeq(xmlData, "!ATTLIST", i)) {
52
+ i += 8;//Not supported
53
+ // const {index} = this.readAttlistExp(xmlData,i+1);
54
+ // i = index;
55
+ } else if (hasBody && hasSeq(xmlData, "!NOTATION", i)) {
56
+ i += 9;//Not supported
57
+ const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);
58
+ i = index;
59
+ } else if (hasSeq(xmlData, "!--", i)) comment = true;
60
+ else throw new Error(`Invalid DOCTYPE`);
61
+
62
+ angleBracketsCount++;
63
+ exp = "";
64
+ } else if (xmlData[i] === '>') { //Read tag content
65
+ if (comment) {
66
+ if (xmlData[i - 1] === "-" && xmlData[i - 2] === "-") {
67
+ comment = false;
68
+ angleBracketsCount--;
69
+ }
70
+ } else {
51
71
  angleBracketsCount--;
52
72
  }
53
- }else{
54
- angleBracketsCount--;
55
- }
56
- if (angleBracketsCount === 0) {
57
- break;
73
+ if (angleBracketsCount === 0) {
74
+ break;
75
+ }
76
+ } else if (xmlData[i] === '[') {
77
+ hasBody = true;
78
+ } else {
79
+ exp += xmlData[i];
58
80
  }
59
- }else if( xmlData[i] === '['){
60
- hasBody = true;
61
- }else{
62
- exp += xmlData[i];
63
81
  }
82
+ if (angleBracketsCount !== 0) {
83
+ throw new Error(`Unclosed DOCTYPE`);
84
+ }
85
+ } else {
86
+ throw new Error(`Invalid Tag instead of DOCTYPE`);
64
87
  }
65
- if(angleBracketsCount !== 0){
66
- throw new Error(`Unclosed DOCTYPE`);
67
- }
68
- }else{
69
- throw new Error(`Invalid Tag instead of DOCTYPE`);
88
+ return { entities, i };
70
89
  }
71
- return {entities, i};
72
- }
90
+ readEntityExp(xmlData, i) {
91
+ //External entities are not supported
92
+ // <!ENTITY ext SYSTEM "http://normal-website.com" >
73
93
 
74
- const skipWhitespace = (data, index) => {
75
- while (index < data.length && /\s/.test(data[index])) {
76
- index++;
77
- }
78
- return index;
79
- };
94
+ //Parameter entities are not supported
95
+ // <!ENTITY entityname "&anotherElement;">
80
96
 
81
- function readEntityExp(xmlData, i) {
82
- //External entities are not supported
83
- // <!ENTITY ext SYSTEM "http://normal-website.com" >
97
+ //Internal entities are supported
98
+ // <!ENTITY entityname "replacement text">
84
99
 
85
- //Parameter entities are not supported
86
- // <!ENTITY entityname "&anotherElement;">
100
+ // Skip leading whitespace after <!ENTITY
101
+ i = skipWhitespace(xmlData, i);
87
102
 
88
- //Internal entities are supported
89
- // <!ENTITY entityname "replacement text">
103
+ // Read entity name
104
+ const startIndex = i;
105
+ while (i < xmlData.length && !/\s/.test(xmlData[i]) && xmlData[i] !== '"' && xmlData[i] !== "'") {
106
+ i++;
107
+ }
108
+ let entityName = xmlData.substring(startIndex, i);
90
109
 
91
- // Skip leading whitespace after <!ENTITY
92
- i = skipWhitespace(xmlData, i);
110
+ validateEntityName(entityName, { xmlVersion: this.xmlVersion });
93
111
 
94
- // Read entity name
95
- let entityName = "";
96
- while (i < xmlData.length && !/\s/.test(xmlData[i]) && xmlData[i] !== '"' && xmlData[i] !== "'") {
97
- entityName += xmlData[i];
98
- i++;
99
- }
100
- validateEntityName(entityName);
112
+ // Skip whitespace after entity name
113
+ i = skipWhitespace(xmlData, i);
101
114
 
102
- // Skip whitespace after entity name
103
- i = skipWhitespace(xmlData, i);
115
+ // Check for unsupported constructs (external entities or parameter entities)
116
+ if (!this.suppressValidationErr) {
117
+ if (xmlData.substring(i, i + 6).toUpperCase() === "SYSTEM") {
118
+ throw new Error("External entities are not supported");
119
+ } else if (xmlData[i] === "%") {
120
+ throw new Error("Parameter entities are not supported");
121
+ }
122
+ }
104
123
 
105
- // Check for unsupported constructs (external entities or parameter entities)
106
- if (xmlData.substring(i, i + 6).toUpperCase() === "SYSTEM") {
107
- throw new Error("External entities are not supported");
108
- }else if (xmlData[i] === "%") {
109
- throw new Error("Parameter entities are not supported");
124
+ // Read entity value (internal entity)
125
+ let entityValue = "";
126
+ [i, entityValue] = this.readIdentifierVal(xmlData, i, "entity");
127
+
128
+ // Validate entity size
129
+ if (this.options.enabled !== false &&
130
+ this.options.maxEntitySize != null &&
131
+ entityValue.length > this.options.maxEntitySize) {
132
+ throw new Error(
133
+ `Entity "${entityName}" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`
134
+ );
135
+ }
136
+
137
+ i--;
138
+ return [entityName, entityValue, i];
110
139
  }
111
140
 
112
- // Read entity value (internal entity)
113
- let entityValue = "";
114
- [i, entityValue] = readIdentifierVal(xmlData, i, "entity");
115
- i--;
116
- return [entityName, entityValue, i ];
117
- }
141
+ readNotationExp(xmlData, i) {
142
+ // Skip leading whitespace after <!NOTATION
143
+ i = skipWhitespace(xmlData, i);
118
144
 
119
- function readNotationExp(xmlData, i) {
120
- // Skip leading whitespace after <!NOTATION
121
- i = skipWhitespace(xmlData, i);
145
+ // Read notation name
122
146
 
123
- // Read notation name
124
- let notationName = "";
125
- while (i < xmlData.length && !/\s/.test(xmlData[i])) {
126
- notationName += xmlData[i];
127
- i++;
128
- }
129
- validateEntityName(notationName);
147
+ const startIndex = i;
148
+ while (i < xmlData.length && !/\s/.test(xmlData[i])) {
149
+ i++;
150
+ }
151
+ let notationName = xmlData.substring(startIndex, i);
130
152
 
131
- // Skip whitespace after notation name
132
- i = skipWhitespace(xmlData, i);
153
+ !this.suppressValidationErr && validateEntityName(notationName, { xmlVersion: this.xmlVersion });
133
154
 
134
- // Check identifier type (SYSTEM or PUBLIC)
135
- const identifierType = xmlData.substring(i, i + 6).toUpperCase();
136
- if (identifierType !== "SYSTEM" && identifierType !== "PUBLIC") {
137
- throw new Error(`Expected SYSTEM or PUBLIC, found "${identifierType}"`);
138
- }
139
- i += identifierType.length;
155
+ // Skip whitespace after notation name
156
+ i = skipWhitespace(xmlData, i);
140
157
 
141
- // Skip whitespace after identifier type
142
- i = skipWhitespace(xmlData, i);
158
+ // Check identifier type (SYSTEM or PUBLIC)
159
+ const identifierType = xmlData.substring(i, i + 6).toUpperCase();
160
+ if (!this.suppressValidationErr && identifierType !== "SYSTEM" && identifierType !== "PUBLIC") {
161
+ throw new Error(`Expected SYSTEM or PUBLIC, found "${identifierType}"`);
162
+ }
163
+ i += identifierType.length;
143
164
 
144
- // Read public identifier (if PUBLIC)
145
- let publicIdentifier = null;
146
- let systemIdentifier = null;
165
+ // Skip whitespace after identifier type
166
+ i = skipWhitespace(xmlData, i);
147
167
 
148
- if (identifierType === "PUBLIC") {
149
- [i, publicIdentifier ] = readIdentifierVal(xmlData, i, "publicIdentifier");
168
+ // Read public identifier (if PUBLIC)
169
+ let publicIdentifier = null;
170
+ let systemIdentifier = null;
150
171
 
151
- // Skip whitespace after public identifier
152
- i = skipWhitespace(xmlData, i);
172
+ if (identifierType === "PUBLIC") {
173
+ [i, publicIdentifier] = this.readIdentifierVal(xmlData, i, "publicIdentifier");
153
174
 
154
- // Optionally read system identifier
155
- if (xmlData[i] === '"' || xmlData[i] === "'") {
156
- [i, systemIdentifier ] = readIdentifierVal(xmlData, i,"systemIdentifier");
157
- }
158
- } else if (identifierType === "SYSTEM") {
159
- // Read system identifier (mandatory for SYSTEM)
160
- [i, systemIdentifier ] = readIdentifierVal(xmlData, i, "systemIdentifier");
175
+ // Skip whitespace after public identifier
176
+ i = skipWhitespace(xmlData, i);
177
+
178
+ // Optionally read system identifier
179
+ if (xmlData[i] === '"' || xmlData[i] === "'") {
180
+ [i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
181
+ }
182
+ } else if (identifierType === "SYSTEM") {
183
+ // Read system identifier (mandatory for SYSTEM)
184
+ [i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
161
185
 
162
- if (!systemIdentifier) {
163
- throw new Error("Missing mandatory system identifier for SYSTEM notation");
186
+ if (!this.suppressValidationErr && !systemIdentifier) {
187
+ throw new Error("Missing mandatory system identifier for SYSTEM notation");
188
+ }
164
189
  }
165
- }
166
-
167
- return {notationName, publicIdentifier, systemIdentifier, index: --i};
168
- }
169
190
 
170
- function readIdentifierVal(xmlData, i, type) {
171
- let identifierVal = "";
172
- const startChar = xmlData[i];
173
- if (startChar !== '"' && startChar !== "'") {
174
- throw new Error(`Expected quoted string, found "${startChar}"`);
191
+ return { notationName, publicIdentifier, systemIdentifier, index: --i };
175
192
  }
176
- i++;
177
193
 
178
- while (i < xmlData.length && xmlData[i] !== startChar) {
179
- identifierVal += xmlData[i];
194
+ readIdentifierVal(xmlData, i, type) {
195
+ let identifierVal = "";
196
+ const startChar = xmlData[i];
197
+ if (startChar !== '"' && startChar !== "'") {
198
+ throw new Error(`Expected quoted string, found "${startChar}"`);
199
+ }
180
200
  i++;
181
- }
182
201
 
183
- if (xmlData[i] !== startChar) {
184
- throw new Error(`Unterminated ${type} value`);
185
- }
186
- i++;
187
- return [i, identifierVal];
188
- }
202
+ const startIndex = i;
203
+ while (i < xmlData.length && xmlData[i] !== startChar) {
204
+ i++;
205
+ }
206
+ identifierVal = xmlData.substring(startIndex, i);
189
207
 
190
- function readElementExp(xmlData, i) {
191
- // <!ELEMENT br EMPTY>
192
- // <!ELEMENT div ANY>
193
- // <!ELEMENT title (#PCDATA)>
194
- // <!ELEMENT book (title, author+)>
195
- // <!ELEMENT name (content-model)>
196
-
197
- // Skip leading whitespace after <!ELEMENT
198
- i = skipWhitespace(xmlData, i);
199
-
200
- // Read element name
201
- let elementName = "";
202
- while (i < xmlData.length && !/\s/.test(xmlData[i])) {
203
- elementName += xmlData[i];
208
+ if (xmlData[i] !== startChar) {
209
+ throw new Error(`Unterminated ${type} value`);
210
+ }
204
211
  i++;
212
+ return [i, identifierVal];
205
213
  }
206
214
 
207
- // Validate element name
208
- if (!validateEntityName(elementName)) {
209
- throw new Error(`Invalid element name: "${elementName}"`);
210
- }
215
+ readElementExp(xmlData, i) {
216
+ // <!ELEMENT br EMPTY>
217
+ // <!ELEMENT div ANY>
218
+ // <!ELEMENT title (#PCDATA)>
219
+ // <!ELEMENT book (title, author+)>
220
+ // <!ELEMENT name (content-model)>
221
+
222
+ // Skip leading whitespace after <!ELEMENT
223
+ i = skipWhitespace(xmlData, i);
211
224
 
212
- // Skip whitespace after element name
213
- i = skipWhitespace(xmlData, i);
214
- let contentModel = "";
215
- // Expect '(' to start content model
216
- if(xmlData[i] === "E" && hasSeq(xmlData, "MPTY",i)) i+=4;
217
- else if(xmlData[i] === "A" && hasSeq(xmlData, "NY",i)) i+=2;
218
- else if (xmlData[i] === "(") {
219
- i++; // Move past '('
220
-
221
- // Read content model
222
- while (i < xmlData.length && xmlData[i] !== ")") {
223
- contentModel += xmlData[i];
225
+ // Read element name
226
+ const startIndex = i;
227
+ while (i < xmlData.length && !/\s/.test(xmlData[i])) {
224
228
  i++;
225
229
  }
226
- if (xmlData[i] !== ")") {
227
- throw new Error("Unterminated content model");
230
+ let elementName = xmlData.substring(startIndex, i);
231
+
232
+ // Validate element name
233
+ if (!this.suppressValidationErr && !isName(elementName, { xmlVersion: this.xmlVersion })) {
234
+ throw new Error(`Invalid element name: "${elementName}"`);
228
235
  }
229
236
 
230
- }else{
231
- throw new Error(`Invalid Element Expression, found "${xmlData[i]}"`);
232
- }
233
-
234
- return {
235
- elementName,
236
- contentModel: contentModel.trim(),
237
- index: i
238
- };
239
- }
237
+ // Skip whitespace after element name
238
+ i = skipWhitespace(xmlData, i);
239
+ let contentModel = "";
240
+ // Expect '(' to start content model
241
+ if (xmlData[i] === "E" && hasSeq(xmlData, "MPTY", i)) i += 4;
242
+ else if (xmlData[i] === "A" && hasSeq(xmlData, "NY", i)) i += 2;
243
+ else if (xmlData[i] === "(") {
244
+ i++; // Move past '('
245
+
246
+ // Read content model
247
+ const startIndex = i;
248
+ while (i < xmlData.length && xmlData[i] !== ")") {
249
+ i++;
250
+ }
251
+ contentModel = xmlData.substring(startIndex, i);
240
252
 
241
- function readAttlistExp(xmlData, i) {
242
- // Skip leading whitespace after <!ATTLIST
243
- i = skipWhitespace(xmlData, i);
253
+ if (xmlData[i] !== ")") {
254
+ throw new Error("Unterminated content model");
255
+ }
244
256
 
245
- // Read element name
246
- let elementName = "";
247
- while (i < xmlData.length && !/\s/.test(xmlData[i])) {
248
- elementName += xmlData[i];
249
- i++;
257
+ } else if (!this.suppressValidationErr) {
258
+ throw new Error(`Invalid Element Expression, found "${xmlData[i]}"`);
259
+ }
260
+
261
+ return {
262
+ elementName,
263
+ contentModel: contentModel.trim(),
264
+ index: i
265
+ };
250
266
  }
251
267
 
252
- // Validate element name
253
- validateEntityName(elementName)
268
+ readAttlistExp(xmlData, i) {
269
+ // Skip leading whitespace after <!ATTLIST
270
+ i = skipWhitespace(xmlData, i);
254
271
 
255
- // Skip whitespace after element name
256
- i = skipWhitespace(xmlData, i);
272
+ // Read element name
273
+ let startIndex = i;
274
+ while (i < xmlData.length && !/\s/.test(xmlData[i])) {
275
+ i++;
276
+ }
277
+ let elementName = xmlData.substring(startIndex, i);
257
278
 
258
- // Read attribute name
259
- let attributeName = "";
260
- while (i < xmlData.length && !/\s/.test(xmlData[i])) {
261
- attributeName += xmlData[i];
262
- i++;
263
- }
279
+ // Validate element name
280
+ validateEntityName(elementName, { xmlVersion: this.xmlVersion })
264
281
 
265
- // Validate attribute name
266
- if (!validateEntityName(attributeName)) {
267
- throw new Error(`Invalid attribute name: "${attributeName}"`);
268
- }
282
+ // Skip whitespace after element name
283
+ i = skipWhitespace(xmlData, i);
269
284
 
270
- // Skip whitespace after attribute name
271
- i = skipWhitespace(xmlData, i);
285
+ // Read attribute name
286
+ startIndex = i;
287
+ while (i < xmlData.length && !/\s/.test(xmlData[i])) {
288
+ i++;
289
+ }
290
+ let attributeName = xmlData.substring(startIndex, i);
272
291
 
273
- // Read attribute type
274
- let attributeType = "";
275
- if (xmlData.substring(i, i + 8).toUpperCase() === "NOTATION") {
276
- attributeType = "NOTATION";
277
- i += 8; // Move past "NOTATION"
292
+ // Validate attribute name
293
+ if (!validateEntityName(attributeName, { xmlVersion: this.xmlVersion })) {
294
+ throw new Error(`Invalid attribute name: "${attributeName}"`);
295
+ }
278
296
 
279
- // Skip whitespace after "NOTATION"
297
+ // Skip whitespace after attribute name
280
298
  i = skipWhitespace(xmlData, i);
281
299
 
282
- // Expect '(' to start the list of notations
283
- if (xmlData[i] !== "(") {
284
- throw new Error(`Expected '(', found "${xmlData[i]}"`);
285
- }
286
- i++; // Move past '('
287
-
288
- // Read the list of allowed notations
289
- let allowedNotations = [];
290
- while (i < xmlData.length && xmlData[i] !== ")") {
291
- let notation = "";
292
- while (i < xmlData.length && xmlData[i] !== "|" && xmlData[i] !== ")") {
293
- notation += xmlData[i];
294
- i++;
300
+ // Read attribute type
301
+ let attributeType = "";
302
+ if (xmlData.substring(i, i + 8).toUpperCase() === "NOTATION") {
303
+ attributeType = "NOTATION";
304
+ i += 8; // Move past "NOTATION"
305
+
306
+ // Skip whitespace after "NOTATION"
307
+ i = skipWhitespace(xmlData, i);
308
+
309
+ // Expect '(' to start the list of notations
310
+ if (xmlData[i] !== "(") {
311
+ throw new Error(`Expected '(', found "${xmlData[i]}"`);
295
312
  }
313
+ i++; // Move past '('
296
314
 
297
- // Validate notation name
298
- notation = notation.trim();
299
- if (!validateEntityName(notation)) {
300
- throw new Error(`Invalid notation name: "${notation}"`);
315
+ // Read the list of allowed notations
316
+ let allowedNotations = [];
317
+ while (i < xmlData.length && xmlData[i] !== ")") {
318
+
319
+
320
+ const startIndex = i;
321
+ while (i < xmlData.length && xmlData[i] !== "|" && xmlData[i] !== ")") {
322
+ i++;
323
+ }
324
+ let notation = xmlData.substring(startIndex, i);
325
+
326
+ // Validate notation name
327
+ notation = notation.trim();
328
+ if (!validateEntityName(notation, { xmlVersion: this.xmlVersion })) {
329
+ throw new Error(`Invalid notation name: "${notation}"`);
330
+ }
331
+
332
+ allowedNotations.push(notation);
333
+
334
+ // Skip '|' separator or exit loop
335
+ if (xmlData[i] === "|") {
336
+ i++; // Move past '|'
337
+ i = skipWhitespace(xmlData, i); // Skip optional whitespace after '|'
338
+ }
301
339
  }
302
340
 
303
- allowedNotations.push(notation);
341
+ if (xmlData[i] !== ")") {
342
+ throw new Error("Unterminated list of notations");
343
+ }
344
+ i++; // Move past ')'
345
+
346
+ // Store the allowed notations as part of the attribute type
347
+ attributeType += " (" + allowedNotations.join("|") + ")";
348
+ } else {
349
+ // Handle simple types (e.g., CDATA, ID, IDREF, etc.)
350
+ const startIndex = i;
351
+ while (i < xmlData.length && !/\s/.test(xmlData[i])) {
352
+ i++;
353
+ }
354
+ attributeType += xmlData.substring(startIndex, i);
304
355
 
305
- // Skip '|' separator or exit loop
306
- if (xmlData[i] === "|") {
307
- i++; // Move past '|'
308
- i = skipWhitespace(xmlData, i); // Skip optional whitespace after '|'
356
+ // Validate simple attribute type
357
+ const validTypes = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
358
+ if (!this.suppressValidationErr && !validTypes.includes(attributeType.toUpperCase())) {
359
+ throw new Error(`Invalid attribute type: "${attributeType}"`);
309
360
  }
310
361
  }
311
362
 
312
- if (xmlData[i] !== ")") {
313
- throw new Error("Unterminated list of notations");
314
- }
315
- i++; // Move past ')'
363
+ // Skip whitespace after attribute type
364
+ i = skipWhitespace(xmlData, i);
316
365
 
317
- // Store the allowed notations as part of the attribute type
318
- attributeType += " (" + allowedNotations.join("|") + ")";
319
- } else {
320
- // Handle simple types (e.g., CDATA, ID, IDREF, etc.)
321
- while (i < xmlData.length && !/\s/.test(xmlData[i])) {
322
- attributeType += xmlData[i];
323
- i++;
366
+ // Read default value
367
+ let defaultValue = "";
368
+ if (xmlData.substring(i, i + 8).toUpperCase() === "#REQUIRED") {
369
+ defaultValue = "#REQUIRED";
370
+ i += 8;
371
+ } else if (xmlData.substring(i, i + 7).toUpperCase() === "#IMPLIED") {
372
+ defaultValue = "#IMPLIED";
373
+ i += 7;
374
+ } else {
375
+ [i, defaultValue] = this.readIdentifierVal(xmlData, i, "ATTLIST");
324
376
  }
325
377
 
326
- // Validate simple attribute type
327
- const validTypes = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
328
- if (!validTypes.includes(attributeType.toUpperCase())) {
329
- throw new Error(`Invalid attribute type: "${attributeType}"`);
378
+ return {
379
+ elementName,
380
+ attributeName,
381
+ attributeType,
382
+ defaultValue,
383
+ index: i
330
384
  }
331
385
  }
386
+ }
387
+
332
388
 
333
- // Skip whitespace after attribute type
334
- i = skipWhitespace(xmlData, i);
335
-
336
- // Read default value
337
- let defaultValue = "";
338
- if (xmlData.substring(i, i + 8).toUpperCase() === "#REQUIRED") {
339
- defaultValue = "#REQUIRED";
340
- i += 8;
341
- } else if (xmlData.substring(i, i + 7).toUpperCase() === "#IMPLIED") {
342
- defaultValue = "#IMPLIED";
343
- i += 7;
344
- } else {
345
- [i, defaultValue] = readIdentifierVal(xmlData, i, "ATTLIST");
346
- }
347
389
 
348
- return {
349
- elementName,
350
- attributeName,
351
- attributeType,
352
- defaultValue,
353
- index: i
390
+ const skipWhitespace = (data, index) => {
391
+ while (index < data.length && /\s/.test(data[index])) {
392
+ index++;
354
393
  }
355
- }
394
+ return index;
395
+ };
356
396
 
357
- function hasSeq(data, seq,i){
358
- for(let j=0;j<seq.length;j++){
359
- if(seq[j]!==data[i+j+1]) return false;
397
+
398
+
399
+ function hasSeq(data, seq, i) {
400
+ for (let j = 0; j < seq.length; j++) {
401
+ if (seq[j] !== data[i + j + 1]) return false;
360
402
  }
361
403
  return true;
362
404
  }
363
405
 
364
- function validateEntityName(name){
365
- if (isName(name))
366
- return name;
406
+ function validateEntityName(name, xmlVersion) {
407
+ if (isName(name, { xmlVersion: xmlVersion }))
408
+ return name;
367
409
  else
368
410
  throw new Error(`Invalid entity name ${name}`);
369
- }
411
+ }