@ai-sdk-tool/rxml 0.1.2 → 0.2.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.js CHANGED
@@ -28,13 +28,6 @@ var RXMLStringifyError = class extends Error {
28
28
  this.cause = cause;
29
29
  }
30
30
  };
31
- var RXMLStreamError = class extends Error {
32
- constructor(message, cause) {
33
- super(message);
34
- this.name = "RXMLStreamError";
35
- this.cause = cause;
36
- }
37
- };
38
31
 
39
32
  // src/core/types.ts
40
33
  var CharCodes = {
@@ -336,353 +329,16 @@ function stringifyObject(tagName, obj, context) {
336
329
  openTag: fullOpenTag
337
330
  });
338
331
  }
339
- function stringifyNodes(nodes, format = true, options = {}) {
340
- let result = "";
341
- for (const node of nodes) {
342
- if (typeof node === "string") {
343
- result += node;
344
- } else {
345
- result += stringifyNode(node, 0, format, options);
346
- }
347
- }
348
- return result;
349
- }
350
- function formatNodeAttribute(attrName, attrValue, minimalEscaping, strictBooleanAttributes) {
351
- if (attrValue === null) {
352
- if (strictBooleanAttributes) {
353
- return ` ${attrName}="${attrName}"`;
354
- }
355
- return ` ${attrName}`;
356
- }
357
- if (attrValue.indexOf('"') === -1) {
358
- const escaped2 = minimalEscaping ? escapeXmlMinimalAttr(attrValue, '"') : escapeXml(attrValue);
359
- return ` ${attrName}="${escaped2}"`;
360
- }
361
- const escaped = minimalEscaping ? escapeXmlMinimalAttr(attrValue, "'") : escapeXml(attrValue);
362
- return ` ${attrName}='${escaped}'`;
363
- }
364
- function buildNodeOpeningTag(node, opts) {
365
- let result = `${opts.indent}<${node.tagName}`;
366
- for (const [attrName, attrValue] of Object.entries(node.attributes)) {
367
- result += formatNodeAttribute(
368
- attrName,
369
- attrValue,
370
- opts.minimalEscaping,
371
- opts.strictBooleanAttributes
372
- );
373
- }
374
- return result;
375
- }
376
- function stringifyNodeChildren(options) {
377
- const {
378
- children,
379
- depth,
380
- format,
381
- stringifyOptions,
382
- minimalEscaping,
383
- newline
384
- } = options;
385
- let content = "";
386
- let hasElementChildren = false;
387
- for (const child of children) {
388
- if (typeof child === "string") {
389
- content += minimalEscaping ? escapeXmlMinimalText(child) : escapeXml(child);
390
- } else {
391
- if (!hasElementChildren && format) {
392
- content += newline;
393
- hasElementChildren = true;
394
- }
395
- content += stringifyNode(child, depth + 1, format, stringifyOptions);
396
- }
397
- }
398
- return { content, hasElementChildren };
399
- }
400
- function stringifyNode(node, depth = 0, format = true, options = {}) {
401
- var _a, _b;
402
- const indent = format ? " ".repeat(depth) : "";
403
- const newline = format ? "\n" : "";
404
- const minimalEscaping = (_a = options.minimalEscaping) != null ? _a : false;
405
- const strictBooleanAttributes = (_b = options.strictBooleanAttributes) != null ? _b : false;
406
- const opts = {
407
- minimalEscaping,
408
- strictBooleanAttributes,
409
- indent,
410
- newline
411
- };
412
- let result = buildNodeOpeningTag(node, opts);
413
- if (node.tagName[0] === "?") {
414
- return `${result}?>${newline}`;
415
- }
416
- if (node.children.length === 0) {
417
- return `${result}/>${newline}`;
418
- }
419
- result += ">";
420
- const { content, hasElementChildren } = stringifyNodeChildren({
421
- children: node.children,
422
- depth,
423
- format,
424
- stringifyOptions: options,
425
- minimalEscaping,
426
- newline
427
- });
428
- result += content;
429
- if (hasElementChildren && format) {
430
- result += indent;
431
- }
432
- result += `</${node.tagName}>`;
433
- if (format) {
434
- result += newline;
435
- }
436
- return result;
437
- }
438
- function toContentString(nodes) {
439
- let result = "";
440
- for (const node of nodes) {
441
- if (typeof node === "string") {
442
- result += ` ${node}`;
443
- } else {
444
- result += ` ${toContentString(node.children)}`;
445
- }
446
- result = result.trim();
447
- }
448
- return result;
449
- }
450
332
 
