@btc-embedded/cdk-extensions 0.23.4 → 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 +5 -5
  2. package/CHANGELOG.md +7 -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 +2 -2
  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
@@ -0,0 +1,359 @@
1
+ import { Expression, Matcher } from 'path-expression-matcher';
2
+ import { safeComment, safeCdata, escapeAttribute } from "./util.js";
3
+ import { qName } from 'xml-naming';
4
+
5
+ const EOL = "\n";
6
+
7
+ /**
8
+ * Detect XML version from the first element of the ordered array input.
9
+ * The first element must be a ?xml processing instruction with a version attribute.
10
+ * Returns '1.0' if not found.
11
+ *
12
+ * @param {array} jArray
13
+ * @param {object} options
14
+ */
15
+ function detectXmlVersionFromArray(jArray, options) {
16
+ if (!Array.isArray(jArray) || jArray.length === 0) return '1.0';
17
+ const first = jArray[0];
18
+ const firstKey = propName(first);
19
+ if (firstKey === '?xml') {
20
+ const attrs = first[':@'];
21
+ if (attrs) {
22
+ const versionKey = options.attributeNamePrefix + 'version';
23
+ if (attrs[versionKey]) return attrs[versionKey];
24
+ }
25
+ }
26
+ return '1.0';
27
+ }
28
+
29
+ /**
30
+ * Resolve a tag or attribute name through sanitizeName if configured.
31
+ * Validation via xml-naming's qName is performed first; the sanitizeName
32
+ * callback is invoked only when the name is invalid. If sanitizeName is
33
+ * false (default), no validation occurs and the name is used as-is.
34
+ *
35
+ * @param {string} name - raw name from the JS object
36
+ * @param {boolean} isAttribute - true when resolving an attribute name
37
+ * @param {object} options
38
+ * @param {Matcher} matcher - current matcher state (readonly from callback perspective)
39
+ * @param {string} xmlVersion - '1.0' or '1.1', forwarded to xml-naming
40
+ */
41
+ function resolveTagName(name, isAttribute, options, matcher, xmlVersion) {
42
+ if (!options.sanitizeName) return name;
43
+ if (qName(name, { xmlVersion })) return name;
44
+ return options.sanitizeName(name, { isAttribute, matcher: matcher.readOnly() });
45
+ }
46
+
47
+ /**
48
+ * @param {array} jArray
49
+ * @param {any} options
50
+ * @returns
51
+ */
52
+ export default function toXml(jArray, options) {
53
+ let indentation = "";
54
+ if (options.format) {
55
+ indentation = EOL;
56
+ }
57
+
58
+ // Pre-compile stopNode expressions for pattern matching
59
+ const stopNodeExpressions = [];
60
+ if (options.stopNodes && Array.isArray(options.stopNodes)) {
61
+ for (let i = 0; i < options.stopNodes.length; i++) {
62
+ const node = options.stopNodes[i];
63
+ if (typeof node === 'string') {
64
+ stopNodeExpressions.push(new Expression(node));
65
+ } else if (node instanceof Expression) {
66
+ stopNodeExpressions.push(node);
67
+ }
68
+ }
69
+ }
70
+
71
+ // Detect XML version for use in name validation
72
+ const xmlVersion = detectXmlVersionFromArray(jArray, options);
73
+
74
+ // Initialize matcher for path tracking
75
+ const matcher = new Matcher();
76
+
77
+ return arrToStr(jArray, options, indentation, matcher, stopNodeExpressions, xmlVersion);
78
+ }
79
+
80
+ function arrToStr(arr, options, indentation, matcher, stopNodeExpressions, xmlVersion) {
81
+ let xmlStr = "";
82
+ let isPreviousElementTag = false;
83
+
84
+ if (options.maxNestedTags && matcher.getDepth() > options.maxNestedTags) {
85
+ throw new Error("Maximum nested tags exceeded");
86
+ }
87
+
88
+ if (!Array.isArray(arr)) {
89
+ // Non-array values (e.g. string tag values) should be treated as text content
90
+ if (arr !== undefined && arr !== null) {
91
+ let text = arr.toString();
92
+ text = replaceEntitiesValue(text, options);
93
+ return text;
94
+ }
95
+ return "";
96
+ }
97
+
98
+ for (let i = 0; i < arr.length; i++) {
99
+ const tagObj = arr[i];
100
+ const rawTagName = propName(tagObj);
101
+ if (rawTagName === undefined) continue;
102
+
103
+ // Special names are exempt from sanitizeName: internal conventions and PI tags
104
+ // are not user-supplied XML element names.
105
+ const isSpecialName = rawTagName === options.textNodeName
106
+ || rawTagName === options.cdataPropName
107
+ || rawTagName === options.commentPropName
108
+ || rawTagName[0] === '?';
109
+
110
+ // Resolve tag name (may transform it; may throw for invalid names)
111
+ const tagName = isSpecialName
112
+ ? rawTagName
113
+ : resolveTagName(rawTagName, false, options, matcher, xmlVersion);
114
+
115
+ // Extract attributes from ":@" property
116
+ const attrValues = extractAttributeValues(tagObj[":@"], options);
117
+
118
+ // Push resolved tag to matcher WITH attributes
119
+ matcher.push(tagName, attrValues);
120
+
121
+ // Check if this is a stop node using Expression matching
122
+ const isStopNode = checkStopNode(matcher, stopNodeExpressions);
123
+
124
+ if (tagName === options.textNodeName) {
125
+ let tagText = tagObj[rawTagName];
126
+ if (!isStopNode) {
127
+ tagText = options.tagValueProcessor(tagName, tagText);
128
+ tagText = replaceEntitiesValue(tagText, options);
129
+ }
130
+ if (isPreviousElementTag) {
131
+ xmlStr += indentation;
132
+ }
133
+ xmlStr += tagText;
134
+ isPreviousElementTag = false;
135
+ matcher.pop();
136
+ continue;
137
+ } else if (tagName === options.cdataPropName) {
138
+ if (isPreviousElementTag) {
139
+ xmlStr += indentation;
140
+ }
141
+ const val = tagObj[rawTagName][0][options.textNodeName];
142
+ const safeVal = safeCdata(val);
143
+ xmlStr += `<![CDATA[${safeVal}]]>`;
144
+ isPreviousElementTag = false;
145
+ matcher.pop();
146
+ continue;
147
+ } else if (tagName === options.commentPropName) {
148
+ const val = tagObj[rawTagName][0][options.textNodeName];
149
+ const safeVal = safeComment(val);
150
+ xmlStr += indentation + `<!--${safeVal}-->`;
151
+ isPreviousElementTag = true;
152
+ matcher.pop();
153
+ continue;
154
+ } else if (tagName[0] === "?") {
155
+ const attStr = attr_to_str(tagObj[":@"], options, isStopNode, matcher, xmlVersion);
156
+ const tempInd = tagName === "?xml" ? "" : indentation;
157
+ // Text node content on PI/XML declaration tags is intentionally ignored.
158
+ // Only attributes are valid on these tags per the XML spec.
159
+ xmlStr += tempInd + `<${tagName}${attStr}?>`;
160
+ isPreviousElementTag = true;
161
+ matcher.pop();
162
+ continue;
163
+ }
164
+
165
+ let newIdentation = indentation;
166
+ if (newIdentation !== "") {
167
+ newIdentation += options.indentBy;
168
+ }
169
+
170
+ // Pass isStopNode to attr_to_str so attributes are also not processed for stopNodes
171
+ const attStr = attr_to_str(tagObj[":@"], options, isStopNode, matcher, xmlVersion);
172
+ const tagStart = indentation + `<${tagName}${attStr}`;
173
+
174
+ // If this is a stopNode, get raw content without processing
175
+ let tagValue;
176
+ if (isStopNode) {
177
+ tagValue = getRawContent(tagObj[rawTagName], options);
178
+ } else {
179
+ tagValue = arrToStr(tagObj[rawTagName], options, newIdentation, matcher, stopNodeExpressions, xmlVersion);
180
+ }
181
+
182
+ if (options.unpairedTags.indexOf(tagName) !== -1) {
183
+ if (options.suppressUnpairedNode) xmlStr += tagStart + ">";
184
+ else xmlStr += tagStart + "/>";
185
+ } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) {
186
+ xmlStr += tagStart + "/>";
187
+ } else if (tagValue && tagValue.endsWith(">")) {
188
+ xmlStr += tagStart + `>${tagValue}${indentation}</${tagName}>`;
189
+ } else {
190
+ xmlStr += tagStart + ">";
191
+ if (tagValue && indentation !== "" && (tagValue.includes("/>") || tagValue.includes("</"))) {
192
+ xmlStr += indentation + options.indentBy + tagValue + indentation;
193
+ } else {
194
+ xmlStr += tagValue;
195
+ }
196
+ xmlStr += `</${tagName}>`;
197
+ }
198
+ isPreviousElementTag = true;
199
+
200
+ // Pop tag from matcher
201
+ matcher.pop();
202
+ }
203
+
204
+ return xmlStr;
205
+ }
206
+
207
+ /**
208
+ * Extract attribute values from the ":@" object and return as plain object
209
+ * for passing to matcher.push()
210
+ */
211
+ function extractAttributeValues(attrMap, options) {
212
+ if (!attrMap || options.ignoreAttributes) return null;
213
+
214
+ const attrValues = {};
215
+ let hasAttrs = false;
216
+
217
+ for (let attr in attrMap) {
218
+ if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;
219
+ // Remove the attribute prefix to get clean attribute name
220
+ const cleanAttrName = attr.startsWith(options.attributeNamePrefix)
221
+ ? attr.substr(options.attributeNamePrefix.length)
222
+ : attr;
223
+ attrValues[cleanAttrName] = escapeAttribute(attrMap[attr]);
224
+ hasAttrs = true;
225
+ }
226
+
227
+ return hasAttrs ? attrValues : null;
228
+ }
229
+
230
+ /**
231
+ * Extract raw content from a stopNode without any processing
232
+ * This preserves the content exactly as-is, including special characters
233
+ */
234
+ function getRawContent(arr, options) {
235
+ if (!Array.isArray(arr)) {
236
+ // Non-array values return as-is
237
+ if (arr !== undefined && arr !== null) {
238
+ return arr.toString();
239
+ }
240
+ return "";
241
+ }
242
+
243
+ let content = "";
244
+ for (let i = 0; i < arr.length; i++) {
245
+ const item = arr[i];
246
+ const tagName = propName(item);
247
+
248
+ if (tagName === options.textNodeName) {
249
+ // Raw text content - NO processing, NO entity replacement
250
+ content += item[tagName];
251
+ } else if (tagName === options.cdataPropName) {
252
+ // CDATA content
253
+ content += item[tagName][0][options.textNodeName];
254
+ } else if (tagName === options.commentPropName) {
255
+ // Comment content
256
+ content += item[tagName][0][options.textNodeName];
257
+ } else if (tagName && tagName[0] === "?") {
258
+ // Processing instruction - skip for stopNodes
259
+ continue;
260
+ } else if (tagName) {
261
+ // Nested tags within stopNode — no sanitizeName, content is raw
262
+ const attStr = attr_to_str_raw(item[":@"], options);
263
+ const nestedContent = getRawContent(item[tagName], options);
264
+
265
+ if (!nestedContent || nestedContent.length === 0) {
266
+ content += `<${tagName}${attStr}/>`;
267
+ } else {
268
+ content += `<${tagName}${attStr}>${nestedContent}</${tagName}>`;
269
+ }
270
+ }
271
+ }
272
+ return content;
273
+ }
274
+
275
+ /**
276
+ * Build attribute string for stopNodes - NO entity replacement
277
+ */
278
+ function attr_to_str_raw(attrMap, options) {
279
+ let attrStr = "";
280
+ if (attrMap && !options.ignoreAttributes) {
281
+ for (let attr in attrMap) {
282
+ if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;
283
+ // For stopNodes, use raw value without processing
284
+ let attrVal = attrMap[attr];
285
+ if (attrVal === true && options.suppressBooleanAttributes) {
286
+ attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`;
287
+ } else {
288
+ attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}="${escapeAttribute(attrVal)}"`;
289
+ }
290
+ }
291
+ }
292
+ return attrStr;
293
+ }
294
+
295
+ function propName(obj) {
296
+ const keys = Object.keys(obj);
297
+ for (let i = 0; i < keys.length; i++) {
298
+ const key = keys[i];
299
+ if (!Object.prototype.hasOwnProperty.call(obj, key)) continue;
300
+ if (key !== ":@") return key;
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Build attribute string, resolving attribute names through sanitizeName when configured.
306
+ * Accepts matcher so the callback has path context.
307
+ */
308
+ function attr_to_str(attrMap, options, isStopNode, matcher, xmlVersion) {
309
+ let attrStr = "";
310
+ if (attrMap && !options.ignoreAttributes) {
311
+ for (let attr in attrMap) {
312
+ if (!Object.prototype.hasOwnProperty.call(attrMap, attr)) continue;
313
+
314
+ // Strip prefix to get the clean XML attribute name, then optionally sanitize it
315
+ const cleanAttrName = attr.substr(options.attributeNamePrefix.length);
316
+ const resolvedAttrName = isStopNode
317
+ ? cleanAttrName // stopNodes are raw — skip sanitizeName for attr names too
318
+ : resolveTagName(cleanAttrName, true, options, matcher, xmlVersion);
319
+
320
+ let attrVal;
321
+ if (isStopNode) {
322
+ // For stopNodes, use raw value without any processing
323
+ attrVal = attrMap[attr];
324
+ } else {
325
+ // Normal processing: apply attributeValueProcessor and entity replacement
326
+ attrVal = options.attributeValueProcessor(attr, attrMap[attr]);
327
+ attrVal = replaceEntitiesValue(attrVal, options);
328
+ }
329
+
330
+ if (attrVal === true && options.suppressBooleanAttributes) {
331
+ attrStr += ` ${resolvedAttrName}`;
332
+ } else {
333
+ attrStr += ` ${resolvedAttrName}="${escapeAttribute(attrVal)}"`;
334
+ }
335
+ }
336
+ }
337
+ return attrStr;
338
+ }
339
+
340
+ function checkStopNode(matcher, stopNodeExpressions) {
341
+ if (!stopNodeExpressions || stopNodeExpressions.length === 0) return false;
342
+
343
+ for (let i = 0; i < stopNodeExpressions.length; i++) {
344
+ if (matcher.matches(stopNodeExpressions[i])) {
345
+ return true;
346
+ }
347
+ }
348
+ return false;
349
+ }
350
+
351
+ function replaceEntitiesValue(textValue, options) {
352
+ if (textValue && textValue.length > 0 && options.processEntities) {
353
+ for (let i = 0; i < options.entities.length; i++) {
354
+ const entity = options.entities[i];
355
+ textValue = textValue.replace(entity.regex, entity.val);
356
+ }
357
+ }
358
+ return textValue;
359
+ }
@@ -0,0 +1,16 @@
1
+
2
+
3
+ export function safeComment(val) {
4
+ return String(val)
5
+ .replace(/--/g, '- -') // -- is illegal anywhere in comment content
6
+ .replace(/--/g, '- -') // handle the scenario when 2 consiucative dashes appears
7
+ .replace(/-$/, '- '); // trailing - would form -- with the closing -->
8
+ }
9
+
10
+ export function safeCdata(val) {
11
+ return String(val).replace(/\]\]>/g, ']]]]><![CDATA[>')
12
+ }
13
+
14
+ export function escapeAttribute(val) {
15
+ return String(val).replace(/"/g, '&quot;').replace(/'/g, '&apos;')
16
+ }
@@ -1,5 +1,170 @@
1
1
  <small>Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library.</small>
2
2
 
3
+ Note: Due to some last quick changes on v4, detail of v4.5.3 & v4.5.4 are not updated here. v4.5.4x is the last tag of v4 in github repository. I'm extremely sorry for the confusion
4
+
5
+ **5.8.0 / 2026-05-12*
6
+ - integrate xml-naming to validate DOCTYPE entity name and notation name (using qname becaue of backward compatibility)
7
+ - This will consider xml-version as well. '1.0' is default
8
+ - update strnum to 2.3.0
9
+ - You can set octal and binary parsing which is bydeault off
10
+ - update fast-xml-builder to 1.2.0
11
+ - can sanitize tag names if found invalid
12
+ - fix format output
13
+
14
+ **5.7.3 / 2006-05-05**
15
+ - fix: alwaysCreateTextNode should create text node when attributes are present for self closing node
16
+ - fix stop node expression when ns prefix is removed (found by [iruizsalinas](https://github.com/iruizsalinas))
17
+ - update XML Builder to 1.1.7
18
+ - mark addEntity deprecated
19
+
20
+
21
+ **5.7.2 / 2026-04-25**
22
+ - allow numerical external entity for backward compatibility
23
+ - fix #705: attributesGroupName working with preserveOrder
24
+ - fix #817: stackoverflow when tag expression is very long
25
+
26
+ **5.7.1 / 2026-04-20**
27
+ - fix typo in CJS typing file
28
+
29
+ **5.7.0 / 2026-04-17**
30
+ - Use `@nodable/entities` v2.1.0
31
+ - breaking changes
32
+ - single entity scan. You're not allowed to user entity value to form another entity name.
33
+ - you cant add numeric external entity
34
+ - entity error message when expantion limit is crossed might change
35
+ - typings are updated for new options related to process entity
36
+ - please follow documentation of `@nodable/entities` for more detail.
37
+ - performance
38
+ - if processEntities is false, then there should not be impact on performance.
39
+ - if processEntities is true, but you dont pass entity decoder separately then performance may degrade by approx 8-10%
40
+ - if processEntities is true, and you pass entity decoder separately
41
+ - if no entity then performance should be same as before
42
+ - if there are entities then performance should be increased from past versions
43
+ - ignoreAttributes is not required to be set to set xml version for NCR entity value
44
+ - update 'fast-xml-builder' to sanitize malicious CDATA and comment's content
45
+
46
+ **5.6.0 / 2026-04-15**
47
+ - fix: entity replacement for numeric entities
48
+ - use @nodable/entities to replace entities
49
+ - this may change some error messages related to entities expansion limit or inavlid use
50
+ - post check would be exposed in future version
51
+
52
+ **5.5.12 / 2026-04-13**
53
+ - Performance Improvement: update path-expression-matcher
54
+ - use proxy pattern than Proxy class
55
+
56
+ **5.5.11 / 2026-04-08**
57
+ - Performance Improvement
58
+ - integrate ExpressionSet for stopNodes
59
+
60
+ **5.5.10 / 2026-04-03**
61
+ - increase default entity explansion limit as many projects demand for that
62
+ - performance improvement
63
+ - reduce calls to toString
64
+ - early return when entities are not present
65
+ - prepare rawAttrsForMatcher only if user sets `jPath: false`
66
+
67
+ **5.5.9 / 2026-03-23**
68
+ - combine typing files
69
+
70
+
71
+ **4.5.5 / 2026-03-22**
72
+
73
+ apply fixes from v5 (legacy maintenance branch v4-maintenance)
74
+
75
+ - support maxEntityCount
76
+ - support onDangerousProperty
77
+ - support maxNestedTags
78
+ - handle prototype pollution
79
+ - fix incorrect entity name replacement
80
+ - fix incorrect condition for entity expansion
81
+
82
+ **5.5.8 / 2026-03-20**
83
+ - pass read only matcher in callback
84
+
85
+ **5.5.7 / 2026-03-19**
86
+ - fix: entity expansion limits
87
+ - update strnum package to 2.2.0
88
+
89
+ **5.5.6 / 2026-03-16**
90
+ - update builder dependency
91
+ - fix incorrect regex to replace \. in entity name
92
+ - fix check for entitiy expansion for lastEntities and html entities too
93
+
94
+ **5.5.5 / 2026-03-13**
95
+ - sanitize dangerous tag or attribute name
96
+ - error on critical property name
97
+ - support onDangerousProperty option
98
+
99
+ **5.5.4 / 2026-03-13**
100
+ - declare Matcher & Expression as unknown so user is not forced to install path-expression-matcher
101
+
102
+
103
+ **5.5.3 / 2026-03-11**
104
+ - upgrade builder
105
+
106
+ **5.5.2 / 2026-03-11**
107
+ - update dependency to fix typings
108
+
109
+ **5.5.1 / 2026-03-10**
110
+ - fix dependency
111
+
112
+ **5.5.0 / 2026-03-10**
113
+ - support path-expression-matcher
114
+ - fix: stopNode should not be parsed
115
+ - performance improvement for stopNode checking
116
+
117
+ **5.4.2 / 2026-03-03**
118
+ - support maxEntityCount option
119
+
120
+ **5.4.1 / 2026-02-25**
121
+ - fix (#785) unpairedTag node should not have tag content
122
+
123
+ **5.4.0 / 2026-02-25**
124
+ - migrate to fast-xml-builder
125
+
126
+ **5.3.9 / 2026-02-25**
127
+ - support strictReservedNames
128
+
129
+ **5.3.8 / 2026-02-25**
130
+ - support maxNestedTags
131
+ - handle non-array input for XML builder when preserveOrder is true (By [Angelo Coetzee](https://github.com/Angelopvtac))
132
+ - save use of js properies
133
+
134
+ **5.3.7 / 2026-02-20**
135
+ - fix typings for CJS (By [Corentin Girard](https://github.com/Drarig29))
136
+
137
+
138
+
139
+ **5.3.6 / 2026-02-14**
140
+ - Improve security and performance of entity processing
141
+ - new options `maxEntitySize`, `maxExpansionDepth`, `maxTotalExpansions`, `maxExpandedLength`, `allowedTags`,`tagFilter`
142
+ - fast return when no edtity is present
143
+ - improvement replacement logic to reduce number of calls
144
+
145
+
146
+ **5.3.5 / 2026-02-08**
147
+ - fix: Escape regex char in entity name
148
+ - update strnum to 2.1.2
149
+ - add missing exports in CJS typings
150
+
151
+
152
+ **5.3.4 / 2026-01-30**
153
+ - fix: handle HTML numeric and hex entities when out of range
154
+
155
+
156
+ **5.3.3 / 2025-12-12**
157
+ - fix #775: transformTagName with allowBooleanAttributes adds an unnecessary attribute
158
+
159
+ **5.3.2 / 2025-11-14**
160
+ - fix for import statement for v6
161
+
162
+ **5.3.1 / 2025-11-03**
163
+ - Performance improvement for stopNodes (By [Maciek Lamberski](https://github.com/macieklamberski))
164
+
165
+ **5.3.0 / 2025-10-03**
166
+ - Use `Uint8Array` in place of `Buffer` in Parser
167
+
3
168
  **5.2.5 / 2025-06-08**
4
169
  - Inform user to use [fxp-cli](https://github.com/NaturalIntelligence/fxp-cli) instead of in-built CLI feature
5
170
  - Export typings for direct use
@@ -7,21 +7,28 @@ Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++
7
7
  <img align="right" src="static/img/fxp_logo.png" width="180px" alt="FXP logo"/>
8
8
 
9
9
  * Validate XML data syntactically. Use [detailed-xml-validator](https://github.com/NaturalIntelligence/detailed-xml-validator/) to verify business rules.
10
- * Parse XML to JS Objectand vice versa
10
+ * Parse XML to JS Objects and vice versa
11
11
  * Common JS, ESM, and browser compatible
12
12
  * Faster than any other pure JS implementation.
13
13
 
14
14
  It can handle big files (tested up to 100mb). XML Entities, HTML entities, and DOCTYPE entites are supported. Unpaired tags (Eg `<br>` in HTML), stop nodes (Eg `<script>` in HTML) are supported. It can also preserve Order of tags in JS object
15
15
 
16
+ > [Flexible-XML-Parser](https://github.com/nodable/flexible-xml-parser) is 2 times faster than this library and allows to deal with incomplete XML/HTML. Output is highly customizable. Build whatever you want. So if you're fine with some extra configuration then try it out.
17
+
16
18
  ---
17
19
  # Your Support, Our Motivation
18
20
 
19
- ## Try out our New Thoughts
21
+ Please join [Discord community](https://discord.gg/X4Qp9u6Vz) for pre release announcements and discussions. This will prevent us to release breaking changes.
22
+
23
+
20
24
 
21
- We've recently launched **Flowgger**
22
- <a href="https://github.com/solothought/flowgger"> <img src="static/img/flowgger_h.webp" alt="Flowgger Logging Framework" /></a>
25
+ <!-- ## Try out our New Thoughts
23
26
 
24
- Don't forget to check our new library [Text2Chart](https://solothought.com/text2chart/flow) that constructs flow chart out of simple text. Very helpful in creating or alayzing an algorithm, and documentation purpose.
27
+ - WishIn - You need it if negative thoughts take over all the time <br>
28
+ <a href="https://play.google.com/store/apps/details?id=com.solothought.wishin"> <img src="https://solothought.com/products/assets/images/wishin/YouTubeThumbnail.png" width="500px"/> </a>
29
+ - **Flowgger**: 90% less logs size and 90% less debugging time<br>
30
+ <a href="https://github.com/solothought/flowgger"> <img src="static/img/flowgger_h.webp" alt="Flowgger Logging Framework" width="300px"/></a>
31
+ - [Text2Chart](https://solothought.com/text2chart/flow): interactive flow chart out of simple text. -->
25
32
 
26
33
  ## Financial Support
27
34
 
@@ -33,37 +40,10 @@ Sponsor this project
33
40
  <a href="https://opencollective.com/fast-xml-parser/donate" target="_blank">
34
41
  <img src="https://opencollective.com/fast-xml-parser/donate/button@2x.png?color=blue" width=180 />
35
42
  </a>
36
- <a href="https://paypal.me/naturalintelligence"> <img src="static/img/support_paypal.svg" alt="donate button" width="180"/></a>
37
43
  <br>
38
44
  <br>
39
45
  <br>
40
46
 
41
- <!--
42
- ### Current Sponsors
43
-
44
- Check the complete list at [ThankYouBackers](https://github.com/NaturalIntelligence/ThankYouBackers) for our sponsors and supporters.
45
-
46
- Through Github
47
-
48
- <a href="https://github.com/skunkteam" target="_blank"><img src="https://avatars.githubusercontent.com/u/46373671?s=60" width="60px"></a>
49
- <a href="https://github.com/getsentry" target="_blank"><img src="https://avatars.githubusercontent.com/u/1396951?s=60" width="60px"></a>
50
-
51
- Through OpenCollective
52
-
53
- <a href="https://opencollective.com/fast-xml-parser/sponsor/0/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/0/avatar.svg"></a>
54
- <a href="https://opencollective.com/fast-xml-parser/sponsor/1/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/1/avatar.svg"></a>
55
- <a href="https://opencollective.com/fast-xml-parser/sponsor/2/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/2/avatar.svg"></a>
56
- <a href="https://opencollective.com/fast-xml-parser/sponsor/3/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/3/avatar.svg"></a>
57
- <a href="https://opencollective.com/fast-xml-parser/sponsor/4/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/4/avatar.svg"></a>
58
- <a href="https://opencollective.com/fast-xml-parser/sponsor/5/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/5/avatar.svg"></a>
59
- <a href="https://opencollective.com/fast-xml-parser/sponsor/6/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/6/avatar.svg"></a>
60
- <a href="https://opencollective.com/fast-xml-parser/sponsor/7/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/7/avatar.svg"></a>
61
- <a href="https://opencollective.com/fast-xml-parser/sponsor/8/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/8/avatar.svg"></a>
62
- <a href="https://opencollective.com/fast-xml-parser/sponsor/9/website" target="_blank"><img src="https://opencollective.com/fast-xml-parser/sponsor/9/avatar.svg"></a>
63
- -->
64
-
65
- ![fxp_sponsors](https://raw.githubusercontent.com/NaturalIntelligence/ThankYouBackers/main/assets/NI_sponsors.jpg)
66
-
67
47
  > This is a donation. No goods or services are expected in return. Any requests for refunds for those purposes will be rejected.
68
48
 
69
49
  ## Users
@@ -151,26 +131,23 @@ Bundle size
151
131
  <a href="./docs/v3/docs.md">documents</a>
152
132
  </td>
153
133
  <td><ol>
154
- <li><a href="./docs/v4/1.GettingStarted.md">Getting Started</a></li>
155
- <li><a href="./docs/v4/2.XMLparseOptions.md">XML Parser</a></li>
156
- <li><a href="./docs/v4/3.XMLBuilder.md">XML Builder</a></li>
157
- <li><a href="./docs/v4/4.XMLValidator.md">XML Validator</a></li>
158
- <li><a href="./docs/v4/5.Entities.md">Entities</a></li>
159
- <li><a href="./docs/v4/6.HTMLParsing.md">HTML Document Parsing</a></li>
160
- <li><a href="./docs/v4/7.PITags.md">PI Tag processing</a></li>
134
+ <li><a href="./docs/v4,v5/1.GettingStarted.md">Getting Started</a></li>
135
+ <li><a href="./docs/v4,v5/2.XMLparseOptions.md">XML Parser</a></li>
136
+ <li><a href="./docs/v4,v5/3.XMLBuilder.md">XML Builder</a></li>
137
+ <li><a href="./docs/v4,v5/4.XMLValidator.md">XML Validator</a></li>
138
+ <li><a href="./docs/v4,v5/5.Entities.md">Entities</a></li>
139
+ <li><a href="./docs/v4,v5/6.HTMLParsing.md">HTML Document Parsing</a></li>
140
+ <li><a href="./docs/v4,v5/7.PITags.md">PI Tag processing</a></li>
141
+ <li><a href="./docs/v4,v5/8.PathExpression.md">Path Expression</a></li>
161
142
  </ol></td>
162
143
  <td><ol>
163
144
  <li></li><a href="./docs/v6/1.GettingStarted.md">Getting Started</a></li>
164
- <li><a href="./docs/v6/2.Features.md">Features</a></li>
165
- <li><a href="./docs/v6/3.Options.md">Options</a></li>
166
- <li><a href="./docs/v6/4.OutputBuilders.md">Output Builders</a></li>
167
- <li><a href="./docs/v6/5.ValueParsers.md">Value Parsers</a></li>
168
145
  </ol></td>
169
146
  </tr>
170
147
  </table>
171
148
 
172
149
  **note**:
173
- - Version 6 is released with version 4 for experimental use. Based on it's demand, it'll be developed and the features can be different in final release.
150
+ - Version 6 is released with version 4 for experimental use. Based on its demand, it'll be developed and the features can be different in final release.
174
151
  - Version 5 has the same functionalities as version 4.
175
152
 
176
153
  ## Performance