@cogitator-ai/wasm-tools 0.5.10 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +84 -25
  2. package/dist/index.d.ts +22 -3
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +81 -14
  5. package/dist/index.js.map +1 -1
  6. package/dist/manager/file-watcher.d.ts.map +1 -1
  7. package/dist/manager/file-watcher.js +6 -0
  8. package/dist/manager/file-watcher.js.map +1 -1
  9. package/dist/manager/types.d.ts +11 -3
  10. package/dist/manager/types.d.ts.map +1 -1
  11. package/dist/manager/wasm-loader.d.ts +1 -0
  12. package/dist/manager/wasm-loader.d.ts.map +1 -1
  13. package/dist/manager/wasm-loader.js +26 -5
  14. package/dist/manager/wasm-loader.js.map +1 -1
  15. package/dist/manager/wasm-tool-manager.d.ts +6 -0
  16. package/dist/manager/wasm-tool-manager.d.ts.map +1 -1
  17. package/dist/manager/wasm-tool-manager.js +115 -30
  18. package/dist/manager/wasm-tool-manager.js.map +1 -1
  19. package/dist/runtime.d.ts +11 -0
  20. package/dist/runtime.d.ts.map +1 -0
  21. package/dist/runtime.js +104 -0
  22. package/dist/runtime.js.map +1 -0
  23. package/dist/wasm/base64.wasm +0 -0
  24. package/dist/wasm/calc.wasm +0 -0
  25. package/dist/wasm/compression.wasm +0 -0
  26. package/dist/wasm/csv.wasm +0 -0
  27. package/dist/wasm/datetime.wasm +0 -0
  28. package/dist/wasm/diff.wasm +0 -0
  29. package/dist/wasm/hash.wasm +0 -0
  30. package/dist/wasm/json.wasm +0 -0
  31. package/dist/wasm/markdown.wasm +0 -0
  32. package/dist/wasm/regex.wasm +0 -0
  33. package/dist/wasm/signing.wasm +0 -0
  34. package/dist/wasm/slug.wasm +0 -0
  35. package/dist/wasm/validation.wasm +0 -0
  36. package/dist/wasm/xml.wasm +0 -0
  37. package/package.json +5 -6
  38. package/dist/__tests__/file-watcher.test.d.ts +0 -2
  39. package/dist/__tests__/file-watcher.test.d.ts.map +0 -1
  40. package/dist/__tests__/file-watcher.test.js +0 -99
  41. package/dist/__tests__/file-watcher.test.js.map +0 -1
  42. package/dist/__tests__/index.test.d.ts +0 -2
  43. package/dist/__tests__/index.test.d.ts.map +0 -1
  44. package/dist/__tests__/index.test.js +0 -226
  45. package/dist/__tests__/index.test.js.map +0 -1
  46. package/dist/__tests__/wasm-loader.test.d.ts +0 -2
  47. package/dist/__tests__/wasm-loader.test.d.ts.map +0 -1
  48. package/dist/__tests__/wasm-loader.test.js +0 -68
  49. package/dist/__tests__/wasm-loader.test.js.map +0 -1
  50. package/dist/__tests__/wasm-tool-manager.test.d.ts +0 -2
  51. package/dist/__tests__/wasm-tool-manager.test.d.ts.map +0 -1
  52. package/dist/__tests__/wasm-tool-manager.test.js +0 -166
  53. package/dist/__tests__/wasm-tool-manager.test.js.map +0 -1
  54. package/dist/plugins/base64.d.ts +0 -12
  55. package/dist/plugins/base64.d.ts.map +0 -1
  56. package/dist/plugins/base64.js +0 -95
  57. package/dist/plugins/base64.js.map +0 -1
  58. package/dist/plugins/calc.d.ts +0 -12
  59. package/dist/plugins/calc.d.ts.map +0 -1
  60. package/dist/plugins/calc.js +0 -95
  61. package/dist/plugins/calc.js.map +0 -1
  62. package/dist/plugins/compression.d.ts +0 -2
  63. package/dist/plugins/compression.d.ts.map +0 -1
  64. package/dist/plugins/compression.js +0 -545
  65. package/dist/plugins/compression.js.map +0 -1
  66. package/dist/plugins/csv.d.ts +0 -2
  67. package/dist/plugins/csv.d.ts.map +0 -1
  68. package/dist/plugins/csv.js +0 -136
  69. package/dist/plugins/csv.js.map +0 -1
  70. package/dist/plugins/datetime.d.ts +0 -2
  71. package/dist/plugins/datetime.d.ts.map +0 -1
  72. package/dist/plugins/datetime.js +0 -186
  73. package/dist/plugins/datetime.js.map +0 -1
  74. package/dist/plugins/diff.d.ts +0 -2
  75. package/dist/plugins/diff.d.ts.map +0 -1
  76. package/dist/plugins/diff.js +0 -187
  77. package/dist/plugins/diff.js.map +0 -1
  78. package/dist/plugins/hash.d.ts +0 -12
  79. package/dist/plugins/hash.d.ts.map +0 -1
  80. package/dist/plugins/hash.js +0 -309
  81. package/dist/plugins/hash.js.map +0 -1
  82. package/dist/plugins/json.d.ts +0 -12
  83. package/dist/plugins/json.d.ts.map +0 -1
  84. package/dist/plugins/json.js +0 -70
  85. package/dist/plugins/json.js.map +0 -1
  86. package/dist/plugins/markdown.d.ts +0 -2
  87. package/dist/plugins/markdown.d.ts.map +0 -1
  88. package/dist/plugins/markdown.js +0 -213
  89. package/dist/plugins/markdown.js.map +0 -1
  90. package/dist/plugins/regex.d.ts +0 -2
  91. package/dist/plugins/regex.d.ts.map +0 -1
  92. package/dist/plugins/regex.js +0 -120
  93. package/dist/plugins/regex.js.map +0 -1
  94. package/dist/plugins/signing.d.ts +0 -2
  95. package/dist/plugins/signing.d.ts.map +0 -1
  96. package/dist/plugins/signing.js +0 -576
  97. package/dist/plugins/signing.js.map +0 -1
  98. package/dist/plugins/slug.d.ts +0 -2
  99. package/dist/plugins/slug.d.ts.map +0 -1
  100. package/dist/plugins/slug.js +0 -180
  101. package/dist/plugins/slug.js.map +0 -1
  102. package/dist/plugins/validation.d.ts +0 -2
  103. package/dist/plugins/validation.d.ts.map +0 -1
  104. package/dist/plugins/validation.js +0 -105
  105. package/dist/plugins/validation.js.map +0 -1
  106. package/dist/plugins/xml.d.ts +0 -2
  107. package/dist/plugins/xml.d.ts.map +0 -1
  108. package/dist/plugins/xml.js +0 -297
  109. package/dist/plugins/xml.js.map +0 -1
  110. package/dist/temp/base64.js +0 -102
  111. package/dist/temp/calc.js +0 -102
  112. package/dist/temp/compression.js +0 -738
  113. package/dist/temp/csv.js +0 -155
  114. package/dist/temp/datetime.js +0 -201
  115. package/dist/temp/diff.js +0 -198
  116. package/dist/temp/hash.js +0 -423
  117. package/dist/temp/json.js +0 -80
  118. package/dist/temp/markdown.js +0 -224
  119. package/dist/temp/regex.js +0 -141
  120. package/dist/temp/signing.js +0 -584
  121. package/dist/temp/slug.js +0 -198
  122. package/dist/temp/validation.js +0 -125
  123. package/dist/temp/xml.js +0 -295
