@ai-sdk-tool/parser 3.2.1 → 3.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -17,7 +17,6 @@ var __copyProps = (to, from, except, desc) => {
17
17
  }
18
18
  return to;
19
19
  };
20
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
21
20
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
21
  // If the importer is in node compatibility mode or this is not an ESM
23
22
  // file that has been converted to a CommonJS file using a Babel-
@@ -52,7 +51,10 @@ __export(src_exports, {
52
51
  logParsedSummary: () => logParsedSummary,
53
52
  logRawChunk: () => logRawChunk,
54
53
  originalToolsSchema: () => originalToolsSchema,
54
+ parse: () => parse,
55
+ stringify: () => stringify,
55
56
  toolChoiceStream: () => toolChoiceStream,
57
+ transform: () => transform,
56
58
  transformParams: () => transformParams,
57
59
  wrapGenerate: () => wrapGenerate,
58
60
  wrapStream: () => wrapStream,
@@ -62,10 +64,671 @@ __export(src_exports, {
62
64
  yamlToolMiddleware: () => yamlToolMiddleware
63
65
  });
64
66
  module.exports = __toCommonJS(src_exports);
65
- __reExport(src_exports, require("@ai-sdk-tool/rjson"), module.exports);
66
67
 
67
- // src/core/protocols/json-protocol.ts
68
- var import_rjson = require("@ai-sdk-tool/rjson");
68
+ // src/rjson/index.ts
69
+ var WHITESPACE_TEST_REGEX = /\s/;
70
+ var WHITESPACE_REGEX = /^\s+/;
71
+ var OBJECT_START_REGEX = /^\{/;
72
+ var OBJECT_END_REGEX = /^\}/;
73
+ var ARRAY_START_REGEX = /^\[/;
74
+ var ARRAY_END_REGEX = /^\]/;
75
+ var COMMA_REGEX = /^,/;
76
+ var COLON_REGEX = /^:/;
77
+ var KEYWORD_REGEX = /^(?:true|false|null)/;
78
+ var NUMBER_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?/;
79
+ var STRING_DOUBLE_REGEX = /^"(?:[^"\\]|\\["bnrtf\\/]|\\u[0-9a-fA-F]{4})*"/;
80
+ var STRING_SINGLE_REGEX = /^'((?:[^'\\]|\\['bnrtf\\/]|\\u[0-9a-fA-F]{4})*)'/;
81
+ var COMMENT_SINGLE_REGEX = /^\/\/.*?(?:\r\n|\r|\n)/;
82
+ var COMMENT_MULTI_REGEX = /^\/\*[\s\S]*?\*\//;
83
+ var IDENTIFIER_REGEX = /^[$a-zA-Z0-9_\-+.*?!|&%^/#\\]+/;
84
+ function some(array, f) {
85
+ let acc = false;
86
+ for (let i = 0; i < array.length; i += 1) {
87
+ const result = f(array[i], i, array);
88
+ acc = result === void 0 ? false : result;
89
+ if (acc) {
90
+ return acc;
91
+ }
92
+ }
93
+ return acc;
94
+ }
95
+ function makeLexer(tokenSpecs) {
96
+ return (contents) => {
97
+ const tokens = [];
98
+ let line = 1;
99
+ let remainingContents = contents;
100
+ function findToken() {
101
+ const result = some(tokenSpecs, (tokenSpec) => {
102
+ const m = tokenSpec.re.exec(remainingContents);
103
+ if (m) {
104
+ const raw = m[0];
105
+ remainingContents = remainingContents.slice(raw.length);
106
+ return {
107
+ raw,
108
+ matched: tokenSpec.f(m)
109
+ // Process the match using the spec's function
110
+ };
111
+ }
112
+ return;
113
+ });
114
+ return result === false ? void 0 : result;
115
+ }
116
+ while (remainingContents !== "") {
117
+ const matched = findToken();
118
+ if (!matched) {
119
+ const err = new SyntaxError(
120
+ `Unexpected character: ${remainingContents[0]}; input: ${remainingContents.substr(
121
+ 0,
122
+ 100
123
+ )}`
124
+ );
125
+ err.line = line;
126
+ throw err;
127
+ }
128
+ const tokenWithLine = matched.matched;
129
+ tokenWithLine.line = line;
130
+ line += matched.raw.replace(/[^\n]/g, "").length;
131
+ tokens.push(tokenWithLine);
132
+ }
133
+ return tokens;
134
+ };
135
+ }
136
+ function fStringSingle(m) {
137
+ const content = m[1].replace(
138
+ /([^'\\]|\\['bnrtf\\]|\\u[0-9a-fA-F]{4})/g,
139
+ (mm) => {
140
+ if (mm === '"') {
141
+ return '\\"';
142
+ }
143
+ if (mm === "\\'") {
144
+ return "'";
145
+ }
146
+ return mm;
147
+ }
148
+ );
149
+ const match = `"${content}"`;
150
+ return {
151
+ type: "string",
152
+ match,
153
+ // The transformed, double-quoted string representation
154
+ // Use JSON.parse on the transformed string to handle escape sequences correctly
155
+ value: JSON.parse(match)
156
+ };
157
+ }
158
+ function fStringDouble(m) {
159
+ return {
160
+ type: "string",
161
+ match: m[0],
162
+ // The raw matched string (including quotes)
163
+ value: JSON.parse(m[0])
164
+ // Use JSON.parse to handle escapes and get the value
165
+ };
166
+ }
167
+ function fIdentifier(m) {
168
+ const value = m[0];
169
+ const match = '"' + value.replace(/\\/g, "\\\\").replace(/"/g, '\\"') + // Escape backslashes and quotes
170
+ '"';
171
+ return {
172
+ type: "string",
173
+ // Treat identifiers as strings
174
+ value,
175
+ // The original identifier name
176
+ match
177
+ // The double-quoted string representation
178
+ };
179
+ }
180
+ function fComment(m) {
181
+ const match = m[0].replace(
182
+ /./g,
183
+ (c) => WHITESPACE_TEST_REGEX.test(c) ? c : " "
184
+ );
185
+ return {
186
+ type: " ",
187
+ // Represent comments as whitespace tokens
188
+ match,
189
+ // String containing original newlines and spaces for other chars
190
+ value: void 0
191
+ // Comments don't have a semantic value
192
+ };
193
+ }
194
+ function fNumber(m) {
195
+ return {
196
+ type: "number",
197
+ match: m[0],
198
+ // The raw matched number string
199
+ value: Number.parseFloat(m[0])
200
+ // Convert string to number
201
+ };
202
+ }
203
+ function fKeyword(m) {
204
+ let value;
205
+ switch (m[0]) {
206
+ case "null":
207
+ value = null;
208
+ break;
209
+ case "true":
210
+ value = true;
211
+ break;
212
+ case "false":
213
+ value = false;
214
+ break;
215
+ default:
216
+ throw new Error(`Unexpected keyword: ${m[0]}`);
217
+ }
218
+ return {
219
+ type: "atom",
220
+ // Use 'atom' type for these literals
221
+ match: m[0],
222
+ // The raw matched keyword
223
+ value
224
+ // The corresponding JavaScript value
225
+ };
226
+ }
227
+ function makeTokenSpecs(relaxed) {
228
+ function f(type) {
229
+ return (m) => {
230
+ return { type, match: m[0], value: void 0 };
231
+ };
232
+ }
233
+ let tokenSpecs = [
234
+ { re: WHITESPACE_REGEX, f: f(" ") },
235
+ // Whitespace
236
+ { re: OBJECT_START_REGEX, f: f("{") },
237
+ // Object start
238
+ { re: OBJECT_END_REGEX, f: f("}") },
239
+ // Object end
240
+ { re: ARRAY_START_REGEX, f: f("[") },
241
+ // Array start
242
+ { re: ARRAY_END_REGEX, f: f("]") },
243
+ // Array end
244
+ { re: COMMA_REGEX, f: f(",") },
245
+ // Comma separator
246
+ { re: COLON_REGEX, f: f(":") },
247
+ // Key-value separator
248
+ { re: KEYWORD_REGEX, f: fKeyword },
249
+ // Keywords
250
+ // Number: optional sign, digits, optional decimal part, optional exponent
251
+ { re: NUMBER_REGEX, f: fNumber },
252
+ // String: double-quoted, handles escapes
253
+ { re: STRING_DOUBLE_REGEX, f: fStringDouble }
254
+ ];
255
+ if (relaxed) {
256
+ tokenSpecs = tokenSpecs.concat([
257
+ // Single-quoted strings
258
+ {
259
+ re: STRING_SINGLE_REGEX,
260
+ f: fStringSingle
261
+ },
262
+ // Single-line comments (// ...)
263
+ { re: COMMENT_SINGLE_REGEX, f: fComment },
264
+ // Multi-line comments (/* ... */)
265
+ { re: COMMENT_MULTI_REGEX, f: fComment },
266
+ // Unquoted identifiers (treated as strings)
267
+ // Allows letters, numbers, _, -, +, ., *, ?, !, |, &, %, ^, /, #, \
268
+ { re: IDENTIFIER_REGEX, f: fIdentifier }
269
+ // Note: The order matters here. Identifiers are checked after keywords/numbers.
270
+ ]);
271
+ }
272
+ return tokenSpecs;
273
+ }
274
+ var lexer = makeLexer(makeTokenSpecs(true));
275
+ var strictLexer = makeLexer(makeTokenSpecs(false));
276
+ function previousNWSToken(tokens, index) {
277
+ let currentIndex = index;
278
+ for (; currentIndex >= 0; currentIndex -= 1) {
279
+ if (tokens[currentIndex].type !== " ") {
280
+ return currentIndex;
281
+ }
282
+ }
283
+ return;
284
+ }
285
+ function stripTrailingComma(tokens) {
286
+ const res = [];
287
+ tokens.forEach((token, index) => {
288
+ if (index > 0 && (token.type === "]" || token.type === "}")) {
289
+ const prevNWSTokenIndex = previousNWSToken(res, res.length - 1);
290
+ if (prevNWSTokenIndex !== void 0 && res[prevNWSTokenIndex].type === ",") {
291
+ const preCommaIndex = previousNWSToken(res, prevNWSTokenIndex - 1);
292
+ if (preCommaIndex !== void 0 && res[preCommaIndex].type !== "[" && res[preCommaIndex].type !== "{") {
293
+ res[prevNWSTokenIndex] = {
294
+ type: " ",
295
+ match: " ",
296
+ // Represent as a single space
297
+ value: void 0,
298
+ // Whitespace has no value
299
+ line: res[prevNWSTokenIndex].line
300
+ // Preserve original line number
301
+ };
302
+ }
303
+ }
304
+ }
305
+ res.push(token);
306
+ });
307
+ return res;
308
+ }
309
+ function transform(text) {
310
+ let tokens = lexer(text);
311
+ tokens = stripTrailingComma(tokens);
312
+ return tokens.reduce((str, token) => str + token.match, "");
313
+ }
314
+ function popToken(tokens, state) {
315
+ var _a, _b;
316
+ const token = tokens[state.pos];
317
+ state.pos += 1;
318
+ if (!token) {
319
+ const lastLine = tokens.length !== 0 ? (_b = (_a = tokens.at(-1)) == null ? void 0 : _a.line) != null ? _b : 1 : 1;
320
+ return { type: "eof", match: "", value: void 0, line: lastLine };
321
+ }
322
+ return token;
323
+ }
324
+ function strToken(token) {
325
+ switch (token.type) {
326
+ case "atom":
327
+ case "string":
328
+ case "number":
329
+ return `${token.type} ${token.match}`;
330
+ case "eof":
331
+ return "end-of-file";
332
+ default:
333
+ return `'${token.type}'`;
334
+ }
335
+ }
336
+ function skipColon(tokens, state) {
337
+ const colon = popToken(tokens, state);
338
+ if (colon.type !== ":") {
339
+ const message = `Unexpected token: ${strToken(colon)}, expected ':'`;
340
+ if (state.tolerant) {
341
+ state.warnings.push({
342
+ message,
343
+ line: colon.line
344
+ });
345
+ state.pos -= 1;
346
+ } else {
347
+ const err = new SyntaxError(message);
348
+ err.line = colon.line;
349
+ throw err;
350
+ }
351
+ }
352
+ }
353
+ function skipPunctuation(tokens, state, valid) {
354
+ const punctuation = [",", ":", "]", "}"];
355
+ let token = popToken(tokens, state);
356
+ while (true) {
357
+ if (valid == null ? void 0 : valid.includes(token.type)) {
358
+ return token;
359
+ }
360
+ if (token.type === "eof") {
361
+ return token;
362
+ }
363
+ if (punctuation.includes(token.type)) {
364
+ const message = `Unexpected token: ${strToken(
365
+ token
366
+ )}, expected '[', '{', number, string or atom`;
367
+ if (state.tolerant) {
368
+ state.warnings.push({
369
+ message,
370
+ line: token.line
371
+ });
372
+ token = popToken(tokens, state);
373
+ } else {
374
+ const err = new SyntaxError(message);
375
+ err.line = token.line;
376
+ throw err;
377
+ }
378
+ } else {
379
+ return token;
380
+ }
381
+ }
382
+ }
383
+ function raiseError(state, token, message) {
384
+ if (state.tolerant) {
385
+ state.warnings.push({
386
+ message,
387
+ line: token.line
388
+ });
389
+ } else {
390
+ const err = new SyntaxError(message);
391
+ err.line = token.line;
392
+ throw err;
393
+ }
394
+ }
395
+ function raiseUnexpected(state, token, expected) {
396
+ raiseError(
397
+ state,
398
+ token,
399
+ `Unexpected token: ${strToken(token)}, expected ${expected}`
400
+ );
401
+ }
402
+ function checkDuplicates(state, obj, token) {
403
+ const key = String(token.value);
404
+ if (!state.duplicate && Object.hasOwn(obj, key)) {
405
+ raiseError(state, token, `Duplicate key: ${key}`);
406
+ }
407
+ }
408
+ function appendPair(state, obj, key, value) {
409
+ const finalValue = state.reviver ? state.reviver(key, value) : value;
410
+ if (finalValue !== void 0) {
411
+ obj[key] = finalValue;
412
+ }
413
+ }
414
+ function parsePair(tokens, state, obj) {
415
+ let token = skipPunctuation(tokens, state, [":", "string", "number", "atom"]);
416
+ let value;
417
+ if (token.type !== "string") {
418
+ raiseUnexpected(state, token, "string key");
419
+ if (state.tolerant) {
420
+ switch (token.type) {
421
+ case ":":
422
+ token = {
423
+ type: "string",
424
+ value: "null",
425
+ match: '"null"',
426
+ line: token.line
427
+ };
428
+ state.pos -= 1;
429
+ break;
430
+ case "number":
431
+ // Use number as string key
432
+ case "atom":
433
+ token = {
434
+ type: "string",
435
+ value: String(token.value),
436
+ match: `"${token.value}"`,
437
+ line: token.line
438
+ };
439
+ break;
440
+ case "[":
441
+ // Assume missing key before an array
442
+ case "{":
443
+ state.pos -= 1;
444
+ value = parseAny(tokens, state);
445
+ checkDuplicates(state, obj, {
446
+ type: "string",
447
+ value: "null",
448
+ match: '"null"',
449
+ line: token.line
450
+ });
451
+ appendPair(state, obj, "null", value);
452
+ return;
453
+ // Finished parsing this "pair"
454
+ case "eof":
455
+ return;
456
+ // Cannot recover
457
+ default:
458
+ return;
459
+ }
460
+ } else {
461
+ return;
462
+ }
463
+ }
464
+ checkDuplicates(state, obj, token);
465
+ const key = String(token.value);
466
+ skipColon(tokens, state);
467
+ value = parseAny(tokens, state);
468
+ appendPair(state, obj, key, value);
469
+ }
470
+ function parseElement(tokens, state, arr) {
471
+ const key = arr.length;
472
+ const value = parseAny(tokens, state);
473
+ arr[key] = state.reviver ? state.reviver(String(key), value) : value;
474
+ }
475
+ function parseObject(tokens, state) {
476
+ const obj = {};
477
+ return parseMany(tokens, state, obj, {
478
+ skip: [":", "}"],
479
+ // Initially skip over colon or closing brace (for empty/tolerant cases)
480
+ elementParser: parsePair,
481
+ // Use parsePair to parse each key-value element
482
+ elementName: "string key",
483
+ // Expected element type for errors
484
+ endSymbol: "}"
485
+ // The closing token for an object
486
+ });
487
+ }
488
+ function parseArray(tokens, state) {
489
+ const arr = [];
490
+ return parseMany(tokens, state, arr, {
491
+ skip: ["]"],
492
+ // Initially skip over closing bracket (for empty/tolerant cases)
493
+ elementParser: parseElement,
494
+ // Use parseElement to parse each array item
495
+ elementName: "json value",
496
+ // Expected element type for errors
497
+ endSymbol: "]"
498
+ // The closing token for an array
499
+ });
500
+ }
501
+ function handleInvalidToken(token, state, opts, result) {
502
+ raiseUnexpected(state, token, `',' or '${opts.endSymbol}'`);
503
+ if (state.tolerant) {
504
+ if (token.type === "eof") {
505
+ return result;
506
+ }
507
+ state.pos -= 1;
508
+ return null;
509
+ }
510
+ return result;
511
+ }
512
+ function handleCommaToken(params) {
513
+ const { token, tokens, state, opts, result } = params;
514
+ const nextToken = tokens[state.pos];
515
+ if (state.tolerant && nextToken && nextToken.type === opts.endSymbol) {
516
+ raiseError(state, token, `Trailing comma before '${opts.endSymbol}'`);
517
+ popToken(tokens, state);
518
+ return result;
519
+ }
520
+ opts.elementParser(tokens, state, result);
521
+ return null;
522
+ }
523
+ function parseManyInitialElement(tokens, state, result, opts) {
524
+ const token = skipPunctuation(tokens, state, opts.skip);
525
+ if (token.type === "eof") {
526
+ raiseUnexpected(state, token, `'${opts.endSymbol}' or ${opts.elementName}`);
527
+ return result;
528
+ }
529
+ if (token.type === opts.endSymbol) {
530
+ return result;
531
+ }
532
+ state.pos -= 1;
533
+ opts.elementParser(tokens, state, result);
534
+ return;
535
+ }
536
+ function parseManyProcessToken(params) {
537
+ const { token, tokens, state, opts, result } = params;
538
+ if (token.type !== opts.endSymbol && token.type !== ",") {
539
+ const handledResult = handleInvalidToken(token, state, opts, result);
540
+ if (handledResult !== null) {
541
+ return handledResult;
542
+ }
543
+ }
544
+ if (token.type === opts.endSymbol) {
545
+ return result;
546
+ }
547
+ if (token.type === ",") {
548
+ const handledResult = handleCommaToken({
549
+ token,
550
+ tokens,
551
+ state,
552
+ opts,
553
+ result
554
+ });
555
+ if (handledResult !== null) {
556
+ return handledResult;
557
+ }
558
+ return;
559
+ }
560
+ opts.elementParser(tokens, state, result);
561
+ return;
562
+ }
563
+ function parseMany(tokens, state, result, opts) {
564
+ const initialResult = parseManyInitialElement(tokens, state, result, opts);
565
+ if (initialResult !== void 0) {
566
+ return initialResult;
567
+ }
568
+ while (true) {
569
+ const token = popToken(tokens, state);
570
+ const processedResult = parseManyProcessToken({
571
+ token,
572
+ tokens,
573
+ state,
574
+ opts,
575
+ result
576
+ });
577
+ if (processedResult !== void 0) {
578
+ return processedResult;
579
+ }
580
+ }
581
+ }
582
+ function endChecks(tokens, state, ret) {
583
+ if (state.pos < tokens.length) {
584
+ if (state.tolerant) {
585
+ skipPunctuation(tokens, state);
586
+ }
587
+ if (state.pos < tokens.length) {
588
+ raiseError(
589
+ state,
590
+ tokens[state.pos],
591
+ `Unexpected token: ${strToken(tokens[state.pos])}, expected end-of-input`
592
+ );
593
+ }
594
+ }
595
+ if (state.tolerant && state.warnings.length > 0) {
596
+ const message = state.warnings.length === 1 ? state.warnings[0].message : `${state.warnings.length} parse warnings`;
597
+ const err = new SyntaxError(message);
598
+ err.line = state.warnings[0].line;
599
+ err.warnings = state.warnings;
600
+ err.obj = ret;
601
+ throw err;
602
+ }
603
+ }
604
+ function parseAny(tokens, state, end = false) {
605
+ const token = skipPunctuation(tokens, state);
606
+ let ret;
607
+ if (token.type === "eof") {
608
+ if (end) {
609
+ raiseUnexpected(state, token, "json value");
610
+ }
611
+ raiseUnexpected(state, token, "json value");
612
+ return;
613
+ }
614
+ switch (token.type) {
615
+ case "{":
616
+ ret = parseObject(tokens, state);
617
+ break;
618
+ case "[":
619
+ ret = parseArray(tokens, state);
620
+ break;
621
+ case "string":
622
+ // String literal
623
+ case "number":
624
+ // Number literal
625
+ case "atom":
626
+ ret = token.value;
627
+ break;
628
+ default:
629
+ raiseUnexpected(state, token, "json value");
630
+ if (state.tolerant) {
631
+ ret = null;
632
+ } else {
633
+ return;
634
+ }
635
+ }
636
+ if (end) {
637
+ ret = state.reviver ? state.reviver("", ret) : ret;
638
+ endChecks(tokens, state, ret);
639
+ }
640
+ return ret;
641
+ }
642
+ function normalizeParseOptions(optsOrReviver) {
643
+ var _a;
644
+ let options = {};
645
+ if (typeof optsOrReviver === "function") {
646
+ options.reviver = optsOrReviver;
647
+ } else if (optsOrReviver !== null && typeof optsOrReviver === "object") {
648
+ options = { ...optsOrReviver };
649
+ } else if (optsOrReviver !== void 0) {
650
+ throw new TypeError(
651
+ "Second argument must be a reviver function or an options object."
652
+ );
653
+ }
654
+ if (options.relaxed === void 0) {
655
+ if (options.warnings === true || options.tolerant === true) {
656
+ options.relaxed = true;
657
+ } else if (options.warnings === false && options.tolerant === false) {
658
+ options.relaxed = false;
659
+ } else {
660
+ options.relaxed = true;
661
+ }
662
+ }
663
+ options.tolerant = options.tolerant || options.warnings;
664
+ options.duplicate = (_a = options.duplicate) != null ? _a : false;
665
+ return options;
666
+ }
667
+ function createParseState(options) {
668
+ var _a, _b;
669
+ return {
670
+ pos: 0,
671
+ reviver: options.reviver,
672
+ tolerant: (_a = options.tolerant) != null ? _a : false,
673
+ duplicate: (_b = options.duplicate) != null ? _b : false,
674
+ warnings: []
675
+ };
676
+ }
677
+ function parseWithCustomParser(text, options) {
678
+ const lexerToUse = options.relaxed ? lexer : strictLexer;
679
+ let tokens = lexerToUse(text);
680
+ if (options.relaxed) {
681
+ tokens = stripTrailingComma(tokens);
682
+ }
683
+ tokens = tokens.filter((token) => token.type !== " ");
684
+ const state = createParseState(options);
685
+ return parseAny(tokens, state, true);
686
+ }
687
+ function parseWithTransform(text, options) {
688
+ let tokens = lexer(text);
689
+ tokens = stripTrailingComma(tokens);
690
+ const newtext = tokens.reduce((str, token) => str + token.match, "");
691
+ return JSON.parse(
692
+ newtext,
693
+ options.reviver
694
+ );
695
+ }
696
+ function parse(text, optsOrReviver) {
697
+ const options = normalizeParseOptions(optsOrReviver);
698
+ if (!(options.relaxed || options.warnings || options.tolerant) && options.duplicate) {
699
+ return JSON.parse(
700
+ text,
701
+ options.reviver
702
+ );
703
+ }
704
+ if (options.warnings || options.tolerant || !options.duplicate) {
705
+ return parseWithCustomParser(text, options);
706
+ }
707
+ return parseWithTransform(text, options);
708
+ }
709
+ function stringifyPair(obj, key) {
710
+ return `${JSON.stringify(key)}:${stringify(obj[key])}`;
711
+ }
712
+ function stringify(obj) {
713
+ const type = typeof obj;
714
+ if (type === "string" || type === "number" || type === "boolean" || obj === null) {
715
+ return JSON.stringify(obj);
716
+ }
717
+ if (type === "undefined") {
718
+ return "null";
719
+ }
720
+ if (Array.isArray(obj)) {
721
+ const elements = obj.map(stringify).join(",");
722
+ return `[${elements}]`;
723
+ }
724
+ if (type === "object") {
725
+ const keys = Object.keys(obj);
726
+ keys.sort();
727
+ const pairs = keys.map((key) => stringifyPair(obj, key)).join(",");
728
+ return `{${pairs}}`;
729
+ }
730
+ return "null";
731
+ }
69
732
 
70
733
  // src/core/utils/debug.ts
71
734
  var LINE_SPLIT_REGEX = /\r?\n/;
@@ -254,7 +917,7 @@ function escapeRegExp(literal) {
254
917
  function processToolCallJson(toolCallJson, fullMatch, processedElements, options) {
255
918
  var _a, _b;
256
919
  try {
257
- const parsedToolCall = (0, import_rjson.parse)(toolCallJson);
920
+ const parsedToolCall = parse(toolCallJson);
258
921
  processedElements.push({
259
922
  type: "tool-call",
260
923
  toolCallId: generateId(),
@@ -324,260 +987,2847 @@ function closeTextBlock(state, controller) {
324
987
  state.hasEmittedTextStart = false;
325
988
  }
326
989
  }
327
- function emitIncompleteToolCall(state, controller, toolCallStart) {
328
- if (!state.currentToolCallJson) {
329
- return;
990
+ function emitIncompleteToolCall(state, controller, toolCallStart) {
991
+ if (!state.currentToolCallJson) {
992
+ return;
993
+ }
994
+ logParseFailure({
995
+ phase: "stream",
996
+ reason: "Incomplete streaming tool call segment emitted as text",
997
+ snippet: `${toolCallStart}${state.currentToolCallJson}`
998
+ });
999
+ const errorId = generateId();
1000
+ const errorContent = `${toolCallStart}${state.currentToolCallJson}`;
1001
+ controller.enqueue({
1002
+ type: "text-start",
1003
+ id: errorId
1004
+ });
1005
+ controller.enqueue({
1006
+ type: "text-delta",
1007
+ id: errorId,
1008
+ delta: errorContent
1009
+ });
1010
+ controller.enqueue({
1011
+ type: "text-end",
1012
+ id: errorId
1013
+ });
1014
+ state.currentToolCallJson = "";
1015
+ }
1016
+ function handleFinishChunk(state, controller, toolCallStart, chunk) {
1017
+ if (state.buffer.length > 0) {
1018
+ flushBuffer(state, controller, toolCallStart);
1019
+ }
1020
+ closeTextBlock(state, controller);
1021
+ emitIncompleteToolCall(state, controller, toolCallStart);
1022
+ controller.enqueue(chunk);
1023
+ }
1024
+ function publishText(text, state, controller) {
1025
+ if (state.isInsideToolCall) {
1026
+ closeTextBlock(state, controller);
1027
+ state.currentToolCallJson += text;
1028
+ } else if (text.length > 0) {
1029
+ if (!state.currentTextId) {
1030
+ state.currentTextId = generateId();
1031
+ controller.enqueue({
1032
+ type: "text-start",
1033
+ id: state.currentTextId
1034
+ });
1035
+ state.hasEmittedTextStart = true;
1036
+ }
1037
+ controller.enqueue({
1038
+ type: "text-delta",
1039
+ id: state.currentTextId,
1040
+ delta: text
1041
+ });
1042
+ }
1043
+ }
1044
+ function emitToolCall(context) {
1045
+ var _a, _b;
1046
+ const { state, controller, toolCallStart, toolCallEnd, options } = context;
1047
+ try {
1048
+ const parsedToolCall = parse(state.currentToolCallJson);
1049
+ closeTextBlock(state, controller);
1050
+ controller.enqueue({
1051
+ type: "tool-call",
1052
+ toolCallId: generateId(),
1053
+ toolName: parsedToolCall.name,
1054
+ input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
1055
+ });
1056
+ } catch (error) {
1057
+ logParseFailure({
1058
+ phase: "stream",
1059
+ reason: "Failed to parse streaming tool call JSON segment",
1060
+ snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
1061
+ error
1062
+ });
1063
+ const errorId = generateId();
1064
+ const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
1065
+ controller.enqueue({
1066
+ type: "text-start",
1067
+ id: errorId
1068
+ });
1069
+ controller.enqueue({
1070
+ type: "text-delta",
1071
+ id: errorId,
1072
+ delta: errorContent
1073
+ });
1074
+ controller.enqueue({
1075
+ type: "text-end",
1076
+ id: errorId
1077
+ });
1078
+ (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
1079
+ options,
1080
+ "Could not process streaming JSON tool call; emitting original text.",
1081
+ {
1082
+ toolCall: errorContent
1083
+ }
1084
+ );
1085
+ }
1086
+ }
1087
+ function processTagMatch(context) {
1088
+ const { state } = context;
1089
+ if (state.isInsideToolCall) {
1090
+ emitToolCall(context);
1091
+ state.currentToolCallJson = "";
1092
+ state.isInsideToolCall = false;
1093
+ } else {
1094
+ state.currentToolCallJson = "";
1095
+ state.isInsideToolCall = true;
1096
+ }
1097
+ }
1098
+ function processBufferTags(context) {
1099
+ const { state, controller, toolCallStart, toolCallEnd } = context;
1100
+ let startIndex = getPotentialStartIndex(
1101
+ state.buffer,
1102
+ state.isInsideToolCall ? toolCallEnd : toolCallStart
1103
+ );
1104
+ while (startIndex != null) {
1105
+ const tag = state.isInsideToolCall ? toolCallEnd : toolCallStart;
1106
+ if (startIndex + tag.length > state.buffer.length) {
1107
+ break;
1108
+ }
1109
+ publishText(state.buffer.slice(0, startIndex), state, controller);
1110
+ state.buffer = state.buffer.slice(startIndex + tag.length);
1111
+ processTagMatch(context);
1112
+ startIndex = getPotentialStartIndex(
1113
+ state.buffer,
1114
+ state.isInsideToolCall ? toolCallEnd : toolCallStart
1115
+ );
1116
+ }
1117
+ }
1118
+ function handlePartialTag(state, controller, toolCallStart) {
1119
+ if (state.isInsideToolCall) {
1120
+ return;
1121
+ }
1122
+ const potentialIndex = getPotentialStartIndex(state.buffer, toolCallStart);
1123
+ if (potentialIndex != null && potentialIndex + toolCallStart.length > state.buffer.length) {
1124
+ publishText(state.buffer.slice(0, potentialIndex), state, controller);
1125
+ state.buffer = state.buffer.slice(potentialIndex);
1126
+ } else {
1127
+ publishText(state.buffer, state, controller);
1128
+ state.buffer = "";
1129
+ }
1130
+ }
1131
+ var jsonProtocol = ({
1132
+ toolCallStart = "<tool_call>",
1133
+ toolCallEnd = "</tool_call>"
1134
+ } = {}) => ({
1135
+ formatTools({
1136
+ tools,
1137
+ toolSystemPromptTemplate
1138
+ }) {
1139
+ return toolSystemPromptTemplate(tools || []);
1140
+ },
1141
+ formatToolCall(toolCall) {
1142
+ let args = {};
1143
+ if (toolCall.input != null) {
1144
+ try {
1145
+ args = JSON.parse(toolCall.input);
1146
+ } catch (e) {
1147
+ args = toolCall.input;
1148
+ }
1149
+ }
1150
+ return `${toolCallStart}${JSON.stringify({
1151
+ name: toolCall.toolName,
1152
+ arguments: args
1153
+ })}${toolCallEnd}`;
1154
+ },
1155
+ parseGeneratedText({
1156
+ text,
1157
+ options
1158
+ }) {
1159
+ const startEsc = escapeRegExp(toolCallStart);
1160
+ const endEsc = escapeRegExp(toolCallEnd);
1161
+ const toolCallRegex = new RegExp(
1162
+ `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
1163
+ "gs"
1164
+ );
1165
+ const processedElements = [];
1166
+ let currentIndex = 0;
1167
+ let match = toolCallRegex.exec(text);
1168
+ while (match !== null) {
1169
+ currentIndex = processMatchedToolCall({
1170
+ match,
1171
+ text,
1172
+ currentIndex,
1173
+ processedElements,
1174
+ options
1175
+ });
1176
+ match = toolCallRegex.exec(text);
1177
+ }
1178
+ if (currentIndex < text.length) {
1179
+ const remainingText = text.substring(currentIndex);
1180
+ addTextSegment(remainingText, processedElements);
1181
+ }
1182
+ return processedElements;
1183
+ },
1184
+ createStreamParser({
1185
+ options
1186
+ }) {
1187
+ const state = {
1188
+ isInsideToolCall: false,
1189
+ buffer: "",
1190
+ currentToolCallJson: "",
1191
+ currentTextId: null,
1192
+ hasEmittedTextStart: false
1193
+ };
1194
+ return new TransformStream({
1195
+ transform(chunk, controller) {
1196
+ var _a;
1197
+ if (chunk.type === "finish") {
1198
+ handleFinishChunk(state, controller, toolCallStart, chunk);
1199
+ return;
1200
+ }
1201
+ if (chunk.type !== "text-delta") {
1202
+ controller.enqueue(chunk);
1203
+ return;
1204
+ }
1205
+ const textContent = (_a = chunk.delta) != null ? _a : "";
1206
+ state.buffer += textContent;
1207
+ processBufferTags({
1208
+ state,
1209
+ controller,
1210
+ toolCallStart,
1211
+ toolCallEnd,
1212
+ options
1213
+ });
1214
+ handlePartialTag(state, controller, toolCallStart);
1215
+ }
1216
+ });
1217
+ },
1218
+ extractToolCallSegments({ text }) {
1219
+ const startEsc = escapeRegExp(toolCallStart);
1220
+ const endEsc = escapeRegExp(toolCallEnd);
1221
+ const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
1222
+ const segments = [];
1223
+ let m = regex.exec(text);
1224
+ while (m != null) {
1225
+ segments.push(m[0]);
1226
+ m = regex.exec(text);
1227
+ }
1228
+ return segments;
1229
+ }
1230
+ });
1231
+
1232
+ // src/core/protocols/protocol-interface.ts
1233
+ function isProtocolFactory(protocol) {
1234
+ return typeof protocol === "function";
1235
+ }
1236
+ function isTCMProtocolFactory(protocol) {
1237
+ return typeof protocol === "function";
1238
+ }
1239
+
1240
+ // src/rxml/errors/types.ts
1241
+ var RXMLParseError = class extends Error {
1242
+ constructor(message, cause, line, column) {
1243
+ super(message);
1244
+ this.name = "RXMLParseError";
1245
+ this.cause = cause;
1246
+ this.line = line;
1247
+ this.column = column;
1248
+ }
1249
+ };
1250
+ var RXMLDuplicateStringTagError = class extends Error {
1251
+ constructor(message) {
1252
+ super(message);
1253
+ this.name = "RXMLDuplicateStringTagError";
1254
+ }
1255
+ };
1256
+ var RXMLCoercionError = class extends Error {
1257
+ constructor(message, cause) {
1258
+ super(message);
1259
+ this.name = "RXMLCoercionError";
1260
+ this.cause = cause;
1261
+ }
1262
+ };
1263
+ var RXMLStringifyError = class extends Error {
1264
+ constructor(message, cause) {
1265
+ super(message);
1266
+ this.name = "RXMLStringifyError";
1267
+ this.cause = cause;
1268
+ }
1269
+ };
1270
+
1271
+ // src/rxml/core/types.ts
1272
+ var CharCodes = {
1273
+ OPEN_BRACKET: "<".charCodeAt(0),
1274
+ CLOSE_BRACKET: ">".charCodeAt(0),
1275
+ MINUS: "-".charCodeAt(0),
1276
+ SLASH: "/".charCodeAt(0),
1277
+ EXCLAMATION: "!".charCodeAt(0),
1278
+ QUESTION: "?".charCodeAt(0),
1279
+ SINGLE_QUOTE: "'".charCodeAt(0),
1280
+ DOUBLE_QUOTE: '"'.charCodeAt(0),
1281
+ OPEN_CORNER_BRACKET: "[".charCodeAt(0),
1282
+ CLOSE_CORNER_BRACKET: "]".charCodeAt(0),
1283
+ SPACE: " ".charCodeAt(0),
1284
+ TAB: " ".charCodeAt(0),
1285
+ NEWLINE: "\n".charCodeAt(0),
1286
+ CARRIAGE_RETURN: "\r".charCodeAt(0)
1287
+ };
1288
+ var DEFAULT_NO_CHILD_NODES = [
1289
+ "img",
1290
+ "br",
1291
+ "input",
1292
+ "meta",
1293
+ "link",
1294
+ "hr",
1295
+ "area",
1296
+ "base",
1297
+ "col",
1298
+ "embed",
1299
+ "param",
1300
+ "source",
1301
+ "track",
1302
+ "wbr"
1303
+ ];
1304
+ var NAME_SPACER = "\r\n >/= ";
1305
+
1306
+ // src/rxml/utils/helpers.ts
1307
+ var NAME_START_CHAR_REGEX = /[A-Za-z_:]/;
1308
+ var NAME_CHAR_REGEX = /[A-Za-z0-9_.:-]/;
1309
+ function isNameStartChar(ch) {
1310
+ return NAME_START_CHAR_REGEX.test(ch);
1311
+ }
1312
+ function isNameChar(ch) {
1313
+ return NAME_CHAR_REGEX.test(ch);
1314
+ }
1315
+ function skipQuoted(s, i) {
1316
+ const quote = s[i];
1317
+ let pos = i + 1;
1318
+ while (pos < s.length) {
1319
+ const ch = s[pos];
1320
+ if (ch === "\\") {
1321
+ pos += 2;
1322
+ continue;
1323
+ }
1324
+ if (ch === quote) {
1325
+ return pos + 1;
1326
+ }
1327
+ pos += 1;
1328
+ }
1329
+ return pos;
1330
+ }
1331
+ function parseName(s, pos) {
1332
+ const start = pos;
1333
+ let currentPos = pos;
1334
+ while (NAME_SPACER.indexOf(s[currentPos]) === -1 && s[currentPos]) {
1335
+ currentPos += 1;
1336
+ }
1337
+ return { name: s.slice(start, currentPos), newPos: currentPos };
1338
+ }
1339
+ function parseString(s, pos) {
1340
+ const startChar = s[pos];
1341
+ const startPos = pos + 1;
1342
+ const endPos = s.indexOf(startChar, startPos);
1343
+ if (endPos === -1) {
1344
+ const tagEnd = s.indexOf(">", startPos);
1345
+ if (tagEnd !== -1) {
1346
+ return { value: s.slice(startPos, tagEnd), newPos: tagEnd };
1347
+ }
1348
+ return { value: s.slice(startPos), newPos: s.length };
1349
+ }
1350
+ return { value: s.slice(startPos, endPos), newPos: endPos + 1 };
1351
+ }
1352
+ function getLineColumn(s, pos) {
1353
+ let line = 1;
1354
+ let column = 1;
1355
+ for (let i = 0; i < pos && i < s.length; i += 1) {
1356
+ if (s[i] === "\n") {
1357
+ line += 1;
1358
+ column = 1;
1359
+ } else {
1360
+ column += 1;
1361
+ }
1362
+ }
1363
+ return { line, column };
1364
+ }
1365
+ function escapeXml(text) {
1366
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1367
+ }
1368
+ function escapeXmlMinimalText(text) {
1369
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/]]>/g, "]]&gt;");
1370
+ }
1371
+ function escapeXmlMinimalAttr(value, wrapper = '"') {
1372
+ let escaped = value.replace(/&/g, "&amp;").replace(/</g, "&lt;");
1373
+ if (wrapper === '"') {
1374
+ escaped = escaped.replace(/"/g, "&quot;");
1375
+ } else {
1376
+ escaped = escaped.replace(/'/g, "&apos;");
1377
+ }
1378
+ return escaped;
1379
+ }
1380
+ function unescapeXml(text) {
1381
+ return text.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&apos;/g, "'").replace(/&amp;/g, "&");
1382
+ }
1383
+
1384
+ // src/rxml/builders/stringify.ts
1385
+ function stringify2(rootTag, obj, options = {}) {
1386
+ var _a, _b, _c, _d, _e;
1387
+ try {
1388
+ const format = (_a = options.format) != null ? _a : true;
1389
+ const declaration = (_b = options.declaration) != null ? _b : false;
1390
+ const minimalEscaping = (_c = options.minimalEscaping) != null ? _c : false;
1391
+ const suppressEmptyNode = (_d = options.suppressEmptyNode) != null ? _d : false;
1392
+ const strictBooleanAttributes = (_e = options.strictBooleanAttributes) != null ? _e : false;
1393
+ let result = "";
1394
+ if (declaration) {
1395
+ result += '<?xml version="1.0" encoding="UTF-8"?>\n';
1396
+ }
1397
+ result += stringifyValue(rootTag, obj, {
1398
+ depth: 0,
1399
+ format,
1400
+ suppressEmptyNode,
1401
+ minimalEscaping,
1402
+ strictBooleanAttributes
1403
+ });
1404
+ if (result.endsWith("\n")) {
1405
+ return result.slice(0, -1);
1406
+ }
1407
+ return result;
1408
+ } catch (error) {
1409
+ throw new RXMLStringifyError("Failed to stringify XML", error);
1410
+ }
1411
+ }
1412
+ function escapeContent(content, minimalEscaping) {
1413
+ return minimalEscaping ? escapeXmlMinimalText(content) : escapeXml(content);
1414
+ }
1415
+ function createSelfClosingTag(tagName, indent, newline) {
1416
+ return `${indent}<${tagName}/>${newline}`;
1417
+ }
1418
+ function createTextElement(tagName, content, indent, newline) {
1419
+ return `${indent}<${tagName}>${content}</${tagName}>${newline}`;
1420
+ }
1421
+ function isPrimitive(value) {
1422
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
1423
+ }
1424
+ function stringifyPrimitive(tagName, value, context, format) {
1425
+ const { minimalEscaping, suppressEmptyNode } = context;
1426
+ const content = escapeContent(String(value), minimalEscaping);
1427
+ if (content === "" && suppressEmptyNode) {
1428
+ return "";
1429
+ }
1430
+ return createTextElement(tagName, content, format.indent, format.newline);
1431
+ }
1432
+ function stringifyArray(tagName, value, context) {
1433
+ let result = "";
1434
+ for (const item of value) {
1435
+ result += stringifyValue(tagName, item, context);
1436
+ }
1437
+ return result;
1438
+ }
1439
+ function stringifyValue(tagName, value, context) {
1440
+ const { format, suppressEmptyNode, minimalEscaping } = context;
1441
+ const indent = format ? " ".repeat(context.depth) : "";
1442
+ const newline = format ? "\n" : "";
1443
+ if (value === null || value === void 0) {
1444
+ if (suppressEmptyNode) {
1445
+ return "";
1446
+ }
1447
+ return createSelfClosingTag(tagName, indent, newline);
1448
+ }
1449
+ if (isPrimitive(value)) {
1450
+ return stringifyPrimitive(tagName, value, context, { indent, newline });
1451
+ }
1452
+ if (Array.isArray(value)) {
1453
+ return stringifyArray(tagName, value, context);
1454
+ }
1455
+ if (typeof value === "object") {
1456
+ return stringifyObject(tagName, value, context);
1457
+ }
1458
+ const content = escapeContent(String(value), minimalEscaping);
1459
+ if (content === "" && suppressEmptyNode) {
1460
+ return "";
1461
+ }
1462
+ return createTextElement(tagName, content, indent, newline);
1463
+ }
1464
+ function extractObjectParts(obj) {
1465
+ const attributes = {};
1466
+ const elements = {};
1467
+ let textContent;
1468
+ for (const [key, value] of Object.entries(obj)) {
1469
+ if (key.startsWith("@")) {
1470
+ attributes[key.substring(1)] = value;
1471
+ } else if (key === "#text" || key === "_text") {
1472
+ textContent = String(value);
1473
+ } else if (key === "_attributes") {
1474
+ if (typeof value === "object" && value !== null) {
1475
+ Object.assign(attributes, value);
1476
+ }
1477
+ } else {
1478
+ elements[key] = value;
1479
+ }
1480
+ }
1481
+ return { attributes, elements, textContent };
1482
+ }
1483
+ function formatAttribute(attrName, attrValue, minimalEscaping, strictBooleanAttributes) {
1484
+ if (attrValue === null) {
1485
+ return strictBooleanAttributes ? ` ${attrName}="${attrName}"` : ` ${attrName}`;
1486
+ }
1487
+ const valueStr = String(attrValue);
1488
+ if (valueStr.indexOf('"') === -1) {
1489
+ const escaped2 = minimalEscaping ? escapeXmlMinimalAttr(valueStr, '"') : escapeXml(valueStr);
1490
+ return ` ${attrName}="${escaped2}"`;
1491
+ }
1492
+ const escaped = minimalEscaping ? escapeXmlMinimalAttr(valueStr, "'") : escapeXml(valueStr);
1493
+ return ` ${attrName}='${escaped}'`;
1494
+ }
1495
+ function buildOpeningTag(tagName, attributes, context) {
1496
+ let openTag = `<${tagName}`;
1497
+ const { minimalEscaping, strictBooleanAttributes } = context;
1498
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
1499
+ openTag += formatAttribute(
1500
+ attrName,
1501
+ attrValue,
1502
+ minimalEscaping,
1503
+ strictBooleanAttributes
1504
+ );
1505
+ }
1506
+ return openTag;
1507
+ }
1508
+ function stringifyTextOnlyContent(options) {
1509
+ const { tagName, textContent, openTag, format, minimalEscaping } = options;
1510
+ const content = escapeContent(textContent, minimalEscaping);
1511
+ return `${format.indent}${openTag}${content}</${tagName}>${format.newline}`;
1512
+ }
1513
+ function stringifyComplexContent(tagName, parts, context, options) {
1514
+ const { format, minimalEscaping, depth } = context;
1515
+ const { textContent, elements } = parts;
1516
+ const hasElements = Object.keys(elements).length > 0;
1517
+ let result = `${options.indent}${options.openTag}`;
1518
+ if (textContent) {
1519
+ const content = escapeContent(textContent, minimalEscaping);
1520
+ result += format ? `${options.newline}${options.childIndent}${content}` : content;
1521
+ }
1522
+ if (hasElements) {
1523
+ if (format) {
1524
+ result += options.newline;
1525
+ }
1526
+ for (const [elementName, elementValue] of Object.entries(elements)) {
1527
+ result += stringifyValue(elementName, elementValue, {
1528
+ ...context,
1529
+ depth: depth + 1
1530
+ });
1531
+ }
1532
+ if (format) {
1533
+ result += options.indent;
1534
+ }
1535
+ }
1536
+ result += `</${tagName}>${options.newline}`;
1537
+ return result;
1538
+ }
1539
+ function stringifyObject(tagName, obj, context) {
1540
+ const { depth, format, suppressEmptyNode } = context;
1541
+ const indent = format ? " ".repeat(depth) : "";
1542
+ const newline = format ? "\n" : "";
1543
+ const childIndent = format ? " ".repeat(depth + 1) : "";
1544
+ const parts = extractObjectParts(obj);
1545
+ const openTag = buildOpeningTag(tagName, parts.attributes, context);
1546
+ const hasElements = Object.keys(parts.elements).length > 0;
1547
+ const hasTextContent = parts.textContent !== void 0 && parts.textContent !== "";
1548
+ if (!(hasElements || hasTextContent)) {
1549
+ if (suppressEmptyNode) {
1550
+ return "";
1551
+ }
1552
+ return `${indent}${openTag}/>${newline}`;
1553
+ }
1554
+ const fullOpenTag = `${openTag}>`;
1555
+ if (!hasElements && hasTextContent && parts.textContent) {
1556
+ return stringifyTextOnlyContent({
1557
+ tagName,
1558
+ textContent: parts.textContent,
1559
+ openTag: fullOpenTag,
1560
+ format: { indent, newline },
1561
+ minimalEscaping: context.minimalEscaping
1562
+ });
1563
+ }
1564
+ return stringifyComplexContent(tagName, parts, context, {
1565
+ indent,
1566
+ newline,
1567
+ childIndent,
1568
+ openTag: fullOpenTag
1569
+ });
1570
+ }
1571
+
1572
+ // src/schema-coerce/index.ts
1573
+ var NUMERIC_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
1574
+ var EMPTY_OBJECT_REGEX = /^\{\s*\}$/s;
1575
+ var NEWLINE_SPLIT_REGEX = /\n+/;
1576
+ var COMMA_SPLIT_REGEX = /,\s*/;
1577
+ var DIGIT_KEY_REGEX = /^\d+$/;
1578
+ function unwrapJsonSchema(schema) {
1579
+ if (!schema || typeof schema !== "object") {
1580
+ return schema;
1581
+ }
1582
+ const s = schema;
1583
+ if (s.jsonSchema && typeof s.jsonSchema === "object") {
1584
+ return unwrapJsonSchema(s.jsonSchema);
1585
+ }
1586
+ return schema;
1587
+ }
1588
+ function getSchemaType(schema) {
1589
+ const unwrapped = unwrapJsonSchema(schema);
1590
+ if (!unwrapped || typeof unwrapped !== "object") {
1591
+ return;
1592
+ }
1593
+ const t = unwrapped.type;
1594
+ if (typeof t === "string") {
1595
+ return t;
1596
+ }
1597
+ if (Array.isArray(t)) {
1598
+ const preferred = [
1599
+ "object",
1600
+ "array",
1601
+ "boolean",
1602
+ "number",
1603
+ "integer",
1604
+ "string"
1605
+ ];
1606
+ for (const p of preferred) {
1607
+ if (t.includes(p)) {
1608
+ return p;
1609
+ }
1610
+ }
1611
+ }
1612
+ const s = unwrapped;
1613
+ if (s && typeof s === "object" && (s.properties || s.additionalProperties)) {
1614
+ return "object";
1615
+ }
1616
+ if (s && typeof s === "object" && (s.items || s.prefixItems)) {
1617
+ return "array";
1618
+ }
1619
+ return;
1620
+ }
1621
+ function schemaAllowsPropertyViaCombinators(s, key, depth) {
1622
+ const anyOfValues = s.anyOf;
1623
+ const oneOfValues = s.oneOf;
1624
+ const allOfValues = s.allOf;
1625
+ let hasCombinator = false;
1626
+ let anyOfAllows = true;
1627
+ let oneOfAllows = true;
1628
+ let allOfAllows = true;
1629
+ if (Array.isArray(anyOfValues)) {
1630
+ hasCombinator = true;
1631
+ anyOfAllows = anyOfValues.some(
1632
+ (sub) => schemaHasProperty(sub, key, depth + 1)
1633
+ );
1634
+ }
1635
+ if (Array.isArray(oneOfValues)) {
1636
+ hasCombinator = true;
1637
+ oneOfAllows = oneOfValues.some(
1638
+ (sub) => schemaHasProperty(sub, key, depth + 1)
1639
+ );
1640
+ }
1641
+ if (Array.isArray(allOfValues)) {
1642
+ hasCombinator = true;
1643
+ allOfAllows = allOfValues.every(
1644
+ (sub) => schemaHasProperty(sub, key, depth + 1)
1645
+ );
1646
+ }
1647
+ if (!hasCombinator) {
1648
+ return false;
1649
+ }
1650
+ return anyOfAllows && oneOfAllows && allOfAllows;
1651
+ }
1652
+ function schemaHasPropertyDirectly(s, key) {
1653
+ const props = s.properties;
1654
+ if (props && typeof props === "object" && !Array.isArray(props) && Object.hasOwn(props, key) && props[key] !== false) {
1655
+ return true;
1656
+ }
1657
+ const required = s.required;
1658
+ if (Array.isArray(required) && required.includes(key)) {
1659
+ return true;
1660
+ }
1661
+ const patternSchemas = getPatternSchemasForKey(s.patternProperties, key);
1662
+ return patternSchemas.some((schema) => schema !== false);
1663
+ }
1664
+ function schemaHasPropertyViaAdditional(s) {
1665
+ const additional = s.additionalProperties;
1666
+ if (additional === true || additional && typeof additional === "object" && !Array.isArray(additional)) {
1667
+ return true;
1668
+ }
1669
+ if (Object.hasOwn(s, "additionalProperties")) {
1670
+ return false;
1671
+ }
1672
+ const type = s.type;
1673
+ const isObjectType = type === "object" || Array.isArray(type) && type.includes("object");
1674
+ const hasObjectKeywords = s.properties && typeof s.properties === "object" && !Array.isArray(s.properties) || s.patternProperties && typeof s.patternProperties === "object" && !Array.isArray(s.patternProperties) || Array.isArray(s.required) && s.required.length > 0;
1675
+ return !!(isObjectType || hasObjectKeywords);
1676
+ }
1677
+ function schemaDisallowsPropertyDirectly(s, key) {
1678
+ const props = s.properties;
1679
+ if (props && typeof props === "object" && !Array.isArray(props) && Object.hasOwn(props, key) && props[key] === false) {
1680
+ return true;
1681
+ }
1682
+ const patternSchemas = getPatternSchemasForKey(s.patternProperties, key);
1683
+ return patternSchemas.some((schema) => schema === false);
1684
+ }
1685
+ function schemaHasProperty(schema, key, depth = 0) {
1686
+ if (depth > 5) {
1687
+ return true;
1688
+ }
1689
+ const unwrapped = unwrapJsonSchema(schema);
1690
+ if (schemaIsUnconstrained(unwrapped)) {
1691
+ return true;
1692
+ }
1693
+ if (!unwrapped || typeof unwrapped !== "object") {
1694
+ return false;
1695
+ }
1696
+ const s = unwrapped;
1697
+ if (schemaDisallowsPropertyDirectly(s, key)) {
1698
+ return false;
1699
+ }
1700
+ if (schemaHasPropertyDirectly(s, key)) {
1701
+ return true;
1702
+ }
1703
+ if (schemaHasPropertyViaAdditional(s)) {
1704
+ return true;
1705
+ }
1706
+ return schemaAllowsPropertyViaCombinators(s, key, depth);
1707
+ }
1708
+ function schemaIsUnconstrained(schema) {
1709
+ const unwrapped = unwrapJsonSchema(schema);
1710
+ if (unwrapped == null || unwrapped === true) {
1711
+ return true;
1712
+ }
1713
+ if (typeof unwrapped !== "object" || Array.isArray(unwrapped)) {
1714
+ return false;
1715
+ }
1716
+ return Object.keys(unwrapped).length === 0;
1717
+ }
1718
+ function getPatternSchemasForKey(patternProperties, key) {
1719
+ if (!patternProperties || typeof patternProperties !== "object" || Array.isArray(patternProperties)) {
1720
+ return [];
1721
+ }
1722
+ const schemas = [];
1723
+ for (const [pattern, schema] of Object.entries(
1724
+ patternProperties
1725
+ )) {
1726
+ try {
1727
+ const regex = new RegExp(pattern);
1728
+ if (regex.test(key)) {
1729
+ schemas.push(schema);
1730
+ }
1731
+ } catch (e) {
1732
+ }
1733
+ }
1734
+ return schemas;
1735
+ }
1736
+ function coerceValueForKey(value, key, unwrapped) {
1737
+ const schemas = [];
1738
+ const props = unwrapped.properties;
1739
+ if (props && Object.hasOwn(props, key)) {
1740
+ schemas.push(props[key]);
1741
+ }
1742
+ const patternSchemas = getPatternSchemasForKey(
1743
+ unwrapped.patternProperties,
1744
+ key
1745
+ );
1746
+ if (patternSchemas.length > 0) {
1747
+ schemas.push(...patternSchemas);
1748
+ }
1749
+ if (schemas.length > 0) {
1750
+ let out = value;
1751
+ for (const schema of schemas) {
1752
+ if (typeof schema === "boolean") {
1753
+ continue;
1754
+ }
1755
+ out = coerceBySchema(out, schema);
1756
+ }
1757
+ return out;
1758
+ }
1759
+ const additional = unwrapped.additionalProperties;
1760
+ if (additional && typeof additional === "object" && !Array.isArray(additional)) {
1761
+ return coerceBySchema(value, additional);
1762
+ }
1763
+ if (additional === true || additional === false) {
1764
+ return value;
1765
+ }
1766
+ return coerceBySchema(value, void 0);
1767
+ }
1768
+ function coerceStringWithoutSchema(value) {
1769
+ const s = value.trim();
1770
+ const lower = s.toLowerCase();
1771
+ if (lower === "true") {
1772
+ return true;
1773
+ }
1774
+ if (lower === "false") {
1775
+ return false;
1776
+ }
1777
+ if (NUMERIC_REGEX.test(s)) {
1778
+ const num = Number(s);
1779
+ if (Number.isFinite(num)) {
1780
+ return num;
1781
+ }
1782
+ }
1783
+ if (s.startsWith("{") && s.endsWith("}") || s.startsWith("[") && s.endsWith("]")) {
1784
+ try {
1785
+ const parsed = JSON.parse(s);
1786
+ return coerceBySchema(parsed, void 0);
1787
+ } catch (e) {
1788
+ }
1789
+ }
1790
+ return value;
1791
+ }
1792
+ function coerceStringToObject(s, unwrapped) {
1793
+ try {
1794
+ let normalized = s.replace(/'/g, '"');
1795
+ normalized = normalized.replace(EMPTY_OBJECT_REGEX, "{}");
1796
+ const obj = JSON.parse(normalized);
1797
+ if (obj && typeof obj === "object" && !Array.isArray(obj)) {
1798
+ return coerceObjectToObject(obj, unwrapped);
1799
+ }
1800
+ } catch (e) {
1801
+ }
1802
+ return null;
1803
+ }
1804
+ function coerceStringToArray(s, unwrapped) {
1805
+ const prefixItems = Array.isArray(unwrapped.prefixItems) ? unwrapped.prefixItems : void 0;
1806
+ const itemsSchema = unwrapped.items;
1807
+ try {
1808
+ const normalized = s.replace(/'/g, '"');
1809
+ const arr = JSON.parse(normalized);
1810
+ if (Array.isArray(arr)) {
1811
+ if (prefixItems && arr.length === prefixItems.length) {
1812
+ return arr.map((v, i) => coerceBySchema(v, prefixItems[i]));
1813
+ }
1814
+ return arr.map((v) => coerceBySchema(v, itemsSchema));
1815
+ }
1816
+ } catch (e) {
1817
+ const csv = s.includes("\n") ? s.split(NEWLINE_SPLIT_REGEX) : s.split(COMMA_SPLIT_REGEX);
1818
+ const trimmed = csv.map((x) => x.trim()).filter((x) => x.length > 0);
1819
+ if (prefixItems && trimmed.length === prefixItems.length) {
1820
+ return trimmed.map((x, i) => coerceBySchema(x, prefixItems[i]));
1821
+ }
1822
+ return trimmed.map((x) => coerceBySchema(x, itemsSchema));
1823
+ }
1824
+ return null;
1825
+ }
1826
+ function coerceObjectToObject(value, unwrapped) {
1827
+ const out = {};
1828
+ for (const [k, v] of Object.entries(value)) {
1829
+ out[k] = coerceValueForKey(v, k, unwrapped);
1830
+ }
1831
+ return out;
1832
+ }
1833
+ function coerceArrayToArray(value, prefixItems, itemsSchema) {
1834
+ if (prefixItems && value.length === prefixItems.length) {
1835
+ return value.map((v, i) => coerceBySchema(v, prefixItems[i]));
1836
+ }
1837
+ return value.map((v) => coerceBySchema(v, itemsSchema));
1838
+ }
1839
+ function coerceObjectToArray(maybe, prefixItems, itemsSchema) {
1840
+ if (Object.hasOwn(maybe, "item")) {
1841
+ const items = maybe.item;
1842
+ const arr = Array.isArray(items) ? items : [items];
1843
+ return coerceArrayToArray(arr, prefixItems, itemsSchema);
1844
+ }
1845
+ const keys = Object.keys(maybe);
1846
+ if (keys.length > 0 && keys.every((k) => DIGIT_KEY_REGEX.test(k))) {
1847
+ const arr = keys.sort((a, b) => Number(a) - Number(b)).map((k) => maybe[k]);
1848
+ return coerceArrayToArray(arr, prefixItems, itemsSchema);
1849
+ }
1850
+ if (keys.length === 1) {
1851
+ const singleKey = keys[0];
1852
+ if (!(schemaIsUnconstrained(itemsSchema) || schemaHasProperty(itemsSchema, singleKey))) {
1853
+ const singleValue = maybe[singleKey];
1854
+ if (Array.isArray(singleValue)) {
1855
+ return singleValue.map((v) => coerceBySchema(v, itemsSchema));
1856
+ }
1857
+ if (singleValue && typeof singleValue === "object") {
1858
+ return [coerceBySchema(singleValue, itemsSchema)];
1859
+ }
1860
+ }
1861
+ }
1862
+ return null;
1863
+ }
1864
+ function coercePrimitiveToArray(value, prefixItems, itemsSchema) {
1865
+ if (prefixItems && prefixItems.length > 0) {
1866
+ return [coerceBySchema(value, prefixItems[0])];
1867
+ }
1868
+ return [coerceBySchema(value, itemsSchema)];
1869
+ }
1870
+ function coerceStringToPrimitive(s, schemaType) {
1871
+ if (schemaType === "boolean") {
1872
+ const lower = s.toLowerCase();
1873
+ if (lower === "true") {
1874
+ return true;
1875
+ }
1876
+ if (lower === "false") {
1877
+ return false;
1878
+ }
1879
+ }
1880
+ if ((schemaType === "number" || schemaType === "integer") && NUMERIC_REGEX.test(s)) {
1881
+ const num = Number(s);
1882
+ if (Number.isFinite(num)) {
1883
+ return num;
1884
+ }
1885
+ }
1886
+ return null;
1887
+ }
1888
+ function coerceStringValue(value, schemaType, u) {
1889
+ const s = value.trim();
1890
+ if (schemaType === "object") {
1891
+ const result = coerceStringToObject(s, u);
1892
+ if (result !== null) {
1893
+ return result;
1894
+ }
1895
+ }
1896
+ if (schemaType === "array") {
1897
+ const result = coerceStringToArray(s, u);
1898
+ if (result !== null) {
1899
+ return result;
1900
+ }
1901
+ }
1902
+ const primitiveResult = coerceStringToPrimitive(s, schemaType);
1903
+ if (primitiveResult !== null) {
1904
+ return primitiveResult;
1905
+ }
1906
+ return value;
1907
+ }
1908
+ function coerceArrayValue(value, prefixItems, itemsSchema) {
1909
+ if (Array.isArray(value)) {
1910
+ return coerceArrayToArray(value, prefixItems, itemsSchema);
1911
+ }
1912
+ if (value && typeof value === "object") {
1913
+ const result = coerceObjectToArray(
1914
+ value,
1915
+ prefixItems,
1916
+ itemsSchema
1917
+ );
1918
+ if (result !== null) {
1919
+ return result;
1920
+ }
1921
+ if (getSchemaType(itemsSchema) === "array") {
1922
+ return [value];
1923
+ }
1924
+ return [coerceBySchema(value, itemsSchema)];
1925
+ }
1926
+ if (value == null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1927
+ return coercePrimitiveToArray(value, prefixItems, itemsSchema);
1928
+ }
1929
+ return [value];
1930
+ }
1931
+ function coerceBySchema(value, schema) {
1932
+ const unwrapped = unwrapJsonSchema(schema);
1933
+ if (!unwrapped || typeof unwrapped !== "object") {
1934
+ if (typeof value === "string") {
1935
+ return coerceStringWithoutSchema(value);
1936
+ }
1937
+ return value;
1938
+ }
1939
+ const schemaType = getSchemaType(unwrapped);
1940
+ const u = unwrapped;
1941
+ if (typeof value === "string") {
1942
+ return coerceStringValue(value, schemaType, u);
1943
+ }
1944
+ if (schemaType === "object" && value && typeof value === "object" && !Array.isArray(value)) {
1945
+ return coerceObjectToObject(value, u);
1946
+ }
1947
+ if (schemaType === "array") {
1948
+ const prefixItems = Array.isArray(u.prefixItems) ? u.prefixItems : void 0;
1949
+ const itemsSchema = u.items;
1950
+ return coerceArrayValue(value, prefixItems, itemsSchema);
1951
+ }
1952
+ return value;
1953
+ }
1954
+
1955
+ // src/rxml/schema/coercion.ts
1956
+ function getPropertySchema(toolSchema, key) {
1957
+ const unwrapped = unwrapJsonSchema(toolSchema);
1958
+ if (!unwrapped || typeof unwrapped !== "object") {
1959
+ return;
1960
+ }
1961
+ const u = unwrapped;
1962
+ const props = u.properties;
1963
+ if (props && Object.hasOwn(props, key)) {
1964
+ return props[key];
1965
+ }
1966
+ return;
1967
+ }
1968
+ function getNodeValue(children, schema, tagName, textNodeName) {
1969
+ if (children.length === 0) {
1970
+ return "";
1971
+ }
1972
+ if (children.length === 1 && typeof children[0] === "string") {
1973
+ return children[0];
1974
+ }
1975
+ return processComplexContent(
1976
+ children,
1977
+ getPropertySchema(schema, tagName),
1978
+ textNodeName
1979
+ );
1980
+ }
1981
+ function addAttributesToValue(value, attributes, textNodeName) {
1982
+ if (Object.keys(attributes).length === 0) {
1983
+ return value;
1984
+ }
1985
+ if (typeof value === "string") {
1986
+ const valueResult = { [textNodeName]: value };
1987
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
1988
+ valueResult[`@_${attrName}`] = attrValue;
1989
+ }
1990
+ return valueResult;
1991
+ }
1992
+ if (value && typeof value === "object" && !Array.isArray(value)) {
1993
+ for (const [attrName, attrValue] of Object.entries(attributes)) {
1994
+ value[`@_${attrName}`] = attrValue;
1995
+ }
1996
+ }
1997
+ return value;
1998
+ }
1999
+ function addToResult(result, tagName, value) {
2000
+ if (result[tagName]) {
2001
+ if (!Array.isArray(result[tagName])) {
2002
+ result[tagName] = [result[tagName]];
2003
+ }
2004
+ result[tagName].push(value);
2005
+ } else {
2006
+ result[tagName] = value;
2007
+ }
2008
+ }
2009
+ function domToObject(nodes, schema, textNodeName = "#text") {
2010
+ const result = {};
2011
+ for (const node of nodes) {
2012
+ if (typeof node === "string") {
2013
+ continue;
2014
+ }
2015
+ const { tagName, children, attributes } = node;
2016
+ let value = getNodeValue(children, schema, tagName, textNodeName);
2017
+ value = addAttributesToValue(value, attributes, textNodeName);
2018
+ addToResult(result, tagName, value);
2019
+ }
2020
+ return result;
2021
+ }
2022
+ function processChildElement(child, schema, textNodeName) {
2023
+ let childValue;
2024
+ if (child.children.length === 0) {
2025
+ childValue = "";
2026
+ } else if (child.children.length === 1 && typeof child.children[0] === "string") {
2027
+ childValue = child.children[0];
2028
+ } else {
2029
+ childValue = processComplexContent(
2030
+ child.children,
2031
+ getPropertySchema(schema, child.tagName),
2032
+ textNodeName
2033
+ );
2034
+ }
2035
+ return addAttributesToValue(childValue, child.attributes, textNodeName);
2036
+ }
2037
+ function combineContent(textContent, elements, textNodeName) {
2038
+ const hasText = textContent.length > 0;
2039
+ const hasElements = Object.keys(elements).length > 0;
2040
+ if (hasText && hasElements) {
2041
+ return {
2042
+ [textNodeName]: textContent.join("").trim(),
2043
+ ...elements
2044
+ };
2045
+ }
2046
+ if (hasText) {
2047
+ return textContent.join("").trim();
2048
+ }
2049
+ if (hasElements) {
2050
+ return elements;
2051
+ }
2052
+ return "";
2053
+ }
2054
+ function processComplexContent(children, schema, textNodeName) {
2055
+ const textContent = [];
2056
+ const elements = {};
2057
+ for (const child of children) {
2058
+ if (typeof child === "string") {
2059
+ textContent.push(child);
2060
+ } else {
2061
+ const childValue = processChildElement(child, schema, textNodeName);
2062
+ addToResult(elements, child.tagName, childValue);
2063
+ }
2064
+ }
2065
+ return combineContent(textContent, elements, textNodeName);
2066
+ }
2067
+ function coerceDomBySchema(domObject, schema) {
2068
+ try {
2069
+ return coerceBySchema(domObject, schema);
2070
+ } catch (error) {
2071
+ throw new RXMLCoercionError("Failed to coerce DOM object by schema", error);
2072
+ }
2073
+ }
2074
+ function visitObjectProperties(props, collected, visit) {
2075
+ for (const [key, propSchema] of Object.entries(props)) {
2076
+ const t = getSchemaType(propSchema);
2077
+ if (t === "string") {
2078
+ collected.add(key);
2079
+ } else if (t === "object" || t === "array") {
2080
+ visit(propSchema);
2081
+ }
2082
+ }
2083
+ }
2084
+ function visitArrayItems(u, visit) {
2085
+ const items = u.items;
2086
+ if (items) {
2087
+ visit(items);
2088
+ }
2089
+ const prefix = u.prefixItems;
2090
+ if (Array.isArray(prefix)) {
2091
+ for (const item of prefix) {
2092
+ visit(item);
2093
+ }
2094
+ }
2095
+ }
2096
+ function getStringTypedProperties(schema) {
2097
+ const collected = /* @__PURE__ */ new Set();
2098
+ const visit = (s) => {
2099
+ const unwrapped = unwrapJsonSchema(s);
2100
+ if (!unwrapped || typeof unwrapped !== "object") {
2101
+ return;
2102
+ }
2103
+ const u = unwrapped;
2104
+ const type = getSchemaType(unwrapped);
2105
+ if (type === "object") {
2106
+ const props = u.properties;
2107
+ if (props && typeof props === "object") {
2108
+ visitObjectProperties(props, collected, visit);
2109
+ }
2110
+ } else if (type === "array") {
2111
+ visitArrayItems(u, visit);
2112
+ }
2113
+ };
2114
+ visit(schema);
2115
+ return collected;
2116
+ }
2117
+ function processArrayContent(value, schema, textNodeName) {
2118
+ if (!Array.isArray(value)) {
2119
+ return value;
2120
+ }
2121
+ const schemaType = getSchemaType(schema);
2122
+ if (schemaType === "string") {
2123
+ return value.map((item) => {
2124
+ if (typeof item === "string") {
2125
+ return item.trim();
2126
+ }
2127
+ if (item && typeof item === "object" && textNodeName in item) {
2128
+ const textVal = item[textNodeName];
2129
+ return typeof textVal === "string" ? textVal.trim() : String(textVal);
2130
+ }
2131
+ return String(item);
2132
+ });
2133
+ }
2134
+ return value.map((item) => {
2135
+ if (typeof item === "string") {
2136
+ return item.trim();
2137
+ }
2138
+ if (item && typeof item === "object" && textNodeName in item) {
2139
+ const textVal = item[textNodeName];
2140
+ return typeof textVal === "string" ? textVal.trim() : textVal;
2141
+ }
2142
+ return item;
2143
+ });
2144
+ }
2145
+ function processIndexedTuple(obj, textNodeName) {
2146
+ const keys = Object.keys(obj);
2147
+ const indices = keys.map((k) => Number.parseInt(k, 10)).sort((a, b) => a - b);
2148
+ const isValidTuple = indices[0] === 0 && indices.every((val, idx) => val === idx);
2149
+ if (!isValidTuple) {
2150
+ return [obj];
2151
+ }
2152
+ const sortedKeys = keys.sort(
2153
+ (a, b) => Number.parseInt(a, 10) - Number.parseInt(b, 10)
2154
+ );
2155
+ return sortedKeys.map((key) => {
2156
+ const item = obj[key];
2157
+ if (item && typeof item === "object" && textNodeName in item) {
2158
+ const textVal = item[textNodeName];
2159
+ return typeof textVal === "string" ? textVal.trim() : textVal;
2160
+ }
2161
+ return typeof item === "string" ? item.trim() : item;
2162
+ });
2163
+ }
2164
+
2165
+ // src/rxml/schema/extraction.ts
2166
+ function skipDoctype(xmlContent, i, len) {
2167
+ const gt = xmlContent.indexOf(">", i + 1);
2168
+ return gt === -1 ? len : gt + 1;
2169
+ }
2170
+ function skipComment(xmlContent, i, len) {
2171
+ const close = xmlContent.indexOf("-->", i + 4);
2172
+ return close === -1 ? len : close + 3;
2173
+ }
2174
+ function skipCdata(xmlContent, i, len) {
2175
+ const close = xmlContent.indexOf("]]>", i + 9);
2176
+ return close === -1 ? len : close + 3;
2177
+ }
2178
+ function skipProcessingInstruction(xmlContent, i, len) {
2179
+ const close = xmlContent.indexOf("?>", i + 1);
2180
+ return close === -1 ? len : close + 2;
2181
+ }
2182
+ function skipSpecialConstruct(xmlContent, i, len) {
2183
+ const ch = xmlContent[i];
2184
+ if (ch === "!") {
2185
+ if (xmlContent.startsWith("!DOCTYPE", i + 1)) {
2186
+ return skipDoctype(xmlContent, i, len);
2187
+ }
2188
+ if (xmlContent.startsWith("!--", i + 1)) {
2189
+ return skipComment(xmlContent, i, len);
2190
+ }
2191
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
2192
+ return skipCdata(xmlContent, i, len);
2193
+ }
2194
+ const gt = xmlContent.indexOf(">", i + 1);
2195
+ return gt === -1 ? len : gt + 1;
2196
+ }
2197
+ if (ch === "?") {
2198
+ return skipProcessingInstruction(xmlContent, i, len);
2199
+ }
2200
+ return -1;
2201
+ }
2202
+ function parseTagName(xmlContent, i, len) {
2203
+ let j = i;
2204
+ if (j < len && isNameStartChar(xmlContent[j])) {
2205
+ j += 1;
2206
+ while (j < len && isNameChar(xmlContent[j])) {
2207
+ j += 1;
2208
+ }
2209
+ }
2210
+ return { name: xmlContent.slice(i, j), pos: j };
2211
+ }
2212
+ function skipToTagEnd(xmlContent, start, len) {
2213
+ let k = start;
2214
+ let isSelfClosing = false;
2215
+ while (k < len) {
2216
+ const c = xmlContent[k];
2217
+ if (c === '"' || c === "'") {
2218
+ k = skipQuoted(xmlContent, k);
2219
+ continue;
2220
+ }
2221
+ if (c === ">") {
2222
+ break;
2223
+ }
2224
+ if (c === "/" && xmlContent[k + 1] === ">") {
2225
+ isSelfClosing = true;
2226
+ k += 1;
2227
+ break;
2228
+ }
2229
+ k += 1;
2230
+ }
2231
+ return { pos: k, isSelfClosing };
2232
+ }
2233
+ function processClosingTagMatch(options) {
2234
+ const { xmlContent, nx, len, tagName, depth, nextLt } = options;
2235
+ const tagInfo = parseTagName(xmlContent, nx + 1, len);
2236
+ const gt = xmlContent.indexOf(">", tagInfo.pos);
2237
+ if (tagInfo.name === tagName) {
2238
+ const newDepth = depth - 1;
2239
+ if (newDepth === 0) {
2240
+ return { newPos: nextLt, newDepth, found: true };
2241
+ }
2242
+ return { newPos: gt === -1 ? len : gt + 1, newDepth, found: false };
2243
+ }
2244
+ return { newPos: gt === -1 ? len : gt + 1, newDepth: depth, found: false };
2245
+ }
2246
+ function processOpeningTagMatch(options) {
2247
+ const { xmlContent, nx, len, tagName, depth } = options;
2248
+ const tagInfo = parseTagName(xmlContent, nx, len);
2249
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
2250
+ const newDepth = tagInfo.name === tagName && !tagEndInfo.isSelfClosing ? depth + 1 : depth;
2251
+ const newPos = xmlContent[tagEndInfo.pos] === ">" ? tagEndInfo.pos + 1 : tagEndInfo.pos + 1;
2252
+ return { newPos, newDepth };
2253
+ }
2254
+ function findMatchingCloseTag(xmlContent, startPos, tagName, len) {
2255
+ let pos = startPos;
2256
+ let depth = 1;
2257
+ while (pos < len) {
2258
+ const nextLt = xmlContent.indexOf("<", pos);
2259
+ if (nextLt === -1 || nextLt + 1 >= len) {
2260
+ break;
2261
+ }
2262
+ const nx = nextLt + 1;
2263
+ const h = xmlContent[nx];
2264
+ const specialPos = skipSpecialConstruct(xmlContent, nx, len);
2265
+ if (specialPos !== -1) {
2266
+ pos = specialPos;
2267
+ continue;
2268
+ }
2269
+ if (h === "/") {
2270
+ const result = processClosingTagMatch({
2271
+ xmlContent,
2272
+ nx,
2273
+ len,
2274
+ tagName,
2275
+ depth,
2276
+ nextLt
2277
+ });
2278
+ if (result.found) {
2279
+ return result.newPos;
2280
+ }
2281
+ pos = result.newPos;
2282
+ depth = result.newDepth;
2283
+ } else {
2284
+ const result = processOpeningTagMatch({
2285
+ xmlContent,
2286
+ nx,
2287
+ len,
2288
+ tagName,
2289
+ depth
2290
+ });
2291
+ pos = result.newPos;
2292
+ depth = result.newDepth;
2293
+ }
2294
+ }
2295
+ return -1;
2296
+ }
2297
+ function updateBestMatch(depth, bestDepth, contentStart, contentEnd) {
2298
+ if (depth < bestDepth) {
2299
+ return { start: contentStart, end: contentEnd, depth };
2300
+ }
2301
+ return null;
2302
+ }
2303
+ function processTargetTag(options) {
2304
+ const { xmlContent, tagEnd, isSelfClosing, target, len, depth, bestDepth } = options;
2305
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
2306
+ if (isSelfClosing) {
2307
+ return updateBestMatch(depth, bestDepth, contentStart, contentStart);
2308
+ }
2309
+ const closePos = findMatchingCloseTag(xmlContent, contentStart, target, len);
2310
+ if (closePos !== -1) {
2311
+ return updateBestMatch(depth, bestDepth, contentStart, closePos);
2312
+ }
2313
+ return null;
2314
+ }
2315
+ function handleClosingTagInExtract(xmlContent, i, len, depth) {
2316
+ const gt = xmlContent.indexOf(">", i + 1);
2317
+ return {
2318
+ newPos: gt === -1 ? len : gt + 1,
2319
+ newDepth: Math.max(0, depth - 1)
2320
+ };
2321
+ }
2322
+ function processOpeningTagInExtract(options) {
2323
+ const { xmlContent, i, len, target, depth, bestDepth } = options;
2324
+ const tagInfo = parseTagName(xmlContent, i, len);
2325
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
2326
+ const tagEnd = tagEndInfo.pos;
2327
+ const isSelfClosing = tagEndInfo.isSelfClosing;
2328
+ let bestMatch = null;
2329
+ if (tagInfo.name === target) {
2330
+ bestMatch = processTargetTag({
2331
+ xmlContent,
2332
+ tagEnd,
2333
+ isSelfClosing,
2334
+ target,
2335
+ len,
2336
+ depth,
2337
+ bestDepth
2338
+ });
2339
+ }
2340
+ return {
2341
+ newPos: xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1,
2342
+ newDepth: depth + (isSelfClosing ? 0 : 1),
2343
+ bestMatch
2344
+ };
2345
+ }
2346
+ function extractRawInner(xmlContent, tagName) {
2347
+ const len = xmlContent.length;
2348
+ const target = tagName;
2349
+ let bestStart = -1;
2350
+ let bestEnd = -1;
2351
+ let bestDepth = Number.POSITIVE_INFINITY;
2352
+ let i = 0;
2353
+ let depth = 0;
2354
+ while (i < len) {
2355
+ const lt = xmlContent.indexOf("<", i);
2356
+ if (lt === -1 || lt + 1 >= len) {
2357
+ return;
2358
+ }
2359
+ i = lt + 1;
2360
+ const ch = xmlContent[i];
2361
+ const specialPos = skipSpecialConstruct(xmlContent, i, len);
2362
+ if (specialPos !== -1) {
2363
+ i = specialPos;
2364
+ continue;
2365
+ }
2366
+ if (ch === "/") {
2367
+ const result2 = handleClosingTagInExtract(xmlContent, i, len, depth);
2368
+ i = result2.newPos;
2369
+ depth = result2.newDepth;
2370
+ continue;
2371
+ }
2372
+ const result = processOpeningTagInExtract({
2373
+ xmlContent,
2374
+ i,
2375
+ len,
2376
+ target,
2377
+ depth,
2378
+ bestDepth
2379
+ });
2380
+ if (result.bestMatch) {
2381
+ bestStart = result.bestMatch.start;
2382
+ bestEnd = result.bestMatch.end;
2383
+ bestDepth = result.bestMatch.depth;
2384
+ }
2385
+ i = result.newPos;
2386
+ depth = result.newDepth;
2387
+ }
2388
+ if (bestStart !== -1) {
2389
+ return xmlContent.slice(bestStart, bestEnd);
2390
+ }
2391
+ return;
2392
+ }
2393
+ function processOpeningTag(options) {
2394
+ const { xmlContent, tagEnd, isSelfClosing, target, len, ranges } = options;
2395
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
2396
+ if (isSelfClosing) {
2397
+ ranges.push({ start: contentStart, end: contentStart });
2398
+ return contentStart;
2399
+ }
2400
+ const closePos = findMatchingCloseTag(xmlContent, contentStart, target, len);
2401
+ if (closePos !== -1) {
2402
+ ranges.push({ start: contentStart, end: closePos });
2403
+ const gt = xmlContent.indexOf(">", closePos);
2404
+ return gt === -1 ? len : gt + 1;
2405
+ }
2406
+ return -1;
2407
+ }
2408
+ function handleClosingTagInFindAll(xmlContent, i, len) {
2409
+ const gt = xmlContent.indexOf(">", i + 1);
2410
+ return gt === -1 ? len : gt + 1;
2411
+ }
2412
+ function findAllInnerRanges(xmlContent, tagName) {
2413
+ const len = xmlContent.length;
2414
+ const target = tagName;
2415
+ const ranges = [];
2416
+ let i = 0;
2417
+ while (i < len) {
2418
+ const lt = xmlContent.indexOf("<", i);
2419
+ if (lt === -1 || lt + 1 >= len) {
2420
+ break;
2421
+ }
2422
+ i = lt + 1;
2423
+ const ch = xmlContent[i];
2424
+ const specialPos = skipSpecialConstruct(xmlContent, i, len);
2425
+ if (specialPos !== -1) {
2426
+ i = specialPos;
2427
+ continue;
2428
+ }
2429
+ if (ch === "/") {
2430
+ i = handleClosingTagInFindAll(xmlContent, i, len);
2431
+ continue;
2432
+ }
2433
+ const tagInfo = parseTagName(xmlContent, i, len);
2434
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
2435
+ const tagEnd = tagEndInfo.pos;
2436
+ const isSelfClosing = tagEndInfo.isSelfClosing;
2437
+ if (tagInfo.name !== target) {
2438
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
2439
+ continue;
2440
+ }
2441
+ const nextPos = processOpeningTag({
2442
+ xmlContent,
2443
+ tagEnd,
2444
+ isSelfClosing,
2445
+ target,
2446
+ len,
2447
+ ranges
2448
+ });
2449
+ if (nextPos === -1) {
2450
+ break;
2451
+ }
2452
+ i = nextPos;
2453
+ }
2454
+ return ranges;
2455
+ }
2456
+ function findTopLevelTargetRange(options) {
2457
+ const { xmlContent, tagEnd, isSelfClosing, target, len } = options;
2458
+ const contentStart = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
2459
+ if (isSelfClosing) {
2460
+ return { start: contentStart, end: contentStart };
2461
+ }
2462
+ const closePos = findMatchingCloseTag(xmlContent, contentStart, target, len);
2463
+ if (closePos !== -1) {
2464
+ return { start: contentStart, end: closePos };
2465
+ }
2466
+ return;
2467
+ }
2468
+ function handleClosingTagInFindFirst(xmlContent, i, len, depth) {
2469
+ const gt = xmlContent.indexOf(">", i + 1);
2470
+ return {
2471
+ newPos: gt === -1 ? len : gt + 1,
2472
+ newDepth: Math.max(0, depth - 1)
2473
+ };
2474
+ }
2475
+ function findFirstTopLevelRange(xmlContent, tagName) {
2476
+ const len = xmlContent.length;
2477
+ const target = tagName;
2478
+ let i = 0;
2479
+ let depth = 0;
2480
+ while (i < len) {
2481
+ const lt = xmlContent.indexOf("<", i);
2482
+ if (lt === -1 || lt + 1 >= len) {
2483
+ return;
2484
+ }
2485
+ i = lt + 1;
2486
+ const ch = xmlContent[i];
2487
+ const specialPos = skipSpecialConstruct(xmlContent, i, len);
2488
+ if (specialPos !== -1) {
2489
+ i = specialPos;
2490
+ continue;
2491
+ }
2492
+ if (ch === "/") {
2493
+ const result = handleClosingTagInFindFirst(xmlContent, i, len, depth);
2494
+ i = result.newPos;
2495
+ depth = result.newDepth;
2496
+ continue;
2497
+ }
2498
+ const tagInfo = parseTagName(xmlContent, i, len);
2499
+ const tagEndInfo = skipToTagEnd(xmlContent, tagInfo.pos, len);
2500
+ const tagEnd = tagEndInfo.pos;
2501
+ const isSelfClosing = tagEndInfo.isSelfClosing;
2502
+ if (depth === 0 && tagInfo.name === target) {
2503
+ return findTopLevelTargetRange({
2504
+ xmlContent,
2505
+ tagEnd,
2506
+ isSelfClosing,
2507
+ target,
2508
+ len
2509
+ });
2510
+ }
2511
+ i = xmlContent[tagEnd] === ">" ? tagEnd + 1 : tagEnd + 1;
2512
+ depth += isSelfClosing ? 0 : 1;
2513
+ }
2514
+ return;
2515
+ }
2516
+ function isPositionExcluded(pos, excludeRanges) {
2517
+ if (!excludeRanges || excludeRanges.length === 0) {
2518
+ return false;
2519
+ }
2520
+ for (const r of excludeRanges) {
2521
+ if (pos >= r.start && pos < r.end) {
2522
+ return true;
2523
+ }
2524
+ }
2525
+ return false;
2526
+ }
2527
+ function skipCommentInCounting(xmlContent, i, len) {
2528
+ const close = xmlContent.indexOf("-->", i + 4);
2529
+ return close === -1 ? len : close + 3;
2530
+ }
2531
+ function skipCdataInCounting(xmlContent, i, len) {
2532
+ const close = xmlContent.indexOf("]]>", i + 9);
2533
+ return close === -1 ? len : close + 3;
2534
+ }
2535
+ function skipSpecialInCounting(xmlContent, ch, i, len) {
2536
+ if (ch === "!") {
2537
+ if (xmlContent.startsWith("!--", i + 1)) {
2538
+ return skipCommentInCounting(xmlContent, i, len);
2539
+ }
2540
+ if (xmlContent.startsWith("![CDATA[", i + 1)) {
2541
+ return skipCdataInCounting(xmlContent, i, len);
2542
+ }
2543
+ const gt = xmlContent.indexOf(">", i + 1);
2544
+ return gt === -1 ? len : gt + 1;
2545
+ }
2546
+ if (ch === "?") {
2547
+ const close = xmlContent.indexOf("?>", i + 1);
2548
+ return close === -1 ? len : close + 2;
2549
+ }
2550
+ if (ch === "/") {
2551
+ const gt = xmlContent.indexOf(">", i + 1);
2552
+ return gt === -1 ? len : gt + 1;
2553
+ }
2554
+ return -1;
2555
+ }
2556
+ function parseAndCountTag(options) {
2557
+ const { xmlContent, i, len, target, lt, excludeRanges } = options;
2558
+ let j = i;
2559
+ if (j < len && isNameStartChar(xmlContent[j])) {
2560
+ j += 1;
2561
+ while (j < len && isNameChar(xmlContent[j])) {
2562
+ j += 1;
2563
+ }
2564
+ }
2565
+ const name = xmlContent.slice(i, j);
2566
+ let k = j;
2567
+ while (k < len) {
2568
+ const c = xmlContent[k];
2569
+ if (c === '"' || c === "'") {
2570
+ k = skipQuoted(xmlContent, k);
2571
+ continue;
2572
+ }
2573
+ if (c === ">") {
2574
+ break;
2575
+ }
2576
+ if (c === "/" && xmlContent[k + 1] === ">") {
2577
+ k += 1;
2578
+ break;
2579
+ }
2580
+ k += 1;
2581
+ }
2582
+ const shouldCount = name === target && !isPositionExcluded(lt, excludeRanges);
2583
+ return { nextPos: k + 1, shouldCount };
2584
+ }
2585
+ function countTagOccurrences(xmlContent, tagName, excludeRanges, shouldSkipFirst = true) {
2586
+ const len = xmlContent.length;
2587
+ const target = tagName;
2588
+ let i = 0;
2589
+ let count = 0;
2590
+ let skipFirstLocal = shouldSkipFirst;
2591
+ while (i < len) {
2592
+ const lt = xmlContent.indexOf("<", i);
2593
+ if (lt === -1) {
2594
+ break;
2595
+ }
2596
+ i = lt + 1;
2597
+ if (i >= len) {
2598
+ break;
2599
+ }
2600
+ const ch = xmlContent[i];
2601
+ const skipPos = skipSpecialInCounting(xmlContent, ch, i, len);
2602
+ if (skipPos !== -1) {
2603
+ i = skipPos;
2604
+ continue;
2605
+ }
2606
+ const result = parseAndCountTag({
2607
+ xmlContent,
2608
+ i,
2609
+ len,
2610
+ target,
2611
+ lt,
2612
+ excludeRanges
2613
+ });
2614
+ if (result.shouldCount) {
2615
+ if (skipFirstLocal) {
2616
+ skipFirstLocal = false;
2617
+ } else {
2618
+ count += 1;
2619
+ }
2620
+ }
2621
+ i = result.nextPos;
2622
+ }
2623
+ return count;
2624
+ }
2625
+
2626
+ // src/rxml/core/tokenizer.ts
2627
+ var XMLTokenizer = class {
2628
+ constructor(xmlString, options = {}) {
2629
+ this.pos = 0;
2630
+ this.xmlString = xmlString;
2631
+ this.options = {
2632
+ keepComments: false,
2633
+ keepWhitespace: false,
2634
+ noChildNodes: DEFAULT_NO_CHILD_NODES.slice(),
2635
+ textNodeName: "#text",
2636
+ throwOnDuplicateStringTags: true,
2637
+ ...options
2638
+ };
2639
+ this.pos = options.pos || 0;
2640
+ }
2641
+ /**
2642
+ * Handle closing tag parsing
2643
+ */
2644
+ handleClosingTag(tagName, children) {
2645
+ const closeStart = this.pos + 2;
2646
+ this.pos = this.xmlString.indexOf(">", this.pos);
2647
+ const closeTag = this.xmlString.substring(closeStart, this.pos);
2648
+ if (tagName && closeTag.trim() !== tagName) {
2649
+ const { line, column } = getLineColumn(this.xmlString, this.pos);
2650
+ throw new RXMLParseError(
2651
+ `Unexpected close tag at line ${line}, column ${column}. Expected </${tagName}>, found </${closeTag}>`,
2652
+ void 0,
2653
+ line,
2654
+ column
2655
+ );
2656
+ }
2657
+ if (this.pos !== -1) {
2658
+ this.pos += 1;
2659
+ }
2660
+ return children;
2661
+ }
2662
+ /**
2663
+ * Check if we're at end of string and should throw unclosed tag error
2664
+ */
2665
+ checkUnclosedTag(tagName, consumedToEnd) {
2666
+ if (tagName && this.pos >= this.xmlString.length && !consumedToEnd) {
2667
+ const { line, column } = getLineColumn(this.xmlString, this.pos - 1);
2668
+ throw new RXMLParseError(
2669
+ `Unclosed tag at line ${line}, column ${column}. Expected closing tag </${tagName}>`,
2670
+ void 0,
2671
+ line,
2672
+ column
2673
+ );
2674
+ }
2675
+ }
2676
+ /**
2677
+ * Process special content (comments, CDATA, DOCTYPE) and track if we consumed to end
2678
+ */
2679
+ processSpecialContent(children) {
2680
+ const prevPos = this.pos;
2681
+ this.handleSpecialContent(children);
2682
+ return this.pos >= this.xmlString.length && prevPos < this.xmlString.length;
2683
+ }
2684
+ /**
2685
+ * Handle text content parsing
2686
+ */
2687
+ handleTextContent(children) {
2688
+ const text = this.parseText();
2689
+ if (this.options.keepWhitespace) {
2690
+ if (text.length > 0) {
2691
+ children.push(text);
2692
+ }
2693
+ } else {
2694
+ const trimmed = text.trim();
2695
+ if (trimmed.length > 0) {
2696
+ children.push(trimmed);
2697
+ }
2698
+ }
2699
+ this.pos += 1;
2700
+ }
2701
+ /**
2702
+ * Handle regular element parsing
2703
+ */
2704
+ handleRegularElement(children) {
2705
+ const node = this.parseNode();
2706
+ children.push(node);
2707
+ if (node.tagName[0] === "?") {
2708
+ children.push(...node.children);
2709
+ node.children = [];
2710
+ }
2711
+ }
2712
+ /**
2713
+ * Process a single child element based on the current character
2714
+ */
2715
+ processSingleChild(children, tagName) {
2716
+ if (this.xmlString.charCodeAt(this.pos) !== CharCodes.OPEN_BRACKET) {
2717
+ this.handleTextContent(children);
2718
+ return { shouldReturn: false, consumedToEnd: false };
2719
+ }
2720
+ const nextChar = this.xmlString.charCodeAt(this.pos + 1);
2721
+ if (nextChar === CharCodes.SLASH) {
2722
+ const result = this.handleClosingTag(tagName, children);
2723
+ if (result !== null) {
2724
+ return { shouldReturn: true, consumedToEnd: false };
2725
+ }
2726
+ return { shouldReturn: false, consumedToEnd: false };
2727
+ }
2728
+ if (nextChar === CharCodes.EXCLAMATION) {
2729
+ const wasConsumedToEnd = this.processSpecialContent(children);
2730
+ return { shouldReturn: false, consumedToEnd: wasConsumedToEnd };
2731
+ }
2732
+ this.handleRegularElement(children);
2733
+ return { shouldReturn: false, consumedToEnd: false };
2734
+ }
2735
+ /**
2736
+ * Parse XML children recursively
2737
+ */
2738
+ parseChildren(tagName) {
2739
+ const children = [];
2740
+ let consumedToEnd = false;
2741
+ while (this.xmlString[this.pos]) {
2742
+ const result = this.processSingleChild(children, tagName);
2743
+ if (result.shouldReturn) {
2744
+ return children;
2745
+ }
2746
+ if (result.consumedToEnd) {
2747
+ consumedToEnd = true;
2748
+ }
2749
+ }
2750
+ this.checkUnclosedTag(tagName, consumedToEnd);
2751
+ return children;
2752
+ }
2753
+ /**
2754
+ * Check if character is whitespace
2755
+ */
2756
+ isWhitespace(code) {
2757
+ return code === CharCodes.SPACE || code === CharCodes.TAB || code === CharCodes.NEWLINE || code === CharCodes.CARRIAGE_RETURN;
2758
+ }
2759
+ /**
2760
+ * Skip whitespace characters
2761
+ */
2762
+ skipWhitespace() {
2763
+ while (this.pos < this.xmlString.length && this.isWhitespace(this.xmlString.charCodeAt(this.pos))) {
2764
+ this.pos += 1;
2765
+ }
2766
+ }
2767
+ /**
2768
+ * Parse attribute value
2769
+ */
2770
+ parseAttributeValue() {
2771
+ if (this.pos >= this.xmlString.length || this.xmlString[this.pos] !== "=") {
2772
+ return null;
2773
+ }
2774
+ this.pos += 1;
2775
+ this.skipWhitespace();
2776
+ const code = this.xmlString.charCodeAt(this.pos);
2777
+ if (code === CharCodes.SINGLE_QUOTE || code === CharCodes.DOUBLE_QUOTE) {
2778
+ const { value: parsedValue, newPos: valueEnd } = parseString(
2779
+ this.xmlString,
2780
+ this.pos
2781
+ );
2782
+ this.pos = valueEnd;
2783
+ return parsedValue;
2784
+ }
2785
+ return null;
2786
+ }
2787
+ /**
2788
+ * Parse single attribute
2789
+ */
2790
+ parseAttribute(attributes) {
2791
+ const { name: attrName, newPos: nameEnd } = parseName(
2792
+ this.xmlString,
2793
+ this.pos
2794
+ );
2795
+ this.pos = nameEnd;
2796
+ this.skipWhitespace();
2797
+ const value = this.parseAttributeValue();
2798
+ attributes[attrName] = value;
2799
+ }
2800
+ /**
2801
+ * Parse all attributes
2802
+ */
2803
+ parseAttributes() {
2804
+ const attributes = {};
2805
+ while (this.xmlString.charCodeAt(this.pos) !== CharCodes.CLOSE_BRACKET && this.xmlString[this.pos]) {
2806
+ const c = this.xmlString.charCodeAt(this.pos);
2807
+ if (this.isWhitespace(c)) {
2808
+ this.pos += 1;
2809
+ continue;
2810
+ }
2811
+ if (c > 64 && c < 91 || c > 96 && c < 123) {
2812
+ this.parseAttribute(attributes);
2813
+ } else {
2814
+ this.pos += 1;
2815
+ }
2816
+ }
2817
+ return attributes;
2818
+ }
2819
+ /**
2820
+ * Parse special tag content (script, style)
2821
+ */
2822
+ parseSpecialTagContent(_tagName, closingTag) {
2823
+ const start = this.pos + 1;
2824
+ this.pos = this.xmlString.indexOf(closingTag, this.pos);
2825
+ if (this.pos === -1) {
2826
+ const children2 = [this.xmlString.slice(start)];
2827
+ this.pos = this.xmlString.length;
2828
+ return children2;
2829
+ }
2830
+ const children = [this.xmlString.slice(start, this.pos)];
2831
+ this.pos += closingTag.length;
2832
+ return children;
2833
+ }
2834
+ /**
2835
+ * Parse node children based on tag type
2836
+ */
2837
+ parseNodeChildren(tagName, isSelfClosing) {
2838
+ var _a;
2839
+ if (isSelfClosing) {
2840
+ this.pos += 1;
2841
+ return [];
2842
+ }
2843
+ if (tagName === "script") {
2844
+ return this.parseSpecialTagContent(tagName, "</script>");
2845
+ }
2846
+ if (tagName === "style") {
2847
+ return this.parseSpecialTagContent(tagName, "</style>");
2848
+ }
2849
+ if (((_a = this.options.noChildNodes) == null ? void 0 : _a.indexOf(tagName)) === -1) {
2850
+ this.pos += 1;
2851
+ return this.parseChildren(tagName);
2852
+ }
2853
+ this.pos += 1;
2854
+ if (DEFAULT_NO_CHILD_NODES.includes(tagName)) {
2855
+ return [];
2856
+ }
2857
+ const closingTag = `</${tagName}>`;
2858
+ const closingPos = this.xmlString.indexOf(closingTag, this.pos);
2859
+ if (closingPos !== -1) {
2860
+ this.pos = closingPos + closingTag.length;
2861
+ }
2862
+ return [];
2863
+ }
2864
+ /**
2865
+ * Parse a single XML node
2866
+ */
2867
+ parseNode() {
2868
+ this.pos += 1;
2869
+ const { name: tagName, newPos } = parseName(this.xmlString, this.pos);
2870
+ this.pos = newPos;
2871
+ const attributes = this.parseAttributes();
2872
+ const isSelfClosing = this.xmlString.charCodeAt(this.pos - 1) === CharCodes.SLASH || tagName[0] === "?" && this.xmlString.charCodeAt(this.pos - 1) === CharCodes.QUESTION;
2873
+ const children = this.parseNodeChildren(tagName, isSelfClosing);
2874
+ return { tagName, attributes, children };
2875
+ }
2876
+ /**
2877
+ * Parse text content until next tag
2878
+ */
2879
+ parseText() {
2880
+ const start = this.pos;
2881
+ this.pos = this.xmlString.indexOf("<", this.pos) - 1;
2882
+ if (this.pos === -2) {
2883
+ this.pos = this.xmlString.length;
2884
+ }
2885
+ return this.xmlString.slice(start, this.pos + 1);
2886
+ }
2887
+ /**
2888
+ * Handle comments, CDATA, and DOCTYPE declarations
2889
+ */
2890
+ handleSpecialContent(children) {
2891
+ if (this.xmlString.charCodeAt(this.pos + 2) === CharCodes.MINUS) {
2892
+ this.handleComment(children);
2893
+ } 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") {
2894
+ this.handleCData(children);
2895
+ } else {
2896
+ this.handleDoctype(children);
2897
+ }
2898
+ }
2899
+ /**
2900
+ * Handle XML comments
2901
+ */
2902
+ handleComment(children) {
2903
+ const startCommentPos = this.pos;
2904
+ 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)) {
2905
+ this.pos = this.xmlString.indexOf(">", this.pos + 1);
2906
+ }
2907
+ if (this.pos === -1) {
2908
+ this.pos = this.xmlString.length;
2909
+ }
2910
+ if (this.options.keepComments) {
2911
+ children.push(this.xmlString.substring(startCommentPos, this.pos + 1));
2912
+ }
2913
+ this.pos += 1;
2914
+ }
2915
+ /**
2916
+ * Handle CDATA sections
2917
+ */
2918
+ handleCData(children) {
2919
+ const cdataEndIndex = this.xmlString.indexOf("]]>", this.pos);
2920
+ if (cdataEndIndex === -1) {
2921
+ children.push(this.xmlString.substr(this.pos + 9));
2922
+ this.pos = this.xmlString.length;
2923
+ } else {
2924
+ children.push(this.xmlString.substring(this.pos + 9, cdataEndIndex));
2925
+ this.pos = cdataEndIndex + 3;
2926
+ }
2927
+ }
2928
+ /**
2929
+ * Handle DOCTYPE declarations
2930
+ */
2931
+ handleDoctype(children) {
2932
+ const startDoctype = this.pos + 1;
2933
+ this.pos += 2;
2934
+ let encapsulated = false;
2935
+ while ((this.xmlString.charCodeAt(this.pos) !== CharCodes.CLOSE_BRACKET || encapsulated) && this.xmlString[this.pos]) {
2936
+ if (this.xmlString.charCodeAt(this.pos) === CharCodes.OPEN_CORNER_BRACKET) {
2937
+ encapsulated = true;
2938
+ } else if (encapsulated && this.xmlString.charCodeAt(this.pos) === CharCodes.CLOSE_CORNER_BRACKET) {
2939
+ encapsulated = false;
2940
+ }
2941
+ this.pos += 1;
2942
+ }
2943
+ children.push(this.xmlString.substring(startDoctype, this.pos));
2944
+ this.pos += 1;
2945
+ }
2946
+ /**
2947
+ * Get current position
2948
+ */
2949
+ getPosition() {
2950
+ return this.pos;
2951
+ }
2952
+ /**
2953
+ * Set position
2954
+ */
2955
+ setPosition(pos) {
2956
+ this.pos = pos;
2957
+ }
2958
+ };
2959
+
2960
+ // src/rxml/core/parser.ts
2961
+ var WHITESPACE_REGEX2 = /\s/;
2962
+ var NUMERIC_STRING_REGEX = /^-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?$/;
2963
+ var DIGIT_KEY_REGEX2 = /^\d+$/;
2964
+ function getTopLevelStringProps(s) {
2965
+ const set = /* @__PURE__ */ new Set();
2966
+ const unwrapped = unwrapJsonSchema(s);
2967
+ if (unwrapped && typeof unwrapped === "object") {
2968
+ const props = unwrapped.properties;
2969
+ if (props && typeof props === "object") {
2970
+ for (const [k, v] of Object.entries(props)) {
2971
+ if (getSchemaType(v) === "string") {
2972
+ set.add(k);
2973
+ }
2974
+ }
2975
+ }
2976
+ }
2977
+ return set;
2978
+ }
2979
+ function restorePlaceholderString(val, placeholderMap) {
2980
+ if (val.startsWith("__RXML_PLACEHOLDER_")) {
2981
+ const orig = placeholderMap.get(val);
2982
+ return orig !== void 0 ? orig : val;
2983
+ }
2984
+ return val;
2985
+ }
2986
+ function restorePlaceholdersInObject(obj, _placeholderMap, textNodeName, restorer) {
2987
+ const out = {};
2988
+ for (const [k, v] of Object.entries(obj)) {
2989
+ const restored = restorer(v);
2990
+ if (k === textNodeName && typeof restored === "string") {
2991
+ out[k] = restored.trim();
2992
+ } else {
2993
+ out[k] = restored;
2994
+ }
2995
+ }
2996
+ return out;
2997
+ }
2998
+ function createPlaceholderRestorer(placeholderMap, textNodeName) {
2999
+ const restorer = (val) => {
3000
+ if (val == null) {
3001
+ return val;
3002
+ }
3003
+ if (typeof val === "string") {
3004
+ return restorePlaceholderString(val, placeholderMap);
3005
+ }
3006
+ if (Array.isArray(val)) {
3007
+ return val.map(restorer);
3008
+ }
3009
+ if (typeof val === "object") {
3010
+ return restorePlaceholdersInObject(
3011
+ val,
3012
+ placeholderMap,
3013
+ textNodeName,
3014
+ restorer
3015
+ );
3016
+ }
3017
+ return val;
3018
+ };
3019
+ return restorer;
3020
+ }
3021
+ function tryConvertToNumber(val) {
3022
+ if (typeof val !== "string") {
3023
+ return val;
3024
+ }
3025
+ const trimmed = val.trim();
3026
+ if (NUMERIC_STRING_REGEX.test(trimmed)) {
3027
+ const num = Number(trimmed);
3028
+ if (Number.isFinite(num)) {
3029
+ return num;
3030
+ }
3031
+ }
3032
+ return trimmed;
3033
+ }
3034
+ function processItemValue(item, textNodeName) {
3035
+ let currentVal = item;
3036
+ if (item && typeof item === "object" && Object.hasOwn(item, textNodeName)) {
3037
+ currentVal = item[textNodeName];
3038
+ }
3039
+ const trimmed = typeof currentVal === "string" ? currentVal.trim() : currentVal;
3040
+ return tryConvertToNumber(trimmed);
3041
+ }
3042
+ function processItemWrapper(itemValue, textNodeName) {
3043
+ if (Array.isArray(itemValue)) {
3044
+ return itemValue.map((item) => processItemValue(item, textNodeName));
3045
+ }
3046
+ const trimmed = typeof itemValue === "string" ? itemValue.trim() : itemValue;
3047
+ return tryConvertToNumber(trimmed);
3048
+ }
3049
+ function deepDecodeStringsBySchema(input, schema) {
3050
+ var _a;
3051
+ if (input == null || schema == null) {
3052
+ return input;
3053
+ }
3054
+ const type = getSchemaType(schema);
3055
+ if (type === "string" && typeof input === "string") {
3056
+ return unescapeXml(input);
3057
+ }
3058
+ if (type === "array" && Array.isArray(input)) {
3059
+ const unwrapped = unwrapJsonSchema(schema);
3060
+ const itemSchema = (_a = unwrapped == null ? void 0 : unwrapped.items) != null ? _a : {};
3061
+ return input.map((item) => deepDecodeStringsBySchema(item, itemSchema));
3062
+ }
3063
+ if (type === "object" && input && typeof input === "object") {
3064
+ const obj = input;
3065
+ const out = {};
3066
+ for (const key of Object.keys(obj)) {
3067
+ const childSchema = getPropertySchema(schema, key);
3068
+ out[key] = deepDecodeStringsBySchema(obj[key], childSchema);
3069
+ }
3070
+ return out;
3071
+ }
3072
+ if (typeof input === "string") {
3073
+ return unescapeXml(input);
3074
+ }
3075
+ return input;
3076
+ }
3077
+ function parse2(xmlInner, schema, options = {}) {
3078
+ var _a, _b, _c;
3079
+ const textNodeName = (_a = options.textNodeName) != null ? _a : "#text";
3080
+ const throwDup = (_b = options.throwOnDuplicateStringTags) != null ? _b : true;
3081
+ let actualXmlInner = xmlInner.trim();
3082
+ if (actualXmlInner.startsWith("<") && actualXmlInner.endsWith(">")) {
3083
+ const s = actualXmlInner;
3084
+ let i = 0;
3085
+ let rootStart = -1;
3086
+ let rootName = "";
3087
+ while (i < s.length) {
3088
+ const lt = s.indexOf("<", i);
3089
+ if (lt === -1) {
3090
+ break;
3091
+ }
3092
+ const next = s[lt + 1];
3093
+ if (next === "?") {
3094
+ const end = s.indexOf("?>", lt + 2);
3095
+ i = end === -1 ? s.length : end + 2;
3096
+ continue;
3097
+ }
3098
+ if (next === "!") {
3099
+ if (s.startsWith("!--", lt + 2)) {
3100
+ const end2 = s.indexOf("-->", lt + 5);
3101
+ i = end2 === -1 ? s.length : end2 + 3;
3102
+ continue;
3103
+ }
3104
+ if (s.startsWith("![CDATA[", lt + 2)) {
3105
+ const end2 = s.indexOf("]]>", lt + 9);
3106
+ i = end2 === -1 ? s.length : end2 + 3;
3107
+ continue;
3108
+ }
3109
+ const end = s.indexOf(">", lt + 2);
3110
+ i = end === -1 ? s.length : end + 1;
3111
+ continue;
3112
+ }
3113
+ if (next === "/") {
3114
+ break;
3115
+ }
3116
+ let j = lt + 1;
3117
+ while (j < s.length && s[j] !== " " && s[j] !== "\n" && s[j] !== "\r" && s[j] !== " " && s[j] !== "/" && s[j] !== ">") {
3118
+ j += 1;
3119
+ }
3120
+ rootStart = lt;
3121
+ rootName = s.slice(lt + 1, j);
3122
+ break;
3123
+ }
3124
+ if (rootStart === 0 && rootName) {
3125
+ const range = findFirstTopLevelRange(s, rootName);
3126
+ if (range) {
3127
+ let fullEnd = range.end + `</${rootName}>`.length;
3128
+ const closeHead = s.indexOf(`</${rootName}`, range.end);
3129
+ if (closeHead === range.end) {
3130
+ let p = closeHead + 2 + rootName.length;
3131
+ while (p < s.length && WHITESPACE_REGEX2.test(s[p])) {
3132
+ p += 1;
3133
+ }
3134
+ if (s[p] === ">") {
3135
+ fullEnd = p + 1;
3136
+ }
3137
+ }
3138
+ if (fullEnd === s.length) {
3139
+ const unwrapped = unwrapJsonSchema(schema);
3140
+ const schemaProps = unwrapped && typeof unwrapped === "object" ? unwrapped.properties : void 0;
3141
+ if (schemaProps && !Object.hasOwn(schemaProps, rootName)) {
3142
+ actualXmlInner = s.slice(range.start, range.end);
3143
+ }
3144
+ }
3145
+ }
3146
+ }
3147
+ }
3148
+ const topLevelStringProps = getTopLevelStringProps(schema);
3149
+ const deepStringTypedProps = getStringTypedProperties(schema);
3150
+ const duplicateKeys = /* @__PURE__ */ new Set();
3151
+ for (const key of topLevelStringProps) {
3152
+ const excludeRanges = [];
3153
+ for (const other of topLevelStringProps) {
3154
+ if (other === key) {
3155
+ continue;
3156
+ }
3157
+ const range = findFirstTopLevelRange(actualXmlInner, other);
3158
+ if (range) {
3159
+ excludeRanges.push(range);
3160
+ }
3161
+ }
3162
+ const occurrences = countTagOccurrences(
3163
+ actualXmlInner,
3164
+ key,
3165
+ excludeRanges,
3166
+ true
3167
+ );
3168
+ if (occurrences > 0 && throwDup) {
3169
+ throw new RXMLDuplicateStringTagError(
3170
+ `Duplicate string tags for <${key}> detected`
3171
+ );
3172
+ }
3173
+ if (occurrences > 0 && !throwDup) {
3174
+ duplicateKeys.add(key);
3175
+ if (options.onError) {
3176
+ options.onError(
3177
+ `RXML: Duplicate string tags for <${key}> detected; using first occurrence.`,
3178
+ { tag: key, occurrences }
3179
+ );
3180
+ }
3181
+ }
3182
+ }
3183
+ let xmlInnerForParsing = actualXmlInner;
3184
+ const originalContentMap = /* @__PURE__ */ new Map();
3185
+ try {
3186
+ const ranges = [];
3187
+ for (const key of deepStringTypedProps) {
3188
+ const innerRanges = findAllInnerRanges(actualXmlInner, key);
3189
+ for (const r of innerRanges) {
3190
+ if (r.end > r.start) {
3191
+ ranges.push({ ...r, key });
3192
+ }
3193
+ }
3194
+ }
3195
+ if (ranges.length > 0) {
3196
+ const sorted = [...ranges].sort((a, b) => a.start - b.start);
3197
+ let rebuilt = "";
3198
+ let cursor = 0;
3199
+ for (const r of sorted) {
3200
+ if (r.start < cursor) {
3201
+ continue;
3202
+ }
3203
+ if (cursor < r.start) {
3204
+ rebuilt += actualXmlInner.slice(cursor, r.start);
3205
+ }
3206
+ const placeholder = `__RXML_PLACEHOLDER_${r.key}_${r.start}_${r.end}__`;
3207
+ const originalContent = actualXmlInner.slice(r.start, r.end);
3208
+ originalContentMap.set(placeholder, originalContent);
3209
+ rebuilt += placeholder;
3210
+ cursor = r.end;
3211
+ }
3212
+ if (cursor < actualXmlInner.length) {
3213
+ rebuilt += actualXmlInner.slice(cursor);
3214
+ }
3215
+ xmlInnerForParsing = rebuilt;
3216
+ }
3217
+ } catch (error) {
3218
+ if (options.onError) {
3219
+ options.onError(
3220
+ "RXML: Failed to replace string placeholders, falling back to original XML.",
3221
+ { error }
3222
+ );
3223
+ }
3224
+ xmlInnerForParsing = actualXmlInner;
3225
+ }
3226
+ let parsedNodes;
3227
+ try {
3228
+ const wrappedXml = `<root>${xmlInnerForParsing}</root>`;
3229
+ const tokenizer = new XMLTokenizer(wrappedXml, {
3230
+ ...options,
3231
+ textNodeName
3232
+ });
3233
+ const rootNode = tokenizer.parseNode();
3234
+ parsedNodes = rootNode.children;
3235
+ } catch (cause) {
3236
+ throw new RXMLParseError("Failed to parse XML", cause);
3237
+ }
3238
+ const parsedArgs = domToObject(parsedNodes, schema, textNodeName);
3239
+ const restorePlaceholdersDeep = createPlaceholderRestorer(
3240
+ originalContentMap,
3241
+ textNodeName
3242
+ );
3243
+ const parsedArgsRestored = restorePlaceholdersDeep(parsedArgs);
3244
+ const args = {};
3245
+ for (const k of Object.keys(parsedArgsRestored || {})) {
3246
+ const v = parsedArgsRestored[k];
3247
+ let val = v;
3248
+ const propSchema = getPropertySchema(schema, k);
3249
+ const propType = getSchemaType(propSchema);
3250
+ if (propType === "string" && duplicateKeys.has(k) && Array.isArray(v)) {
3251
+ const firstValue = v[0];
3252
+ if (typeof firstValue === "string" && firstValue.startsWith("__RXML_PLACEHOLDER_")) {
3253
+ const originalContent = originalContentMap.get(firstValue);
3254
+ if (originalContent !== void 0) {
3255
+ args[k] = originalContent;
3256
+ continue;
3257
+ }
3258
+ } else {
3259
+ args[k] = firstValue;
3260
+ continue;
3261
+ }
3262
+ }
3263
+ if (propType === "string" && !Array.isArray(v)) {
3264
+ const placeholderUsed = typeof v === "string" && v.startsWith("__RXML_PLACEHOLDER_") || v && typeof v === "object" && Object.hasOwn(v, textNodeName) && typeof v[textNodeName] === "string" && v[textNodeName].startsWith(
3265
+ "__RXML_PLACEHOLDER_"
3266
+ );
3267
+ if (placeholderUsed) {
3268
+ let placeholderKey;
3269
+ if (typeof v === "string") {
3270
+ placeholderKey = v;
3271
+ } else {
3272
+ placeholderKey = v[textNodeName];
3273
+ }
3274
+ const originalContent = originalContentMap.get(placeholderKey);
3275
+ if (originalContent !== void 0) {
3276
+ args[k] = originalContent;
3277
+ continue;
3278
+ }
3279
+ }
3280
+ const raw = extractRawInner(actualXmlInner, k);
3281
+ if (typeof raw === "string") {
3282
+ args[k] = raw;
3283
+ continue;
3284
+ }
3285
+ }
3286
+ if (v && typeof v === "object" && Object.hasOwn(v, textNodeName)) {
3287
+ val = v[textNodeName];
3288
+ }
3289
+ if (Array.isArray(v)) {
3290
+ if (propType === "string") {
3291
+ const mapped = v.map((item) => {
3292
+ if (item && typeof item === "object" && Object.hasOwn(item, textNodeName)) {
3293
+ const textVal = item[textNodeName];
3294
+ return typeof textVal === "string" ? textVal : String(textVal);
3295
+ }
3296
+ return typeof item === "string" ? item : String(item);
3297
+ });
3298
+ if (mapped.length > 1 && throwDup) {
3299
+ throw new RXMLDuplicateStringTagError(
3300
+ `Duplicate string tags for <${k}> detected`
3301
+ );
3302
+ }
3303
+ if (mapped.length > 1 && !throwDup && options.onError) {
3304
+ options.onError(
3305
+ `RXML: Duplicate string tags for <${k}> detected; using first occurrence.`,
3306
+ { tag: k, occurrences: mapped.length }
3307
+ );
3308
+ }
3309
+ args[k] = (_c = mapped[0]) != null ? _c : "";
3310
+ continue;
3311
+ }
3312
+ val = processArrayContent(v, propSchema, textNodeName);
3313
+ } else if (v && typeof v === "object" && !Object.hasOwn(v, textNodeName)) {
3314
+ const obj = v;
3315
+ const keys2 = Object.keys(obj);
3316
+ if (keys2.length === 1 && keys2[0] === "item") {
3317
+ val = processItemWrapper(obj.item, textNodeName);
3318
+ } else {
3319
+ let isIndexedTuple = false;
3320
+ if (keys2.length > 0 && keys2.every((key) => DIGIT_KEY_REGEX2.test(key))) {
3321
+ const indices = keys2.map((keyStr) => Number.parseInt(keyStr, 10)).sort((a, b) => a - b);
3322
+ isIndexedTuple = indices[0] === 0 && indices.every((indexVal, idx) => indexVal === idx);
3323
+ }
3324
+ if (isIndexedTuple) {
3325
+ val = processIndexedTuple(obj, textNodeName);
3326
+ } else {
3327
+ val = v;
3328
+ }
3329
+ }
3330
+ }
3331
+ args[k] = typeof val === "string" ? val.trim() : val;
3332
+ }
3333
+ for (const key of topLevelStringProps) {
3334
+ if (!Object.hasOwn(args, key)) {
3335
+ const raw = extractRawInner(actualXmlInner, key);
3336
+ if (typeof raw === "string") {
3337
+ args[key] = raw;
3338
+ }
3339
+ }
3340
+ }
3341
+ let dataToCoerce = args;
3342
+ const keys = Object.keys(args);
3343
+ if (keys.length === 1) {
3344
+ const rootKey = keys[0];
3345
+ const rootValue = args[rootKey];
3346
+ const unwrapped = unwrapJsonSchema(schema);
3347
+ if (unwrapped && typeof unwrapped === "object") {
3348
+ const schemaProps = unwrapped.properties;
3349
+ if (schemaProps && !Object.hasOwn(schemaProps, rootKey)) {
3350
+ dataToCoerce = rootValue;
3351
+ }
3352
+ }
3353
+ }
3354
+ try {
3355
+ const coerced = coerceDomBySchema(dataToCoerce, schema);
3356
+ const decoded = deepDecodeStringsBySchema(coerced, schema);
3357
+ return decoded;
3358
+ } catch (error) {
3359
+ throw new RXMLCoercionError("Failed to coerce by schema", error);
3360
+ }
3361
+ }
3362
+
3363
+ // src/rxml/heuristics/engine.ts
3364
+ function applyRawSegmentUpdate(current, result) {
3365
+ if (result.rawSegment !== void 0) {
3366
+ return { ...current, rawSegment: result.rawSegment };
3367
+ }
3368
+ return current;
3369
+ }
3370
+ function applyParsedUpdate(current, result) {
3371
+ if (result.parsed !== void 0) {
3372
+ return { ...current, parsed: result.parsed };
3373
+ }
3374
+ return current;
3375
+ }
3376
+ function applyWarningsUpdate(current, result) {
3377
+ var _a, _b;
3378
+ if (result.warnings && result.warnings.length > 0) {
3379
+ const meta = (_a = current.meta) != null ? _a : {};
3380
+ const existingWarnings = (_b = meta.warnings) != null ? _b : [];
3381
+ return {
3382
+ ...current,
3383
+ meta: { ...meta, warnings: [...existingWarnings, ...result.warnings] }
3384
+ };
3385
+ }
3386
+ return current;
3387
+ }
3388
+ function attemptReparse(current, result, reparseCount, maxReparses, parse4) {
3389
+ if (!result.reparse || result.rawSegment === void 0 || reparseCount >= maxReparses) {
3390
+ return { state: current, newCount: reparseCount };
3391
+ }
3392
+ try {
3393
+ const reparsed = parse4(result.rawSegment, current.schema);
3394
+ return {
3395
+ state: { ...current, parsed: reparsed, errors: [] },
3396
+ newCount: reparseCount + 1
3397
+ };
3398
+ } catch (error) {
3399
+ return {
3400
+ state: { ...current, errors: [...current.errors, error] },
3401
+ newCount: reparseCount + 1
3402
+ };
3403
+ }
3404
+ }
3405
+ function executePhase(ctx, heuristics, options) {
3406
+ var _a;
3407
+ let current = ctx;
3408
+ let reparseCount = 0;
3409
+ const maxReparses = (_a = options.maxReparses) != null ? _a : 2;
3410
+ for (const heuristic of heuristics) {
3411
+ if (!heuristic.applies(current)) {
3412
+ continue;
3413
+ }
3414
+ const result = heuristic.run(current);
3415
+ current = applyRawSegmentUpdate(current, result);
3416
+ current = applyParsedUpdate(current, result);
3417
+ current = applyWarningsUpdate(current, result);
3418
+ const reparseResult = attemptReparse(
3419
+ current,
3420
+ result,
3421
+ reparseCount,
3422
+ maxReparses,
3423
+ options.parse
3424
+ );
3425
+ current = reparseResult.state;
3426
+ reparseCount = reparseResult.newCount;
3427
+ if (result.stop) {
3428
+ break;
3429
+ }
3430
+ }
3431
+ return current;
3432
+ }
3433
+ function applyHeuristicPipeline(ctx, config, options) {
3434
+ let current = ctx;
3435
+ if (config.preParse && config.preParse.length > 0) {
3436
+ current = executePhase(current, config.preParse, options);
3437
+ }
3438
+ if (current.parsed === null && current.errors.length === 0) {
3439
+ try {
3440
+ const parsed = options.parse(current.rawSegment, current.schema);
3441
+ current = { ...current, parsed, errors: [] };
3442
+ } catch (error) {
3443
+ current = { ...current, errors: [error] };
3444
+ }
3445
+ }
3446
+ if (current.errors.length > 0 && config.fallbackReparse && config.fallbackReparse.length > 0) {
3447
+ current = executePhase(current, config.fallbackReparse, options);
3448
+ }
3449
+ if (current.parsed !== null && config.postParse && config.postParse.length > 0) {
3450
+ current = executePhase(current, config.postParse, options);
3451
+ }
3452
+ return current;
3453
+ }
3454
+ function createIntermediateCall(toolName, rawSegment, schema) {
3455
+ return {
3456
+ toolName,
3457
+ schema,
3458
+ rawSegment,
3459
+ parsed: null,
3460
+ errors: [],
3461
+ meta: { originalContent: rawSegment }
3462
+ };
3463
+ }
3464
+
3465
+ // src/rxml/heuristics/xml-defaults.ts
3466
+ var MALFORMED_CLOSE_RE_G = /<\/\s+([A-Za-z0-9_:-]+)\s*>/g;
3467
+ var MALFORMED_CLOSE_RE = /<\/\s+([A-Za-z0-9_:-]+)\s*>/;
3468
+ var STATUS_TO_STEP_BOUNDARY_RE = /<\/status>\s*<step>/g;
3469
+ var WHITESPACE_REGEX3 = /\s/;
3470
+ var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
3471
+ var NAME_START_CHAR_RE = /[A-Za-z_:]/;
3472
+ var STEP_TAG_RE = /<step>([\s\S]*?)<\/step>/i;
3473
+ var STATUS_TAG_RE = /<status>([\s\S]*?)<\/status>/i;
3474
+ var normalizeCloseTagsHeuristic = {
3475
+ id: "normalize-close-tags",
3476
+ phase: "pre-parse",
3477
+ applies: () => true,
3478
+ run: (ctx) => {
3479
+ const normalized = ctx.rawSegment.replace(MALFORMED_CLOSE_RE_G, "</$1>");
3480
+ if (normalized !== ctx.rawSegment) {
3481
+ return { rawSegment: normalized };
3482
+ }
3483
+ return {};
3484
+ }
3485
+ };
3486
+ var escapeInvalidLtHeuristic = {
3487
+ id: "escape-invalid-lt",
3488
+ phase: "pre-parse",
3489
+ applies: () => true,
3490
+ run: (ctx) => {
3491
+ const escaped = escapeInvalidLt(ctx.rawSegment);
3492
+ if (escaped !== ctx.rawSegment) {
3493
+ return { rawSegment: escaped };
3494
+ }
3495
+ return {};
3496
+ }
3497
+ };
3498
+ var balanceTagsHeuristic = {
3499
+ id: "balance-tags",
3500
+ phase: "fallback-reparse",
3501
+ applies: (ctx) => {
3502
+ var _a;
3503
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
3504
+ const normalized = original.replace(MALFORMED_CLOSE_RE_G, "</$1>");
3505
+ const balanced = balanceTags(original);
3506
+ const hasMalformedClose = MALFORMED_CLOSE_RE.test(original);
3507
+ if (!hasMalformedClose && balanced.length > normalized.length && ctx.errors.length === 0) {
3508
+ return false;
3509
+ }
3510
+ return balanced !== normalized;
3511
+ },
3512
+ run: (ctx) => {
3513
+ var _a;
3514
+ const original = ((_a = ctx.meta) == null ? void 0 : _a.originalContent) || ctx.rawSegment;
3515
+ const balanced = balanceTags(original);
3516
+ const escaped = escapeInvalidLt(balanced);
3517
+ return { rawSegment: escaped, reparse: true };
3518
+ }
3519
+ };
3520
+ var dedupeShellStringTagsHeuristic = {
3521
+ id: "dedupe-shell-string-tags",
3522
+ phase: "fallback-reparse",
3523
+ applies: (ctx) => shouldDeduplicateStringTags(ctx.schema),
3524
+ run: (ctx) => {
3525
+ const names = getStringPropertyNames(ctx.schema);
3526
+ let deduped = ctx.rawSegment;
3527
+ for (const key of names) {
3528
+ deduped = dedupeSingleTag(deduped, key);
3529
+ }
3530
+ if (deduped !== ctx.rawSegment) {
3531
+ return { rawSegment: deduped, reparse: true };
3532
+ }
3533
+ return {};
3534
+ }
3535
+ };
3536
+ var repairAgainstSchemaHeuristic = {
3537
+ id: "repair-against-schema",
3538
+ phase: "post-parse",
3539
+ applies: (ctx) => ctx.parsed !== null && typeof ctx.parsed === "object",
3540
+ run: (ctx) => {
3541
+ const repaired = repairParsedAgainstSchema(ctx.parsed, ctx.schema);
3542
+ if (repaired !== ctx.parsed) {
3543
+ return { parsed: repaired };
3544
+ }
3545
+ return {};
3546
+ }
3547
+ };
3548
+ var defaultPipelineConfig = {
3549
+ preParse: [normalizeCloseTagsHeuristic, escapeInvalidLtHeuristic],
3550
+ fallbackReparse: [balanceTagsHeuristic, dedupeShellStringTagsHeuristic],
3551
+ postParse: [repairAgainstSchemaHeuristic]
3552
+ };
3553
+ var INDEX_TAG_RE = /^<(\d+)(?:>|\/?>)/;
3554
+ function isIndexTagAt(xml, pos) {
3555
+ const remaining = xml.slice(pos);
3556
+ return INDEX_TAG_RE.test(remaining);
3557
+ }
3558
+ function escapeInvalidLt(xml) {
3559
+ const len = xml.length;
3560
+ let out = "";
3561
+ for (let i = 0; i < len; i += 1) {
3562
+ const ch = xml[i];
3563
+ if (ch === "<") {
3564
+ const next = i + 1 < len ? xml[i + 1] : "";
3565
+ const isValidStart = NAME_START_CHAR_RE.test(next) || next === "/" || next === "!" || next === "?";
3566
+ const isIndexTag = !isValidStart && isIndexTagAt(xml, i);
3567
+ if (!(isValidStart || isIndexTag)) {
3568
+ out += "&lt;";
3569
+ continue;
3570
+ }
3571
+ }
3572
+ out += ch;
3573
+ }
3574
+ return out;
3575
+ }
3576
+ function balanceTags(xml) {
3577
+ const src = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>").replace(STATUS_TO_STEP_BOUNDARY_RE, "</status></step><step>");
3578
+ let i = 0;
3579
+ const len = src.length;
3580
+ const out = [];
3581
+ const stack = [];
3582
+ while (i < len) {
3583
+ const lt = src.indexOf("<", i);
3584
+ if (lt === -1) {
3585
+ out.push(src.slice(i));
3586
+ break;
3587
+ }
3588
+ out.push(src.slice(i, lt));
3589
+ if (lt + 1 >= len) {
3590
+ break;
3591
+ }
3592
+ const next = src[lt + 1];
3593
+ if (next === "!" || next === "?") {
3594
+ i = handleSpecialTagSegment(src, lt, out);
3595
+ continue;
3596
+ }
3597
+ if (next === "/") {
3598
+ i = handleClosingTagSegment(src, lt, out, stack);
3599
+ continue;
3600
+ }
3601
+ i = handleOpeningTagSegment(src, lt, out, stack);
3602
+ }
3603
+ for (let k = stack.length - 1; k >= 0; k -= 1) {
3604
+ out.push(`</${stack[k]}>`);
3605
+ }
3606
+ return out.join("");
3607
+ }
3608
+ function skipWs(s, p, len) {
3609
+ let idx = p;
3610
+ while (idx < len && WHITESPACE_REGEX3.test(s[idx])) {
3611
+ idx += 1;
3612
+ }
3613
+ return idx;
3614
+ }
3615
+ function parseTagNameAt(s, p, len) {
3616
+ let idx = p;
3617
+ const start = idx;
3618
+ while (idx < len && NAME_CHAR_RE.test(s[idx])) {
3619
+ idx += 1;
3620
+ }
3621
+ return { name: s.slice(start, idx), pos: idx };
3622
+ }
3623
+ function handleSpecialTagSegment(src, lt, out) {
3624
+ const gt = src.indexOf(">", lt + 1);
3625
+ if (gt === -1) {
3626
+ out.push(src.slice(lt));
3627
+ return src.length;
3628
+ }
3629
+ out.push(src.slice(lt, gt + 1));
3630
+ return gt + 1;
3631
+ }
3632
+ function handleClosingTagSegment(src, lt, out, stack) {
3633
+ const len = src.length;
3634
+ let p = skipWs(src, lt + 2, len);
3635
+ const { name, pos } = parseTagNameAt(src, p, len);
3636
+ p = pos;
3637
+ const gt = src.indexOf(">", p);
3638
+ const closingText = gt === -1 ? src.slice(lt) : src.slice(lt, gt + 1);
3639
+ const idx = stack.lastIndexOf(name);
3640
+ if (idx !== -1) {
3641
+ for (let k = stack.length - 1; k > idx; k -= 1) {
3642
+ out.push(`</${stack[k]}>`);
3643
+ stack.pop();
3644
+ }
3645
+ out.push(closingText);
3646
+ stack.pop();
3647
+ }
3648
+ return gt === -1 ? len : gt + 1;
3649
+ }
3650
+ function handleOpeningTagSegment(src, lt, out, stack) {
3651
+ const len = src.length;
3652
+ let p = skipWs(src, lt + 1, len);
3653
+ const nameStart = p;
3654
+ const parsed = parseTagNameAt(src, p, len);
3655
+ p = parsed.pos;
3656
+ const name = src.slice(nameStart, p);
3657
+ const q = src.indexOf(">", p);
3658
+ if (q === -1) {
3659
+ out.push(src.slice(lt));
3660
+ return len;
3661
+ }
3662
+ let r = q - 1;
3663
+ while (r >= nameStart && WHITESPACE_REGEX3.test(src[r])) {
3664
+ r -= 1;
3665
+ }
3666
+ const selfClosing = src[r] === "/";
3667
+ out.push(src.slice(lt, q + 1));
3668
+ if (!selfClosing && name) {
3669
+ stack.push(name);
3670
+ }
3671
+ return q + 1;
3672
+ }
3673
+ function extractSchemaProperties(schema) {
3674
+ const unwrapped = unwrapJsonSchema(schema);
3675
+ if (!unwrapped || typeof unwrapped !== "object") {
3676
+ return void 0;
330
3677
  }
331
- logParseFailure({
332
- phase: "stream",
333
- reason: "Incomplete streaming tool call segment emitted as text",
334
- snippet: `${toolCallStart}${state.currentToolCallJson}`
335
- });
336
- const errorId = generateId();
337
- const errorContent = `${toolCallStart}${state.currentToolCallJson}`;
338
- controller.enqueue({
339
- type: "text-start",
340
- id: errorId
341
- });
342
- controller.enqueue({
343
- type: "text-delta",
344
- id: errorId,
345
- delta: errorContent
346
- });
347
- controller.enqueue({
348
- type: "text-end",
349
- id: errorId
350
- });
351
- state.currentToolCallJson = "";
3678
+ return unwrapped.properties;
352
3679
  }
353
- function handleFinishChunk(state, controller, toolCallStart, chunk) {
354
- if (state.buffer.length > 0) {
355
- flushBuffer(state, controller, toolCallStart);
3680
+ function shouldDeduplicateStringTags(schema) {
3681
+ const props = extractSchemaProperties(schema);
3682
+ if (!props) {
3683
+ return false;
356
3684
  }
357
- closeTextBlock(state, controller);
358
- emitIncompleteToolCall(state, controller, toolCallStart);
359
- controller.enqueue(chunk);
3685
+ const commandRaw = props.command;
3686
+ if (!commandRaw) {
3687
+ return false;
3688
+ }
3689
+ const command = unwrapJsonSchema(commandRaw);
3690
+ return (command == null ? void 0 : command.type) === "array";
360
3691
  }
361
- function publishText(text, state, controller) {
362
- if (state.isInsideToolCall) {
363
- closeTextBlock(state, controller);
364
- state.currentToolCallJson += text;
365
- } else if (text.length > 0) {
366
- if (!state.currentTextId) {
367
- state.currentTextId = generateId();
368
- controller.enqueue({
369
- type: "text-start",
370
- id: state.currentTextId
371
- });
372
- state.hasEmittedTextStart = true;
3692
+ function getStringPropertyNames(schema) {
3693
+ const props = extractSchemaProperties(schema);
3694
+ if (!props) {
3695
+ return [];
3696
+ }
3697
+ const names = [];
3698
+ for (const key of Object.keys(props)) {
3699
+ const prop = unwrapJsonSchema(props[key]);
3700
+ if ((prop == null ? void 0 : prop.type) === "string") {
3701
+ names.push(key);
373
3702
  }
374
- controller.enqueue({
375
- type: "text-delta",
376
- id: state.currentTextId,
377
- delta: text
378
- });
379
3703
  }
3704
+ return names;
380
3705
  }
381
- function emitToolCall(context) {
3706
+ function escapeRegExp2(s) {
3707
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3708
+ }
3709
+ function dedupeSingleTag(xml, key) {
382
3710
  var _a, _b;
383
- const { state, controller, toolCallStart, toolCallEnd, options } = context;
384
- try {
385
- const parsedToolCall = (0, import_rjson.parse)(state.currentToolCallJson);
386
- closeTextBlock(state, controller);
387
- controller.enqueue({
388
- type: "tool-call",
389
- toolCallId: generateId(),
390
- toolName: parsedToolCall.name,
391
- input: JSON.stringify((_a = parsedToolCall.arguments) != null ? _a : {})
392
- });
393
- } catch (error) {
394
- logParseFailure({
395
- phase: "stream",
396
- reason: "Failed to parse streaming tool call JSON segment",
397
- snippet: `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`,
398
- error
399
- });
400
- const errorId = generateId();
401
- const errorContent = `${toolCallStart}${state.currentToolCallJson}${toolCallEnd}`;
402
- controller.enqueue({
403
- type: "text-start",
404
- id: errorId
405
- });
406
- controller.enqueue({
407
- type: "text-delta",
408
- id: errorId,
409
- delta: errorContent
410
- });
411
- controller.enqueue({
412
- type: "text-end",
413
- id: errorId
414
- });
415
- (_b = options == null ? void 0 : options.onError) == null ? void 0 : _b.call(
416
- options,
417
- "Could not process streaming JSON tool call; emitting original text.",
418
- {
419
- toolCall: errorContent
420
- }
421
- );
3711
+ const escaped = escapeRegExp2(key);
3712
+ const re = new RegExp(`<${escaped}>([\\s\\S]*?)<\\/${escaped}>`, "g");
3713
+ const matches = Array.from(xml.matchAll(re));
3714
+ if (matches.length <= 1) {
3715
+ return xml;
3716
+ }
3717
+ const last = matches.at(-1);
3718
+ let result = "";
3719
+ let cursor = 0;
3720
+ for (const m of matches) {
3721
+ const idx = (_a = m.index) != null ? _a : 0;
3722
+ result += xml.slice(cursor, idx);
3723
+ if (last && idx === ((_b = last.index) != null ? _b : -1)) {
3724
+ result += m[0];
3725
+ }
3726
+ cursor = idx + m[0].length;
422
3727
  }
3728
+ result += xml.slice(cursor);
3729
+ return result;
423
3730
  }
424
- function processTagMatch(context) {
425
- const { state } = context;
426
- if (state.isInsideToolCall) {
427
- emitToolCall(context);
428
- state.currentToolCallJson = "";
429
- state.isInsideToolCall = false;
430
- } else {
431
- state.currentToolCallJson = "";
432
- state.isInsideToolCall = true;
3731
+ function repairParsedAgainstSchema(input, schema) {
3732
+ if (!input || typeof input !== "object") {
3733
+ return input;
3734
+ }
3735
+ const properties = extractSchemaProperties(schema);
3736
+ if (!properties) {
3737
+ return input;
433
3738
  }
3739
+ applySchemaProps(input, properties);
3740
+ return input;
434
3741
  }
435
- function processBufferTags(context) {
436
- const { state, controller, toolCallStart, toolCallEnd } = context;
437
- let startIndex = getPotentialStartIndex(
438
- state.buffer,
439
- state.isInsideToolCall ? toolCallEnd : toolCallStart
440
- );
441
- while (startIndex != null) {
442
- const tag = state.isInsideToolCall ? toolCallEnd : toolCallStart;
443
- if (startIndex + tag.length > state.buffer.length) {
444
- break;
3742
+ function applySchemaProps(obj, properties) {
3743
+ for (const key of Object.keys(obj)) {
3744
+ const propSchema = properties[key];
3745
+ if (!propSchema) {
3746
+ continue;
3747
+ }
3748
+ const prop = unwrapJsonSchema(propSchema);
3749
+ if ((prop == null ? void 0 : prop.type) === "array" && prop.items) {
3750
+ const itemSchema = unwrapJsonSchema(prop.items);
3751
+ obj[key] = coerceArrayItems(obj[key], itemSchema);
3752
+ continue;
3753
+ }
3754
+ if ((prop == null ? void 0 : prop.type) === "object") {
3755
+ const val = obj[key];
3756
+ if (val && typeof val === "object") {
3757
+ obj[key] = repairParsedAgainstSchema(val, prop);
3758
+ }
445
3759
  }
446
- publishText(state.buffer.slice(0, startIndex), state, controller);
447
- state.buffer = state.buffer.slice(startIndex + tag.length);
448
- processTagMatch(context);
449
- startIndex = getPotentialStartIndex(
450
- state.buffer,
451
- state.isInsideToolCall ? toolCallEnd : toolCallStart
452
- );
453
3760
  }
454
3761
  }
455
- function handlePartialTag(state, controller, toolCallStart) {
456
- if (state.isInsideToolCall) {
457
- return;
458
- }
459
- const potentialIndex = getPotentialStartIndex(state.buffer, toolCallStart);
460
- if (potentialIndex != null && potentialIndex + toolCallStart.length > state.buffer.length) {
461
- publishText(state.buffer.slice(0, potentialIndex), state, controller);
462
- state.buffer = state.buffer.slice(potentialIndex);
463
- } else {
464
- publishText(state.buffer, state, controller);
465
- state.buffer = "";
3762
+ function coerceArrayItems(val, itemSchema) {
3763
+ if (!Array.isArray(val)) {
3764
+ return val;
466
3765
  }
3766
+ return val.map((v) => coerceArrayItem(v, itemSchema));
467
3767
  }
468
- var jsonProtocol = ({
469
- toolCallStart = "<tool_call>",
470
- toolCallEnd = "</tool_call>"
471
- } = {}) => ({
472
- formatTools({
473
- tools,
474
- toolSystemPromptTemplate
475
- }) {
476
- return toolSystemPromptTemplate(tools || []);
477
- },
478
- formatToolCall(toolCall) {
479
- let args = {};
480
- if (toolCall.input != null) {
481
- try {
482
- args = JSON.parse(toolCall.input);
483
- } catch (e) {
484
- args = toolCall.input;
485
- }
3768
+ function coerceArrayItem(v, itemSchema) {
3769
+ const itemType = itemSchema == null ? void 0 : itemSchema.type;
3770
+ if (typeof v === "string" && itemType === "object") {
3771
+ const parsed = tryParseStringToSchemaObject(v, itemSchema);
3772
+ if (parsed !== null) {
3773
+ return parsed;
486
3774
  }
487
- return `${toolCallStart}${JSON.stringify({
488
- name: toolCall.toolName,
489
- arguments: args
490
- })}${toolCallEnd}`;
491
- },
492
- parseGeneratedText({
493
- text,
494
- options
495
- }) {
496
- const startEsc = escapeRegExp(toolCallStart);
497
- const endEsc = escapeRegExp(toolCallEnd);
498
- const toolCallRegex = new RegExp(
499
- `${startEsc}([\0-\uFFFF]*?)${endEsc}`,
500
- "gs"
3775
+ const fallback = extractStepStatusFromString(
3776
+ v.replace(MALFORMED_CLOSE_RE_G, "</$1>")
501
3777
  );
502
- const processedElements = [];
503
- let currentIndex = 0;
504
- let match = toolCallRegex.exec(text);
505
- while (match !== null) {
506
- currentIndex = processMatchedToolCall({
507
- match,
508
- text,
509
- currentIndex,
510
- processedElements,
511
- options
512
- });
513
- match = toolCallRegex.exec(text);
514
- }
515
- if (currentIndex < text.length) {
516
- const remainingText = text.substring(currentIndex);
517
- addTextSegment(remainingText, processedElements);
518
- }
519
- return processedElements;
520
- },
521
- createStreamParser({
522
- options
523
- }) {
524
- const state = {
525
- isInsideToolCall: false,
526
- buffer: "",
527
- currentToolCallJson: "",
528
- currentTextId: null,
529
- hasEmittedTextStart: false
530
- };
531
- return new TransformStream({
532
- transform(chunk, controller) {
533
- var _a;
534
- if (chunk.type === "finish") {
535
- handleFinishChunk(state, controller, toolCallStart, chunk);
536
- return;
537
- }
538
- if (chunk.type !== "text-delta") {
539
- controller.enqueue(chunk);
540
- return;
541
- }
542
- const textContent = (_a = chunk.delta) != null ? _a : "";
543
- state.buffer += textContent;
544
- processBufferTags({
545
- state,
546
- controller,
547
- toolCallStart,
548
- toolCallEnd,
549
- options
550
- });
551
- handlePartialTag(state, controller, toolCallStart);
552
- }
553
- });
554
- },
555
- extractToolCallSegments({ text }) {
556
- const startEsc = escapeRegExp(toolCallStart);
557
- const endEsc = escapeRegExp(toolCallEnd);
558
- const regex = new RegExp(`${startEsc}([\0-\uFFFF]*?)${endEsc}`, "gs");
559
- const segments = [];
560
- let m = regex.exec(text);
561
- while (m != null) {
562
- segments.push(m[0]);
563
- m = regex.exec(text);
3778
+ if (fallback) {
3779
+ return fallback;
564
3780
  }
565
- return segments;
3781
+ return v;
566
3782
  }
567
- });
568
-
569
- // src/core/protocols/protocol-interface.ts
570
- function isProtocolFactory(protocol) {
571
- return typeof protocol === "function";
3783
+ if (v && typeof v === "object" && itemType === "object") {
3784
+ return repairParsedAgainstSchema(v, itemSchema);
3785
+ }
3786
+ return v;
572
3787
  }
573
- function isTCMProtocolFactory(protocol) {
574
- return typeof protocol === "function";
3788
+ function tryParseStringToSchemaObject(xml, itemSchema) {
3789
+ try {
3790
+ const normalized = xml.replace(MALFORMED_CLOSE_RE_G, "</$1>");
3791
+ const fixed = parse2(normalized, itemSchema, { noChildNodes: [] });
3792
+ return typeof fixed === "string" ? null : fixed;
3793
+ } catch (e) {
3794
+ return null;
3795
+ }
3796
+ }
3797
+ function extractStepStatusFromString(normXml) {
3798
+ const stepMatch = normXml.match(STEP_TAG_RE);
3799
+ const statusMatch = normXml.match(STATUS_TAG_RE);
3800
+ if (stepMatch && statusMatch) {
3801
+ return { step: stepMatch[1], status: statusMatch[1] };
3802
+ }
3803
+ return null;
3804
+ }
3805
+
3806
+ // src/rxml/parse.ts
3807
+ function parse3(xml, schema, options = {}) {
3808
+ if (!options.repair) {
3809
+ return parse2(xml, schema, options);
3810
+ }
3811
+ const baseOptions = {
3812
+ ...options,
3813
+ repair: false
3814
+ };
3815
+ const ctx = createIntermediateCall("", xml, schema);
3816
+ const result = applyHeuristicPipeline(ctx, defaultPipelineConfig, {
3817
+ parse: (raw, s) => parse2(raw, s, baseOptions),
3818
+ onError: options.onError,
3819
+ maxReparses: options.maxReparses
3820
+ });
3821
+ if (result.parsed !== null) {
3822
+ return result.parsed;
3823
+ }
3824
+ const error = result.errors[0];
3825
+ throw new RXMLParseError("Failed to parse XML with repair heuristics", error);
575
3826
  }
576
3827
 
577
3828
  // src/core/protocols/xml-protocol.ts
578
- var import_rxml = require("@ai-sdk-tool/rxml");
579
- var NAME_CHAR_RE = /[A-Za-z0-9_:-]/;
580
- var WHITESPACE_REGEX = /\s/;
3829
+ var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
3830
+ var WHITESPACE_REGEX4 = /\s/;
581
3831
  function getToolSchema(tools, toolName) {
582
3832
  var _a;
583
3833
  return (_a = tools.find((t) => t.name === toolName)) == null ? void 0 : _a.inputSchema;
@@ -591,7 +3841,7 @@ function processToolCall(params) {
591
3841
  onError: (_a = options == null ? void 0 : options.onError) != null ? _a : parseOptions == null ? void 0 : parseOptions.onError
592
3842
  };
593
3843
  try {
594
- const parsed = (0, import_rxml.parse)(toolCall.content, toolSchema, parseConfig);
3844
+ const parsed = parse3(toolCall.content, toolSchema, parseConfig);
595
3845
  processedElements.push({
596
3846
  type: "tool-call",
597
3847
  toolCallId: generateId(),
@@ -629,7 +3879,7 @@ function handleStreamingToolCallEnd(params) {
629
3879
  };
630
3880
  flushText(ctrl);
631
3881
  try {
632
- const parsedResult = (0, import_rxml.parse)(toolContent, toolSchema, parseConfig);
3882
+ const parsedResult = parse3(toolContent, toolSchema, parseConfig);
633
3883
  ctrl.enqueue({
634
3884
  type: "tool-call",
635
3885
  toolCallId: generateId(),
@@ -679,11 +3929,11 @@ function consumeClosingTag(text, lt) {
679
3929
  }
680
3930
  function consumeOpenTag(text, lt) {
681
3931
  let p = lt + 1;
682
- while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
3932
+ while (p < text.length && WHITESPACE_REGEX4.test(text[p])) {
683
3933
  p += 1;
684
3934
  }
685
3935
  const nameStart = p;
686
- while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
3936
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
687
3937
  p += 1;
688
3938
  }
689
3939
  const name = text.slice(nameStart, p);
@@ -692,7 +3942,7 @@ function consumeOpenTag(text, lt) {
692
3942
  return null;
693
3943
  }
694
3944
  let r = q - 1;
695
- while (r >= nameStart && WHITESPACE_REGEX.test(text[r])) {
3945
+ while (r >= nameStart && WHITESPACE_REGEX4.test(text[r])) {
696
3946
  r -= 1;
697
3947
  }
698
3948
  const selfClosing = text[r] === "/";
@@ -721,11 +3971,11 @@ function nextTagToken(text, fromPos) {
721
3971
  if (next === "/") {
722
3972
  const closing = consumeClosingTag(text, lt);
723
3973
  let p = lt + 2;
724
- while (p < text.length && WHITESPACE_REGEX.test(text[p])) {
3974
+ while (p < text.length && WHITESPACE_REGEX4.test(text[p])) {
725
3975
  p += 1;
726
3976
  }
727
3977
  const nameStart = p;
728
- while (p < text.length && NAME_CHAR_RE.test(text.charAt(p))) {
3978
+ while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
729
3979
  p += 1;
730
3980
  }
731
3981
  const name = text.slice(nameStart, p);
@@ -896,7 +4146,7 @@ function isOpenTagPrefix(suffix, toolName) {
896
4146
  }
897
4147
  function consumeWhitespace(text, index) {
898
4148
  let i = index;
899
- while (i < text.length && WHITESPACE_REGEX.test(text.charAt(i))) {
4149
+ while (i < text.length && WHITESPACE_REGEX4.test(text.charAt(i))) {
900
4150
  i += 1;
901
4151
  }
902
4152
  return i;
@@ -1167,7 +4417,7 @@ var xmlProtocol = (protocolOptions) => {
1167
4417
  args = toolCall.input;
1168
4418
  }
1169
4419
  }
1170
- return (0, import_rxml.stringify)(toolCall.toolName, args, {
4420
+ return stringify2(toolCall.toolName, args, {
1171
4421
  suppressEmptyNode: false,
1172
4422
  format: true,
1173
4423
  minimalEscaping: true
@@ -1285,8 +4535,8 @@ var xmlProtocol = (protocolOptions) => {
1285
4535
 
1286
4536
  // src/core/protocols/yaml-protocol.ts
1287
4537
  var import_yaml = __toESM(require("yaml"), 1);
1288
- var NAME_CHAR_RE2 = /[A-Za-z0-9_:-]/;
1289
- var WHITESPACE_REGEX2 = /\s/;
4538
+ var NAME_CHAR_RE3 = /[A-Za-z0-9_:-]/;
4539
+ var WHITESPACE_REGEX5 = /\s/;
1290
4540
  var LEADING_WHITESPACE_RE = /^(\s*)/;
1291
4541
  function findClosingTagEnd(text, contentStart, toolName) {
1292
4542
  let pos = contentStart;
@@ -1303,11 +4553,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
1303
4553
  break;
1304
4554
  }
1305
4555
  let p = ltIdx + 2;
1306
- while (p < gtIdx && WHITESPACE_REGEX2.test(text[p])) {
4556
+ while (p < gtIdx && WHITESPACE_REGEX5.test(text[p])) {
1307
4557
  p++;
1308
4558
  }
1309
4559
  const nameStart = p;
1310
- while (p < gtIdx && NAME_CHAR_RE2.test(text.charAt(p))) {
4560
+ while (p < gtIdx && NAME_CHAR_RE3.test(text.charAt(p))) {
1311
4561
  p++;
1312
4562
  }
1313
4563
  const name = text.slice(nameStart, p);
@@ -1323,11 +4573,11 @@ function findClosingTagEnd(text, contentStart, toolName) {
1323
4573
  pos = gtIdx === -1 ? text.length : gtIdx + 1;
1324
4574
  } else {
1325
4575
  let p = ltIdx + 1;
1326
- while (p < text.length && WHITESPACE_REGEX2.test(text[p])) {
4576
+ while (p < text.length && WHITESPACE_REGEX5.test(text[p])) {
1327
4577
  p++;
1328
4578
  }
1329
4579
  const nameStart = p;
1330
- while (p < text.length && NAME_CHAR_RE2.test(text.charAt(p))) {
4580
+ while (p < text.length && NAME_CHAR_RE3.test(text.charAt(p))) {
1331
4581
  p++;
1332
4582
  }
1333
4583
  const name = text.slice(nameStart, p);
@@ -1336,7 +4586,7 @@ function findClosingTagEnd(text, contentStart, toolName) {
1336
4586
  break;
1337
4587
  }
1338
4588
  let r = gtIdx - 1;
1339
- while (r >= nameStart && WHITESPACE_REGEX2.test(text[r])) {
4589
+ while (r >= nameStart && WHITESPACE_REGEX5.test(text[r])) {
1340
4590
  r--;
1341
4591
  }
1342
4592
  const selfClosing = text[r] === "/";
@@ -1841,7 +5091,6 @@ function hasInputProperty(obj) {
1841
5091
 
1842
5092
  // src/generate-handler.ts
1843
5093
  var import_provider_utils = require("@ai-sdk/provider-utils");
1844
- var import_schema_coerce = require("@ai-sdk-tool/schema-coerce");
1845
5094
  function parseToolChoiceJson(text, providerOptions) {
1846
5095
  var _a;
1847
5096
  try {
@@ -2003,7 +5252,7 @@ function fixToolCallWithSchema(part, tools) {
2003
5252
  args = part.input;
2004
5253
  }
2005
5254
  const schema = (_a = tools.find((t) => t.name === part.toolName)) == null ? void 0 : _a.inputSchema;
2006
- const coerced = (0, import_schema_coerce.coerceBySchema)(args, schema);
5255
+ const coerced = coerceBySchema(args, schema);
2007
5256
  return {
2008
5257
  ...part,
2009
5258
  input: JSON.stringify(coerced != null ? coerced : {})
@@ -2928,14 +6177,16 @@ var yamlToolMiddleware = createToolMiddleware({
2928
6177
  logParsedSummary,
2929
6178
  logRawChunk,
2930
6179
  originalToolsSchema,
6180
+ parse,
6181
+ stringify,
2931
6182
  toolChoiceStream,
6183
+ transform,
2932
6184
  transformParams,
2933
6185
  wrapGenerate,
2934
6186
  wrapStream,
2935
6187
  xmlProtocol,
2936
6188
  xmlToolMiddleware,
2937
6189
  yamlProtocol,
2938
- yamlToolMiddleware,
2939
- ...require("@ai-sdk-tool/rjson")
6190
+ yamlToolMiddleware
2940
6191
  });
2941
6192
  //# sourceMappingURL=index.cjs.map