@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,105 +1,114 @@
1
1
  const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
2
+ const binRegex = /^0b[01]+$/;
3
+ const octRegex = /^0o[0-7]+$/;
2
4
  const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
3
- // const octRegex = /^0x[a-z0-9]+/;
4
- // const binRegex = /0x[a-z0-9]+/;
5
5
 
6
-
7
6
  const consider = {
8
- hex : true,
9
- // oct: false,
7
+ hex: true,
8
+ binary: false,
9
+ octal: false,
10
10
  leadingZeros: true,
11
11
  decimalPoint: "\.",
12
12
  eNotation: true,
13
- //skipLike: /regex/
13
+ //skipLike: /regex/,
14
+ infinity: "original", // "null", "infinity" (Infinity type), "string" ("Infinity" (the string literal))
14
15
  };
15
16
 
16
- export default function toNumber(str, options = {}){
17
- options = Object.assign({}, consider, options );
18
- if(!str || typeof str !== "string" ) return str;
19
-
20
- let trimmedStr = str.trim();
21
-
22
- if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
23
- else if(str==="0") return 0;
17
+ export default function toNumber(str, options = {}) {
18
+ options = Object.assign({}, consider, options);
19
+ if (!str || typeof str !== "string") return str;
20
+
21
+ let trimmedStr = str.trim();
22
+
23
+ if (trimmedStr.length === 0) return str;
24
+ else if (options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
25
+ else if (trimmedStr === "0") return 0;
24
26
  else if (options.hex && hexRegex.test(trimmedStr)) {
25
27
  return parse_int(trimmedStr, 16);
26
- // }else if (options.oct && octRegex.test(str)) {
27
- // return Number.parseInt(val, 8);
28
- }else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation
29
- return resolveEnotation(str,trimmedStr,options);
30
- // }else if (options.parseBin && binRegex.test(str)) {
31
- // return Number.parseInt(val, 2);
32
- }else{
28
+ } else if (options.binary && binRegex.test(trimmedStr)) {
29
+ return parse_int(trimmedStr, 2);
30
+ } else if (options.octal && octRegex.test(trimmedStr)) {
31
+ return parse_int(trimmedStr, 8);
32
+ } else if (!isFinite(trimmedStr)) { //Infinity
33
+ return handleInfinity(str, Number(trimmedStr), options);
34
+ } else if (trimmedStr.includes('e') || trimmedStr.includes('E')) { //eNotation
35
+ return resolveEnotation(str, trimmedStr, options);
36
+ } else {
33
37
  //separate negative sign, leading zeros, and rest number
34
38
  const match = numRegex.exec(trimmedStr);
35
39
  // +00.123 => [ , '+', '00', '.123', ..
36
- if(match){
40
+ if (match) {
37
41
  const sign = match[1] || "";
38
42
  const leadingZeros = match[2];
39
43
  let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
40
44
  const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.
41
- str[leadingZeros.length+1] === "."
45
+ str[leadingZeros.length + 1] === "."
42
46
  : str[leadingZeros.length] === ".";
43
47
 
44
48
  //trim ending zeros for floating number
45
- if(!options.leadingZeros //leading zeros are not allowed
46
- && (leadingZeros.length > 1
47
- || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))){
49
+ if (!options.leadingZeros //leading zeros are not allowed
50
+ && (leadingZeros.length > 1
51
+ || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))) {
48
52
  // 00, 00.3, +03.24, 03, 03.24
49
53
  return str;
50
54
  }
51
- else{//no leading zeros or leading zeros are allowed
55
+ else {//no leading zeros or leading zeros are allowed
52
56
  const num = Number(trimmedStr);
53
57
  const parsedStr = String(num);
54
58
 
55
- if( num === 0) return num;
56
- if(parsedStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
57
- if(options.eNotation) return num;
59
+ if (num === 0) return num;
60
+ if (parsedStr.search(/[eE]/) !== -1) { //given number is long and parsed to eNotation
61
+ if (options.eNotation) return num;
58
62
  else return str;
59
- }else if(trimmedStr.indexOf(".") !== -1){ //floating number
60
- if(parsedStr === "0") return num; //0.0
61
- else if(parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000
62
- else if( parsedStr === `${sign}${numTrimmedByZeros}`) return num;
63
+ } else if (trimmedStr.indexOf(".") !== -1) { //floating number
64
+ if (parsedStr === "0") return num; //0.0
65
+ else if (parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000
66
+ else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;
63
67
  else return str;
64
68
  }
65
-
66
- let n = leadingZeros? numTrimmedByZeros : trimmedStr;
67
- if(leadingZeros){
69
+
70
+ let n = leadingZeros ? numTrimmedByZeros : trimmedStr;
71
+ if (leadingZeros) {
68
72
  // -009 => -9
69
- return (n === parsedStr) || (sign+n === parsedStr) ? num : str
70
- }else {
73
+ return (n === parsedStr) || (sign + n === parsedStr) ? num : str
74
+ } else {
71
75
  // +9
72
- return (n === parsedStr) || (n === sign+parsedStr) ? num : str
76
+ return (n === parsedStr) || (n === sign + parsedStr) ? num : str
73
77
  }
74
78
  }
75
- }else{ //non-numeric string
79
+ } else { //non-numeric string
76
80
  return str;
77
81
  }
78
82
  }
79
83
  }
80
84
 
81
85
  const eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
82
- function resolveEnotation(str,trimmedStr,options){
83
- if(!options.eNotation) return str;
84
- const notation = trimmedStr.match(eNotationRegx);
85
- if(notation){
86
+ function resolveEnotation(str, trimmedStr, options) {
87
+ if (!options.eNotation) return str;
88
+ const notation = trimmedStr.match(eNotationRegx);
89
+ if (notation) {
86
90
  let sign = notation[1] || "";
87
91
  const eChar = notation[3].indexOf("e") === -1 ? "E" : "e";
88
92
  const leadingZeros = notation[2];
89
93
  const eAdjacentToLeadingZeros = sign ? // 0E.
90
- str[leadingZeros.length+1] === eChar
94
+ str[leadingZeros.length + 1] === eChar
91
95
  : str[leadingZeros.length] === eChar;
92
96
 
93
- if(leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
94
- else if(leadingZeros.length === 1
95
- && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)){
97
+ if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
98
+ else if (leadingZeros.length === 1
99
+ && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {
100
+ return Number(trimmedStr);
101
+ } else if (leadingZeros.length > 0) {
102
+ // Has leading zeros — only accept if leadingZeros option allows it
103
+ if (options.leadingZeros && !eAdjacentToLeadingZeros) {
104
+ trimmedStr = (notation[1] || "") + notation[3];
96
105
  return Number(trimmedStr);
97
- }else if(options.leadingZeros && !eAdjacentToLeadingZeros){ //accept with leading zeros
98
- //remove leading 0s
99
- trimmedStr = (notation[1] || "") + notation[3];
106
+ } else return str;
107
+ } else {
108
+ // No leading zeros always valid e-notation, parse it
100
109
  return Number(trimmedStr);
101
- }else return str;
102
- }else{
110
+ }
111
+ } else {
103
112
  return str;
104
113
  }
105
114
  }
@@ -109,21 +118,46 @@ function resolveEnotation(str,trimmedStr,options){
109
118
  * @param {string} numStr without leading zeros
110
119
  * @returns
111
120
  */
112
- function trimZeros(numStr){
113
- if(numStr && numStr.indexOf(".") !== -1){//float
121
+ function trimZeros(numStr) {
122
+ if (numStr && numStr.indexOf(".") !== -1) {//float
114
123
  numStr = numStr.replace(/0+$/, ""); //remove ending zeros
115
- if(numStr === ".") numStr = "0";
116
- else if(numStr[0] === ".") numStr = "0"+numStr;
117
- else if(numStr[numStr.length-1] === ".") numStr = numStr.substring(0,numStr.length-1);
124
+ if (numStr === ".") numStr = "0";
125
+ else if (numStr[0] === ".") numStr = "0" + numStr;
126
+ else if (numStr[numStr.length - 1] === ".") numStr = numStr.substring(0, numStr.length - 1);
118
127
  return numStr;
119
128
  }
120
129
  return numStr;
121
130
  }
122
131
 
123
- function parse_int(numStr, base){
124
- //polyfill
125
- if(parseInt) return parseInt(numStr, base);
126
- else if(Number.parseInt) return Number.parseInt(numStr, base);
127
- else if(window && window.parseInt) return window.parseInt(numStr, base);
128
- else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")
132
+ function parse_int(numStr, base) {
133
+ const str = numStr.trim();
134
+ if (base === 2 || base === 8) numStr = str.substring(2);
135
+
136
+ if (parseInt) return parseInt(numStr, base);
137
+ else if (Number.parseInt) return Number.parseInt(numStr, base);
138
+ else if (window && window.parseInt) return window.parseInt(numStr, base);
139
+ else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
140
+ }
141
+
142
+ /**
143
+ * Handle infinite values based on user option
144
+ * @param {string} str - original input string
145
+ * @param {number} num - parsed number (Infinity or -Infinity)
146
+ * @param {object} options - user options
147
+ * @returns {string|number|null} based on infinity option
148
+ */
149
+ function handleInfinity(str, num, options) {
150
+ const isPositive = num === Infinity;
151
+
152
+ switch (options.infinity.toLowerCase()) {
153
+ case "null":
154
+ return null;
155
+ case "infinity":
156
+ return num; // Return Infinity or -Infinity
157
+ case "string":
158
+ return isPositive ? "Infinity" : "-Infinity";
159
+ case "original":
160
+ default:
161
+ return str; // Return original string like "1e1000"
162
+ }
129
163
  }
@@ -0,0 +1,189 @@
1
+ # xml-naming
2
+
3
+ Validates XML name productions as defined in the [XML 1.0](https://www.w3.org/TR/xml/) and [XML 1.1](https://www.w3.org/TR/xml11/) specifications.
4
+
5
+ Covers all five productions:
6
+
7
+ | Production | Description | Colon | Digit/hyphen start |
8
+ |---|---|---|---|
9
+ | `Name` | General XML name | ✅ | ❌ |
10
+ | `NCName` | Non-Colonized name | ❌ | ❌ |
11
+ | `QName` | Namespace-qualified name (`prefix:local`) | ✅ (one only) | ❌ |
12
+ | `NMToken` | Name token (relaxed start) | ✅ | ✅ |
13
+ | `NMTokens` | Whitespace-separated NMToken list | ✅ | ✅ |
14
+
15
+ Used internally by [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser), [fast-xml-validator](https://github.com/NaturalIntelligence/fast-xml-validator), [@nodable\flexible-xml-parser](https://github.com/nodable/flexible-xml-parser) and [fast-svg-parser](https://github.com/amitguptagwl/fast-svg-parser).
16
+
17
+ ---
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ npm install xml-naming
23
+ ```
24
+
25
+ ---
26
+
27
+ ## Usage
28
+
29
+ ### Boolean validators
30
+
31
+ ```js
32
+ import { name, ncName, qName, nmToken, nmTokens } from 'xml-naming';
33
+
34
+ // Name — colon allowed anywhere, used for DOCTYPE entity names
35
+ name('foo') // true
36
+ name('a:b:c') // true ← multiple colons fine for Name
37
+ name('1foo') // false ← digit start invalid
38
+
39
+ // NCName — no colon, used for SVG id attributes, namespace prefixes
40
+ ncName('my-id') // true
41
+ ncName('xlink:href') // false ← colon not allowed
42
+
43
+ // QName — exactly one colon as prefix separator, used for element/attribute names
44
+ qName('svg:circle') // true
45
+ qName('foo') // true ← unprefixed QName is valid
46
+ qName('a:b:c') // false ← only one colon allowed
47
+ qName(':foo') // false ← cannot start with colon
48
+
49
+ // NMToken — any NameChar at start, used for DTD NMTOKEN attributes
50
+ nmToken('123') // true ← digit start is fine
51
+ nmToken('-bar') // true
52
+ nmToken('foo bar') // false ← space not allowed
53
+
54
+ // NMTokens — whitespace-separated NMToken list
55
+ nmTokens('tok1 tok2 -foo 123') // true
56
+ ```
57
+
58
+ ### XML version option
59
+
60
+ All validators accept an optional `{ xmlVersion }` option:
61
+
62
+ ```js
63
+ import { name } from 'xml-naming';
64
+
65
+ name('\u0085', { xmlVersion: '1.0' }) // false — NEL (Next Line), not in 1.0 ranges
66
+ name('\u0085', { xmlVersion: '1.1' }) // true — explicitly allowed in 1.1
67
+
68
+ name('\uD800\uDC00', { xmlVersion: '1.0' }) // false
69
+ name('\uD800\uDC00', { xmlVersion: '1.1' }) // true
70
+ ```
71
+
72
+ ---
73
+
74
+ ### Diagnostic validation
75
+
76
+ ```js
77
+ import { validate } from 'xml-naming';
78
+
79
+ validate('svg:circle', 'qName')
80
+ // { valid: true, production: 'qName', input: 'svg:circle' }
81
+
82
+ validate('1foo', 'ncName')
83
+ // {
84
+ // valid: false,
85
+ // production: 'ncName',
86
+ // input: '1foo',
87
+ // reason: 'First character "1" is not a valid NameStartChar',
88
+ // position: 0
89
+ // }
90
+
91
+ validate('foo:bar', 'ncName')
92
+ // {
93
+ // valid: false,
94
+ // production: 'ncName',
95
+ // input: 'foo:bar',
96
+ // reason: 'Colon is not allowed in NCName',
97
+ // position: 3
98
+ // }
99
+
100
+ validate('a:b:c', 'qName')
101
+ // {
102
+ // valid: false,
103
+ // production: 'qName',
104
+ // input: 'a:b:c',
105
+ // reason: 'QName can have at most one colon',
106
+ // position: 3
107
+ // }
108
+ ```
109
+
110
+ ---
111
+
112
+ ### Batch validation
113
+
114
+ ```js
115
+ import { validateAll } from 'xml-naming';
116
+
117
+ validateAll(['svg', 'circle', '123bad', 'xlink:href'], 'ncName')
118
+ // [
119
+ // { valid: true, production: 'ncName', input: 'svg' },
120
+ // { valid: true, production: 'ncName', input: 'circle' },
121
+ // { valid: false, production: 'ncName', input: '123bad', reason: '...', position: 0 },
122
+ // { valid: false, production: 'ncName', input: 'xlink:href',reason: '...', position: 5 }
123
+ // ]
124
+ ```
125
+
126
+ ---
127
+
128
+ ### Sanitize / auto-fix
129
+
130
+ Useful when generating XML/SVG programmatically from user-supplied strings:
131
+
132
+ ```js
133
+ import { sanitize } from 'xml-naming';
134
+
135
+ sanitize('123abc', 'ncName') // '_123abc' ← digit start fixed
136
+ sanitize('my element','name') // 'my_element' ← space replaced
137
+ sanitize('foo:bar', 'ncName') // 'foobar' ← colon stripped
138
+ sanitize('hello!', 'name') // 'hello_' ← illegal char replaced
139
+
140
+ // Custom replacement character
141
+ sanitize('my element', 'name', { replacement: '-' }) // 'my-element'
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Which production should I use?
147
+
148
+ | Context | Production |
149
+ |---|---|
150
+ | XML element/attribute names (namespace-aware) | `qName` |
151
+ | SVG `id` attribute values | `ncName` |
152
+ | Namespace prefix alone | `ncName` |
153
+ | DOCTYPE `<!ENTITY name ...>` | `name` |
154
+ | DOCTYPE `<!NOTATION name ...>` | `name` |
155
+ | DTD `NMTOKEN` attribute values | `nmToken` |
156
+ | DTD `NMTOKENS` attribute values | `nmTokens` |
157
+
158
+ > **Note:** DOCTYPE entity and notation names must use `Name`, not `QName`. Colons carry no namespace meaning in the DTD subset.
159
+
160
+ ---
161
+
162
+ ## API
163
+
164
+ ### `name(str, opts?)` → `boolean`
165
+ ### `ncName(str, opts?)` → `boolean`
166
+ ### `qName(str, opts?)` → `boolean`
167
+ ### `nmToken(str, opts?)` → `boolean`
168
+ ### `nmTokens(str, opts?)` → `boolean`
169
+
170
+ `opts`:
171
+ - `xmlVersion`: `'1.0'` (default) | `'1.1'`
172
+
173
+ ### `validate(str, production, opts?)` → `ValidationResult`
174
+
175
+ `production`: `'name'` | `'ncName'` | `'qName'` | `'nmToken'` | `'nmTokens'`
176
+
177
+ ### `validateAll(strings[], production, opts?)` → `ValidationResult[]`
178
+
179
+ ### `sanitize(str, production?, opts?)` → `string`
180
+
181
+ `opts`:
182
+ - `xmlVersion`: `'1.0'` | `'1.1'`
183
+ - `replacement`: string (default `'_'`)
184
+
185
+ ---
186
+
187
+ ## License
188
+
189
+ MIT
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "xml-naming",
3
+ "version": "0.1.0",
4
+ "description": "Validates XML name productions — Name, NCName, QName, NMToken, NMTokens — for XML 1.0 and 1.1",
5
+ "type": "module",
6
+ "main": "./src/index.js",
7
+ "types": "./src/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./src/index.js",
11
+ "types": "./src/index.d.ts"
12
+ }
13
+ },
14
+ "files": [
15
+ "src",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "test": "jasmine specs/*spec.js"
20
+ },
21
+ "keywords": [
22
+ "xml",
23
+ "xml-name",
24
+ "ncname",
25
+ "qname",
26
+ "nmtoken",
27
+ "xml-validation",
28
+ "xml-namespace",
29
+ "name-validator",
30
+ "xml-1.0",
31
+ "xml-1.1"
32
+ ],
33
+ "author": "Amit Gupta (https://solothought.com)",
34
+ "license": "MIT",
35
+ "funding": [
36
+ {
37
+ "type": "github",
38
+ "url": "https://github.com/sponsors/NaturalIntelligence"
39
+ }
40
+ ],
41
+ "devDependencies": {
42
+ "jasmine": "^5.0.0"
43
+ },
44
+ "engines": {
45
+ "node": ">=16.0.0"
46
+ },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/NaturalIntelligence/xml-naming"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/NaturalIntelligence/xml-naming/issues"
53
+ }
54
+ }
@@ -0,0 +1,74 @@
1
+ export interface ValidationOptions {
2
+ /** XML specification version to validate against. Defaults to '1.0'. */
3
+ xmlVersion?: '1.0' | '1.1';
4
+ }
5
+
6
+ export interface SanitizeOptions extends ValidationOptions {
7
+ /** Character used to replace invalid characters. Defaults to '_'. */
8
+ replacement?: string;
9
+ }
10
+
11
+ export type Production = 'name' | 'ncName' | 'qName' | 'nmToken' | 'nmTokens';
12
+
13
+ export interface ValidationResult {
14
+ valid: boolean;
15
+ production: Production;
16
+ input: string;
17
+ /** Present only when valid is false. */
18
+ reason?: string;
19
+ /** Index of the first offending character. Present only when valid is false. */
20
+ position?: number;
21
+ }
22
+
23
+ /**
24
+ * Returns true if the string is a valid XML Name.
25
+ * Colons are permitted anywhere (Name production).
26
+ * Used for: DOCTYPE entity names, notation names, DTD element declarations.
27
+ */
28
+ export function name(str: string, opts?: ValidationOptions): boolean;
29
+
30
+ /**
31
+ * Returns true if the string is a valid NCName (Non-Colonized Name).
32
+ * Colons are not permitted.
33
+ * Used for: namespace prefixes, local names, SVG id attributes.
34
+ */
35
+ export function ncName(str: string, opts?: ValidationOptions): boolean;
36
+
37
+ /**
38
+ * Returns true if the string is a valid QName (Qualified Name).
39
+ * Allows exactly one colon as a prefix separator: prefix:localName.
40
+ * Used for: element and attribute names in namespace-aware XML/SVG.
41
+ */
42
+ export function qName(str: string, opts?: ValidationOptions): boolean;
43
+
44
+ /**
45
+ * Returns true if the string is a valid NMToken.
46
+ * Same character set as Name but no restriction on the first character.
47
+ * Used for: DTD NMTOKEN attribute values.
48
+ */
49
+ export function nmToken(str: string, opts?: ValidationOptions): boolean;
50
+
51
+ /**
52
+ * Returns true if the string is a valid NMTokens value.
53
+ * A whitespace-separated list of NMToken values.
54
+ * Used for: DTD NMTOKENS attribute values.
55
+ */
56
+ export function nmTokens(str: string, opts?: ValidationOptions): boolean;
57
+
58
+ /**
59
+ * Validates a string against a named XML production and returns a detailed result.
60
+ */
61
+ export function validate(str: string, production: Production, opts?: ValidationOptions): ValidationResult;
62
+
63
+ /**
64
+ * Validates an array of strings against a named XML production.
65
+ */
66
+ export function validateAll(strings: string[], production: Production, opts?: ValidationOptions): ValidationResult[];
67
+
68
+ /**
69
+ * Transforms an invalid string into the nearest valid XML name for the given production.
70
+ * - Strips or replaces illegal characters
71
+ * - Fixes invalid start characters by prepending the replacement character
72
+ * - Removes colons for NCName production
73
+ */
74
+ export function sanitize(str: string, production?: Production, opts?: SanitizeOptions): string;