@abapify/ts-xsd 0.4.0 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1923 @@
1
+ import { _ as getLocalName, a as loadAndLinkSchema, c as getSubstitutes, d as SchemaTraverser, f as resolveSchemaTypes, g as getChildElements, h as getAttributeValue, i as linkSchema, l as resolveSchema, m as getAllChildElements, n as createSchemaLoader, o as loadSchema, p as parseXsd, r as defaultLoader, s as parseSchemaContent, t as runCodegen, u as SchemaResolver, v as getTextContent } from "./runner-BSGqj8LM.mjs";
2
+ import { n as generateSchemaLiteral, t as generateSchemaFile } from "./generate-Br6rW6sE.mjs";
3
+ import { n as deriveRootTypeName, r as generateInterfaces, t as defineConfig } from "./types-Ch0GQQ5n.mjs";
4
+ import { DOMImplementation, DOMParser, XMLSerializer } from "@xmldom/xmldom";
5
+
6
+ //#region src/xsd/build.ts
7
+ /**
8
+ * Build an XSD string from a typed Schema object
9
+ */
10
+ function buildXsd(schema, options = {}) {
11
+ const prefix = options.prefix ?? "xs";
12
+ const pretty = options.pretty ?? true;
13
+ const ctx = {
14
+ prefix,
15
+ pretty,
16
+ indent: options.indent ?? " ",
17
+ level: 0
18
+ };
19
+ const lines = [];
20
+ lines.push("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
21
+ lines.push(buildSchema(schema, ctx));
22
+ return lines.join(pretty ? "\n" : "");
23
+ }
24
+ function buildSchema(schema, ctx) {
25
+ const attrs = [];
26
+ if (schema.$xmlns) for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (prefix === "") attrs.push(`xmlns="${uri}"`);
27
+ else attrs.push(`xmlns:${prefix}="${uri}"`);
28
+ addAttr(attrs, "id", schema.id);
29
+ addAttr(attrs, "targetNamespace", schema.targetNamespace);
30
+ addAttr(attrs, "version", schema.version);
31
+ addAttr(attrs, "finalDefault", schema.finalDefault);
32
+ addAttr(attrs, "blockDefault", schema.blockDefault);
33
+ addAttr(attrs, "attributeFormDefault", schema.attributeFormDefault);
34
+ addAttr(attrs, "elementFormDefault", schema.elementFormDefault);
35
+ addAttr(attrs, "defaultAttributes", schema.defaultAttributes);
36
+ addAttr(attrs, "xpathDefaultNamespace", schema.xpathDefaultNamespace);
37
+ addAttr(attrs, "xml:lang", schema["xml:lang"]);
38
+ const children = [];
39
+ const childCtx = {
40
+ ...ctx,
41
+ level: ctx.level + 1
42
+ };
43
+ if (schema.annotation) for (const ann of schema.annotation) children.push(buildAnnotation(ann, childCtx));
44
+ if (schema.include) for (const inc of schema.include) children.push(buildInclude(inc, childCtx));
45
+ if (schema.import) for (const imp of schema.import) children.push(buildImport(imp, childCtx));
46
+ if (schema.redefine) for (const red of schema.redefine) children.push(buildRedefine(red, childCtx));
47
+ if (schema.override) for (const ovr of schema.override) children.push(buildOverride(ovr, childCtx));
48
+ if (schema.defaultOpenContent) children.push(buildDefaultOpenContent(schema.defaultOpenContent, childCtx));
49
+ if (schema.simpleType && Array.isArray(schema.simpleType)) for (const st of schema.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
50
+ if (schema.complexType && Array.isArray(schema.complexType)) for (const ct of schema.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
51
+ if (schema.group) for (const grp of schema.group) children.push(buildNamedGroup(grp, childCtx));
52
+ if (schema.attributeGroup) for (const ag of schema.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
53
+ if (schema.element) for (const el of schema.element) children.push(buildTopLevelElement(el, childCtx));
54
+ if (schema.attribute) for (const attr of schema.attribute) children.push(buildTopLevelAttribute(attr, childCtx));
55
+ if (schema.notation) for (const not of schema.notation) children.push(buildNotation(not, childCtx));
56
+ return buildElement$1(`${ctx.prefix}:schema`, attrs, children, ctx);
57
+ }
58
+ function buildAnnotation(ann, ctx) {
59
+ const attrs = [];
60
+ addAttr(attrs, "id", ann.id);
61
+ const children = [];
62
+ const childCtx = {
63
+ ...ctx,
64
+ level: ctx.level + 1
65
+ };
66
+ if (ann.appinfo) for (const ai of ann.appinfo) children.push(buildAppinfo(ai, childCtx));
67
+ if (ann.documentation) for (const doc of ann.documentation) children.push(buildDocumentation(doc, childCtx));
68
+ return buildElement$1(`${ctx.prefix}:annotation`, attrs, children, ctx);
69
+ }
70
+ function buildDocumentation(doc, ctx) {
71
+ const attrs = [];
72
+ addAttr(attrs, "source", doc.source);
73
+ addAttr(attrs, "xml:lang", doc["xml:lang"]);
74
+ if (doc._text) return buildElementWithText(`${ctx.prefix}:documentation`, attrs, doc._text, ctx);
75
+ return buildElement$1(`${ctx.prefix}:documentation`, attrs, [], ctx);
76
+ }
77
+ function buildAppinfo(ai, ctx) {
78
+ const attrs = [];
79
+ addAttr(attrs, "source", ai.source);
80
+ if (ai._text) return buildElementWithText(`${ctx.prefix}:appinfo`, attrs, ai._text, ctx);
81
+ return buildElement$1(`${ctx.prefix}:appinfo`, attrs, [], ctx);
82
+ }
83
+ function buildInclude(inc, ctx) {
84
+ const attrs = [];
85
+ addAttr(attrs, "id", inc.id);
86
+ addAttr(attrs, "schemaLocation", inc.schemaLocation);
87
+ const children = [];
88
+ if (inc.annotation) children.push(buildAnnotation(inc.annotation, {
89
+ ...ctx,
90
+ level: ctx.level + 1
91
+ }));
92
+ return buildElement$1(`${ctx.prefix}:include`, attrs, children, ctx);
93
+ }
94
+ function buildImport(imp, ctx) {
95
+ const attrs = [];
96
+ addAttr(attrs, "id", imp.id);
97
+ addAttr(attrs, "namespace", imp.namespace);
98
+ addAttr(attrs, "schemaLocation", imp.schemaLocation);
99
+ const children = [];
100
+ if (imp.annotation) children.push(buildAnnotation(imp.annotation, {
101
+ ...ctx,
102
+ level: ctx.level + 1
103
+ }));
104
+ return buildElement$1(`${ctx.prefix}:import`, attrs, children, ctx);
105
+ }
106
+ function buildRedefine(red, ctx) {
107
+ const attrs = [];
108
+ addAttr(attrs, "id", red.id);
109
+ addAttr(attrs, "schemaLocation", red.schemaLocation);
110
+ const children = [];
111
+ const childCtx = {
112
+ ...ctx,
113
+ level: ctx.level + 1
114
+ };
115
+ if (red.annotation) for (const ann of red.annotation) children.push(buildAnnotation(ann, childCtx));
116
+ if (red.simpleType) for (const st of red.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
117
+ if (red.complexType) for (const ct of red.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
118
+ if (red.group) for (const grp of red.group) children.push(buildNamedGroup(grp, childCtx));
119
+ if (red.attributeGroup) for (const ag of red.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
120
+ return buildElement$1(`${ctx.prefix}:redefine`, attrs, children, ctx);
121
+ }
122
+ function buildOverride(ovr, ctx) {
123
+ const attrs = [];
124
+ addAttr(attrs, "id", ovr.id);
125
+ addAttr(attrs, "schemaLocation", ovr.schemaLocation);
126
+ const children = [];
127
+ const childCtx = {
128
+ ...ctx,
129
+ level: ctx.level + 1
130
+ };
131
+ if (ovr.annotation) for (const ann of ovr.annotation) children.push(buildAnnotation(ann, childCtx));
132
+ if (ovr.simpleType) for (const st of ovr.simpleType) children.push(buildTopLevelSimpleType(st, childCtx));
133
+ if (ovr.complexType) for (const ct of ovr.complexType) children.push(buildTopLevelComplexType(ct, childCtx));
134
+ if (ovr.group) for (const grp of ovr.group) children.push(buildNamedGroup(grp, childCtx));
135
+ if (ovr.attributeGroup) for (const ag of ovr.attributeGroup) children.push(buildNamedAttributeGroup(ag, childCtx));
136
+ if (ovr.element) for (const el of ovr.element) children.push(buildTopLevelElement(el, childCtx));
137
+ if (ovr.attribute) for (const attr of ovr.attribute) children.push(buildTopLevelAttribute(attr, childCtx));
138
+ if (ovr.notation) for (const not of ovr.notation) children.push(buildNotation(not, childCtx));
139
+ return buildElement$1(`${ctx.prefix}:override`, attrs, children, ctx);
140
+ }
141
+ function buildTopLevelElement(el, ctx) {
142
+ const attrs = [];
143
+ addAttr(attrs, "id", el.id);
144
+ addAttr(attrs, "name", el.name);
145
+ addAttr(attrs, "type", el.type);
146
+ addAttr(attrs, "substitutionGroup", el.substitutionGroup);
147
+ addAttr(attrs, "default", el.default);
148
+ addAttr(attrs, "fixed", el.fixed);
149
+ addBoolAttr(attrs, "nillable", el.nillable);
150
+ addBoolAttr(attrs, "abstract", el.abstract);
151
+ addAttr(attrs, "final", el.final);
152
+ addAttr(attrs, "block", el.block);
153
+ const children = [];
154
+ const childCtx = {
155
+ ...ctx,
156
+ level: ctx.level + 1
157
+ };
158
+ if (el.annotation) children.push(buildAnnotation(el.annotation, childCtx));
159
+ if (el.simpleType) children.push(buildLocalSimpleType(el.simpleType, childCtx));
160
+ if (el.complexType) children.push(buildLocalComplexType(el.complexType, childCtx));
161
+ if (el.alternative) for (const alt of el.alternative) children.push(buildAlternative(alt, childCtx));
162
+ if (el.unique) for (const u of el.unique) children.push(buildUnique(u, childCtx));
163
+ if (el.key) for (const k of el.key) children.push(buildKey(k, childCtx));
164
+ if (el.keyref) for (const kr of el.keyref) children.push(buildKeyref(kr, childCtx));
165
+ return buildElement$1(`${ctx.prefix}:element`, attrs, children, ctx);
166
+ }
167
+ function buildLocalElement(el, ctx) {
168
+ const attrs = [];
169
+ addAttr(attrs, "id", el.id);
170
+ addAttr(attrs, "name", el.name);
171
+ addAttr(attrs, "ref", el.ref);
172
+ addAttr(attrs, "type", el.type);
173
+ addOccursAttr(attrs, "minOccurs", el.minOccurs);
174
+ addOccursAttr(attrs, "maxOccurs", el.maxOccurs);
175
+ addAttr(attrs, "default", el.default);
176
+ addAttr(attrs, "fixed", el.fixed);
177
+ addBoolAttr(attrs, "nillable", el.nillable);
178
+ addAttr(attrs, "block", el.block);
179
+ addAttr(attrs, "form", el.form);
180
+ addAttr(attrs, "targetNamespace", el.targetNamespace);
181
+ const children = [];
182
+ const childCtx = {
183
+ ...ctx,
184
+ level: ctx.level + 1
185
+ };
186
+ if (el.annotation) children.push(buildAnnotation(el.annotation, childCtx));
187
+ if (el.simpleType) children.push(buildLocalSimpleType(el.simpleType, childCtx));
188
+ if (el.complexType) children.push(buildLocalComplexType(el.complexType, childCtx));
189
+ if (el.alternative) for (const alt of el.alternative) children.push(buildAlternative(alt, childCtx));
190
+ if (el.unique) for (const u of el.unique) children.push(buildUnique(u, childCtx));
191
+ if (el.key) for (const k of el.key) children.push(buildKey(k, childCtx));
192
+ if (el.keyref) for (const kr of el.keyref) children.push(buildKeyref(kr, childCtx));
193
+ return buildElement$1(`${ctx.prefix}:element`, attrs, children, ctx);
194
+ }
195
+ function buildTopLevelAttribute(attr, ctx) {
196
+ const attrs = [];
197
+ addAttr(attrs, "id", attr.id);
198
+ addAttr(attrs, "name", attr.name);
199
+ addAttr(attrs, "type", attr.type);
200
+ addAttr(attrs, "default", attr.default);
201
+ addAttr(attrs, "fixed", attr.fixed);
202
+ addBoolAttr(attrs, "inheritable", attr.inheritable);
203
+ const children = [];
204
+ const childCtx = {
205
+ ...ctx,
206
+ level: ctx.level + 1
207
+ };
208
+ if (attr.annotation) children.push(buildAnnotation(attr.annotation, childCtx));
209
+ if (attr.simpleType) children.push(buildLocalSimpleType(attr.simpleType, childCtx));
210
+ return buildElement$1(`${ctx.prefix}:attribute`, attrs, children, ctx);
211
+ }
212
+ function buildLocalAttribute(attr, ctx) {
213
+ const attrs = [];
214
+ addAttr(attrs, "id", attr.id);
215
+ addAttr(attrs, "name", attr.name);
216
+ addAttr(attrs, "ref", attr.ref);
217
+ addAttr(attrs, "type", attr.type);
218
+ addAttr(attrs, "use", attr.use);
219
+ addAttr(attrs, "default", attr.default);
220
+ addAttr(attrs, "fixed", attr.fixed);
221
+ addAttr(attrs, "form", attr.form);
222
+ addAttr(attrs, "targetNamespace", attr.targetNamespace);
223
+ addBoolAttr(attrs, "inheritable", attr.inheritable);
224
+ const children = [];
225
+ const childCtx = {
226
+ ...ctx,
227
+ level: ctx.level + 1
228
+ };
229
+ if (attr.annotation) children.push(buildAnnotation(attr.annotation, childCtx));
230
+ if (attr.simpleType) children.push(buildLocalSimpleType(attr.simpleType, childCtx));
231
+ return buildElement$1(`${ctx.prefix}:attribute`, attrs, children, ctx);
232
+ }
233
+ function buildTopLevelComplexType(ct, ctx) {
234
+ const attrs = [];
235
+ addAttr(attrs, "id", ct.id);
236
+ addAttr(attrs, "name", ct.name);
237
+ addBoolAttr(attrs, "mixed", ct.mixed);
238
+ addBoolAttr(attrs, "abstract", ct.abstract);
239
+ addAttr(attrs, "final", ct.final);
240
+ addAttr(attrs, "block", ct.block);
241
+ addBoolAttr(attrs, "defaultAttributesApply", ct.defaultAttributesApply);
242
+ return buildComplexTypeContent(ct, attrs, ctx);
243
+ }
244
+ function buildLocalComplexType(ct, ctx) {
245
+ const attrs = [];
246
+ addAttr(attrs, "id", ct.id);
247
+ addBoolAttr(attrs, "mixed", ct.mixed);
248
+ return buildComplexTypeContent(ct, attrs, ctx);
249
+ }
250
+ function buildComplexTypeContent(ct, attrs, ctx) {
251
+ const children = [];
252
+ const childCtx = {
253
+ ...ctx,
254
+ level: ctx.level + 1
255
+ };
256
+ if (ct.annotation) children.push(buildAnnotation(ct.annotation, childCtx));
257
+ if (ct.simpleContent) children.push(buildSimpleContent(ct.simpleContent, childCtx));
258
+ else if (ct.complexContent) children.push(buildComplexContent(ct.complexContent, childCtx));
259
+ else {
260
+ if (ct.openContent) children.push(buildOpenContent(ct.openContent, childCtx));
261
+ if (ct.group) children.push(buildGroupRef(ct.group, childCtx));
262
+ if (ct.all) children.push(buildAll(ct.all, childCtx));
263
+ if (ct.choice) children.push(buildExplicitGroup(ct.choice, "choice", childCtx));
264
+ if (ct.sequence) children.push(buildExplicitGroup(ct.sequence, "sequence", childCtx));
265
+ if (ct.attribute) for (const attr of ct.attribute) children.push(buildLocalAttribute(attr, childCtx));
266
+ if (ct.attributeGroup) for (const ag of ct.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
267
+ if (ct.anyAttribute) children.push(buildAnyAttribute(ct.anyAttribute, childCtx));
268
+ if (ct.assert) for (const a of ct.assert) children.push(buildAssertion(a, childCtx));
269
+ }
270
+ return buildElement$1(`${ctx.prefix}:complexType`, attrs, children, ctx);
271
+ }
272
+ function buildTopLevelSimpleType(st, ctx) {
273
+ const attrs = [];
274
+ addAttr(attrs, "id", st.id);
275
+ addAttr(attrs, "name", st.name);
276
+ addAttr(attrs, "final", st.final);
277
+ return buildSimpleTypeContent(st, attrs, ctx);
278
+ }
279
+ function buildLocalSimpleType(st, ctx) {
280
+ const attrs = [];
281
+ addAttr(attrs, "id", st.id);
282
+ return buildSimpleTypeContent(st, attrs, ctx);
283
+ }
284
+ function buildSimpleTypeContent(st, attrs, ctx) {
285
+ const children = [];
286
+ const childCtx = {
287
+ ...ctx,
288
+ level: ctx.level + 1
289
+ };
290
+ if (st.annotation) children.push(buildAnnotation(st.annotation, childCtx));
291
+ if (st.restriction) children.push(buildSimpleTypeRestriction(st.restriction, childCtx));
292
+ else if (st.list) children.push(buildList(st.list, childCtx));
293
+ else if (st.union) children.push(buildUnion(st.union, childCtx));
294
+ return buildElement$1(`${ctx.prefix}:simpleType`, attrs, children, ctx);
295
+ }
296
+ function buildSimpleTypeRestriction(r, ctx) {
297
+ const attrs = [];
298
+ addAttr(attrs, "id", r.id);
299
+ addAttr(attrs, "base", r.base);
300
+ const children = [];
301
+ const childCtx = {
302
+ ...ctx,
303
+ level: ctx.level + 1
304
+ };
305
+ if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
306
+ if (r.simpleType) children.push(buildLocalSimpleType(r.simpleType, childCtx));
307
+ buildFacets(r, children, childCtx);
308
+ return buildElement$1(`${ctx.prefix}:restriction`, attrs, children, ctx);
309
+ }
310
+ function buildFacets(r, children, ctx) {
311
+ if (r.minExclusive) for (const f of r.minExclusive) children.push(buildFacet(f, "minExclusive", ctx));
312
+ if (r.minInclusive) for (const f of r.minInclusive) children.push(buildFacet(f, "minInclusive", ctx));
313
+ if (r.maxExclusive) for (const f of r.maxExclusive) children.push(buildFacet(f, "maxExclusive", ctx));
314
+ if (r.maxInclusive) for (const f of r.maxInclusive) children.push(buildFacet(f, "maxInclusive", ctx));
315
+ if (r.totalDigits) for (const f of r.totalDigits) children.push(buildFacet(f, "totalDigits", ctx));
316
+ if (r.fractionDigits) for (const f of r.fractionDigits) children.push(buildFacet(f, "fractionDigits", ctx));
317
+ if (r.length) for (const f of r.length) children.push(buildFacet(f, "length", ctx));
318
+ if (r.minLength) for (const f of r.minLength) children.push(buildFacet(f, "minLength", ctx));
319
+ if (r.maxLength) for (const f of r.maxLength) children.push(buildFacet(f, "maxLength", ctx));
320
+ if (r.enumeration) for (const f of r.enumeration) children.push(buildFacet(f, "enumeration", ctx));
321
+ if (r.whiteSpace) for (const f of r.whiteSpace) children.push(buildFacet(f, "whiteSpace", ctx));
322
+ if (r.pattern) for (const p of r.pattern) children.push(buildPattern(p, ctx));
323
+ if (r.assertion) for (const a of r.assertion) children.push(buildAssertion(a, ctx));
324
+ if (r.explicitTimezone) for (const f of r.explicitTimezone) children.push(buildFacet(f, "explicitTimezone", ctx));
325
+ }
326
+ function buildFacet(f, name, ctx) {
327
+ const attrs = [];
328
+ addAttr(attrs, "id", f.id);
329
+ addAttr(attrs, "value", f.value);
330
+ addBoolAttr(attrs, "fixed", f.fixed);
331
+ const children = [];
332
+ if (f.annotation) children.push(buildAnnotation(f.annotation, {
333
+ ...ctx,
334
+ level: ctx.level + 1
335
+ }));
336
+ return buildElement$1(`${ctx.prefix}:${name}`, attrs, children, ctx);
337
+ }
338
+ function buildPattern(p, ctx) {
339
+ const attrs = [];
340
+ addAttr(attrs, "id", p.id);
341
+ addAttr(attrs, "value", p.value);
342
+ const children = [];
343
+ if (p.annotation) children.push(buildAnnotation(p.annotation, {
344
+ ...ctx,
345
+ level: ctx.level + 1
346
+ }));
347
+ return buildElement$1(`${ctx.prefix}:pattern`, attrs, children, ctx);
348
+ }
349
+ function buildList(l, ctx) {
350
+ const attrs = [];
351
+ addAttr(attrs, "id", l.id);
352
+ addAttr(attrs, "itemType", l.itemType);
353
+ const children = [];
354
+ const childCtx = {
355
+ ...ctx,
356
+ level: ctx.level + 1
357
+ };
358
+ if (l.annotation) children.push(buildAnnotation(l.annotation, childCtx));
359
+ if (l.simpleType) children.push(buildLocalSimpleType(l.simpleType, childCtx));
360
+ return buildElement$1(`${ctx.prefix}:list`, attrs, children, ctx);
361
+ }
362
+ function buildUnion(u, ctx) {
363
+ const attrs = [];
364
+ addAttr(attrs, "id", u.id);
365
+ addAttr(attrs, "memberTypes", u.memberTypes);
366
+ const children = [];
367
+ const childCtx = {
368
+ ...ctx,
369
+ level: ctx.level + 1
370
+ };
371
+ if (u.annotation) children.push(buildAnnotation(u.annotation, childCtx));
372
+ if (u.simpleType) for (const st of u.simpleType) children.push(buildLocalSimpleType(st, childCtx));
373
+ return buildElement$1(`${ctx.prefix}:union`, attrs, children, ctx);
374
+ }
375
+ function buildComplexContent(cc, ctx) {
376
+ const attrs = [];
377
+ addAttr(attrs, "id", cc.id);
378
+ addBoolAttr(attrs, "mixed", cc.mixed);
379
+ const children = [];
380
+ const childCtx = {
381
+ ...ctx,
382
+ level: ctx.level + 1
383
+ };
384
+ if (cc.annotation) children.push(buildAnnotation(cc.annotation, childCtx));
385
+ if (cc.restriction) children.push(buildComplexContentRestriction(cc.restriction, childCtx));
386
+ else if (cc.extension) children.push(buildComplexContentExtension(cc.extension, childCtx));
387
+ return buildElement$1(`${ctx.prefix}:complexContent`, attrs, children, ctx);
388
+ }
389
+ function buildSimpleContent(sc, ctx) {
390
+ const attrs = [];
391
+ addAttr(attrs, "id", sc.id);
392
+ const children = [];
393
+ const childCtx = {
394
+ ...ctx,
395
+ level: ctx.level + 1
396
+ };
397
+ if (sc.annotation) children.push(buildAnnotation(sc.annotation, childCtx));
398
+ if (sc.restriction) children.push(buildSimpleContentRestriction(sc.restriction, childCtx));
399
+ else if (sc.extension) children.push(buildSimpleContentExtension(sc.extension, childCtx));
400
+ return buildElement$1(`${ctx.prefix}:simpleContent`, attrs, children, ctx);
401
+ }
402
+ function buildComplexContentRestriction(r, ctx) {
403
+ const attrs = [];
404
+ addAttr(attrs, "id", r.id);
405
+ addAttr(attrs, "base", r.base);
406
+ const children = [];
407
+ const childCtx = {
408
+ ...ctx,
409
+ level: ctx.level + 1
410
+ };
411
+ if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
412
+ if (r.openContent) children.push(buildOpenContent(r.openContent, childCtx));
413
+ if (r.group) children.push(buildGroupRef(r.group, childCtx));
414
+ if (r.all) children.push(buildAll(r.all, childCtx));
415
+ if (r.choice) children.push(buildExplicitGroup(r.choice, "choice", childCtx));
416
+ if (r.sequence) children.push(buildExplicitGroup(r.sequence, "sequence", childCtx));
417
+ if (r.attribute) for (const attr of r.attribute) children.push(buildLocalAttribute(attr, childCtx));
418
+ if (r.attributeGroup) for (const ag of r.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
419
+ if (r.anyAttribute) children.push(buildAnyAttribute(r.anyAttribute, childCtx));
420
+ if (r.assert) for (const a of r.assert) children.push(buildAssertion(a, childCtx));
421
+ return buildElement$1(`${ctx.prefix}:restriction`, attrs, children, ctx);
422
+ }
423
+ function buildComplexContentExtension(e, ctx) {
424
+ const attrs = [];
425
+ addAttr(attrs, "id", e.id);
426
+ addAttr(attrs, "base", e.base);
427
+ const children = [];
428
+ const childCtx = {
429
+ ...ctx,
430
+ level: ctx.level + 1
431
+ };
432
+ if (e.annotation) children.push(buildAnnotation(e.annotation, childCtx));
433
+ if (e.openContent) children.push(buildOpenContent(e.openContent, childCtx));
434
+ if (e.group) children.push(buildGroupRef(e.group, childCtx));
435
+ if (e.all) children.push(buildAll(e.all, childCtx));
436
+ if (e.choice) children.push(buildExplicitGroup(e.choice, "choice", childCtx));
437
+ if (e.sequence) children.push(buildExplicitGroup(e.sequence, "sequence", childCtx));
438
+ if (e.attribute) for (const attr of e.attribute) children.push(buildLocalAttribute(attr, childCtx));
439
+ if (e.attributeGroup) for (const ag of e.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
440
+ if (e.anyAttribute) children.push(buildAnyAttribute(e.anyAttribute, childCtx));
441
+ if (e.assert) for (const a of e.assert) children.push(buildAssertion(a, childCtx));
442
+ return buildElement$1(`${ctx.prefix}:extension`, attrs, children, ctx);
443
+ }
444
+ function buildSimpleContentRestriction(r, ctx) {
445
+ const attrs = [];
446
+ addAttr(attrs, "id", r.id);
447
+ addAttr(attrs, "base", r.base);
448
+ const children = [];
449
+ const childCtx = {
450
+ ...ctx,
451
+ level: ctx.level + 1
452
+ };
453
+ if (r.annotation) children.push(buildAnnotation(r.annotation, childCtx));
454
+ if (r.simpleType) children.push(buildLocalSimpleType(r.simpleType, childCtx));
455
+ buildFacets(r, children, childCtx);
456
+ if (r.attribute) for (const attr of r.attribute) children.push(buildLocalAttribute(attr, childCtx));
457
+ if (r.attributeGroup) for (const ag of r.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
458
+ if (r.anyAttribute) children.push(buildAnyAttribute(r.anyAttribute, childCtx));
459
+ if (r.assert) for (const a of r.assert) children.push(buildAssertion(a, childCtx));
460
+ return buildElement$1(`${ctx.prefix}:restriction`, attrs, children, ctx);
461
+ }
462
+ function buildSimpleContentExtension(e, ctx) {
463
+ const attrs = [];
464
+ addAttr(attrs, "id", e.id);
465
+ addAttr(attrs, "base", e.base);
466
+ const children = [];
467
+ const childCtx = {
468
+ ...ctx,
469
+ level: ctx.level + 1
470
+ };
471
+ if (e.annotation) children.push(buildAnnotation(e.annotation, childCtx));
472
+ if (e.attribute) for (const attr of e.attribute) children.push(buildLocalAttribute(attr, childCtx));
473
+ if (e.attributeGroup) for (const ag of e.attributeGroup) children.push(buildAttributeGroupRef(ag, childCtx));
474
+ if (e.anyAttribute) children.push(buildAnyAttribute(e.anyAttribute, childCtx));
475
+ if (e.assert) for (const a of e.assert) children.push(buildAssertion(a, childCtx));
476
+ return buildElement$1(`${ctx.prefix}:extension`, attrs, children, ctx);
477
+ }
478
+ function buildExplicitGroup(g, name, ctx) {
479
+ const attrs = [];
480
+ addAttr(attrs, "id", g.id);
481
+ addOccursAttr(attrs, "minOccurs", g.minOccurs);
482
+ addOccursAttr(attrs, "maxOccurs", g.maxOccurs);
483
+ const children = [];
484
+ const childCtx = {
485
+ ...ctx,
486
+ level: ctx.level + 1
487
+ };
488
+ if (g.annotation) children.push(buildAnnotation(g.annotation, childCtx));
489
+ if (g.element) for (const el of g.element) children.push(buildLocalElement(el, childCtx));
490
+ if (g.group) for (const grp of g.group) children.push(buildGroupRef(grp, childCtx));
491
+ if (g.choice) for (const c of g.choice) children.push(buildExplicitGroup(c, "choice", childCtx));
492
+ if (g.sequence) for (const s of g.sequence) children.push(buildExplicitGroup(s, "sequence", childCtx));
493
+ if (g.any) for (const a of g.any) children.push(buildAny(a, childCtx));
494
+ return buildElement$1(`${ctx.prefix}:${name}`, attrs, children, ctx);
495
+ }
496
+ function buildAll(a, ctx) {
497
+ const attrs = [];
498
+ addAttr(attrs, "id", a.id);
499
+ addOccursAttr(attrs, "minOccurs", a.minOccurs);
500
+ addOccursAttr(attrs, "maxOccurs", a.maxOccurs);
501
+ const children = [];
502
+ const childCtx = {
503
+ ...ctx,
504
+ level: ctx.level + 1
505
+ };
506
+ if (a.annotation) children.push(buildAnnotation(a.annotation, childCtx));
507
+ if (a.element) for (const el of a.element) children.push(buildLocalElement(el, childCtx));
508
+ if (a.any) for (const any of a.any) children.push(buildAny(any, childCtx));
509
+ if (a.group) for (const grp of a.group) children.push(buildGroupRef(grp, childCtx));
510
+ return buildElement$1(`${ctx.prefix}:all`, attrs, children, ctx);
511
+ }
512
+ function buildNamedGroup(g, ctx) {
513
+ const attrs = [];
514
+ addAttr(attrs, "id", g.id);
515
+ addAttr(attrs, "name", g.name);
516
+ const children = [];
517
+ const childCtx = {
518
+ ...ctx,
519
+ level: ctx.level + 1
520
+ };
521
+ if (g.annotation) children.push(buildAnnotation(g.annotation, childCtx));
522
+ if (g.all) children.push(buildAll(g.all, childCtx));
523
+ if (g.choice) children.push(buildExplicitGroup(g.choice, "choice", childCtx));
524
+ if (g.sequence) children.push(buildExplicitGroup(g.sequence, "sequence", childCtx));
525
+ return buildElement$1(`${ctx.prefix}:group`, attrs, children, ctx);
526
+ }
527
+ function buildGroupRef(g, ctx) {
528
+ const attrs = [];
529
+ addAttr(attrs, "id", g.id);
530
+ addAttr(attrs, "ref", g.ref);
531
+ addOccursAttr(attrs, "minOccurs", g.minOccurs);
532
+ addOccursAttr(attrs, "maxOccurs", g.maxOccurs);
533
+ const children = [];
534
+ if (g.annotation) children.push(buildAnnotation(g.annotation, {
535
+ ...ctx,
536
+ level: ctx.level + 1
537
+ }));
538
+ return buildElement$1(`${ctx.prefix}:group`, attrs, children, ctx);
539
+ }
540
+ function buildNamedAttributeGroup(ag, ctx) {
541
+ const attrs = [];
542
+ addAttr(attrs, "id", ag.id);
543
+ addAttr(attrs, "name", ag.name);
544
+ const children = [];
545
+ const childCtx = {
546
+ ...ctx,
547
+ level: ctx.level + 1
548
+ };
549
+ if (ag.annotation) children.push(buildAnnotation(ag.annotation, childCtx));
550
+ if (ag.attribute) for (const attr of ag.attribute) children.push(buildLocalAttribute(attr, childCtx));
551
+ if (ag.attributeGroup) for (const agr of ag.attributeGroup) children.push(buildAttributeGroupRef(agr, childCtx));
552
+ if (ag.anyAttribute) children.push(buildAnyAttribute(ag.anyAttribute, childCtx));
553
+ return buildElement$1(`${ctx.prefix}:attributeGroup`, attrs, children, ctx);
554
+ }
555
+ function buildAttributeGroupRef(ag, ctx) {
556
+ const attrs = [];
557
+ addAttr(attrs, "id", ag.id);
558
+ addAttr(attrs, "ref", ag.ref);
559
+ const children = [];
560
+ if (ag.annotation) children.push(buildAnnotation(ag.annotation, {
561
+ ...ctx,
562
+ level: ctx.level + 1
563
+ }));
564
+ return buildElement$1(`${ctx.prefix}:attributeGroup`, attrs, children, ctx);
565
+ }
566
+ function buildAny(a, ctx) {
567
+ const attrs = [];
568
+ addAttr(attrs, "id", a.id);
569
+ addOccursAttr(attrs, "minOccurs", a.minOccurs);
570
+ addOccursAttr(attrs, "maxOccurs", a.maxOccurs);
571
+ addAttr(attrs, "namespace", a.namespace);
572
+ addAttr(attrs, "processContents", a.processContents);
573
+ addAttr(attrs, "notNamespace", a.notNamespace);
574
+ addAttr(attrs, "notQName", a.notQName);
575
+ const children = [];
576
+ if (a.annotation) children.push(buildAnnotation(a.annotation, {
577
+ ...ctx,
578
+ level: ctx.level + 1
579
+ }));
580
+ return buildElement$1(`${ctx.prefix}:any`, attrs, children, ctx);
581
+ }
582
+ function buildAnyAttribute(aa, ctx) {
583
+ const attrs = [];
584
+ addAttr(attrs, "id", aa.id);
585
+ addAttr(attrs, "namespace", aa.namespace);
586
+ addAttr(attrs, "processContents", aa.processContents);
587
+ addAttr(attrs, "notNamespace", aa.notNamespace);
588
+ addAttr(attrs, "notQName", aa.notQName);
589
+ const children = [];
590
+ if (aa.annotation) children.push(buildAnnotation(aa.annotation, {
591
+ ...ctx,
592
+ level: ctx.level + 1
593
+ }));
594
+ return buildElement$1(`${ctx.prefix}:anyAttribute`, attrs, children, ctx);
595
+ }
596
+ function buildUnique(u, ctx) {
597
+ const attrs = [];
598
+ addAttr(attrs, "id", u.id);
599
+ addAttr(attrs, "name", u.name);
600
+ addAttr(attrs, "ref", u.ref);
601
+ const children = [];
602
+ const childCtx = {
603
+ ...ctx,
604
+ level: ctx.level + 1
605
+ };
606
+ if (u.annotation) children.push(buildAnnotation(u.annotation, childCtx));
607
+ if (u.selector) children.push(buildSelector(u.selector, childCtx));
608
+ if (u.field) for (const f of u.field) children.push(buildField$1(f, childCtx));
609
+ return buildElement$1(`${ctx.prefix}:unique`, attrs, children, ctx);
610
+ }
611
+ function buildKey(k, ctx) {
612
+ const attrs = [];
613
+ addAttr(attrs, "id", k.id);
614
+ addAttr(attrs, "name", k.name);
615
+ addAttr(attrs, "ref", k.ref);
616
+ const children = [];
617
+ const childCtx = {
618
+ ...ctx,
619
+ level: ctx.level + 1
620
+ };
621
+ if (k.annotation) children.push(buildAnnotation(k.annotation, childCtx));
622
+ if (k.selector) children.push(buildSelector(k.selector, childCtx));
623
+ if (k.field) for (const f of k.field) children.push(buildField$1(f, childCtx));
624
+ return buildElement$1(`${ctx.prefix}:key`, attrs, children, ctx);
625
+ }
626
+ function buildKeyref(kr, ctx) {
627
+ const attrs = [];
628
+ addAttr(attrs, "id", kr.id);
629
+ addAttr(attrs, "name", kr.name);
630
+ addAttr(attrs, "ref", kr.ref);
631
+ addAttr(attrs, "refer", kr.refer);
632
+ const children = [];
633
+ const childCtx = {
634
+ ...ctx,
635
+ level: ctx.level + 1
636
+ };
637
+ if (kr.annotation) children.push(buildAnnotation(kr.annotation, childCtx));
638
+ if (kr.selector) children.push(buildSelector(kr.selector, childCtx));
639
+ if (kr.field) for (const f of kr.field) children.push(buildField$1(f, childCtx));
640
+ return buildElement$1(`${ctx.prefix}:keyref`, attrs, children, ctx);
641
+ }
642
+ function buildSelector(s, ctx) {
643
+ const attrs = [];
644
+ addAttr(attrs, "id", s.id);
645
+ addAttr(attrs, "xpath", s.xpath);
646
+ addAttr(attrs, "xpathDefaultNamespace", s.xpathDefaultNamespace);
647
+ const children = [];
648
+ if (s.annotation) children.push(buildAnnotation(s.annotation, {
649
+ ...ctx,
650
+ level: ctx.level + 1
651
+ }));
652
+ return buildElement$1(`${ctx.prefix}:selector`, attrs, children, ctx);
653
+ }
654
+ function buildField$1(f, ctx) {
655
+ const attrs = [];
656
+ addAttr(attrs, "id", f.id);
657
+ addAttr(attrs, "xpath", f.xpath);
658
+ addAttr(attrs, "xpathDefaultNamespace", f.xpathDefaultNamespace);
659
+ const children = [];
660
+ if (f.annotation) children.push(buildAnnotation(f.annotation, {
661
+ ...ctx,
662
+ level: ctx.level + 1
663
+ }));
664
+ return buildElement$1(`${ctx.prefix}:field`, attrs, children, ctx);
665
+ }
666
+ function buildOpenContent(oc, ctx) {
667
+ const attrs = [];
668
+ addAttr(attrs, "id", oc.id);
669
+ addAttr(attrs, "mode", oc.mode);
670
+ const children = [];
671
+ const childCtx = {
672
+ ...ctx,
673
+ level: ctx.level + 1
674
+ };
675
+ if (oc.annotation) children.push(buildAnnotation(oc.annotation, childCtx));
676
+ if (oc.any) children.push(buildAny(oc.any, childCtx));
677
+ return buildElement$1(`${ctx.prefix}:openContent`, attrs, children, ctx);
678
+ }
679
+ function buildDefaultOpenContent(doc, ctx) {
680
+ const attrs = [];
681
+ addAttr(attrs, "id", doc.id);
682
+ addBoolAttr(attrs, "appliesToEmpty", doc.appliesToEmpty);
683
+ addAttr(attrs, "mode", doc.mode);
684
+ const children = [];
685
+ const childCtx = {
686
+ ...ctx,
687
+ level: ctx.level + 1
688
+ };
689
+ if (doc.annotation) children.push(buildAnnotation(doc.annotation, childCtx));
690
+ children.push(buildAny(doc.any, childCtx));
691
+ return buildElement$1(`${ctx.prefix}:defaultOpenContent`, attrs, children, ctx);
692
+ }
693
+ function buildAssertion(a, ctx) {
694
+ const attrs = [];
695
+ addAttr(attrs, "id", a.id);
696
+ addAttr(attrs, "test", a.test);
697
+ addAttr(attrs, "xpathDefaultNamespace", a.xpathDefaultNamespace);
698
+ const children = [];
699
+ if (a.annotation) children.push(buildAnnotation(a.annotation, {
700
+ ...ctx,
701
+ level: ctx.level + 1
702
+ }));
703
+ return buildElement$1(`${ctx.prefix}:assert`, attrs, children, ctx);
704
+ }
705
+ function buildAlternative(alt, ctx) {
706
+ const attrs = [];
707
+ addAttr(attrs, "id", alt.id);
708
+ addAttr(attrs, "test", alt.test);
709
+ addAttr(attrs, "type", alt.type);
710
+ addAttr(attrs, "xpathDefaultNamespace", alt.xpathDefaultNamespace);
711
+ const children = [];
712
+ const childCtx = {
713
+ ...ctx,
714
+ level: ctx.level + 1
715
+ };
716
+ if (alt.annotation) children.push(buildAnnotation(alt.annotation, childCtx));
717
+ if (alt.simpleType) children.push(buildLocalSimpleType(alt.simpleType, childCtx));
718
+ if (alt.complexType) children.push(buildLocalComplexType(alt.complexType, childCtx));
719
+ return buildElement$1(`${ctx.prefix}:alternative`, attrs, children, ctx);
720
+ }
721
+ function buildNotation(n, ctx) {
722
+ const attrs = [];
723
+ addAttr(attrs, "id", n.id);
724
+ addAttr(attrs, "name", n.name);
725
+ addAttr(attrs, "public", n.public);
726
+ addAttr(attrs, "system", n.system);
727
+ const children = [];
728
+ if (n.annotation) children.push(buildAnnotation(n.annotation, {
729
+ ...ctx,
730
+ level: ctx.level + 1
731
+ }));
732
+ return buildElement$1(`${ctx.prefix}:notation`, attrs, children, ctx);
733
+ }
734
+ function addAttr(attrs, name, value) {
735
+ if (value !== void 0) attrs.push(`${name}="${escapeXml(value)}"`);
736
+ }
737
+ function addBoolAttr(attrs, name, value) {
738
+ if (value !== void 0) attrs.push(`${name}="${value}"`);
739
+ }
740
+ function addOccursAttr(attrs, name, value) {
741
+ if (value !== void 0) attrs.push(`${name}="${value}"`);
742
+ }
743
+ function escapeXml(str) {
744
+ return str.replaceAll(/&/g, "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&apos;");
745
+ }
746
+ function buildElement$1(tag, attrs, children, ctx) {
747
+ const indent = ctx.pretty ? ctx.indent.repeat(ctx.level) : "";
748
+ const attrStr = attrs.length > 0 ? " " + attrs.join(" ") : "";
749
+ if (children.length === 0) return `${indent}<${tag}${attrStr}/>`;
750
+ const nl = ctx.pretty ? "\n" : "";
751
+ return `${indent}<${tag}${attrStr}>${nl}${children.join(nl)}${nl}${indent}</${tag}>`;
752
+ }
753
+ function buildElementWithText(tag, attrs, text, ctx) {
754
+ return `${ctx.pretty ? ctx.indent.repeat(ctx.level) : ""}<${tag}${attrs.length > 0 ? " " + attrs.join(" ") : ""}>${escapeXml(text)}</${tag}>`;
755
+ }
756
+
757
+ //#endregion
758
+ //#region src/xsd/helpers.ts
759
+ /**
760
+ * Resolve $imports for a schema by matching import schemaLocation to $filename.
761
+ *
762
+ * @param schema - The schema to resolve imports for
763
+ * @param availableSchemas - Array of schemas that may be imported
764
+ * @returns A new schema object with $imports populated
765
+ *
766
+ * @example
767
+ * ```typescript
768
+ * const orderSchema = parseXsd(orderXsd);
769
+ * const commonSchema = { ...parseXsd(commonXsd), $filename: 'common.xsd' };
770
+ *
771
+ * // orderSchema has: import: [{ schemaLocation: 'common.xsd', ... }]
772
+ * const resolved = resolveImports(orderSchema, [commonSchema]);
773
+ * // resolved.$imports = [commonSchema]
774
+ * ```
775
+ */
776
+ function resolveImports(schema, availableSchemas) {
777
+ const imports = [];
778
+ if (schema.import) {
779
+ for (const imp of schema.import) if (imp.schemaLocation) {
780
+ const found = availableSchemas.find((s) => s.$filename === imp.schemaLocation);
781
+ if (found) imports.push(found);
782
+ }
783
+ }
784
+ return {
785
+ ...schema,
786
+ $imports: imports
787
+ };
788
+ }
789
+ /**
790
+ * Resolve $imports for multiple schemas, linking them together.
791
+ *
792
+ * @param schemas - Array of schemas to link together
793
+ * @returns Array of schemas with $imports populated
794
+ *
795
+ * @example
796
+ * ```typescript
797
+ * const schemas = [
798
+ * { ...parseXsd(orderXsd), $filename: 'order.xsd' },
799
+ * { ...parseXsd(commonXsd), $filename: 'common.xsd' },
800
+ * ];
801
+ * const linked = linkSchemas(schemas);
802
+ * // Each schema now has $imports resolved
803
+ * ```
804
+ */
805
+ function linkSchemas(schemas) {
806
+ return schemas.map((schema) => resolveImports(schema, schemas));
807
+ }
808
+
809
+ //#endregion
810
+ //#region src/walker/index.ts
811
+ /**
812
+ * Walk all complexTypes in a schema and its $imports/$includes (depth-first).
813
+ *
814
+ * @param schema - Root schema to start from
815
+ * @param options - Walk options (e.g., includesOnly to skip $imports)
816
+ * @yields ComplexType with the schema it was found in
817
+ *
818
+ * @example
819
+ * ```typescript
820
+ * function findComplexType(name: string, schema: SchemaLike) {
821
+ * for (const { ct, schema: s } of walkComplexTypes(schema)) {
822
+ * if (ct.name === name) return { type: ct, schema: s };
823
+ * }
824
+ * }
825
+ * ```
826
+ */
827
+ function* walkComplexTypes(schema, options = {}) {
828
+ const complexTypes = schema.complexType;
829
+ if (complexTypes) {
830
+ if (Array.isArray(complexTypes)) for (const ct of complexTypes) yield {
831
+ ct,
832
+ schema
833
+ };
834
+ else for (const [name, ct] of Object.entries(complexTypes)) yield {
835
+ ct: {
836
+ ...ct,
837
+ name
838
+ },
839
+ schema
840
+ };
841
+ }
842
+ if (schema.redefine) {
843
+ for (const redef of schema.redefine) if (redef.complexType) for (const ct of redef.complexType) yield {
844
+ ct,
845
+ schema
846
+ };
847
+ }
848
+ if (schema.override) {
849
+ for (const ovr of schema.override) if (ovr.complexType) for (const ct of ovr.complexType) yield {
850
+ ct,
851
+ schema
852
+ };
853
+ }
854
+ if (schema.$includes) for (const included of schema.$includes) yield* walkComplexTypes(included, options);
855
+ if (!options.includesOnly && schema.$imports) for (const imported of schema.$imports) yield* walkComplexTypes(imported, options);
856
+ }
857
+ /**
858
+ * Walk all simpleTypes in a schema and its $imports/$includes.
859
+ */
860
+ function* walkSimpleTypes(schema, options = {}) {
861
+ const simpleTypes = schema.simpleType;
862
+ if (simpleTypes) {
863
+ if (Array.isArray(simpleTypes)) for (const st of simpleTypes) yield {
864
+ st,
865
+ schema
866
+ };
867
+ else for (const [name, st] of Object.entries(simpleTypes)) yield {
868
+ st: {
869
+ ...st,
870
+ name
871
+ },
872
+ schema
873
+ };
874
+ }
875
+ if (schema.redefine) {
876
+ for (const redef of schema.redefine) if (redef.simpleType) for (const st of redef.simpleType) yield {
877
+ st,
878
+ schema
879
+ };
880
+ }
881
+ if (schema.override) {
882
+ for (const ovr of schema.override) if (ovr.simpleType) for (const st of ovr.simpleType) yield {
883
+ st,
884
+ schema
885
+ };
886
+ }
887
+ if (schema.$includes) for (const included of schema.$includes) yield* walkSimpleTypes(included, options);
888
+ if (!options.includesOnly && schema.$imports) for (const imported of schema.$imports) yield* walkSimpleTypes(imported, options);
889
+ }
890
+ /**
891
+ * Walk all top-level elements in a schema and its $imports/$includes.
892
+ */
893
+ function* walkTopLevelElements(schema, options = {}) {
894
+ if (schema.element) for (const element of schema.element) yield {
895
+ element,
896
+ schema
897
+ };
898
+ if (schema.$includes) for (const included of schema.$includes) yield* walkTopLevelElements(included, options);
899
+ if (!options.includesOnly && schema.$imports) for (const imported of schema.$imports) yield* walkTopLevelElements(imported, options);
900
+ }
901
+ /**
902
+ * Find a complexType by name, searching schema and $imports.
903
+ * Returns both the type AND the schema it was found in (important for inheritance).
904
+ */
905
+ function findComplexType(name, schema) {
906
+ for (const entry of walkComplexTypes(schema)) if (entry.ct.name === name) return entry;
907
+ }
908
+ /**
909
+ * Find a simpleType by name, searching schema and $imports.
910
+ */
911
+ function findSimpleType(name, schema) {
912
+ for (const entry of walkSimpleTypes(schema)) if (entry.st.name === name) return entry;
913
+ }
914
+ /**
915
+ * Find a top-level element by name, searching schema and $imports.
916
+ */
917
+ function findElement(name, schema) {
918
+ for (const entry of walkTopLevelElements(schema)) if (entry.element.name === name) return entry;
919
+ }
920
+ /**
921
+ * Walk all elements in a complexType, handling:
922
+ * - sequence, choice, all groups
923
+ * - Nested groups (recursive)
924
+ * - complexContent/extension inheritance
925
+ * - Group references
926
+ *
927
+ * @param ct - ComplexType to walk
928
+ * @param schema - Schema context (for resolving base types and group refs)
929
+ * @yields Elements with metadata (optional, array, source)
930
+ */
931
+ function* walkElements(ct, schema) {
932
+ if (ct.complexContent?.extension) {
933
+ const ext = ct.complexContent.extension;
934
+ if (ext.base) {
935
+ const baseEntry = findComplexType(stripNsPrefix(ext.base), schema);
936
+ if (baseEntry) yield* walkElements(baseEntry.ct, baseEntry.schema);
937
+ }
938
+ yield* walkGroup(ext.sequence, "sequence", schema);
939
+ yield* walkGroup(ext.choice, "choice", schema);
940
+ yield* walkGroup(ext.all, "all", schema);
941
+ if (ext.group?.ref) yield* walkGroupRef(ext.group.ref, schema);
942
+ return;
943
+ }
944
+ if (ct.complexContent?.restriction) {
945
+ const rest = ct.complexContent.restriction;
946
+ yield* walkGroup(rest.sequence, "sequence", schema);
947
+ yield* walkGroup(rest.choice, "choice", schema);
948
+ yield* walkGroup(rest.all, "all", schema);
949
+ if (rest.group?.ref) yield* walkGroupRef(rest.group.ref, schema);
950
+ return;
951
+ }
952
+ yield* walkGroup(ct.sequence, "sequence", schema);
953
+ yield* walkGroup(ct.choice, "choice", schema);
954
+ yield* walkGroup(ct.all, "all", schema);
955
+ if (ct.group?.ref) yield* walkGroupRef(ct.group.ref, schema);
956
+ }
957
+ /**
958
+ * Walk elements in a group (sequence/choice/all), handling nested groups.
959
+ */
960
+ function* walkGroup(group, source, schema, parentOptional = false, parentArray = false) {
961
+ if (!group) return;
962
+ const groupOptional = parentOptional || group.minOccurs === 0 || group.minOccurs === "0";
963
+ const groupArray = parentArray || isArray(group);
964
+ const choiceOptional = source === "choice";
965
+ if (group.element) for (const element of group.element) {
966
+ const optional = choiceOptional || groupOptional || element.minOccurs === 0 || element.minOccurs === "0";
967
+ const array = groupArray || isArray(element);
968
+ if (element.ref) {
969
+ const refName = stripNsPrefix(element.ref);
970
+ const refEntry = findElement(refName, schema);
971
+ if (refEntry && isAbstractElement(refEntry.element)) {
972
+ const substitutes = findSubstitutes(refName, schema);
973
+ if (substitutes.length > 0) {
974
+ for (const sub of substitutes) yield {
975
+ element: sub,
976
+ optional,
977
+ array,
978
+ source,
979
+ schema
980
+ };
981
+ continue;
982
+ }
983
+ }
984
+ }
985
+ yield {
986
+ element,
987
+ optional,
988
+ array,
989
+ source,
990
+ schema
991
+ };
992
+ }
993
+ if (group.sequence) {
994
+ const sequences = Array.isArray(group.sequence) ? group.sequence : [group.sequence];
995
+ for (const nested of sequences) yield* walkGroup(nested, "sequence", schema, groupOptional, groupArray);
996
+ }
997
+ if (group.choice) {
998
+ const choices = Array.isArray(group.choice) ? group.choice : [group.choice];
999
+ for (const nested of choices) yield* walkGroup(nested, "choice", schema, true, groupArray || isArray(nested));
1000
+ }
1001
+ if (group.group) {
1002
+ const refs = Array.isArray(group.group) ? group.group : [group.group];
1003
+ for (const ref of refs) if (ref.ref) yield* walkGroupRef(ref.ref, schema, groupOptional || choiceOptional, groupArray || isArray(ref));
1004
+ }
1005
+ }
1006
+ /**
1007
+ * Walk elements from a group reference (xs:group ref="...").
1008
+ */
1009
+ function* walkGroupRef(ref, schema, parentOptional = false, parentArray = false) {
1010
+ const group = findGroup(stripNsPrefix(ref), schema);
1011
+ if (group) {
1012
+ if (group.sequence) yield* walkGroup(group.sequence, "sequence", schema, parentOptional, parentArray);
1013
+ if (group.choice) yield* walkGroup(group.choice, "choice", schema, true, parentArray);
1014
+ if (group.all) yield* walkGroup(group.all, "all", schema, parentOptional, parentArray);
1015
+ }
1016
+ }
1017
+ /**
1018
+ * Walk all attributes in a complexType, handling:
1019
+ * - Direct attributes
1020
+ * - complexContent/extension attributes
1021
+ * - simpleContent/extension attributes
1022
+ * - Inherited attributes from base type
1023
+ * - AttributeGroup references
1024
+ */
1025
+ function* walkAttributes(ct, schema) {
1026
+ if (ct.complexContent?.extension) {
1027
+ const ext = ct.complexContent.extension;
1028
+ if (ext.base) {
1029
+ const baseEntry = findComplexType(stripNsPrefix(ext.base), schema);
1030
+ if (baseEntry) yield* walkAttributes(baseEntry.ct, baseEntry.schema);
1031
+ }
1032
+ if (ext.attribute) for (const attr of ext.attribute) {
1033
+ const resolved = resolveAttribute(attr, schema);
1034
+ if (resolved) yield {
1035
+ attribute: resolved,
1036
+ required: resolved.use === "required",
1037
+ schema
1038
+ };
1039
+ }
1040
+ yield* walkAttributeGroupRefs(ext.attributeGroup, schema);
1041
+ return;
1042
+ }
1043
+ if (ct.simpleContent?.extension) {
1044
+ const ext = ct.simpleContent.extension;
1045
+ if (ext.attribute) for (const attr of ext.attribute) {
1046
+ const resolved = resolveAttribute(attr, schema);
1047
+ if (resolved) yield {
1048
+ attribute: resolved,
1049
+ required: resolved.use === "required",
1050
+ schema
1051
+ };
1052
+ }
1053
+ yield* walkAttributeGroupRefs(ext.attributeGroup, schema);
1054
+ return;
1055
+ }
1056
+ if (ct.attribute) for (const attr of ct.attribute) {
1057
+ const resolved = resolveAttribute(attr, schema);
1058
+ if (resolved) yield {
1059
+ attribute: resolved,
1060
+ required: resolved.use === "required",
1061
+ schema
1062
+ };
1063
+ }
1064
+ yield* walkAttributeGroupRefs(ct.attributeGroup, schema);
1065
+ }
1066
+ /**
1067
+ * Walk attributes from attributeGroup references.
1068
+ */
1069
+ function* walkAttributeGroupRefs(refs, schema) {
1070
+ if (!refs) return;
1071
+ for (const ref of refs) {
1072
+ const refObj = ref;
1073
+ if (refObj.ref) {
1074
+ const group = findAttributeGroup(stripNsPrefix(refObj.ref), schema);
1075
+ if (group?.attribute) for (const attribute of group.attribute) yield {
1076
+ attribute,
1077
+ required: attribute.use === "required",
1078
+ schema
1079
+ };
1080
+ }
1081
+ }
1082
+ }
1083
+ /**
1084
+ * Find a named group (xs:group) by name.
1085
+ */
1086
+ function findGroup(name, schema) {
1087
+ if (schema.group) {
1088
+ for (const g of schema.group) if (g.name === name) return g;
1089
+ }
1090
+ if (schema.$includes) for (const included of schema.$includes) {
1091
+ const found = findGroup(name, included);
1092
+ if (found) return found;
1093
+ }
1094
+ if (schema.$imports) for (const imported of schema.$imports) {
1095
+ const found = findGroup(name, imported);
1096
+ if (found) return found;
1097
+ }
1098
+ }
1099
+ /**
1100
+ * Find a top-level attribute by name.
1101
+ * Searches current schema and $imports.
1102
+ */
1103
+ function findAttribute(name, schema) {
1104
+ const schemaWithAttrs = schema;
1105
+ if (schemaWithAttrs.attribute) {
1106
+ for (const attr of schemaWithAttrs.attribute) if (attr.name === name) return attr;
1107
+ }
1108
+ if (schema.$includes) for (const included of schema.$includes) {
1109
+ const found = findAttribute(name, included);
1110
+ if (found) return found;
1111
+ }
1112
+ if (schema.$imports) for (const imported of schema.$imports) {
1113
+ const found = findAttribute(name, imported);
1114
+ if (found) return found;
1115
+ }
1116
+ }
1117
+ /**
1118
+ * Resolve an attribute - handles both direct attributes and refs.
1119
+ * Returns the resolved attribute with its name.
1120
+ */
1121
+ function resolveAttribute(attribute, schema) {
1122
+ if (attribute.ref) {
1123
+ const refName = stripNsPrefix(attribute.ref);
1124
+ const resolved = findAttribute(refName, schema);
1125
+ if (resolved) return {
1126
+ ...resolved,
1127
+ use: attribute.use ?? resolved.use
1128
+ };
1129
+ return {
1130
+ name: refName,
1131
+ type: "xs:string",
1132
+ use: attribute.use
1133
+ };
1134
+ }
1135
+ return attribute;
1136
+ }
1137
+ /**
1138
+ * Find an attributeGroup by name.
1139
+ */
1140
+ function findAttributeGroup(name, schema) {
1141
+ if (schema.attributeGroup) {
1142
+ for (const g of schema.attributeGroup) if (g.name === name) return g;
1143
+ }
1144
+ if (schema.$includes) for (const included of schema.$includes) {
1145
+ const found = findAttributeGroup(name, included);
1146
+ if (found) return found;
1147
+ }
1148
+ if (schema.$imports) for (const imported of schema.$imports) {
1149
+ const found = findAttributeGroup(name, imported);
1150
+ if (found) return found;
1151
+ }
1152
+ }
1153
+ /**
1154
+ * Strip namespace prefix from a QName (e.g., "tns:PersonType" -> "PersonType")
1155
+ */
1156
+ function stripNsPrefix(name) {
1157
+ const colonIndex = name.indexOf(":");
1158
+ return colonIndex >= 0 ? name.slice(colonIndex + 1) : name;
1159
+ }
1160
+ /**
1161
+ * Check if element/group has maxOccurs > 1 (is array)
1162
+ */
1163
+ function isArray(item) {
1164
+ if (item.maxOccurs === "unbounded") return true;
1165
+ if (typeof item.maxOccurs === "number") return item.maxOccurs > 1;
1166
+ if (typeof item.maxOccurs === "string") {
1167
+ if (item.maxOccurs === "unbounded") return true;
1168
+ const num = Number.parseInt(item.maxOccurs, 10);
1169
+ return !Number.isNaN(num) && num > 1;
1170
+ }
1171
+ return false;
1172
+ }
1173
+ /**
1174
+ * Check if an element is abstract
1175
+ */
1176
+ function isAbstractElement(element) {
1177
+ return element.abstract === true || element.abstract === "true";
1178
+ }
1179
+ /**
1180
+ * Find all elements that substitute for a given abstract element.
1181
+ * This handles XSD substitution groups where concrete elements can
1182
+ * substitute for an abstract element.
1183
+ */
1184
+ function findSubstitutes(abstractElementName, schema) {
1185
+ const substitutes = [];
1186
+ for (const { element } of walkTopLevelElements(schema)) {
1187
+ const subGroup = element.substitutionGroup;
1188
+ if (subGroup) {
1189
+ if (stripNsPrefix(subGroup) === abstractElementName) substitutes.push(element);
1190
+ }
1191
+ }
1192
+ return substitutes;
1193
+ }
1194
+
1195
+ //#endregion
1196
+ //#region src/xml/parse.ts
1197
+ /**
1198
+ * XML Parser for W3C Schema
1199
+ *
1200
+ * Parse XML string to typed JavaScript object using W3C-compliant Schema definition.
1201
+ * Uses the walker module for schema traversal.
1202
+ */
1203
+ /**
1204
+ * Find all elements that substitute for a given abstract element
1205
+ * Searches current schema and all $imports
1206
+ */
1207
+ function findSubstitutingElements(abstractElementName, schema) {
1208
+ const results = [];
1209
+ const checkSchema = (s) => {
1210
+ const elements = s.element;
1211
+ if (!elements) return;
1212
+ for (const el of elements) if (el.substitutionGroup) {
1213
+ if (stripNsPrefix(el.substitutionGroup) === abstractElementName) results.push({
1214
+ element: el,
1215
+ schema: s
1216
+ });
1217
+ }
1218
+ };
1219
+ checkSchema(schema);
1220
+ const imports = schema.$imports;
1221
+ if (imports) for (const imported of imports) {
1222
+ checkSchema(imported);
1223
+ const nestedResults = findSubstitutingElements(abstractElementName, imported);
1224
+ results.push(...nestedResults);
1225
+ }
1226
+ return results;
1227
+ }
1228
+ /**
1229
+ * Check if an element is abstract
1230
+ * Searches current schema and all $imports
1231
+ */
1232
+ function isAbstractElement$1(elementName, schema) {
1233
+ const elements = schema.element;
1234
+ if (elements) {
1235
+ for (const el of elements) if (el.name === elementName && el.abstract === true) return true;
1236
+ }
1237
+ const imports = schema.$imports;
1238
+ if (imports) {
1239
+ for (const imported of imports) if (isAbstractElement$1(elementName, imported)) return true;
1240
+ }
1241
+ return false;
1242
+ }
1243
+ /**
1244
+ * Parse XML string to typed object using schema definition
1245
+ */
1246
+ function parse(schema, xml) {
1247
+ const root = new DOMParser().parseFromString(xml, "text/xml")?.documentElement;
1248
+ if (!root) throw new Error("Invalid XML: missing root element");
1249
+ const rootLocalName = getLocalName(root);
1250
+ const elementEntry = findElementByName(schema, rootLocalName);
1251
+ if (!elementEntry) throw new Error(`Schema missing element declaration for: ${rootLocalName}`);
1252
+ const inlineComplexType = elementEntry.element.complexType;
1253
+ if (inlineComplexType) {
1254
+ const content = parseElement(root, inlineComplexType, elementEntry.schema, schema);
1255
+ return { [rootLocalName]: content };
1256
+ }
1257
+ const typeName = stripNsPrefix(elementEntry.element.type || elementEntry.element.name || "");
1258
+ const typeEntry = findComplexType(typeName, schema);
1259
+ if (!typeEntry) throw new Error(`Schema missing complexType for: ${typeName}`);
1260
+ const content = parseElement(root, typeEntry.ct, typeEntry.schema, schema);
1261
+ return { [rootLocalName]: content };
1262
+ }
1263
+ /**
1264
+ * Find element declaration by name (case-insensitive fallback)
1265
+ */
1266
+ function findElementByName(schema, name) {
1267
+ const exact = findElement(name, schema);
1268
+ if (exact) return exact;
1269
+ const elements = schema.element;
1270
+ if (elements) {
1271
+ const lowerName = name.toLowerCase();
1272
+ const found = elements.find((el) => el.name?.toLowerCase() === lowerName);
1273
+ if (found) return {
1274
+ element: found,
1275
+ schema
1276
+ };
1277
+ }
1278
+ }
1279
+ /**
1280
+ * Parse a single element using its complexType definition
1281
+ * Uses walker to iterate elements and attributes (handles inheritance automatically)
1282
+ * @param node - The XML element to parse
1283
+ * @param typeDef - The complexType definition for this element
1284
+ * @param schema - The schema where typeDef is defined (for type resolution)
1285
+ * @param rootSchema - The root schema (for substitution group lookups)
1286
+ */
1287
+ function parseElement(node, typeDef, schema, rootSchema) {
1288
+ const result = {};
1289
+ if (typeDef.simpleContent?.extension) return parseSimpleContent(node, typeDef, schema, rootSchema);
1290
+ for (const { attribute } of walkAttributes(typeDef, schema)) {
1291
+ if (!attribute.name) continue;
1292
+ const value = getAttributeValue(node, attribute.name);
1293
+ if (value !== null) result[attribute.name] = convertValue(value, attribute.type || "string");
1294
+ else if (attribute.default !== void 0) result[attribute.name] = convertValue(String(attribute.default), attribute.type || "string");
1295
+ }
1296
+ for (const { element, array } of walkElements(typeDef, schema)) {
1297
+ const resolved = resolveElementInfo$1(element, schema);
1298
+ if (!resolved) continue;
1299
+ if (isAbstractElement$1(resolved.name, rootSchema)) {
1300
+ const substitutes = findSubstitutingElements(resolved.name, rootSchema);
1301
+ const allChildren = getAllChildElements(node);
1302
+ for (const child of allChildren) {
1303
+ const childName = getLocalName(child);
1304
+ const substitute = substitutes.find((s) => s.element.name === childName);
1305
+ if (substitute && substitute.element.name) {
1306
+ const subTypeName = substitute.element.type ? stripNsPrefix(substitute.element.type) : void 0;
1307
+ result[substitute.element.name] = parseChildValue(child, subTypeName, substitute.schema, rootSchema);
1308
+ }
1309
+ }
1310
+ } else {
1311
+ const children = getChildElements(node, resolved.name);
1312
+ if (array || children.length > 1) {
1313
+ const values = children.map((child) => parseChildValue(child, resolved.typeName, schema, rootSchema));
1314
+ if (values.length > 0) result[resolved.name] = values;
1315
+ } else if (children.length === 1) result[resolved.name] = parseChildValue(children[0], resolved.typeName, schema, rootSchema);
1316
+ }
1317
+ }
1318
+ return result;
1319
+ }
1320
+ /**
1321
+ * Parse simpleContent (text content with attributes)
1322
+ */
1323
+ function parseSimpleContent(node, typeDef, _schema, _rootSchema) {
1324
+ const result = {};
1325
+ const simpleContent = typeDef.simpleContent;
1326
+ if (!simpleContent?.extension) return result;
1327
+ const ext = simpleContent.extension;
1328
+ result.$value = convertValue(getTextContent(node), ext.base ? stripNsPrefix(ext.base) : "string");
1329
+ if (ext.attribute) for (const attrDef of ext.attribute) {
1330
+ if (!attrDef.name) continue;
1331
+ const value = getAttributeValue(node, attrDef.name);
1332
+ if (value !== null) result[attrDef.name] = convertValue(value, attrDef.type || "string");
1333
+ else if (attrDef.default !== void 0) result[attrDef.name] = convertValue(String(attrDef.default), attrDef.type || "string");
1334
+ }
1335
+ return result;
1336
+ }
1337
+ /**
1338
+ * Resolve element info (name and type), handling ref
1339
+ */
1340
+ function resolveElementInfo$1(element, schema) {
1341
+ if (element.name) return {
1342
+ name: element.name,
1343
+ typeName: element.type ? stripNsPrefix(element.type) : void 0
1344
+ };
1345
+ if (element.ref) {
1346
+ const refName = stripNsPrefix(element.ref);
1347
+ const refElement = findElement(refName, schema);
1348
+ if (refElement) return {
1349
+ name: refElement.element.name ?? refName,
1350
+ typeName: refElement.element.type ? stripNsPrefix(refElement.element.type) : void 0
1351
+ };
1352
+ return {
1353
+ name: refName,
1354
+ typeName: void 0
1355
+ };
1356
+ }
1357
+ }
1358
+ /**
1359
+ * Parse a child element's value (either complex type or simple value)
1360
+ */
1361
+ function parseChildValue(child, typeName, schema, rootSchema) {
1362
+ const nestedType = typeName ? findComplexType(typeName, schema) : void 0;
1363
+ if (nestedType) return parseElement(child, nestedType.ct, nestedType.schema, rootSchema);
1364
+ return convertValue(getTextContent(child) || "", typeName || "string");
1365
+ }
1366
+ /**
1367
+ * Convert string value to typed value based on XSD type
1368
+ */
1369
+ function convertValue(value, type) {
1370
+ switch (stripNsPrefix(type)) {
1371
+ case "int":
1372
+ case "integer":
1373
+ case "decimal":
1374
+ case "float":
1375
+ case "double":
1376
+ case "short":
1377
+ case "long":
1378
+ case "byte":
1379
+ case "unsignedInt":
1380
+ case "unsignedShort":
1381
+ case "unsignedLong":
1382
+ case "unsignedByte":
1383
+ case "positiveInteger":
1384
+ case "negativeInteger":
1385
+ case "nonPositiveInteger":
1386
+ case "nonNegativeInteger": return Number(value);
1387
+ case "boolean": return value === "true" || value === "1";
1388
+ case "date":
1389
+ case "dateTime": return value;
1390
+ default: return value;
1391
+ }
1392
+ }
1393
+
1394
+ //#endregion
1395
+ //#region src/xml/build-utils.ts
1396
+ /**
1397
+ * Get namespace prefix from schema $xmlns declarations
1398
+ */
1399
+ function getSchemaPrefix(schema) {
1400
+ if (!schema.$xmlns || !schema.targetNamespace) return void 0;
1401
+ for (const [prefix, uri] of Object.entries(schema.$xmlns)) if (uri === schema.targetNamespace && prefix) return prefix;
1402
+ }
1403
+ /**
1404
+ * Create XML document with namespace
1405
+ */
1406
+ function createXmlDocument(schema) {
1407
+ const impl = new DOMImplementation();
1408
+ const ns = schema.targetNamespace || null;
1409
+ return impl.createDocument(ns, "", null);
1410
+ }
1411
+ /**
1412
+ * Collect namespace declarations from a schema and its $imports/$includes recursively.
1413
+ *
1414
+ * Gathers all $xmlns prefix→URI mappings from the schema tree.
1415
+ * Unused declarations are cleaned up later by stripUnusedNamespaces()
1416
+ * after the XML tree is built — that approach is generic and doesn't
1417
+ * require any domain-specific knowledge.
1418
+ */
1419
+ function collectAllNamespaces(schema, collected = /* @__PURE__ */ new Map(), visited = /* @__PURE__ */ new Set()) {
1420
+ if (visited.has(schema)) return collected;
1421
+ visited.add(schema);
1422
+ if (schema.$xmlns) {
1423
+ for (const [pfx, uri] of Object.entries(schema.$xmlns)) if (!collected.has(pfx)) collected.set(pfx, uri);
1424
+ }
1425
+ const imports = schema.$imports;
1426
+ if (imports) for (const imported of imports) collectAllNamespaces(imported, collected, visited);
1427
+ const includes = schema.$includes;
1428
+ if (includes) for (const included of includes) collectAllNamespaces(included, collected, visited);
1429
+ return collected;
1430
+ }
1431
+ /**
1432
+ * Create root element with namespace declarations
1433
+ *
1434
+ * When elementFormDefault="unqualified", the root element should NOT have
1435
+ * a namespace prefix. This is important for formats like abapGit where
1436
+ * the root element (abapGit) is unqualified but child elements may have prefixes.
1437
+ */
1438
+ function createRootElement(doc, elementName, schema, prefix) {
1439
+ const ns = schema.targetNamespace || null;
1440
+ const usePrefix = schema.elementFormDefault === "unqualified" ? void 0 : prefix;
1441
+ const rootTag = usePrefix ? `${usePrefix}:${elementName}` : elementName;
1442
+ const root = doc.createElement(rootTag);
1443
+ if (ns && prefix) root.setAttribute(`xmlns:${prefix}`, ns);
1444
+ else if (ns && !prefix) root.setAttribute("xmlns", ns);
1445
+ const allNamespaces = collectAllNamespaces(schema);
1446
+ for (const [pfx, uri] of allNamespaces) if (pfx && pfx !== prefix) root.setAttribute(`xmlns:${pfx}`, uri);
1447
+ else if (!pfx) root.setAttribute("xmlns", uri);
1448
+ return root;
1449
+ }
1450
+ /**
1451
+ * Remove xmlns declarations from the root element for prefixes that are
1452
+ * not actually used anywhere in the document tree.
1453
+ *
1454
+ * This prevents emitting unused namespace declarations (e.g. xmlns:abapsource,
1455
+ * xmlns:abapoo) that come from the schema's $imports chain but aren't
1456
+ * referenced by any element or attribute in the built XML.
1457
+ *
1458
+ * The prefix that maps to the schema's own targetNamespace is always
1459
+ * preserved — even when elementFormDefault="unqualified" causes the root
1460
+ * element to be emitted without a prefix, the xmlns declaration is still
1461
+ * required for the document to be in the correct namespace.
1462
+ */
1463
+ /**
1464
+ * Add namespace prefix from a qualified name to the set (if present).
1465
+ */
1466
+ function addPrefixFromName(name, usedPrefixes) {
1467
+ const colon = name.indexOf(":");
1468
+ if (colon > 0) usedPrefixes.add(name.substring(0, colon));
1469
+ }
1470
+ /**
1471
+ * Collect namespace prefixes referenced by attributes on a single element
1472
+ * (xmlns declarations are skipped — they declare rather than use prefixes).
1473
+ */
1474
+ function collectPrefixesFromAttributes(node, usedPrefixes) {
1475
+ if (!node.attributes) return;
1476
+ for (const attr of Array.from(node.attributes)) if (!attr.name.startsWith("xmlns:") && attr.name !== "xmlns") addPrefixFromName(attr.name, usedPrefixes);
1477
+ }
1478
+ /**
1479
+ * Collect prefixes used by elements and attributes in the tree (recursive walk).
1480
+ */
1481
+ function collectUsedPrefixes(node, usedPrefixes) {
1482
+ addPrefixFromName(node.tagName, usedPrefixes);
1483
+ collectPrefixesFromAttributes(node, usedPrefixes);
1484
+ if (node.childNodes) {
1485
+ for (const child of Array.from(node.childNodes)) if (child.nodeType === 1) collectUsedPrefixes(child, usedPrefixes);
1486
+ }
1487
+ }
1488
+ /**
1489
+ * Collect xmlns:prefix attribute names on the root element whose prefix
1490
+ * is not in the used-prefixes set.
1491
+ */
1492
+ function findUnusedXmlnsAttrs(root, usedPrefixes) {
1493
+ const toRemove = [];
1494
+ if (!root.attributes) return toRemove;
1495
+ for (const attr of Array.from(root.attributes)) if (attr.name.startsWith("xmlns:")) {
1496
+ const pfx = attr.name.substring(6);
1497
+ if (!usedPrefixes.has(pfx)) toRemove.push(attr.name);
1498
+ }
1499
+ return toRemove;
1500
+ }
1501
+ function stripUnusedNamespaces(root, schema) {
1502
+ const usedPrefixes = /* @__PURE__ */ new Set();
1503
+ if (schema?.targetNamespace && schema.$xmlns) {
1504
+ for (const [pfx, uri] of Object.entries(schema.$xmlns)) if (pfx && uri === schema.targetNamespace) usedPrefixes.add(pfx);
1505
+ }
1506
+ collectUsedPrefixes(root, usedPrefixes);
1507
+ for (const name of findUnusedXmlnsAttrs(root, usedPrefixes)) root.removeAttribute(name);
1508
+ }
1509
+ /**
1510
+ * Format value for XML output
1511
+ */
1512
+ function formatValue(value, type) {
1513
+ if (value instanceof Date) return stripNsPrefix(type) === "date" ? value.toISOString().split("T")[0] : value.toISOString();
1514
+ if (typeof value === "boolean") return value ? "true" : "false";
1515
+ return String(value);
1516
+ }
1517
+ /**
1518
+ * Simple XML formatter (basic indentation)
1519
+ *
1520
+ * Keeps text content inline: <tag>text</tag>
1521
+ * Only adds newlines for nested elements
1522
+ */
1523
+ function formatXml(xml) {
1524
+ let formatted = "";
1525
+ let indent = 0;
1526
+ const parts = [];
1527
+ let pos = 0;
1528
+ while (pos < xml.length) if (xml.charCodeAt(pos) === 60) {
1529
+ const end = xml.indexOf(">", pos + 1);
1530
+ if (end === -1) {
1531
+ parts.push(xml.slice(pos));
1532
+ break;
1533
+ }
1534
+ parts.push(xml.slice(pos, end + 1));
1535
+ pos = end + 1;
1536
+ } else {
1537
+ const next = xml.indexOf("<", pos);
1538
+ if (next === -1) {
1539
+ parts.push(xml.slice(pos));
1540
+ break;
1541
+ }
1542
+ if (next > pos) parts.push(xml.slice(pos, next));
1543
+ pos = next;
1544
+ }
1545
+ let lastWasText = false;
1546
+ for (let i = 0; i < parts.length; i++) {
1547
+ const part = parts[i];
1548
+ const nextPart = parts[i + 1];
1549
+ if (part.startsWith("<?")) {
1550
+ formatted += part + "\n";
1551
+ lastWasText = false;
1552
+ } else if (part.startsWith("</")) {
1553
+ indent = Math.max(0, indent - 1);
1554
+ if (lastWasText) formatted += part + "\n";
1555
+ else formatted += " ".repeat(indent) + part + "\n";
1556
+ lastWasText = false;
1557
+ } else if (part.startsWith("<") && part.endsWith("/>")) {
1558
+ formatted += " ".repeat(indent) + part + "\n";
1559
+ lastWasText = false;
1560
+ } else if (part.startsWith("<")) {
1561
+ formatted += " ".repeat(indent) + part;
1562
+ if (!part.includes("</")) indent++;
1563
+ if (nextPart && !nextPart.startsWith("<")) {} else formatted += "\n";
1564
+ lastWasText = false;
1565
+ } else {
1566
+ const trimmed = part.trim();
1567
+ if (trimmed) {
1568
+ formatted += trimmed;
1569
+ lastWasText = true;
1570
+ }
1571
+ }
1572
+ }
1573
+ return formatted.trim();
1574
+ }
1575
+
1576
+ //#endregion
1577
+ //#region src/xml/build.ts
1578
+ /**
1579
+ * XML Builder for W3C Schema (Walker-based implementation)
1580
+ *
1581
+ * Build XML string from typed JavaScript object using W3C-compliant Schema definition.
1582
+ * Uses the walker module for schema traversal.
1583
+ */
1584
+ /**
1585
+ * Collect all namespace prefixes from a schema and its $imports chain
1586
+ */
1587
+ function collectAllXmlns(schema, visited = /* @__PURE__ */ new Set()) {
1588
+ if (visited.has(schema)) return {};
1589
+ visited.add(schema);
1590
+ const result = {};
1591
+ const xmlns = schema.$xmlns;
1592
+ if (xmlns) Object.assign(result, xmlns);
1593
+ const imports = schema.$imports;
1594
+ if (imports) for (const imported of imports) Object.assign(result, collectAllXmlns(imported, visited));
1595
+ return result;
1596
+ }
1597
+ /**
1598
+ * Get the namespace prefix for a schema's targetNamespace from the root schema's $xmlns
1599
+ * and all imported schemas' $xmlns (for inherited attributes)
1600
+ */
1601
+ function getPrefixForSchema(schema, rootSchema) {
1602
+ const targetNs = schema.targetNamespace;
1603
+ if (!targetNs) return void 0;
1604
+ const allXmlns = collectAllXmlns(rootSchema);
1605
+ for (const [prefix, ns] of Object.entries(allXmlns)) if (ns === targetNs) return prefix;
1606
+ }
1607
+ /**
1608
+ * Build XML string from typed object using schema definition
1609
+ */
1610
+ function build(schema, data, options = {}) {
1611
+ const { xmlDecl = true, encoding = "utf-8", pretty = false } = options;
1612
+ const prefix = options.prefix ?? getSchemaPrefix(schema);
1613
+ const doc = createXmlDocument(schema);
1614
+ let elementDecl;
1615
+ let elementSchema = schema;
1616
+ let elementData = data;
1617
+ if (options.rootElement) {
1618
+ const found = findElement(options.rootElement, schema);
1619
+ if (!found) throw new Error(`Element '${options.rootElement}' not found in schema`);
1620
+ elementDecl = found.element;
1621
+ elementSchema = found.schema;
1622
+ if (elementData[options.rootElement] !== void 0) elementData = elementData[options.rootElement];
1623
+ } else {
1624
+ const dataKeys = Object.keys(elementData);
1625
+ if (dataKeys.length === 1) {
1626
+ const potentialElementName = dataKeys[0];
1627
+ const found = findElement(potentialElementName, schema);
1628
+ if (found) {
1629
+ elementDecl = found.element;
1630
+ elementSchema = found.schema;
1631
+ elementData = elementData[potentialElementName];
1632
+ }
1633
+ }
1634
+ if (!elementDecl) {
1635
+ elementDecl = findMatchingElement(elementData, schema);
1636
+ if (!elementDecl) throw new Error("Schema has no element declarations");
1637
+ }
1638
+ }
1639
+ let rootType;
1640
+ let rootSchema = elementSchema;
1641
+ if (elementDecl.complexType) rootType = elementDecl.complexType;
1642
+ else if (elementDecl.type) {
1643
+ const typeName = stripNsPrefix(elementDecl.type);
1644
+ const rootTypeEntry = findComplexType(typeName, elementSchema);
1645
+ if (!rootTypeEntry) throw new Error(`Schema missing complexType for: ${typeName}`);
1646
+ rootType = rootTypeEntry.ct;
1647
+ rootSchema = rootTypeEntry.schema;
1648
+ } else throw new Error(`Element ${elementDecl.name} has no type or inline complexType`);
1649
+ const elementName = elementDecl.name ?? elementDecl.ref;
1650
+ if (!elementName) throw new Error("Element declaration has no name or ref");
1651
+ const root = createRootElement(doc, elementName, schema, prefix);
1652
+ buildElement(doc, root, elementData, rootType, rootSchema, schema, prefix);
1653
+ stripUnusedNamespaces(root, schema);
1654
+ if (!root.hasChildNodes()) root.appendChild(doc.createTextNode(""));
1655
+ doc.appendChild(root);
1656
+ let xml = new XMLSerializer().serializeToString(doc);
1657
+ if (xmlDecl) xml = `<?xml version="1.0" encoding="${encoding}"?>\n${xml}`;
1658
+ if (pretty) xml = formatXml(xml);
1659
+ return xml;
1660
+ }
1661
+ /**
1662
+ * Find the element declaration that best matches the data structure.
1663
+ * Searches in the main schema first, then in $imports.
1664
+ */
1665
+ function findMatchingElement(data, schema) {
1666
+ const dataKeys = new Set(Object.keys(data));
1667
+ let bestMatch;
1668
+ let bestScore = -1;
1669
+ const scoreElement = (element, searchSchema) => {
1670
+ let ct;
1671
+ let ctSchema = searchSchema;
1672
+ if (element.complexType) ct = element.complexType;
1673
+ else if (element.type) {
1674
+ const typeName = stripNsPrefix(element.type);
1675
+ const typeEntry = findComplexType(typeName, searchSchema);
1676
+ if (typeEntry) {
1677
+ ct = typeEntry.ct;
1678
+ ctSchema = typeEntry.schema;
1679
+ }
1680
+ }
1681
+ if (!ct) return 0;
1682
+ const typeFields = /* @__PURE__ */ new Set();
1683
+ for (const { element: el } of walkElements(ct, ctSchema)) if (el.name) typeFields.add(el.name);
1684
+ for (const { attribute } of walkAttributes(ct, ctSchema)) if (attribute.name) typeFields.add(attribute.name);
1685
+ let score = 0;
1686
+ dataKeys.forEach((key) => {
1687
+ if (typeFields.has(key)) score++;
1688
+ });
1689
+ return score;
1690
+ };
1691
+ const elements = schema.element;
1692
+ if (elements && elements.length > 0) for (const element of elements) {
1693
+ const score = scoreElement(element, schema);
1694
+ if (score > bestScore) {
1695
+ bestScore = score;
1696
+ bestMatch = element;
1697
+ }
1698
+ }
1699
+ const imports = schema.$imports;
1700
+ if (imports) for (const importedSchema of imports) {
1701
+ const importedElements = importedSchema.element;
1702
+ if (!importedElements) continue;
1703
+ for (const element of importedElements) {
1704
+ const score = scoreElement(element, importedSchema);
1705
+ if (score > bestScore) {
1706
+ bestScore = score;
1707
+ bestMatch = element;
1708
+ }
1709
+ }
1710
+ }
1711
+ if (!bestMatch && elements && elements.length > 0) return elements[0];
1712
+ return bestMatch;
1713
+ }
1714
+ /**
1715
+ * Build element content using its complexType definition
1716
+ * Uses walker to iterate elements and attributes (handles inheritance automatically)
1717
+ * @param rootSchema - The original schema passed to build(), used for substitution group lookup
1718
+ */
1719
+ function buildElement(doc, node, data, typeDef, schema, rootSchema, prefix) {
1720
+ for (const { attribute, schema: attrSchema } of walkAttributes(typeDef, schema)) {
1721
+ if (!attribute.name) continue;
1722
+ const value = data[attribute.name];
1723
+ if (value !== void 0 && value !== null) {
1724
+ const attributeFormDefault = attrSchema.attributeFormDefault;
1725
+ const attrForm = attribute.form;
1726
+ let attrName = attribute.name;
1727
+ if (attrForm === "qualified" || attrForm !== "unqualified" && attributeFormDefault === "qualified") {
1728
+ const attrPrefix = getPrefixForSchema(attrSchema, rootSchema);
1729
+ if (attrPrefix) attrName = `${attrPrefix}:${attribute.name}`;
1730
+ }
1731
+ node.setAttribute(attrName, formatValue(value, attribute.type || "string"));
1732
+ }
1733
+ }
1734
+ for (const { element, schema: elementDefSchema } of walkElements(typeDef, schema)) {
1735
+ if (element.ref) {
1736
+ const refName = stripNsPrefix(element.ref);
1737
+ const refElement = findElement(refName, elementDefSchema);
1738
+ if (refElement && refElement.element.abstract) {
1739
+ const substitutes = findSubstitutes$1(refName, rootSchema);
1740
+ for (const substitute of substitutes) {
1741
+ const subName = substitute.element.name;
1742
+ if (!subName) continue;
1743
+ const value = data[subName];
1744
+ if (value != null) buildField(doc, node, value, subName, substitute.element.type ? stripNsPrefix(substitute.element.type) : void 0, substitute.schema, rootSchema, prefix);
1745
+ }
1746
+ continue;
1747
+ }
1748
+ }
1749
+ const resolved = resolveElementInfo(element, elementDefSchema);
1750
+ if (!resolved) continue;
1751
+ const value = data[resolved.dataKey];
1752
+ if (value != null) buildFieldWithTagName(doc, node, value, resolved.tagName, resolved.typeName, resolved.inlineComplexType, resolved.elementSchema, rootSchema, prefix, resolved.form);
1753
+ }
1754
+ }
1755
+ /**
1756
+ * Resolve element info (name and type), handling ref
1757
+ *
1758
+ * Returns:
1759
+ * - tagName: The XML tag name to use (may include prefix like "asx:abap")
1760
+ * - dataKey: The key to look up in data object (local name without prefix)
1761
+ * - typeName: The type name for building nested content (if type attribute)
1762
+ * - inlineComplexType: The inline complexType definition (if present)
1763
+ * - elementSchema: The schema where the element was found
1764
+ * - form: Per-element form override ("qualified" or "unqualified")
1765
+ */
1766
+ function resolveElementInfo(element, schema) {
1767
+ if (element.name) return {
1768
+ tagName: element.name,
1769
+ dataKey: element.name,
1770
+ typeName: element.type ? stripNsPrefix(element.type) : void 0,
1771
+ inlineComplexType: element.complexType,
1772
+ elementSchema: schema,
1773
+ form: element.form
1774
+ };
1775
+ if (element.ref) {
1776
+ const refName = stripNsPrefix(element.ref);
1777
+ const refElement = findElement(refName, schema);
1778
+ if (refElement) return {
1779
+ tagName: element.ref,
1780
+ dataKey: refElement.element.name ?? refName,
1781
+ typeName: refElement.element.type ? stripNsPrefix(refElement.element.type) : void 0,
1782
+ inlineComplexType: refElement.element.complexType,
1783
+ elementSchema: refElement.schema,
1784
+ form: void 0
1785
+ };
1786
+ return {
1787
+ tagName: element.ref,
1788
+ dataKey: refName,
1789
+ typeName: void 0,
1790
+ inlineComplexType: void 0,
1791
+ elementSchema: schema,
1792
+ form: void 0
1793
+ };
1794
+ }
1795
+ }
1796
+ /**
1797
+ * Build a field (child element)
1798
+ *
1799
+ * Respects elementFormDefault:
1800
+ * - "qualified": local elements get namespace prefix
1801
+ * - "unqualified" (default): local elements do NOT get namespace prefix
1802
+ */
1803
+ function buildField(doc, parent, value, elementName, typeName, schema, rootSchema, prefix) {
1804
+ const nestedType = typeName ? findComplexType(typeName, schema) : void 0;
1805
+ const usePrefix = rootSchema.elementFormDefault === "qualified" ? prefix : void 0;
1806
+ const tagName = usePrefix ? `${usePrefix}:${elementName}` : elementName;
1807
+ if (Array.isArray(value)) for (const item of value) {
1808
+ const child = doc.createElement(tagName);
1809
+ if (nestedType) buildElement(doc, child, item, nestedType.ct, nestedType.schema, rootSchema, prefix);
1810
+ else {
1811
+ const text = formatValue(item, typeName || "string");
1812
+ if (text) child.appendChild(doc.createTextNode(text));
1813
+ }
1814
+ parent.appendChild(child);
1815
+ }
1816
+ else {
1817
+ const child = doc.createElement(tagName);
1818
+ if (nestedType) buildElement(doc, child, value, nestedType.ct, nestedType.schema, rootSchema, prefix);
1819
+ else {
1820
+ const text = formatValue(value, typeName || "string");
1821
+ if (text) child.appendChild(doc.createTextNode(text));
1822
+ }
1823
+ parent.appendChild(child);
1824
+ }
1825
+ }
1826
+ /**
1827
+ * Build a field with an explicit tag name (used for element refs with prefix)
1828
+ *
1829
+ * Handles three cases:
1830
+ * 1. Element refs with prefix (e.g., ref="asx:abap") - use tagName directly
1831
+ * 2. Elements with form="unqualified" - never use prefix
1832
+ * 3. Direct elements - apply elementFormDefault logic
1833
+ */
1834
+ function buildFieldWithTagName(doc, parent, value, tagName, typeName, inlineComplexType, elementSchema, rootSchema, prefix, elementForm) {
1835
+ let nestedType;
1836
+ if (inlineComplexType) nestedType = {
1837
+ ct: inlineComplexType,
1838
+ schema: elementSchema
1839
+ };
1840
+ else if (typeName) nestedType = findComplexType(typeName, elementSchema);
1841
+ let actualTagName = tagName;
1842
+ if (!tagName.includes(":")) {
1843
+ let usePrefix;
1844
+ if (elementForm === "unqualified") usePrefix = void 0;
1845
+ else if (elementForm === "qualified") usePrefix = getPrefixForSchema(elementSchema, rootSchema) ?? prefix;
1846
+ else usePrefix = (elementSchema.elementFormDefault ?? rootSchema.elementFormDefault) === "qualified" ? getPrefixForSchema(elementSchema, rootSchema) ?? prefix : void 0;
1847
+ actualTagName = usePrefix ? `${usePrefix}:${tagName}` : tagName;
1848
+ }
1849
+ if (Array.isArray(value)) for (const item of value) {
1850
+ const child = doc.createElement(actualTagName);
1851
+ if (nestedType) buildElement(doc, child, item, nestedType.ct, nestedType.schema, rootSchema, prefix);
1852
+ else {
1853
+ const text = formatValue(item, typeName || "string");
1854
+ if (text) child.appendChild(doc.createTextNode(text));
1855
+ }
1856
+ parent.appendChild(child);
1857
+ }
1858
+ else {
1859
+ const child = doc.createElement(actualTagName);
1860
+ if (nestedType) buildElement(doc, child, value, nestedType.ct, nestedType.schema, rootSchema, prefix);
1861
+ else {
1862
+ const text = formatValue(value, typeName || "string");
1863
+ if (text) child.appendChild(doc.createTextNode(text));
1864
+ }
1865
+ parent.appendChild(child);
1866
+ }
1867
+ }
1868
+ /**
1869
+ * Find all elements that substitute for a given abstract element name.
1870
+ * Searches in the main schema and all $imports.
1871
+ */
1872
+ function findSubstitutes$1(abstractElementName, schema) {
1873
+ const substitutes = [];
1874
+ const searchSchema = (s) => {
1875
+ const elements = s.element;
1876
+ if (!elements) return;
1877
+ for (const el of elements) if (el.substitutionGroup) {
1878
+ if (stripNsPrefix(el.substitutionGroup) === abstractElementName) substitutes.push({
1879
+ element: el,
1880
+ schema: s
1881
+ });
1882
+ }
1883
+ };
1884
+ searchSchema(schema);
1885
+ const imports = schema.$imports;
1886
+ if (imports) for (const imported of imports) searchSchema(imported);
1887
+ return substitutes;
1888
+ }
1889
+
1890
+ //#endregion
1891
+ //#region src/xml/typed.ts
1892
+ /**
1893
+ * Create a typed schema wrapper
1894
+ *
1895
+ * @param schema - Raw schema literal (with `as const`)
1896
+ * @returns Typed schema with parse/build methods
1897
+ *
1898
+ * @example
1899
+ * ```typescript
1900
+ * // Infer type from schema
1901
+ * const personSchema = typedSchema(rawPersonSchema);
1902
+ * const person = personSchema.parse(xml);
1903
+ *
1904
+ * // Or with explicit type
1905
+ * const personSchema = typedSchema<PersonType>(rawPersonSchema);
1906
+ * ```
1907
+ */
1908
+ function typedSchema(schema) {
1909
+ return {
1910
+ _type: null,
1911
+ schema,
1912
+ parse(xml) {
1913
+ return parse(schema, xml);
1914
+ },
1915
+ build(data, options) {
1916
+ return build(schema, data, options);
1917
+ }
1918
+ };
1919
+ }
1920
+
1921
+ //#endregion
1922
+ export { SchemaResolver, SchemaTraverser, build as buildXml, buildXsd, createSchemaLoader, defaultLoader, defineConfig, deriveRootTypeName, findComplexType, findElement, findSimpleType, findSubstitutes, generateInterfaces, generateSchemaFile, generateSchemaLiteral, getSubstitutes, isAbstractElement, linkSchema, linkSchemas, loadAndLinkSchema, loadSchema, parseXsd as parse, parseXsd, parseSchemaContent, parse as parseXml, resolveImports, resolveSchema, resolveSchemaTypes, runCodegen, stripNsPrefix, typedSchema, walkAttributes, walkComplexTypes, walkElements, walkSimpleTypes, walkTopLevelElements };
1923
+ //# sourceMappingURL=index.mjs.map