451
- // src/schema/base-coercion.ts
452
- var NUMERIC_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
453
- var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
454
- var NEWLINE_SPLIT_REGEX = /\n+/;
455
- var COMMA_SPLIT_REGEX = /,\s*/;
456
- var DIGIT_KEY_REGEX = /^\d+$/;
457
- function unwrapJsonSchema(schema) {
458
- if (!schema || typeof schema !== "object") {
459
- return schema;
460
- }
461
- const s = schema;
462
- if (s.jsonSchema && typeof s.jsonSchema === "object") {
463
- return unwrapJsonSchema(s.jsonSchema);
464
- }
465
- return schema;
466
- }
467
- function getSchemaType(schema) {
468
- const unwrapped = unwrapJsonSchema(schema);
469
- if (!unwrapped || typeof unwrapped !== "object") {
470
- return;
471
- }
472
- const t = unwrapped.type;
473
- if (typeof t === "string") {
474
- return t;
475
- }
476
- if (Array.isArray(t)) {
477
- const preferred = [
478
- "object",
479
- "array",
480
- "boolean",
481
- "number",
482
- "integer",
483
- "string"
484
- ];
485
- for (const p of preferred) {
486
- if (t.includes(p)) {
487
- return p;
488
- }
489
- }
490
- }
491
- const s = unwrapped;
492
- if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
493
- return "object";
494
- }
495
- if (s && typeof s === "object" && (s.items || s.prefixItems)) {
496
- return "array";
497
- }
498
- return;
499
- }
500
- function coerceStringWithoutSchema(value) {
501
- const s = value.trim();
502
- const lower = s.toLowerCase();
503
- if (lower === "true") {
504
- return true;
505
- }
506
- if (lower === "false") {
507
- return false;
508
- }
509
- if (NUMERIC_REGEX.test(s)) {
510
- const num = Number(s);
511
- if (Number.isFinite(num)) {
512
- return num;
513
- }
514
- }
515
- if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
516
- try {
517
- const parsed = JSON.parse(s);
518
- return coerceBySchema(parsed, void 0);
519
- } catch (e) {
520
- }
521
- }
522
- return value;
523
- }
524
- function coerceStringToObject(s, unwrapped) {
525
- try {
526
- let normalized = s.replace(/'/g, '"');
527
- normalized = normalized.replace(EMPTY_OBJECT_REGEX, "{}");
528
- const obj = JSON.parse(normalized);
529
- if (obj && typeof obj === "object" && !Array.isArray(obj)) {
530
- const props = unwrapped.properties;
531
- const out = {};
532
- for (const [k, v] of Object.entries(obj)) {
533
- const propSchema = props ? props[k] : void 0;
534
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
535
- }
536
- return out;
537
- }
538
- } catch (e) {
539
- }
540
- return null;
541
- }
542
- function coerceStringToArray(s, unwrapped) {
543
- const prefixItems = Array.isArray(unwrapped.prefixItems) ? unwrapped.prefixItems : void 0;
544
- const itemsSchema = unwrapped.items;
545
- try {
546
- const normalized = s.replace(/'/g, '"');
547
- const arr = JSON.parse(normalized);
548
- if (Array.isArray(arr)) {
549
- if (prefixItems && arr.length === prefixItems.length) {
550
- return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
551
- }
552
- return arr.map((v) => coerceBySchema(v, itemsSchema));
553
- }
554
- } catch (e) {
555
- const csv = s.includes("\n") ? s.split(NEWLINE_SPLIT_REGEX) : s.split(COMMA_SPLIT_REGEX);
556
- const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
557
- if (prefixItems && trimmed.length === prefixItems.length) {
558
- return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
559
- }
560
- return trimmed.map((x) => coerceBySchema(x, itemsSchema));
561
- }
562
- return null;
563
- }
564
- function coerceObjectToObject(value, unwrapped) {
565
- const out = {};
566
- const props = unwrapped.properties;
567
- for (const [k, v] of Object.entries(value)) {
568
- const propSchema = props ? props[k] : void 0;
569
- out[k] = typeof propSchema === "boolean" ? v : coerceBySchema(v, propSchema);
570
- }
571
- return out;
572
- }
573
- function coerceArrayToArray(value, prefixItems, itemsSchema) {
574
- if (prefixItems && value.length === prefixItems.length) {
575
- return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
576
- }
577
- return value.map((v) => coerceBySchema(v, itemsSchema));
578
- }
579
- function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
580
- if (Object.hasOwn(maybe, "item")) {
581
- const items = maybe.item;
582
- const arr = Array.isArray(items) ? items : [items];
583
- return coerceArrayToArray(arr, prefixItems, itemsSchema);
584
- }
585
- const keys = Object.keys(maybe);
586
- if (keys.length === 1) {
587
- const singleValue = maybe[keys[0]];
588
- if (Array.isArray(singleValue)) {
589
- return singleValue.map((v) => coerceBySchema(v, itemsSchema));
590
- }
591
- }
592
- if (keys.length > 0 && keys.every((k) => DIGIT_KEY_REGEX.test(k))) {
593
- const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
594
- return coerceArrayToArray(arr, prefixItems, itemsSchema);
595
- }
596
- return null;
597
- }
598
- function coercePrimitiveToArray(value, prefixItems, itemsSchema) {
599
- if (prefixItems && prefixItems.length > 0) {
600
- return [coerceBySchema(value, prefixItems[0])];
601
- }
602
- return [coerceBySchema(value, itemsSchema)];
603
- }
604
- function coerceStringToPrimitive(s, schemaType) {
605
- if (schemaType === "boolean") {
606
- const lower = s.toLowerCase();
607
- if (lower === "true") {
608
- return true;
609
- }
610
- if (lower === "false") {
611
- return false;
612
- }
613
- }
614
- if ((schemaType === "number" || schemaType === "integer") && NUMERIC_REGEX.test(s)) {
615
- const num = Number(s);
616
- if (Number.isFinite(num)) {
617
- return num;
618
- }
619
- }
620
- return null;
621
- }
622
- function coerceStringValue(value, schemaType, u) {
623
- const s = value.trim();
624
- if (schemaType === "object") {
625
- const result = coerceStringToObject(s, u);
626
- if (result !== null) {
627
- return result;
628
- }
629
- }
630
- if (schemaType === "array") {
631
- const result = coerceStringToArray(s, u);
632
- if (result !== null) {
633
- return result;
634
- }
635
- }
636
- const primitiveResult = coerceStringToPrimitive(s, schemaType);
637
- if (primitiveResult !== null) {
638
- return primitiveResult;
639
- }
640
- return value;
641
- }
642
- function coerceArrayValue(value, prefixItems, itemsSchema) {
643
- if (Array.isArray(value)) {
644
- return coerceArrayToArray(value, prefixItems, itemsSchema);
645
- }
646
- if (value && typeof value === "object") {
647
- const result = coerceObjectToArray(
648
- value,
649
- prefixItems,
650
- itemsSchema
651
- );
652
- if (result !== null) {
653
- return result;
654
- }
655
- }
656
- if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
657
- return coercePrimitiveToArray(value, prefixItems, itemsSchema);
658
- }
659
- return value;
660
- }
661
- function coerceBySchema(value, schema) {
662
- const unwrapped = unwrapJsonSchema(schema);
663
- if (!unwrapped || typeof unwrapped !== "object") {
664
- if (typeof value === "string") {
665
- return coerceStringWithoutSchema(value);
666
- }
667
- return value;
668
- }
669
- const schemaType = getSchemaType(unwrapped);
670
- const u = unwrapped;
671
- if (typeof value === "string") {
672
- return coerceStringValue(value, schemaType, u);
673
- }
674
- if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
675
- return coerceObjectToObject(value, u);
676
- }
677
- if (schemaType === "array") {
678
- const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
679
- const itemsSchema = u.items;
680
- return coerceArrayValue(value, prefixItems, itemsSchema);
681
- }
682
- return value;
683
- }
333
+ // src/core/parser.ts
334
+ import { getSchemaType as getSchemaType2, unwrapJsonSchema as unwrapJsonSchema2 } from "@ai-sdk-tool/schema-coerce";
684
335
 
685
336
  // src/schema/coercion.ts