package/dist/temp/slug.js DELETED
@@ -1,198 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/plugins/slug.ts
21
- var slug_exports = {};
22
- __export(slug_exports, {
23
- slug: () => slug
24
- });
25
- module.exports = __toCommonJS(slug_exports);
26
- var CHAR_MAP = {
27
- \u00E0: "a",
28
- \u00E1: "a",
29
- \u00E2: "a",
30
- \u00E3: "a",
31
- \u00E4: "a",
32
- \u00E5: "a",
33
- \u00E6: "ae",
34
- \u00E7: "c",
35
- \u00E8: "e",
36
- \u00E9: "e",
37
- \u00EA: "e",
38
- \u00EB: "e",
39
- \u00EC: "i",
40
- \u00ED: "i",
41
- \u00EE: "i",
42
- \u00EF: "i",
43
- \u00F0: "d",
44
- \u00F1: "n",
45
- \u00F2: "o",
46
- \u00F3: "o",
47
- \u00F4: "o",
48
- \u00F5: "o",
49
- \u00F6: "o",
50
- \u00F8: "o",
51
- \u00F9: "u",
52
- \u00FA: "u",
53
- \u00FB: "u",
54
- \u00FC: "u",
55
- \u00FD: "y",
56
- \u00FF: "y",
57
- \u00FE: "th",
58
- \u00DF: "ss",
59
- \u0105: "a",
60
- \u0107: "c",
61
- \u0119: "e",
62
- \u0142: "l",
63
- \u0144: "n",
64
- \u015B: "s",
65
- \u017A: "z",
66
- \u017C: "z",
67
- \u010D: "c",
68
- \u010F: "d",
69
- \u011B: "e",
70
- \u0148: "n",
71
- \u0159: "r",
72
- \u0161: "s",
73
- \u0165: "t",
74
- \u016F: "u",
75
- \u017E: "z",
76
- \u0101: "a",
77
- \u0113: "e",
78
- \u0123: "g",
79
- \u012B: "i",
80
- \u0137: "k",
81
- \u013C: "l",
82
- \u0146: "n",
83
- \u016B: "u",
84
- \u0151: "o",
85
- \u0171: "u",
86
- \u0430: "a",
87
- \u0431: "b",
88
- \u0432: "v",
89
- \u0433: "g",
90
- \u0434: "d",
91
- \u0435: "e",
92
- \u0451: "yo",
93
- \u0436: "zh",
94
- \u0437: "z",
95
- \u0438: "i",
96
- \u0439: "y",
97
- \u043A: "k",
98
- \u043B: "l",
99
- \u043C: "m",
100
- \u043D: "n",
101
- \u043E: "o",
102
- \u043F: "p",
103
- \u0440: "r",
104
- \u0441: "s",
105
- \u0442: "t",
106
- \u0443: "u",
107
- \u0444: "f",
108
- \u0445: "h",
109
- \u0446: "ts",
110
- \u0447: "ch",
111
- \u0448: "sh",
112
- \u0449: "sch",
113
- \u044A: "",
114
- \u044B: "y",
115
- \u044C: "",
116
- \u044D: "e",
117
- \u044E: "yu",
118
- \u044F: "ya",
119
- \u03B1: "a",
120
- \u03B2: "b",
121
- \u03B3: "g",
122
- \u03B4: "d",
123
- \u03B5: "e",
124
- \u03B6: "z",
125
- \u03B7: "h",
126
- \u03B8: "th",
127
- \u03B9: "i",
128
- \u03BA: "k",
129
- \u03BB: "l",
130
- \u03BC: "m",
131
- \u03BD: "n",
132
- \u03BE: "x",
133
- \u03BF: "o",
134
- \u03C0: "p",
135
- \u03C1: "r",
136
- \u03C3: "s",
137
- \u03C4: "t",
138
- \u03C5: "y",
139
- \u03C6: "ph",
140
- \u03C7: "ch",
141
- \u03C8: "ps",
142
- \u03C9: "o"
143
- };
144
- function transliterate(str) {
145
- let result = "";
146
- for (const char of str) {
147
- const lower = char.toLowerCase();
148
- if (CHAR_MAP[lower]) {
149
- const mapped = CHAR_MAP[lower];
150
- result += char === lower ? mapped : mapped.toUpperCase();
151
- } else {
152
- result += char;
153
- }
154
- }
155
- return result;
156
- }
157
- function generateSlug(text, separator, lowercase, maxLength) {
158
- let slug2 = transliterate(text);
159
- if (lowercase) {
160
- slug2 = slug2.toLowerCase();
161
- }
162
- slug2 = slug2.replace(/[^a-zA-Z0-9\s-]/g, "").replace(/\s+/g, separator).replace(new RegExp(`${escapeRegex(separator)}+`, "g"), separator).replace(new RegExp(`^${escapeRegex(separator)}|${escapeRegex(separator)}$`, "g"), "");
163
- if (maxLength !== void 0 && maxLength > 0 && slug2.length > maxLength) {
164
- slug2 = slug2.substring(0, maxLength);
165
- const lastSep = slug2.lastIndexOf(separator);
166
- if (lastSep > maxLength * 0.5) {
167
- slug2 = slug2.substring(0, lastSep);
168
- }
169
- slug2 = slug2.replace(new RegExp(`${escapeRegex(separator)}$`), "");
170
- }
171
- return slug2;
172
- }
173
- function escapeRegex(str) {
174
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
175
- }
176
- function slug() {
177
- try {
178
- const inputStr = Host.inputString();
179
- const input = JSON.parse(inputStr);
180
- const separator = input.separator ?? "-";
181
- const lowercase = input.lowercase ?? true;
182
- const result = generateSlug(input.text, separator, lowercase, input.maxLength);
183
- const output = {
184
- slug: result,
185
- original: input.text
186
- };
187
- Host.outputString(JSON.stringify(output));
188
- return 0;
189
- } catch (error) {
190
- const output = {
191
- slug: "",
192
- original: "",
193
- error: error instanceof Error ? error.message : String(error)
194
- };
195
- Host.outputString(JSON.stringify(output));
196
- return 1;
197
- }
198
- }
@@ -1,125 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/plugins/validation.ts
21
- var validation_exports = {};
22
- __export(validation_exports, {
23
- validate: () => validate
24
- });
25
- module.exports = __toCommonJS(validation_exports);
26
- var EMAIL_REGEX = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
27
- var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
28
- var IPV4_REGEX = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
29
- var IPV6_REGEX = /^(?:(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|::(?:[fF]{4}:)?(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))$/;
30
- function validateEmail(value) {
31
- const trimmed = value.trim().toLowerCase();
32
- const valid = EMAIL_REGEX.test(trimmed) && trimmed.length <= 254;
33
- return { valid, normalized: valid ? trimmed : void 0 };
34
- }
35
- function validateUrl(value) {
36
- try {
37
- const trimmed = value.trim();
38
- const hasProtocol = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(trimmed);
39
- const urlStr = hasProtocol ? trimmed : `https://${trimmed}`;
40
- const parts = /^([a-zA-Z][a-zA-Z0-9+.-]*):\/\/([^/?#]+)(.*)$/.exec(urlStr);
41
- if (!parts) return { valid: false };
42
- const [, protocol, host] = parts;
43
- if (!["http", "https", "ftp", "ftps"].includes(protocol.toLowerCase())) {
44
- return { valid: false };
45
- }
46
- const hostParts = host.split(":");
47
- const hostname = hostParts[0];
48
- const port = hostParts[1];
49
- if (port && (!/^\d+$/.test(port) || parseInt(port) > 65535)) {
50
- return { valid: false };
51
- }
52
- if (!/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/.test(
53
- hostname
54
- )) {
55
- if (!IPV4_REGEX.test(hostname) && !hostname.startsWith("[")) {
56
- return { valid: false };
57
- }
58
- }
59
- return { valid: true, normalized: urlStr };
60
- } catch {
61
- return { valid: false };
62
- }
63
- }
64
- function validateUuid(value) {
65
- const trimmed = value.trim().toLowerCase();
66
- const valid = UUID_REGEX.test(trimmed);
67
- return { valid, normalized: valid ? trimmed : void 0 };
68
- }
69
- function validateIpv4(value) {
70
- const trimmed = value.trim();
71
- const valid = IPV4_REGEX.test(trimmed);
72
- if (valid) {
73
- const normalized = trimmed.split(".").map((n) => parseInt(n, 10).toString()).join(".");
74
- return { valid: true, normalized };
75
- }
76
- return { valid: false };
77
- }
78
- function validateIpv6(value) {
79
- const trimmed = value.trim().toLowerCase();
80
- const valid = IPV6_REGEX.test(trimmed);
81
- return { valid, normalized: valid ? trimmed : void 0 };
82
- }
83
- function validate() {
84
- try {
85
- const inputStr = Host.inputString();
86
- const input = JSON.parse(inputStr);
87
- let result;
88
- switch (input.type) {
89
- case "email":
90
- result = validateEmail(input.value);
91
- break;
92
- case "url":
93
- result = validateUrl(input.value);
94
- break;
95
- case "uuid":
96
- result = validateUuid(input.value);
97
- break;
98
- case "ipv4":
99
- result = validateIpv4(input.value);
100
- break;
101
- case "ipv6":
102
- result = validateIpv6(input.value);
103
- break;
104
- default:
105
- throw new Error(`Unknown validation type: ${input.type}`);
106
- }
107
- const output = {
108
- valid: result.valid,
109
- type: input.type,
110
- value: input.value,
111
- normalized: result.normalized
112
- };
113
- Host.outputString(JSON.stringify(output));
114
- return 0;
115
- } catch (error) {
116
- const output = {
117
- valid: false,
118
- type: "unknown",
119
- value: "",
120
- error: error instanceof Error ? error.message : String(error)
121
- };
122
- Host.outputString(JSON.stringify(output));
123
- return 1;
124
- }
125
- }
package/dist/temp/xml.js DELETED
@@ -1,295 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/plugins/xml.ts
21
- var xml_exports = {};
22
- __export(xml_exports, {
23
- xml: () => xml
24
- });
25
- module.exports = __toCommonJS(xml_exports);
26
- function parseXml(xml2) {
27
- let pos = 0;
28
- const skipWhitespace = () => {
29
- while (pos < xml2.length && /\s/.test(xml2[pos])) pos++;
30
- };
31
- const parseAttributes = () => {
32
- const attrs = {};
33
- while (pos < xml2.length) {
34
- skipWhitespace();
35
- if (xml2[pos] === ">" || xml2[pos] === "/" || xml2[pos] === "?") break;
36
- let name = "";
37
- while (pos < xml2.length && /[a-zA-Z0-9_:-]/.test(xml2[pos])) {
38
- name += xml2[pos++];
39
- }
40
- if (!name) break;
41
- skipWhitespace();
42
- if (xml2[pos] !== "=") {
43
- attrs[name] = "true";
44
- continue;
45
- }
46
- pos++;
47
- skipWhitespace();
48
- const quote = xml2[pos];
49
- if (quote !== '"' && quote !== "'") {
50
- throw new Error(`Expected quote at position ${pos}`);
51
- }
52
- pos++;
53
- let value = "";
54
- while (pos < xml2.length && xml2[pos] !== quote) {
55
- if (xml2[pos] === "&") {
56
- const entity = parseEntity();
57
- value += entity;
58
- } else {
59
- value += xml2[pos++];
60
- }
61
- }
62
- pos++;
63
- attrs[name] = value;
64
- }
65
- return attrs;
66
- };
67
- const parseEntity = () => {
68
- let entity = "";
69
- pos++;
70
- while (pos < xml2.length && xml2[pos] !== ";") {
71
- entity += xml2[pos++];
72
- }
73
- pos++;
74
- switch (entity) {
75
- case "lt":
76
- return "<";
77
- case "gt":
78
- return ">";
79
- case "amp":
80
- return "&";
81
- case "quot":
82
- return '"';
83
- case "apos":
84
- return "'";
85
- default:
86
- if (entity.startsWith("#x")) {
87
- return String.fromCharCode(parseInt(entity.slice(2), 16));
88
- } else if (entity.startsWith("#")) {
89
- return String.fromCharCode(parseInt(entity.slice(1), 10));
90
- }
91
- return `&${entity};`;
92
- }
93
- };
94
- const parseText = () => {
95
- let text = "";
96
- while (pos < xml2.length && xml2[pos] !== "<") {
97
- if (xml2[pos] === "&") {
98
- text += parseEntity();
99
- } else {
100
- text += xml2[pos++];
101
- }
102
- }
103
- return text;
104
- };
105
- const parseNode = () => {
106
- skipWhitespace();
107
- if (pos >= xml2.length) return null;
108
- if (xml2[pos] !== "<") {
109
- const text = parseText().trim();
110
- if (text) {
111
- return { type: "text", value: text };
112
- }
113
- return null;
114
- }
115
- pos++;
116
- if (xml2.slice(pos, pos + 3) === "!--") {
117
- pos += 3;
118
- const endPos = xml2.indexOf("-->", pos);
119
- if (endPos === -1) throw new Error("Unclosed comment");
120
- const value = xml2.slice(pos, endPos);
121
- pos = endPos + 3;
122
- return { type: "comment", value };
123
- }
124
- if (xml2.slice(pos, pos + 8) === "![CDATA[") {
125
- pos += 8;
126
- const endPos = xml2.indexOf("]]>", pos);
127
- if (endPos === -1) throw new Error("Unclosed CDATA");
128
- const value = xml2.slice(pos, endPos);
129
- pos = endPos + 3;
130
- return { type: "cdata", value };
131
- }
132
- if (xml2[pos] === "?") {
133
- const endPos = xml2.indexOf("?>", pos);
134
- if (endPos === -1) throw new Error("Unclosed processing instruction");
135
- pos = endPos + 2;
136
- return parseNode();
137
- }
138
- if (xml2[pos] === "!") {
139
- const endPos = xml2.indexOf(">", pos);
140
- if (endPos === -1) throw new Error("Unclosed declaration");
141
- pos = endPos + 1;
142
- return parseNode();
143
- }
144
- if (xml2[pos] === "/") {
145
- return null;
146
- }
147
- let name = "";
148
- while (pos < xml2.length && /[a-zA-Z0-9_:-]/.test(xml2[pos])) {
149
- name += xml2[pos++];
150
- }
151
- if (!name) throw new Error(`Expected element name at position ${pos}`);
152
- const attributes = parseAttributes();
153
- skipWhitespace();
154
- if (xml2.slice(pos, pos + 2) === "/>") {
155
- pos += 2;
156
- return { type: "element", name, attributes, children: [] };
157
- }
158
- if (xml2[pos] !== ">") {
159
- throw new Error(`Expected > at position ${pos}`);
160
- }
161
- pos++;
162
- const children = [];
163
- while (pos < xml2.length) {
164
- skipWhitespace();
165
- if (xml2.slice(pos, pos + 2) === "</") {
166
- pos += 2;
167
- let closeName = "";
168
- while (pos < xml2.length && /[a-zA-Z0-9_:-]/.test(xml2[pos])) {
169
- closeName += xml2[pos++];
170
- }
171
- skipWhitespace();
172
- if (xml2[pos] !== ">") throw new Error(`Expected > at position ${pos}`);
173
- pos++;
174
- if (closeName !== name) {
175
- throw new Error(`Mismatched tags: ${name} vs ${closeName}`);
176
- }
177
- break;
178
- }
179
- const child = parseNode();
180
- if (child) {
181
- children.push(child);
182
- } else if (xml2[pos] !== "<") {
183
- break;
184
- }
185
- }
186
- return { type: "element", name, attributes, children };
187
- };
188
- const root = parseNode();
189
- if (!root) throw new Error("Empty document");
190
- return root;
191
- }
192
- function queryXml(node, query) {
193
- const parts = query.split("/").filter((p) => p);
194
- if (parts.length === 0) return node;
195
- let current = node;
196
- for (let i = 0; i < parts.length; i++) {
197
- const part = parts[i];
198
- if (part.startsWith("@")) {
199
- const attrName = part.slice(1);
200
- if (Array.isArray(current)) {
201
- const attrs = [];
202
- for (const n of current) {
203
- if (typeof n !== "string" && n.type === "element" && n.attributes?.[attrName]) {
204
- attrs.push(n.attributes[attrName]);
205
- }
206
- }
207
- return attrs.length > 0 ? attrs : null;
208
- }
209
- if (current.type === "element" && current.attributes?.[attrName]) {
210
- return current.attributes[attrName];
211
- }
212
- return null;
213
- }
214
- const isRecursive = part === "";
215
- if (isRecursive) {
216
- i++;
217
- if (i >= parts.length) return null;
218
- const targetName = parts[i];
219
- const results = [];
220
- const findAll = (n) => {
221
- if (n.type === "element") {
222
- if (n.name === targetName) results.push(n);
223
- if (n.children) n.children.forEach(findAll);
224
- }
225
- };
226
- if (Array.isArray(current)) {
227
- current.forEach(findAll);
228
- } else {
229
- findAll(current);
230
- }
231
- current = results;
232
- continue;
233
- }
234
- if (Array.isArray(current)) {
235
- const results = [];
236
- for (const n of current) {
237
- if (n.type === "element" && n.children) {
238
- for (const child of n.children) {
239
- if (child.type === "element" && child.name === part) {
240
- results.push(child);
241
- }
242
- }
243
- }
244
- }
245
- current = results;
246
- } else {
247
- if (current.type !== "element" || !current.children) return null;
248
- const matches = current.children.filter(
249
- (c) => c.type === "element" && c.name === part
250
- );
251
- if (matches.length === 0) return null;
252
- if (matches.length === 1) {
253
- current = matches[0];
254
- } else {
255
- current = matches;
256
- }
257
- }
258
- }
259
- return current;
260
- }
261
- function xml() {
262
- try {
263
- const inputStr = Host.inputString();
264
- const input = JSON.parse(inputStr);
265
- const parsed = parseXml(input.xml);
266
- let result = parsed;
267
- let type = "document";
268
- if (input.query) {
269
- result = queryXml(parsed, input.query);
270
- if (result === null) {
271
- type = "element";
272
- } else if (typeof result === "string") {
273
- type = "text";
274
- } else if (Array.isArray(result)) {
275
- type = "array";
276
- } else {
277
- type = "element";
278
- }
279
- }
280
- const output = {
281
- result,
282
- type
283
- };
284
- Host.outputString(JSON.stringify(output));
285
- return 0;
286
- } catch (error) {
287
- const output = {
288
- result: null,
289
- type: "document",
290
- error: error instanceof Error ? error.message : String(error)
291
- };
292
- Host.outputString(JSON.stringify(output));
293
- return 1;
294
- }
295
- }