@ai-sdk-tool/rxml 0.1.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,2124 @@
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/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ RXMLCoercionError: () => RXMLCoercionError,
24
+ RXMLDuplicateStringTagError: () => RXMLDuplicateStringTagError,
25
+ RXMLParseError: () => RXMLParseError,
26
+ RXMLStreamError: () => RXMLStreamError,
27
+ RXMLStringifyError: () => RXMLStringifyError,
28
+ XMLTokenizer: () => XMLTokenizer,
29
+ XMLTransformStream: () => XMLTransformStream,
30
+ coerceDomBySchema: () => coerceDomBySchema,
31
+ countTagOccurrences: () => countTagOccurrences,
32
+ createXMLStream: () => createXMLStream,
33
+ domToObject: () => domToObject,
34
+ extractRawInner: () => extractRawInner,
35
+ filter: () => filter,
36
+ findElementByIdStream: () => findElementByIdStream,
37
+ findElementsByClassStream: () => findElementsByClassStream,
38
+ findFirstTopLevelRange: () => findFirstTopLevelRange,
39
+ getPropertySchema: () => getPropertySchema,
40
+ getStringTypedProperties: () => getStringTypedProperties,
41
+ parse: () => parse,
42
+ parseFromStream: () => parseFromStream,
43
+ parseNode: () => parseNode,
44
+ parseWithoutSchema: () => parseWithoutSchema,
45
+ processArrayContent: () => processArrayContent,
46
+ processIndexedTuple: () => processIndexedTuple,
47
+ processXMLStream: () => processXMLStream,
48
+ simplify: () => simplify,
49
+ stringify: () => stringify,
50
+ stringifyNode: () => stringifyNode,
51
+ stringifyNodes: () => stringifyNodes,
52
+ toContentString: () => toContentString
53
+ });
54
+ module.exports = __toCommonJS(index_exports);
55
+
56
+ // src/errors/types.ts
57
+ var RXMLParseError = class extends Error {
58
+ constructor(message, cause, line, column) {
59
+ super(message);
60
+ this.cause = cause;
61
+ this.line = line;
62
+ this.column = column;
63
+ this.name = "RXMLParseError";
64
+ }
65
+ };
66
+ var RXMLDuplicateStringTagError = class extends Error {
67
+ constructor(message) {
68
+ super(message);
69
+ this.name = "RXMLDuplicateStringTagError";
70
+ }
71
+ };
72
+ var RXMLCoercionError = class extends Error {
73
+ constructor(message, cause) {
74
+ super(message);
75
+ this.cause = cause;
76
+ this.name = "RXMLCoercionError";
77
+ }
78
+ };
79
+ var RXMLStringifyError = class extends Error {
80
+ constructor(message, cause) {
81
+ super(message);
82
+ this.cause = cause;
83
+ this.name = "RXMLStringifyError";
84
+ }
85
+ };
86
+ var RXMLStreamError = class extends Error {
87
+ constructor(message, cause) {
88
+ super(message);
89
+ this.cause = cause;
90
+ this.name = "RXMLStreamError";
91
+ }
92
+ };
93
+
94
+ // src/schema/base-coercion.ts
95
+ function unwrapJsonSchema(schema) {
96
+ if (!schema || typeof schema !== "object") return schema;
97
+ const s = schema;
98
+ if (s.jsonSchema && typeof s.jsonSchema === "object") {
99
+ return unwrapJsonSchema(s.jsonSchema);
100
+ }
101
+ return schema;
102
+ }
103
+ function getSchemaType(schema) {
104
+ const unwrapped = unwrapJsonSchema(schema);
105
+ if (!unwrapped || typeof unwrapped !== "object") return void 0;
106
+ const t = unwrapped.type;
107
+ if (typeof t === "string") return t;
108
+ if (Array.isArray(t)) {
109
+ const preferred = [
110
+ "object",
111
+ "array",
112
+ "boolean",
113
+ "number",
114
+ "integer",
115
+ "string"
116
+ ];
117
+ for (const p of preferred) if (t.includes(p)) return p;
118
+ }
119
+ const s = unwrapped;
120
+ if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
121
+ return "object";
122
+ }
123
+ if (s && typeof s === "object" && (s.items || s.prefixItems)) {
124
+ return "array";
125
+ }
126
+ return void 0;
127
+ }
128
+ function coerceBySchema(value, schema) {
129
+ const unwrapped = unwrapJsonSchema(schema);
130
+ if (!unwrapped || typeof unwrapped !== "object") {
131
+ if (typeof value === "string") {
132
+ const s = value.trim();
133
+ const lower = s.toLowerCase();
134
+ if (lower === "true") return true;
135
+ if (lower === "false") return false;
136
+ if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
137
+ const num = Number(s);
138
+ if (Number.isFinite(num)) return num;
139
+ }
140
+ if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
141
+ try {
142
+ const parsed = JSON.parse(s);
143
+ return coerceBySchema(parsed, void 0);
144
+ } catch (e) {
145
+ }
146
+ }
147
+ }
148
+ return value;
149
+ }
150
+ const schemaType = getSchemaType(unwrapped);
151
+ if (typeof value === "string") {
152
+ const s = value.trim();
153
+ if (schemaType === "object") {
154
+ try {
155
+ let normalized = s.replace(/'/g, '"');
156
+ normalized = normalized.replace(/^\{\s*\}$/s, "{}");
157
+ const obj = JSON.parse(normalized);
158
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
159
+ const props = unwrapped.properties;
160
+ const out = {};
161
+ for (const [k, v] of Object.entries(obj)) {
162
+ const propSchema = props ? props[k] : void 0;
163
+ out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
164
+ }
165
+ return out;
166
+ }
167
+ } catch (e) {
168
+ }
169
+ }
170
+ if (schemaType === "array") {
171
+ try {
172
+ const normalized = s.replace(/'/g, '"');
173
+ const arr = JSON.parse(normalized);
174
+ if (Array.isArray(arr)) {
175
+ const u = unwrapped;
176
+ const prefixItems = Array.isArray(
177
+ u.prefixItems
178
+ ) ? u.prefixItems : void 0;
179
+ const itemsSchema = u.items;
180
+ if (prefixItems && arr.length === prefixItems.length) {
181
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
182
+ }
183
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
184
+ }
185
+ } catch (e) {
186
+ const csv = s.includes("\n") ? s.split(/\n+/) : s.split(/,\s*/);
187
+ const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
188
+ const u = unwrapped;
189
+ const prefixItems = Array.isArray(
190
+ u.prefixItems
191
+ ) ? u.prefixItems : void 0;
192
+ const itemsSchema = u.items;
193
+ if (prefixItems && trimmed.length === prefixItems.length) {
194
+ return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
195
+ }
196
+ return trimmed.map((x) => coerceBySchema(x, itemsSchema));
197
+ }
198
+ }
199
+ }
200
+ if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
201
+ const out = {};
202
+ const props = unwrapped.properties;
203
+ for (const [k, v] of Object.entries(value)) {
204
+ const propSchema = props ? props[k] : void 0;
205
+ out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
206
+ }
207
+ return out;
208
+ }
209
+ if (schemaType === "array") {
210
+ const u = unwrapped;
211
+ const itemsSchema = u.items;
212
+ const prefixItems = Array.isArray(
213
+ u.prefixItems
214
+ ) ? u.prefixItems : void 0;
215
+ if (Array.isArray(value)) {
216
+ if (prefixItems && value.length === prefixItems.length) {
217
+ return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
218
+ }
219
+ return value.map((v) => coerceBySchema(v, itemsSchema));
220
+ }
221
+ if (value && typeof value === "object") {
222
+ const maybe = value;
223
+ if (Object.prototype.hasOwnProperty.call(maybe, "item")) {
224
+ const items = maybe.item;
225
+ const arr = Array.isArray(items) ? items : [items];
226
+ if (prefixItems && arr.length === prefixItems.length) {
227
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
228
+ }
229
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
230
+ }
231
+ const keys = Object.keys(maybe);
232
+ if (keys.length === 1) {
233
+ const singleKey = keys[0];
234
+ const singleValue = maybe[singleKey];
235
+ if (Array.isArray(singleValue)) {
236
+ const coercedArray = singleValue.map(
237
+ (v) => coerceBySchema(v, itemsSchema)
238
+ );
239
+ return coercedArray;
240
+ }
241
+ }
242
+ if (keys.length > 0 && keys.every((k) => /^\d+$/.test(k))) {
243
+ const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
244
+ if (prefixItems && arr.length === prefixItems.length) {
245
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
246
+ }
247
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
248
+ }
249
+ }
250
+ if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
251
+ if (prefixItems && prefixItems.length > 0) {
252
+ return [coerceBySchema(value, prefixItems[0])];
253
+ }
254
+ return [coerceBySchema(value, itemsSchema)];
255
+ }
256
+ }
257
+ if (typeof value === "string") {
258
+ const s = value.trim();
259
+ if (schemaType === "boolean") {
260
+ const lower = s.toLowerCase();
261
+ if (lower === "true") return true;
262
+ if (lower === "false") return false;
263
+ }
264
+ if (schemaType === "number" || schemaType === "integer") {
265
+ if (/^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(s)) {
266
+ const num = Number(s);
267
+ if (Number.isFinite(num)) return num;
268
+ }
269
+ }
270
+ }
271
+ return value;
272
+ }
273
+
274
+ // src/schema/coercion.ts
275
+ function getPropertySchema(toolSchema, key) {
276
+ const unwrapped = unwrapJsonSchema(toolSchema);
277
+ if (!unwrapped || typeof unwrapped !== "object") return void 0;
278
+ const u = unwrapped;
279
+ const props = u.properties;
280
+ if (props && Object.prototype.hasOwnProperty.call(props, key)) {
281
+ return props[key];
282
+ }
283
+ return void 0;
284
+ }
285
+ function domToObject(nodes, schema, textNodeName = "#text") {
286
+ const result = {};
287
+ for (const node of nodes) {
288
+ if (typeof node === "string") {
289
+ continue;
290
+ }
291
+ const { tagName, children, attributes } = node;
292
+ let value;
293
+ if (children.length === 0) {
294
+ value = "";
295
+ } else if (children.length === 1 && typeof children[0] === "string") {
296
+ value = children[0];
297
+ } else {
298
+ value = processComplexContent(
299
+ children,
300
+ getPropertySchema(schema, tagName),
301
+ textNodeName
302
+ );
303
+ }
304
+ if (Object.keys(attributes).length > 0) {
305
+ if (typeof value === "string") {
306
+ const result2 = { [textNodeName]: value };
307
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
308
+ result2[`@_${attrName}`] = attrValue;
309
+ }
310
+ value = result2;
311
+ } else if (value && typeof value === "object" && !Array.isArray(value)) {
312
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
313
+ value[`@_${attrName}`] = attrValue;
314
+ }
315
+ }
316
+ }
317
+ if (result[tagName]) {
318
+ if (!Array.isArray(result[tagName])) {
319
+ result[tagName] = [result[tagName]];
320
+ }
321
+ result[tagName].push(value);
322
+ } else {
323
+ result[tagName] = value;
324
+ }
325
+ }
326
+ return result;
327
+ }
328
+ function processComplexContent(children, schema, textNodeName) {
329
+ const textContent = [];
330
+ const elements = {};
331
+ for (const child of children) {
332
+ if (typeof child === "string") {
333
+ textContent.push(child);
334
+ } else {
335
+ let childValue;
336
+ if (child.children.length === 0) {
337
+ childValue = "";
338
+ } else if (child.children.length === 1 && typeof child.children[0] === "string") {
339
+ childValue = child.children[0];
340
+ } else {
341
+ childValue = processComplexContent(
342
+ child.children,
343
+ getPropertySchema(schema, child.tagName),
344
+ textNodeName
345
+ );
346
+ }
347
+ if (Object.keys(child.attributes).length > 0) {
348
+ if (typeof childValue === "string") {
349
+ const result = {
350
+ [textNodeName]: childValue
351
+ };
352
+ for (const [attrName, attrValue] of Object.entries(
353
+ child.attributes
354
+ )) {
355
+ result[`@_${attrName}`] = attrValue;
356
+ }
357
+ childValue = result;
358
+ } else if (childValue && typeof childValue === "object" && !Array.isArray(childValue)) {
359
+ for (const [attrName, attrValue] of Object.entries(
360
+ child.attributes
361
+ )) {
362
+ childValue[`@_${attrName}`] = attrValue;
363
+ }
364
+ }
365
+ }
366
+ if (elements[child.tagName]) {
367
+ if (!Array.isArray(elements[child.tagName])) {
368
+ elements[child.tagName] = [elements[child.tagName]];
369
+ }
370
+ elements[child.tagName].push(childValue);
371
+ } else {
372
+ elements[child.tagName] = childValue;
373
+ }
374
+ }
375
+ }
376
+ if (textContent.length > 0 && Object.keys(elements).length > 0) {
377
+ return {
378
+ [textNodeName]: textContent.join("").trim(),
379
+ ...elements
380
+ };
381
+ }
382
+ if (textContent.length > 0 && Object.keys(elements).length === 0) {
383
+ return textContent.join("").trim();
384
+ }
385
+ if (Object.keys(elements).length > 0) {
386
+ return elements;
387
+ }
388
+ return "";
389
+ }
390
+ function coerceDomBySchema(domObject, schema) {
391
+ try {
392
+ return coerceBySchema(domObject, schema);
393
+ } catch (error) {
394
+ throw new RXMLCoercionError("Failed to coerce DOM object by schema", error);
395
+ }
396
+ }
397
+ function getStringTypedProperties(schema) {
398
+ const set = /* @__PURE__ */ new Set();
399
+ const unwrapped = unwrapJsonSchema(schema);
400
+ if (unwrapped && typeof unwrapped === "object") {
401
+ const u = unwrapped;
402
+ const props = u.properties;
403
+ if (props && typeof props === "object") {
404
+ for (const key of Object.keys(props)) {
405
+ const propSchema = props[key];
406
+ const propType = getSchemaType(propSchema);
407
+ if (propType === "string") {
408
+ set.add(key);
409
+ }
410
+ }
411
+ }
412
+ }
413
+ return set;
414
+ }
415
+ function processArrayContent(value, schema, textNodeName) {
416
+ if (!Array.isArray(value)) return value;
417
+ const schemaType = getSchemaType(schema);
418
+ if (schemaType === "string") {
419
+ return value.map((item) => {
420
+ if (typeof item === "string") return item.trim();
421
+ if (item && typeof item === "object" && textNodeName in item) {
422
+ const textVal = item[textNodeName];
423
+ return typeof textVal === "string" ? textVal.trim() : String(textVal);
424
+ }
425
+ return String(item);
426
+ });
427
+ }
428
+ return value.map((item) => {
429
+ if (typeof item === "string") return item.trim();
430
+ if (item && typeof item === "object" && textNodeName in item) {
431
+ const textVal = item[textNodeName];
432
+ return typeof textVal === "string" ? textVal.trim() : textVal;
433
+ }
434
+ return item;
435
+ });
436
+ }
437
+ function processIndexedTuple(obj, textNodeName) {
438
+ const keys = Object.keys(obj);
439
+ const indices = keys.map((k) => parseInt(k, 10)).sort((a, b) => a - b);
440
+ const isValidTuple = indices[0] === 0 && indices.every((val, idx) => val === idx);
441
+ if (!isValidTuple) return [obj];
442
+ const sortedKeys = keys.sort((a, b) => parseInt(a, 10) - parseInt(b, 10));
443
+ return sortedKeys.map((key) => {
444
+ const item = obj[key];
445
+ if (item && typeof item === "object" && textNodeName in item) {
446
+ const textVal = item[textNodeName];
447
+ return typeof textVal === "string" ? textVal.trim() : textVal;
448
+ }
449
+ return typeof item === "string" ? item.trim() : item;
450
+ });
451
+ }
452
+
453
+ // src/core/types.ts
454
+ var CharCodes = {
455
+ OPEN_BRACKET: "<".charCodeAt(0),
456
+ CLOSE_BRACKET: ">".charCodeAt(0),
457
+ MINUS: "-".charCodeAt(0),
458
+ SLASH: "/".charCodeAt(0),
459
+ EXCLAMATION: "!".charCodeAt(0),
460
+ QUESTION: "?".charCodeAt(0),
461
+ SINGLE_QUOTE: "'".charCodeAt(0),
462
+ DOUBLE_QUOTE: '"'.charCodeAt(0),
463
+ OPEN_CORNER_BRACKET: "[".charCodeAt(0),
464
+ CLOSE_CORNER_BRACKET: "]".charCodeAt(0),
465
+ SPACE: " ".charCodeAt(0),
466
+ TAB: " ".charCodeAt(0),
467
+ NEWLINE: "\n".charCodeAt(0),
468
+ CARRIAGE_RETURN: "\r".charCodeAt(0)
469
+ };
470
+ var DEFAULT_NO_CHILD_NODES = [
471
+ "img",
472
+ "br",
473
+ "input",
474
+ "meta",
475
+ "link",
476
+ "hr",
477
+ "area",
478
+ "base",
479
+ "col",
480
+ "embed",
481
+ "param",
482
+ "source",
483
+ "track",
484
+ "wbr"
485
+ ];
486
+ var NAME_SPACER = "\r\n >/= ";
487
+
488
+ // src/utils/helpers.ts
489
+ function isNameStartChar(ch) {
490
+ return /[A-Za-z_:]/.test(ch);
491
+ }
492
+ function isNameChar(ch) {
493
+ return /[A-Za-z0-9_.:-]/.test(ch);
494
+ }
495
+ function skipQuoted(s, i) {
496
+ const quote = s[i];
497
+ i++;
498
+ while (i < s.length) {
499
+ const ch = s[i];
500
+ if (ch === "\\") {
501
+ i += 2;
502
+ continue;
503
+ }
504
+ if (ch === quote) return i + 1;
505
+ i++;
506
+ }
507
+ return i;
508
+ }
509
+ function parseName(s, pos) {
510
+ const start = pos;
511
+ while (NAME_SPACER.indexOf(s[pos]) === -1 && s[pos]) {
512
+ pos++;
513
+ }
514
+ return { name: s.slice(start, pos), newPos: pos };
515
+ }
516
+ function parseString(s, pos) {
517
+ const startChar = s[pos];
518
+ const startPos = pos + 1;
519
+ const endPos = s.indexOf(startChar, startPos);
520
+ if (endPos === -1) {
521
+ const tagEnd = s.indexOf(">", startPos);
522
+ if (tagEnd !== -1) {
523
+ return { value: s.slice(startPos, tagEnd), newPos: tagEnd };
524
+ }
525
+ return { value: s.slice(startPos), newPos: s.length };
526
+ }
527
+ return { value: s.slice(startPos, endPos), newPos: endPos + 1 };
528
+ }
529
+ function getLineColumn(s, pos) {
530
+ let line = 1;
531
+ let column = 1;
532
+ for (let i = 0; i < pos && i < s.length; i++) {
533
+ if (s[i] === "\n") {
534
+ line++;
535
+ column = 1;
536
+ } else {
537
+ column++;
538
+ }
539
+ }
540
+ return { line, column };
541
+ }
542
+ function escapeXml(text) {
543
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
544
+ }
545
+ function escapeXmlMinimalText(text) {
546
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/]]>/g, "]]&gt;");
547
+ }
548
+ function escapeXmlMinimalAttr(value, wrapper = '"') {
549
+ let escaped = value.replace(/&/g, "&amp;").replace(/</g, "&lt;");
550
+ if (wrapper === '"') {
551
+ escaped = escaped.replace(/"/g, "&quot;");
552
+ } else {
553
+ escaped = escaped.replace(/'/g, "&apos;");
554
+ }
555
+ return escaped;
556
+ }
557
+
558
+ // src/schema/extraction.ts
559
+ function extractRawInner(xmlContent, tagName) {
560
+ const len = xmlContent.length;
561
+ const target = tagName;
562
+ let bestStart = -1;
563
+ let bestEnd = -1;
564
+ let bestDepth = Number.POSITIVE_INFINITY;
565
+ let i = 0;
566
+ let depth = 0;
567
+ while (i < len) {
568
+ const lt = xmlContent.indexOf("<", i);
569
+ if (lt === -1) return void 0;
570
+ i = lt + 1;
571
+ if (i >= len) return void 0;
572
+ const ch = xmlContent[i];
573
+ if (ch === "!") {
574
+ if (xmlContent.startsWith("!--", i + 1)) {
575
+ const close = xmlContent.indexOf("-->", i + 4);
576
+ i = close === -1 ? len : close + 3;
577
+ continue;
578
+ }
579
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
580
+ const close = xmlContent.indexOf("]]>", i + 9);
581
+ i = close === -1 ? len : close + 3;
582
+ continue;
583
+ }
584
+ const gt = xmlContent.indexOf(">", i + 1);
585
+ i = gt === -1 ? len : gt + 1;
586
+ continue;
587
+ } else if (ch === "?") {
588
+ const close = xmlContent.indexOf("?>", i + 1);
589
+ i = close === -1 ? len : close + 2;
590
+ continue;
591
+ } else if (ch === "/") {
592
+ const gt = xmlContent.indexOf(">", i + 1);
593
+ i = gt === -1 ? len : gt + 1;
594
+ depth = Math.max(0, depth - 1);
595
+ continue;
596
+ } else {
597
+ let j = i;
598
+ if (j < len && isNameStartChar(xmlContent[j])) {
599
+ j++;
600
+ while (j < len && isNameChar(xmlContent[j])) j++;
601
+ }
602
+ const name = xmlContent.slice(i, j);
603
+ let k = j;
604
+ let isSelfClosing = false;
605
+ while (k < len) {
606
+ const c = xmlContent[k];
607
+ if (c === '"' || c === "'") {
608
+ k = skipQuoted(xmlContent, k);
609
+ continue;
610
+ }
611
+ if (c === ">") break;
612
+ if (c === "/" && xmlContent[k + 1] === ">") {
613
+ isSelfClosing = true;
614
+ k++;
615
+ break;
616
+ }
617
+ k++;
618
+ }
619
+ const tagEnd = k;
620
+ if (name === target) {
621
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
622
+ if (isSelfClosing) {
623
+ if (depth < bestDepth) {
624
+ bestStart = contentStart;
625
+ bestEnd = contentStart;
626
+ bestDepth = depth;
627
+ }
628
+ } else {
629
+ let pos = contentStart;
630
+ let sameDepth = 1;
631
+ while (pos < len) {
632
+ const nextLt = xmlContent.indexOf("<", pos);
633
+ if (nextLt === -1) break;
634
+ const nx = nextLt + 1;
635
+ if (nx >= len) break;
636
+ const h = xmlContent[nx];
637
+ if (h === "!") {
638
+ if (xmlContent.startsWith("!--", nx + 1)) {
639
+ const close = xmlContent.indexOf("-->", nx + 4);
640
+ pos = close === -1 ? len : close + 3;
641
+ continue;
642
+ }
643
+ if (xmlContent.startsWith("![CDATA[", nx + 1)) {
644
+ const close = xmlContent.indexOf("]]>", nx + 9);
645
+ pos = close === -1 ? len : close + 3;
646
+ continue;
647
+ }
648
+ const gt2 = xmlContent.indexOf(">", nx + 1);
649
+ pos = gt2 === -1 ? len : gt2 + 1;
650
+ continue;
651
+ } else if (h === "?") {
652
+ const close = xmlContent.indexOf("?>", nx + 1);
653
+ pos = close === -1 ? len : close + 2;
654
+ continue;
655
+ } else if (h === "/") {
656
+ let t = nx + 1;
657
+ if (t < len && isNameStartChar(xmlContent[t])) {
658
+ t++;
659
+ while (t < len && isNameChar(xmlContent[t])) t++;
660
+ }
661
+ const endName = xmlContent.slice(nx + 1, t);
662
+ const gt2 = xmlContent.indexOf(">", t);
663
+ if (endName === target) {
664
+ sameDepth--;
665
+ if (sameDepth === 0) {
666
+ if (depth < bestDepth) {
667
+ bestStart = contentStart;
668
+ bestEnd = nextLt;
669
+ bestDepth = depth;
670
+ }
671
+ break;
672
+ }
673
+ }
674
+ pos = gt2 === -1 ? len : gt2 + 1;
675
+ continue;
676
+ } else {
677
+ let t = nx;
678
+ if (t < len && isNameStartChar(xmlContent[t])) {
679
+ t++;
680
+ while (t < len && isNameChar(xmlContent[t])) t++;
681
+ }
682
+ let u = t;
683
+ let isSelfClosingNested = false;
684
+ while (u < len) {
685
+ const cu = xmlContent[u];
686
+ if (cu === '"' || cu === "'") {
687
+ u = skipQuoted(xmlContent, u);
688
+ continue;
689
+ }
690
+ if (cu === ">") break;
691
+ if (cu === "/" && xmlContent[u + 1] === ">") {
692
+ isSelfClosingNested = true;
693
+ u++;
694
+ break;
695
+ }
696
+ u++;
697
+ }
698
+ const startName = xmlContent.slice(nx, t);
699
+ if (startName === target && !isSelfClosingNested) {
700
+ sameDepth++;
701
+ }
702
+ pos = xmlContent[u] === ">" ? u + 1 : u + 1;
703
+ continue;
704
+ }
705
+ }
706
+ }
707
+ }
708
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
709
+ depth += isSelfClosing ? 0 : 1;
710
+ continue;
711
+ }
712
+ }
713
+ if (bestStart !== -1) {
714
+ return xmlContent.slice(bestStart, bestEnd);
715
+ }
716
+ return void 0;
717
+ }
718
+ function findFirstTopLevelRange(xmlContent, tagName) {
719
+ const len = xmlContent.length;
720
+ const target = tagName;
721
+ let i = 0;
722
+ let depth = 0;
723
+ while (i < len) {
724
+ const lt = xmlContent.indexOf("<", i);
725
+ if (lt === -1) return void 0;
726
+ i = lt + 1;
727
+ if (i >= len) return void 0;
728
+ const ch = xmlContent[i];
729
+ if (ch === "!") {
730
+ if (xmlContent.startsWith("!--", i + 1)) {
731
+ const close = xmlContent.indexOf("-->", i + 4);
732
+ i = close === -1 ? len : close + 3;
733
+ continue;
734
+ }
735
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
736
+ const close = xmlContent.indexOf("]]>", i + 9);
737
+ i = close === -1 ? len : close + 3;
738
+ continue;
739
+ }
740
+ const gt = xmlContent.indexOf(">", i + 1);
741
+ i = gt === -1 ? len : gt + 1;
742
+ continue;
743
+ } else if (ch === "?") {
744
+ const close = xmlContent.indexOf("?>", i + 1);
745
+ i = close === -1 ? len : close + 2;
746
+ continue;
747
+ } else if (ch === "/") {
748
+ const gt = xmlContent.indexOf(">", i + 1);
749
+ i = gt === -1 ? len : gt + 1;
750
+ depth = Math.max(0, depth - 1);
751
+ continue;
752
+ } else {
753
+ let j = i;
754
+ if (j < len && isNameStartChar(xmlContent[j])) {
755
+ j++;
756
+ while (j < len && isNameChar(xmlContent[j])) j++;
757
+ }
758
+ const name = xmlContent.slice(i, j);
759
+ let k = j;
760
+ let isSelfClosing = false;
761
+ while (k < len) {
762
+ const c = xmlContent[k];
763
+ if (c === '"' || c === "'") {
764
+ k = skipQuoted(xmlContent, k);
765
+ continue;
766
+ }
767
+ if (c === ">") break;
768
+ if (c === "/" && xmlContent[k + 1] === ">") {
769
+ isSelfClosing = true;
770
+ k++;
771
+ break;
772
+ }
773
+ k++;
774
+ }
775
+ const tagEnd = k;
776
+ if (depth === 0 && name === target) {
777
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
778
+ if (isSelfClosing) return { start: contentStart, end: contentStart };
779
+ let pos = contentStart;
780
+ let sameDepth = 1;
781
+ while (pos < len) {
782
+ const nextLt = xmlContent.indexOf("<", pos);
783
+ if (nextLt === -1) break;
784
+ const nx = nextLt + 1;
785
+ if (nx >= len) break;
786
+ const h = xmlContent[nx];
787
+ if (h === "!") {
788
+ if (xmlContent.startsWith("!--", nx + 1)) {
789
+ const close = xmlContent.indexOf("-->", nx + 4);
790
+ pos = close === -1 ? len : close + 3;
791
+ continue;
792
+ }
793
+ if (xmlContent.startsWith("![CDATA[", nx + 1)) {
794
+ const close = xmlContent.indexOf("]]>", nx + 9);
795
+ pos = close === -1 ? len : close + 3;
796
+ continue;
797
+ }
798
+ const gt2 = xmlContent.indexOf(">", nx + 1);
799
+ pos = gt2 === -1 ? len : gt2 + 1;
800
+ continue;
801
+ } else if (h === "?") {
802
+ const close = xmlContent.indexOf("?>", nx + 1);
803
+ pos = close === -1 ? len : close + 2;
804
+ continue;
805
+ } else if (h === "/") {
806
+ let t = nx + 1;
807
+ if (t < len && isNameStartChar(xmlContent[t])) {
808
+ t++;
809
+ while (t < len && isNameChar(xmlContent[t])) t++;
810
+ }
811
+ const endName = xmlContent.slice(nx + 1, t);
812
+ const gt2 = xmlContent.indexOf(">", t);
813
+ if (endName === target) {
814
+ sameDepth--;
815
+ if (sameDepth === 0) {
816
+ return { start: contentStart, end: nextLt };
817
+ }
818
+ }
819
+ pos = gt2 === -1 ? len : gt2 + 1;
820
+ continue;
821
+ } else {
822
+ let t = nx;
823
+ if (t < len && isNameStartChar(xmlContent[t])) {
824
+ t++;
825
+ while (t < len && isNameChar(xmlContent[t])) t++;
826
+ }
827
+ const startName = xmlContent.slice(nx, t);
828
+ let u = t;
829
+ let isSelfClosingNested = false;
830
+ while (u < len) {
831
+ const cu = xmlContent[u];
832
+ if (cu === '"' || cu === "'") {
833
+ u = skipQuoted(xmlContent, u);
834
+ continue;
835
+ }
836
+ if (cu === ">") break;
837
+ if (cu === "/" && xmlContent[u + 1] === ">") {
838
+ isSelfClosingNested = true;
839
+ u++;
840
+ break;
841
+ }
842
+ u++;
843
+ }
844
+ if (startName === target && !isSelfClosingNested) {
845
+ sameDepth++;
846
+ }
847
+ pos = xmlContent[u] === ">" ? u + 1 : u + 1;
848
+ continue;
849
+ }
850
+ }
851
+ return void 0;
852
+ }
853
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
854
+ depth += isSelfClosing ? 0 : 1;
855
+ continue;
856
+ }
857
+ }
858
+ return void 0;
859
+ }
860
+ function countTagOccurrences(xmlContent, tagName, excludeRanges, shouldSkipFirst = true) {
861
+ const len = xmlContent.length;
862
+ const target = tagName;
863
+ let i = 0;
864
+ let count = 0;
865
+ let skipFirstLocal = shouldSkipFirst;
866
+ const isExcluded = (pos) => {
867
+ if (!excludeRanges || excludeRanges.length === 0) return false;
868
+ for (const r of excludeRanges) {
869
+ if (pos >= r.start && pos < r.end) return true;
870
+ }
871
+ return false;
872
+ };
873
+ while (i < len) {
874
+ const lt = xmlContent.indexOf("<", i);
875
+ if (lt === -1) break;
876
+ i = lt + 1;
877
+ if (i >= len) break;
878
+ const ch = xmlContent[i];
879
+ if (ch === "!") {
880
+ if (xmlContent.startsWith("!--", i + 1)) {
881
+ const close = xmlContent.indexOf("-->", i + 4);
882
+ i = close === -1 ? len : close + 3;
883
+ continue;
884
+ }
885
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
886
+ const close = xmlContent.indexOf("]]>", i + 9);
887
+ i = close === -1 ? len : close + 3;
888
+ continue;
889
+ }
890
+ const gt = xmlContent.indexOf(">", i + 1);
891
+ i = gt === -1 ? len : gt + 1;
892
+ continue;
893
+ } else if (ch === "?") {
894
+ const close = xmlContent.indexOf("?>", i + 1);
895
+ i = close === -1 ? len : close + 2;
896
+ continue;
897
+ } else if (ch === "/") {
898
+ const gt = xmlContent.indexOf(">", i + 1);
899
+ i = gt === -1 ? len : gt + 1;
900
+ continue;
901
+ } else {
902
+ let j = i;
903
+ if (j < len && isNameStartChar(xmlContent[j])) {
904
+ j++;
905
+ while (j < len && isNameChar(xmlContent[j])) j++;
906
+ }
907
+ const name = xmlContent.slice(i, j);
908
+ let k = j;
909
+ while (k < len) {
910
+ const c = xmlContent[k];
911
+ if (c === '"' || c === "'") {
912
+ k = skipQuoted(xmlContent, k);
913
+ continue;
914
+ }
915
+ if (c === ">") break;
916
+ if (c === "/" && xmlContent[k + 1] === ">") {
917
+ k++;
918
+ break;
919
+ }
920
+ k++;
921
+ }
922
+ if (name === target && !isExcluded(lt)) {
923
+ if (skipFirstLocal) {
924
+ skipFirstLocal = false;
925
+ } else {
926
+ count++;
927
+ }
928
+ }
929
+ i = k + 1;
930
+ continue;
931
+ }
932
+ }
933
+ return count;
934
+ }
935
+
936
+ // src/core/tokenizer.ts
937
+ var XMLTokenizer = class {
938
+ constructor(xmlString, options = {}) {
939
+ this.pos = 0;
940
+ this.xmlString = xmlString;
941
+ this.options = {
942
+ keepComments: false,
943
+ keepWhitespace: false,
944
+ noChildNodes: DEFAULT_NO_CHILD_NODES.slice(),
945
+ textNodeName: "#text",
946
+ throwOnDuplicateStringTags: true,
947
+ ...options
948
+ };
949
+ this.pos = options.pos || 0;
950
+ }
951
+ /**
952
+ * Parse XML children recursively
953
+ */
954
+ parseChildren(tagName) {
955
+ const children = [];
956
+ let consumedToEnd = false;
957
+ while (this.xmlString[this.pos]) {
958
+ if (this.xmlString.charCodeAt(this.pos) === CharCodes.OPEN_BRACKET) {
959
+ if (this.xmlString.charCodeAt(this.pos + 1) === CharCodes.SLASH) {
960
+ const closeStart = this.pos + 2;
961
+ this.pos = this.xmlString.indexOf(">", this.pos);
962
+ const closeTag = this.xmlString.substring(closeStart, this.pos);
963
+ if (tagName && closeTag.trim() !== tagName) {
964
+ const { line, column } = getLineColumn(this.xmlString, this.pos);
965
+ throw new RXMLParseError(
966
+ `Unexpected close tag at line ${line}, column ${column}. Expected </${tagName}>, found </${closeTag}>`,
967
+ void 0,
968
+ line,
969
+ column
970
+ );
971
+ }
972
+ if (this.pos !== -1) this.pos += 1;
973
+ return children;
974
+ } else if (this.xmlString.charCodeAt(this.pos + 1) === CharCodes.EXCLAMATION) {
975
+ const prevPos = this.pos;
976
+ this.handleSpecialContent(children);
977
+ if (this.pos >= this.xmlString.length && prevPos < this.xmlString.length) {
978
+ consumedToEnd = true;
979
+ }
980
+ } else {
981
+ const node = this.parseNode();
982
+ children.push(node);
983
+ if (node.tagName[0] === "?") {
984
+ children.push(...node.children);
985
+ node.children = [];
986
+ }
987
+ }
988
+ } else {
989
+ const text = this.parseText();
990
+ if (this.options.keepWhitespace) {
991
+ if (text.length > 0) {
992
+ children.push(text);
993
+ }
994
+ } else {
995
+ const trimmed = text.trim();
996
+ if (trimmed.length > 0) {
997
+ children.push(trimmed);
998
+ }
999
+ }
1000
+ this.pos++;
1001
+ }
1002
+ }
1003
+ if (tagName && this.pos >= this.xmlString.length && !consumedToEnd) {
1004
+ const { line, column } = getLineColumn(this.xmlString, this.pos - 1);
1005
+ throw new RXMLParseError(
1006
+ `Unclosed tag at line ${line}, column ${column}. Expected closing tag </${tagName}>`,
1007
+ void 0,
1008
+ line,
1009
+ column
1010
+ );
1011
+ }
1012
+ return children;
1013
+ }
1014
+ /**
1015
+ * Parse a single XML node
1016
+ */
1017
+ parseNode() {
1018
+ var _a;
1019
+ this.pos++;
1020
+ const { name: tagName, newPos } = parseName(this.xmlString, this.pos);
1021
+ this.pos = newPos;
1022
+ const attributes = {};
1023
+ let children = [];
1024
+ while (this.xmlString.charCodeAt(this.pos) !== CharCodes.CLOSE_BRACKET && this.xmlString[this.pos]) {
1025
+ const c = this.xmlString.charCodeAt(this.pos);
1026
+ if (c === CharCodes.SPACE || c === CharCodes.TAB || c === CharCodes.NEWLINE || c === CharCodes.CARRIAGE_RETURN) {
1027
+ this.pos++;
1028
+ continue;
1029
+ }
1030
+ if (c > 64 && c < 91 || c > 96 && c < 123) {
1031
+ const { name: attrName, newPos: nameEnd } = parseName(
1032
+ this.xmlString,
1033
+ this.pos
1034
+ );
1035
+ this.pos = nameEnd;
1036
+ while (this.pos < this.xmlString.length && (this.xmlString.charCodeAt(this.pos) === CharCodes.SPACE || this.xmlString.charCodeAt(this.pos) === CharCodes.TAB || this.xmlString.charCodeAt(this.pos) === CharCodes.NEWLINE || this.xmlString.charCodeAt(this.pos) === CharCodes.CARRIAGE_RETURN)) {
1037
+ this.pos++;
1038
+ }
1039
+ let value = null;
1040
+ if (this.pos < this.xmlString.length && this.xmlString[this.pos] === "=") {
1041
+ this.pos++;
1042
+ while (this.pos < this.xmlString.length && (this.xmlString.charCodeAt(this.pos) === CharCodes.SPACE || this.xmlString.charCodeAt(this.pos) === CharCodes.TAB || this.xmlString.charCodeAt(this.pos) === CharCodes.NEWLINE || this.xmlString.charCodeAt(this.pos) === CharCodes.CARRIAGE_RETURN)) {
1043
+ this.pos++;
1044
+ }
1045
+ const code = this.xmlString.charCodeAt(this.pos);
1046
+ if (code === CharCodes.SINGLE_QUOTE || code === CharCodes.DOUBLE_QUOTE) {
1047
+ const { value: parsedValue, newPos: valueEnd } = parseString(
1048
+ this.xmlString,
1049
+ this.pos
1050
+ );
1051
+ value = parsedValue;
1052
+ this.pos = valueEnd;
1053
+ }
1054
+ }
1055
+ attributes[attrName] = value;
1056
+ } else {
1057
+ this.pos++;
1058
+ }
1059
+ }
1060
+ const isSelfClosing = this.xmlString.charCodeAt(this.pos - 1) === CharCodes.SLASH || tagName[0] === "?" && this.xmlString.charCodeAt(this.pos - 1) === CharCodes.QUESTION;
1061
+ if (!isSelfClosing) {
1062
+ if (tagName === "script") {
1063
+ const start = this.pos + 1;
1064
+ this.pos = this.xmlString.indexOf("</script>", this.pos);
1065
+ if (this.pos === -1) {
1066
+ children = [this.xmlString.slice(start)];
1067
+ this.pos = this.xmlString.length;
1068
+ } else {
1069
+ children = [this.xmlString.slice(start, this.pos)];
1070
+ this.pos += 9;
1071
+ }
1072
+ } else if (tagName === "style") {
1073
+ const start = this.pos + 1;
1074
+ this.pos = this.xmlString.indexOf("</style>", this.pos);
1075
+ if (this.pos === -1) {
1076
+ children = [this.xmlString.slice(start)];
1077
+ this.pos = this.xmlString.length;
1078
+ } else {
1079
+ children = [this.xmlString.slice(start, this.pos)];
1080
+ this.pos += 8;
1081
+ }
1082
+ } else if (((_a = this.options.noChildNodes) == null ? void 0 : _a.indexOf(tagName)) === -1) {
1083
+ this.pos++;
1084
+ children = this.parseChildren(tagName);
1085
+ } else {
1086
+ this.pos++;
1087
+ if (DEFAULT_NO_CHILD_NODES.includes(tagName)) {
1088
+ } else {
1089
+ const closingTag = `</${tagName}>`;
1090
+ const closingPos = this.xmlString.indexOf(closingTag, this.pos);
1091
+ if (closingPos !== -1) {
1092
+ this.pos = closingPos + closingTag.length;
1093
+ }
1094
+ }
1095
+ }
1096
+ } else {
1097
+ this.pos++;
1098
+ }
1099
+ return { tagName, attributes, children };
1100
+ }
1101
+ /**
1102
+ * Parse text content until next tag
1103
+ */
1104
+ parseText() {
1105
+ const start = this.pos;
1106
+ this.pos = this.xmlString.indexOf("<", this.pos) - 1;
1107
+ if (this.pos === -2) {
1108
+ this.pos = this.xmlString.length;
1109
+ }
1110
+ return this.xmlString.slice(start, this.pos + 1);
1111
+ }
1112
+ /**
1113
+ * Handle comments, CDATA, and DOCTYPE declarations
1114
+ */
1115
+ handleSpecialContent(children) {
1116
+ if (this.xmlString.charCodeAt(this.pos + 2) === CharCodes.MINUS) {
1117
+ this.handleComment(children);
1118
+ } else if (this.xmlString.charCodeAt(this.pos + 2) === CharCodes.OPEN_CORNER_BRACKET && this.xmlString.charCodeAt(this.pos + 8) === CharCodes.OPEN_CORNER_BRACKET && this.xmlString.substr(this.pos + 3, 5).toLowerCase() === "cdata") {
1119
+ this.handleCData(children);
1120
+ } else {
1121
+ this.handleDoctype(children);
1122
+ }
1123
+ }
1124
+ /**
1125
+ * Handle XML comments
1126
+ */
1127
+ handleComment(children) {
1128
+ const startCommentPos = this.pos;
1129
+ while (this.pos !== -1 && !(this.xmlString.charCodeAt(this.pos) === CharCodes.CLOSE_BRACKET && this.xmlString.charCodeAt(this.pos - 1) === CharCodes.MINUS && this.xmlString.charCodeAt(this.pos - 2) === CharCodes.MINUS)) {
1130
+ this.pos = this.xmlString.indexOf(">", this.pos + 1);
1131
+ }
1132
+ if (this.pos === -1) {
1133
+ this.pos = this.xmlString.length;
1134
+ }
1135
+ if (this.options.keepComments) {
1136
+ children.push(this.xmlString.substring(startCommentPos, this.pos + 1));
1137
+ }
1138
+ this.pos++;
1139
+ }
1140
+ /**
1141
+ * Handle CDATA sections
1142
+ */
1143
+ handleCData(children) {
1144
+ const cdataEndIndex = this.xmlString.indexOf("]]>", this.pos);
1145
+ if (cdataEndIndex === -1) {
1146
+ children.push(this.xmlString.substr(this.pos + 9));
1147
+ this.pos = this.xmlString.length;
1148
+ } else {
1149
+ children.push(this.xmlString.substring(this.pos + 9, cdataEndIndex));
1150
+ this.pos = cdataEndIndex + 3;
1151
+ }
1152
+ }
1153
+ /**
1154
+ * Handle DOCTYPE declarations
1155
+ */
1156
+ handleDoctype(children) {
1157
+ const startDoctype = this.pos + 1;
1158
+ this.pos += 2;
1159
+ let encapsulated = false;
1160
+ while ((this.xmlString.charCodeAt(this.pos) !== CharCodes.CLOSE_BRACKET || encapsulated) && this.xmlString[this.pos]) {
1161
+ if (this.xmlString.charCodeAt(this.pos) === CharCodes.OPEN_CORNER_BRACKET) {
1162
+ encapsulated = true;
1163
+ } else if (encapsulated && this.xmlString.charCodeAt(this.pos) === CharCodes.CLOSE_CORNER_BRACKET) {
1164
+ encapsulated = false;
1165
+ }
1166
+ this.pos++;
1167
+ }
1168
+ children.push(this.xmlString.substring(startDoctype, this.pos));
1169
+ this.pos++;
1170
+ }
1171
+ /**
1172
+ * Get current position
1173
+ */
1174
+ getPosition() {
1175
+ return this.pos;
1176
+ }
1177
+ /**
1178
+ * Set position
1179
+ */
1180
+ setPosition(pos) {
1181
+ this.pos = pos;
1182
+ }
1183
+ };
1184
+
1185
+ // src/core/parser.ts
1186
+ function parse(xmlInner, schema, options = {}) {
1187
+ var _a, _b, _c;
1188
+ const textNodeName = (_a = options.textNodeName) != null ? _a : "#text";
1189
+ const throwDup = (_b = options.throwOnDuplicateStringTags) != null ? _b : true;
1190
+ let actualXmlInner = xmlInner.trim();
1191
+ if (actualXmlInner.startsWith("<") && actualXmlInner.endsWith(">")) {
1192
+ const s = actualXmlInner;
1193
+ let i = 0;
1194
+ let rootStart = -1;
1195
+ let rootName = "";
1196
+ while (i < s.length) {
1197
+ const lt = s.indexOf("<", i);
1198
+ if (lt === -1) break;
1199
+ const next = s[lt + 1];
1200
+ if (next === "?") {
1201
+ const end = s.indexOf("?>", lt + 2);
1202
+ i = end === -1 ? s.length : end + 2;
1203
+ continue;
1204
+ }
1205
+ if (next === "!") {
1206
+ if (s.startsWith("!--", lt + 2)) {
1207
+ const end2 = s.indexOf("-->", lt + 5);
1208
+ i = end2 === -1 ? s.length : end2 + 3;
1209
+ continue;
1210
+ }
1211
+ if (s.startsWith("![CDATA[", lt + 2)) {
1212
+ const end2 = s.indexOf("]]>", lt + 9);
1213
+ i = end2 === -1 ? s.length : end2 + 3;
1214
+ continue;
1215
+ }
1216
+ const end = s.indexOf(">", lt + 2);
1217
+ i = end === -1 ? s.length : end + 1;
1218
+ continue;
1219
+ }
1220
+ if (next === "/") {
1221
+ break;
1222
+ }
1223
+ let j = lt + 1;
1224
+ while (j < s.length && s[j] !== " " && s[j] !== "\n" && s[j] !== "\r" && s[j] !== " " && s[j] !== "/" && s[j] !== ">") {
1225
+ j++;
1226
+ }
1227
+ rootStart = lt;
1228
+ rootName = s.slice(lt + 1, j);
1229
+ break;
1230
+ }
1231
+ if (rootStart === 0 && rootName) {
1232
+ const range = findFirstTopLevelRange(s, rootName);
1233
+ if (range) {
1234
+ let fullEnd = range.end + `</${rootName}>`.length;
1235
+ const closeHead = s.indexOf(`</${rootName}`, range.end);
1236
+ if (closeHead === range.end) {
1237
+ let p = closeHead + 2 + rootName.length;
1238
+ while (p < s.length && /\s/.test(s[p])) p++;
1239
+ if (s[p] === ">") fullEnd = p + 1;
1240
+ }
1241
+ if (fullEnd === s.length) {
1242
+ const unwrapped = unwrapJsonSchema(schema);
1243
+ const schemaProps = unwrapped && typeof unwrapped === "object" ? unwrapped.properties : void 0;
1244
+ if (schemaProps && !Object.prototype.hasOwnProperty.call(schemaProps, rootName)) {
1245
+ actualXmlInner = s.slice(range.start, range.end);
1246
+ }
1247
+ }
1248
+ }
1249
+ }
1250
+ }
1251
+ const stringTypedProps = getStringTypedProperties(schema);
1252
+ const duplicateKeys = /* @__PURE__ */ new Set();
1253
+ for (const key of stringTypedProps) {
1254
+ const excludeRanges = [];
1255
+ for (const other of stringTypedProps) {
1256
+ if (other === key) continue;
1257
+ const range = findFirstTopLevelRange(actualXmlInner, other);
1258
+ if (range) excludeRanges.push(range);
1259
+ }
1260
+ const occurrences = countTagOccurrences(
1261
+ actualXmlInner,
1262
+ key,
1263
+ excludeRanges,
1264
+ true
1265
+ );
1266
+ if (occurrences > 0 && throwDup) {
1267
+ throw new RXMLDuplicateStringTagError(
1268
+ `Duplicate string tags for <${key}> detected`
1269
+ );
1270
+ }
1271
+ if (occurrences > 0 && !throwDup) {
1272
+ duplicateKeys.add(key);
1273
+ if (options.onError) {
1274
+ options.onError(
1275
+ `RXML: Duplicate string tags for <${key}> detected; using first occurrence.`,
1276
+ { tag: key, occurrences }
1277
+ );
1278
+ }
1279
+ }
1280
+ }
1281
+ let xmlInnerForParsing = actualXmlInner;
1282
+ const originalContentMap = /* @__PURE__ */ new Map();
1283
+ try {
1284
+ const ranges = [];
1285
+ for (const key of stringTypedProps) {
1286
+ const r = findFirstTopLevelRange(actualXmlInner, key);
1287
+ if (r && r.end > r.start) ranges.push({ ...r, key });
1288
+ }
1289
+ if (ranges.length > 0) {
1290
+ const sorted = [...ranges].sort((a, b) => a.start - b.start);
1291
+ const filtered = [];
1292
+ for (const r of sorted) {
1293
+ const last = filtered[filtered.length - 1];
1294
+ if (last && r.start >= last.start && r.end <= last.end) {
1295
+ continue;
1296
+ }
1297
+ filtered.push(r);
1298
+ }
1299
+ if (filtered.length > 0) {
1300
+ filtered.sort((a, b) => a.start - b.start);
1301
+ let rebuilt = "";
1302
+ let cursor = 0;
1303
+ for (const r of filtered) {
1304
+ if (cursor < r.start)
1305
+ rebuilt += actualXmlInner.slice(cursor, r.start);
1306
+ const placeholder = `__RXML_PLACEHOLDER_${r.key}__`;
1307
+ const originalContent = actualXmlInner.slice(r.start, r.end);
1308
+ originalContentMap.set(placeholder, originalContent);
1309
+ rebuilt += placeholder;
1310
+ cursor = r.end;
1311
+ }
1312
+ if (cursor < actualXmlInner.length)
1313
+ rebuilt += actualXmlInner.slice(cursor);
1314
+ xmlInnerForParsing = rebuilt;
1315
+ }
1316
+ }
1317
+ } catch (error) {
1318
+ if (options.onError) {
1319
+ options.onError(
1320
+ "RXML: Failed to replace string placeholders, falling back to original XML.",
1321
+ { error }
1322
+ );
1323
+ }
1324
+ xmlInnerForParsing = actualXmlInner;
1325
+ }
1326
+ let parsedNodes;
1327
+ try {
1328
+ const wrappedXml = `<root>${xmlInnerForParsing}</root>`;
1329
+ const tokenizer = new XMLTokenizer(wrappedXml, {
1330
+ ...options,
1331
+ textNodeName
1332
+ });
1333
+ const rootNode = tokenizer.parseNode();
1334
+ parsedNodes = rootNode.children;
1335
+ } catch (cause) {
1336
+ throw new RXMLParseError("Failed to parse XML", cause);
1337
+ }
1338
+ const parsedArgs = domToObject(parsedNodes, schema, textNodeName);
1339
+ const args = {};
1340
+ for (const k of Object.keys(parsedArgs || {})) {
1341
+ const v = parsedArgs[k];
1342
+ let val = v;
1343
+ const propSchema = getPropertySchema(schema, k);
1344
+ const propType = getSchemaType(propSchema);
1345
+ if (propType === "string" && duplicateKeys.has(k) && Array.isArray(v)) {
1346
+ const firstValue = v[0];
1347
+ if (typeof firstValue === "string" && firstValue.startsWith("__RXML_PLACEHOLDER_")) {
1348
+ const originalContent = originalContentMap.get(firstValue);
1349
+ if (originalContent !== void 0) {
1350
+ args[k] = originalContent;
1351
+ continue;
1352
+ }
1353
+ } else {
1354
+ args[k] = firstValue;
1355
+ continue;
1356
+ }
1357
+ }
1358
+ if (propType === "string" && !Array.isArray(v)) {
1359
+ const placeholderUsed = typeof v === "string" && v.startsWith("__RXML_PLACEHOLDER_") || v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, textNodeName) && typeof v[textNodeName] === "string" && v[textNodeName].startsWith(
1360
+ "__RXML_PLACEHOLDER_"
1361
+ );
1362
+ if (placeholderUsed) {
1363
+ let placeholderKey;
1364
+ if (typeof v === "string") {
1365
+ placeholderKey = v;
1366
+ } else {
1367
+ placeholderKey = v[textNodeName];
1368
+ }
1369
+ const originalContent = originalContentMap.get(placeholderKey);
1370
+ if (originalContent !== void 0) {
1371
+ args[k] = originalContent;
1372
+ continue;
1373
+ }
1374
+ }
1375
+ const raw = extractRawInner(actualXmlInner, k);
1376
+ if (typeof raw === "string") {
1377
+ args[k] = raw;
1378
+ continue;
1379
+ }
1380
+ }
1381
+ if (v && typeof v === "object" && Object.prototype.hasOwnProperty.call(v, textNodeName)) {
1382
+ val = v[textNodeName];
1383
+ }
1384
+ if (Array.isArray(v)) {
1385
+ if (propType === "string") {
1386
+ const mapped = v.map((item) => {
1387
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, textNodeName)) {
1388
+ const textVal = item[textNodeName];
1389
+ return typeof textVal === "string" ? textVal : String(textVal);
1390
+ }
1391
+ return typeof item === "string" ? item : String(item);
1392
+ });
1393
+ if (mapped.length > 1 && throwDup) {
1394
+ throw new RXMLDuplicateStringTagError(
1395
+ `Duplicate string tags for <${k}> detected`
1396
+ );
1397
+ }
1398
+ if (mapped.length > 1 && !throwDup && options.onError) {
1399
+ options.onError(
1400
+ `RXML: Duplicate string tags for <${k}> detected; using first occurrence.`,
1401
+ { tag: k, occurrences: mapped.length }
1402
+ );
1403
+ }
1404
+ args[k] = (_c = mapped[0]) != null ? _c : "";
1405
+ continue;
1406
+ } else {
1407
+ val = processArrayContent(v, propSchema, textNodeName);
1408
+ }
1409
+ } else if (v && typeof v === "object" && !Object.prototype.hasOwnProperty.call(v, textNodeName)) {
1410
+ const obj = v;
1411
+ const keys2 = Object.keys(obj);
1412
+ if (keys2.length === 1 && keys2[0] === "item") {
1413
+ const itemValue = obj.item;
1414
+ if (Array.isArray(itemValue)) {
1415
+ val = itemValue.map((item) => {
1416
+ let currentVal = item;
1417
+ if (item && typeof item === "object" && Object.prototype.hasOwnProperty.call(item, textNodeName)) {
1418
+ currentVal = item[textNodeName];
1419
+ }
1420
+ const trimmed = typeof currentVal === "string" ? currentVal.trim() : currentVal;
1421
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1422
+ const num = Number(trimmed);
1423
+ if (Number.isFinite(num)) return num;
1424
+ }
1425
+ return trimmed;
1426
+ });
1427
+ } else {
1428
+ const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1429
+ if (typeof trimmed === "string" && /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/.test(trimmed)) {
1430
+ const num = Number(trimmed);
1431
+ val = Number.isFinite(num) ? num : trimmed;
1432
+ } else {
1433
+ val = trimmed;
1434
+ }
1435
+ }
1436
+ } else {
1437
+ let isIndexedTuple = false;
1438
+ if (keys2.length > 0 && keys2.every((key) => /^\d+$/.test(key))) {
1439
+ const indices = keys2.map((k2) => parseInt(k2, 10)).sort((a, b) => a - b);
1440
+ isIndexedTuple = indices[0] === 0 && indices.every((val2, idx) => val2 === idx);
1441
+ }
1442
+ if (isIndexedTuple) {
1443
+ val = processIndexedTuple(obj, textNodeName);
1444
+ } else {
1445
+ val = v;
1446
+ }
1447
+ }
1448
+ }
1449
+ args[k] = typeof val === "string" ? val.trim() : val;
1450
+ }
1451
+ for (const key of stringTypedProps) {
1452
+ if (!Object.prototype.hasOwnProperty.call(args, key)) {
1453
+ const raw = extractRawInner(actualXmlInner, key);
1454
+ if (typeof raw === "string") {
1455
+ args[key] = raw;
1456
+ }
1457
+ }
1458
+ }
1459
+ let dataToCoerce = args;
1460
+ const keys = Object.keys(args);
1461
+ if (keys.length === 1) {
1462
+ const rootKey = keys[0];
1463
+ const rootValue = args[rootKey];
1464
+ const unwrapped = unwrapJsonSchema(schema);
1465
+ if (unwrapped && typeof unwrapped === "object") {
1466
+ const schemaProps = unwrapped.properties;
1467
+ if (schemaProps && !Object.prototype.hasOwnProperty.call(schemaProps, rootKey)) {
1468
+ dataToCoerce = rootValue;
1469
+ }
1470
+ }
1471
+ }
1472
+ try {
1473
+ const coerced = coerceDomBySchema(dataToCoerce, schema);
1474
+ return coerced;
1475
+ } catch (error) {
1476
+ throw new RXMLCoercionError("Failed to coerce by schema", error);
1477
+ }
1478
+ }
1479
+ function parseWithoutSchema(xmlString, options = {}) {
1480
+ try {
1481
+ const tokenizer = new XMLTokenizer(xmlString, options);
1482
+ return tokenizer.parseChildren();
1483
+ } catch (error) {
1484
+ if (error instanceof RXMLParseError) {
1485
+ const isSimple = xmlString.split("<").length < 6;
1486
+ if (error.message.includes("Unexpected close tag") && isSimple || error.message.includes("Unclosed tag") && isSimple) {
1487
+ throw new RXMLParseError(
1488
+ error.message,
1489
+ error.cause,
1490
+ error.line,
1491
+ error.column
1492
+ );
1493
+ }
1494
+ }
1495
+ if (options.onError) {
1496
+ options.onError("Failed to parse XML without schema", { error });
1497
+ }
1498
+ try {
1499
+ const partialResults = [];
1500
+ const xmlPattern = /<([a-zA-Z_][\w.-]*)[^>]*>.*?<\/\1>/gs;
1501
+ let match;
1502
+ while ((match = xmlPattern.exec(xmlString)) !== null) {
1503
+ try {
1504
+ const elementXml = match[0];
1505
+ const tokenizer = new XMLTokenizer(elementXml, options);
1506
+ const parsed = tokenizer.parseChildren();
1507
+ partialResults.push(...parsed);
1508
+ } catch (e) {
1509
+ continue;
1510
+ }
1511
+ }
1512
+ if (partialResults.length > 0) {
1513
+ return partialResults;
1514
+ }
1515
+ } catch (e) {
1516
+ }
1517
+ return [xmlString.trim()];
1518
+ }
1519
+ }
1520
+ function parseNode(xmlString, options = {}) {
1521
+ try {
1522
+ const tokenizer = new XMLTokenizer(xmlString, options);
1523
+ return tokenizer.parseNode();
1524
+ } catch (error) {
1525
+ throw new RXMLParseError("Failed to parse XML node", error);
1526
+ }
1527
+ }
1528
+ function simplify(children) {
1529
+ if (!children.length) {
1530
+ return "";
1531
+ }
1532
+ if (children.length === 1 && typeof children[0] === "string") {
1533
+ return children[0];
1534
+ }
1535
+ const out = {};
1536
+ children.forEach((child) => {
1537
+ if (typeof child !== "object") {
1538
+ return;
1539
+ }
1540
+ if (!out[child.tagName]) {
1541
+ out[child.tagName] = [];
1542
+ }
1543
+ const kids = simplify(child.children);
1544
+ let nodeValue = kids;
1545
+ if (Object.keys(child.attributes).length) {
1546
+ if (typeof kids === "string") {
1547
+ nodeValue = kids;
1548
+ if (kids !== "") {
1549
+ nodeValue = { _attributes: child.attributes, value: kids };
1550
+ } else {
1551
+ nodeValue = { _attributes: child.attributes };
1552
+ }
1553
+ } else if (typeof kids === "object" && kids !== null) {
1554
+ kids._attributes = child.attributes;
1555
+ nodeValue = kids;
1556
+ } else {
1557
+ nodeValue = { _attributes: child.attributes };
1558
+ }
1559
+ }
1560
+ out[child.tagName].push(nodeValue);
1561
+ });
1562
+ for (const key in out) {
1563
+ const value = out[key];
1564
+ if (Array.isArray(value) && value.length === 1) {
1565
+ out[key] = value[0];
1566
+ }
1567
+ }
1568
+ return out;
1569
+ }
1570
+ function filter(children, filterFn, depth = 0, path = "") {
1571
+ const out = [];
1572
+ children.forEach((child, i) => {
1573
+ if (typeof child === "object" && filterFn(child, i, depth, path)) {
1574
+ out.push(child);
1575
+ }
1576
+ if (typeof child === "object" && child.children) {
1577
+ const kids = filter(
1578
+ child.children,
1579
+ filterFn,
1580
+ depth + 1,
1581
+ (path ? path + "." : "") + i + "." + child.tagName
1582
+ );
1583
+ out.push(...kids);
1584
+ }
1585
+ });
1586
+ return out;
1587
+ }
1588
+
1589
+ // src/core/stream.ts
1590
+ var import_stream = require("stream");
1591
+ var XMLTransformStream = class extends import_stream.Transform {
1592
+ constructor(offset, parseOptions = {}) {
1593
+ super({ readableObjectMode: true });
1594
+ this.buffer = "";
1595
+ this.emittedCount = 0;
1596
+ this.sawTagChar = false;
1597
+ if (typeof offset === "string") {
1598
+ this.position = offset.length;
1599
+ } else {
1600
+ this.position = offset || 0;
1601
+ }
1602
+ this.parseOptions = {
1603
+ keepComments: false,
1604
+ keepWhitespace: false,
1605
+ ...parseOptions
1606
+ };
1607
+ }
1608
+ _transform(chunk, encoding, callback) {
1609
+ try {
1610
+ const incoming = chunk.toString();
1611
+ if (incoming.includes("<")) this.sawTagChar = true;
1612
+ this.buffer += incoming;
1613
+ this.processBuffer();
1614
+ callback();
1615
+ } catch (error) {
1616
+ callback(new RXMLStreamError("Transform error", error));
1617
+ }
1618
+ }
1619
+ _flush(callback) {
1620
+ try {
1621
+ if (this.buffer.length > 0) {
1622
+ this.processBuffer(true);
1623
+ }
1624
+ if (this.sawTagChar && this.emittedCount === 0) {
1625
+ throw new RXMLStreamError(
1626
+ "Flush error",
1627
+ new Error("No XML elements could be parsed from stream")
1628
+ );
1629
+ }
1630
+ callback();
1631
+ } catch (error) {
1632
+ callback(new RXMLStreamError("Flush error", error));
1633
+ }
1634
+ }
1635
+ processBuffer(isFlush = false) {
1636
+ while (this.buffer.length > 0) {
1637
+ const openBracket = this.buffer.indexOf("<");
1638
+ if (openBracket === -1) {
1639
+ if (isFlush) this.buffer = "";
1640
+ break;
1641
+ }
1642
+ if (openBracket > 0) {
1643
+ this.buffer = this.buffer.slice(openBracket);
1644
+ }
1645
+ if (this.buffer.startsWith("<?") || this.buffer.startsWith("<!--") || this.buffer.startsWith("<![CDATA[")) {
1646
+ const endMarkers = {
1647
+ "<?": "?>",
1648
+ "<!--": "-->",
1649
+ "<![CDATA[": "]]>"
1650
+ };
1651
+ let endMarker = "";
1652
+ for (const [start, end] of Object.entries(endMarkers)) {
1653
+ if (this.buffer.startsWith(start)) {
1654
+ endMarker = end;
1655
+ break;
1656
+ }
1657
+ }
1658
+ const endPos = endMarker ? this.buffer.indexOf(endMarker) : -1;
1659
+ if (endPos === -1) {
1660
+ if (!isFlush) break;
1661
+ this.buffer = "";
1662
+ break;
1663
+ }
1664
+ if (this.parseOptions.keepComments && this.buffer.startsWith("<!--")) {
1665
+ this.push(this.buffer.slice(0, endPos + endMarker.length));
1666
+ }
1667
+ this.buffer = this.buffer.slice(endPos + endMarker.length);
1668
+ continue;
1669
+ }
1670
+ if (this.buffer.startsWith("</")) {
1671
+ const closeEnd = this.buffer.indexOf(">");
1672
+ if (closeEnd === -1) {
1673
+ if (!isFlush) break;
1674
+ this.buffer = "";
1675
+ break;
1676
+ }
1677
+ this.buffer = this.buffer.slice(closeEnd + 1);
1678
+ continue;
1679
+ }
1680
+ const openTagEnd = this.buffer.indexOf(">");
1681
+ if (openTagEnd === -1) {
1682
+ if (!isFlush) break;
1683
+ this.buffer = "";
1684
+ break;
1685
+ }
1686
+ const openTagContent = this.buffer.slice(1, openTagEnd);
1687
+ const nameMatch = openTagContent.match(/^([a-zA-Z_][\w.-]*)/);
1688
+ if (!nameMatch) {
1689
+ this.buffer = this.buffer.slice(1);
1690
+ continue;
1691
+ }
1692
+ const tagName = nameMatch[1];
1693
+ const isSelfClosing = this.buffer[openTagEnd - 1] === "/";
1694
+ if (isSelfClosing) {
1695
+ const elementEnd2 = openTagEnd + 1;
1696
+ const elementXml2 = this.buffer.slice(0, elementEnd2);
1697
+ try {
1698
+ const tokenizer = new XMLTokenizer(elementXml2, this.parseOptions);
1699
+ const node = tokenizer.parseNode();
1700
+ this.emitElementAndChildren(node);
1701
+ this.buffer = this.buffer.slice(elementEnd2);
1702
+ continue;
1703
+ } catch (e) {
1704
+ this.buffer = this.buffer.slice(1);
1705
+ continue;
1706
+ }
1707
+ }
1708
+ const closingTag = `</${tagName}>`;
1709
+ let depth = 1;
1710
+ let searchStart = openTagEnd + 1;
1711
+ let elementEnd = -1;
1712
+ while (searchStart < this.buffer.length) {
1713
+ let nextOpen = this.buffer.indexOf(`<${tagName}`, searchStart);
1714
+ while (nextOpen !== -1) {
1715
+ const after = this.buffer[nextOpen + tagName.length + 1];
1716
+ if (after === void 0 || after === ">" || /\s/.test(after)) break;
1717
+ nextOpen = this.buffer.indexOf(`<${tagName}`, nextOpen + 1);
1718
+ }
1719
+ const nextCloseStart = this.buffer.indexOf(`</${tagName}`, searchStart);
1720
+ if (nextCloseStart === -1) break;
1721
+ if (nextOpen !== -1 && nextOpen < nextCloseStart) {
1722
+ depth++;
1723
+ searchStart = nextOpen + 1;
1724
+ } else {
1725
+ depth--;
1726
+ let p = nextCloseStart + 2 + tagName.length;
1727
+ while (p < this.buffer.length && /\s/.test(this.buffer[p])) p++;
1728
+ if (this.buffer[p] !== ">") break;
1729
+ const closeAdvance = p + 1;
1730
+ searchStart = closeAdvance;
1731
+ if (depth === 0) {
1732
+ elementEnd = searchStart;
1733
+ break;
1734
+ }
1735
+ }
1736
+ }
1737
+ if (elementEnd === -1) {
1738
+ if (!isFlush) break;
1739
+ this.buffer = this.buffer.slice(1);
1740
+ continue;
1741
+ }
1742
+ const elementXml = this.buffer.slice(0, elementEnd);
1743
+ try {
1744
+ const tokenizer = new XMLTokenizer(elementXml, this.parseOptions);
1745
+ const node = tokenizer.parseNode();
1746
+ this.emitElementAndChildren(node);
1747
+ this.buffer = this.buffer.slice(elementEnd);
1748
+ } catch (e) {
1749
+ this.emit("error", new RXMLStreamError("Parse error", e));
1750
+ return;
1751
+ }
1752
+ }
1753
+ }
1754
+ /**
1755
+ * Emit an element and recursively emit its children as separate events
1756
+ */
1757
+ emitElementAndChildren(node) {
1758
+ if (typeof node === "string") {
1759
+ if (this.parseOptions.keepComments && node.includes("<!--")) {
1760
+ this.push(node);
1761
+ this.emittedCount++;
1762
+ }
1763
+ return;
1764
+ }
1765
+ this.push(node);
1766
+ this.emittedCount++;
1767
+ for (const child of node.children) {
1768
+ this.emitElementAndChildren(child);
1769
+ }
1770
+ }
1771
+ };
1772
+ function createXMLStream(offset, parseOptions) {
1773
+ return new XMLTransformStream(offset, parseOptions);
1774
+ }
1775
+ async function parseFromStream(stream, offset, parseOptions) {
1776
+ return new Promise((resolve, reject) => {
1777
+ const results = [];
1778
+ const transformStream = createXMLStream(offset, parseOptions);
1779
+ const onSourceError = (err) => {
1780
+ transformStream.destroy(err);
1781
+ };
1782
+ stream.on("error", onSourceError);
1783
+ transformStream.on("data", (element) => {
1784
+ results.push(element);
1785
+ });
1786
+ transformStream.on("end", () => {
1787
+ stream.off("error", onSourceError);
1788
+ resolve(results);
1789
+ });
1790
+ transformStream.on("error", (error) => {
1791
+ stream.off("error", onSourceError);
1792
+ reject(new RXMLStreamError("Stream parsing failed", error));
1793
+ });
1794
+ stream.pipe(transformStream);
1795
+ });
1796
+ }
1797
+ async function* processXMLStream(stream, offset, parseOptions) {
1798
+ const transformStream = createXMLStream(offset, parseOptions);
1799
+ let ended = false;
1800
+ let error = null;
1801
+ const queue = [];
1802
+ let resolveNext = null;
1803
+ const onSourceError = (err) => {
1804
+ error = err;
1805
+ transformStream.destroy(err);
1806
+ };
1807
+ stream.on("error", onSourceError);
1808
+ transformStream.on("data", (element) => {
1809
+ if (resolveNext) {
1810
+ resolveNext({ value: element, done: false });
1811
+ resolveNext = null;
1812
+ } else {
1813
+ queue.push(element);
1814
+ }
1815
+ });
1816
+ transformStream.on("end", () => {
1817
+ ended = true;
1818
+ if (resolveNext) {
1819
+ resolveNext({ value: void 0, done: true });
1820
+ resolveNext = null;
1821
+ }
1822
+ stream.off("error", onSourceError);
1823
+ });
1824
+ transformStream.on("error", (err) => {
1825
+ error = err;
1826
+ if (resolveNext) {
1827
+ resolveNext({ value: void 0, done: true });
1828
+ resolveNext = null;
1829
+ }
1830
+ stream.off("error", onSourceError);
1831
+ });
1832
+ stream.pipe(transformStream);
1833
+ while (true) {
1834
+ if (error) {
1835
+ throw new RXMLStreamError("Stream processing error", error);
1836
+ }
1837
+ if (queue.length > 0) {
1838
+ yield queue.shift();
1839
+ continue;
1840
+ }
1841
+ if (ended) {
1842
+ break;
1843
+ }
1844
+ const result = await new Promise(
1845
+ (resolve) => {
1846
+ resolveNext = resolve;
1847
+ }
1848
+ );
1849
+ if (result.done) {
1850
+ if (error) {
1851
+ throw new RXMLStreamError("Stream processing error", error);
1852
+ }
1853
+ break;
1854
+ }
1855
+ yield result.value;
1856
+ }
1857
+ }
1858
+ async function* findElementByIdStream(stream, id, offset, parseOptions) {
1859
+ for await (const element of processXMLStream(stream, offset, parseOptions)) {
1860
+ if (typeof element === "object" && element.attributes.id === id) {
1861
+ yield element;
1862
+ }
1863
+ }
1864
+ }
1865
+ async function* findElementsByClassStream(stream, className, offset, parseOptions) {
1866
+ const classRegex = new RegExp(`\\b${className}\\b`);
1867
+ for await (const element of processXMLStream(stream, offset, parseOptions)) {
1868
+ if (typeof element === "object" && element.attributes.class && classRegex.test(element.attributes.class)) {
1869
+ yield element;
1870
+ }
1871
+ }
1872
+ }
1873
+
1874
+ // src/builders/stringify.ts
1875
+ function stringify(rootTag, obj, options = {}) {
1876
+ var _a, _b, _c, _d;
1877
+ try {
1878
+ const format = (_a = options.format) != null ? _a : true;
1879
+ const minimalEscaping = (_b = options.minimalEscaping) != null ? _b : false;
1880
+ const suppressEmptyNode = (_c = options.suppressEmptyNode) != null ? _c : false;
1881
+ const strictBooleanAttributes = (_d = options.strictBooleanAttributes) != null ? _d : false;
1882
+ let result = "";
1883
+ if (format) {
1884
+ result += '<?xml version="1.0" encoding="UTF-8"?>\n';
1885
+ }
1886
+ result += stringifyValue(
1887
+ rootTag,
1888
+ obj,
1889
+ 0,
1890
+ format,
1891
+ suppressEmptyNode,
1892
+ minimalEscaping,
1893
+ strictBooleanAttributes
1894
+ );
1895
+ return result;
1896
+ } catch (error) {
1897
+ throw new RXMLStringifyError("Failed to stringify XML", error);
1898
+ }
1899
+ }
1900
+ function stringifyValue(tagName, value, depth, format, suppressEmptyNode, minimalEscaping, strictBooleanAttributes) {
1901
+ const indent = format ? " ".repeat(depth) : "";
1902
+ const newline = format ? "\n" : "";
1903
+ if (value === null || value === void 0) {
1904
+ if (suppressEmptyNode) return "";
1905
+ return `${indent}<${tagName}/>${newline}`;
1906
+ }
1907
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1908
+ const content2 = minimalEscaping ? escapeXmlMinimalText(String(value)) : escapeXml(String(value));
1909
+ if (content2 === "" && suppressEmptyNode) return "";
1910
+ return `${indent}<${tagName}>${content2}</${tagName}>${newline}`;
1911
+ }
1912
+ if (Array.isArray(value)) {
1913
+ let result = "";
1914
+ for (const item of value) {
1915
+ result += stringifyValue(
1916
+ tagName,
1917
+ item,
1918
+ depth,
1919
+ format,
1920
+ suppressEmptyNode,
1921
+ minimalEscaping,
1922
+ strictBooleanAttributes
1923
+ );
1924
+ }
1925
+ return result;
1926
+ }
1927
+ if (typeof value === "object") {
1928
+ return stringifyObject(
1929
+ tagName,
1930
+ value,
1931
+ depth,
1932
+ format,
1933
+ suppressEmptyNode,
1934
+ minimalEscaping,
1935
+ strictBooleanAttributes
1936
+ );
1937
+ }
1938
+ const content = minimalEscaping ? escapeXmlMinimalText(String(value)) : escapeXml(String(value));
1939
+ if (content === "" && suppressEmptyNode) return "";
1940
+ return `${indent}<${tagName}>${content}</${tagName}>${newline}`;
1941
+ }
1942
+ function stringifyObject(tagName, obj, depth, format, suppressEmptyNode, minimalEscaping, strictBooleanAttributes) {
1943
+ const indent = format ? " ".repeat(depth) : "";
1944
+ const newline = format ? "\n" : "";
1945
+ const childIndent = format ? " ".repeat(depth + 1) : "";
1946
+ const attributes = {};
1947
+ const elements = {};
1948
+ let textContent;
1949
+ for (const [key, value] of Object.entries(obj)) {
1950
+ if (key.startsWith("@")) {
1951
+ attributes[key.substring(1)] = value;
1952
+ } else if (key === "#text" || key === "_text") {
1953
+ textContent = String(value);
1954
+ } else if (key === "_attributes") {
1955
+ if (typeof value === "object" && value !== null) {
1956
+ Object.assign(attributes, value);
1957
+ }
1958
+ } else {
1959
+ elements[key] = value;
1960
+ }
1961
+ }
1962
+ let openTag = `<${tagName}`;
1963
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
1964
+ if (attrValue === null) {
1965
+ if (strictBooleanAttributes) {
1966
+ openTag += ` ${attrName}="${attrName}"`;
1967
+ } else {
1968
+ openTag += ` ${attrName}`;
1969
+ }
1970
+ } else {
1971
+ const valueStr = String(attrValue);
1972
+ if (valueStr.indexOf('"') === -1) {
1973
+ const escaped = minimalEscaping ? escapeXmlMinimalAttr(valueStr, '"') : escapeXml(valueStr);
1974
+ openTag += ` ${attrName}="${escaped}"`;
1975
+ } else {
1976
+ const escaped = minimalEscaping ? escapeXmlMinimalAttr(valueStr, "'") : escapeXml(valueStr);
1977
+ openTag += ` ${attrName}='${escaped}'`;
1978
+ }
1979
+ }
1980
+ }
1981
+ const hasElements = Object.keys(elements).length > 0;
1982
+ const hasTextContent = textContent !== void 0 && textContent !== "";
1983
+ if (!hasElements && !hasTextContent) {
1984
+ if (suppressEmptyNode) return "";
1985
+ return `${indent}${openTag}/>${newline}`;
1986
+ }
1987
+ openTag += ">";
1988
+ if (!hasElements && hasTextContent && textContent) {
1989
+ const content = minimalEscaping ? escapeXmlMinimalText(textContent) : escapeXml(textContent);
1990
+ return `${indent}${openTag}${content}</${tagName}>${newline}`;
1991
+ }
1992
+ let result = `${indent}${openTag}`;
1993
+ if (hasTextContent && textContent) {
1994
+ const content = minimalEscaping ? escapeXmlMinimalText(textContent) : escapeXml(textContent);
1995
+ if (format) result += `${newline}${childIndent}${content}`;
1996
+ else result += content;
1997
+ }
1998
+ if (hasElements) {
1999
+ if (format) result += newline;
2000
+ for (const [elementName, elementValue] of Object.entries(elements)) {
2001
+ result += stringifyValue(
2002
+ elementName,
2003
+ elementValue,
2004
+ depth + 1,
2005
+ format,
2006
+ suppressEmptyNode,
2007
+ minimalEscaping,
2008
+ strictBooleanAttributes
2009
+ );
2010
+ }
2011
+ if (format) result += indent;
2012
+ }
2013
+ result += `</${tagName}>${newline}`;
2014
+ return result;
2015
+ }
2016
+ function stringifyNodes(nodes, format = true, options = {}) {
2017
+ let result = "";
2018
+ for (const node of nodes) {
2019
+ if (typeof node === "string") {
2020
+ result += node;
2021
+ } else {
2022
+ result += stringifyNode(node, 0, format, options);
2023
+ }
2024
+ }
2025
+ return result;
2026
+ }
2027
+ function stringifyNode(node, depth = 0, format = true, options = {}) {
2028
+ var _a, _b;
2029
+ const indent = format ? " ".repeat(depth) : "";
2030
+ const newline = format ? "\n" : "";
2031
+ const minimalEscaping = (_a = options.minimalEscaping) != null ? _a : false;
2032
+ const strictBooleanAttributes = (_b = options.strictBooleanAttributes) != null ? _b : false;
2033
+ let result = `${indent}<${node.tagName}`;
2034
+ for (const [attrName, attrValue] of Object.entries(node.attributes)) {
2035
+ if (attrValue === null) {
2036
+ if (strictBooleanAttributes) {
2037
+ result += ` ${attrName}="${attrName}"`;
2038
+ } else {
2039
+ result += ` ${attrName}`;
2040
+ }
2041
+ } else if (attrValue.indexOf('"') === -1) {
2042
+ const escaped = minimalEscaping ? escapeXmlMinimalAttr(attrValue, '"') : escapeXml(attrValue);
2043
+ result += ` ${attrName}="${escaped}"`;
2044
+ } else {
2045
+ const escaped = minimalEscaping ? escapeXmlMinimalAttr(attrValue, "'") : escapeXml(attrValue);
2046
+ result += ` ${attrName}='${escaped}'`;
2047
+ }
2048
+ }
2049
+ if (node.tagName[0] === "?") {
2050
+ result += "?>";
2051
+ return result + newline;
2052
+ }
2053
+ if (node.children.length === 0) {
2054
+ result += "/>";
2055
+ return result + newline;
2056
+ }
2057
+ result += ">";
2058
+ let hasElementChildren = false;
2059
+ for (const child of node.children) {
2060
+ if (typeof child === "string") {
2061
+ result += minimalEscaping ? escapeXmlMinimalText(child) : escapeXml(child);
2062
+ } else {
2063
+ if (!hasElementChildren && format) {
2064
+ result += newline;
2065
+ hasElementChildren = true;
2066
+ }
2067
+ result += stringifyNode(child, depth + 1, format, options);
2068
+ }
2069
+ }
2070
+ if (hasElementChildren && format) {
2071
+ result += indent;
2072
+ }
2073
+ result += `</${node.tagName}>`;
2074
+ if (format) {
2075
+ result += newline;
2076
+ }
2077
+ return result;
2078
+ }
2079
+ function toContentString(nodes) {
2080
+ let result = "";
2081
+ for (const node of nodes) {
2082
+ if (typeof node === "string") {
2083
+ result += " " + node;
2084
+ } else {
2085
+ result += " " + toContentString(node.children);
2086
+ }
2087
+ result = result.trim();
2088
+ }
2089
+ return result;
2090
+ }
2091
+ // Annotate the CommonJS export names for ESM import in node:
2092
+ 0 && (module.exports = {
2093
+ RXMLCoercionError,
2094
+ RXMLDuplicateStringTagError,
2095
+ RXMLParseError,
2096
+ RXMLStreamError,
2097
+ RXMLStringifyError,
2098
+ XMLTokenizer,
2099
+ XMLTransformStream,
2100
+ coerceDomBySchema,
2101
+ countTagOccurrences,
2102
+ createXMLStream,
2103
+ domToObject,
2104
+ extractRawInner,
2105
+ filter,
2106
+ findElementByIdStream,
2107
+ findElementsByClassStream,
2108
+ findFirstTopLevelRange,
2109
+ getPropertySchema,
2110
+ getStringTypedProperties,
2111
+ parse,
2112
+ parseFromStream,
2113
+ parseNode,
2114
+ parseWithoutSchema,
2115
+ processArrayContent,
2116
+ processIndexedTuple,
2117
+ processXMLStream,
2118
+ simplify,
2119
+ stringify,
2120
+ stringifyNode,
2121
+ stringifyNodes,
2122
+ toContentString
2123
+ });
2124
+ //# sourceMappingURL=index.cjs.map