337
+ import {
338
+ coerceBySchema as baseCoerceBySchema,
339
+ getSchemaType,
340
+ unwrapJsonSchema
341
+ } from "@ai-sdk-tool/schema-coerce";
686
342
  function getPropertySchema(toolSchema, key) {
687
343
  const unwrapped = unwrapJsonSchema(toolSchema);
688
344
  if (!unwrapped || typeof unwrapped !== "object") {
@@ -796,7 +452,7 @@ function processComplexContent(children, schema, textNodeName) {
796
452
  }
797
453
  function coerceDomBySchema(domObject, schema) {
798
454
  try {
799
- return coerceBySchema(domObject, schema);
455
+ return baseCoerceBySchema(domObject, schema);
800
456
  } catch (error) {
801
457
  throw new RXMLCoercionError("Failed to coerce DOM object by schema", error);
802
458
  }
@@ -1352,159 +1008,6 @@ function countTagOccurrences(xmlContent, tagName, excludeRanges, shouldSkipFirst
1352
1008
  }
1353
1009
  return count;
1354
1010
  }
1355
- function skipAttributes(xmlContent, i, len) {
1356
- let k = i;
1357
- while (k < len && xmlContent[k] !== ">") {
1358
- const c = xmlContent[k];
1359
- if (c === '"' || c === "'") {
1360
- k = skipQuoted(xmlContent, k);
1361
- continue;
1362
- }
1363
- if (c === "/" && xmlContent[k + 1] === ">") {
1364
- k += 1;
1365
- break;
1366
- }
1367
- k += 1;
1368
- }
1369
- return k;
1370
- }
1371
- function updateDepthForClosingTag(xmlContent, nextLt, target, closeDepth) {
1372
- const { name: closeName } = parseName(xmlContent, nextLt + 2);
1373
- return closeName === target ? closeDepth - 1 : closeDepth;
1374
- }
1375
- function updateDepthForOpeningTag(xmlContent, nextLt, target, closeDepth) {
1376
- const { name: openName } = parseName(xmlContent, nextLt + 1);
1377
- return openName === target ? closeDepth + 1 : closeDepth;
1378
- }
1379
- function findClosingTagForRange(xmlContent, k, len, target) {
1380
- let closeDepth = 1;
1381
- let j = k + 1;
1382
- while (j < len && closeDepth > 0) {
1383
- const nextLt = xmlContent.indexOf("<", j);
1384
- if (nextLt === -1) {
1385
- break;
1386
- }
1387
- if (xmlContent[nextLt + 1] === "/") {
1388
- closeDepth = updateDepthForClosingTag(
1389
- xmlContent,
1390
- nextLt,
1391
- target,
1392
- closeDepth
1393
- );
1394
- } else if (xmlContent[nextLt + 1] !== "!" && xmlContent[nextLt + 1] !== "?") {
1395
- closeDepth = updateDepthForOpeningTag(
1396
- xmlContent,
1397
- nextLt,
1398
- target,
1399
- closeDepth
1400
- );
1401
- }
1402
- j = xmlContent.indexOf(">", nextLt + 1);
1403
- if (j === -1) {
1404
- break;
1405
- }
1406
- j += 1;
1407
- }
1408
- return closeDepth === 0 ? j : -1;
1409
- }
1410
- function processTopLevelTarget(options) {
1411
- const { xmlContent, tagStart, k, len, target, ranges } = options;
1412
- const isSelfClosing = xmlContent[k] === "/" || xmlContent.startsWith("/>", k);
1413
- if (isSelfClosing) {
1414
- ranges.push({
1415
- start: tagStart,
1416
- end: k + (xmlContent[k] === "/" ? 2 : 1)
1417
- });
1418
- return { newDepth: 0 };
1419
- }
1420
- const endPos = findClosingTagForRange(xmlContent, k, len, target);
1421
- if (endPos !== -1) {
1422
- ranges.push({ start: tagStart, end: endPos });
1423
- }
1424
- return { newDepth: 0 };
1425
- }
1426
- function skipDoctypeInSpecial(xmlContent, i, len) {
1427
- const gt = xmlContent.indexOf(">", i + 1);
1428
- return gt === -1 ? len : gt + 1;
1429
- }
1430
- function handleSpecialConstructs(xmlContent, ch, i, len) {
1431
- if (ch === "!") {
1432
- if (xmlContent.startsWith("!DOCTYPE", i + 1)) {
1433
- return skipDoctypeInSpecial(xmlContent, i, len);
1434
- }
1435
- if (xmlContent.startsWith("!--", i + 1)) {
1436
- return skipCommentInCounting(xmlContent, i, len);
1437
- }
1438
- if (xmlContent.startsWith("![CDATA[", i + 1)) {
1439
- return skipCdataInCounting(xmlContent, i, len);
1440
- }
1441
- const gt = xmlContent.indexOf(">", i + 1);
1442
- return gt === -1 ? len : gt + 1;
1443
- }
1444
- if (ch === "?") {
1445
- const close = xmlContent.indexOf("?>", i + 1);
1446
- return close === -1 ? len : close + 2;
1447
- }
1448
- return -1;
1449
- }
1450
- function handleClosingTagInFindAllTop(xmlContent, i, target, depth) {
1451
- const { name: closingName, newPos: closingPos } = parseName(
1452
- xmlContent,
1453
- i + 1
1454
- );
1455
- const newDepth = closingName === target ? depth - 1 : depth;
1456
- const gt = xmlContent.indexOf(">", closingPos);
1457
- return {
1458
- newPos: gt === -1 ? -1 : gt + 1,
1459
- newDepth
1460
- };
1461
- }
1462
- function findAllTopLevelRanges(xmlContent, tagName) {
1463
- const ranges = [];
1464
- const len = xmlContent.length;
1465
- const target = tagName;
1466
- let i = 0;
1467
- let depth = 0;
1468
- while (i < len) {
1469
- const lt = xmlContent.indexOf("<", i);
1470
- if (lt === -1 || lt + 1 >= len) {
1471
- break;
1472
- }
1473
- i = lt + 1;
1474
- const ch = xmlContent[i];
1475
- const specialPos = handleSpecialConstructs(xmlContent, ch, i, len);
1476
- if (specialPos !== -1) {
1477
- i = specialPos;
1478
- continue;
1479
- }
1480
- if (ch === "/") {
1481
- const result = handleClosingTagInFindAllTop(xmlContent, i, target, depth);
1482
- if (result.newPos === -1) {
1483
- break;
1484
- }
1485
- i = result.newPos;
1486
- depth = result.newDepth;
1487
- continue;
1488
- }
1489
- const { name, newPos } = parseName(xmlContent, i);
1490
- i = newPos;
1491
- const k = skipAttributes(xmlContent, i, len);
1492
- if (name === target && depth === 0) {
1493
- depth += 1;
1494
- const result = processTopLevelTarget({
1495
- xmlContent,
1496
- tagStart: lt,
1497
- k,
1498
- len,
1499
- target,
1500
- ranges
1501
- });
1502
- depth += result.newDepth;
1503
- }
1504
- i = k + 1;
1505
- }
1506
- return ranges;
1507
- }
1508
1011
 
1509
1012
  // src/core/tokenizer.ts
1510
1013
  var XMLTokenizer = class {
@@ -1843,15 +1346,15 @@ var XMLTokenizer = class {
1843
1346
  // src/core/parser.ts
1844
1347
  var WHITESPACE_REGEX = /\s/;
1845
1348
  var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
1846
- var DIGIT_KEY_REGEX2 = /^\d+$/;
1349
+ var DIGIT_KEY_REGEX = /^\d+$/;
1847
1350
  function getTopLevelStringProps(s) {
1848
1351
  const set = /* @__PURE__ */ new Set();
1849
- const unwrapped = unwrapJsonSchema(s);
1352
+ const unwrapped = unwrapJsonSchema2(s);
1850
1353
  if (unwrapped && typeof unwrapped === "object") {
1851
1354
  const props = unwrapped.properties;
1852
1355
  if (props && typeof props === "object") {
1853
1356
  for (const [k, v] of Object.entries(props)) {
1854
- if (getSchemaType(v) === "string") {
1357
+ if (getSchemaType2(v) === "string") {
1855
1358
  set.add(k);
1856
1359
  }
1857
1360
  }
@@ -1929,41 +1432,17 @@ function processItemWrapper(itemValue, textNodeName) {
1929
1432
  const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
1930
1433
  return tryConvertToNumber(trimmed);
1931
1434
  }
1932
- function shouldRethrowParseError(error, xmlString) {
1933
- if (!(error instanceof RXMLParseError)) {
1934
- return false;
1935
- }
1936
- const isSimple = xmlString.split("<").length < 6;
1937
- return error.message.includes("Unexpected close tag") && isSimple || error.message.includes("Unclosed tag") && isSimple;
1938
- }
1939
- function extractPartialXmlResults(xmlString, options) {
1940
- const partialResults = [];
1941
- const xmlPattern = /<([a-zA-Z_][\w.-]*)[^>]*>.*?<\/\1>/gs;
1942
- let match = null;
1943
- match = xmlPattern.exec(xmlString);
1944
- while (match !== null) {
1945
- try {
1946
- const elementXml = match[0];
1947
- const tokenizer = new XMLTokenizer(elementXml, options);
1948
- const parsed = tokenizer.parseChildren();
1949
- partialResults.push(...parsed);
1950
- } catch (e) {
1951
- }
1952
- match = xmlPattern.exec(xmlString);
1953
- }
1954
- return partialResults;
1955
- }
1956
1435
  function deepDecodeStringsBySchema(input, schema) {
1957
1436
  var _a;
1958
1437
  if (input == null || schema == null) {
1959
1438
  return input;
1960
1439
  }
1961
- const type = getSchemaType(schema);
1440
+ const type = getSchemaType2(schema);
1962
1441
  if (type === "string" && typeof input === "string") {
1963
1442
  return unescapeXml(input);
1964
1443
  }
1965
1444
  if (type === "array" && Array.isArray(input)) {
1966
- const unwrapped = unwrapJsonSchema(schema);
1445
+ const unwrapped = unwrapJsonSchema2(schema);
1967
1446
  const itemSchema = (_a = unwrapped == null ? void 0 : unwrapped.items) != null ? _a : {};
1968
1447
  return input.map((item) => deepDecodeStringsBySchema(item, itemSchema));
1969
1448
  }
@@ -2043,7 +1522,7 @@ function parse(xmlInner, schema, options = {}) {
2043
1522
  }
2044
1523
  }
2045
1524
  if (fullEnd === s.length) {
2046
- const unwrapped = unwrapJsonSchema(schema);
1525
+ const unwrapped = unwrapJsonSchema2(schema);
2047
1526
  const schemaProps = unwrapped && typeof unwrapped === "object" ? unwrapped.properties : void 0;
2048
1527
  if (schemaProps && !Object.hasOwn(schemaProps, rootName)) {
2049
1528
  actualXmlInner = s.slice(range.start, range.end);
@@ -2153,7 +1632,7 @@ function parse(xmlInner, schema, options = {}) {
2153
1632
  const v = parsedArgsRestored[k];
2154
1633
  let val = v;
2155
1634
  const propSchema = getPropertySchema(schema, k);
2156
- const propType = getSchemaType(propSchema);
1635
+ const propType = getSchemaType2(propSchema);
2157
1636
  if (propType === "string" && duplicateKeys.has(k) && Array.isArray(v)) {
2158
1637
  const firstValue = v[0];
2159
1638
  if (typeof firstValue === "string" && firstValue.startsWith("__RXML_PLACEHOLDER_")) {
@@ -2224,7 +1703,7 @@ function parse(xmlInner, schema, options = {}) {
2224
1703
  val = processItemWrapper(obj.item, textNodeName);
2225
1704
  } else {
2226
1705
  let isIndexedTuple = false;
2227
- if (keys2.length > 0 && keys2.every((key) => DIGIT_KEY_REGEX2.test(key))) {
1706
+ if (keys2.length > 0 && keys2.every((key) => DIGIT_KEY_REGEX.test(key))) {
2228
1707
  const indices = keys2.map((keyStr) => Number.parseInt(keyStr, 10)).sort((a, b) => a - b);
2229
1708
  isIndexedTuple = indices[0] === 0 && indices.every((indexVal, idx) => indexVal === idx);
2230
1709
  }
@@ -2250,7 +1729,7 @@ function parse(xmlInner, schema, options = {}) {
2250
1729
  if (keys.length === 1) {
2251
1730
  const rootKey = keys[0];
2252
1731
  const rootValue = args[rootKey];
2253
- const unwrapped = unwrapJsonSchema(schema);
1732
+ const unwrapped = unwrapJsonSchema2(schema);
2254
1733
  if (unwrapped && typeof unwrapped === "object") {
2255
1734
  const schemaProps = unwrapped.properties;
2256
1735
  if (schemaProps && !Object.hasOwn(schemaProps, rootKey)) {
@@ -2266,494 +1745,474 @@ function parse(xmlInner, schema, options = {}) {
2266
1745
  throw new RXMLCoercionError("Failed to coerce by schema", error);
2267
1746
  }
2268
1747
  }
2269
- function parseWithoutSchema(xmlString, options = {}) {
2270
- try {
2271
- const tokenizer = new XMLTokenizer(xmlString, options);
2272
- return tokenizer.parseChildren();
2273
- } catch (error) {
2274
- if (shouldRethrowParseError(error, xmlString)) {
2275
- throw new RXMLParseError(
2276
- error.message,
2277
- error.cause,
2278
- error.line,
2279
- error.column
2280
- );
2281
- }
2282
- if (options.onError) {
2283
- options.onError("Failed to parse XML without schema", { error });
2284
- }
2285
- try {
2286
- const partialResults = extractPartialXmlResults(xmlString, options);
2287
- if (partialResults.length > 0) {
2288
- return partialResults;
2289
- }
2290
- } catch (e) {
2291
- }
2292
- return [xmlString.trim()];
1748
+
1749
+ // src/heuristics/engine.ts
1750
+ function applyRawSegmentUpdate(current, result) {
1751
+ if (result.rawSegment !== void 0) {
1752
+ return { ...current, rawSegment: result.rawSegment };
2293
1753
  }
1754
+ return current;
2294
1755
  }
2295
- function parseNode(xmlString, options = {}) {
2296
- try {
2297
- const tokenizer = new XMLTokenizer(xmlString, options);
2298
- return tokenizer.parseNode();
2299
- } catch (error) {
2300
- throw new RXMLParseError("Failed to parse XML node", error);
1756
+ function applyParsedUpdate(current, result) {
1757
+ if (result.parsed !== void 0) {
1758
+ return { ...current, parsed: result.parsed };
2301
1759
  }
1760
+ return current;
2302
1761
  }
2303
- function buildNodeValue(child) {
2304
- const kids = simplify(child.children);
2305
- let nodeValue = kids;
2306
- if (Object.keys(child.attributes).length) {
2307
- if (typeof kids === "string") {
2308
- nodeValue = kids;
2309
- if (kids !== "") {
2310
- nodeValue = { _attributes: child.attributes, value: kids };
2311
- } else {
2312
- nodeValue = { _attributes: child.attributes };
2313
- }
2314
- } else if (typeof kids === "object" && kids !== null) {
2315
- kids._attributes = child.attributes;
2316
- nodeValue = kids;
2317
- } else {
2318
- nodeValue = { _attributes: child.attributes };
2319
- }
1762
+ function applyWarningsUpdate(current, result) {
1763
+ var _a, _b;
1764
+ if (result.warnings && result.warnings.length > 0) {
1765
+ const meta = (_a = current.meta) != null ? _a : {};
1766
+ const existingWarnings = (_b = meta.warnings) != null ? _b : [];
1767
+ return {
1768
+ ...current,
1769
+ meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
1770
+ };
2320
1771
  }
2321
- return nodeValue;
1772
+ return current;
2322
1773
  }
2323
- function simplify(children) {
2324
- if (!children.length) {
2325
- return "";
2326
- }
2327
- if (children.length === 1 && typeof children[0] === "string") {
2328
- return children[0];
2329
- }
2330
- const out = {};
2331
- for (const child of children) {
2332
- if (typeof child !== "object") {
2333
- continue;
2334
- }
2335
- if (!out[child.tagName]) {
2336
- out[child.tagName] = [];
2337
- }
2338
- const nodeValue = buildNodeValue(child);
2339
- out[child.tagName].push(nodeValue);
1774
+ function attemptReparse(current, result, reparseCount, maxReparses, parse3) {
1775
+ if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
1776
+ return { state: current, newCount: reparseCount };
2340
1777
  }
2341
- for (const key in out) {
2342
- if (!Object.hasOwn(out, key)) {
2343
- continue;
2344
- }
2345
- const value = out[key];
2346
- if (Array.isArray(value) && value.length === 1) {
2347
- out[key] = value[0];
2348
- }
1778
+ try {
1779
+ const reparsed = parse3(result.rawSegment, current.schema);
1780
+ return {
1781
+ state: { ...current, parsed: reparsed, errors: [] },
1782
+ newCount: reparseCount + 1
1783
+ };
1784
+ } catch (error) {
1785
+ return {
1786
+ state: { ...current, errors: [...current.errors, error] },
1787
+ newCount: reparseCount + 1
1788
+ };
2349
1789
  }
2350
- return out;
2351
1790
  }
2352
- function filter(children, filterFn, depth = 0, path = "") {
2353
- const out = [];
2354
- for (let i = 0; i < children.length; i += 1) {
2355
- const child = children[i];
2356
- if (typeof child === "object" && filterFn(child, i, depth, path)) {
2357
- out.push(child);
1791
+ function executePhase(ctx, heuristics, options) {
1792
+ var _a;
1793
+ let current = ctx;
1794
+ let reparseCount = 0;
1795
+ const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
1796
+ for (const heuristic of heuristics) {
1797
+ if (!heuristic.applies(current)) {
1798
+ continue;
2358
1799
  }
2359
- if (typeof child === "object" && child.children) {
2360
- const childPath = `${path ? `${path}.` : ""}${i}.${child.tagName}`;
2361
- const kids = filter(child.children, filterFn, depth + 1, childPath);
2362
- out.push(...kids);
1800
+ const result = heuristic.run(current);
1801
+ current = applyRawSegmentUpdate(current, result);
1802
+ current = applyParsedUpdate(current, result);
1803
+ current = applyWarningsUpdate(current, result);
1804
+ const reparseResult = attemptReparse(
1805
+ current,
1806
+ result,
1807
+ reparseCount,
1808
+ maxReparses,
1809
+ options.parse
1810
+ );
1811
+ current = reparseResult.state;
1812
+ reparseCount = reparseResult.newCount;
1813
+ if (result.stop) {
1814
+ break;
2363
1815
  }
2364
1816
  }
2365
- return out;
1817
+ return current;
2366
1818
  }
2367
-
2368
- // src/core/stream.ts
2369
- import { Transform } from "stream";
2370
- var TAG_NAME_REGEX = /^([a-zA-Z_][\w.-]*)/;
2371
- var WHITESPACE_REGEX2 = /\s/;
2372
- var XMLTransformStream = class extends Transform {
2373
- constructor(_offset, parseOptions = {}) {
2374
- super({ readableObjectMode: true });
2375
- this.buffer = "";
2376
- this.emittedCount = 0;
2377
- this.sawTagChar = false;
2378
- this.parseOptions = {
2379
- keepComments: false,
2380
- keepWhitespace: false,
2381
- ...parseOptions
2382
- };
1819
+ function applyHeuristicPipeline(ctx, config, options) {
1820
+ let current = ctx;
1821
+ if (config.preParse && config.preParse.length > 0) {
1822
+ current = executePhase(current, config.preParse, options);
2383
1823
  }
2384
- _transform(chunk, _encoding, callback) {
1824
+ if (current.parsed === null && current.errors.length === 0) {
2385
1825
  try {
2386
- const incoming = chunk.toString();
2387
- if (incoming.includes("<")) {
2388
- this.sawTagChar = true;
2389
- }
2390
- this.buffer += incoming;
2391
- this.processBuffer();
2392
- callback();
1826
+ const parsed = options.parse(current.rawSegment, current.schema);
1827
+ current = { ...current, parsed, errors: [] };
2393
1828
  } catch (error) {
2394
- callback(new RXMLStreamError("Transform error", error));
1829
+ current = { ...current, errors: [error] };
2395
1830
  }
2396
1831
  }
2397
- _flush(callback) {
2398
- try {
2399
- if (this.buffer.length > 0) {
2400
- this.processBuffer(true);
2401
- }
2402
- if (this.sawTagChar && this.emittedCount === 0) {
2403
- throw new RXMLStreamError(
2404
- "Flush error",
2405
- new Error("No XML elements could be parsed from stream")
2406
- );
2407
- }
2408
- callback();
2409
- } catch (error) {
2410
- callback(new RXMLStreamError("Flush error", error));
2411
- }
1832
+ if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
1833
+ current = executePhase(current, config.fallbackReparse, options);
2412
1834
  }
2413
- processBuffer(isFlush = false) {
2414
- while (this.buffer.length > 0) {
2415
- if (!this.trimToNextTag(isFlush)) {
2416
- break;
2417
- }
2418
- if (this.tryProcessSpecialNode(isFlush)) {
2419
- continue;
2420
- }
2421
- if (this.trySkipStrayClosingTag(isFlush)) {
2422
- continue;
2423
- }
2424
- const tagInfo = this.extractTagInfo(isFlush);
2425
- if (!tagInfo) {
2426
- break;
2427
- }
2428
- if (this.tryProcessSelfClosingTag(tagInfo)) {
2429
- continue;
2430
- }
2431
- if (!this.tryProcessRegularElement(tagInfo, isFlush)) {
2432
- break;
2433
- }
2434
- }
1835
+ if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
1836
+ current = executePhase(current, config.postParse, options);
2435
1837
  }
2436
- trimToNextTag(isFlush) {
2437
- const openBracket = this.buffer.indexOf("<");
2438
- if (openBracket === -1) {
2439
- if (isFlush) {
2440
- this.buffer = "";
2441
- }
2442
- return false;
2443
- }
2444
- if (openBracket > 0) {
2445
- this.buffer = this.buffer.slice(openBracket);
1838
+ return current;
1839
+ }
1840
+ function createIntermediateCall(toolName, rawSegment, schema) {
1841
+ return {
1842
+ toolName,
1843
+ schema,
1844
+ rawSegment,
1845
+ parsed: null,
1846
+ errors: [],
1847
+ meta: { originalContent: rawSegment }
1848
+ };
1849
+ }
1850
+
1851
+ // src/heuristics/xml-defaults.ts
1852
+ import { unwrapJsonSchema as unwrapJsonSchema3 } from "@ai-sdk-tool/schema-coerce";
1853
+ var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
1854
+ var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
1855
+ var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
1856
+ var WHITESPACE_REGEX2 = /\s/;
1857
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
1858
+ var NAME_START_CHAR_RE = /[A-Za-z_:]/;
1859
+ var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
1860
+ var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
1861
+ var normalizeCloseTagsHeuristic = {
1862
+ id: "normalize-close-tags",
1863
+ phase: "pre-parse",
1864
+ applies: () => true,
1865
+ run: (ctx) => {
1866
+ const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1867
+ if (normalized !== ctx.rawSegment) {
1868
+ return { rawSegment: normalized };
1869
+ }
1870
+ return {};
1871
+ }
1872
+ };
1873
+ var escapeInvalidLtHeuristic = {
1874
+ id: "escape-invalid-lt",
1875
+ phase: "pre-parse",
1876
+ applies: () => true,
1877
+ run: (ctx) => {
1878
+ const escaped = escapeInvalidLt(ctx.rawSegment);
1879
+ if (escaped !== ctx.rawSegment) {
1880
+ return { rawSegment: escaped };
2446
1881
  }
2447
- return true;
1882
+ return {};
2448
1883
  }
2449
- tryProcessSpecialNode(isFlush) {
2450
- if (!(this.buffer.startsWith("<?") || this.buffer.startsWith("<!--") || this.buffer.startsWith("<![CDATA["))) {
1884
+ };
1885
+ var balanceTagsHeuristic = {
1886
+ id: "balance-tags",
1887
+ phase: "fallback-reparse",
1888
+ applies: (ctx) => {
1889
+ var _a;
1890
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
1891
+ const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
1892
+ const balanced = balanceTags(original);
1893
+ const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
1894
+ if (!hasMalformedClose && balanced.length > normalized.length && ctx.errors.length === 0) {
2451
1895
  return false;
2452
1896
  }
2453
- const endMarkers = {
2454
- "<?": "?>",
2455
- "<!--": "-->",
2456
- "<![CDATA[": "]]>"
2457
- };
2458
- let endMarker = "";
2459
- for (const [start, end] of Object.entries(endMarkers)) {
2460
- if (this.buffer.startsWith(start)) {
2461
- endMarker = end;
2462
- break;
2463
- }
2464
- }
2465
- const endPos = endMarker ? this.buffer.indexOf(endMarker) : -1;
2466
- if (endPos === -1) {
2467
- if (isFlush) {
2468
- this.buffer = "";
2469
- }
2470
- return false;
1897
+ return balanced !== normalized;
1898
+ },
1899
+ run: (ctx) => {
1900
+ var _a;
1901
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
1902
+ const balanced = balanceTags(original);
1903
+ const escaped = escapeInvalidLt(balanced);
1904
+ return { rawSegment: escaped, reparse: true };
1905
+ }
1906
+ };
1907
+ var dedupeShellStringTagsHeuristic = {
1908
+ id: "dedupe-shell-string-tags",
1909
+ phase: "fallback-reparse",
1910
+ applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
1911
+ run: (ctx) => {
1912
+ const names = getStringPropertyNames(ctx.schema);
1913
+ let deduped = ctx.rawSegment;
1914
+ for (const key of names) {
1915
+ deduped = dedupeSingleTag(deduped, key);
2471
1916
  }
2472
- if (this.parseOptions.keepComments && this.buffer.startsWith("<!--")) {
2473
- this.push(this.buffer.slice(0, endPos + endMarker.length));
1917
+ if (deduped !== ctx.rawSegment) {
1918
+ return { rawSegment: deduped, reparse: true };
2474
1919
  }
2475
- this.buffer = this.buffer.slice(endPos + endMarker.length);
2476
- return true;
1920
+ return {};
2477
1921
  }
2478
- trySkipStrayClosingTag(isFlush) {
2479
- if (!this.buffer.startsWith("</")) {
2480
- return false;
2481
- }
2482
- const closeEnd = this.buffer.indexOf(">");
2483
- if (closeEnd === -1) {
2484
- if (isFlush) {
2485
- this.buffer = "";
2486
- }
2487
- return true;
1922
+ };
1923
+ var repairAgainstSchemaHeuristic = {
1924
+ id: "repair-against-schema",
1925
+ phase: "post-parse",
1926
+ applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
1927
+ run: (ctx) => {
1928
+ const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
1929
+ if (repaired !== ctx.parsed) {
1930
+ return { parsed: repaired };
2488
1931
  }
2489
- this.buffer = this.buffer.slice(closeEnd + 1);
2490
- return true;
1932
+ return {};
2491
1933
  }
2492
- extractTagInfo(isFlush) {
2493
- const openTagEnd = this.buffer.indexOf(">");
2494
- if (openTagEnd === -1) {
2495
- if (isFlush) {
2496
- this.buffer = "";
1934
+ };
1935
+ var defaultPipelineConfig = {
1936
+ preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
1937
+ fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
1938
+ postParse: [repairAgainstSchemaHeuristic]
1939
+ };
1940
+ var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
1941
+ function isIndexTagAt(xml, pos) {
1942
+ const remaining = xml.slice(pos);
1943
+ return INDEX_TAG_RE.test(remaining);
1944
+ }
1945
+ function escapeInvalidLt(xml) {
1946
+ const len = xml.length;
1947
+ let out = "";
1948
+ for (let i = 0; i < len; i += 1) {
1949
+ const ch = xml[i];
1950
+ if (ch === "<") {
1951
+ const next = i + 1 < len ? xml[i + 1] : "";
1952
+ const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
1953
+ const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
1954
+ if (!(isValidStart || isIndexTag)) {
1955
+ out += "&lt;";
1956
+ continue;
2497
1957
  }
2498
- return null;
2499
- }
2500
- const openTagContent = this.buffer.slice(1, openTagEnd);
2501
- const nameMatch = openTagContent.match(TAG_NAME_REGEX);
2502
- if (!nameMatch) {
2503
- this.buffer = this.buffer.slice(1);
2504
- return null;
2505
1958
  }
2506
- return { openTagEnd, tagName: nameMatch[1] };
1959
+ out += ch;
2507
1960
  }
2508
- tryProcessSelfClosingTag(tagInfo) {
2509
- const isSelfClosing = this.buffer[tagInfo.openTagEnd - 1] === "/";
2510
- if (!isSelfClosing) {
2511
- return false;
1961
+ return out;
1962
+ }
1963
+ function balanceTags(xml) {
1964
+ const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
1965
+ let i = 0;
1966
+ const len = src.length;
1967
+ const out = [];
1968
+ const stack = [];
1969
+ while (i < len) {
1970
+ const lt = src.indexOf("<", i);
1971
+ if (lt === -1) {
1972
+ out.push(src.slice(i));
1973
+ break;
2512
1974
  }
2513
- const elementEnd = tagInfo.openTagEnd + 1;
2514
- const elementXml = this.buffer.slice(0, elementEnd);
2515
- try {
2516
- const tokenizer = new XMLTokenizer(elementXml, this.parseOptions);
2517
- const node = tokenizer.parseNode();
2518
- this.emitElementAndChildren(node);
2519
- this.buffer = this.buffer.slice(elementEnd);
2520
- return true;
2521
- } catch (e) {
2522
- this.buffer = this.buffer.slice(1);
2523
- return true;
1975
+ out.push(src.slice(i, lt));
1976
+ if (lt + 1 >= len) {
1977
+ break;
2524
1978
  }
2525
- }
2526
- tryProcessRegularElement(tagInfo, isFlush) {
2527
- const elementEnd = this.findMatchingClosingTag(
2528
- tagInfo.tagName,
2529
- tagInfo.openTagEnd
2530
- );
2531
- if (elementEnd === -1) {
2532
- if (isFlush) {
2533
- this.buffer = this.buffer.slice(1);
2534
- return true;
2535
- }
2536
- return false;
1979
+ const next = src[lt + 1];
1980
+ if (next === "!" || next === "?") {
1981
+ i = handleSpecialTagSegment(src, lt, out);
1982
+ continue;
2537
1983
  }
2538
- const elementXml = this.buffer.slice(0, elementEnd);
2539
- try {
2540
- const tokenizer = new XMLTokenizer(elementXml, this.parseOptions);
2541
- const node = tokenizer.parseNode();
2542
- this.emitElementAndChildren(node);
2543
- this.buffer = this.buffer.slice(elementEnd);
2544
- return true;
2545
- } catch (e) {
2546
- this.emit("error", new RXMLStreamError("Parse error", e));
2547
- return false;
1984
+ if (next === "/") {
1985
+ i = handleClosingTagSegment(src, lt, out, stack);
1986
+ continue;
2548
1987
  }
1988
+ i = handleOpeningTagSegment(src, lt, out, stack);
2549
1989
  }
2550
- findMatchingClosingTag(tagName, openTagEnd) {
2551
- let depth = 1;
2552
- let searchStart = openTagEnd + 1;
2553
- while (searchStart < this.buffer.length) {
2554
- const nextOpen = this.findNextOpeningTag(tagName, searchStart);
2555
- const nextCloseStart = this.buffer.indexOf(`</${tagName}`, searchStart);
2556
- if (nextCloseStart === -1) {
2557
- return -1;
2558
- }
2559
- if (nextOpen !== -1 && nextOpen < nextCloseStart) {
2560
- depth += 1;
2561
- searchStart = nextOpen + 1;
2562
- } else {
2563
- depth -= 1;
2564
- const closeAdvance = this.advancePastClosingTag(
2565
- tagName,
2566
- nextCloseStart
2567
- );
2568
- if (closeAdvance === -1) {
2569
- return -1;
2570
- }
2571
- searchStart = closeAdvance;
2572
- if (depth === 0) {
2573
- return searchStart;
2574
- }
2575
- }
2576
- }
2577
- return -1;
1990
+ for (let k = stack.length - 1; k >= 0; k -= 1) {
1991
+ out.push(`</${stack[k]}>`);
2578
1992
  }
2579
- findNextOpeningTag(tagName, searchStart) {
2580
- let nextOpen = this.buffer.indexOf(`<${tagName}`, searchStart);
2581
- while (nextOpen !== -1) {
2582
- const after = this.buffer[nextOpen + tagName.length + 1];
2583
- if (after === void 0 || after === ">" || WHITESPACE_REGEX2.test(after)) {
2584
- break;
2585
- }
2586
- nextOpen = this.buffer.indexOf(`<${tagName}`, nextOpen + 1);
2587
- }
2588
- return nextOpen;
1993
+ return out.join("");
1994
+ }
1995
+ function skipWs(s, p, len) {
1996
+ let idx = p;
1997
+ while (idx < len && WHITESPACE_REGEX2.test(s[idx])) {
1998
+ idx += 1;
2589
1999
  }
2590
- advancePastClosingTag(tagName, nextCloseStart) {
2591
- let p = nextCloseStart + 2 + tagName.length;
2592
- while (p < this.buffer.length && WHITESPACE_REGEX2.test(this.buffer[p])) {
2593
- p += 1;
2594
- }
2595
- if (this.buffer[p] !== ">") {
2596
- return -1;
2597
- }
2598
- return p + 1;
2000
+ return idx;
2001
+ }
2002
+ function parseTagNameAt(s, p, len) {
2003
+ let idx = p;
2004
+ const start = idx;
2005
+ while (idx < len && NAME_CHAR_RE.test(s[idx])) {
2006
+ idx += 1;
2599
2007
  }
2600
- /**
2601
- * Emit an element and recursively emit its children as separate events
2602
- */
2603
- emitElementAndChildren(node) {
2604
- if (typeof node === "string") {
2605
- if (this.parseOptions.keepComments && node.includes("<!--")) {
2606
- this.push(node);
2607
- this.emittedCount += 1;
2608
- }
2609
- return;
2008
+ return { name: s.slice(start, idx), pos: idx };
2009
+ }
2010
+ function handleSpecialTagSegment(src, lt, out) {
2011
+ const gt = src.indexOf(">", lt + 1);
2012
+ if (gt === -1) {
2013
+ out.push(src.slice(lt));
2014
+ return src.length;
2015
+ }
2016
+ out.push(src.slice(lt, gt + 1));
2017
+ return gt + 1;
2018
+ }
2019
+ function handleClosingTagSegment(src, lt, out, stack) {
2020
+ const len = src.length;
2021
+ let p = skipWs(src, lt + 2, len);
2022
+ const { name, pos } = parseTagNameAt(src, p, len);
2023
+ p = pos;
2024
+ const gt = src.indexOf(">", p);
2025
+ const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
2026
+ const idx = stack.lastIndexOf(name);
2027
+ if (idx !== -1) {
2028
+ for (let k = stack.length - 1; k > idx; k -= 1) {
2029
+ out.push(`</${stack[k]}>`);
2030
+ stack.pop();
2610
2031
  }
2611
- this.push(node);
2612
- this.emittedCount += 1;
2613
- for (const child of node.children) {
2614
- this.emitElementAndChildren(child);
2032
+ out.push(closingText);
2033
+ stack.pop();
2034
+ }
2035
+ return gt === -1 ? len : gt + 1;
2036
+ }
2037
+ function handleOpeningTagSegment(src, lt, out, stack) {
2038
+ const len = src.length;
2039
+ let p = skipWs(src, lt + 1, len);
2040
+ const nameStart = p;
2041
+ const parsed = parseTagNameAt(src, p, len);
2042
+ p = parsed.pos;
2043
+ const name = src.slice(nameStart, p);
2044
+ const q = src.indexOf(">", p);
2045
+ if (q === -1) {
2046
+ out.push(src.slice(lt));
2047
+ return len;
2048
+ }
2049
+ let r = q - 1;
2050
+ while (r >= nameStart && WHITESPACE_REGEX2.test(src[r])) {
2051
+ r -= 1;
2052
+ }
2053
+ const selfClosing = src[r] === "/";
2054
+ out.push(src.slice(lt, q + 1));
2055
+ if (!selfClosing && name) {
2056
+ stack.push(name);
2057
+ }
2058
+ return q + 1;
2059
+ }
2060
+ function extractSchemaProperties(schema) {
2061
+ const unwrapped = unwrapJsonSchema3(schema);
2062
+ if (!unwrapped || typeof unwrapped !== "object") {
2063
+ return void 0;
2064
+ }
2065
+ return unwrapped.properties;
2066
+ }
2067
+ function shouldDeduplicateStringTags(schema) {
2068
+ const props = extractSchemaProperties(schema);
2069
+ if (!props) {
2070
+ return false;
2071
+ }
2072
+ const commandRaw = props.command;
2073
+ if (!commandRaw) {
2074
+ return false;
2075
+ }
2076
+ const command = unwrapJsonSchema3(commandRaw);
2077
+ return (command == null ? void 0 : command.type) === "array";
2078
+ }
2079
+ function getStringPropertyNames(schema) {
2080
+ const props = extractSchemaProperties(schema);
2081
+ if (!props) {
2082
+ return [];
2083
+ }
2084
+ const names = [];
2085
+ for (const key of Object.keys(props)) {
2086
+ const prop = unwrapJsonSchema3(props[key]);
2087
+ if ((prop == null ? void 0 : prop.type) === "string") {
2088
+ names.push(key);
2615
2089
  }
2616
2090
  }
2617
- };
2618
- function createXMLStream(offset, parseOptions) {
2619
- return new XMLTransformStream(offset, parseOptions);
2620
- }
2621
- function parseFromStream(stream, offset, parseOptions) {
2622
- return new Promise((resolve, reject) => {
2623
- const results = [];
2624
- const transformStream = createXMLStream(offset, parseOptions);
2625
- const onSourceError = (err) => {
2626
- transformStream.destroy(err);
2627
- };
2628
- stream.on("error", onSourceError);
2629
- transformStream.on("data", (element) => {
2630
- results.push(element);
2631
- });
2632
- transformStream.on("end", () => {
2633
- stream.off("error", onSourceError);
2634
- resolve(results);
2635
- });
2636
- transformStream.on("error", (error) => {
2637
- stream.off("error", onSourceError);
2638
- reject(new RXMLStreamError("Stream parsing failed", error));
2639
- });
2640
- stream.pipe(transformStream);
2641
- });
2091
+ return names;
2642
2092
  }
2643
- async function* processXMLStream(stream, offset, parseOptions) {
2644
- const transformStream = createXMLStream(offset, parseOptions);
2645
- let ended = false;
2646
- let error = null;
2647
- const queue = [];
2648
- let resolveNext = null;
2649
- const onSourceError = (err) => {
2650
- error = err;
2651
- transformStream.destroy(err);
2652
- };
2653
- stream.on("error", onSourceError);
2654
- transformStream.on("data", (element) => {
2655
- if (resolveNext) {
2656
- resolveNext({ value: element, done: false });
2657
- resolveNext = null;
2658
- } else {
2659
- queue.push(element);
2093
+ function escapeRegExp(s) {
2094
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2095
+ }
2096
+ function dedupeSingleTag(xml, key) {
2097
+ var _a, _b;
2098
+ const escaped = escapeRegExp(key);
2099
+ const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
2100
+ const matches = Array.from(xml.matchAll(re));
2101
+ if (matches.length <= 1) {
2102
+ return xml;
2103
+ }
2104
+ const last = matches.at(-1);
2105
+ let result = "";
2106
+ let cursor = 0;
2107
+ for (const m of matches) {
2108
+ const idx = (_a = m.index) != null ? _a : 0;
2109
+ result += xml.slice(cursor, idx);
2110
+ if (last && idx === ((_b = last.index) != null ? _b : -1)) {
2111
+ result += m[0];
2660
2112
  }
2661
- });
2662
- transformStream.on("end", () => {
2663
- ended = true;
2664
- if (resolveNext) {
2665
- resolveNext({ value: void 0, done: true });
2666
- resolveNext = null;
2113
+ cursor = idx + m[0].length;
2114
+ }
2115
+ result += xml.slice(cursor);
2116
+ return result;
2117
+ }
2118
+ function repairParsedAgainstSchema(input, schema) {
2119
+ if (!input || typeof input !== "object") {
2120
+ return input;
2121
+ }
2122
+ const properties = extractSchemaProperties(schema);
2123
+ if (!properties) {
2124
+ return input;
2125
+ }
2126
+ applySchemaProps(input, properties);
2127
+ return input;
2128
+ }
2129
+ function applySchemaProps(obj, properties) {
2130
+ for (const key of Object.keys(obj)) {
2131
+ const propSchema = properties[key];
2132
+ if (!propSchema) {
2133
+ continue;
2667
2134
  }
2668
- stream.off("error", onSourceError);
2669
- });
2670
- transformStream.on("error", (err) => {
2671
- error = err;
2672
- if (resolveNext) {
2673
- resolveNext({ value: void 0, done: true });
2674
- resolveNext = null;
2135
+ const prop = unwrapJsonSchema3(propSchema);
2136
+ if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
2137
+ const itemSchema = unwrapJsonSchema3(prop.items);
2138
+ obj[key] = coerceArrayItems(obj[key], itemSchema);
2139
+ continue;
2675
2140
  }
2676
- stream.off("error", onSourceError);
2677
- });
2678
- stream.pipe(transformStream);
2679
- while (true) {
2680
- if (error) {
2681
- throw new RXMLStreamError("Stream processing error", error);
2682
- }
2683
- if (queue.length > 0) {
2684
- const item = queue.shift();
2685
- if (item !== void 0) {
2686
- yield item;
2141
+ if ((prop == null ? void 0 : prop.type) === "object") {
2142
+ const val = obj[key];
2143
+ if (val && typeof val === "object") {
2144
+ obj[key] = repairParsedAgainstSchema(val, prop);
2687
2145
  }
2688
- continue;
2689
2146
  }
2690
- if (ended) {
2691
- break;
2147
+ }
2148
+ }
2149
+ function coerceArrayItems(val, itemSchema) {
2150
+ if (!Array.isArray(val)) {
2151
+ return val;
2152
+ }
2153
+ return val.map((v) => coerceArrayItem(v, itemSchema));
2154
+ }
2155
+ function coerceArrayItem(v, itemSchema) {
2156
+ const itemType = itemSchema == null ? void 0 : itemSchema.type;
2157
+ if (typeof v === "string" && itemType === "object") {
2158
+ const parsed = tryParseStringToSchemaObject(v, itemSchema);
2159
+ if (parsed !== null) {
2160
+ return parsed;
2692
2161
  }
2693
- const result = await new Promise(
2694
- (resolve) => {
2695
- resolveNext = resolve;
2696
- }
2162
+ const fallback = extractStepStatusFromString(
2163
+ v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
2697
2164
  );
2698
- if (result.done) {
2699
- if (error) {
2700
- throw new RXMLStreamError("Stream processing error", error);
2701
- }
2702
- break;
2165
+ if (fallback) {
2166
+ return fallback;
2703
2167
  }
2704
- yield result.value;
2168
+ return v;
2705
2169
  }
2170
+ if (v && typeof v === "object" && itemType === "object") {
2171
+ return repairParsedAgainstSchema(v, itemSchema);
2172
+ }
2173
+ return v;
2706
2174
  }
2707
- async function* findElementByIdStream(stream, id, offset, parseOptions) {
2708
- for await (const element of processXMLStream(stream, offset, parseOptions)) {
2709
- if (typeof element === "object" && element.attributes.id === id) {
2710
- yield element;
2711
- }
2175
+ function tryParseStringToSchemaObject(xml, itemSchema) {
2176
+ try {
2177
+ const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
2178
+ const fixed = parse(normalized, itemSchema, { noChildNodes: [] });
2179
+ return typeof fixed === "string" ? null : fixed;
2180
+ } catch (e) {
2181
+ return null;
2712
2182
  }
2713
2183
  }
2714
- async function* findElementsByClassStream(stream, className, offset, parseOptions) {
2715
- const classRegex = new RegExp(`\\b${className}\\b`);
2716
- for await (const element of processXMLStream(stream, offset, parseOptions)) {
2717
- if (typeof element === "object" && element.attributes.class && classRegex.test(element.attributes.class)) {
2718
- yield element;
2719
- }
2184
+ function extractStepStatusFromString(normXml) {
2185
+ const stepMatch = normXml.match(STEP_TAG_RE);
2186
+ const statusMatch = normXml.match(STATUS_TAG_RE);
2187
+ if (stepMatch && statusMatch) {
2188
+ return { step: stepMatch[1], status: statusMatch[1] };
2189
+ }
2190
+ return null;
2191
+ }
2192
+
2193
+ // src/parse.ts
2194
+ function parse2(xml, schema, options = {}) {
2195
+ if (!options.repair) {
2196
+ return parse(xml, schema, options);
2197
+ }
2198
+ const baseOptions = {
2199
+ ...options,
2200
+ repair: false
2201
+ };
2202
+ const ctx = createIntermediateCall("", xml, schema);
2203
+ const result = applyHeuristicPipeline(ctx, defaultPipelineConfig, {
2204
+ parse: (raw, s) => parse(raw, s, baseOptions),
2205
+ onError: options.onError,
2206
+ maxReparses: options.maxReparses
2207
+ });
2208
+ if (result.parsed !== null) {
2209
+ return result.parsed;
2720
2210
  }
2211
+ const error = result.errors[0];
2212
+ throw new RXMLParseError("Failed to parse XML with repair heuristics", error);
2721
2213
  }
2722
2214
  export {
2723
- RXMLCoercionError,
2724
- RXMLDuplicateStringTagError,
2725
- RXMLParseError,
2726
- RXMLStreamError,
2727
- RXMLStringifyError,
2728
- XMLTokenizer,
2729
- XMLTransformStream,
2730
- coerceBySchema,
2731
- coerceDomBySchema,
2732
- countTagOccurrences,
2733
- createXMLStream,
2734
- domToObject,
2735
- extractRawInner,
2736
- filter,
2737
- findAllTopLevelRanges,
2738
- findElementByIdStream,
2739
- findElementsByClassStream,
2740
- findFirstTopLevelRange,
2741
- getPropertySchema,
2742
- getSchemaType,
2743
- getStringTypedProperties,
2744
- parse,
2745
- parseFromStream,
2746
- parseNode,
2747
- parseWithoutSchema,
2748
- processArrayContent,
2749
- processIndexedTuple,
2750
- processXMLStream,
2751
- simplify,
2752
- stringify,
2753
- stringifyNode,
2754
- stringifyNodes,
2755
- toContentString,
2756
- unescapeXml,
2757
- unwrapJsonSchema
2215
+ parse2 as parse,
2216
+ stringify
2758
2217
  };
2759
2218
  //# sourceMappingURL=index.js.map