@abapify/ts-xsd 0.4.0 → 0.4.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.
@@ -0,0 +1,2651 @@
1
+ import { DOMParser } from "@xmldom/xmldom";
2
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
4
+
5
+ //#region src/xml/dom-utils.ts
6
+ /**
7
+ * Type guard to check if a Node is an Element
8
+ */
9
+ function isElement(node) {
10
+ return node.nodeType === 1;
11
+ }
12
+ /**
13
+ * Get attribute value, handling namespaced attributes
14
+ * Tries direct attribute first, then searches by local name
15
+ */
16
+ function getAttributeValue(node, name) {
17
+ if (node.hasAttribute(name)) return node.getAttribute(name);
18
+ for (let i = 0; i < node.attributes.length; i++) {
19
+ const attr = node.attributes[i];
20
+ if ((attr.localName || attr.name.split(":").pop()) === name) return attr.value;
21
+ }
22
+ return null;
23
+ }
24
+ /**
25
+ * Get child elements by local name (namespace-agnostic)
26
+ */
27
+ function getChildElements(parent, name) {
28
+ const result = [];
29
+ for (let i = 0; i < parent.childNodes.length; i++) {
30
+ const child = parent.childNodes[i];
31
+ if (isElement(child)) {
32
+ if ((child.localName || child.tagName.split(":").pop()) === name) result.push(child);
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+ /**
38
+ * Get all child elements (any name)
39
+ */
40
+ function getAllChildElements(parent) {
41
+ const result = [];
42
+ for (let i = 0; i < parent.childNodes.length; i++) {
43
+ const child = parent.childNodes[i];
44
+ if (isElement(child)) result.push(child);
45
+ }
46
+ return result;
47
+ }
48
+ /**
49
+ * Get text content of an element (concatenates all text nodes)
50
+ */
51
+ function getTextContent(node) {
52
+ let text = "";
53
+ for (let i = 0; i < node.childNodes.length; i++) {
54
+ const child = node.childNodes[i];
55
+ if (child.nodeType === 3) text += child.textContent || "";
56
+ }
57
+ return text.trim();
58
+ }
59
+ /**
60
+ * Get local name of an element (strips namespace prefix)
61
+ */
62
+ function getLocalName(node) {
63
+ return node.localName || node.tagName.split(":").pop() || node.tagName;
64
+ }
65
+
66
+ //#endregion
67
+ //#region src/xsd/parse.ts
68
+ /**
69
+ * XSD Parser - Parse XSD documents to typed Schema objects
70
+ *
71
+ * This parser understands XSD semantics and produces correctly typed output
72
+ * matching the W3C XMLSchema.xsd specification.
73
+ *
74
+ * No intermediate JSON - direct XSD to typed objects.
75
+ */
76
+ /**
77
+ * Parse an XSD string to a typed Schema object
78
+ */
79
+ function parseXsd(xml) {
80
+ const root = new DOMParser().parseFromString(xml, "text/xml").documentElement;
81
+ if (!root || getLocalName(root) !== "schema") throw new Error("Invalid XSD: root element must be xs:schema");
82
+ return parseSchema(root);
83
+ }
84
+ function parseSchema(el) {
85
+ const schema = {};
86
+ copyXmlns(el, schema);
87
+ copyAttr(el, schema, "id");
88
+ copyAttr(el, schema, "targetNamespace");
89
+ copyAttr(el, schema, "version");
90
+ copyAttr(el, schema, "finalDefault");
91
+ copyAttr(el, schema, "blockDefault");
92
+ copyAttr(el, schema, "attributeFormDefault");
93
+ copyAttr(el, schema, "elementFormDefault");
94
+ copyAttr(el, schema, "defaultAttributes");
95
+ copyAttr(el, schema, "xpathDefaultNamespace");
96
+ copyAttr(el, schema, "xml:lang");
97
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
98
+ case "annotation":
99
+ pushTo(schema, "annotation", parseAnnotation(child));
100
+ break;
101
+ case "include":
102
+ pushTo(schema, "include", parseInclude(child));
103
+ break;
104
+ case "import":
105
+ pushTo(schema, "import", parseImport(child));
106
+ break;
107
+ case "redefine":
108
+ pushTo(schema, "redefine", parseRedefine(child));
109
+ break;
110
+ case "override":
111
+ pushTo(schema, "override", parseOverride(child));
112
+ break;
113
+ case "element":
114
+ pushTo(schema, "element", parseTopLevelElement(child));
115
+ break;
116
+ case "attribute":
117
+ pushTo(schema, "attribute", parseTopLevelAttribute(child));
118
+ break;
119
+ case "simpleType":
120
+ pushTo(schema, "simpleType", parseTopLevelSimpleType(child));
121
+ break;
122
+ case "complexType":
123
+ pushTo(schema, "complexType", parseTopLevelComplexType(child));
124
+ break;
125
+ case "group":
126
+ pushTo(schema, "group", parseNamedGroup(child));
127
+ break;
128
+ case "attributeGroup":
129
+ pushTo(schema, "attributeGroup", parseNamedAttributeGroup(child));
130
+ break;
131
+ case "notation":
132
+ pushTo(schema, "notation", parseNotation(child));
133
+ break;
134
+ case "defaultOpenContent":
135
+ schema.defaultOpenContent = parseDefaultOpenContent(child);
136
+ break;
137
+ }
138
+ return schema;
139
+ }
140
+ function parseAnnotation(el) {
141
+ const result = {};
142
+ copyAttr(el, result, "id");
143
+ for (const child of getAllChildElements(el)) {
144
+ const name = getLocalName(child);
145
+ if (name === "documentation") pushTo(result, "documentation", parseDocumentation(child));
146
+ else if (name === "appinfo") pushTo(result, "appinfo", parseAppinfo(child));
147
+ }
148
+ return result;
149
+ }
150
+ function parseDocumentation(el) {
151
+ const result = {};
152
+ copyAttr(el, result, "source");
153
+ copyAttr(el, result, "xml:lang");
154
+ const text = getTextContent(el);
155
+ if (text) result._text = text;
156
+ return result;
157
+ }
158
+ function parseAppinfo(el) {
159
+ const result = {};
160
+ copyAttr(el, result, "source");
161
+ const text = getTextContent(el);
162
+ if (text) result._text = text;
163
+ return result;
164
+ }
165
+ function parseInclude(el) {
166
+ const result = { schemaLocation: "" };
167
+ copyAttr(el, result, "id");
168
+ copyAttr(el, result, "schemaLocation");
169
+ parseAnnotationChild(el, result);
170
+ return result;
171
+ }
172
+ function parseImport(el) {
173
+ const result = {};
174
+ copyAttr(el, result, "id");
175
+ copyAttr(el, result, "namespace");
176
+ copyAttr(el, result, "schemaLocation");
177
+ parseAnnotationChild(el, result);
178
+ return result;
179
+ }
180
+ function parseRedefine(el) {
181
+ const result = { schemaLocation: "" };
182
+ copyAttr(el, result, "id");
183
+ copyAttr(el, result, "schemaLocation");
184
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
185
+ case "annotation":
186
+ pushTo(result, "annotation", parseAnnotation(child));
187
+ break;
188
+ case "simpleType":
189
+ pushTo(result, "simpleType", parseTopLevelSimpleType(child));
190
+ break;
191
+ case "complexType":
192
+ pushTo(result, "complexType", parseTopLevelComplexType(child));
193
+ break;
194
+ case "group":
195
+ pushTo(result, "group", parseNamedGroup(child));
196
+ break;
197
+ case "attributeGroup":
198
+ pushTo(result, "attributeGroup", parseNamedAttributeGroup(child));
199
+ break;
200
+ }
201
+ return result;
202
+ }
203
+ function parseOverride(el) {
204
+ const result = { schemaLocation: "" };
205
+ copyAttr(el, result, "id");
206
+ copyAttr(el, result, "schemaLocation");
207
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
208
+ case "annotation":
209
+ pushTo(result, "annotation", parseAnnotation(child));
210
+ break;
211
+ case "simpleType":
212
+ pushTo(result, "simpleType", parseTopLevelSimpleType(child));
213
+ break;
214
+ case "complexType":
215
+ pushTo(result, "complexType", parseTopLevelComplexType(child));
216
+ break;
217
+ case "group":
218
+ pushTo(result, "group", parseNamedGroup(child));
219
+ break;
220
+ case "attributeGroup":
221
+ pushTo(result, "attributeGroup", parseNamedAttributeGroup(child));
222
+ break;
223
+ case "element":
224
+ pushTo(result, "element", parseTopLevelElement(child));
225
+ break;
226
+ case "attribute":
227
+ pushTo(result, "attribute", parseTopLevelAttribute(child));
228
+ break;
229
+ case "notation":
230
+ pushTo(result, "notation", parseNotation(child));
231
+ break;
232
+ }
233
+ return result;
234
+ }
235
+ function parseTopLevelElement(el) {
236
+ const result = { name: "" };
237
+ copyAttr(el, result, "id");
238
+ copyAttr(el, result, "name");
239
+ copyAttr(el, result, "type");
240
+ copyAttr(el, result, "substitutionGroup");
241
+ copyAttr(el, result, "default");
242
+ copyAttr(el, result, "fixed");
243
+ copyBoolAttr(el, result, "nillable");
244
+ copyBoolAttr(el, result, "abstract");
245
+ copyAttr(el, result, "final");
246
+ copyAttr(el, result, "block");
247
+ parseAnnotationChild(el, result);
248
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
249
+ case "simpleType":
250
+ result.simpleType = parseLocalSimpleType(child);
251
+ break;
252
+ case "complexType":
253
+ result.complexType = parseLocalComplexType(child);
254
+ break;
255
+ case "unique":
256
+ pushTo(result, "unique", parseUnique(child));
257
+ break;
258
+ case "key":
259
+ pushTo(result, "key", parseKey(child));
260
+ break;
261
+ case "keyref":
262
+ pushTo(result, "keyref", parseKeyref(child));
263
+ break;
264
+ case "alternative":
265
+ pushTo(result, "alternative", parseAlternative(child));
266
+ break;
267
+ }
268
+ return result;
269
+ }
270
+ function parseLocalElement(el) {
271
+ const result = {};
272
+ copyAttr(el, result, "id");
273
+ copyAttr(el, result, "name");
274
+ copyAttr(el, result, "ref");
275
+ copyAttr(el, result, "type");
276
+ copyAttr(el, result, "minOccurs");
277
+ copyAttr(el, result, "maxOccurs");
278
+ copyAttr(el, result, "default");
279
+ copyAttr(el, result, "fixed");
280
+ copyBoolAttr(el, result, "nillable");
281
+ copyAttr(el, result, "block");
282
+ copyAttr(el, result, "form");
283
+ copyAttr(el, result, "targetNamespace");
284
+ parseAnnotationChild(el, result);
285
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
286
+ case "simpleType":
287
+ result.simpleType = parseLocalSimpleType(child);
288
+ break;
289
+ case "complexType":
290
+ result.complexType = parseLocalComplexType(child);
291
+ break;
292
+ case "unique":
293
+ pushTo(result, "unique", parseUnique(child));
294
+ break;
295
+ case "key":
296
+ pushTo(result, "key", parseKey(child));
297
+ break;
298
+ case "keyref":
299
+ pushTo(result, "keyref", parseKeyref(child));
300
+ break;
301
+ case "alternative":
302
+ pushTo(result, "alternative", parseAlternative(child));
303
+ break;
304
+ }
305
+ return result;
306
+ }
307
+ function parseTopLevelAttribute(el) {
308
+ const result = { name: "" };
309
+ copyAttr(el, result, "id");
310
+ copyAttr(el, result, "name");
311
+ copyAttr(el, result, "type");
312
+ copyAttr(el, result, "default");
313
+ copyAttr(el, result, "fixed");
314
+ copyBoolAttr(el, result, "inheritable");
315
+ parseAnnotationChild(el, result);
316
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "simpleType") result.simpleType = parseLocalSimpleType(child);
317
+ return result;
318
+ }
319
+ function parseLocalAttribute(el) {
320
+ const result = {};
321
+ copyAttr(el, result, "id");
322
+ copyAttr(el, result, "name");
323
+ copyAttr(el, result, "ref");
324
+ copyAttr(el, result, "type");
325
+ copyAttr(el, result, "use");
326
+ copyAttr(el, result, "default");
327
+ copyAttr(el, result, "fixed");
328
+ copyAttr(el, result, "form");
329
+ copyAttr(el, result, "targetNamespace");
330
+ copyBoolAttr(el, result, "inheritable");
331
+ parseAnnotationChild(el, result);
332
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "simpleType") result.simpleType = parseLocalSimpleType(child);
333
+ return result;
334
+ }
335
+ function parseTopLevelComplexType(el) {
336
+ const result = { name: "" };
337
+ copyAttr(el, result, "id");
338
+ copyAttr(el, result, "name");
339
+ copyBoolAttr(el, result, "mixed");
340
+ copyBoolAttr(el, result, "abstract");
341
+ copyAttr(el, result, "final");
342
+ copyAttr(el, result, "block");
343
+ copyBoolAttr(el, result, "defaultAttributesApply");
344
+ parseAnnotationChild(el, result);
345
+ parseComplexTypeContent(el, result);
346
+ return result;
347
+ }
348
+ function parseLocalComplexType(el) {
349
+ const result = {};
350
+ copyAttr(el, result, "id");
351
+ copyBoolAttr(el, result, "mixed");
352
+ parseAnnotationChild(el, result);
353
+ parseComplexTypeContent(el, result);
354
+ return result;
355
+ }
356
+ function parseComplexTypeContent(el, result) {
357
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
358
+ case "simpleContent":
359
+ result.simpleContent = parseSimpleContent(child);
360
+ break;
361
+ case "complexContent":
362
+ result.complexContent = parseComplexContent(child);
363
+ break;
364
+ case "openContent":
365
+ result.openContent = parseOpenContent(child);
366
+ break;
367
+ case "group":
368
+ result.group = parseGroupRef(child);
369
+ break;
370
+ case "all":
371
+ result.all = parseAll(child);
372
+ break;
373
+ case "choice":
374
+ result.choice = parseExplicitGroup(child);
375
+ break;
376
+ case "sequence":
377
+ result.sequence = parseExplicitGroup(child);
378
+ break;
379
+ case "attribute":
380
+ pushTo(result, "attribute", parseLocalAttribute(child));
381
+ break;
382
+ case "attributeGroup":
383
+ pushTo(result, "attributeGroup", parseAttributeGroupRef(child));
384
+ break;
385
+ case "anyAttribute":
386
+ result.anyAttribute = parseAnyAttribute(child);
387
+ break;
388
+ case "assert":
389
+ pushTo(result, "assert", parseAssertion(child));
390
+ break;
391
+ }
392
+ }
393
+ function parseTopLevelSimpleType(el) {
394
+ const result = { name: "" };
395
+ copyAttr(el, result, "id");
396
+ copyAttr(el, result, "name");
397
+ copyAttr(el, result, "final");
398
+ parseAnnotationChild(el, result);
399
+ parseSimpleTypeContent(el, result);
400
+ return result;
401
+ }
402
+ function parseLocalSimpleType(el) {
403
+ const result = {};
404
+ copyAttr(el, result, "id");
405
+ parseAnnotationChild(el, result);
406
+ parseSimpleTypeContent(el, result);
407
+ return result;
408
+ }
409
+ function parseSimpleTypeContent(el, result) {
410
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
411
+ case "restriction":
412
+ result.restriction = parseSimpleTypeRestriction(child);
413
+ break;
414
+ case "list":
415
+ result.list = parseList(child);
416
+ break;
417
+ case "union":
418
+ result.union = parseUnion(child);
419
+ break;
420
+ }
421
+ }
422
+ function parseSimpleTypeRestriction(el) {
423
+ const result = {};
424
+ copyAttr(el, result, "id");
425
+ copyAttr(el, result, "base");
426
+ parseAnnotationChild(el, result);
427
+ for (const child of getAllChildElements(el)) {
428
+ const name = getLocalName(child);
429
+ switch (name) {
430
+ case "simpleType":
431
+ result.simpleType = parseLocalSimpleType(child);
432
+ break;
433
+ case "minExclusive":
434
+ case "minInclusive":
435
+ case "maxExclusive":
436
+ case "maxInclusive":
437
+ case "totalDigits":
438
+ case "fractionDigits":
439
+ case "length":
440
+ case "minLength":
441
+ case "maxLength":
442
+ case "enumeration":
443
+ case "whiteSpace":
444
+ case "explicitTimezone":
445
+ pushTo(result, name, parseFacet(child));
446
+ break;
447
+ case "pattern":
448
+ pushTo(result, "pattern", parsePattern(child));
449
+ break;
450
+ case "assertion":
451
+ pushTo(result, "assertion", parseAssertion(child));
452
+ break;
453
+ }
454
+ }
455
+ return result;
456
+ }
457
+ function parseList(el) {
458
+ const result = {};
459
+ copyAttr(el, result, "id");
460
+ copyAttr(el, result, "itemType");
461
+ parseAnnotationChild(el, result);
462
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "simpleType") result.simpleType = parseLocalSimpleType(child);
463
+ return result;
464
+ }
465
+ function parseUnion(el) {
466
+ const result = {};
467
+ copyAttr(el, result, "id");
468
+ copyAttr(el, result, "memberTypes");
469
+ parseAnnotationChild(el, result);
470
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "simpleType") pushTo(result, "simpleType", parseLocalSimpleType(child));
471
+ return result;
472
+ }
473
+ function parseFacet(el) {
474
+ const result = { value: "" };
475
+ copyAttr(el, result, "id");
476
+ copyAttr(el, result, "value");
477
+ copyBoolAttr(el, result, "fixed");
478
+ parseAnnotationChild(el, result);
479
+ return result;
480
+ }
481
+ function parsePattern(el) {
482
+ const result = { value: "" };
483
+ copyAttr(el, result, "id");
484
+ copyAttr(el, result, "value");
485
+ parseAnnotationChild(el, result);
486
+ return result;
487
+ }
488
+ function parseComplexContent(el) {
489
+ const result = {};
490
+ copyAttr(el, result, "id");
491
+ copyBoolAttr(el, result, "mixed");
492
+ parseAnnotationChild(el, result);
493
+ for (const child of getAllChildElements(el)) {
494
+ const name = getLocalName(child);
495
+ if (name === "restriction") result.restriction = parseComplexContentRestriction(child);
496
+ else if (name === "extension") result.extension = parseComplexContentExtension(child);
497
+ }
498
+ return result;
499
+ }
500
+ function parseSimpleContent(el) {
501
+ const result = {};
502
+ copyAttr(el, result, "id");
503
+ parseAnnotationChild(el, result);
504
+ for (const child of getAllChildElements(el)) {
505
+ const name = getLocalName(child);
506
+ if (name === "restriction") result.restriction = parseSimpleContentRestriction(child);
507
+ else if (name === "extension") result.extension = parseSimpleContentExtension(child);
508
+ }
509
+ return result;
510
+ }
511
+ function parseComplexContentRestriction(el) {
512
+ const result = { base: "" };
513
+ copyAttr(el, result, "id");
514
+ copyAttr(el, result, "base");
515
+ parseAnnotationChild(el, result);
516
+ parseComplexTypeContent(el, result);
517
+ return result;
518
+ }
519
+ function parseComplexContentExtension(el) {
520
+ const result = { base: "" };
521
+ copyAttr(el, result, "id");
522
+ copyAttr(el, result, "base");
523
+ parseAnnotationChild(el, result);
524
+ parseComplexTypeContent(el, result);
525
+ return result;
526
+ }
527
+ function parseSimpleContentRestriction(el) {
528
+ const result = { base: "" };
529
+ copyAttr(el, result, "id");
530
+ copyAttr(el, result, "base");
531
+ parseAnnotationChild(el, result);
532
+ for (const child of getAllChildElements(el)) {
533
+ const name = getLocalName(child);
534
+ switch (name) {
535
+ case "simpleType":
536
+ result.simpleType = parseLocalSimpleType(child);
537
+ break;
538
+ case "minExclusive":
539
+ case "minInclusive":
540
+ case "maxExclusive":
541
+ case "maxInclusive":
542
+ case "totalDigits":
543
+ case "fractionDigits":
544
+ case "length":
545
+ case "minLength":
546
+ case "maxLength":
547
+ case "enumeration":
548
+ case "whiteSpace":
549
+ case "explicitTimezone":
550
+ pushTo(result, name, parseFacet(child));
551
+ break;
552
+ case "pattern":
553
+ pushTo(result, "pattern", parsePattern(child));
554
+ break;
555
+ case "assertion":
556
+ pushTo(result, "assertion", parseAssertion(child));
557
+ break;
558
+ case "attribute":
559
+ pushTo(result, "attribute", parseLocalAttribute(child));
560
+ break;
561
+ case "attributeGroup":
562
+ pushTo(result, "attributeGroup", parseAttributeGroupRef(child));
563
+ break;
564
+ case "anyAttribute":
565
+ result.anyAttribute = parseAnyAttribute(child);
566
+ break;
567
+ case "assert":
568
+ pushTo(result, "assert", parseAssertion(child));
569
+ break;
570
+ }
571
+ }
572
+ return result;
573
+ }
574
+ function parseSimpleContentExtension(el) {
575
+ const result = { base: "" };
576
+ copyAttr(el, result, "id");
577
+ copyAttr(el, result, "base");
578
+ parseAnnotationChild(el, result);
579
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
580
+ case "attribute":
581
+ pushTo(result, "attribute", parseLocalAttribute(child));
582
+ break;
583
+ case "attributeGroup":
584
+ pushTo(result, "attributeGroup", parseAttributeGroupRef(child));
585
+ break;
586
+ case "anyAttribute":
587
+ result.anyAttribute = parseAnyAttribute(child);
588
+ break;
589
+ case "assert":
590
+ pushTo(result, "assert", parseAssertion(child));
591
+ break;
592
+ }
593
+ return result;
594
+ }
595
+ function parseExplicitGroup(el) {
596
+ const result = {};
597
+ copyAttr(el, result, "id");
598
+ copyAttr(el, result, "minOccurs");
599
+ copyAttr(el, result, "maxOccurs");
600
+ parseAnnotationChild(el, result);
601
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
602
+ case "element":
603
+ pushTo(result, "element", parseLocalElement(child));
604
+ break;
605
+ case "group":
606
+ pushTo(result, "group", parseGroupRef(child));
607
+ break;
608
+ case "choice":
609
+ pushTo(result, "choice", parseExplicitGroup(child));
610
+ break;
611
+ case "sequence":
612
+ pushTo(result, "sequence", parseExplicitGroup(child));
613
+ break;
614
+ case "any":
615
+ pushTo(result, "any", parseAny(child));
616
+ break;
617
+ }
618
+ return result;
619
+ }
620
+ function parseAll(el) {
621
+ const result = {};
622
+ copyAttr(el, result, "id");
623
+ copyAttr(el, result, "minOccurs");
624
+ copyAttr(el, result, "maxOccurs");
625
+ parseAnnotationChild(el, result);
626
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
627
+ case "element":
628
+ pushTo(result, "element", parseLocalElement(child));
629
+ break;
630
+ case "any":
631
+ pushTo(result, "any", parseAny(child));
632
+ break;
633
+ case "group":
634
+ pushTo(result, "group", parseGroupRef(child));
635
+ break;
636
+ }
637
+ return result;
638
+ }
639
+ function parseNamedGroup(el) {
640
+ const result = { name: "" };
641
+ copyAttr(el, result, "id");
642
+ copyAttr(el, result, "name");
643
+ parseAnnotationChild(el, result);
644
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
645
+ case "all":
646
+ result.all = parseAll(child);
647
+ break;
648
+ case "choice":
649
+ result.choice = parseExplicitGroup(child);
650
+ break;
651
+ case "sequence":
652
+ result.sequence = parseExplicitGroup(child);
653
+ break;
654
+ }
655
+ return result;
656
+ }
657
+ function parseGroupRef(el) {
658
+ const result = { ref: "" };
659
+ copyAttr(el, result, "id");
660
+ copyAttr(el, result, "ref");
661
+ copyAttr(el, result, "minOccurs");
662
+ copyAttr(el, result, "maxOccurs");
663
+ parseAnnotationChild(el, result);
664
+ return result;
665
+ }
666
+ function parseNamedAttributeGroup(el) {
667
+ const result = { name: "" };
668
+ copyAttr(el, result, "id");
669
+ copyAttr(el, result, "name");
670
+ parseAnnotationChild(el, result);
671
+ for (const child of getAllChildElements(el)) switch (getLocalName(child)) {
672
+ case "attribute":
673
+ pushTo(result, "attribute", parseLocalAttribute(child));
674
+ break;
675
+ case "attributeGroup":
676
+ pushTo(result, "attributeGroup", parseAttributeGroupRef(child));
677
+ break;
678
+ case "anyAttribute":
679
+ result.anyAttribute = parseAnyAttribute(child);
680
+ break;
681
+ }
682
+ return result;
683
+ }
684
+ function parseAttributeGroupRef(el) {
685
+ const result = { ref: "" };
686
+ copyAttr(el, result, "id");
687
+ copyAttr(el, result, "ref");
688
+ parseAnnotationChild(el, result);
689
+ return result;
690
+ }
691
+ function parseAny(el) {
692
+ const result = {};
693
+ copyAttr(el, result, "id");
694
+ copyAttr(el, result, "minOccurs");
695
+ copyAttr(el, result, "maxOccurs");
696
+ copyAttr(el, result, "namespace");
697
+ copyAttr(el, result, "processContents");
698
+ copyAttr(el, result, "notNamespace");
699
+ copyAttr(el, result, "notQName");
700
+ parseAnnotationChild(el, result);
701
+ return result;
702
+ }
703
+ function parseAnyAttribute(el) {
704
+ const result = {};
705
+ copyAttr(el, result, "id");
706
+ copyAttr(el, result, "namespace");
707
+ copyAttr(el, result, "processContents");
708
+ copyAttr(el, result, "notNamespace");
709
+ copyAttr(el, result, "notQName");
710
+ parseAnnotationChild(el, result);
711
+ return result;
712
+ }
713
+ function parseUnique(el) {
714
+ const result = { name: "" };
715
+ copyAttr(el, result, "id");
716
+ copyAttr(el, result, "name");
717
+ copyAttr(el, result, "ref");
718
+ parseAnnotationChild(el, result);
719
+ for (const child of getAllChildElements(el)) {
720
+ const name = getLocalName(child);
721
+ if (name === "selector") result.selector = parseSelector(child);
722
+ else if (name === "field") pushTo(result, "field", parseField(child));
723
+ }
724
+ return result;
725
+ }
726
+ function parseKey(el) {
727
+ const result = { name: "" };
728
+ copyAttr(el, result, "id");
729
+ copyAttr(el, result, "name");
730
+ copyAttr(el, result, "ref");
731
+ parseAnnotationChild(el, result);
732
+ for (const child of getAllChildElements(el)) {
733
+ const name = getLocalName(child);
734
+ if (name === "selector") result.selector = parseSelector(child);
735
+ else if (name === "field") pushTo(result, "field", parseField(child));
736
+ }
737
+ return result;
738
+ }
739
+ function parseKeyref(el) {
740
+ const result = {
741
+ name: "",
742
+ refer: ""
743
+ };
744
+ copyAttr(el, result, "id");
745
+ copyAttr(el, result, "name");
746
+ copyAttr(el, result, "ref");
747
+ copyAttr(el, result, "refer");
748
+ parseAnnotationChild(el, result);
749
+ for (const child of getAllChildElements(el)) {
750
+ const name = getLocalName(child);
751
+ if (name === "selector") result.selector = parseSelector(child);
752
+ else if (name === "field") pushTo(result, "field", parseField(child));
753
+ }
754
+ return result;
755
+ }
756
+ function parseSelector(el) {
757
+ const result = { xpath: "" };
758
+ copyAttr(el, result, "id");
759
+ copyAttr(el, result, "xpath");
760
+ copyAttr(el, result, "xpathDefaultNamespace");
761
+ parseAnnotationChild(el, result);
762
+ return result;
763
+ }
764
+ function parseField(el) {
765
+ const result = { xpath: "" };
766
+ copyAttr(el, result, "id");
767
+ copyAttr(el, result, "xpath");
768
+ copyAttr(el, result, "xpathDefaultNamespace");
769
+ parseAnnotationChild(el, result);
770
+ return result;
771
+ }
772
+ function parseOpenContent(el) {
773
+ const result = {};
774
+ copyAttr(el, result, "id");
775
+ copyAttr(el, result, "mode");
776
+ parseAnnotationChild(el, result);
777
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "any") result.any = parseAny(child);
778
+ return result;
779
+ }
780
+ function parseDefaultOpenContent(el) {
781
+ const result = { any: {} };
782
+ copyAttr(el, result, "id");
783
+ copyBoolAttr(el, result, "appliesToEmpty");
784
+ copyAttr(el, result, "mode");
785
+ parseAnnotationChild(el, result);
786
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "any") result.any = parseAny(child);
787
+ return result;
788
+ }
789
+ function parseAssertion(el) {
790
+ const result = {};
791
+ copyAttr(el, result, "id");
792
+ copyAttr(el, result, "test");
793
+ copyAttr(el, result, "xpathDefaultNamespace");
794
+ parseAnnotationChild(el, result);
795
+ return result;
796
+ }
797
+ function parseAlternative(el) {
798
+ const result = {};
799
+ copyAttr(el, result, "id");
800
+ copyAttr(el, result, "test");
801
+ copyAttr(el, result, "type");
802
+ copyAttr(el, result, "xpathDefaultNamespace");
803
+ parseAnnotationChild(el, result);
804
+ for (const child of getAllChildElements(el)) {
805
+ const name = getLocalName(child);
806
+ if (name === "simpleType") result.simpleType = parseLocalSimpleType(child);
807
+ else if (name === "complexType") result.complexType = parseLocalComplexType(child);
808
+ }
809
+ return result;
810
+ }
811
+ function parseNotation(el) {
812
+ const result = {
813
+ name: "",
814
+ public: ""
815
+ };
816
+ copyAttr(el, result, "id");
817
+ copyAttr(el, result, "name");
818
+ copyAttr(el, result, "public");
819
+ copyAttr(el, result, "system");
820
+ parseAnnotationChild(el, result);
821
+ return result;
822
+ }
823
+ function copyAttr(el, target, name) {
824
+ if (el.hasAttribute(name)) {
825
+ const value = el.getAttribute(name);
826
+ if (value !== null) target[name] = value;
827
+ }
828
+ }
829
+ function copyBoolAttr(el, target, name) {
830
+ if (el.hasAttribute(name)) {
831
+ const value = el.getAttribute(name);
832
+ if (value !== null) target[name] = value === "true";
833
+ }
834
+ }
835
+ function pushTo(target, name, value) {
836
+ if (!target[name]) target[name] = [];
837
+ target[name].push(value);
838
+ }
839
+ function parseAnnotationChild(el, result) {
840
+ for (const child of getAllChildElements(el)) if (getLocalName(child) === "annotation") {
841
+ result.annotation = parseAnnotation(child);
842
+ break;
843
+ }
844
+ }
845
+ /**
846
+ * Extract xmlns declarations from an element's attributes.
847
+ * Returns undefined if no xmlns declarations found.
848
+ *
849
+ * @example
850
+ * For <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://example.com">
851
+ * Returns: { xs: "http://www.w3.org/2001/XMLSchema", tns: "http://example.com" }
852
+ *
853
+ * For <xs:element xmlns="http://default.com">
854
+ * Returns: { "": "http://default.com" }
855
+ */
856
+ function extractXmlns(el) {
857
+ const xmlns = {};
858
+ let hasXmlns = false;
859
+ for (let i = 0; i < el.attributes.length; i++) {
860
+ const attr = el.attributes[i];
861
+ const name = attr.name;
862
+ const value = attr.value;
863
+ if (name === "xmlns") {
864
+ xmlns[""] = value;
865
+ hasXmlns = true;
866
+ } else if (name.startsWith("xmlns:")) {
867
+ const prefix = name.substring(6);
868
+ xmlns[prefix] = value;
869
+ hasXmlns = true;
870
+ }
871
+ }
872
+ return hasXmlns ? xmlns : void 0;
873
+ }
874
+ /**
875
+ * Copy xmlns declarations to target if present
876
+ */
877
+ function copyXmlns(el, target) {
878
+ const xmlns = extractXmlns(el);
879
+ if (xmlns) target.$xmlns = xmlns;
880
+ }
881
+
882
+ //#endregion
883
+ //#region src/xsd/build.ts
884
+ /**
885
+ * Build an XSD string from a typed Schema object
886
+ */
887
+ function buildXsd(schema, options = {}) {
888
+ const prefix = options.prefix ?? "xs";
889
+ const pretty = options.pretty ?? true;
890
+ const ctx = {
891
+ prefix,
892
+ pretty,
893
+ indent: options.indent ?? " ",
894
+ level: 0
895
+ };
896
+ const lines = [];
897
+ lines.push("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
898
+ lines.push(buildSchema(schema, ctx));
899
+ return lines.join(pretty ? "\n" : "");
900
+ }
901
+ function buildSchema(schema, ctx) {
902
+ const attrs = [];
903
+ if (schema.$xmlns) for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (prefix === "") attrs.push(`xmlns="${uri}"`);
904
+ else attrs.push(`xmlns:${prefix}="${uri}"`);
905
+ addAttr(attrs, "id", schema.id);
906
+ addAttr(attrs, "targetNamespace", schema.targetNamespace);
907
+ addAttr(attrs, "version", schema.version);
908
+ addAttr(attrs, "finalDefault", schema.finalDefault);
909
+ addAttr(attrs, "blockDefault", schema.blockDefault);
910
+ addAttr(attrs, "attributeFormDefault", schema.attributeFormDefault);
911
+ addAttr(attrs, "elementFormDefault", schema.elementFormDefault);
912
+ addAttr(attrs, "defaultAttributes", schema.defaultAttributes);
913
+ addAttr(attrs, "xpathDefaultNamespace", schema.xpathDefaultNamespace);
914
+ addAttr(attrs, "xml:lang", schema["xml:lang"]);
915
+ const children = [];
916
+ const childCtx = {
917
+ ...ctx,
918
+ level: ctx.level + 1
919
+ };
920
+ if (schema.annotation) for (const ann of schema.annotation) children.push(buildAnnotation(ann, childCtx));
921
+ if (schema.include) for (const inc of schema.include) children.push(buildInclude(inc, childCtx));
922
+ if (schema.import) for (const imp of schema.import) children.push(buildImport(imp, childCtx));
923
+ if (schema.redefine) for (const red of schema.redefine) children.push(buildRedefine(red, childCtx));
924
+ if (schema.override) for (const ovr of schema.override) children.push(buildOverride(ovr, childCtx));
925
+ if (schema.defaultOpenContent) children.push(buildDefaultOpenContent(schema.defaultOpenContent, childCtx));
926
+ if (schema.simpleType && Array.isArray(schema.simpleType)) for (const st of schema.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
927
+ if (schema.complexType && Array.isArray(schema.complexType)) for (const ct of schema.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
928
+ if (schema.group) for (const grp of schema.group) children.push(buildNamedGroup(grp, childCtx));
929
+ if (schema.attributeGroup) for (const ag of schema.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
930
+ if (schema.element) for (const el of schema.element) children.push(buildTopLevelElement(el, childCtx));
931
+ if (schema.attribute) for (const attr of schema.attribute) children.push(buildTopLevelAttribute(attr, childCtx));
932
+ if (schema.notation) for (const not of schema.notation) children.push(buildNotation(not, childCtx));
933
+ return buildElement(`${ctx.prefix}:schema`, attrs, children, ctx);
934
+ }
935
+ function buildAnnotation(ann, ctx) {
936
+ const attrs = [];
937
+ addAttr(attrs, "id", ann.id);
938
+ const children = [];
939
+ const childCtx = {
940
+ ...ctx,
941
+ level: ctx.level + 1
942
+ };
943
+ if (ann.appinfo) for (const ai of ann.appinfo) children.push(buildAppinfo(ai, childCtx));
944
+ if (ann.documentation) for (const doc of ann.documentation) children.push(buildDocumentation(doc, childCtx));
945
+ return buildElement(`${ctx.prefix}:annotation`, attrs, children, ctx);
946
+ }
947
+ function buildDocumentation(doc, ctx) {
948
+ const attrs = [];
949
+ addAttr(attrs, "source", doc.source);
950
+ addAttr(attrs, "xml:lang", doc["xml:lang"]);
951
+ if (doc._text) return buildElementWithText(`${ctx.prefix}:documentation`, attrs, doc._text, ctx);
952
+ return buildElement(`${ctx.prefix}:documentation`, attrs, [], ctx);
953
+ }
954
+ function buildAppinfo(ai, ctx) {
955
+ const attrs = [];
956
+ addAttr(attrs, "source", ai.source);
957
+ if (ai._text) return buildElementWithText(`${ctx.prefix}:appinfo`, attrs, ai._text, ctx);
958
+ return buildElement(`${ctx.prefix}:appinfo`, attrs, [], ctx);
959
+ }
960
+ function buildInclude(inc, ctx) {
961
+ const attrs = [];
962
+ addAttr(attrs, "id", inc.id);
963
+ addAttr(attrs, "schemaLocation", inc.schemaLocation);
964
+ const children = [];
965
+ if (inc.annotation) children.push(buildAnnotation(inc.annotation, {
966
+ ...ctx,
967
+ level: ctx.level + 1
968
+ }));
969
+ return buildElement(`${ctx.prefix}:include`, attrs, children, ctx);
970
+ }
971
+ function buildImport(imp, ctx) {
972
+ const attrs = [];
973
+ addAttr(attrs, "id", imp.id);
974
+ addAttr(attrs, "namespace", imp.namespace);
975
+ addAttr(attrs, "schemaLocation", imp.schemaLocation);
976
+ const children = [];
977
+ if (imp.annotation) children.push(buildAnnotation(imp.annotation, {
978
+ ...ctx,
979
+ level: ctx.level + 1
980
+ }));
981
+ return buildElement(`${ctx.prefix}:import`, attrs, children, ctx);
982
+ }
983
+ function buildRedefine(red, ctx) {
984
+ const attrs = [];
985
+ addAttr(attrs, "id", red.id);
986
+ addAttr(attrs, "schemaLocation", red.schemaLocation);
987
+ const children = [];
988
+ const childCtx = {
989
+ ...ctx,
990
+ level: ctx.level + 1
991
+ };
992
+ if (red.annotation) for (const ann of red.annotation) children.push(buildAnnotation(ann, childCtx));
993
+ if (red.simpleType) for (const st of red.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
994
+ if (red.complexType) for (const ct of red.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
995
+ if (red.group) for (const grp of red.group) children.push(buildNamedGroup(grp, childCtx));
996
+ if (red.attributeGroup) for (const ag of red.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
997
+ return buildElement(`${ctx.prefix}:redefine`, attrs, children, ctx);
998
+ }
999
+ function buildOverride(ovr, ctx) {
1000
+ const attrs = [];
1001
+ addAttr(attrs, "id", ovr.id);
1002
+ addAttr(attrs, "schemaLocation", ovr.schemaLocation);
1003
+ const children = [];
1004
+ const childCtx = {
1005
+ ...ctx,
1006
+ level: ctx.level + 1
1007
+ };
1008
+ if (ovr.annotation) for (const ann of ovr.annotation) children.push(buildAnnotation(ann, childCtx));
1009
+ if (ovr.simpleType) for (const st of ovr.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
1010
+ if (ovr.complexType) for (const ct of ovr.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
1011
+ if (ovr.group) for (const grp of ovr.group) children.push(buildNamedGroup(grp, childCtx));
1012
+ if (ovr.attributeGroup) for (const ag of ovr.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
1013
+ if (ovr.element) for (const el of ovr.element) children.push(buildTopLevelElement(el, childCtx));
1014
+ if (ovr.attribute) for (const attr of ovr.attribute) children.push(buildTopLevelAttribute(attr, childCtx));
1015
+ if (ovr.notation) for (const not of ovr.notation) children.push(buildNotation(not, childCtx));
1016
+ return buildElement(`${ctx.prefix}:override`, attrs, children, ctx);
1017
+ }
1018
+ function buildTopLevelElement(el, ctx) {
1019
+ const attrs = [];
1020
+ addAttr(attrs, "id", el.id);
1021
+ addAttr(attrs, "name", el.name);
1022
+ addAttr(attrs, "type", el.type);
1023
+ addAttr(attrs, "substitutionGroup", el.substitutionGroup);
1024
+ addAttr(attrs, "default", el.default);
1025
+ addAttr(attrs, "fixed", el.fixed);
1026
+ addBoolAttr(attrs, "nillable", el.nillable);
1027
+ addBoolAttr(attrs, "abstract", el.abstract);
1028
+ addAttr(attrs, "final", el.final);
1029
+ addAttr(attrs, "block", el.block);
1030
+ const children = [];
1031
+ const childCtx = {
1032
+ ...ctx,
1033
+ level: ctx.level + 1
1034
+ };
1035
+ if (el.annotation) children.push(buildAnnotation(el.annotation, childCtx));
1036
+ if (el.simpleType) children.push(buildLocalSimpleType(el.simpleType, childCtx));
1037
+ if (el.complexType) children.push(buildLocalComplexType(el.complexType, childCtx));
1038
+ if (el.alternative) for (const alt of el.alternative) children.push(buildAlternative(alt, childCtx));
1039
+ if (el.unique) for (const u of el.unique) children.push(buildUnique(u, childCtx));
1040
+ if (el.key) for (const k of el.key) children.push(buildKey(k, childCtx));
1041
+ if (el.keyref) for (const kr of el.keyref) children.push(buildKeyref(kr, childCtx));
1042
+ return buildElement(`${ctx.prefix}:element`, attrs, children, ctx);
1043
+ }
1044
+ function buildLocalElement(el, ctx) {
1045
+ const attrs = [];
1046
+ addAttr(attrs, "id", el.id);
1047
+ addAttr(attrs, "name", el.name);
1048
+ addAttr(attrs, "ref", el.ref);
1049
+ addAttr(attrs, "type", el.type);
1050
+ addOccursAttr(attrs, "minOccurs", el.minOccurs);
1051
+ addOccursAttr(attrs, "maxOccurs", el.maxOccurs);
1052
+ addAttr(attrs, "default", el.default);
1053
+ addAttr(attrs, "fixed", el.fixed);
1054
+ addBoolAttr(attrs, "nillable", el.nillable);
1055
+ addAttr(attrs, "block", el.block);
1056
+ addAttr(attrs, "form", el.form);
1057
+ addAttr(attrs, "targetNamespace", el.targetNamespace);
1058
+ const children = [];
1059
+ const childCtx = {
1060
+ ...ctx,
1061
+ level: ctx.level + 1
1062
+ };
1063
+ if (el.annotation) children.push(buildAnnotation(el.annotation, childCtx));
1064
+ if (el.simpleType) children.push(buildLocalSimpleType(el.simpleType, childCtx));
1065
+ if (el.complexType) children.push(buildLocalComplexType(el.complexType, childCtx));
1066
+ if (el.alternative) for (const alt of el.alternative) children.push(buildAlternative(alt, childCtx));
1067
+ if (el.unique) for (const u of el.unique) children.push(buildUnique(u, childCtx));
1068
+ if (el.key) for (const k of el.key) children.push(buildKey(k, childCtx));
1069
+ if (el.keyref) for (const kr of el.keyref) children.push(buildKeyref(kr, childCtx));
1070
+ return buildElement(`${ctx.prefix}:element`, attrs, children, ctx);
1071
+ }
1072
+ function buildTopLevelAttribute(attr, ctx) {
1073
+ const attrs = [];
1074
+ addAttr(attrs, "id", attr.id);
1075
+ addAttr(attrs, "name", attr.name);
1076
+ addAttr(attrs, "type", attr.type);
1077
+ addAttr(attrs, "default", attr.default);
1078
+ addAttr(attrs, "fixed", attr.fixed);
1079
+ addBoolAttr(attrs, "inheritable", attr.inheritable);
1080
+ const children = [];
1081
+ const childCtx = {
1082
+ ...ctx,
1083
+ level: ctx.level + 1
1084
+ };
1085
+ if (attr.annotation) children.push(buildAnnotation(attr.annotation, childCtx));
1086
+ if (attr.simpleType) children.push(buildLocalSimpleType(attr.simpleType, childCtx));
1087
+ return buildElement(`${ctx.prefix}:attribute`, attrs, children, ctx);
1088
+ }
1089
+ function buildLocalAttribute(attr, ctx) {
1090
+ const attrs = [];
1091
+ addAttr(attrs, "id", attr.id);
1092
+ addAttr(attrs, "name", attr.name);
1093
+ addAttr(attrs, "ref", attr.ref);
1094
+ addAttr(attrs, "type", attr.type);
1095
+ addAttr(attrs, "use", attr.use);
1096
+ addAttr(attrs, "default", attr.default);
1097
+ addAttr(attrs, "fixed", attr.fixed);
1098
+ addAttr(attrs, "form", attr.form);
1099
+ addAttr(attrs, "targetNamespace", attr.targetNamespace);
1100
+ addBoolAttr(attrs, "inheritable", attr.inheritable);
1101
+ const children = [];
1102
+ const childCtx = {
1103
+ ...ctx,
1104
+ level: ctx.level + 1
1105
+ };
1106
+ if (attr.annotation) children.push(buildAnnotation(attr.annotation, childCtx));
1107
+ if (attr.simpleType) children.push(buildLocalSimpleType(attr.simpleType, childCtx));
1108
+ return buildElement(`${ctx.prefix}:attribute`, attrs, children, ctx);
1109
+ }
1110
+ function buildTopLevelComplexType(ct, ctx) {
1111
+ const attrs = [];
1112
+ addAttr(attrs, "id", ct.id);
1113
+ addAttr(attrs, "name", ct.name);
1114
+ addBoolAttr(attrs, "mixed", ct.mixed);
1115
+ addBoolAttr(attrs, "abstract", ct.abstract);
1116
+ addAttr(attrs, "final", ct.final);
1117
+ addAttr(attrs, "block", ct.block);
1118
+ addBoolAttr(attrs, "defaultAttributesApply", ct.defaultAttributesApply);
1119
+ return buildComplexTypeContent(ct, attrs, ctx);
1120
+ }
1121
+ function buildLocalComplexType(ct, ctx) {
1122
+ const attrs = [];
1123
+ addAttr(attrs, "id", ct.id);
1124
+ addBoolAttr(attrs, "mixed", ct.mixed);
1125
+ return buildComplexTypeContent(ct, attrs, ctx);
1126
+ }
1127
+ function buildComplexTypeContent(ct, attrs, ctx) {
1128
+ const children = [];
1129
+ const childCtx = {
1130
+ ...ctx,
1131
+ level: ctx.level + 1
1132
+ };
1133
+ if (ct.annotation) children.push(buildAnnotation(ct.annotation, childCtx));
1134
+ if (ct.simpleContent) children.push(buildSimpleContent(ct.simpleContent, childCtx));
1135
+ else if (ct.complexContent) children.push(buildComplexContent(ct.complexContent, childCtx));
1136
+ else {
1137
+ if (ct.openContent) children.push(buildOpenContent(ct.openContent, childCtx));
1138
+ if (ct.group) children.push(buildGroupRef(ct.group, childCtx));
1139
+ if (ct.all) children.push(buildAll(ct.all, childCtx));
1140
+ if (ct.choice) children.push(buildExplicitGroup(ct.choice, "choice", childCtx));
1141
+ if (ct.sequence) children.push(buildExplicitGroup(ct.sequence, "sequence", childCtx));
1142
+ if (ct.attribute) for (const attr of ct.attribute) children.push(buildLocalAttribute(attr, childCtx));
1143
+ if (ct.attributeGroup) for (const ag of ct.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
1144
+ if (ct.anyAttribute) children.push(buildAnyAttribute(ct.anyAttribute, childCtx));
1145
+ if (ct.assert) for (const a of ct.assert) children.push(buildAssertion(a, childCtx));
1146
+ }
1147
+ return buildElement(`${ctx.prefix}:complexType`, attrs, children, ctx);
1148
+ }
1149
+ function buildTopLevelSimpleType(st, ctx) {
1150
+ const attrs = [];
1151
+ addAttr(attrs, "id", st.id);
1152
+ addAttr(attrs, "name", st.name);
1153
+ addAttr(attrs, "final", st.final);
1154
+ return buildSimpleTypeContent(st, attrs, ctx);
1155
+ }
1156
+ function buildLocalSimpleType(st, ctx) {
1157
+ const attrs = [];
1158
+ addAttr(attrs, "id", st.id);
1159
+ return buildSimpleTypeContent(st, attrs, ctx);
1160
+ }
1161
+ function buildSimpleTypeContent(st, attrs, ctx) {
1162
+ const children = [];
1163
+ const childCtx = {
1164
+ ...ctx,
1165
+ level: ctx.level + 1
1166
+ };
1167
+ if (st.annotation) children.push(buildAnnotation(st.annotation, childCtx));
1168
+ if (st.restriction) children.push(buildSimpleTypeRestriction(st.restriction, childCtx));
1169
+ else if (st.list) children.push(buildList(st.list, childCtx));
1170
+ else if (st.union) children.push(buildUnion(st.union, childCtx));
1171
+ return buildElement(`${ctx.prefix}:simpleType`, attrs, children, ctx);
1172
+ }
1173
+ function buildSimpleTypeRestriction(r, ctx) {
1174
+ const attrs = [];
1175
+ addAttr(attrs, "id", r.id);
1176
+ addAttr(attrs, "base", r.base);
1177
+ const children = [];
1178
+ const childCtx = {
1179
+ ...ctx,
1180
+ level: ctx.level + 1
1181
+ };
1182
+ if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
1183
+ if (r.simpleType) children.push(buildLocalSimpleType(r.simpleType, childCtx));
1184
+ buildFacets(r, children, childCtx);
1185
+ return buildElement(`${ctx.prefix}:restriction`, attrs, children, ctx);
1186
+ }
1187
+ function buildFacets(r, children, ctx) {
1188
+ if (r.minExclusive) for (const f of r.minExclusive) children.push(buildFacet(f, "minExclusive", ctx));
1189
+ if (r.minInclusive) for (const f of r.minInclusive) children.push(buildFacet(f, "minInclusive", ctx));
1190
+ if (r.maxExclusive) for (const f of r.maxExclusive) children.push(buildFacet(f, "maxExclusive", ctx));
1191
+ if (r.maxInclusive) for (const f of r.maxInclusive) children.push(buildFacet(f, "maxInclusive", ctx));
1192
+ if (r.totalDigits) for (const f of r.totalDigits) children.push(buildFacet(f, "totalDigits", ctx));
1193
+ if (r.fractionDigits) for (const f of r.fractionDigits) children.push(buildFacet(f, "fractionDigits", ctx));
1194
+ if (r.length) for (const f of r.length) children.push(buildFacet(f, "length", ctx));
1195
+ if (r.minLength) for (const f of r.minLength) children.push(buildFacet(f, "minLength", ctx));
1196
+ if (r.maxLength) for (const f of r.maxLength) children.push(buildFacet(f, "maxLength", ctx));
1197
+ if (r.enumeration) for (const f of r.enumeration) children.push(buildFacet(f, "enumeration", ctx));
1198
+ if (r.whiteSpace) for (const f of r.whiteSpace) children.push(buildFacet(f, "whiteSpace", ctx));
1199
+ if (r.pattern) for (const p of r.pattern) children.push(buildPattern(p, ctx));
1200
+ if (r.assertion) for (const a of r.assertion) children.push(buildAssertion(a, ctx));
1201
+ if (r.explicitTimezone) for (const f of r.explicitTimezone) children.push(buildFacet(f, "explicitTimezone", ctx));
1202
+ }
1203
+ function buildFacet(f, name, ctx) {
1204
+ const attrs = [];
1205
+ addAttr(attrs, "id", f.id);
1206
+ addAttr(attrs, "value", f.value);
1207
+ addBoolAttr(attrs, "fixed", f.fixed);
1208
+ const children = [];
1209
+ if (f.annotation) children.push(buildAnnotation(f.annotation, {
1210
+ ...ctx,
1211
+ level: ctx.level + 1
1212
+ }));
1213
+ return buildElement(`${ctx.prefix}:${name}`, attrs, children, ctx);
1214
+ }
1215
+ function buildPattern(p, ctx) {
1216
+ const attrs = [];
1217
+ addAttr(attrs, "id", p.id);
1218
+ addAttr(attrs, "value", p.value);
1219
+ const children = [];
1220
+ if (p.annotation) children.push(buildAnnotation(p.annotation, {
1221
+ ...ctx,
1222
+ level: ctx.level + 1
1223
+ }));
1224
+ return buildElement(`${ctx.prefix}:pattern`, attrs, children, ctx);
1225
+ }
1226
+ function buildList(l, ctx) {
1227
+ const attrs = [];
1228
+ addAttr(attrs, "id", l.id);
1229
+ addAttr(attrs, "itemType", l.itemType);
1230
+ const children = [];
1231
+ const childCtx = {
1232
+ ...ctx,
1233
+ level: ctx.level + 1
1234
+ };
1235
+ if (l.annotation) children.push(buildAnnotation(l.annotation, childCtx));
1236
+ if (l.simpleType) children.push(buildLocalSimpleType(l.simpleType, childCtx));
1237
+ return buildElement(`${ctx.prefix}:list`, attrs, children, ctx);
1238
+ }
1239
+ function buildUnion(u, ctx) {
1240
+ const attrs = [];
1241
+ addAttr(attrs, "id", u.id);
1242
+ addAttr(attrs, "memberTypes", u.memberTypes);
1243
+ const children = [];
1244
+ const childCtx = {
1245
+ ...ctx,
1246
+ level: ctx.level + 1
1247
+ };
1248
+ if (u.annotation) children.push(buildAnnotation(u.annotation, childCtx));
1249
+ if (u.simpleType) for (const st of u.simpleType) children.push(buildLocalSimpleType(st, childCtx));
1250
+ return buildElement(`${ctx.prefix}:union`, attrs, children, ctx);
1251
+ }
1252
+ function buildComplexContent(cc, ctx) {
1253
+ const attrs = [];
1254
+ addAttr(attrs, "id", cc.id);
1255
+ addBoolAttr(attrs, "mixed", cc.mixed);
1256
+ const children = [];
1257
+ const childCtx = {
1258
+ ...ctx,
1259
+ level: ctx.level + 1
1260
+ };
1261
+ if (cc.annotation) children.push(buildAnnotation(cc.annotation, childCtx));
1262
+ if (cc.restriction) children.push(buildComplexContentRestriction(cc.restriction, childCtx));
1263
+ else if (cc.extension) children.push(buildComplexContentExtension(cc.extension, childCtx));
1264
+ return buildElement(`${ctx.prefix}:complexContent`, attrs, children, ctx);
1265
+ }
1266
+ function buildSimpleContent(sc, ctx) {
1267
+ const attrs = [];
1268
+ addAttr(attrs, "id", sc.id);
1269
+ const children = [];
1270
+ const childCtx = {
1271
+ ...ctx,
1272
+ level: ctx.level + 1
1273
+ };
1274
+ if (sc.annotation) children.push(buildAnnotation(sc.annotation, childCtx));
1275
+ if (sc.restriction) children.push(buildSimpleContentRestriction(sc.restriction, childCtx));
1276
+ else if (sc.extension) children.push(buildSimpleContentExtension(sc.extension, childCtx));
1277
+ return buildElement(`${ctx.prefix}:simpleContent`, attrs, children, ctx);
1278
+ }
1279
+ function buildComplexContentRestriction(r, ctx) {
1280
+ const attrs = [];
1281
+ addAttr(attrs, "id", r.id);
1282
+ addAttr(attrs, "base", r.base);
1283
+ const children = [];
1284
+ const childCtx = {
1285
+ ...ctx,
1286
+ level: ctx.level + 1
1287
+ };
1288
+ if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
1289
+ if (r.openContent) children.push(buildOpenContent(r.openContent, childCtx));
1290
+ if (r.group) children.push(buildGroupRef(r.group, childCtx));
1291
+ if (r.all) children.push(buildAll(r.all, childCtx));
1292
+ if (r.choice) children.push(buildExplicitGroup(r.choice, "choice", childCtx));
1293
+ if (r.sequence) children.push(buildExplicitGroup(r.sequence, "sequence", childCtx));
1294
+ if (r.attribute) for (const attr of r.attribute) children.push(buildLocalAttribute(attr, childCtx));
1295
+ if (r.attributeGroup) for (const ag of r.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
1296
+ if (r.anyAttribute) children.push(buildAnyAttribute(r.anyAttribute, childCtx));
1297
+ if (r.assert) for (const a of r.assert) children.push(buildAssertion(a, childCtx));
1298
+ return buildElement(`${ctx.prefix}:restriction`, attrs, children, ctx);
1299
+ }
1300
+ function buildComplexContentExtension(e, ctx) {
1301
+ const attrs = [];
1302
+ addAttr(attrs, "id", e.id);
1303
+ addAttr(attrs, "base", e.base);
1304
+ const children = [];
1305
+ const childCtx = {
1306
+ ...ctx,
1307
+ level: ctx.level + 1
1308
+ };
1309
+ if (e.annotation) children.push(buildAnnotation(e.annotation, childCtx));
1310
+ if (e.openContent) children.push(buildOpenContent(e.openContent, childCtx));
1311
+ if (e.group) children.push(buildGroupRef(e.group, childCtx));
1312
+ if (e.all) children.push(buildAll(e.all, childCtx));
1313
+ if (e.choice) children.push(buildExplicitGroup(e.choice, "choice", childCtx));
1314
+ if (e.sequence) children.push(buildExplicitGroup(e.sequence, "sequence", childCtx));
1315
+ if (e.attribute) for (const attr of e.attribute) children.push(buildLocalAttribute(attr, childCtx));
1316
+ if (e.attributeGroup) for (const ag of e.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
1317
+ if (e.anyAttribute) children.push(buildAnyAttribute(e.anyAttribute, childCtx));
1318
+ if (e.assert) for (const a of e.assert) children.push(buildAssertion(a, childCtx));
1319
+ return buildElement(`${ctx.prefix}:extension`, attrs, children, ctx);
1320
+ }
1321
+ function buildSimpleContentRestriction(r, ctx) {
1322
+ const attrs = [];
1323
+ addAttr(attrs, "id", r.id);
1324
+ addAttr(attrs, "base", r.base);
1325
+ const children = [];
1326
+ const childCtx = {
1327
+ ...ctx,
1328
+ level: ctx.level + 1
1329
+ };
1330
+ if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
1331
+ if (r.simpleType) children.push(buildLocalSimpleType(r.simpleType, childCtx));
1332
+ buildFacets(r, children, childCtx);
1333
+ if (r.attribute) for (const attr of r.attribute) children.push(buildLocalAttribute(attr, childCtx));
1334
+ if (r.attributeGroup) for (const ag of r.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
1335
+ if (r.anyAttribute) children.push(buildAnyAttribute(r.anyAttribute, childCtx));
1336
+ if (r.assert) for (const a of r.assert) children.push(buildAssertion(a, childCtx));
1337
+ return buildElement(`${ctx.prefix}:restriction`, attrs, children, ctx);
1338
+ }
1339
+ function buildSimpleContentExtension(e, ctx) {
1340
+ const attrs = [];
1341
+ addAttr(attrs, "id", e.id);
1342
+ addAttr(attrs, "base", e.base);
1343
+ const children = [];
1344
+ const childCtx = {
1345
+ ...ctx,
1346
+ level: ctx.level + 1
1347
+ };
1348
+ if (e.annotation) children.push(buildAnnotation(e.annotation, childCtx));
1349
+ if (e.attribute) for (const attr of e.attribute) children.push(buildLocalAttribute(attr, childCtx));
1350
+ if (e.attributeGroup) for (const ag of e.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
1351
+ if (e.anyAttribute) children.push(buildAnyAttribute(e.anyAttribute, childCtx));
1352
+ if (e.assert) for (const a of e.assert) children.push(buildAssertion(a, childCtx));
1353
+ return buildElement(`${ctx.prefix}:extension`, attrs, children, ctx);
1354
+ }
1355
+ function buildExplicitGroup(g, name, ctx) {
1356
+ const attrs = [];
1357
+ addAttr(attrs, "id", g.id);
1358
+ addOccursAttr(attrs, "minOccurs", g.minOccurs);
1359
+ addOccursAttr(attrs, "maxOccurs", g.maxOccurs);
1360
+ const children = [];
1361
+ const childCtx = {
1362
+ ...ctx,
1363
+ level: ctx.level + 1
1364
+ };
1365
+ if (g.annotation) children.push(buildAnnotation(g.annotation, childCtx));
1366
+ if (g.element) for (const el of g.element) children.push(buildLocalElement(el, childCtx));
1367
+ if (g.group) for (const grp of g.group) children.push(buildGroupRef(grp, childCtx));
1368
+ if (g.choice) for (const c of g.choice) children.push(buildExplicitGroup(c, "choice", childCtx));
1369
+ if (g.sequence) for (const s of g.sequence) children.push(buildExplicitGroup(s, "sequence", childCtx));
1370
+ if (g.any) for (const a of g.any) children.push(buildAny(a, childCtx));
1371
+ return buildElement(`${ctx.prefix}:${name}`, attrs, children, ctx);
1372
+ }
1373
+ function buildAll(a, ctx) {
1374
+ const attrs = [];
1375
+ addAttr(attrs, "id", a.id);
1376
+ addOccursAttr(attrs, "minOccurs", a.minOccurs);
1377
+ addOccursAttr(attrs, "maxOccurs", a.maxOccurs);
1378
+ const children = [];
1379
+ const childCtx = {
1380
+ ...ctx,
1381
+ level: ctx.level + 1
1382
+ };
1383
+ if (a.annotation) children.push(buildAnnotation(a.annotation, childCtx));
1384
+ if (a.element) for (const el of a.element) children.push(buildLocalElement(el, childCtx));
1385
+ if (a.any) for (const any of a.any) children.push(buildAny(any, childCtx));
1386
+ if (a.group) for (const grp of a.group) children.push(buildGroupRef(grp, childCtx));
1387
+ return buildElement(`${ctx.prefix}:all`, attrs, children, ctx);
1388
+ }
1389
+ function buildNamedGroup(g, ctx) {
1390
+ const attrs = [];
1391
+ addAttr(attrs, "id", g.id);
1392
+ addAttr(attrs, "name", g.name);
1393
+ const children = [];
1394
+ const childCtx = {
1395
+ ...ctx,
1396
+ level: ctx.level + 1
1397
+ };
1398
+ if (g.annotation) children.push(buildAnnotation(g.annotation, childCtx));
1399
+ if (g.all) children.push(buildAll(g.all, childCtx));
1400
+ if (g.choice) children.push(buildExplicitGroup(g.choice, "choice", childCtx));
1401
+ if (g.sequence) children.push(buildExplicitGroup(g.sequence, "sequence", childCtx));
1402
+ return buildElement(`${ctx.prefix}:group`, attrs, children, ctx);
1403
+ }
1404
+ function buildGroupRef(g, ctx) {
1405
+ const attrs = [];
1406
+ addAttr(attrs, "id", g.id);
1407
+ addAttr(attrs, "ref", g.ref);
1408
+ addOccursAttr(attrs, "minOccurs", g.minOccurs);
1409
+ addOccursAttr(attrs, "maxOccurs", g.maxOccurs);
1410
+ const children = [];
1411
+ if (g.annotation) children.push(buildAnnotation(g.annotation, {
1412
+ ...ctx,
1413
+ level: ctx.level + 1
1414
+ }));
1415
+ return buildElement(`${ctx.prefix}:group`, attrs, children, ctx);
1416
+ }
1417
+ function buildNamedAttributeGroup(ag, ctx) {
1418
+ const attrs = [];
1419
+ addAttr(attrs, "id", ag.id);
1420
+ addAttr(attrs, "name", ag.name);
1421
+ const children = [];
1422
+ const childCtx = {
1423
+ ...ctx,
1424
+ level: ctx.level + 1
1425
+ };
1426
+ if (ag.annotation) children.push(buildAnnotation(ag.annotation, childCtx));
1427
+ if (ag.attribute) for (const attr of ag.attribute) children.push(buildLocalAttribute(attr, childCtx));
1428
+ if (ag.attributeGroup) for (const agr of ag.attributeGroup) children.push(buildAttributeGroupRef(agr, childCtx));
1429
+ if (ag.anyAttribute) children.push(buildAnyAttribute(ag.anyAttribute, childCtx));
1430
+ return buildElement(`${ctx.prefix}:attributeGroup`, attrs, children, ctx);
1431
+ }
1432
+ function buildAttributeGroupRef(ag, ctx) {
1433
+ const attrs = [];
1434
+ addAttr(attrs, "id", ag.id);
1435
+ addAttr(attrs, "ref", ag.ref);
1436
+ const children = [];
1437
+ if (ag.annotation) children.push(buildAnnotation(ag.annotation, {
1438
+ ...ctx,
1439
+ level: ctx.level + 1
1440
+ }));
1441
+ return buildElement(`${ctx.prefix}:attributeGroup`, attrs, children, ctx);
1442
+ }
1443
+ function buildAny(a, ctx) {
1444
+ const attrs = [];
1445
+ addAttr(attrs, "id", a.id);
1446
+ addOccursAttr(attrs, "minOccurs", a.minOccurs);
1447
+ addOccursAttr(attrs, "maxOccurs", a.maxOccurs);
1448
+ addAttr(attrs, "namespace", a.namespace);
1449
+ addAttr(attrs, "processContents", a.processContents);
1450
+ addAttr(attrs, "notNamespace", a.notNamespace);
1451
+ addAttr(attrs, "notQName", a.notQName);
1452
+ const children = [];
1453
+ if (a.annotation) children.push(buildAnnotation(a.annotation, {
1454
+ ...ctx,
1455
+ level: ctx.level + 1
1456
+ }));
1457
+ return buildElement(`${ctx.prefix}:any`, attrs, children, ctx);
1458
+ }
1459
+ function buildAnyAttribute(aa, ctx) {
1460
+ const attrs = [];
1461
+ addAttr(attrs, "id", aa.id);
1462
+ addAttr(attrs, "namespace", aa.namespace);
1463
+ addAttr(attrs, "processContents", aa.processContents);
1464
+ addAttr(attrs, "notNamespace", aa.notNamespace);
1465
+ addAttr(attrs, "notQName", aa.notQName);
1466
+ const children = [];
1467
+ if (aa.annotation) children.push(buildAnnotation(aa.annotation, {
1468
+ ...ctx,
1469
+ level: ctx.level + 1
1470
+ }));
1471
+ return buildElement(`${ctx.prefix}:anyAttribute`, attrs, children, ctx);
1472
+ }
1473
+ function buildUnique(u, ctx) {
1474
+ const attrs = [];
1475
+ addAttr(attrs, "id", u.id);
1476
+ addAttr(attrs, "name", u.name);
1477
+ addAttr(attrs, "ref", u.ref);
1478
+ const children = [];
1479
+ const childCtx = {
1480
+ ...ctx,
1481
+ level: ctx.level + 1
1482
+ };
1483
+ if (u.annotation) children.push(buildAnnotation(u.annotation, childCtx));
1484
+ if (u.selector) children.push(buildSelector(u.selector, childCtx));
1485
+ if (u.field) for (const f of u.field) children.push(buildField(f, childCtx));
1486
+ return buildElement(`${ctx.prefix}:unique`, attrs, children, ctx);
1487
+ }
1488
+ function buildKey(k, ctx) {
1489
+ const attrs = [];
1490
+ addAttr(attrs, "id", k.id);
1491
+ addAttr(attrs, "name", k.name);
1492
+ addAttr(attrs, "ref", k.ref);
1493
+ const children = [];
1494
+ const childCtx = {
1495
+ ...ctx,
1496
+ level: ctx.level + 1
1497
+ };
1498
+ if (k.annotation) children.push(buildAnnotation(k.annotation, childCtx));
1499
+ if (k.selector) children.push(buildSelector(k.selector, childCtx));
1500
+ if (k.field) for (const f of k.field) children.push(buildField(f, childCtx));
1501
+ return buildElement(`${ctx.prefix}:key`, attrs, children, ctx);
1502
+ }
1503
+ function buildKeyref(kr, ctx) {
1504
+ const attrs = [];
1505
+ addAttr(attrs, "id", kr.id);
1506
+ addAttr(attrs, "name", kr.name);
1507
+ addAttr(attrs, "ref", kr.ref);
1508
+ addAttr(attrs, "refer", kr.refer);
1509
+ const children = [];
1510
+ const childCtx = {
1511
+ ...ctx,
1512
+ level: ctx.level + 1
1513
+ };
1514
+ if (kr.annotation) children.push(buildAnnotation(kr.annotation, childCtx));
1515
+ if (kr.selector) children.push(buildSelector(kr.selector, childCtx));
1516
+ if (kr.field) for (const f of kr.field) children.push(buildField(f, childCtx));
1517
+ return buildElement(`${ctx.prefix}:keyref`, attrs, children, ctx);
1518
+ }
1519
+ function buildSelector(s, ctx) {
1520
+ const attrs = [];
1521
+ addAttr(attrs, "id", s.id);
1522
+ addAttr(attrs, "xpath", s.xpath);
1523
+ addAttr(attrs, "xpathDefaultNamespace", s.xpathDefaultNamespace);
1524
+ const children = [];
1525
+ if (s.annotation) children.push(buildAnnotation(s.annotation, {
1526
+ ...ctx,
1527
+ level: ctx.level + 1
1528
+ }));
1529
+ return buildElement(`${ctx.prefix}:selector`, attrs, children, ctx);
1530
+ }
1531
+ function buildField(f, ctx) {
1532
+ const attrs = [];
1533
+ addAttr(attrs, "id", f.id);
1534
+ addAttr(attrs, "xpath", f.xpath);
1535
+ addAttr(attrs, "xpathDefaultNamespace", f.xpathDefaultNamespace);
1536
+ const children = [];
1537
+ if (f.annotation) children.push(buildAnnotation(f.annotation, {
1538
+ ...ctx,
1539
+ level: ctx.level + 1
1540
+ }));
1541
+ return buildElement(`${ctx.prefix}:field`, attrs, children, ctx);
1542
+ }
1543
+ function buildOpenContent(oc, ctx) {
1544
+ const attrs = [];
1545
+ addAttr(attrs, "id", oc.id);
1546
+ addAttr(attrs, "mode", oc.mode);
1547
+ const children = [];
1548
+ const childCtx = {
1549
+ ...ctx,
1550
+ level: ctx.level + 1
1551
+ };
1552
+ if (oc.annotation) children.push(buildAnnotation(oc.annotation, childCtx));
1553
+ if (oc.any) children.push(buildAny(oc.any, childCtx));
1554
+ return buildElement(`${ctx.prefix}:openContent`, attrs, children, ctx);
1555
+ }
1556
+ function buildDefaultOpenContent(doc, ctx) {
1557
+ const attrs = [];
1558
+ addAttr(attrs, "id", doc.id);
1559
+ addBoolAttr(attrs, "appliesToEmpty", doc.appliesToEmpty);
1560
+ addAttr(attrs, "mode", doc.mode);
1561
+ const children = [];
1562
+ const childCtx = {
1563
+ ...ctx,
1564
+ level: ctx.level + 1
1565
+ };
1566
+ if (doc.annotation) children.push(buildAnnotation(doc.annotation, childCtx));
1567
+ children.push(buildAny(doc.any, childCtx));
1568
+ return buildElement(`${ctx.prefix}:defaultOpenContent`, attrs, children, ctx);
1569
+ }
1570
+ function buildAssertion(a, ctx) {
1571
+ const attrs = [];
1572
+ addAttr(attrs, "id", a.id);
1573
+ addAttr(attrs, "test", a.test);
1574
+ addAttr(attrs, "xpathDefaultNamespace", a.xpathDefaultNamespace);
1575
+ const children = [];
1576
+ if (a.annotation) children.push(buildAnnotation(a.annotation, {
1577
+ ...ctx,
1578
+ level: ctx.level + 1
1579
+ }));
1580
+ return buildElement(`${ctx.prefix}:assert`, attrs, children, ctx);
1581
+ }
1582
+ function buildAlternative(alt, ctx) {
1583
+ const attrs = [];
1584
+ addAttr(attrs, "id", alt.id);
1585
+ addAttr(attrs, "test", alt.test);
1586
+ addAttr(attrs, "type", alt.type);
1587
+ addAttr(attrs, "xpathDefaultNamespace", alt.xpathDefaultNamespace);
1588
+ const children = [];
1589
+ const childCtx = {
1590
+ ...ctx,
1591
+ level: ctx.level + 1
1592
+ };
1593
+ if (alt.annotation) children.push(buildAnnotation(alt.annotation, childCtx));
1594
+ if (alt.simpleType) children.push(buildLocalSimpleType(alt.simpleType, childCtx));
1595
+ if (alt.complexType) children.push(buildLocalComplexType(alt.complexType, childCtx));
1596
+ return buildElement(`${ctx.prefix}:alternative`, attrs, children, ctx);
1597
+ }
1598
+ function buildNotation(n, ctx) {
1599
+ const attrs = [];
1600
+ addAttr(attrs, "id", n.id);
1601
+ addAttr(attrs, "name", n.name);
1602
+ addAttr(attrs, "public", n.public);
1603
+ addAttr(attrs, "system", n.system);
1604
+ const children = [];
1605
+ if (n.annotation) children.push(buildAnnotation(n.annotation, {
1606
+ ...ctx,
1607
+ level: ctx.level + 1
1608
+ }));
1609
+ return buildElement(`${ctx.prefix}:notation`, attrs, children, ctx);
1610
+ }
1611
+ function addAttr(attrs, name, value) {
1612
+ if (value !== void 0) attrs.push(`${name}="${escapeXml(value)}"`);
1613
+ }
1614
+ function addBoolAttr(attrs, name, value) {
1615
+ if (value !== void 0) attrs.push(`${name}="${value}"`);
1616
+ }
1617
+ function addOccursAttr(attrs, name, value) {
1618
+ if (value !== void 0) attrs.push(`${name}="${value}"`);
1619
+ }
1620
+ function escapeXml(str) {
1621
+ return str.replaceAll(/&/g, "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
1622
+ }
1623
+ function buildElement(tag, attrs, children, ctx) {
1624
+ const indent = ctx.pretty ? ctx.indent.repeat(ctx.level) : "";
1625
+ const attrStr = attrs.length > 0 ? " " + attrs.join(" ") : "";
1626
+ if (children.length === 0) return `${indent}<${tag}${attrStr}/>`;
1627
+ const nl = ctx.pretty ? "\n" : "";
1628
+ return `${indent}<${tag}${attrStr}>${nl}${children.join(nl)}${nl}${indent}</${tag}>`;
1629
+ }
1630
+ function buildElementWithText(tag, attrs, text, ctx) {
1631
+ return `${ctx.pretty ? ctx.indent.repeat(ctx.level) : ""}<${tag}${attrs.length > 0 ? " " + attrs.join(" ") : ""}>${escapeXml(text)}</${tag}>`;
1632
+ }
1633
+
1634
+ //#endregion
1635
+ //#region src/xsd/helpers.ts
1636
+ /**
1637
+ * Resolve $imports for a schema by matching import schemaLocation to $filename.
1638
+ *
1639
+ * @param schema - The schema to resolve imports for
1640
+ * @param availableSchemas - Array of schemas that may be imported
1641
+ * @returns A new schema object with $imports populated
1642
+ *
1643
+ * @example
1644
+ * ```typescript
1645
+ * const orderSchema = parseXsd(orderXsd);
1646
+ * const commonSchema = { ...parseXsd(commonXsd), $filename: 'common.xsd' };
1647
+ *
1648
+ * // orderSchema has: import: [{ schemaLocation: 'common.xsd', ... }]
1649
+ * const resolved = resolveImports(orderSchema, [commonSchema]);
1650
+ * // resolved.$imports = [commonSchema]
1651
+ * ```
1652
+ */
1653
+ function resolveImports(schema, availableSchemas) {
1654
+ const imports = [];
1655
+ if (schema.import) {
1656
+ for (const imp of schema.import) if (imp.schemaLocation) {
1657
+ const found = availableSchemas.find((s) => s.$filename === imp.schemaLocation);
1658
+ if (found) imports.push(found);
1659
+ }
1660
+ }
1661
+ return {
1662
+ ...schema,
1663
+ $imports: imports
1664
+ };
1665
+ }
1666
+ /**
1667
+ * Resolve $imports for multiple schemas, linking them together.
1668
+ *
1669
+ * @param schemas - Array of schemas to link together
1670
+ * @returns Array of schemas with $imports populated
1671
+ *
1672
+ * @example
1673
+ * ```typescript
1674
+ * const schemas = [
1675
+ * { ...parseXsd(orderXsd), $filename: 'order.xsd' },
1676
+ * { ...parseXsd(commonXsd), $filename: 'common.xsd' },
1677
+ * ];
1678
+ * const linked = linkSchemas(schemas);
1679
+ * // Each schema now has $imports resolved
1680
+ * ```
1681
+ */
1682
+ function linkSchemas(schemas) {
1683
+ return schemas.map((schema) => resolveImports(schema, schemas));
1684
+ }
1685
+
1686
+ //#endregion
1687
+ //#region src/xsd/traverser.ts
1688
+ /**
1689
+ * Base class for OO schema traversal using real W3C XSD types.
1690
+ *
1691
+ * Subclass and override the `on*` methods you need.
1692
+ * Context is available via `this` - no parameter passing needed.
1693
+ */
1694
+ var SchemaTraverser = class {
1695
+ /** Root schema being traversed */
1696
+ rootSchema;
1697
+ /** Current schema being visited */
1698
+ currentSchema;
1699
+ /** Source of current node (direct, redefine, override, include, import) */
1700
+ source = "direct";
1701
+ /** Depth in schema hierarchy (0 = root) */
1702
+ depth = 0;
1703
+ /** Traversal options */
1704
+ options = {
1705
+ includeImports: true,
1706
+ includeIncludes: true,
1707
+ maxDepth: Infinity
1708
+ };
1709
+ /** Visited schemas (prevents infinite loops) */
1710
+ visited = /* @__PURE__ */ new Set();
1711
+ /**
1712
+ * Traverse a schema and all its imports/includes.
1713
+ * Override `on*` methods to handle specific node types.
1714
+ */
1715
+ traverse(schema, options = {}) {
1716
+ this.rootSchema = schema;
1717
+ this.options = {
1718
+ ...this.options,
1719
+ ...options
1720
+ };
1721
+ this.visited.clear();
1722
+ this.traverseSchema(schema, "direct", 0);
1723
+ return this;
1724
+ }
1725
+ /** Called when entering a schema */
1726
+ onEnterSchema(_schema) {}
1727
+ /** Called when leaving a schema */
1728
+ onLeaveSchema(_schema) {}
1729
+ /** Called for each top-level complexType */
1730
+ onComplexType(_ct) {}
1731
+ /** Called for each top-level simpleType */
1732
+ onSimpleType(_st) {}
1733
+ /** Called for each top-level element */
1734
+ onElement(_element) {}
1735
+ /** Called for each top-level attribute */
1736
+ onAttribute(_attr) {}
1737
+ /** Called for each named group */
1738
+ onGroup(_group) {}
1739
+ /** Called for each named attributeGroup */
1740
+ onAttributeGroup(_group) {}
1741
+ /** Called for each redefine block */
1742
+ onRedefine(_redefine) {}
1743
+ /** Called for each override block */
1744
+ onOverride(_override) {}
1745
+ traverseSchema(schema, source, depth) {
1746
+ if (this.visited.has(schema)) return;
1747
+ if (depth > this.options.maxDepth) return;
1748
+ this.visited.add(schema);
1749
+ this.currentSchema = schema;
1750
+ this.source = source;
1751
+ this.depth = depth;
1752
+ this.onEnterSchema(schema);
1753
+ this.traverseSchemaChildren(schema);
1754
+ this.traverseRedefines(schema);
1755
+ this.traverseOverrides(schema);
1756
+ this.traverseIncludes(schema, depth);
1757
+ this.traverseImports(schema, depth);
1758
+ this.onLeaveSchema(schema);
1759
+ }
1760
+ traverseSchemaChildren(schema) {
1761
+ if (schema.complexType) for (const ct of schema.complexType) this.onComplexType(ct);
1762
+ if (schema.simpleType) for (const st of schema.simpleType) this.onSimpleType(st);
1763
+ if (schema.element) for (const element of schema.element) this.onElement(element);
1764
+ if (schema.attribute) for (const attr of schema.attribute) this.onAttribute(attr);
1765
+ if (schema.group) for (const group of schema.group) this.onGroup(group);
1766
+ if (schema.attributeGroup) for (const group of schema.attributeGroup) this.onAttributeGroup(group);
1767
+ }
1768
+ traverseRedefines(schema) {
1769
+ if (!schema.redefine) return;
1770
+ const prevSource = this.source;
1771
+ this.source = "redefine";
1772
+ for (const redefine of schema.redefine) {
1773
+ this.onRedefine(redefine);
1774
+ if (redefine.complexType) for (const ct of redefine.complexType) this.onComplexType(ct);
1775
+ if (redefine.simpleType) for (const st of redefine.simpleType) this.onSimpleType(st);
1776
+ if (redefine.group) for (const group of redefine.group) this.onGroup(group);
1777
+ if (redefine.attributeGroup) for (const group of redefine.attributeGroup) this.onAttributeGroup(group);
1778
+ }
1779
+ this.source = prevSource;
1780
+ }
1781
+ traverseOverrides(schema) {
1782
+ if (!schema.override) return;
1783
+ const prevSource = this.source;
1784
+ this.source = "override";
1785
+ for (const override of schema.override) {
1786
+ this.onOverride(override);
1787
+ if (override.complexType) for (const ct of override.complexType) this.onComplexType(ct);
1788
+ if (override.simpleType) for (const st of override.simpleType) this.onSimpleType(st);
1789
+ if (override.element) for (const element of override.element) this.onElement(element);
1790
+ if (override.attribute) for (const attr of override.attribute) this.onAttribute(attr);
1791
+ if (override.group) for (const group of override.group) this.onGroup(group);
1792
+ if (override.attributeGroup) for (const group of override.attributeGroup) this.onAttributeGroup(group);
1793
+ }
1794
+ this.source = prevSource;
1795
+ }
1796
+ traverseIncludes(schema, depth) {
1797
+ if (!this.options.includeIncludes || !schema.$includes) return;
1798
+ for (const included of schema.$includes) this.traverseSchema(included, "include", depth + 1);
1799
+ }
1800
+ traverseImports(schema, depth) {
1801
+ if (!this.options.includeImports || !schema.$imports) return;
1802
+ for (const imported of schema.$imports) this.traverseSchema(imported, "import", depth + 1);
1803
+ }
1804
+ };
1805
+ /**
1806
+ * Resolves a schema hierarchy into a flat structure.
1807
+ * All types are collected into Maps for O(1) lookup.
1808
+ *
1809
+ * Precedence rules:
1810
+ * - redefine/override types take precedence over original
1811
+ * - root schema types take precedence over imported/included
1812
+ */
1813
+ var SchemaResolver = class extends SchemaTraverser {
1814
+ complexTypes = /* @__PURE__ */ new Map();
1815
+ simpleTypes = /* @__PURE__ */ new Map();
1816
+ elements = /* @__PURE__ */ new Map();
1817
+ attributes = /* @__PURE__ */ new Map();
1818
+ groups = /* @__PURE__ */ new Map();
1819
+ attributeGroups = /* @__PURE__ */ new Map();
1820
+ xmlns = /* @__PURE__ */ new Map();
1821
+ substitutionGroups = /* @__PURE__ */ new Map();
1822
+ /** Get the resolved schema structure */
1823
+ getResolved() {
1824
+ return {
1825
+ complexTypes: this.complexTypes,
1826
+ simpleTypes: this.simpleTypes,
1827
+ elements: this.elements,
1828
+ attributes: this.attributes,
1829
+ groups: this.groups,
1830
+ attributeGroups: this.attributeGroups,
1831
+ xmlns: this.xmlns,
1832
+ substitutionGroups: this.substitutionGroups
1833
+ };
1834
+ }
1835
+ onEnterSchema(schema) {
1836
+ if (schema.$xmlns) {
1837
+ for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (!this.xmlns.has(prefix)) this.xmlns.set(prefix, uri);
1838
+ }
1839
+ }
1840
+ onComplexType(ct) {
1841
+ if (!this.complexTypes.has(ct.name) || this.source === "redefine" || this.source === "override" || this.depth === 0 && this.source === "direct") this.complexTypes.set(ct.name, {
1842
+ ct,
1843
+ schema: this.currentSchema
1844
+ });
1845
+ }
1846
+ onSimpleType(st) {
1847
+ if (!this.simpleTypes.has(st.name) || this.source === "redefine" || this.source === "override" || this.depth === 0 && this.source === "direct") this.simpleTypes.set(st.name, {
1848
+ st,
1849
+ schema: this.currentSchema
1850
+ });
1851
+ }
1852
+ onElement(element) {
1853
+ if (!this.elements.has(element.name) || this.source === "override" || this.depth === 0 && this.source === "direct") this.elements.set(element.name, {
1854
+ element,
1855
+ schema: this.currentSchema
1856
+ });
1857
+ if (element.substitutionGroup) {
1858
+ const abstractName = stripNsPrefix(element.substitutionGroup);
1859
+ const existing = this.substitutionGroups.get(abstractName) ?? [];
1860
+ existing.push(element);
1861
+ this.substitutionGroups.set(abstractName, existing);
1862
+ }
1863
+ }
1864
+ onAttribute(attr) {
1865
+ if (!this.attributes.has(attr.name) || this.source === "override" || this.depth === 0 && this.source === "direct") this.attributes.set(attr.name, {
1866
+ attr,
1867
+ schema: this.currentSchema
1868
+ });
1869
+ }
1870
+ onGroup(group) {
1871
+ if (!this.groups.has(group.name) || this.source === "redefine" || this.source === "override" || this.depth === 0 && this.source === "direct") this.groups.set(group.name, {
1872
+ group,
1873
+ schema: this.currentSchema
1874
+ });
1875
+ }
1876
+ onAttributeGroup(group) {
1877
+ if (!this.attributeGroups.has(group.name) || this.source === "redefine" || this.source === "override" || this.depth === 0 && this.source === "direct") this.attributeGroups.set(group.name, {
1878
+ group,
1879
+ schema: this.currentSchema
1880
+ });
1881
+ }
1882
+ };
1883
+ /**
1884
+ * Strip namespace prefix from a QName (e.g., "xs:string" -> "string")
1885
+ */
1886
+ function stripNsPrefix(qname) {
1887
+ const colonIndex = qname.indexOf(":");
1888
+ return colonIndex >= 0 ? qname.slice(colonIndex + 1) : qname;
1889
+ }
1890
+ /**
1891
+ * Resolve a schema hierarchy into a flat structure.
1892
+ * Convenience function that creates a SchemaResolver and returns the result.
1893
+ */
1894
+ function resolveSchemaTypes(schema, options = {}) {
1895
+ const resolver = new SchemaResolver();
1896
+ resolver.traverse(schema, options);
1897
+ return resolver.getResolved();
1898
+ }
1899
+
1900
+ //#endregion
1901
+ //#region src/xsd/resolve.ts
1902
+ /**
1903
+ * Collects all schema components into Maps for resolution.
1904
+ *
1905
+ * IMPORTANT: Elements are only collected from schemas with the SAME targetNamespace
1906
+ * as the root schema. This follows XSD semantics where xs:import brings in types
1907
+ * from a different namespace but doesn't merge elements into the current namespace.
1908
+ */
1909
+ var SchemaCollector = class extends SchemaTraverser {
1910
+ complexTypes = /* @__PURE__ */ new Map();
1911
+ simpleTypes = /* @__PURE__ */ new Map();
1912
+ elements = /* @__PURE__ */ new Map();
1913
+ groups = /* @__PURE__ */ new Map();
1914
+ attributeGroups = /* @__PURE__ */ new Map();
1915
+ substitutionGroups = /* @__PURE__ */ new Map();
1916
+ xmlns = /* @__PURE__ */ new Map();
1917
+ onEnterSchema(schema) {
1918
+ if (schema.$xmlns) {
1919
+ for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (!this.xmlns.has(prefix)) this.xmlns.set(prefix, uri);
1920
+ }
1921
+ }
1922
+ onComplexType(ct) {
1923
+ if (!this.complexTypes.has(ct.name)) this.complexTypes.set(ct.name, ct);
1924
+ }
1925
+ onSimpleType(st) {
1926
+ if (!this.simpleTypes.has(st.name)) this.simpleTypes.set(st.name, st);
1927
+ }
1928
+ onElement(element) {
1929
+ const rootNs = this.rootSchema.targetNamespace;
1930
+ const currentNs = this.currentSchema.targetNamespace;
1931
+ const sameOrNoNamespace = currentNs === rootNs || !currentNs;
1932
+ const hasSubstitutionGroup = !!element.substitutionGroup;
1933
+ const isAbstract = !!element.abstract;
1934
+ if ((sameOrNoNamespace || hasSubstitutionGroup || isAbstract) && !this.elements.has(element.name)) this.elements.set(element.name, element);
1935
+ if (element.substitutionGroup) {
1936
+ const abstractName = stripNsPrefix(element.substitutionGroup);
1937
+ const existing = this.substitutionGroups.get(abstractName) ?? [];
1938
+ existing.push(element);
1939
+ this.substitutionGroups.set(abstractName, existing);
1940
+ }
1941
+ }
1942
+ onGroup(group) {
1943
+ if (!this.groups.has(group.name)) this.groups.set(group.name, group);
1944
+ }
1945
+ onAttributeGroup(group) {
1946
+ if (!this.attributeGroups.has(group.name)) this.attributeGroups.set(group.name, group);
1947
+ }
1948
+ };
1949
+ /**
1950
+ * Resolve a schema by merging all imports/includes and expanding all references.
1951
+ * Returns a new self-contained schema with no external dependencies.
1952
+ */
1953
+ function resolveSchema(schema, options = {}) {
1954
+ const { resolveImports = true, resolveIncludes = true, expandExtensions = true, expandSubstitutions = true, filterToRootElements = false, keepImportsRef = false } = options;
1955
+ const collector = new SchemaCollector();
1956
+ collector.traverse(schema, {
1957
+ includeImports: resolveImports,
1958
+ includeIncludes: resolveIncludes
1959
+ });
1960
+ let elements;
1961
+ if (filterToRootElements) {
1962
+ const referencedElements = /* @__PURE__ */ new Set();
1963
+ for (const el of collector.elements.values()) collectElementRefs(el, referencedElements);
1964
+ for (const ct of collector.complexTypes.values()) collectElementRefsFromType(ct, referencedElements);
1965
+ elements = Array.from(collector.elements.values()).filter((el) => {
1966
+ if (el.abstract === true) return false;
1967
+ if (referencedElements.has(el.name)) return false;
1968
+ return true;
1969
+ });
1970
+ } else elements = Array.from(collector.elements.values());
1971
+ let resolvedComplexTypes = Array.from(collector.complexTypes.values());
1972
+ if (expandExtensions) resolvedComplexTypes = resolvedComplexTypes.map((ct) => expandComplexTypeExtension(ct, collector.complexTypes));
1973
+ if (expandSubstitutions) resolvedComplexTypes = resolvedComplexTypes.map((ct) => expandSubstitutionGroupsInType(ct, collector.elements, collector.substitutionGroups));
1974
+ const resolved = {
1975
+ targetNamespace: schema.targetNamespace,
1976
+ elementFormDefault: schema.elementFormDefault,
1977
+ $filename: schema.$filename,
1978
+ $xmlns: collector.xmlns.size > 0 ? Object.fromEntries(collector.xmlns) : schema.$xmlns
1979
+ };
1980
+ if (elements.length > 0) resolved.element = elements;
1981
+ if (resolvedComplexTypes.length > 0) resolved.complexType = resolvedComplexTypes;
1982
+ if (collector.simpleTypes.size > 0) resolved.simpleType = Array.from(collector.simpleTypes.values());
1983
+ if (collector.groups.size > 0) resolved.group = Array.from(collector.groups.values());
1984
+ if (collector.attributeGroups.size > 0) resolved.attributeGroup = Array.from(collector.attributeGroups.values());
1985
+ if (keepImportsRef && schema.$imports) resolved.$imports = schema.$imports;
1986
+ return resolved;
1987
+ }
1988
+ /**
1989
+ * Expand complexContent/extension by merging base type properties.
1990
+ * Uses a visited set to prevent infinite recursion on circular inheritance.
1991
+ */
1992
+ function expandComplexTypeExtension(ct, allTypes, visited = /* @__PURE__ */ new Set()) {
1993
+ const extension = ct.complexContent?.extension;
1994
+ if (!extension?.base) return ct;
1995
+ if (visited.has(ct.name)) return ct;
1996
+ visited.add(ct.name);
1997
+ const mergedElements = [];
1998
+ const mergedAttributes = [];
1999
+ const baseName = stripNsPrefix(extension.base);
2000
+ const baseType = allTypes.get(baseName);
2001
+ if (baseType && !visited.has(baseName)) {
2002
+ const expandedBase = expandComplexTypeExtension(baseType, allTypes, visited);
2003
+ collectElementsFromType(expandedBase, mergedElements);
2004
+ if (expandedBase.attribute) mergedAttributes.push(...expandedBase.attribute);
2005
+ }
2006
+ collectElementsFromGroup(extension.sequence, mergedElements);
2007
+ collectElementsFromGroup(extension.choice, mergedElements);
2008
+ collectElementsFromGroup(extension.all, mergedElements);
2009
+ if (extension.attribute) mergedAttributes.push(...extension.attribute);
2010
+ const flattened = { name: ct.name };
2011
+ if (mergedElements.length > 0) flattened.all = { element: mergedElements };
2012
+ if (mergedAttributes.length > 0) flattened.attribute = mergedAttributes;
2013
+ for (const [key, value] of Object.entries(ct)) if (![
2014
+ "name",
2015
+ "complexContent",
2016
+ "all",
2017
+ "sequence",
2018
+ "choice",
2019
+ "attribute"
2020
+ ].includes(key)) flattened[key] = value;
2021
+ return flattened;
2022
+ }
2023
+ /**
2024
+ * Collect elements from a complex type's content model.
2025
+ */
2026
+ function collectElementsFromType(ct, elements) {
2027
+ collectElementsFromGroup(ct.sequence, elements);
2028
+ collectElementsFromGroup(ct.choice, elements);
2029
+ collectElementsFromGroup(ct.all, elements);
2030
+ }
2031
+ /**
2032
+ * Collect elements from a group (sequence/choice/all).
2033
+ */
2034
+ function collectElementsFromGroup(group, elements) {
2035
+ if (!group?.element) return;
2036
+ elements.push(...group.element);
2037
+ }
2038
+ /**
2039
+ * Expand substitution group references in a complex type.
2040
+ * Replaces abstract element refs with concrete substitute elements.
2041
+ */
2042
+ function expandSubstitutionGroupsInType(ct, allElements, substitutionGroups) {
2043
+ let changed = false;
2044
+ const result = { ...ct };
2045
+ if (ct.sequence) {
2046
+ const expanded = expandSubstitutionGroupsInGroup(ct.sequence, allElements, substitutionGroups);
2047
+ if (expanded !== ct.sequence) {
2048
+ result.sequence = expanded;
2049
+ changed = true;
2050
+ }
2051
+ }
2052
+ if (ct.all) {
2053
+ const expanded = expandSubstitutionGroupsInGroup(ct.all, allElements, substitutionGroups);
2054
+ if (expanded !== ct.all) {
2055
+ result.all = expanded;
2056
+ changed = true;
2057
+ }
2058
+ }
2059
+ if (ct.choice) {
2060
+ const expanded = expandSubstitutionGroupsInGroup(ct.choice, allElements, substitutionGroups);
2061
+ if (expanded !== ct.choice) {
2062
+ result.choice = expanded;
2063
+ changed = true;
2064
+ }
2065
+ }
2066
+ return changed ? result : ct;
2067
+ }
2068
+ /**
2069
+ * Expand substitution groups in a group (sequence/all/choice).
2070
+ */
2071
+ function expandSubstitutionGroupsInGroup(group, allElements, substitutionGroups) {
2072
+ if (!group.element) return group;
2073
+ const expandedElements = [];
2074
+ let hasChanges = false;
2075
+ for (const el of group.element) {
2076
+ if (el.ref) {
2077
+ const refName = stripNsPrefix(el.ref);
2078
+ if (allElements.get(refName)?.abstract) {
2079
+ const substitutes = substitutionGroups.get(refName);
2080
+ if (substitutes && substitutes.length > 0) {
2081
+ for (const sub of substitutes) expandedElements.push({
2082
+ name: sub.name,
2083
+ type: sub.type,
2084
+ minOccurs: el.minOccurs ?? 0,
2085
+ maxOccurs: el.maxOccurs
2086
+ });
2087
+ hasChanges = true;
2088
+ continue;
2089
+ }
2090
+ }
2091
+ }
2092
+ expandedElements.push(el);
2093
+ }
2094
+ if (!hasChanges) return group;
2095
+ return {
2096
+ ...group,
2097
+ element: expandedElements
2098
+ };
2099
+ }
2100
+ /**
2101
+ * Get all substitutes for an abstract element.
2102
+ */
2103
+ function getSubstitutes(abstractElementName, schema) {
2104
+ const collector = new SchemaCollector();
2105
+ collector.traverse(schema);
2106
+ return collector.substitutionGroups.get(abstractElementName) ?? [];
2107
+ }
2108
+ /**
2109
+ * Collect element refs from an element's nested structure
2110
+ */
2111
+ function collectElementRefs(el, refs) {
2112
+ const record = el;
2113
+ if (record.complexType) collectElementRefsFromType(record.complexType, refs);
2114
+ }
2115
+ /**
2116
+ * Recursively collect element refs from a complex type
2117
+ */
2118
+ function collectElementRefsFromType(ct, refs) {
2119
+ const record = ct;
2120
+ for (const groupKey of [
2121
+ "sequence",
2122
+ "all",
2123
+ "choice"
2124
+ ]) {
2125
+ const group = record[groupKey];
2126
+ if (group?.element) {
2127
+ const elements = group.element;
2128
+ for (const el of elements) {
2129
+ if (el.ref) {
2130
+ const refName = stripNsPrefix(el.ref);
2131
+ refs.add(refName);
2132
+ }
2133
+ if (el.complexType) collectElementRefsFromType(el.complexType, refs);
2134
+ }
2135
+ }
2136
+ }
2137
+ if (record.complexContent) {
2138
+ const cc = record.complexContent;
2139
+ if (cc.extension) collectElementRefsFromType(cc.extension, refs);
2140
+ }
2141
+ }
2142
+
2143
+ //#endregion
2144
+ //#region src/xsd/loader.ts
2145
+ /**
2146
+ * Schema Loader - Load and parse XSD files from disk
2147
+ *
2148
+ * Simple loader that reads XSD files and parses them into Schema objects.
2149
+ * Resolution of imports/includes is handled by the resolver.
2150
+ */
2151
+ /**
2152
+ * Default XSD loader - reads from filesystem
2153
+ */
2154
+ function defaultLoader(schemaLocation, basePath) {
2155
+ const fullPath = resolve(basePath, schemaLocation);
2156
+ if (!existsSync(fullPath)) return null;
2157
+ return readFileSync(fullPath, "utf-8");
2158
+ }
2159
+ /**
2160
+ * Load and parse a single XSD file.
2161
+ *
2162
+ * @param schemaPath - Path to the XSD file
2163
+ * @param options - Loader options
2164
+ * @param options.autoLink - Populate $imports/$includes with loaded schemas (preserves structure)
2165
+ * @param options.autoResolve - Flatten into single schema with all types merged (implies autoLink)
2166
+ * @returns Parsed schema
2167
+ *
2168
+ * @example
2169
+ * ```typescript
2170
+ * // Just parse - no linking
2171
+ * const schema = loadSchema('/path/to/schema.xsd');
2172
+ *
2173
+ * // Link - populate $imports/$includes (preserves multi-schema structure)
2174
+ * const linked = loadSchema('/path/to/schema.xsd', { autoLink: true });
2175
+ * // linked.$imports contains actual Schema objects
2176
+ *
2177
+ * // Resolve - flatten everything into one schema
2178
+ * const resolved = loadSchema('/path/to/schema.xsd', { autoResolve: true });
2179
+ * // resolved has all types merged, no $imports/$includes
2180
+ * ```
2181
+ */
2182
+ function loadSchema(schemaPath, options = {}) {
2183
+ const { basePath = dirname(schemaPath), loader = defaultLoader, autoLink = false, autoResolve = false, throwOnMissing = false } = options;
2184
+ const content = loader(schemaPath, basePath);
2185
+ if (!content) throw new Error(`Failed to load schema: ${schemaPath}`);
2186
+ let schema = parseXsd(content);
2187
+ Object.assign(schema, { $filename: schemaPath });
2188
+ if (autoLink || autoResolve) linkSchema(schema, {
2189
+ basePath,
2190
+ loader,
2191
+ throwOnMissing
2192
+ });
2193
+ if (autoResolve) schema = resolveSchema(schema);
2194
+ return schema;
2195
+ }
2196
+ /**
2197
+ * Load and parse XSD content from a string.
2198
+ */
2199
+ function parseSchemaContent(content, filename) {
2200
+ const schema = parseXsd(content);
2201
+ if (filename) Object.assign(schema, { $filename: filename });
2202
+ return schema;
2203
+ }
2204
+ /**
2205
+ * Create a schema loader function that can be passed to the resolver.
2206
+ * The resolver will call this to load schemas referenced by schemaLocation.
2207
+ */
2208
+ function createSchemaLoader(basePath, loader = defaultLoader) {
2209
+ const cache = /* @__PURE__ */ new Map();
2210
+ return (schemaLocation) => {
2211
+ const fullPath = resolve(basePath, schemaLocation);
2212
+ const cached = cache.get(fullPath);
2213
+ if (cached) return cached;
2214
+ const content = loader(schemaLocation, basePath);
2215
+ if (!content) return null;
2216
+ const schema = parseXsd(content);
2217
+ Object.assign(schema, { $filename: schemaLocation });
2218
+ cache.set(fullPath, schema);
2219
+ return schema;
2220
+ };
2221
+ }
2222
+ /**
2223
+ * Link a schema by resolving all schemaLocation references.
2224
+ *
2225
+ * Processes:
2226
+ * - xs:import → populates $imports
2227
+ * - xs:include → populates $includes
2228
+ * - xs:redefine → loads base schema, keeps redefinitions in redefine array
2229
+ * - xs:override → loads base schema, keeps overrides in override array
2230
+ *
2231
+ * @param schema - Schema to link (will be mutated with $imports/$includes)
2232
+ * @param options - Link options including basePath for resolving paths
2233
+ * @returns The same schema with $imports and $includes populated
2234
+ *
2235
+ * @example
2236
+ * ```typescript
2237
+ * const schema = parseXsd(xsdContent);
2238
+ * linkSchema(schema, { basePath: '/path/to/xsd/files' });
2239
+ * // schema.$imports and schema.$includes are now populated
2240
+ * ```
2241
+ */
2242
+ function linkSchema(schema, options) {
2243
+ const { basePath, loader = defaultLoader, throwOnMissing = true } = options;
2244
+ const cache = /* @__PURE__ */ new Map();
2245
+ const inProgress = /* @__PURE__ */ new Set();
2246
+ const loadAndLink = (schemaLocation, currentBasePath) => {
2247
+ const fullPath = resolve(currentBasePath, schemaLocation);
2248
+ const cached = cache.get(fullPath);
2249
+ if (cached) return cached;
2250
+ if (inProgress.has(fullPath)) return cache.get(fullPath) ?? null;
2251
+ const content = loader(schemaLocation, currentBasePath);
2252
+ if (!content) {
2253
+ if (throwOnMissing) throw new Error(`Failed to load schema: ${schemaLocation} (resolved: ${fullPath})`);
2254
+ return null;
2255
+ }
2256
+ const loadedSchema = parseXsd(content);
2257
+ Object.assign(loadedSchema, { $filename: schemaLocation });
2258
+ inProgress.add(fullPath);
2259
+ cache.set(fullPath, loadedSchema);
2260
+ linkSchemaInternal(loadedSchema, dirname(fullPath));
2261
+ inProgress.delete(fullPath);
2262
+ return loadedSchema;
2263
+ };
2264
+ const linkSchemaInternal = (s, currentBasePath) => {
2265
+ const imports = [];
2266
+ const includes = [];
2267
+ if (s.import) {
2268
+ for (const imp of s.import) if (imp.schemaLocation) {
2269
+ const linked = loadAndLink(imp.schemaLocation, currentBasePath);
2270
+ if (linked) imports.push(linked);
2271
+ }
2272
+ }
2273
+ if (s.include) {
2274
+ for (const inc of s.include) if (inc.schemaLocation) {
2275
+ const linked = loadAndLink(inc.schemaLocation, currentBasePath);
2276
+ if (linked) includes.push(linked);
2277
+ }
2278
+ }
2279
+ if (s.redefine) {
2280
+ for (const redef of s.redefine) if (redef.schemaLocation) {
2281
+ const linked = loadAndLink(redef.schemaLocation, currentBasePath);
2282
+ if (linked) Object.assign(redef, { $schema: linked });
2283
+ }
2284
+ }
2285
+ if (s.override) {
2286
+ for (const ovr of s.override) if (ovr.schemaLocation) {
2287
+ const linked = loadAndLink(ovr.schemaLocation, currentBasePath);
2288
+ if (linked) Object.assign(ovr, { $schema: linked });
2289
+ }
2290
+ }
2291
+ if (imports.length > 0) Object.assign(s, { $imports: imports });
2292
+ if (includes.length > 0) Object.assign(s, { $includes: includes });
2293
+ };
2294
+ linkSchemaInternal(schema, basePath);
2295
+ return schema;
2296
+ }
2297
+ /**
2298
+ * Load and link a schema from a file path.
2299
+ * Convenience function that combines loadSchema + linkSchema.
2300
+ *
2301
+ * @param schemaPath - Path to the XSD file
2302
+ * @param options - Optional loader options
2303
+ * @returns Fully linked schema with $imports and $includes populated
2304
+ *
2305
+ * @example
2306
+ * ```typescript
2307
+ * const schema = loadAndLinkSchema('/path/to/schema.xsd');
2308
+ * // schema.$imports and schema.$includes are populated
2309
+ * // Ready for type inference or resolution
2310
+ * ```
2311
+ */
2312
+ function loadAndLinkSchema(schemaPath, options = {}) {
2313
+ const basePath = dirname(schemaPath);
2314
+ return linkSchema(loadSchema(schemaPath, {
2315
+ ...options,
2316
+ basePath
2317
+ }), {
2318
+ basePath,
2319
+ loader: options.loader
2320
+ });
2321
+ }
2322
+
2323
+ //#endregion
2324
+ //#region src/codegen/runner.ts
2325
+ /**
2326
+ * Config Runner
2327
+ *
2328
+ * Executes the generator pipeline based on configuration.
2329
+ */
2330
+ /**
2331
+ * Run the codegen pipeline
2332
+ */
2333
+ async function runCodegen(config, options) {
2334
+ const { rootDir, dryRun = false, verbose = false } = options;
2335
+ const result = {
2336
+ files: [],
2337
+ schemas: [],
2338
+ errors: []
2339
+ };
2340
+ const log = verbose ? console.log.bind(console) : () => {};
2341
+ const sources = {};
2342
+ for (const [name, sourceConfig] of Object.entries(config.sources)) {
2343
+ const xsdDir = isAbsolute(sourceConfig.xsdDir) ? sourceConfig.xsdDir : join(rootDir, sourceConfig.xsdDir);
2344
+ let schemas = sourceConfig.schemas;
2345
+ if (sourceConfig.autoLink) schemas = discoverDependentSchemas(sourceConfig.schemas, xsdDir, log);
2346
+ sources[name] = {
2347
+ name,
2348
+ xsdDir,
2349
+ outputDir: isAbsolute(sourceConfig.outputDir) ? sourceConfig.outputDir : join(rootDir, sourceConfig.outputDir),
2350
+ schemas
2351
+ };
2352
+ }
2353
+ const setupCtx = {
2354
+ sources,
2355
+ rootDir
2356
+ };
2357
+ if (config.clean) {
2358
+ log(`\n🧹 Cleaning output directories...`);
2359
+ for (const source of Object.values(sources)) if (existsSync(source.outputDir)) {
2360
+ rmSync(source.outputDir, {
2361
+ recursive: true,
2362
+ force: true
2363
+ });
2364
+ log(` ✅ Cleaned ${relative(rootDir, source.outputDir)}`);
2365
+ }
2366
+ }
2367
+ if (config.beforeAll) {
2368
+ log(`\n🔧 Running beforeAll hook...`);
2369
+ await config.beforeAll({
2370
+ sources,
2371
+ rootDir
2372
+ });
2373
+ }
2374
+ for (const generator of config.generators) if (generator.setup) {
2375
+ log(`[${generator.name}] Running setup...`);
2376
+ await generator.setup(setupCtx);
2377
+ }
2378
+ const processedSchemas = /* @__PURE__ */ new Map();
2379
+ const globalAllSchemas = /* @__PURE__ */ new Map();
2380
+ /**
2381
+ * Recursively discover and parse schemas referenced via xs:include or xs:redefine.
2382
+ * This ensures schemas like types/devc.xsd are in globalAllSchemas when devc.xsd references them.
2383
+ *
2384
+ * @param schema - The parsed schema object
2385
+ * @param xsdDir - The root XSD directory (e.g., '.xsd')
2386
+ * @param currentXsdPath - The path of the current XSD file (for resolving relative paths)
2387
+ * @param sourceName - The source name for logging
2388
+ * @param discovered - Set of already discovered schema names
2389
+ */
2390
+ function discoverReferencedSchemas(schema, xsdDir, currentXsdPath, sourceName, discovered = /* @__PURE__ */ new Set()) {
2391
+ const includes = schema.include;
2392
+ const redefines = schema.redefine;
2393
+ const refs = [...includes ?? [], ...redefines ?? []];
2394
+ for (const ref of refs) {
2395
+ if (!ref.schemaLocation) continue;
2396
+ const schemaNameWithPath = ref.schemaLocation.replace(/\.xsd$/, "");
2397
+ if (discovered.has(schemaNameWithPath) || globalAllSchemas.has(schemaNameWithPath)) continue;
2398
+ discovered.add(schemaNameWithPath);
2399
+ const currentXsdDir = dirname(currentXsdPath);
2400
+ const refXsdPath = join(currentXsdDir, ref.schemaLocation);
2401
+ if (!existsSync(refXsdPath)) {
2402
+ log(` ⚠️ Referenced schema not found: ${ref.schemaLocation} (resolved from ${currentXsdDir})`);
2403
+ continue;
2404
+ }
2405
+ try {
2406
+ const refXsdContent = readFileSync(refXsdPath, "utf-8");
2407
+ const refSchema = parseXsd(refXsdContent);
2408
+ refSchema.$filename = ref.schemaLocation;
2409
+ const refSchemaInfo = {
2410
+ name: schemaNameWithPath,
2411
+ xsdContent: refXsdContent,
2412
+ schema: refSchema,
2413
+ sourceName,
2414
+ xsdPath: refXsdPath
2415
+ };
2416
+ globalAllSchemas.set(schemaNameWithPath, refSchemaInfo);
2417
+ log(` 📎 Auto-discovered: ${schemaNameWithPath}`);
2418
+ discoverReferencedSchemas(refSchema, xsdDir, refXsdPath, sourceName, discovered);
2419
+ } catch (error) {
2420
+ const err = error instanceof Error ? error : new Error(String(error));
2421
+ log(` ⚠️ Failed to parse referenced schema ${ref.schemaLocation}: ${err.message}`);
2422
+ }
2423
+ }
2424
+ }
2425
+ for (const [sourceName, source] of Object.entries(sources)) {
2426
+ log(`\n📦 Processing source: ${sourceName}`);
2427
+ const schemaInfos = [];
2428
+ for (const schemaName of source.schemas) {
2429
+ const xsdPath = join(source.xsdDir, `${schemaName}.xsd`);
2430
+ if (!existsSync(xsdPath)) {
2431
+ log(` ⚠️ Skipping ${schemaName} - XSD not found`);
2432
+ continue;
2433
+ }
2434
+ try {
2435
+ const xsdContent = readFileSync(xsdPath, "utf-8");
2436
+ const schema = parseXsd(xsdContent);
2437
+ schema.$filename = `${schemaName}.xsd`;
2438
+ linkSchema(schema, {
2439
+ basePath: dirname(xsdPath),
2440
+ throwOnMissing: false
2441
+ });
2442
+ const schemaInfo = {
2443
+ name: schemaName,
2444
+ xsdContent,
2445
+ schema,
2446
+ sourceName,
2447
+ xsdPath
2448
+ };
2449
+ schemaInfos.push(schemaInfo);
2450
+ globalAllSchemas.set(schemaName, schemaInfo);
2451
+ result.schemas.push({
2452
+ name: schemaName,
2453
+ source: sourceName
2454
+ });
2455
+ discoverReferencedSchemas(schema, source.xsdDir, xsdPath, sourceName);
2456
+ } catch (error) {
2457
+ const err = error instanceof Error ? error : new Error(String(error));
2458
+ log(` ❌ Failed to parse ${schemaName}: ${err.message}`);
2459
+ result.errors.push({
2460
+ schema: schemaName,
2461
+ source: sourceName,
2462
+ error: err
2463
+ });
2464
+ }
2465
+ }
2466
+ processedSchemas.set(sourceName, schemaInfos);
2467
+ }
2468
+ for (const [sourceName, source] of Object.entries(sources)) {
2469
+ const schemaInfos = processedSchemas.get(sourceName) ?? [];
2470
+ for (const schemaInfo of schemaInfos) {
2471
+ const transformCtx = {
2472
+ schema: schemaInfo,
2473
+ source,
2474
+ allSchemas: globalAllSchemas,
2475
+ allSources: sources,
2476
+ rootDir,
2477
+ resolveImport: createImportResolver(schemaInfo, source, sources, config)
2478
+ };
2479
+ for (const generator of config.generators) if (generator.transform) try {
2480
+ const files = await generator.transform(transformCtx);
2481
+ for (const file of files) {
2482
+ const fullPath = join(source.outputDir, file.path);
2483
+ if (!dryRun) {
2484
+ mkdirSync(dirname(fullPath), { recursive: true });
2485
+ writeFileSync(fullPath, file.content);
2486
+ }
2487
+ result.files.push({
2488
+ path: fullPath,
2489
+ source: sourceName
2490
+ });
2491
+ log(` ✅ [${generator.name}] Generated ${file.path}`);
2492
+ }
2493
+ } catch (error) {
2494
+ const err = error instanceof Error ? error : new Error(String(error));
2495
+ log(` ❌ [${generator.name}] Failed ${schemaInfo.name}: ${err.message}`);
2496
+ result.errors.push({
2497
+ schema: schemaInfo.name,
2498
+ source: sourceName,
2499
+ error: err
2500
+ });
2501
+ }
2502
+ }
2503
+ }
2504
+ const finalizeCtx = {
2505
+ processedSchemas,
2506
+ sources,
2507
+ rootDir
2508
+ };
2509
+ for (const generator of config.generators) if (generator.finalize) try {
2510
+ log(`\n[${generator.name}] Running finalize...`);
2511
+ const files = await generator.finalize(finalizeCtx);
2512
+ for (const file of files) for (const [sourceName, source] of Object.entries(sources)) {
2513
+ const fullPath = join(source.outputDir, file.path);
2514
+ if (!dryRun) {
2515
+ mkdirSync(dirname(fullPath), { recursive: true });
2516
+ writeFileSync(fullPath, file.content);
2517
+ }
2518
+ result.files.push({
2519
+ path: fullPath,
2520
+ source: sourceName
2521
+ });
2522
+ log(` ✅ [${generator.name}] Generated ${file.path} for ${sourceName}`);
2523
+ }
2524
+ } catch (error) {
2525
+ const err = error instanceof Error ? error : new Error(String(error));
2526
+ log(` ❌ [${generator.name}] Finalize failed: ${err.message}`);
2527
+ result.errors.push({ error: err });
2528
+ }
2529
+ if (config.afterAll) {
2530
+ log(`\n🔧 Running afterAll hook...`);
2531
+ const afterAllCtx = {
2532
+ sources,
2533
+ rootDir,
2534
+ processedSchemas,
2535
+ generatedFiles: result.files.map((f) => ({
2536
+ path: f.path,
2537
+ content: ""
2538
+ }))
2539
+ };
2540
+ const extraFiles = await config.afterAll(afterAllCtx);
2541
+ if (extraFiles && Array.isArray(extraFiles)) for (const file of extraFiles) {
2542
+ const fullPath = join(rootDir, file.path);
2543
+ if (!dryRun) {
2544
+ mkdirSync(dirname(fullPath), { recursive: true });
2545
+ writeFileSync(fullPath, file.content);
2546
+ }
2547
+ result.files.push({
2548
+ path: fullPath,
2549
+ source: "afterAll"
2550
+ });
2551
+ log(` ✅ [afterAll] Generated ${file.path}`);
2552
+ }
2553
+ }
2554
+ return result;
2555
+ }
2556
+ function createImportResolver(currentSchema, currentSource, allSources, config) {
2557
+ const ext = config.importExtension ?? "";
2558
+ return (schemaLocation) => {
2559
+ const schemaPath = schemaLocation.replace(/\.xsd$/, "");
2560
+ const schemaBaseName = schemaPath.replace(/^.*\//, "");
2561
+ const currentSchemaDir = dirname(currentSchema.name);
2562
+ const normalizedPath = (currentSchemaDir !== "." ? join(currentSchemaDir, schemaPath).replaceAll(/\\/g, "/") : schemaPath).split("/").reduce((acc, part) => {
2563
+ if (part === "..") acc.pop();
2564
+ else if (part !== ".") acc.push(part);
2565
+ return acc;
2566
+ }, []).join("/");
2567
+ if (currentSource.schemas.includes(normalizedPath)) {
2568
+ const fromDir = dirname(currentSchema.name);
2569
+ const toPath = normalizedPath;
2570
+ const relImport = fromDir === dirname(toPath) ? `./${basename(toPath)}${ext}` : relative(fromDir || ".", toPath).replaceAll(/\\/g, "/") || `./${basename(toPath)}`;
2571
+ return relImport.startsWith(".") ? `${relImport}${ext}` : `./${relImport}${ext}`;
2572
+ }
2573
+ if (currentSource.schemas.includes(schemaPath)) return `./${schemaPath}${ext}`;
2574
+ if (currentSource.schemas.includes(schemaBaseName)) return `./${schemaBaseName}${ext}`;
2575
+ for (const [sourceName, source] of Object.entries(allSources)) {
2576
+ if (sourceName === currentSource.name) continue;
2577
+ if (source.schemas.includes(normalizedPath)) return `${relative(currentSource.outputDir, source.outputDir)}/${normalizedPath}${ext}`.replaceAll(/\\/g, "/");
2578
+ if (source.schemas.includes(schemaPath)) return `${relative(currentSource.outputDir, source.outputDir)}/${schemaPath}${ext}`.replaceAll(/\\/g, "/");
2579
+ if (source.schemas.includes(schemaBaseName)) return `${relative(currentSource.outputDir, source.outputDir)}/${schemaBaseName}${ext}`.replaceAll(/\\/g, "/");
2580
+ }
2581
+ return null;
2582
+ };
2583
+ }
2584
+ /**
2585
+ * Discover all dependent schemas by recursively parsing XSD files
2586
+ * and extracting schemaLocation from xs:import, xs:include, xs:redefine
2587
+ */
2588
+ function discoverDependentSchemas(entrySchemas, xsdDir, log) {
2589
+ const discovered = /* @__PURE__ */ new Set();
2590
+ const queue = [...entrySchemas];
2591
+ while (queue.length > 0) {
2592
+ const schemaName = queue.shift();
2593
+ if (!schemaName) continue;
2594
+ if (discovered.has(schemaName)) continue;
2595
+ const xsdPath = join(xsdDir, `${schemaName}.xsd`);
2596
+ if (!existsSync(xsdPath)) throw new Error(`Schema not found: ${schemaName}.xsd (resolved: ${xsdPath})`);
2597
+ discovered.add(schemaName);
2598
+ try {
2599
+ const deps = extractSchemaLocations(parseXsd(readFileSync(xsdPath, "utf-8")), xsdDir, schemaName);
2600
+ for (const dep of deps) if (!discovered.has(dep)) {
2601
+ queue.push(dep);
2602
+ log(` 🔗 Discovered dependency: ${dep} (from ${schemaName})`);
2603
+ }
2604
+ } catch {
2605
+ log(` ❌ Failed to parse ${schemaName} for dependency discovery`);
2606
+ }
2607
+ }
2608
+ return Array.from(discovered);
2609
+ }
2610
+ /**
2611
+ * Extract schema names from schemaLocation attributes
2612
+ */
2613
+ function extractSchemaLocations(schema, xsdDir, currentSchema) {
2614
+ const locations = [];
2615
+ const currentDir = dirname(join(xsdDir, `${currentSchema}.xsd`));
2616
+ const imports = schema.import;
2617
+ if (imports) {
2618
+ for (const imp of imports) if (imp.schemaLocation) {
2619
+ const name = resolveSchemaName(imp.schemaLocation, currentDir, xsdDir);
2620
+ if (name) locations.push(name);
2621
+ }
2622
+ }
2623
+ const includes = schema.include;
2624
+ if (includes) {
2625
+ for (const inc of includes) if (inc.schemaLocation) {
2626
+ const name = resolveSchemaName(inc.schemaLocation, currentDir, xsdDir);
2627
+ if (name) locations.push(name);
2628
+ }
2629
+ }
2630
+ const redefines = schema.redefine;
2631
+ if (redefines) {
2632
+ for (const red of redefines) if (red.schemaLocation) {
2633
+ const name = resolveSchemaName(red.schemaLocation, currentDir, xsdDir);
2634
+ if (name) locations.push(name);
2635
+ }
2636
+ }
2637
+ return locations;
2638
+ }
2639
+ /**
2640
+ * Resolve schemaLocation to a schema name relative to xsdDir
2641
+ */
2642
+ function resolveSchemaName(schemaLocation, currentDir, xsdDir) {
2643
+ const fullPath = join(currentDir, schemaLocation);
2644
+ const name = relative(xsdDir, fullPath).replace(/\.xsd$/, "");
2645
+ if (existsSync(fullPath)) return name;
2646
+ return null;
2647
+ }
2648
+
2649
+ //#endregion
2650
+ export { getAllChildElements as _, loadAndLinkSchema as a, getLocalName as b, getSubstitutes as c, SchemaTraverser as d, resolveSchemaTypes as f, parseXsd as g, buildXsd as h, linkSchema as i, resolveSchema as l, resolveImports as m, createSchemaLoader as n, loadSchema as o, linkSchemas as p, defaultLoader as r, parseSchemaContent as s, runCodegen as t, SchemaResolver as u, getAttributeValue as v, getTextContent as x, getChildElements as y };
2651
+ //# sourceMappingURL=runner-CRhT3smd.mjs.map