@ai-sdk-tool/parser 3.2.0 → 3.3.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/rxml.cjs ADDED
@@ -0,0 +1,2471 @@
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/rxml/index.ts
21
+ var rxml_exports = {};
22
+ __export(rxml_exports, {
23
+ parse: () => parse2,
24
+ stringify: () => stringify
25
+ });
26
+ module.exports = __toCommonJS(rxml_exports);
27
+
28
+ // src/rxml/errors/types.ts
29
+ var RXMLParseError = class extends Error {
30
+ constructor(message, cause, line, column) {
31
+ super(message);
32
+ this.name = "RXMLParseError";
33
+ this.cause = cause;
34
+ this.line = line;
35
+ this.column = column;
36
+ }
37
+ };
38
+ var RXMLDuplicateStringTagError = class extends Error {
39
+ constructor(message) {
40
+ super(message);
41
+ this.name = "RXMLDuplicateStringTagError";
42
+ }
43
+ };
44
+ var RXMLCoercionError = class extends Error {
45
+ constructor(message, cause) {
46
+ super(message);
47
+ this.name = "RXMLCoercionError";
48
+ this.cause = cause;
49
+ }
50
+ };
51
+ var RXMLStringifyError = class extends Error {
52
+ constructor(message, cause) {
53
+ super(message);
54
+ this.name = "RXMLStringifyError";
55
+ this.cause = cause;
56
+ }
57
+ };
58
+
59
+ // src/rxml/core/types.ts
60
+ var CharCodes = {
61
+ OPEN_BRACKET: "<".charCodeAt(0),
62
+ CLOSE_BRACKET: ">".charCodeAt(0),
63
+ MINUS: "-".charCodeAt(0),
64
+ SLASH: "/".charCodeAt(0),
65
+ EXCLAMATION: "!".charCodeAt(0),
66
+ QUESTION: "?".charCodeAt(0),
67
+ SINGLE_QUOTE: "'".charCodeAt(0),
68
+ DOUBLE_QUOTE: '"'.charCodeAt(0),
69
+ OPEN_CORNER_BRACKET: "[".charCodeAt(0),
70
+ CLOSE_CORNER_BRACKET: "]".charCodeAt(0),
71
+ SPACE: " ".charCodeAt(0),
72
+ TAB: " ".charCodeAt(0),
73
+ NEWLINE: "\n".charCodeAt(0),
74
+ CARRIAGE_RETURN: "\r".charCodeAt(0)
75
+ };
76
+ var DEFAULT_NO_CHILD_NODES = [
77
+ "img",
78
+ "br",
79
+ "input",
80
+ "meta",
81
+ "link",
82
+ "hr",
83
+ "area",
84
+ "base",
85
+ "col",
86
+ "embed",
87
+ "param",
88
+ "source",
89
+ "track",
90
+ "wbr"
91
+ ];
92
+ var NAME_SPACER = "\r\n >/= ";
93
+
94
+ // src/rxml/utils/helpers.ts
95
+ var NAME_START_CHAR_REGEX = /[A-Za-z_:]/;
96
+ var NAME_CHAR_REGEX = /[A-Za-z0-9_.:-]/;
97
+ function isNameStartChar(ch) {
98
+ return NAME_START_CHAR_REGEX.test(ch);
99
+ }
100
+ function isNameChar(ch) {
101
+ return NAME_CHAR_REGEX.test(ch);
102
+ }
103
+ function skipQuoted(s, i) {
104
+ const quote = s[i];
105
+ let pos = i + 1;
106
+ while (pos < s.length) {
107
+ const ch = s[pos];
108
+ if (ch === "\\") {
109
+ pos += 2;
110
+ continue;
111
+ }
112
+ if (ch === quote) {
113
+ return pos + 1;
114
+ }
115
+ pos += 1;
116
+ }
117
+ return pos;
118
+ }
119
+ function parseName(s, pos) {
120
+ const start = pos;
121
+ let currentPos = pos;
122
+ while (NAME_SPACER.indexOf(s[currentPos]) === -1 && s[currentPos]) {
123
+ currentPos += 1;
124
+ }
125
+ return { name: s.slice(start, currentPos), newPos: currentPos };
126
+ }
127
+ function parseString(s, pos) {
128
+ const startChar = s[pos];
129
+ const startPos = pos + 1;
130
+ const endPos = s.indexOf(startChar, startPos);
131
+ if (endPos === -1) {
132
+ const tagEnd = s.indexOf(">", startPos);
133
+ if (tagEnd !== -1) {
134
+ return { value: s.slice(startPos, tagEnd), newPos: tagEnd };
135
+ }
136
+ return { value: s.slice(startPos), newPos: s.length };
137
+ }
138
+ return { value: s.slice(startPos, endPos), newPos: endPos + 1 };
139
+ }
140
+ function getLineColumn(s, pos) {
141
+ let line = 1;
142
+ let column = 1;
143
+ for (let i = 0; i < pos && i < s.length; i += 1) {
144
+ if (s[i] === "\n") {
145
+ line += 1;
146
+ column = 1;
147
+ } else {
148
+ column += 1;
149
+ }
150
+ }
151
+ return { line, column };
152
+ }
153
+ function escapeXml(text) {
154
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
155
+ }
156
+ function escapeXmlMinimalText(text) {
157
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/]]>/g, "]]&gt;");
158
+ }
159
+ function escapeXmlMinimalAttr(value, wrapper = '"') {
160
+ let escaped = value.replace(/&/g, "&amp;").replace(/</g, "&lt;");
161
+ if (wrapper === '"') {
162
+ escaped = escaped.replace(/"/g, "&quot;");
163
+ } else {
164
+ escaped = escaped.replace(/'/g, "&apos;");
165
+ }
166
+ return escaped;
167
+ }
168
+ function unescapeXml(text) {
169
+ return text.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
170
+ }
171
+
172
+ // src/rxml/builders/stringify.ts
173
+ function stringify(rootTag, obj, options = {}) {
174
+ var _a, _b, _c, _d, _e;
175
+ try {
176
+ const format = (_a = options.format) != null ? _a : true;
177
+ const declaration = (_b = options.declaration) != null ? _b : false;
178
+ const minimalEscaping = (_c = options.minimalEscaping) != null ? _c : false;
179
+ const suppressEmptyNode = (_d = options.suppressEmptyNode) != null ? _d : false;
180
+ const strictBooleanAttributes = (_e = options.strictBooleanAttributes) != null ? _e : false;
181
+ let result = "";
182
+ if (declaration) {
183
+ result += '<?xml version="1.0" encoding="UTF-8"?>\n';
184
+ }
185
+ result += stringifyValue(rootTag, obj, {
186
+ depth: 0,
187
+ format,
188
+ suppressEmptyNode,
189
+ minimalEscaping,
190
+ strictBooleanAttributes
191
+ });
192
+ if (result.endsWith("\n")) {
193
+ return result.slice(0, -1);
194
+ }
195
+ return result;
196
+ } catch (error) {
197
+ throw new RXMLStringifyError("Failed to stringify XML", error);
198
+ }
199
+ }
200
+ function escapeContent(content, minimalEscaping) {
201
+ return minimalEscaping ? escapeXmlMinimalText(content) : escapeXml(content);
202
+ }
203
+ function createSelfClosingTag(tagName, indent, newline) {
204
+ return `${indent}<${tagName}/>${newline}`;
205
+ }
206
+ function createTextElement(tagName, content, indent, newline) {
207
+ return `${indent}<${tagName}>${content}</${tagName}>${newline}`;
208
+ }
209
+ function isPrimitive(value) {
210
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
211
+ }
212
+ function stringifyPrimitive(tagName, value, context, format) {
213
+ const { minimalEscaping, suppressEmptyNode } = context;
214
+ const content = escapeContent(String(value), minimalEscaping);
215
+ if (content === "" && suppressEmptyNode) {
216
+ return "";
217
+ }
218
+ return createTextElement(tagName, content, format.indent, format.newline);
219
+ }
220
+ function stringifyArray(tagName, value, context) {
221
+ let result = "";
222
+ for (const item of value) {
223
+ result += stringifyValue(tagName, item, context);
224
+ }
225
+ return result;
226
+ }
227
+ function stringifyValue(tagName, value, context) {
228
+ const { format, suppressEmptyNode, minimalEscaping } = context;
229
+ const indent = format ? " ".repeat(context.depth) : "";
230
+ const newline = format ? "\n" : "";
231
+ if (value === null || value === void 0) {
232
+ if (suppressEmptyNode) {
233
+ return "";
234
+ }
235
+ return createSelfClosingTag(tagName, indent, newline);
236
+ }
237
+ if (isPrimitive(value)) {
238
+ return stringifyPrimitive(tagName, value, context, { indent, newline });
239
+ }
240
+ if (Array.isArray(value)) {
241
+ return stringifyArray(tagName, value, context);
242
+ }
243
+ if (typeof value === "object") {
244
+ return stringifyObject(tagName, value, context);
245
+ }
246
+ const content = escapeContent(String(value), minimalEscaping);
247
+ if (content === "" && suppressEmptyNode) {
248
+ return "";
249
+ }
250
+ return createTextElement(tagName, content, indent, newline);
251
+ }
252
+ function extractObjectParts(obj) {
253
+ const attributes = {};
254
+ const elements = {};
255
+ let textContent;
256
+ for (const [key, value] of Object.entries(obj)) {
257
+ if (key.startsWith("@")) {
258
+ attributes[key.substring(1)] = value;
259
+ } else if (key === "#text" || key === "_text") {
260
+ textContent = String(value);
261
+ } else if (key === "_attributes") {
262
+ if (typeof value === "object" && value !== null) {
263
+ Object.assign(attributes, value);
264
+ }
265
+ } else {
266
+ elements[key] = value;
267
+ }
268
+ }
269
+ return { attributes, elements, textContent };
270
+ }
271
+ function formatAttribute(attrName, attrValue, minimalEscaping, strictBooleanAttributes) {
272
+ if (attrValue === null) {
273
+ return strictBooleanAttributes ? ` ${attrName}="${attrName}"` : ` ${attrName}`;
274
+ }
275
+ const valueStr = String(attrValue);
276
+ if (valueStr.indexOf('"') === -1) {
277
+ const escaped2 = minimalEscaping ? escapeXmlMinimalAttr(valueStr, '"') : escapeXml(valueStr);
278
+ return ` ${attrName}="${escaped2}"`;
279
+ }
280
+ const escaped = minimalEscaping ? escapeXmlMinimalAttr(valueStr, "'") : escapeXml(valueStr);
281
+ return ` ${attrName}='${escaped}'`;
282
+ }
283
+ function buildOpeningTag(tagName, attributes, context) {
284
+ let openTag = `<${tagName}`;
285
+ const { minimalEscaping, strictBooleanAttributes } = context;
286
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
287
+ openTag += formatAttribute(
288
+ attrName,
289
+ attrValue,
290
+ minimalEscaping,
291
+ strictBooleanAttributes
292
+ );
293
+ }
294
+ return openTag;
295
+ }
296
+ function stringifyTextOnlyContent(options) {
297
+ const { tagName, textContent, openTag, format, minimalEscaping } = options;
298
+ const content = escapeContent(textContent, minimalEscaping);
299
+ return `${format.indent}${openTag}${content}</${tagName}>${format.newline}`;
300
+ }
301
+ function stringifyComplexContent(tagName, parts, context, options) {
302
+ const { format, minimalEscaping, depth } = context;
303
+ const { textContent, elements } = parts;
304
+ const hasElements = Object.keys(elements).length > 0;
305
+ let result = `${options.indent}${options.openTag}`;
306
+ if (textContent) {
307
+ const content = escapeContent(textContent, minimalEscaping);
308
+ result += format ? `${options.newline}${options.childIndent}${content}` : content;
309
+ }
310
+ if (hasElements) {
311
+ if (format) {
312
+ result += options.newline;
313
+ }
314
+ for (const [elementName, elementValue] of Object.entries(elements)) {
315
+ result += stringifyValue(elementName, elementValue, {
316
+ ...context,
317
+ depth: depth + 1
318
+ });
319
+ }
320
+ if (format) {
321
+ result += options.indent;
322
+ }
323
+ }
324
+ result += `</${tagName}>${options.newline}`;
325
+ return result;
326
+ }
327
+ function stringifyObject(tagName, obj, context) {
328
+ const { depth, format, suppressEmptyNode } = context;
329
+ const indent = format ? " ".repeat(depth) : "";
330
+ const newline = format ? "\n" : "";
331
+ const childIndent = format ? " ".repeat(depth + 1) : "";
332
+ const parts = extractObjectParts(obj);
333
+ const openTag = buildOpeningTag(tagName, parts.attributes, context);
334
+ const hasElements = Object.keys(parts.elements).length > 0;
335
+ const hasTextContent = parts.textContent !== void 0 && parts.textContent !== "";
336
+ if (!(hasElements || hasTextContent)) {
337
+ if (suppressEmptyNode) {
338
+ return "";
339
+ }
340
+ return `${indent}${openTag}/>${newline}`;
341
+ }
342
+ const fullOpenTag = `${openTag}>`;
343
+ if (!hasElements && hasTextContent && parts.textContent) {
344
+ return stringifyTextOnlyContent({
345
+ tagName,
346
+ textContent: parts.textContent,
347
+ openTag: fullOpenTag,
348
+ format: { indent, newline },
349
+ minimalEscaping: context.minimalEscaping
350
+ });
351
+ }
352
+ return stringifyComplexContent(tagName, parts, context, {
353
+ indent,
354
+ newline,
355
+ childIndent,
356
+ openTag: fullOpenTag
357
+ });
358
+ }
359
+
360
+ // src/schema-coerce/index.ts
361
+ var NUMERIC_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
362
+ var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
363
+ var NEWLINE_SPLIT_REGEX = /\n+/;
364
+ var COMMA_SPLIT_REGEX = /,\s*/;
365
+ var DIGIT_KEY_REGEX = /^\d+$/;
366
+ function unwrapJsonSchema(schema) {
367
+ if (!schema || typeof schema !== "object") {
368
+ return schema;
369
+ }
370
+ const s = schema;
371
+ if (s.jsonSchema && typeof s.jsonSchema === "object") {
372
+ return unwrapJsonSchema(s.jsonSchema);
373
+ }
374
+ return schema;
375
+ }
376
+ function getSchemaType(schema) {
377
+ const unwrapped = unwrapJsonSchema(schema);
378
+ if (!unwrapped || typeof unwrapped !== "object") {
379
+ return;
380
+ }
381
+ const t = unwrapped.type;
382
+ if (typeof t === "string") {
383
+ return t;
384
+ }
385
+ if (Array.isArray(t)) {
386
+ const preferred = [
387
+ "object",
388
+ "array",
389
+ "boolean",
390
+ "number",
391
+ "integer",
392
+ "string"
393
+ ];
394
+ for (const p of preferred) {
395
+ if (t.includes(p)) {
396
+ return p;
397
+ }
398
+ }
399
+ }
400
+ const s = unwrapped;
401
+ if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
402
+ return "object";
403
+ }
404
+ if (s && typeof s === "object" && (s.items || s.prefixItems)) {
405
+ return "array";
406
+ }
407
+ return;
408
+ }
409
+ function coerceStringWithoutSchema(value) {
410
+ const s = value.trim();
411
+ const lower = s.toLowerCase();
412
+ if (lower === "true") {
413
+ return true;
414
+ }
415
+ if (lower === "false") {
416
+ return false;
417
+ }
418
+ if (NUMERIC_REGEX.test(s)) {
419
+ const num = Number(s);
420
+ if (Number.isFinite(num)) {
421
+ return num;
422
+ }
423
+ }
424
+ if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
425
+ try {
426
+ const parsed = JSON.parse(s);
427
+ return coerceBySchema(parsed, void 0);
428
+ } catch (e) {
429
+ }
430
+ }
431
+ return value;
432
+ }
433
+ function coerceStringToObject(s, unwrapped) {
434
+ try {
435
+ let normalized = s.replace(/'/g, '"');
436
+ normalized = normalized.replace(EMPTY_OBJECT_REGEX, "{}");
437
+ const obj = JSON.parse(normalized);
438
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
439
+ const props = unwrapped.properties;
440
+ const out = {};
441
+ for (const [k, v] of Object.entries(obj)) {
442
+ const propSchema = props ? props[k] : void 0;
443
+ out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
444
+ }
445
+ return out;
446
+ }
447
+ } catch (e) {
448
+ }
449
+ return null;
450
+ }
451
+ function coerceStringToArray(s, unwrapped) {
452
+ const prefixItems = Array.isArray(unwrapped.prefixItems) ? unwrapped.prefixItems : void 0;
453
+ const itemsSchema = unwrapped.items;
454
+ try {
455
+ const normalized = s.replace(/'/g, '"');
456
+ const arr = JSON.parse(normalized);
457
+ if (Array.isArray(arr)) {
458
+ if (prefixItems && arr.length === prefixItems.length) {
459
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
460
+ }
461
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
462
+ }
463
+ } catch (e) {
464
+ const csv = s.includes("\n") ? s.split(NEWLINE_SPLIT_REGEX) : s.split(COMMA_SPLIT_REGEX);
465
+ const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
466
+ if (prefixItems && trimmed.length === prefixItems.length) {
467
+ return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
468
+ }
469
+ return trimmed.map((x) => coerceBySchema(x, itemsSchema));
470
+ }
471
+ return null;
472
+ }
473
+ function coerceObjectToObject(value, unwrapped) {
474
+ const out = {};
475
+ const props = unwrapped.properties;
476
+ for (const [k, v] of Object.entries(value)) {
477
+ const propSchema = props ? props[k] : void 0;
478
+ out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
479
+ }
480
+ return out;
481
+ }
482
+ function coerceArrayToArray(value, prefixItems, itemsSchema) {
483
+ if (prefixItems && value.length === prefixItems.length) {
484
+ return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
485
+ }
486
+ return value.map((v) => coerceBySchema(v, itemsSchema));
487
+ }
488
+ function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
489
+ if (Object.hasOwn(maybe, "item")) {
490
+ const items = maybe.item;
491
+ const arr = Array.isArray(items) ? items : [items];
492
+ return coerceArrayToArray(arr, prefixItems, itemsSchema);
493
+ }
494
+ const keys = Object.keys(maybe);
495
+ if (keys.length === 1) {
496
+ const singleValue = maybe[keys[0]];
497
+ if (Array.isArray(singleValue)) {
498
+ return singleValue.map((v) => coerceBySchema(v, itemsSchema));
499
+ }
500
+ }
501
+ if (keys.length > 0 && keys.every((k) => DIGIT_KEY_REGEX.test(k))) {
502
+ const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
503
+ return coerceArrayToArray(arr, prefixItems, itemsSchema);
504
+ }
505
+ return null;
506
+ }
507
+ function coercePrimitiveToArray(value, prefixItems, itemsSchema) {
508
+ if (prefixItems && prefixItems.length > 0) {
509
+ return [coerceBySchema(value, prefixItems[0])];
510
+ }
511
+ return [coerceBySchema(value, itemsSchema)];
512
+ }
513
+ function coerceStringToPrimitive(s, schemaType) {
514
+ if (schemaType === "boolean") {
515
+ const lower = s.toLowerCase();
516
+ if (lower === "true") {
517
+ return true;
518
+ }
519
+ if (lower === "false") {
520
+ return false;
521
+ }
522
+ }
523
+ if ((schemaType === "number" || schemaType === "integer") && NUMERIC_REGEX.test(s)) {
524
+ const num = Number(s);
525
+ if (Number.isFinite(num)) {
526
+ return num;
527
+ }
528
+ }
529
+ return null;
530
+ }
531
+ function coerceStringValue(value, schemaType, u) {
532
+ const s = value.trim();
533
+ if (schemaType === "object") {
534
+ const result = coerceStringToObject(s, u);
535
+ if (result !== null) {
536
+ return result;
537
+ }
538
+ }
539
+ if (schemaType === "array") {
540
+ const result = coerceStringToArray(s, u);
541
+ if (result !== null) {
542
+ return result;
543
+ }
544
+ }
545
+ const primitiveResult = coerceStringToPrimitive(s, schemaType);
546
+ if (primitiveResult !== null) {
547
+ return primitiveResult;
548
+ }
549
+ return value;
550
+ }
551
+ function coerceArrayValue(value, prefixItems, itemsSchema) {
552
+ if (Array.isArray(value)) {
553
+ return coerceArrayToArray(value, prefixItems, itemsSchema);
554
+ }
555
+ if (value && typeof value === "object") {
556
+ const result = coerceObjectToArray(
557
+ value,
558
+ prefixItems,
559
+ itemsSchema
560
+ );
561
+ if (result !== null) {
562
+ return result;
563
+ }
564
+ }
565
+ if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
566
+ return coercePrimitiveToArray(value, prefixItems, itemsSchema);
567
+ }
568
+ return value;
569
+ }
570
+ function coerceBySchema(value, schema) {
571
+ const unwrapped = unwrapJsonSchema(schema);
572
+ if (!unwrapped || typeof unwrapped !== "object") {
573
+ if (typeof value === "string") {
574
+ return coerceStringWithoutSchema(value);
575
+ }
576
+ return value;
577
+ }
578
+ const schemaType = getSchemaType(unwrapped);
579
+ const u = unwrapped;
580
+ if (typeof value === "string") {
581
+ return coerceStringValue(value, schemaType, u);
582
+ }
583
+ if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
584
+ return coerceObjectToObject(value, u);
585
+ }
586
+ if (schemaType === "array") {
587
+ const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
588
+ const itemsSchema = u.items;
589
+ return coerceArrayValue(value, prefixItems, itemsSchema);
590
+ }
591
+ return value;
592
+ }
593
+
594
+ // src/rxml/schema/coercion.ts
595
+ function getPropertySchema(toolSchema, key) {
596
+ const unwrapped = unwrapJsonSchema(toolSchema);
597
+ if (!unwrapped || typeof unwrapped !== "object") {
598
+ return;
599
+ }
600
+ const u = unwrapped;
601
+ const props = u.properties;
602
+ if (props && Object.hasOwn(props, key)) {
603
+ return props[key];
604
+ }
605
+ return;
606
+ }
607
+ function getNodeValue(children, schema, tagName, textNodeName) {
608
+ if (children.length === 0) {
609
+ return "";
610
+ }
611
+ if (children.length === 1 && typeof children[0] === "string") {
612
+ return children[0];
613
+ }
614
+ return processComplexContent(
615
+ children,
616
+ getPropertySchema(schema, tagName),
617
+ textNodeName
618
+ );
619
+ }
620
+ function addAttributesToValue(value, attributes, textNodeName) {
621
+ if (Object.keys(attributes).length === 0) {
622
+ return value;
623
+ }
624
+ if (typeof value === "string") {
625
+ const valueResult = { [textNodeName]: value };
626
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
627
+ valueResult[`@_${attrName}`] = attrValue;
628
+ }
629
+ return valueResult;
630
+ }
631
+ if (value && typeof value === "object" && !Array.isArray(value)) {
632
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
633
+ value[`@_${attrName}`] = attrValue;
634
+ }
635
+ }
636
+ return value;
637
+ }
638
+ function addToResult(result, tagName, value) {
639
+ if (result[tagName]) {
640
+ if (!Array.isArray(result[tagName])) {
641
+ result[tagName] = [result[tagName]];
642
+ }
643
+ result[tagName].push(value);
644
+ } else {
645
+ result[tagName] = value;
646
+ }
647
+ }
648
+ function domToObject(nodes, schema, textNodeName = "#text") {
649
+ const result = {};
650
+ for (const node of nodes) {
651
+ if (typeof node === "string") {
652
+ continue;
653
+ }
654
+ const { tagName, children, attributes } = node;
655
+ let value = getNodeValue(children, schema, tagName, textNodeName);
656
+ value = addAttributesToValue(value, attributes, textNodeName);
657
+ addToResult(result, tagName, value);
658
+ }
659
+ return result;
660
+ }
661
+ function processChildElement(child, schema, textNodeName) {
662
+ let childValue;
663
+ if (child.children.length === 0) {
664
+ childValue = "";
665
+ } else if (child.children.length === 1 && typeof child.children[0] === "string") {
666
+ childValue = child.children[0];
667
+ } else {
668
+ childValue = processComplexContent(
669
+ child.children,
670
+ getPropertySchema(schema, child.tagName),
671
+ textNodeName
672
+ );
673
+ }
674
+ return addAttributesToValue(childValue, child.attributes, textNodeName);
675
+ }
676
+ function combineContent(textContent, elements, textNodeName) {
677
+ const hasText = textContent.length > 0;
678
+ const hasElements = Object.keys(elements).length > 0;
679
+ if (hasText && hasElements) {
680
+ return {
681
+ [textNodeName]: textContent.join("").trim(),
682
+ ...elements
683
+ };
684
+ }
685
+ if (hasText) {
686
+ return textContent.join("").trim();
687
+ }
688
+ if (hasElements) {
689
+ return elements;
690
+ }
691
+ return "";
692
+ }
693
+ function processComplexContent(children, schema, textNodeName) {
694
+ const textContent = [];
695
+ const elements = {};
696
+ for (const child of children) {
697
+ if (typeof child === "string") {
698
+ textContent.push(child);
699
+ } else {
700
+ const childValue = processChildElement(child, schema, textNodeName);
701
+ addToResult(elements, child.tagName, childValue);
702
+ }
703
+ }
704
+ return combineContent(textContent, elements, textNodeName);
705
+ }
706
+ function coerceDomBySchema(domObject, schema) {
707
+ try {
708
+ return coerceBySchema(domObject, schema);
709
+ } catch (error) {
710
+ throw new RXMLCoercionError("Failed to coerce DOM object by schema", error);
711
+ }
712
+ }
713
+ function visitObjectProperties(props, collected, visit) {
714
+ for (const [key, propSchema] of Object.entries(props)) {
715
+ const t = getSchemaType(propSchema);
716
+ if (t === "string") {
717
+ collected.add(key);
718
+ } else if (t === "object" || t === "array") {
719
+ visit(propSchema);
720
+ }
721
+ }
722
+ }
723
+ function visitArrayItems(u, visit) {
724
+ const items = u.items;
725
+ if (items) {
726
+ visit(items);
727
+ }
728
+ const prefix = u.prefixItems;
729
+ if (Array.isArray(prefix)) {
730
+ for (const item of prefix) {
731
+ visit(item);
732
+ }
733
+ }
734
+ }
735
+ function getStringTypedProperties(schema) {
736
+ const collected = /* @__PURE__ */ new Set();
737
+ const visit = (s) => {
738
+ const unwrapped = unwrapJsonSchema(s);
739
+ if (!unwrapped || typeof unwrapped !== "object") {
740
+ return;
741
+ }
742
+ const u = unwrapped;
743
+ const type = getSchemaType(unwrapped);
744
+ if (type === "object") {
745
+ const props = u.properties;
746
+ if (props && typeof props === "object") {
747
+ visitObjectProperties(props, collected, visit);
748
+ }
749
+ } else if (type === "array") {
750
+ visitArrayItems(u, visit);
751
+ }
752
+ };
753
+ visit(schema);
754
+ return collected;
755
+ }
756
+ function processArrayContent(value, schema, textNodeName) {
757
+ if (!Array.isArray(value)) {
758
+ return value;
759
+ }
760
+ const schemaType = getSchemaType(schema);
761
+ if (schemaType === "string") {
762
+ return value.map((item) => {
763
+ if (typeof item === "string") {
764
+ return item.trim();
765
+ }
766
+ if (item && typeof item === "object" && textNodeName in item) {
767
+ const textVal = item[textNodeName];
768
+ return typeof textVal === "string" ? textVal.trim() : String(textVal);
769
+ }
770
+ return String(item);
771
+ });
772
+ }
773
+ return value.map((item) => {
774
+ if (typeof item === "string") {
775
+ return item.trim();
776
+ }
777
+ if (item && typeof item === "object" && textNodeName in item) {
778
+ const textVal = item[textNodeName];
779
+ return typeof textVal === "string" ? textVal.trim() : textVal;
780
+ }
781
+ return item;
782
+ });
783
+ }
784
+ function processIndexedTuple(obj, textNodeName) {
785
+ const keys = Object.keys(obj);
786
+ const indices = keys.map((k) => Number.parseInt(k, 10)).sort((a, b) => a - b);
787
+ const isValidTuple = indices[0] === 0 && indices.every((val, idx) => val === idx);
788
+ if (!isValidTuple) {
789
+ return [obj];
790
+ }
791
+ const sortedKeys = keys.sort(
792
+ (a, b) => Number.parseInt(a, 10) - Number.parseInt(b, 10)
793
+ );
794
+ return sortedKeys.map((key) => {
795
+ const item = obj[key];
796
+ if (item && typeof item === "object" && textNodeName in item) {
797
+ const textVal = item[textNodeName];
798
+ return typeof textVal === "string" ? textVal.trim() : textVal;
799
+ }
800
+ return typeof item === "string" ? item.trim() : item;
801
+ });
802
+ }
803
+
804
+ // src/rxml/schema/extraction.ts
805
+ function skipDoctype(xmlContent, i, len) {
806
+ const gt = xmlContent.indexOf(">", i + 1);
807
+ return gt === -1 ? len : gt + 1;
808
+ }
809
+ function skipComment(xmlContent, i, len) {
810
+ const close = xmlContent.indexOf("-->", i + 4);
811
+ return close === -1 ? len : close + 3;
812
+ }
813
+ function skipCdata(xmlContent, i, len) {
814
+ const close = xmlContent.indexOf("]]>", i + 9);
815
+ return close === -1 ? len : close + 3;
816
+ }
817
+ function skipProcessingInstruction(xmlContent, i, len) {
818
+ const close = xmlContent.indexOf("?>", i + 1);
819
+ return close === -1 ? len : close + 2;
820
+ }
821
+ function skipSpecialConstruct(xmlContent, i, len) {
822
+ const ch = xmlContent[i];
823
+ if (ch === "!") {
824
+ if (xmlContent.startsWith("!DOCTYPE", i + 1)) {
825
+ return skipDoctype(xmlContent, i, len);
826
+ }
827
+ if (xmlContent.startsWith("!--", i + 1)) {
828
+ return skipComment(xmlContent, i, len);
829
+ }
830
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
831
+ return skipCdata(xmlContent, i, len);
832
+ }
833
+ const gt = xmlContent.indexOf(">", i + 1);
834
+ return gt === -1 ? len : gt + 1;
835
+ }
836
+ if (ch === "?") {
837
+ return skipProcessingInstruction(xmlContent, i, len);
838
+ }
839
+ return -1;
840
+ }
841
+ function parseTagName(xmlContent, i, len) {
842
+ let j = i;
843
+ if (j < len && isNameStartChar(xmlContent[j])) {
844
+ j += 1;
845
+ while (j < len && isNameChar(xmlContent[j])) {
846
+ j += 1;
847
+ }
848
+ }
849
+ return { name: xmlContent.slice(i, j), pos: j };
850
+ }
851
+ function skipToTagEnd(xmlContent, start, len) {
852
+ let k = start;
853
+ let isSelfClosing = false;
854
+ while (k < len) {
855
+ const c = xmlContent[k];
856
+ if (c === '"' || c === "'") {
857
+ k = skipQuoted(xmlContent, k);
858
+ continue;
859
+ }
860
+ if (c === ">") {
861
+ break;
862
+ }
863
+ if (c === "/" && xmlContent[k + 1] === ">") {
864
+ isSelfClosing = true;
865
+ k += 1;
866
+ break;
867
+ }
868
+ k += 1;
869
+ }
870
+ return { pos: k, isSelfClosing };
871
+ }
872
+ function processClosingTagMatch(options) {
873
+ const { xmlContent, nx, len, tagName, depth, nextLt } = options;
874
+ const tagInfo = parseTagName(xmlContent, nx + 1, len);
875
+ const gt = xmlContent.indexOf(">", tagInfo.pos);
876
+ if (tagInfo.name === tagName) {
877
+ const newDepth = depth - 1;
878
+ if (newDepth === 0) {
879
+ return { newPos: nextLt, newDepth, found: true };
880
+ }
881
+ return { newPos: gt === -1 ? len : gt + 1, newDepth, found: false };
882
+ }
883
+ return { newPos: gt === -1 ? len : gt + 1, newDepth: depth, found: false };
884
+ }
885
+ function processOpeningTagMatch(options) {
886
+ const { xmlContent, nx, len, tagName, depth } = options;
887
+ const tagInfo = parseTagName(xmlContent, nx, len);
888
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
889
+ const newDepth = tagInfo.name === tagName && !tagEndInfo.isSelfClosing ? depth + 1 : depth;
890
+ const newPos = xmlContent[tagEndInfo.pos] === ">" ? tagEndInfo.pos + 1 : tagEndInfo.pos + 1;
891
+ return { newPos, newDepth };
892
+ }
893
+ function findMatchingCloseTag(xmlContent, startPos, tagName, len) {
894
+ let pos = startPos;
895
+ let depth = 1;
896
+ while (pos < len) {
897
+ const nextLt = xmlContent.indexOf("<", pos);
898
+ if (nextLt === -1 || nextLt + 1 >= len) {
899
+ break;
900
+ }
901
+ const nx = nextLt + 1;
902
+ const h = xmlContent[nx];
903
+ const specialPos = skipSpecialConstruct(xmlContent, nx, len);
904
+ if (specialPos !== -1) {
905
+ pos = specialPos;
906
+ continue;
907
+ }
908
+ if (h === "/") {
909
+ const result = processClosingTagMatch({
910
+ xmlContent,
911
+ nx,
912
+ len,
913
+ tagName,
914
+ depth,
915
+ nextLt
916
+ });
917
+ if (result.found) {
918
+ return result.newPos;
919
+ }
920
+ pos = result.newPos;
921
+ depth = result.newDepth;
922
+ } else {
923
+ const result = processOpeningTagMatch({
924
+ xmlContent,
925
+ nx,
926
+ len,
927
+ tagName,
928
+ depth
929
+ });
930
+ pos = result.newPos;
931
+ depth = result.newDepth;
932
+ }
933
+ }
934
+ return -1;
935
+ }
936
+ function updateBestMatch(depth, bestDepth, contentStart, contentEnd) {
937
+ if (depth < bestDepth) {
938
+ return { start: contentStart, end: contentEnd, depth };
939
+ }
940
+ return null;
941
+ }
942
+ function processTargetTag(options) {
943
+ const { xmlContent, tagEnd, isSelfClosing, target, len, depth, bestDepth } = options;
944
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
945
+ if (isSelfClosing) {
946
+ return updateBestMatch(depth, bestDepth, contentStart, contentStart);
947
+ }
948
+ const closePos = findMatchingCloseTag(xmlContent, contentStart, target, len);
949
+ if (closePos !== -1) {
950
+ return updateBestMatch(depth, bestDepth, contentStart, closePos);
951
+ }
952
+ return null;
953
+ }
954
+ function handleClosingTagInExtract(xmlContent, i, len, depth) {
955
+ const gt = xmlContent.indexOf(">", i + 1);
956
+ return {
957
+ newPos: gt === -1 ? len : gt + 1,
958
+ newDepth: Math.max(0, depth - 1)
959
+ };
960
+ }
961
+ function processOpeningTagInExtract(options) {
962
+ const { xmlContent, i, len, target, depth, bestDepth } = options;
963
+ const tagInfo = parseTagName(xmlContent, i, len);
964
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
965
+ const tagEnd = tagEndInfo.pos;
966
+ const isSelfClosing = tagEndInfo.isSelfClosing;
967
+ let bestMatch = null;
968
+ if (tagInfo.name === target) {
969
+ bestMatch = processTargetTag({
970
+ xmlContent,
971
+ tagEnd,
972
+ isSelfClosing,
973
+ target,
974
+ len,
975
+ depth,
976
+ bestDepth
977
+ });
978
+ }
979
+ return {
980
+ newPos: xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1,
981
+ newDepth: depth + (isSelfClosing ? 0 : 1),
982
+ bestMatch
983
+ };
984
+ }
985
+ function extractRawInner(xmlContent, tagName) {
986
+ const len = xmlContent.length;
987
+ const target = tagName;
988
+ let bestStart = -1;
989
+ let bestEnd = -1;
990
+ let bestDepth = Number.POSITIVE_INFINITY;
991
+ let i = 0;
992
+ let depth = 0;
993
+ while (i < len) {
994
+ const lt = xmlContent.indexOf("<", i);
995
+ if (lt === -1 || lt + 1 >= len) {
996
+ return;
997
+ }
998
+ i = lt + 1;
999
+ const ch = xmlContent[i];
1000
+ const specialPos = skipSpecialConstruct(xmlContent, i, len);
1001
+ if (specialPos !== -1) {
1002
+ i = specialPos;
1003
+ continue;
1004
+ }
1005
+ if (ch === "/") {
1006
+ const result2 = handleClosingTagInExtract(xmlContent, i, len, depth);
1007
+ i = result2.newPos;
1008
+ depth = result2.newDepth;
1009
+ continue;
1010
+ }
1011
+ const result = processOpeningTagInExtract({
1012
+ xmlContent,
1013
+ i,
1014
+ len,
1015
+ target,
1016
+ depth,
1017
+ bestDepth
1018
+ });
1019
+ if (result.bestMatch) {
1020
+ bestStart = result.bestMatch.start;
1021
+ bestEnd = result.bestMatch.end;
1022
+ bestDepth = result.bestMatch.depth;
1023
+ }
1024
+ i = result.newPos;
1025
+ depth = result.newDepth;
1026
+ }
1027
+ if (bestStart !== -1) {
1028
+ return xmlContent.slice(bestStart, bestEnd);
1029
+ }
1030
+ return;
1031
+ }
1032
+ function processOpeningTag(options) {
1033
+ const { xmlContent, tagEnd, isSelfClosing, target, len, ranges } = options;
1034
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1035
+ if (isSelfClosing) {
1036
+ ranges.push({ start: contentStart, end: contentStart });
1037
+ return contentStart;
1038
+ }
1039
+ const closePos = findMatchingCloseTag(xmlContent, contentStart, target, len);
1040
+ if (closePos !== -1) {
1041
+ ranges.push({ start: contentStart, end: closePos });
1042
+ const gt = xmlContent.indexOf(">", closePos);
1043
+ return gt === -1 ? len : gt + 1;
1044
+ }
1045
+ return -1;
1046
+ }
1047
+ function handleClosingTagInFindAll(xmlContent, i, len) {
1048
+ const gt = xmlContent.indexOf(">", i + 1);
1049
+ return gt === -1 ? len : gt + 1;
1050
+ }
1051
+ function findAllInnerRanges(xmlContent, tagName) {
1052
+ const len = xmlContent.length;
1053
+ const target = tagName;
1054
+ const ranges = [];
1055
+ let i = 0;
1056
+ while (i < len) {
1057
+ const lt = xmlContent.indexOf("<", i);
1058
+ if (lt === -1 || lt + 1 >= len) {
1059
+ break;
1060
+ }
1061
+ i = lt + 1;
1062
+ const ch = xmlContent[i];
1063
+ const specialPos = skipSpecialConstruct(xmlContent, i, len);
1064
+ if (specialPos !== -1) {
1065
+ i = specialPos;
1066
+ continue;
1067
+ }
1068
+ if (ch === "/") {
1069
+ i = handleClosingTagInFindAll(xmlContent, i, len);
1070
+ continue;
1071
+ }
1072
+ const tagInfo = parseTagName(xmlContent, i, len);
1073
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
1074
+ const tagEnd = tagEndInfo.pos;
1075
+ const isSelfClosing = tagEndInfo.isSelfClosing;
1076
+ if (tagInfo.name !== target) {
1077
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1078
+ continue;
1079
+ }
1080
+ const nextPos = processOpeningTag({
1081
+ xmlContent,
1082
+ tagEnd,
1083
+ isSelfClosing,
1084
+ target,
1085
+ len,
1086
+ ranges
1087
+ });
1088
+ if (nextPos === -1) {
1089
+ break;
1090
+ }
1091
+ i = nextPos;
1092
+ }
1093
+ return ranges;
1094
+ }
1095
+ function findTopLevelTargetRange(options) {
1096
+ const { xmlContent, tagEnd, isSelfClosing, target, len } = options;
1097
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1098
+ if (isSelfClosing) {
1099
+ return { start: contentStart, end: contentStart };
1100
+ }
1101
+ const closePos = findMatchingCloseTag(xmlContent, contentStart, target, len);
1102
+ if (closePos !== -1) {
1103
+ return { start: contentStart, end: closePos };
1104
+ }
1105
+ return;
1106
+ }
1107
+ function handleClosingTagInFindFirst(xmlContent, i, len, depth) {
1108
+ const gt = xmlContent.indexOf(">", i + 1);
1109
+ return {
1110
+ newPos: gt === -1 ? len : gt + 1,
1111
+ newDepth: Math.max(0, depth - 1)
1112
+ };
1113
+ }
1114
+ function findFirstTopLevelRange(xmlContent, tagName) {
1115
+ const len = xmlContent.length;
1116
+ const target = tagName;
1117
+ let i = 0;
1118
+ let depth = 0;
1119
+ while (i < len) {
1120
+ const lt = xmlContent.indexOf("<", i);
1121
+ if (lt === -1 || lt + 1 >= len) {
1122
+ return;
1123
+ }
1124
+ i = lt + 1;
1125
+ const ch = xmlContent[i];
1126
+ const specialPos = skipSpecialConstruct(xmlContent, i, len);
1127
+ if (specialPos !== -1) {
1128
+ i = specialPos;
1129
+ continue;
1130
+ }
1131
+ if (ch === "/") {
1132
+ const result = handleClosingTagInFindFirst(xmlContent, i, len, depth);
1133
+ i = result.newPos;
1134
+ depth = result.newDepth;
1135
+ continue;
1136
+ }
1137
+ const tagInfo = parseTagName(xmlContent, i, len);
1138
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
1139
+ const tagEnd = tagEndInfo.pos;
1140
+ const isSelfClosing = tagEndInfo.isSelfClosing;
1141
+ if (depth === 0 && tagInfo.name === target) {
1142
+ return findTopLevelTargetRange({
1143
+ xmlContent,
1144
+ tagEnd,
1145
+ isSelfClosing,
1146
+ target,
1147
+ len
1148
+ });
1149
+ }
1150
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
1151
+ depth += isSelfClosing ? 0 : 1;
1152
+ }
1153
+ return;
1154
+ }
1155
+ function isPositionExcluded(pos, excludeRanges) {
1156
+ if (!excludeRanges || excludeRanges.length === 0) {
1157
+ return false;
1158
+ }
1159
+ for (const r of excludeRanges) {
1160
+ if (pos >= r.start && pos < r.end) {
1161
+ return true;
1162
+ }
1163
+ }
1164
+ return false;
1165
+ }
1166
+ function skipCommentInCounting(xmlContent, i, len) {
1167
+ const close = xmlContent.indexOf("-->", i + 4);
1168
+ return close === -1 ? len : close + 3;
1169
+ }
1170
+ function skipCdataInCounting(xmlContent, i, len) {
1171
+ const close = xmlContent.indexOf("]]>", i + 9);
1172
+ return close === -1 ? len : close + 3;
1173
+ }
1174
+ function skipSpecialInCounting(xmlContent, ch, i, len) {
1175
+ if (ch === "!") {
1176
+ if (xmlContent.startsWith("!--", i + 1)) {
1177
+ return skipCommentInCounting(xmlContent, i, len);
1178
+ }
1179
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
1180
+ return skipCdataInCounting(xmlContent, i, len);
1181
+ }
1182
+ const gt = xmlContent.indexOf(">", i + 1);
1183
+ return gt === -1 ? len : gt + 1;
1184
+ }
1185
+ if (ch === "?") {
1186
+ const close = xmlContent.indexOf("?>", i + 1);
1187
+ return close === -1 ? len : close + 2;
1188
+ }
1189
+ if (ch === "/") {
1190
+ const gt = xmlContent.indexOf(">", i + 1);
1191
+ return gt === -1 ? len : gt + 1;
1192
+ }
1193
+ return -1;
1194
+ }
1195
+ function parseAndCountTag(options) {
1196
+ const { xmlContent, i, len, target, lt, excludeRanges } = options;
1197
+ let j = i;
1198
+ if (j < len && isNameStartChar(xmlContent[j])) {
1199
+ j += 1;
1200
+ while (j < len && isNameChar(xmlContent[j])) {
1201
+ j += 1;
1202
+ }
1203
+ }
1204
+ const name = xmlContent.slice(i, j);
1205
+ let k = j;
1206
+ while (k < len) {
1207
+ const c = xmlContent[k];
1208
+ if (c === '"' || c === "'") {
1209
+ k = skipQuoted(xmlContent, k);
1210
+ continue;
1211
+ }
1212
+ if (c === ">") {
1213
+ break;
1214
+ }
1215
+ if (c === "/" && xmlContent[k + 1] === ">") {
1216
+ k += 1;
1217
+ break;
1218
+ }
1219
+ k += 1;
1220
+ }
1221
+ const shouldCount = name === target && !isPositionExcluded(lt, excludeRanges);
1222
+ return { nextPos: k + 1, shouldCount };
1223
+ }
1224
+ function countTagOccurrences(xmlContent, tagName, excludeRanges, shouldSkipFirst = true) {
1225
+ const len = xmlContent.length;
1226
+ const target = tagName;
1227
+ let i = 0;
1228
+ let count = 0;
1229
+ let skipFirstLocal = shouldSkipFirst;
1230
+ while (i < len) {
1231
+ const lt = xmlContent.indexOf("<", i);
1232
+ if (lt === -1) {
1233
+ break;
1234
+ }
1235
+ i = lt + 1;
1236
+ if (i >= len) {
1237
+ break;
1238
+ }
1239
+ const ch = xmlContent[i];
1240
+ const skipPos = skipSpecialInCounting(xmlContent, ch, i, len);
1241
+ if (skipPos !== -1) {
1242
+ i = skipPos;
1243
+ continue;
1244
+ }
1245
+ const result = parseAndCountTag({
1246
+ xmlContent,
1247
+ i,
1248
+ len,
1249
+ target,
1250
+ lt,
1251
+ excludeRanges
1252
+ });
1253
+ if (result.shouldCount) {
1254
+ if (skipFirstLocal) {
1255
+ skipFirstLocal = false;
1256
+ } else {
1257
+ count += 1;
1258
+ }
1259
+ }
1260
+ i = result.nextPos;
1261
+ }
1262
+ return count;
1263
+ }
1264
+
1265
+ // src/rxml/core/tokenizer.ts
1266
+ var XMLTokenizer = class {
1267
+ constructor(xmlString, options = {}) {
1268
+ this.pos = 0;
1269
+ this.xmlString = xmlString;
1270
+ this.options = {
1271
+ keepComments: false,
1272
+ keepWhitespace: false,
1273
+ noChildNodes: DEFAULT_NO_CHILD_NODES.slice(),
1274
+ textNodeName: "#text",
1275
+ throwOnDuplicateStringTags: true,
1276
+ ...options
1277
+ };
1278
+ this.pos = options.pos || 0;
1279
+ }
1280
+ /**
1281
+ * Handle closing tag parsing
1282
+ */
1283
+ handleClosingTag(tagName, children) {
1284
+ const closeStart = this.pos + 2;
1285
+ this.pos = this.xmlString.indexOf(">", this.pos);
1286
+ const closeTag = this.xmlString.substring(closeStart, this.pos);
1287
+ if (tagName && closeTag.trim() !== tagName) {
1288
+ const { line, column } = getLineColumn(this.xmlString, this.pos);
1289
+ throw new RXMLParseError(
1290
+ `Unexpected close tag at line ${line}, column ${column}. Expected </${tagName}>, found </${closeTag}>`,
1291
+ void 0,
1292
+ line,
1293
+ column
1294
+ );
1295
+ }
1296
+ if (this.pos !== -1) {
1297
+ this.pos += 1;
1298
+ }
1299
+ return children;
1300
+ }
1301
+ /**
1302
+ * Check if we're at end of string and should throw unclosed tag error
1303
+ */
1304
+ checkUnclosedTag(tagName, consumedToEnd) {
1305
+ if (tagName && this.pos >= this.xmlString.length && !consumedToEnd) {
1306
+ const { line, column } = getLineColumn(this.xmlString, this.pos - 1);
1307
+ throw new RXMLParseError(
1308
+ `Unclosed tag at line ${line}, column ${column}. Expected closing tag </${tagName}>`,
1309
+ void 0,
1310
+ line,
1311
+ column
1312
+ );
1313
+ }
1314
+ }
1315
+ /**
1316
+ * Process special content (comments, CDATA, DOCTYPE) and track if we consumed to end
1317
+ */
1318
+ processSpecialContent(children) {
1319
+ const prevPos = this.pos;
1320
+ this.handleSpecialContent(children);
1321
+ return this.pos >= this.xmlString.length && prevPos < this.xmlString.length;
1322
+ }
1323
+ /**
1324
+ * Handle text content parsing
1325
+ */
1326
+ handleTextContent(children) {
1327
+ const text = this.parseText();
1328
+ if (this.options.keepWhitespace) {
1329
+ if (text.length > 0) {
1330
+ children.push(text);
1331
+ }
1332
+ } else {
1333
+ const trimmed = text.trim();
1334
+ if (trimmed.length > 0) {
1335
+ children.push(trimmed);
1336
+ }
1337
+ }
1338
+ this.pos += 1;
1339
+ }
1340
+ /**
1341
+ * Handle regular element parsing
1342
+ */
1343
+ handleRegularElement(children) {
1344
+ const node = this.parseNode();
1345
+ children.push(node);
1346
+ if (node.tagName[0] === "?") {
1347
+ children.push(...node.children);
1348
+ node.children = [];
1349
+ }
1350
+ }
1351
+ /**
1352
+ * Process a single child element based on the current character
1353
+ */
1354
+ processSingleChild(children, tagName) {
1355
+ if (this.xmlString.charCodeAt(this.pos) !== CharCodes.OPEN_BRACKET) {
1356
+ this.handleTextContent(children);
1357
+ return { shouldReturn: false, consumedToEnd: false };
1358
+ }
1359
+ const nextChar = this.xmlString.charCodeAt(this.pos + 1);
1360
+ if (nextChar === CharCodes.SLASH) {
1361
+ const result = this.handleClosingTag(tagName, children);
1362
+ if (result !== null) {
1363
+ return { shouldReturn: true, consumedToEnd: false };
1364
+ }
1365
+ return { shouldReturn: false, consumedToEnd: false };
1366
+ }
1367
+ if (nextChar === CharCodes.EXCLAMATION) {
1368
+ const wasConsumedToEnd = this.processSpecialContent(children);
1369
+ return { shouldReturn: false, consumedToEnd: wasConsumedToEnd };
1370
+ }
1371
+ this.handleRegularElement(children);
1372
+ return { shouldReturn: false, consumedToEnd: false };
1373
+ }
1374
+ /**
1375
+ * Parse XML children recursively
1376
+ */
1377
+ parseChildren(tagName) {
1378
+ const children = [];
1379
+ let consumedToEnd = false;
1380
+ while (this.xmlString[this.pos]) {
1381
+ const result = this.processSingleChild(children, tagName);
1382
+ if (result.shouldReturn) {
1383
+ return children;
1384
+ }
1385
+ if (result.consumedToEnd) {
1386
+ consumedToEnd = true;
1387
+ }
1388
+ }
1389
+ this.checkUnclosedTag(tagName, consumedToEnd);
1390
+ return children;
1391
+ }
1392
+ /**
1393
+ * Check if character is whitespace
1394
+ */
1395
+ isWhitespace(code) {
1396
+ return code === CharCodes.SPACE || code === CharCodes.TAB || code === CharCodes.NEWLINE || code === CharCodes.CARRIAGE_RETURN;
1397
+ }
1398
+ /**
1399
+ * Skip whitespace characters
1400
+ */
1401
+ skipWhitespace() {
1402
+ while (this.pos < this.xmlString.length && this.isWhitespace(this.xmlString.charCodeAt(this.pos))) {
1403
+ this.pos += 1;
1404
+ }
1405
+ }
1406
+ /**
1407
+ * Parse attribute value
1408
+ */
1409
+ parseAttributeValue() {
1410
+ if (this.pos >= this.xmlString.length || this.xmlString[this.pos] !== "=") {
1411
+ return null;
1412
+ }
1413
+ this.pos += 1;
1414
+ this.skipWhitespace();
1415
+ const code = this.xmlString.charCodeAt(this.pos);
1416
+ if (code === CharCodes.SINGLE_QUOTE || code === CharCodes.DOUBLE_QUOTE) {
1417
+ const { value: parsedValue, newPos: valueEnd } = parseString(
1418
+ this.xmlString,
1419
+ this.pos
1420
+ );
1421
+ this.pos = valueEnd;
1422
+ return parsedValue;
1423
+ }
1424
+ return null;
1425
+ }
1426
+ /**
1427
+ * Parse single attribute
1428
+ */
1429
+ parseAttribute(attributes) {
1430
+ const { name: attrName, newPos: nameEnd } = parseName(
1431
+ this.xmlString,
1432
+ this.pos
1433
+ );
1434
+ this.pos = nameEnd;
1435
+ this.skipWhitespace();
1436
+ const value = this.parseAttributeValue();
1437
+ attributes[attrName] = value;
1438
+ }
1439
+ /**
1440
+ * Parse all attributes
1441
+ */
1442
+ parseAttributes() {
1443
+ const attributes = {};
1444
+ while (this.xmlString.charCodeAt(this.pos) !== CharCodes.CLOSE_BRACKET && this.xmlString[this.pos]) {
1445
+ const c = this.xmlString.charCodeAt(this.pos);
1446
+ if (this.isWhitespace(c)) {
1447
+ this.pos += 1;
1448
+ continue;
1449
+ }
1450
+ if (c > 64 && c < 91 || c > 96 && c < 123) {
1451
+ this.parseAttribute(attributes);
1452
+ } else {
1453
+ this.pos += 1;
1454
+ }
1455
+ }
1456
+ return attributes;
1457
+ }
1458
+ /**
1459
+ * Parse special tag content (script, style)
1460
+ */
1461
+ parseSpecialTagContent(_tagName, closingTag) {
1462
+ const start = this.pos + 1;
1463
+ this.pos = this.xmlString.indexOf(closingTag, this.pos);
1464
+ if (this.pos === -1) {
1465
+ const children2 = [this.xmlString.slice(start)];
1466
+ this.pos = this.xmlString.length;
1467
+ return children2;
1468
+ }
1469
+ const children = [this.xmlString.slice(start, this.pos)];
1470
+ this.pos += closingTag.length;
1471
+ return children;
1472
+ }
1473
+ /**
1474
+ * Parse node children based on tag type
1475
+ */
1476
+ parseNodeChildren(tagName, isSelfClosing) {
1477
+ var _a;
1478
+ if (isSelfClosing) {
1479
+ this.pos += 1;
1480
+ return [];
1481
+ }
1482
+ if (tagName === "script") {
1483
+ return this.parseSpecialTagContent(tagName, "</script>");
1484
+ }
1485
+ if (tagName === "style") {
1486
+ return this.parseSpecialTagContent(tagName, "</style>");
1487
+ }
1488
+ if (((_a = this.options.noChildNodes) == null ? void 0 : _a.indexOf(tagName)) === -1) {
1489
+ this.pos += 1;
1490
+ return this.parseChildren(tagName);
1491
+ }
1492
+ this.pos += 1;
1493
+ if (DEFAULT_NO_CHILD_NODES.includes(tagName)) {
1494
+ return [];
1495
+ }
1496
+ const closingTag = `</${tagName}>`;
1497
+ const closingPos = this.xmlString.indexOf(closingTag, this.pos);
1498
+ if (closingPos !== -1) {
1499
+ this.pos = closingPos + closingTag.length;
1500
+ }
1501
+ return [];
1502
+ }
1503
+ /**
1504
+ * Parse a single XML node
1505
+ */
1506
+ parseNode() {
1507
+ this.pos += 1;
1508
+ const { name: tagName, newPos } = parseName(this.xmlString, this.pos);
1509
+ this.pos = newPos;
1510
+ const attributes = this.parseAttributes();
1511
+ const isSelfClosing = this.xmlString.charCodeAt(this.pos - 1) === CharCodes.SLASH || tagName[0] === "?" && this.xmlString.charCodeAt(this.pos - 1) === CharCodes.QUESTION;
1512
+ const children = this.parseNodeChildren(tagName, isSelfClosing);
1513
+ return { tagName, attributes, children };
1514
+ }
1515
+ /**
1516
+ * Parse text content until next tag
1517
+ */
1518
+ parseText() {
1519
+ const start = this.pos;
1520
+ this.pos = this.xmlString.indexOf("<", this.pos) - 1;
1521
+ if (this.pos === -2) {
1522
+ this.pos = this.xmlString.length;
1523
+ }
1524
+ return this.xmlString.slice(start, this.pos + 1);
1525
+ }
1526
+ /**
1527
+ * Handle comments, CDATA, and DOCTYPE declarations
1528
+ */
1529
+ handleSpecialContent(children) {
1530
+ if (this.xmlString.charCodeAt(this.pos + 2) === CharCodes.MINUS) {
1531
+ this.handleComment(children);
1532
+ } 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") {
1533
+ this.handleCData(children);
1534
+ } else {
1535
+ this.handleDoctype(children);
1536
+ }
1537
+ }
1538
+ /**
1539
+ * Handle XML comments
1540
+ */
1541
+ handleComment(children) {
1542
+ const startCommentPos = this.pos;
1543
+ 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)) {
1544
+ this.pos = this.xmlString.indexOf(">", this.pos + 1);
1545
+ }
1546
+ if (this.pos === -1) {
1547
+ this.pos = this.xmlString.length;
1548
+ }
1549
+ if (this.options.keepComments) {
1550
+ children.push(this.xmlString.substring(startCommentPos, this.pos + 1));
1551
+ }
1552
+ this.pos += 1;
1553
+ }
1554
+ /**
1555
+ * Handle CDATA sections
1556
+ */
1557
+ handleCData(children) {
1558
+ const cdataEndIndex = this.xmlString.indexOf("]]>", this.pos);
1559
+ if (cdataEndIndex === -1) {
1560
+ children.push(this.xmlString.substr(this.pos + 9));
1561
+ this.pos = this.xmlString.length;
1562
+ } else {
1563
+ children.push(this.xmlString.substring(this.pos + 9, cdataEndIndex));
1564
+ this.pos = cdataEndIndex + 3;
1565
+ }
1566
+ }
1567
+ /**
1568
+ * Handle DOCTYPE declarations
1569
+ */
1570
+ handleDoctype(children) {
1571
+ const startDoctype = this.pos + 1;
1572
+ this.pos += 2;
1573
+ let encapsulated = false;
1574
+ while ((this.xmlString.charCodeAt(this.pos) !== CharCodes.CLOSE_BRACKET || encapsulated) && this.xmlString[this.pos]) {
1575
+ if (this.xmlString.charCodeAt(this.pos) === CharCodes.OPEN_CORNER_BRACKET) {
1576
+ encapsulated = true;
1577
+ } else if (encapsulated && this.xmlString.charCodeAt(this.pos) === CharCodes.CLOSE_CORNER_BRACKET) {
1578
+ encapsulated = false;
1579
+ }
1580
+ this.pos += 1;
1581
+ }
1582
+ children.push(this.xmlString.substring(startDoctype, this.pos));
1583
+ this.pos += 1;
1584
+ }
1585
+ /**
1586
+ * Get current position
1587
+ */
1588
+ getPosition() {
1589
+ return this.pos;
1590
+ }
1591
+ /**
1592
+ * Set position
1593
+ */
1594
+ setPosition(pos) {
1595
+ this.pos = pos;
1596
+ }
1597
+ };
1598
+
1599
+ // src/rxml/core/parser.ts
1600
+ var WHITESPACE_REGEX = /\s/;
1601
+ var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
1602
+ var DIGIT_KEY_REGEX2 = /^\d+$/;
1603
+ function getTopLevelStringProps(s) {
1604
+ const set = /* @__PURE__ */ new Set();
1605
+ const unwrapped = unwrapJsonSchema(s);
1606
+ if (unwrapped && typeof unwrapped === "object") {
1607
+ const props = unwrapped.properties;
1608
+ if (props && typeof props === "object") {
1609
+ for (const [k, v] of Object.entries(props)) {
1610
+ if (getSchemaType(v) === "string") {
1611
+ set.add(k);
1612
+ }
1613
+ }
1614
+ }
1615
+ }
1616
+ return set;
1617
+ }
1618
+ function restorePlaceholderString(val, placeholderMap) {
1619
+ if (val.startsWith("__RXML_PLACEHOLDER_")) {
1620
+ const orig = placeholderMap.get(val);
1621
+ return orig !== void 0 ? orig : val;
1622
+ }
1623
+ return val;
1624
+ }
1625
+ function restorePlaceholdersInObject(obj, _placeholderMap, textNodeName, restorer) {
1626
+ const out = {};
1627
+ for (const [k, v] of Object.entries(obj)) {
1628
+ const restored = restorer(v);
1629
+ if (k === textNodeName && typeof restored === "string") {
1630
+ out[k] = restored.trim();
1631
+ } else {
1632
+ out[k] = restored;
1633
+ }
1634
+ }
1635
+ return out;
1636
+ }
1637
+ function createPlaceholderRestorer(placeholderMap, textNodeName) {
1638
+ const restorer = (val) => {
1639
+ if (val == null) {
1640
+ return val;
1641
+ }
1642
+ if (typeof val === "string") {
1643
+ return restorePlaceholderString(val, placeholderMap);
1644
+ }
1645
+ if (Array.isArray(val)) {
1646
+ return val.map(restorer);
1647
+ }
1648
+ if (typeof val === "object") {
1649
+ return restorePlaceholdersInObject(
1650
+ val,
1651
+ placeholderMap,
1652
+ textNodeName,
1653
+ restorer
1654
+ );
1655
+ }
1656
+ return val;
1657
+ };
1658
+ return restorer;
1659
+ }
1660
+ function tryConvertToNumber(val) {
1661
+ if (typeof val !== "string") {
1662
+ return val;
1663
+ }
1664
+ const trimmed = val.trim();
1665
+ if (NUMERIC_STRING_REGEX.test(trimmed)) {
1666
+ const num = Number(trimmed);
1667
+ if (Number.isFinite(num)) {
1668
+ return num;
1669
+ }
1670
+ }
1671
+ return trimmed;
1672
+ }
1673
+ function processItemValue(item, textNodeName) {
1674
+ let currentVal = item;
1675
+ if (item && typeof item === "object" && Object.hasOwn(item, textNodeName)) {
1676
+ currentVal = item[textNodeName];
1677
+ }
1678
+ const trimmed = typeof currentVal === "string" ? currentVal.trim() : currentVal;
1679
+ return tryConvertToNumber(trimmed);
1680
+ }
1681
+ function processItemWrapper(itemValue, textNodeName) {
1682
+ if (Array.isArray(itemValue)) {
1683
+ return itemValue.map((item) => processItemValue(item, textNodeName));
1684
+ }
1685
+ const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1686
+ return tryConvertToNumber(trimmed);
1687
+ }
1688
+ function deepDecodeStringsBySchema(input, schema) {
1689
+ var _a;
1690
+ if (input == null || schema == null) {
1691
+ return input;
1692
+ }
1693
+ const type = getSchemaType(schema);
1694
+ if (type === "string" && typeof input === "string") {
1695
+ return unescapeXml(input);
1696
+ }
1697
+ if (type === "array" && Array.isArray(input)) {
1698
+ const unwrapped = unwrapJsonSchema(schema);
1699
+ const itemSchema = (_a = unwrapped == null ? void 0 : unwrapped.items) != null ? _a : {};
1700
+ return input.map((item) => deepDecodeStringsBySchema(item, itemSchema));
1701
+ }
1702
+ if (type === "object" && input && typeof input === "object") {
1703
+ const obj = input;
1704
+ const out = {};
1705
+ for (const key of Object.keys(obj)) {
1706
+ const childSchema = getPropertySchema(schema, key);
1707
+ out[key] = deepDecodeStringsBySchema(obj[key], childSchema);
1708
+ }
1709
+ return out;
1710
+ }
1711
+ if (typeof input === "string") {
1712
+ return unescapeXml(input);
1713
+ }
1714
+ return input;
1715
+ }
1716
+ function parse(xmlInner, schema, options = {}) {
1717
+ var _a, _b, _c;
1718
+ const textNodeName = (_a = options.textNodeName) != null ? _a : "#text";
1719
+ const throwDup = (_b = options.throwOnDuplicateStringTags) != null ? _b : true;
1720
+ let actualXmlInner = xmlInner.trim();
1721
+ if (actualXmlInner.startsWith("<") && actualXmlInner.endsWith(">")) {
1722
+ const s = actualXmlInner;
1723
+ let i = 0;
1724
+ let rootStart = -1;
1725
+ let rootName = "";
1726
+ while (i < s.length) {
1727
+ const lt = s.indexOf("<", i);
1728
+ if (lt === -1) {
1729
+ break;
1730
+ }
1731
+ const next = s[lt + 1];
1732
+ if (next === "?") {
1733
+ const end = s.indexOf("?>", lt + 2);
1734
+ i = end === -1 ? s.length : end + 2;
1735
+ continue;
1736
+ }
1737
+ if (next === "!") {
1738
+ if (s.startsWith("!--", lt + 2)) {
1739
+ const end2 = s.indexOf("-->", lt + 5);
1740
+ i = end2 === -1 ? s.length : end2 + 3;
1741
+ continue;
1742
+ }
1743
+ if (s.startsWith("![CDATA[", lt + 2)) {
1744
+ const end2 = s.indexOf("]]>", lt + 9);
1745
+ i = end2 === -1 ? s.length : end2 + 3;
1746
+ continue;
1747
+ }
1748
+ const end = s.indexOf(">", lt + 2);
1749
+ i = end === -1 ? s.length : end + 1;
1750
+ continue;
1751
+ }
1752
+ if (next === "/") {
1753
+ break;
1754
+ }
1755
+ let j = lt + 1;
1756
+ while (j < s.length && s[j] !== " " && s[j] !== "\n" && s[j] !== "\r" && s[j] !== " " && s[j] !== "/" && s[j] !== ">") {
1757
+ j += 1;
1758
+ }
1759
+ rootStart = lt;
1760
+ rootName = s.slice(lt + 1, j);
1761
+ break;
1762
+ }
1763
+ if (rootStart === 0 && rootName) {
1764
+ const range = findFirstTopLevelRange(s, rootName);
1765
+ if (range) {
1766
+ let fullEnd = range.end + `</${rootName}>`.length;
1767
+ const closeHead = s.indexOf(`</${rootName}`, range.end);
1768
+ if (closeHead === range.end) {
1769
+ let p = closeHead + 2 + rootName.length;
1770
+ while (p < s.length && WHITESPACE_REGEX.test(s[p])) {
1771
+ p += 1;
1772
+ }
1773
+ if (s[p] === ">") {
1774
+ fullEnd = p + 1;
1775
+ }
1776
+ }
1777
+ if (fullEnd === s.length) {
1778
+ const unwrapped = unwrapJsonSchema(schema);
1779
+ const schemaProps = unwrapped && typeof unwrapped === "object" ? unwrapped.properties : void 0;
1780
+ if (schemaProps && !Object.hasOwn(schemaProps, rootName)) {
1781
+ actualXmlInner = s.slice(range.start, range.end);
1782
+ }
1783
+ }
1784
+ }
1785
+ }
1786
+ }
1787
+ const topLevelStringProps = getTopLevelStringProps(schema);
1788
+ const deepStringTypedProps = getStringTypedProperties(schema);
1789
+ const duplicateKeys = /* @__PURE__ */ new Set();
1790
+ for (const key of topLevelStringProps) {
1791
+ const excludeRanges = [];
1792
+ for (const other of topLevelStringProps) {
1793
+ if (other === key) {
1794
+ continue;
1795
+ }
1796
+ const range = findFirstTopLevelRange(actualXmlInner, other);
1797
+ if (range) {
1798
+ excludeRanges.push(range);
1799
+ }
1800
+ }
1801
+ const occurrences = countTagOccurrences(
1802
+ actualXmlInner,
1803
+ key,
1804
+ excludeRanges,
1805
+ true
1806
+ );
1807
+ if (occurrences > 0 && throwDup) {
1808
+ throw new RXMLDuplicateStringTagError(
1809
+ `Duplicate string tags for <${key}> detected`
1810
+ );
1811
+ }
1812
+ if (occurrences > 0 && !throwDup) {
1813
+ duplicateKeys.add(key);
1814
+ if (options.onError) {
1815
+ options.onError(
1816
+ `RXML: Duplicate string tags for <${key}> detected; using first occurrence.`,
1817
+ { tag: key, occurrences }
1818
+ );
1819
+ }
1820
+ }
1821
+ }
1822
+ let xmlInnerForParsing = actualXmlInner;
1823
+ const originalContentMap = /* @__PURE__ */ new Map();
1824
+ try {
1825
+ const ranges = [];
1826
+ for (const key of deepStringTypedProps) {
1827
+ const innerRanges = findAllInnerRanges(actualXmlInner, key);
1828
+ for (const r of innerRanges) {
1829
+ if (r.end > r.start) {
1830
+ ranges.push({ ...r, key });
1831
+ }
1832
+ }
1833
+ }
1834
+ if (ranges.length > 0) {
1835
+ const sorted = [...ranges].sort((a, b) => a.start - b.start);
1836
+ let rebuilt = "";
1837
+ let cursor = 0;
1838
+ for (const r of sorted) {
1839
+ if (r.start < cursor) {
1840
+ continue;
1841
+ }
1842
+ if (cursor < r.start) {
1843
+ rebuilt += actualXmlInner.slice(cursor, r.start);
1844
+ }
1845
+ const placeholder = `__RXML_PLACEHOLDER_${r.key}_${r.start}_${r.end}__`;
1846
+ const originalContent = actualXmlInner.slice(r.start, r.end);
1847
+ originalContentMap.set(placeholder, originalContent);
1848
+ rebuilt += placeholder;
1849
+ cursor = r.end;
1850
+ }
1851
+ if (cursor < actualXmlInner.length) {
1852
+ rebuilt += actualXmlInner.slice(cursor);
1853
+ }
1854
+ xmlInnerForParsing = rebuilt;
1855
+ }
1856
+ } catch (error) {
1857
+ if (options.onError) {
1858
+ options.onError(
1859
+ "RXML: Failed to replace string placeholders, falling back to original XML.",
1860
+ { error }
1861
+ );
1862
+ }
1863
+ xmlInnerForParsing = actualXmlInner;
1864
+ }
1865
+ let parsedNodes;
1866
+ try {
1867
+ const wrappedXml = `<root>${xmlInnerForParsing}</root>`;
1868
+ const tokenizer = new XMLTokenizer(wrappedXml, {
1869
+ ...options,
1870
+ textNodeName
1871
+ });
1872
+ const rootNode = tokenizer.parseNode();
1873
+ parsedNodes = rootNode.children;
1874
+ } catch (cause) {
1875
+ throw new RXMLParseError("Failed to parse XML", cause);
1876
+ }
1877
+ const parsedArgs = domToObject(parsedNodes, schema, textNodeName);
1878
+ const restorePlaceholdersDeep = createPlaceholderRestorer(
1879
+ originalContentMap,
1880
+ textNodeName
1881
+ );
1882
+ const parsedArgsRestored = restorePlaceholdersDeep(parsedArgs);
1883
+ const args = {};
1884
+ for (const k of Object.keys(parsedArgsRestored || {})) {
1885
+ const v = parsedArgsRestored[k];
1886
+ let val = v;
1887
+ const propSchema = getPropertySchema(schema, k);
1888
+ const propType = getSchemaType(propSchema);
1889
+ if (propType === "string" && duplicateKeys.has(k) && Array.isArray(v)) {
1890
+ const firstValue = v[0];
1891
+ if (typeof firstValue === "string" && firstValue.startsWith("__RXML_PLACEHOLDER_")) {
1892
+ const originalContent = originalContentMap.get(firstValue);
1893
+ if (originalContent !== void 0) {
1894
+ args[k] = originalContent;
1895
+ continue;
1896
+ }
1897
+ } else {
1898
+ args[k] = firstValue;
1899
+ continue;
1900
+ }
1901
+ }
1902
+ if (propType === "string" && !Array.isArray(v)) {
1903
+ const placeholderUsed = typeof v === "string" && v.startsWith("__RXML_PLACEHOLDER_") || v && typeof v === "object" && Object.hasOwn(v, textNodeName) && typeof v[textNodeName] === "string" && v[textNodeName].startsWith(
1904
+ "__RXML_PLACEHOLDER_"
1905
+ );
1906
+ if (placeholderUsed) {
1907
+ let placeholderKey;
1908
+ if (typeof v === "string") {
1909
+ placeholderKey = v;
1910
+ } else {
1911
+ placeholderKey = v[textNodeName];
1912
+ }
1913
+ const originalContent = originalContentMap.get(placeholderKey);
1914
+ if (originalContent !== void 0) {
1915
+ args[k] = originalContent;
1916
+ continue;
1917
+ }
1918
+ }
1919
+ const raw = extractRawInner(actualXmlInner, k);
1920
+ if (typeof raw === "string") {
1921
+ args[k] = raw;
1922
+ continue;
1923
+ }
1924
+ }
1925
+ if (v && typeof v === "object" && Object.hasOwn(v, textNodeName)) {
1926
+ val = v[textNodeName];
1927
+ }
1928
+ if (Array.isArray(v)) {
1929
+ if (propType === "string") {
1930
+ const mapped = v.map((item) => {
1931
+ if (item && typeof item === "object" && Object.hasOwn(item, textNodeName)) {
1932
+ const textVal = item[textNodeName];
1933
+ return typeof textVal === "string" ? textVal : String(textVal);
1934
+ }
1935
+ return typeof item === "string" ? item : String(item);
1936
+ });
1937
+ if (mapped.length > 1 && throwDup) {
1938
+ throw new RXMLDuplicateStringTagError(
1939
+ `Duplicate string tags for <${k}> detected`
1940
+ );
1941
+ }
1942
+ if (mapped.length > 1 && !throwDup && options.onError) {
1943
+ options.onError(
1944
+ `RXML: Duplicate string tags for <${k}> detected; using first occurrence.`,
1945
+ { tag: k, occurrences: mapped.length }
1946
+ );
1947
+ }
1948
+ args[k] = (_c = mapped[0]) != null ? _c : "";
1949
+ continue;
1950
+ }
1951
+ val = processArrayContent(v, propSchema, textNodeName);
1952
+ } else if (v && typeof v === "object" && !Object.hasOwn(v, textNodeName)) {
1953
+ const obj = v;
1954
+ const keys2 = Object.keys(obj);
1955
+ if (keys2.length === 1 && keys2[0] === "item") {
1956
+ val = processItemWrapper(obj.item, textNodeName);
1957
+ } else {
1958
+ let isIndexedTuple = false;
1959
+ if (keys2.length > 0 && keys2.every((key) => DIGIT_KEY_REGEX2.test(key))) {
1960
+ const indices = keys2.map((keyStr) => Number.parseInt(keyStr, 10)).sort((a, b) => a - b);
1961
+ isIndexedTuple = indices[0] === 0 && indices.every((indexVal, idx) => indexVal === idx);
1962
+ }
1963
+ if (isIndexedTuple) {
1964
+ val = processIndexedTuple(obj, textNodeName);
1965
+ } else {
1966
+ val = v;
1967
+ }
1968
+ }
1969
+ }
1970
+ args[k] = typeof val === "string" ? val.trim() : val;
1971
+ }
1972
+ for (const key of topLevelStringProps) {
1973
+ if (!Object.hasOwn(args, key)) {
1974
+ const raw = extractRawInner(actualXmlInner, key);
1975
+ if (typeof raw === "string") {
1976
+ args[key] = raw;
1977
+ }
1978
+ }
1979
+ }
1980
+ let dataToCoerce = args;
1981
+ const keys = Object.keys(args);
1982
+ if (keys.length === 1) {
1983
+ const rootKey = keys[0];
1984
+ const rootValue = args[rootKey];
1985
+ const unwrapped = unwrapJsonSchema(schema);
1986
+ if (unwrapped && typeof unwrapped === "object") {
1987
+ const schemaProps = unwrapped.properties;
1988
+ if (schemaProps && !Object.hasOwn(schemaProps, rootKey)) {
1989
+ dataToCoerce = rootValue;
1990
+ }
1991
+ }
1992
+ }
1993
+ try {
1994
+ const coerced = coerceDomBySchema(dataToCoerce, schema);
1995
+ const decoded = deepDecodeStringsBySchema(coerced, schema);
1996
+ return decoded;
1997
+ } catch (error) {
1998
+ throw new RXMLCoercionError("Failed to coerce by schema", error);
1999
+ }
2000
+ }
2001
+
2002
+ // src/rxml/heuristics/engine.ts
2003
+ function applyRawSegmentUpdate(current, result) {
2004
+ if (result.rawSegment !== void 0) {
2005
+ return { ...current, rawSegment: result.rawSegment };
2006
+ }
2007
+ return current;
2008
+ }
2009
+ function applyParsedUpdate(current, result) {
2010
+ if (result.parsed !== void 0) {
2011
+ return { ...current, parsed: result.parsed };
2012
+ }
2013
+ return current;
2014
+ }
2015
+ function applyWarningsUpdate(current, result) {
2016
+ var _a, _b;
2017
+ if (result.warnings && result.warnings.length > 0) {
2018
+ const meta = (_a = current.meta) != null ? _a : {};
2019
+ const existingWarnings = (_b = meta.warnings) != null ? _b : [];
2020
+ return {
2021
+ ...current,
2022
+ meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
2023
+ };
2024
+ }
2025
+ return current;
2026
+ }
2027
+ function attemptReparse(current, result, reparseCount, maxReparses, parse3) {
2028
+ if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
2029
+ return { state: current, newCount: reparseCount };
2030
+ }
2031
+ try {
2032
+ const reparsed = parse3(result.rawSegment, current.schema);
2033
+ return {
2034
+ state: { ...current, parsed: reparsed, errors: [] },
2035
+ newCount: reparseCount + 1
2036
+ };
2037
+ } catch (error) {
2038
+ return {
2039
+ state: { ...current, errors: [...current.errors, error] },
2040
+ newCount: reparseCount + 1
2041
+ };
2042
+ }
2043
+ }
2044
+ function executePhase(ctx, heuristics, options) {
2045
+ var _a;
2046
+ let current = ctx;
2047
+ let reparseCount = 0;
2048
+ const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
2049
+ for (const heuristic of heuristics) {
2050
+ if (!heuristic.applies(current)) {
2051
+ continue;
2052
+ }
2053
+ const result = heuristic.run(current);
2054
+ current = applyRawSegmentUpdate(current, result);
2055
+ current = applyParsedUpdate(current, result);
2056
+ current = applyWarningsUpdate(current, result);
2057
+ const reparseResult = attemptReparse(
2058
+ current,
2059
+ result,
2060
+ reparseCount,
2061
+ maxReparses,
2062
+ options.parse
2063
+ );
2064
+ current = reparseResult.state;
2065
+ reparseCount = reparseResult.newCount;
2066
+ if (result.stop) {
2067
+ break;
2068
+ }
2069
+ }
2070
+ return current;
2071
+ }
2072
+ function applyHeuristicPipeline(ctx, config, options) {
2073
+ let current = ctx;
2074
+ if (config.preParse && config.preParse.length > 0) {
2075
+ current = executePhase(current, config.preParse, options);
2076
+ }
2077
+ if (current.parsed === null && current.errors.length === 0) {
2078
+ try {
2079
+ const parsed = options.parse(current.rawSegment, current.schema);
2080
+ current = { ...current, parsed, errors: [] };
2081
+ } catch (error) {
2082
+ current = { ...current, errors: [error] };
2083
+ }
2084
+ }
2085
+ if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
2086
+ current = executePhase(current, config.fallbackReparse, options);
2087
+ }
2088
+ if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
2089
+ current = executePhase(current, config.postParse, options);
2090
+ }
2091
+ return current;
2092
+ }
2093
+ function createIntermediateCall(toolName, rawSegment, schema) {
2094
+ return {
2095
+ toolName,
2096
+ schema,
2097
+ rawSegment,
2098
+ parsed: null,
2099
+ errors: [],
2100
+ meta: { originalContent: rawSegment }
2101
+ };
2102
+ }
2103
+
2104
+ // src/rxml/heuristics/xml-defaults.ts
2105
+ var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
2106
+ var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
2107
+ var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
2108
+ var WHITESPACE_REGEX2 = /\s/;
2109
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
2110
+ var NAME_START_CHAR_RE = /[A-Za-z_:]/;
2111
+ var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
2112
+ var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
2113
+ var normalizeCloseTagsHeuristic = {
2114
+ id: "normalize-close-tags",
2115
+ phase: "pre-parse",
2116
+ applies: () => true,
2117
+ run: (ctx) => {
2118
+ const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
2119
+ if (normalized !== ctx.rawSegment) {
2120
+ return { rawSegment: normalized };
2121
+ }
2122
+ return {};
2123
+ }
2124
+ };
2125
+ var escapeInvalidLtHeuristic = {
2126
+ id: "escape-invalid-lt",
2127
+ phase: "pre-parse",
2128
+ applies: () => true,
2129
+ run: (ctx) => {
2130
+ const escaped = escapeInvalidLt(ctx.rawSegment);
2131
+ if (escaped !== ctx.rawSegment) {
2132
+ return { rawSegment: escaped };
2133
+ }
2134
+ return {};
2135
+ }
2136
+ };
2137
+ var balanceTagsHeuristic = {
2138
+ id: "balance-tags",
2139
+ phase: "fallback-reparse",
2140
+ applies: (ctx) => {
2141
+ var _a;
2142
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
2143
+ const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
2144
+ const balanced = balanceTags(original);
2145
+ const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
2146
+ if (!hasMalformedClose && balanced.length > normalized.length && ctx.errors.length === 0) {
2147
+ return false;
2148
+ }
2149
+ return balanced !== normalized;
2150
+ },
2151
+ run: (ctx) => {
2152
+ var _a;
2153
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
2154
+ const balanced = balanceTags(original);
2155
+ const escaped = escapeInvalidLt(balanced);
2156
+ return { rawSegment: escaped, reparse: true };
2157
+ }
2158
+ };
2159
+ var dedupeShellStringTagsHeuristic = {
2160
+ id: "dedupe-shell-string-tags",
2161
+ phase: "fallback-reparse",
2162
+ applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
2163
+ run: (ctx) => {
2164
+ const names = getStringPropertyNames(ctx.schema);
2165
+ let deduped = ctx.rawSegment;
2166
+ for (const key of names) {
2167
+ deduped = dedupeSingleTag(deduped, key);
2168
+ }
2169
+ if (deduped !== ctx.rawSegment) {
2170
+ return { rawSegment: deduped, reparse: true };
2171
+ }
2172
+ return {};
2173
+ }
2174
+ };
2175
+ var repairAgainstSchemaHeuristic = {
2176
+ id: "repair-against-schema",
2177
+ phase: "post-parse",
2178
+ applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
2179
+ run: (ctx) => {
2180
+ const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
2181
+ if (repaired !== ctx.parsed) {
2182
+ return { parsed: repaired };
2183
+ }
2184
+ return {};
2185
+ }
2186
+ };
2187
+ var defaultPipelineConfig = {
2188
+ preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
2189
+ fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
2190
+ postParse: [repairAgainstSchemaHeuristic]
2191
+ };
2192
+ var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
2193
+ function isIndexTagAt(xml, pos) {
2194
+ const remaining = xml.slice(pos);
2195
+ return INDEX_TAG_RE.test(remaining);
2196
+ }
2197
+ function escapeInvalidLt(xml) {
2198
+ const len = xml.length;
2199
+ let out = "";
2200
+ for (let i = 0; i < len; i += 1) {
2201
+ const ch = xml[i];
2202
+ if (ch === "<") {
2203
+ const next = i + 1 < len ? xml[i + 1] : "";
2204
+ const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
2205
+ const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
2206
+ if (!(isValidStart || isIndexTag)) {
2207
+ out += "&lt;";
2208
+ continue;
2209
+ }
2210
+ }
2211
+ out += ch;
2212
+ }
2213
+ return out;
2214
+ }
2215
+ function balanceTags(xml) {
2216
+ const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
2217
+ let i = 0;
2218
+ const len = src.length;
2219
+ const out = [];
2220
+ const stack = [];
2221
+ while (i < len) {
2222
+ const lt = src.indexOf("<", i);
2223
+ if (lt === -1) {
2224
+ out.push(src.slice(i));
2225
+ break;
2226
+ }
2227
+ out.push(src.slice(i, lt));
2228
+ if (lt + 1 >= len) {
2229
+ break;
2230
+ }
2231
+ const next = src[lt + 1];
2232
+ if (next === "!" || next === "?") {
2233
+ i = handleSpecialTagSegment(src, lt, out);
2234
+ continue;
2235
+ }
2236
+ if (next === "/") {
2237
+ i = handleClosingTagSegment(src, lt, out, stack);
2238
+ continue;
2239
+ }
2240
+ i = handleOpeningTagSegment(src, lt, out, stack);
2241
+ }
2242
+ for (let k = stack.length - 1; k >= 0; k -= 1) {
2243
+ out.push(`</${stack[k]}>`);
2244
+ }
2245
+ return out.join("");
2246
+ }
2247
+ function skipWs(s, p, len) {
2248
+ let idx = p;
2249
+ while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
2250
+ idx += 1;
2251
+ }
2252
+ return idx;
2253
+ }
2254
+ function parseTagNameAt(s, p, len) {
2255
+ let idx = p;
2256
+ const start = idx;
2257
+ while (idx < len && NAME_CHAR_RE.test(s[idx])) {
2258
+ idx += 1;
2259
+ }
2260
+ return { name: s.slice(start, idx), pos: idx };
2261
+ }
2262
+ function handleSpecialTagSegment(src, lt, out) {
2263
+ const gt = src.indexOf(">", lt + 1);
2264
+ if (gt === -1) {
2265
+ out.push(src.slice(lt));
2266
+ return src.length;
2267
+ }
2268
+ out.push(src.slice(lt, gt + 1));
2269
+ return gt + 1;
2270
+ }
2271
+ function handleClosingTagSegment(src, lt, out, stack) {
2272
+ const len = src.length;
2273
+ let p = skipWs(src, lt + 2, len);
2274
+ const { name, pos } = parseTagNameAt(src, p, len);
2275
+ p = pos;
2276
+ const gt = src.indexOf(">", p);
2277
+ const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
2278
+ const idx = stack.lastIndexOf(name);
2279
+ if (idx !== -1) {
2280
+ for (let k = stack.length - 1; k > idx; k -= 1) {
2281
+ out.push(`</${stack[k]}>`);
2282
+ stack.pop();
2283
+ }
2284
+ out.push(closingText);
2285
+ stack.pop();
2286
+ }
2287
+ return gt === -1 ? len : gt + 1;
2288
+ }
2289
+ function handleOpeningTagSegment(src, lt, out, stack) {
2290
+ const len = src.length;
2291
+ let p = skipWs(src, lt + 1, len);
2292
+ const nameStart = p;
2293
+ const parsed = parseTagNameAt(src, p, len);
2294
+ p = parsed.pos;
2295
+ const name = src.slice(nameStart, p);
2296
+ const q = src.indexOf(">", p);
2297
+ if (q === -1) {
2298
+ out.push(src.slice(lt));
2299
+ return len;
2300
+ }
2301
+ let r = q - 1;
2302
+ while (r >= nameStart && WHITESPACE_REGEX2.test(src[r])) {
2303
+ r -= 1;
2304
+ }
2305
+ const selfClosing = src[r] === "/";
2306
+ out.push(src.slice(lt, q + 1));
2307
+ if (!selfClosing && name) {
2308
+ stack.push(name);
2309
+ }
2310
+ return q + 1;
2311
+ }
2312
+ function extractSchemaProperties(schema) {
2313
+ const unwrapped = unwrapJsonSchema(schema);
2314
+ if (!unwrapped || typeof unwrapped !== "object") {
2315
+ return void 0;
2316
+ }
2317
+ return unwrapped.properties;
2318
+ }
2319
+ function shouldDeduplicateStringTags(schema) {
2320
+ const props = extractSchemaProperties(schema);
2321
+ if (!props) {
2322
+ return false;
2323
+ }
2324
+ const commandRaw = props.command;
2325
+ if (!commandRaw) {
2326
+ return false;
2327
+ }
2328
+ const command = unwrapJsonSchema(commandRaw);
2329
+ return (command == null ? void 0 : command.type) === "array";
2330
+ }
2331
+ function getStringPropertyNames(schema) {
2332
+ const props = extractSchemaProperties(schema);
2333
+ if (!props) {
2334
+ return [];
2335
+ }
2336
+ const names = [];
2337
+ for (const key of Object.keys(props)) {
2338
+ const prop = unwrapJsonSchema(props[key]);
2339
+ if ((prop == null ? void 0 : prop.type) === "string") {
2340
+ names.push(key);
2341
+ }
2342
+ }
2343
+ return names;
2344
+ }
2345
+ function escapeRegExp(s) {
2346
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2347
+ }
2348
+ function dedupeSingleTag(xml, key) {
2349
+ var _a, _b;
2350
+ const escaped = escapeRegExp(key);
2351
+ const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
2352
+ const matches = Array.from(xml.matchAll(re));
2353
+ if (matches.length <= 1) {
2354
+ return xml;
2355
+ }
2356
+ const last = matches.at(-1);
2357
+ let result = "";
2358
+ let cursor = 0;
2359
+ for (const m of matches) {
2360
+ const idx = (_a = m.index) != null ? _a : 0;
2361
+ result += xml.slice(cursor, idx);
2362
+ if (last && idx === ((_b = last.index) != null ? _b : -1)) {
2363
+ result += m[0];
2364
+ }
2365
+ cursor = idx + m[0].length;
2366
+ }
2367
+ result += xml.slice(cursor);
2368
+ return result;
2369
+ }
2370
+ function repairParsedAgainstSchema(input, schema) {
2371
+ if (!input || typeof input !== "object") {
2372
+ return input;
2373
+ }
2374
+ const properties = extractSchemaProperties(schema);
2375
+ if (!properties) {
2376
+ return input;
2377
+ }
2378
+ applySchemaProps(input, properties);
2379
+ return input;
2380
+ }
2381
+ function applySchemaProps(obj, properties) {
2382
+ for (const key of Object.keys(obj)) {
2383
+ const propSchema = properties[key];
2384
+ if (!propSchema) {
2385
+ continue;
2386
+ }
2387
+ const prop = unwrapJsonSchema(propSchema);
2388
+ if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
2389
+ const itemSchema = unwrapJsonSchema(prop.items);
2390
+ obj[key] = coerceArrayItems(obj[key], itemSchema);
2391
+ continue;
2392
+ }
2393
+ if ((prop == null ? void 0 : prop.type) === "object") {
2394
+ const val = obj[key];
2395
+ if (val && typeof val === "object") {
2396
+ obj[key] = repairParsedAgainstSchema(val, prop);
2397
+ }
2398
+ }
2399
+ }
2400
+ }
2401
+ function coerceArrayItems(val, itemSchema) {
2402
+ if (!Array.isArray(val)) {
2403
+ return val;
2404
+ }
2405
+ return val.map((v) => coerceArrayItem(v, itemSchema));
2406
+ }
2407
+ function coerceArrayItem(v, itemSchema) {
2408
+ const itemType = itemSchema == null ? void 0 : itemSchema.type;
2409
+ if (typeof v === "string" && itemType === "object") {
2410
+ const parsed = tryParseStringToSchemaObject(v, itemSchema);
2411
+ if (parsed !== null) {
2412
+ return parsed;
2413
+ }
2414
+ const fallback = extractStepStatusFromString(
2415
+ v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
2416
+ );
2417
+ if (fallback) {
2418
+ return fallback;
2419
+ }
2420
+ return v;
2421
+ }
2422
+ if (v && typeof v === "object" && itemType === "object") {
2423
+ return repairParsedAgainstSchema(v, itemSchema);
2424
+ }
2425
+ return v;
2426
+ }
2427
+ function tryParseStringToSchemaObject(xml, itemSchema) {
2428
+ try {
2429
+ const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
2430
+ const fixed = parse(normalized, itemSchema, { noChildNodes: [] });
2431
+ return typeof fixed === "string" ? null : fixed;
2432
+ } catch (e) {
2433
+ return null;
2434
+ }
2435
+ }
2436
+ function extractStepStatusFromString(normXml) {
2437
+ const stepMatch = normXml.match(STEP_TAG_RE);
2438
+ const statusMatch = normXml.match(STATUS_TAG_RE);
2439
+ if (stepMatch && statusMatch) {
2440
+ return { step: stepMatch[1], status: statusMatch[1] };
2441
+ }
2442
+ return null;
2443
+ }
2444
+
2445
+ // src/rxml/parse.ts
2446
+ function parse2(xml, schema, options = {}) {
2447
+ if (!options.repair) {
2448
+ return parse(xml, schema, options);
2449
+ }
2450
+ const baseOptions = {
2451
+ ...options,
2452
+ repair: false
2453
+ };
2454
+ const ctx = createIntermediateCall("", xml, schema);
2455
+ const result = applyHeuristicPipeline(ctx, defaultPipelineConfig, {
2456
+ parse: (raw, s) => parse(raw, s, baseOptions),
2457
+ onError: options.onError,
2458
+ maxReparses: options.maxReparses
2459
+ });
2460
+ if (result.parsed !== null) {
2461
+ return result.parsed;
2462
+ }
2463
+ const error = result.errors[0];
2464
+ throw new RXMLParseError("Failed to parse XML with repair heuristics", error);
2465
+ }
2466
+ // Annotate the CommonJS export names for ESM import in node:
2467
+ 0 && (module.exports = {
2468
+ parse,
2469
+ stringify
2470
+ });
2471
+ //# sourceMappingURL=rxml.cjs.map