@techspokes/typescript-wsdl-client 0.30.0 → 0.30.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/README.md CHANGED
@@ -232,6 +232,7 @@ See [CLI Reference](docs/cli-reference.md) for all flags and examples.
232
232
  | [Programmatic API](docs/api-reference.md) | TypeScript functions for build tools |
233
233
  | [Core Concepts](docs/concepts.md) | Flattening, $value, primitives, determinism |
234
234
  | [Architecture](docs/architecture.md) | Internal pipeline for contributors |
235
+ | [File Naming And Path Organization](docs/file-naming-and-path-organization.md) | Contributor convention for taxonomy paths and fixture retrieval |
235
236
  | [Agent Skill Artifact](docs/agent-skill.md) | Release ZIP for consumer-project AI agents |
236
237
  | [Version 1.0 Roadmap Plan](docs/roadmap/README.md) | Conformance framework, implementation slices, and release gates for 1.0 |
237
238
  | [Streamable Responses (ADR-002)](docs/decisions/002-streamable-responses.md) | Opt-in streaming: client `AsyncIterable`, gateway NDJSON or JSON array, `x-wsdl-tsc-stream` |
@@ -515,7 +515,7 @@ function generatePackageJson(appDir, force) {
515
515
  soap: "^1.9.3",
516
516
  },
517
517
  devDependencies: {
518
- "@types/node": "^26.0.0",
518
+ "@types/node": "^26.0.1",
519
519
  tsx: "^4.22.4",
520
520
  typescript: "^6.0.3",
521
521
  },
@@ -38,6 +38,10 @@ export type CompiledWildcard = {
38
38
  namespace?: string;
39
39
  processContents?: "lax" | "strict" | "skip";
40
40
  };
41
+ export type CompiledAttributeWildcard = {
42
+ namespace?: string;
43
+ processContents?: "lax" | "strict" | "skip";
44
+ };
41
45
  export type CompiledChoiceBranch = {
42
46
  name: string;
43
47
  tsType: string;
@@ -68,6 +72,7 @@ export type CompiledChoiceGroup = {
68
72
  * @property {Array<Object>} [localAttrs] - Attributes added in extension (not inherited)
69
73
  * @property {Array<Object>} [localElems] - Elements added in extension (not inherited)
70
74
  * @property {Array<Object>} [wildcards] - xs:any wildcard particles retained on the type
75
+ * @property {Array<Object>} [attributeWildcards] - xs:anyAttribute wildcards retained on the type
71
76
  */
72
77
  export type CompiledType = {
73
78
  name: string;
@@ -108,6 +113,7 @@ export type CompiledType = {
108
113
  doc?: string;
109
114
  }>;
110
115
  wildcards?: CompiledWildcard[];
116
+ attributeWildcards?: CompiledAttributeWildcard[];
111
117
  choiceGroups?: CompiledChoiceGroup[];
112
118
  localChoiceGroups?: CompiledChoiceGroup[];
113
119
  };
@@ -1 +1 @@
1
- {"version":3,"file":"schemaCompiler.d.ts","sourceRoot":"","sources":["../../src/compiler/schemaCompiler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schemaCompiler.d.ts","sourceRoot":"","sources":["../../src/compiler/schemaCompiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,yBAAyB,CAAC;AAIzD,OAAO,KAAK,EAAC,uBAAuB,EAAE,YAAY,EAAC,MAAM,yBAAyB,CAAC;AAEnF;;;;;;GAMG;AACH,MAAM,MAAM,KAAK,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,oBAAoB,EAAE,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;QAC9B,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;QAC9B,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IAEH,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;QAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IAGH,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAG/B,kBAAkB,CAAC,EAAE,yBAAyB,EAAE,CAAC;IAGjD,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,iBAAiB,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,mBAAmB,EAAE,CAAC;CAC/B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,sBAAsB,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB,aAAa,CAAC,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,MAAM,CAAC,EAAE,uBAAuB,CAAC;CAClC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,eAAe,CAAC;IACzB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACjD,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;KAC/C,CAAC;IACF,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,WAAW,CAAC,EAAE,mBAAmB,CAAC;CACnC,CAAC;AAwJF;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,eAAe,EACxB,YAAY,CAAC,EAAE,YAAY,GAC1B,eAAe,CA0gCjB"}
@@ -213,6 +213,30 @@ export function compileCatalog(cat, options, streamConfig) {
213
213
  }
214
214
  return { tsType: xsdToTsPrimitive(declared, options?.primitive), declared };
215
215
  }
216
+ const union = getFirstWithLocalName(simpleNode, "union");
217
+ if (union) {
218
+ const members = [];
219
+ const memberTypes = String(union["@_memberTypes"] ?? "")
220
+ .split(/\s+/)
221
+ .map(value => value.trim())
222
+ .filter(Boolean);
223
+ for (const memberType of memberTypes) {
224
+ const q = resolveQName(memberType, schemaNS, prefixes);
225
+ members.push(resolveTypeRef(q, schemaNS, prefixes));
226
+ }
227
+ for (const inlineSimple of getChildrenWithLocalName(union, "simpleType")) {
228
+ members.push(compileSimpleTypeNode(inlineSimple, schemaNS, prefixes));
229
+ }
230
+ if (members.length > 0) {
231
+ const tsTypes = Array.from(new Set(members.flatMap(member => member.tsType.split("|").map(part => part.trim()))));
232
+ const declared = members.map(member => member.declared).join(" | ");
233
+ return {
234
+ tsType: tsTypes.join(" | "),
235
+ declared,
236
+ jsdoc: JSON.stringify({ kind: "union", members: members.map(member => member.declared) }),
237
+ };
238
+ }
239
+ }
216
240
  const list = getFirstWithLocalName(simpleNode, "list");
217
241
  if (list?.["@_itemType"]) {
218
242
  const q = resolveQName(list["@_itemType"], schemaNS, prefixes);
@@ -398,6 +422,17 @@ export function compileCatalog(cat, options, streamConfig) {
398
422
  recurse(node);
399
423
  return out;
400
424
  };
425
+ const collectAttributeWildcards = (node) => {
426
+ const out = [];
427
+ for (const a of getChildrenWithLocalName(node, "anyAttribute")) {
428
+ const pc = a["@_processContents"];
429
+ out.push({
430
+ ...(a["@_namespace"] ? { namespace: a["@_namespace"] } : {}),
431
+ ...(pc === "lax" || pc === "strict" || pc === "skip" ? { processContents: pc } : {}),
432
+ });
433
+ }
434
+ return out;
435
+ };
401
436
  const readOccurrence = (node) => {
402
437
  const min = node["@_minOccurs"] ? Number(node["@_minOccurs"]) : 1;
403
438
  const maxAttr = node["@_maxOccurs"];
@@ -542,12 +577,16 @@ export function compileCatalog(cat, options, streamConfig) {
542
577
  const newAttrs = collectAttributes(cnode);
543
578
  const newElems = collectParticles(outName, cnode);
544
579
  const newWildcards = collectWildcards(cnode);
580
+ const newAttributeWildcards = collectAttributeWildcards(cnode);
545
581
  const newChoiceGroups = collectChoiceGroups(outName, cnode);
546
582
  mergeAttrs(present.attrs, newAttrs);
547
583
  mergeElems(present.elems, newElems);
548
584
  if (newWildcards.length > 0) {
549
585
  present.wildcards = [...(present.wildcards ?? []), ...newWildcards];
550
586
  }
587
+ if (newAttributeWildcards.length > 0) {
588
+ present.attributeWildcards = [...(present.attributeWildcards ?? []), ...newAttributeWildcards];
589
+ }
551
590
  const mergedChoiceGroups = mergeChoiceGroups(present.choiceGroups, newChoiceGroups);
552
591
  if (mergedChoiceGroups && mergedChoiceGroups.length > 0) {
553
592
  present.choiceGroups = mergedChoiceGroups;
@@ -562,6 +601,7 @@ export function compileCatalog(cat, options, streamConfig) {
562
601
  // result accumulators
563
602
  const attrs = [];
564
603
  const elems = [];
604
+ const attributeWildcards = [];
565
605
  const choiceGroups = [];
566
606
  // Inheritance: complexContent
567
607
  const complexContent = getFirstWithLocalName(cnode, "complexContent");
@@ -582,6 +622,7 @@ export function compileCatalog(cat, options, streamConfig) {
582
622
  // inherit base members
583
623
  attrs.push(...baseType.attrs);
584
624
  elems.push(...baseType.elems);
625
+ attributeWildcards.push(...(baseType.attributeWildcards ?? []));
585
626
  choiceGroups.push(...(baseType.choiceGroups ?? []));
586
627
  }
587
628
  }
@@ -589,9 +630,11 @@ export function compileCatalog(cat, options, streamConfig) {
589
630
  const locals = collectAttributes(node);
590
631
  const localElems = collectParticles(outName, node);
591
632
  const localWildcards = collectWildcards(node);
633
+ const localAttributeWildcards = collectAttributeWildcards(node);
592
634
  const localChoiceGroups = collectChoiceGroups(outName, node);
593
635
  attrs.push(...locals);
594
636
  elems.push(...localElems);
637
+ attributeWildcards.push(...localAttributeWildcards);
595
638
  choiceGroups.push(...localChoiceGroups);
596
639
  const result = {
597
640
  name: outName,
@@ -603,6 +646,7 @@ export function compileCatalog(cat, options, streamConfig) {
603
646
  localAttrs: locals,
604
647
  localElems,
605
648
  ...(localWildcards.length > 0 ? { wildcards: localWildcards } : {}),
649
+ ...(attributeWildcards.length > 0 ? { attributeWildcards } : {}),
606
650
  ...(choiceGroups.length > 0 ? { choiceGroups } : {}),
607
651
  ...(localChoiceGroups.length > 0 ? { localChoiceGroups } : {}),
608
652
  };
@@ -632,7 +676,15 @@ export function compileCatalog(cat, options, streamConfig) {
632
676
  declaredType: r.declared,
633
677
  }]);
634
678
  mergeAttrs(attrs, collectAttributes(scNode));
635
- const result = { name: outName, ns: schemaNS, attrs, elems, doc: typeDoc };
679
+ const attributeWildcards = collectAttributeWildcards(scNode);
680
+ const result = {
681
+ name: outName,
682
+ ns: schemaNS,
683
+ attrs,
684
+ elems,
685
+ doc: typeDoc,
686
+ ...(attributeWildcards.length > 0 ? { attributeWildcards } : {}),
687
+ };
636
688
  compiledMap.set(key, result);
637
689
  inProgress.delete(rawKey);
638
690
  return result;
@@ -648,6 +700,7 @@ export function compileCatalog(cat, options, streamConfig) {
648
700
  mergeAttrs(attrs, collectAttributes(cnode));
649
701
  mergeElems(elems, collectParticles(outName, cnode));
650
702
  const wildcards = collectWildcards(cnode);
703
+ attributeWildcards.push(...collectAttributeWildcards(cnode));
651
704
  choiceGroups.push(...collectChoiceGroups(outName, cnode));
652
705
  const result = {
653
706
  name: outName,
@@ -656,6 +709,7 @@ export function compileCatalog(cat, options, streamConfig) {
656
709
  elems,
657
710
  doc: typeDoc,
658
711
  ...(wildcards.length > 0 ? { wildcards } : {}),
712
+ ...(attributeWildcards.length > 0 ? { attributeWildcards } : {}),
659
713
  ...(choiceGroups.length > 0 ? { choiceGroups } : {}),
660
714
  };
661
715
  compiledMap.set(key, result);
@@ -251,6 +251,10 @@ function canonicalizeType(t) {
251
251
  namespace: w.namespace ?? null,
252
252
  processContents: w.processContents ?? null,
253
253
  })),
254
+ attributeWildcards: (t.attributeWildcards ?? []).map((w) => ({
255
+ namespace: w.namespace ?? null,
256
+ processContents: w.processContents ?? null,
257
+ })),
254
258
  choiceGroups: (t.choiceGroups ?? []).map((g) => ({
255
259
  name: g.name,
256
260
  min: g.min,
@@ -1 +1 @@
1
- {"version":3,"file":"generateSchemas.d.ts","sourceRoot":"","sources":["../../src/openapi/generateSchemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAgB,eAAe,EAAe,MAAM,+BAA+B,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAkNpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,sBAAsB,GAAG,iBAAiB,CA2D1G"}
1
+ {"version":3,"file":"generateSchemas.d.ts","sourceRoot":"","sources":["../../src/openapi/generateSchemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAgB,eAAe,EAAe,MAAM,+BAA+B,CAAC;AAEhG;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAwPpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,sBAAsB,GAAG,iBAAiB,CA2D1G"}
@@ -8,6 +8,10 @@ function isLiteralUnion(ts) {
8
8
  }
9
9
  return null;
10
10
  }
11
+ function unionParts(ts) {
12
+ const parts = ts.split("|").map(p => p.trim()).filter(Boolean);
13
+ return parts.length > 1 ? parts : null;
14
+ }
11
15
  function primitiveSchema(ts) {
12
16
  switch (ts) {
13
17
  case "string":
@@ -25,6 +29,27 @@ function primitiveSchema(ts) {
25
29
  return { $ref: `#/components/schemas/${ts}` };
26
30
  }
27
31
  }
32
+ function schemaForUnionPart(ts) {
33
+ if (/^".*"$/.test(ts)) {
34
+ return { type: "string", enum: [ts.slice(1, -1)] };
35
+ }
36
+ return primitiveSchema(ts);
37
+ }
38
+ function mixedUnionSchema(ts) {
39
+ const parts = unionParts(ts);
40
+ if (!parts)
41
+ return null;
42
+ const schemas = parts.map(schemaForUnionPart);
43
+ const stringEnums = schemas
44
+ .filter((schema) => schema.type === "string" && Array.isArray(schema.enum))
45
+ .flatMap(schema => schema.enum);
46
+ const rest = schemas.filter(schema => !(schema.type === "string" && Array.isArray(schema.enum)));
47
+ const oneOf = [
48
+ ...(stringEnums.length > 0 ? [{ type: "string", enum: Array.from(new Set(stringEnums)) }] : []),
49
+ ...rest,
50
+ ];
51
+ return { oneOf };
52
+ }
28
53
  function buildAliasSchema(a) {
29
54
  const lit = isLiteralUnion(a.tsType);
30
55
  if (lit) {
@@ -34,6 +59,13 @@ function buildAliasSchema(a) {
34
59
  ...(a.doc ? { description: a.doc } : {}),
35
60
  };
36
61
  }
62
+ const union = mixedUnionSchema(a.tsType);
63
+ if (union) {
64
+ return {
65
+ ...union,
66
+ ...(a.doc ? { description: a.doc } : {}),
67
+ };
68
+ }
37
69
  // If alias wraps primitive
38
70
  if (["string", "number", "boolean", "any"].includes(a.tsType) || a.tsType.endsWith("[]")) {
39
71
  return {
@@ -86,6 +118,10 @@ function buildComplexSchema(t, closed, knownTypeNames, aliasNames, flattenWrappe
86
118
  if (lit) {
87
119
  return { type: "string", enum: lit };
88
120
  }
121
+ const union = mixedUnionSchema(ts);
122
+ if (union) {
123
+ return union;
124
+ }
89
125
  if (ts.endsWith("[]")) {
90
126
  const inner = ts.slice(0, -2);
91
127
  return { type: "array", items: refOrPrimitive(inner) };
package/docs/README.md CHANGED
@@ -28,6 +28,7 @@ Human-maintained reference documents for `@techspokes/typescript-wsdl-client`. T
28
28
  - [api-reference.md](api-reference.md): programmatic TypeScript API
29
29
  - [concepts.md](concepts.md): flattening, `$value`, primitives, determinism
30
30
  - [architecture.md](architecture.md): internal pipeline for contributors
31
+ - [file-naming-and-path-organization.md](file-naming-and-path-organization.md): contributor convention for taxonomy paths and fixture retrieval
31
32
  - [agent-skill.md](agent-skill.md): release ZIP for consumer-project AI agents
32
33
  - [roadmap/README.md](roadmap/README.md): conformance framework, implementation slices, and release gates for 1.0
33
34
  - [decisions/002-streamable-responses.md](decisions/002-streamable-responses.md): opt-in streaming design (client `AsyncIterable`, gateway NDJSON or JSON array, `x-wsdl-tsc-stream` OpenAPI extension); shipped in 0.17.0 and extended in 0.28.0
@@ -38,6 +39,7 @@ Human-maintained reference documents for `@techspokes/typescript-wsdl-client`. T
38
39
  - Each document opens with an H1 title and a one-line description.
39
40
  - Cross-reference related documents and the root README where relevant.
40
41
  - Use fenced code blocks for CLI examples; format flags as inline code (`` `--flag-name` ``).
42
+ - Use `bash` fences for portable command examples; reserve `powershell` fences for Windows-specific commands.
41
43
  - Run `npm run docs:validate` to check local links and TypeScript fenced snippets.
42
44
  - Keep language direct and task-oriented; architecture.md targets contributors, all others target users.
43
45
 
@@ -0,0 +1,207 @@
1
+ # File Naming And Path Organization
2
+
3
+ Contributor guide for naming files and organizing fixture paths. See the root [README.md](../README.md) for the authoritative documentation index.
4
+
5
+ ## Purpose
6
+
7
+ Paths should classify files before a reader opens them. The left side of a path carries the broadest concept; each segment to the right narrows the classification until the filename states the exact artifact purpose.
8
+
9
+ This convention is especially important for conformance fixtures. A maintainer should be able to search or list paths and see which WSDL, XSD, SOAP, policy, and recovery concepts already have evidence.
10
+
11
+ ## Authority Model
12
+
13
+ This convention borrows from resource-oriented API design. REST APIs commonly use noun-based paths, hierarchy through `/`, and readable lowercase path segments.
14
+
15
+ Google AIP-122 describes resource names as slash-separated paths and says collection identifiers are usually plural nouns. Zalando REST guidelines require plural resource names, kebab-case path segments, verb-free URLs, and domain-specific resource names. Microsoft Azure API guidelines prefer kebab-casing for URL path segments. REST URI naming guidance uses nouns for resources, `/` for hierarchy, and hyphens for readability.
16
+
17
+ Filesystem paths are not REST APIs, but the same retrieval model applies: a path is a resource name for a contributor, a terminal command, an IDE index, and an agent.
18
+
19
+ ## Shell Examples
20
+
21
+ Use `bash` fences for portable command examples in repository documentation and GitHub workflow notes. Use `powershell` fences only when the command is intentionally Windows-specific.
22
+
23
+ Prefer `rg` for retrieval examples because agents already use it for fast file and content search. Write path filters so they tolerate `/` and `\` separators when possible.
24
+
25
+ On Windows PowerShell, keep `rg` regex arguments in single quotes when the pattern contains backslashes, brackets, or alternation. The examples in this document were checked in PowerShell with single-quoted regexes. A no-match `rg` filter exits with code `1`; that is expected for negative checks such as confirming `service.wsdl` is absent.
26
+
27
+ ## Progressive Discovery
28
+
29
+ Start broad, then narrow. A path should answer these questions from left to right:
30
+
31
+ 1. What repository area owns this artifact?
32
+ 2. What artifact family is this?
33
+ 3. What standards domain or product domain does it belong to?
34
+ 4. What feature family does it exercise?
35
+ 5. What exact purpose does the file serve?
36
+
37
+ For conformance fixtures, this means the preferred shape is:
38
+
39
+ ```text
40
+ test/conformance/fixtures/<domain>/<feature-family>/<feature-name>.<ext>
41
+ ```
42
+
43
+ Use deeper nesting only when it improves retrieval. Do not create a folder level that only repeats the filename.
44
+
45
+ ## Folder Names
46
+
47
+ Folder names are taxonomy terms. They classify a set of files.
48
+
49
+ - Use lowercase kebab-case.
50
+ - Prefer one noun per segment.
51
+ - Prefer plural nouns when the term is naturally countable.
52
+ - Preserve standards terms when pluralizing them would reduce clarity.
53
+ - Avoid verbs, implementation steps, and filler words.
54
+ - Place the broadest useful classifier on the left.
55
+ - Add a narrower folder only when it groups multiple related files or distinguishes a standards boundary.
56
+
57
+ Acceptable standards-domain folders include `wsdl`, `xsd`, `soap`, `ws-policy`, `ws-security`, `interop`, and `recovery`.
58
+
59
+ Acceptable feature-family folders include `types`, `elements`, `bindings`, `policies`, `attachments`, `wildcards`, `compositors`, `sequences`, and `choices`.
60
+
61
+ ## File Names
62
+
63
+ File names state the exact purpose and content of the artifact. They should remain useful when shown without the full path.
64
+
65
+ - Use lowercase kebab-case.
66
+ - Use general-to-specific segment order.
67
+ - Put the broad feature classifier first.
68
+ - Put variable-like qualifiers at the right side.
69
+ - Keep recognized standards terms when they identify the feature.
70
+ - Avoid filler words such as `service`, `sample`, `fixture`, and `test`.
71
+ - Use the file extension to identify format, not the basename.
72
+
73
+ Good file names classify sorted terminal output:
74
+
75
+ ```text
76
+ attachment-mtom-xop.wsdl
77
+ binding-soap-first-multi.wsdl
78
+ choice-union-simple.wsdl
79
+ element-substitution-group.wsdl
80
+ policy-reference-external.wsdl
81
+ sequence-composition-deep.wsdl
82
+ type-complex-abstract-extension.wsdl
83
+ type-union-simple.wsdl
84
+ wildcard-attribute-any.wsdl
85
+ ```
86
+
87
+ Avoid names that only read naturally in English but group poorly in file listings:
88
+
89
+ ```text
90
+ abstract-complex-type-extension.wsdl
91
+ any-attribute.wsdl
92
+ deep-sequence-composition.wsdl
93
+ mtom-xop-attachment.wsdl
94
+ multi-binding-first-soap.wsdl
95
+ xs-union-simple-type.wsdl
96
+ ```
97
+
98
+ ## Conformance Fixtures
99
+
100
+ Conformance fixtures should be committed XML files, not inline strings in tests. Inline XML is acceptable only for throwaway probes or very small unit tests that do not represent a reusable fixture.
101
+
102
+ The fixture path should support discovery by partial path search. A contributor should be able to search `xsd/wildcards`, `soap/attachments`, or `wsdl/bindings` and see what exists.
103
+
104
+ The registry ID should remain stable for test reporting. The fixture path may use taxonomy folders and a more precise filename when that improves retrieval.
105
+
106
+ ## Multi-file Fixtures
107
+
108
+ Use a folder when a fixture needs a root WSDL plus imported schemas or companion files. Keep the root filename aligned with the feature name.
109
+
110
+ ```text
111
+ test/conformance/fixtures/xsd/wildcards/wildcard-attribute-any.wsdl
112
+ test/conformance/fixtures/xsd/wildcards/wildcard-attribute-any-types.xsd
113
+ test/conformance/fixtures/xsd/wildcards/wildcard-attribute-any-shared.xsd
114
+ ```
115
+
116
+ Use purpose suffixes such as `types`, `messages`, `shared`, `policy`, and `binding` for companion files.
117
+
118
+ ## Retrieval Examples
119
+
120
+ List every conformance fixture path:
121
+
122
+ ```bash
123
+ rg --files test/conformance/fixtures | sort
124
+ ```
125
+
126
+ Find every XSD wildcard fixture:
127
+
128
+ ```bash
129
+ rg --files test/conformance/fixtures | rg '(^|[\\/])xsd[\\/]wildcards[\\/]'
130
+ ```
131
+
132
+ Find whether a SOAP attachment fixture exists:
133
+
134
+ ```bash
135
+ rg --files test/conformance/fixtures | rg '(^|[\\/])attachment-'
136
+ ```
137
+
138
+ Use `rg` when searching by concept inside paths or XML content:
139
+
140
+ ```bash
141
+ rg -n "xs:anyAttribute|wildcard-attribute" test\conformance\fixtures
142
+ ```
143
+
144
+ ## Agent Retrieval Playbook
145
+
146
+ Agents should prefer a small number of focused file-system checks before adding or renaming fixtures. These commands are intentionally simple and use portable `rg` patterns.
147
+
148
+ Check the current taxonomy shape:
149
+
150
+ ```bash
151
+ rg --files test/conformance/fixtures | sort
152
+ ```
153
+
154
+ Check whether a domain branch already exists:
155
+
156
+ ```bash
157
+ rg --files test/conformance/fixtures | rg '(^|[\\/])xsd[\\/]types[\\/]'
158
+ ```
159
+
160
+ Find fixtures by filename classifier:
161
+
162
+ ```bash
163
+ rg --files test/conformance/fixtures | rg '(^|[\\/])type-'
164
+ ```
165
+
166
+ Find fixtures by XML feature content:
167
+
168
+ ```bash
169
+ rg -n "xs:union|xs:anyAttribute|substitutionGroup|PolicyReference" test\conformance\fixtures
170
+ ```
171
+
172
+ Check whether old filler names are still present:
173
+
174
+ ```bash
175
+ rg --files test/conformance/fixtures | rg '(^|[\\/])service\.wsdl'
176
+ ```
177
+
178
+ Find the registry row that owns a fixture path:
179
+
180
+ ```bash
181
+ rg -n "wildcard-attribute-any|type-union-simple|attachment-mtom-xop" test\conformance\registry.ts
182
+ ```
183
+
184
+ Use these commands as discovery checks, not as validation gates. Repository validation still runs through `npm run docs:validate`, `npm run test:conformance`, and `npm test`.
185
+
186
+ ## Candidate Fixture Paths
187
+
188
+ Use these paths as the target direction for the current conformance corpus:
189
+
190
+ ```text
191
+ test/conformance/fixtures/xsd/compositors/choice-union-simple.wsdl
192
+ test/conformance/fixtures/xsd/types/type-union-simple.wsdl
193
+ test/conformance/fixtures/xsd/types/type-complex-abstract-extension.wsdl
194
+ test/conformance/fixtures/xsd/elements/element-substitution-group.wsdl
195
+ test/conformance/fixtures/wsdl/bindings/binding-soap-first-multi.wsdl
196
+ test/conformance/fixtures/ws-policy/references/policy-reference-external.wsdl
197
+ test/conformance/fixtures/xsd/sequences/sequence-composition-deep.wsdl
198
+ test/conformance/fixtures/xsd/wildcards/wildcard-attribute-any.wsdl
199
+ test/conformance/fixtures/soap/attachments/attachment-mtom-xop.wsdl
200
+ ```
201
+
202
+ ## References
203
+
204
+ - [Google AIP-122 Resource Names](https://google.aip.dev/122)
205
+ - [Zalando RESTful API Guidelines](https://opensource.zalando.com/restful-api-guidelines/)
206
+ - [Microsoft Azure API Guidelines](https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md)
207
+ - [REST API URI Naming Conventions](https://restfulapi.net/resource-naming/)
@@ -0,0 +1,31 @@
1
+ # TypeScript WSDL Client v0.30.1
2
+
3
+ ## Roadmap And Dependency Patch
4
+
5
+ This patch release refreshes the 1.0 readiness documentation after the `0.30.0` maintenance release and advances the Node type definitions used by the package and generated app scaffold.
6
+
7
+ ## What This Improves
8
+
9
+ Maintainers get roadmap and supported-pattern documentation that matches the current release line before starting the conformance framework work. Contributors also get clearer guidance about optional IDE MCP tooling in public-repository workflows.
10
+
11
+ ## Highlights
12
+
13
+ - Aligns roadmap documentation with the current `0.30.x` release state.
14
+ - Clarifies that `xs:any` wildcard metadata is retained for selected compiler and streaming workflows, but full wildcard serialization is not a typed contract.
15
+ - Documents optional IDE MCP routing while preserving terminal-based contributor fallbacks.
16
+ - Updates `@types/node` to 26.0.1 in both the package and generated app scaffold pins.
17
+
18
+ ## Upgrade Notes
19
+
20
+ No special upgrade steps. Regenerate generated Fastify app scaffolds when you want new app projects to start with the updated `@types/node` pin.
21
+
22
+ ## Validation
23
+
24
+ - CI passed.
25
+ - NPM package contents were validated.
26
+ - Documentation links and TypeScript fenced snippets were validated.
27
+ - Agent skill artifact was validated and packaged.
28
+
29
+ ## Notes
30
+
31
+ Release tag: `v0.30.1`.
@@ -0,0 +1,30 @@
1
+ # TypeScript WSDL Client v0.30.2
2
+
3
+ ## Conformance fixture foundation
4
+
5
+ This patch release adds the first capability conformance fixture corpus, records `xs:anyAttribute` wildcard metadata, and documents a reusable taxonomy for fixture paths and file names.
6
+
7
+ ## What This Improves
8
+
9
+ Maintainers now have a fixture-backed way to classify WSDL and XSD support claims before 1.0. The conformance registry makes supported, partial, diagnostic, unsupported, and research rows explicit, while taxonomy-based fixture paths make it easier to discover existing XML coverage through ordinary file-system search.
10
+
11
+ ## Highlights
12
+
13
+ - Added Phase 1 conformance registry tests and reusable WSDL fixtures.
14
+ - Retained `xs:anyAttribute` declarations as compiled type metadata.
15
+ - Documented taxonomy-based fixture path organization and portable retrieval commands.
16
+
17
+ ## Upgrade Notes
18
+
19
+ No special upgrade steps.
20
+
21
+ ## Validation
22
+
23
+ - Dependency maintenance completed successfully.
24
+ - Documentation validation passed.
25
+ - Test suite passed.
26
+ - Smoke pipeline passed.
27
+
28
+ ## Notes
29
+
30
+ Release tag: `v0.30.2`.
@@ -0,0 +1,33 @@
1
+ # TypeScript WSDL Client v0.30.3
2
+
3
+ ## Fixture-Backed Support Evidence
4
+
5
+ This patch release adds simple `xs:union` support and makes the public support matrix generated from the conformance registry.
6
+
7
+ ## What This Improves
8
+
9
+ Developers using WSDLs with simple `xs:union` aliases now get honest TypeScript union aliases and OpenAPI `oneOf` schemas instead of an under-modeled type. Maintainers also get a generated support matrix that keeps public documentation aligned with fixture-backed conformance rows.
10
+
11
+ The release process guidance now makes the tag gate explicit: development commit titles may use the next patch target, but release tags require package metadata, changelog, release notes, and preflight checks to match first.
12
+
13
+ ## Highlights
14
+
15
+ - Simple `xs:union` aliases now compile to TypeScript unions.
16
+ - Mixed primitive and literal unions now emit OpenAPI `oneOf` schemas.
17
+ - The public capability evidence matrix is generated from the conformance registry.
18
+ - Agent instructions now require release preflight before pushing release tags.
19
+
20
+ ## Upgrade Notes
21
+
22
+ No special upgrade steps.
23
+
24
+ ## Validation
25
+
26
+ - CI passed.
27
+ - NPM package contents were validated.
28
+ - Agent skill artifact was validated and packaged.
29
+ - Release preflight passed against the target tag.
30
+
31
+ ## Notes
32
+
33
+ Release tag: `v0.30.3`.
@@ -1,6 +1,6 @@
1
1
  # Version 1.0 Roadmap Plan
2
2
 
3
- Detailed plan for moving `@techspokes/typescript-wsdl-client` from the released `0.28.x` line to a stable `1.0.0` release.
3
+ Detailed plan for moving `@techspokes/typescript-wsdl-client` from the released `0.30.x` line to a stable `1.0.0` release.
4
4
 
5
5
  See the root [README.md](../../README.md) for project overview and the root [ROADMAP.md](../../ROADMAP.md) for the public roadmap summary.
6
6
 
@@ -8,7 +8,7 @@ See the root [README.md](../../README.md) for project overview and the root [ROA
8
8
 
9
9
  This plan turns the 1.0 roadmap into implementation slices that can be picked up independently. Each slice has its own plan document with scope, testing strategy, acceptance gates, and release implications.
10
10
 
11
- The plan is optimized for preserving quality. The contract and compatibility baselines now exist, choice union mode is shipped, and JSON array streaming is shipped. The remaining readiness work is WSDL coverage evidence and the final release candidate gate pass.
11
+ The plan is optimized for preserving quality. The contract and compatibility baselines now exist, choice union mode is shipped, and JSON array streaming is shipped. The remaining readiness work is the capability conformance framework, WSDL coverage evidence, and the final release candidate gate pass.
12
12
 
13
13
  ## Route Summary
14
14
 
@@ -54,7 +54,7 @@ Run the release candidate gates after feature work and documentation have conver
54
54
 
55
55
  ## Remaining Before 1.0
56
56
 
57
- - Build the capability conformance registry and runner.
57
+ - Build the capability conformance registry and compile-stage runner.
58
58
  - Build and run the WSDL feature matrix as the first conformance domain.
59
59
  - Turn unsupported or partial matrix rows into diagnostics, documentation, or scoped fixes.
60
60
  - Confirm `docs/supported-patterns.md` matches the matrix.
@@ -75,6 +75,8 @@ The generated test stage proves `--test-dir` emits tests that compile and pass f
75
75
 
76
76
  The documentation stage proves `docs/supported-patterns.md` agrees with the capability registry. It should prevent docs from claiming support, partial support, or non-support without a matching conformance row.
77
77
 
78
+ The public evidence matrix in `docs/supported-patterns.md` should be generated from registry rows. The rest of the page should remain human-authored so supported-pattern explanations stay useful to readers.
79
+
78
80
  ## Registry Shape
79
81
 
80
82
  The first implementation should use a TypeScript manifest because tests can import it with full type safety. JSON can be added later if external tooling needs a stable data format.
@@ -89,12 +91,169 @@ interface CapabilityCase {
89
91
  featureTags: string[];
90
92
  fixture: string;
91
93
  docsAnchor?: string;
94
+ publicContract: string;
92
95
  stages: CapabilityStages;
93
96
  }
94
97
  ```
95
98
 
96
99
  Stage payloads should stay small and explicit. Avoid a generic assertion language in the first version; use typed expectation objects and small runner helpers instead.
97
100
 
101
+ ## Standards And External Corpus
102
+
103
+ Use WSDL 1.1, SOAP 1.1, XML Schema 1.0, and WS-I Basic Profile as the authority stack for Phase 1 capability expectations.
104
+
105
+ WSDL 1.1 defines the service description model used by this project: `types`, `message`, `portType`, `binding`, `port`, and `service`, plus SOAP 1.1, HTTP, and MIME binding extensions.
106
+
107
+ SOAP 1.1 defines the envelope and processing model that generated clients ultimately target through `node-soap`.
108
+
109
+ XML Schema 1.0 defines the schema constructs compiled into TypeScript and OpenAPI shapes. XML Schema 1.1 test suites are useful as edge-case inspiration, but the project should not imply full XML Schema 1.1 support.
110
+
111
+ WS-I Basic Profile 1.1 and 1.2 define interoperability constraints across SOAP, WSDL, XML Schema, and HTTP. Treat WS-I rules as the best available profile for portable SOAP behavior, not as a complete fixture source.
112
+
113
+ Do not vendor third-party WSDL or XSD corpora wholesale in Phase 1. Prefer minimized synthetic fixtures derived from standard rules and clearly cite the relevant standard or profile section in the registry row.
114
+
115
+ Third-party suites can inform future rows:
116
+
117
+ - W3C WSDL 2.0 Test Suite: useful for conformance-suite structure, but not directly applicable to this WSDL 1.1 generator.
118
+ - W3C XML Schema test suite: useful for XSD edge-case discovery, but it validates schema processors rather than WSDL-to-client generation.
119
+ - WS-I test assertions and analyzer tools: useful for interoperability rule vocabulary, but heavy and not a direct TypeScript generation oracle.
120
+ - Apache Axis or Apache CXF sample WSDL files: useful as real-world smoke candidates when license and fixture scope are clear.
121
+
122
+ ## Public Fixture Corpus Direction
123
+
124
+ The conformance framework should be designed so its fixtures can later seed a standalone public project, tentatively named `wsdl-conformance-fixtures`.
125
+
126
+ The public fixture project would be an experimental, curated corpus of small WSDL and XSD fixtures for SOAP client and code-generation tools. It should not claim to be an official standards suite. It should provide practical, source-backed examples for valid, partial, diagnostic, unsupported, recovery, and real-world-compatible behaviors.
127
+
128
+ The public corpus should preserve clean licensing and clear provenance. Do not copy external corpora wholesale. Prefer original minimized fixtures derived from standards, profiles, and observed real-world patterns.
129
+
130
+ Phase 1 should add metadata that will make extraction possible later without changing every row:
131
+
132
+ - `authority`: the standard, profile, or real-world source category behind the case.
133
+ - `provenance`: a short explanation of whether the fixture is original, minimized from a report, or inspired by a third-party example.
134
+ - `license`: the fixture license or repository default license.
135
+ - `fixtureKind`: one of `standards-valid`, `interop-profile`, `real-world-compatible`, `diagnostic-required`, or `recovery`.
136
+
137
+ Do not publish the standalone fixture project before the internal registry has proven the metadata shape with multiple useful rows. The first public release should happen only after maintainers can explain how another tool would consume the fixtures without depending on this repository's internals.
138
+
139
+ ## Fixture Corpus Goals
140
+
141
+ The internal corpus should serve this repository first. It should make generator behavior explicit, prevent silent miscompilation, and give maintainers a repeatable way to classify WSDL reports.
142
+
143
+ The future public corpus should serve the SOAP tooling community. It should offer small, understandable fixtures that other generators, validators, and migration tools can run against or inspect.
144
+
145
+ The corpus should distinguish standards conformance from product policy. A fixture can be standards-valid while unsupported by this generator, or non-ideal but common enough to justify recovery behavior.
146
+
147
+ The corpus should be useful without a live network. Every fixture should be committed with local relative imports and no dependency on public SOAP endpoints.
148
+
149
+ The corpus should be explainable. Each fixture should say what behavior it exercises, what source justifies the expectation, and which outcomes are acceptable.
150
+
151
+ ## Decision Framework
152
+
153
+ Use this framework before changing a capability from `research` to a final status. The decision should optimize for truthful generation, deterministic output, and maintainable SOAP modernization rather than broad standards completeness.
154
+
155
+ First decide whether the construct is important enough for this project. Favor support when the feature is common in WSDLs, important for enterprise modernization, or already required by existing generated outputs. Favor deferral when the feature is rare, can be worked around, or requires a runtime contract outside the current product surface.
156
+
157
+ Then decide whether the construct can be modeled honestly in `catalog.json`. If the catalog can represent the shape without losing semantics, support or partial support may be appropriate. If the catalog would hide polymorphism, transport behavior, binary parts, external network policy, or runtime ambiguity, prefer a diagnostic or unsupported decision.
158
+
159
+ Then check downstream stages. A `supported` row must work through every relevant stage. A feature that compiles but cannot be represented in generated TypeScript, OpenAPI, gateway runtime, or generated tests should be `partial` unless those stages do not apply.
160
+
161
+ Then check implementation locality. Local schema transforms such as simple aliases, deterministic metadata retention, and documented first-choice behavior are good support candidates. Features that require broad runtime semantics, wire-protocol changes, or public API design should usually become diagnostics or explicit deferrals before 1.0.
162
+
163
+ Use these decisions:
164
+
165
+ - `support`: implement and prove the feature through relevant stages.
166
+ - `partial-support`: implement the honest subset and document the limit.
167
+ - `diagnostic`: reject or warn clearly to avoid silent miscompilation.
168
+ - `defer`: keep a fixture and rationale, but do not claim support yet.
169
+ - `out-of-scope`: document that the feature is intentionally outside the 1.0 product contract.
170
+
171
+ When full support is clearly local, deterministic, and representable, implement it rather than leaving unnecessary diagnostics. When full support would imply semantics the generator cannot preserve, prefer diagnostics over partial, misleading output.
172
+
173
+ ## Phase 1 Decisions
174
+
175
+ Phase 1 is internal test infrastructure. It must not add exports from `src/index.ts`, new public CLI commands, or new consumer-facing APIs.
176
+
177
+ The first registry should live under `test/conformance/registry.ts`. It should export types and data for repository tests only. Public package exports can be reconsidered after the inspector has a stable use case.
178
+
179
+ The first runner should live under `test/conformance/runner.ts`. It should execute compile-stage checks by calling `loadWsdl`, `compileCatalog`, and `resolveCompilerOptions` directly.
180
+
181
+ The first Vitest entry point should be `test/conformance/conformance.test.ts`. Add `npm run test:conformance` and keep it included in `npm test` through Vitest's normal test discovery.
182
+
183
+ Fixtures should live under `test/conformance/fixtures/`. Each fixture should be a committed `.wsdl` or `.xsd` file, use relative files only, and require no network access.
184
+
185
+ Documentation drift checks should start as a lightweight test in `test/conformance/docs.test.ts`. The test should verify that each registry row with a `docsAnchor` points to an existing heading anchor in `docs/supported-patterns.md`.
186
+
187
+ The public evidence matrix should be generated from the registry with `npm run docs:support-matrix`. The check command should fail when the generated table and committed table drift.
188
+
189
+ ## Phase 1 File Map
190
+
191
+ Create `test/conformance/types.ts` for shared registry types. Keep these types out of `src/` until a public API is justified.
192
+
193
+ Create `test/conformance/registry.ts` for the initial capability rows. Include every priority feature from the WSDL coverage matrix.
194
+
195
+ Create `test/conformance/runner.ts` for compile-stage execution helpers. Resolve fixture paths relative to `test/conformance/fixtures/` and create one temporary output directory per case under the OS temp directory.
196
+
197
+ Create `test/conformance/conformance.test.ts` for manifest-driven compile tests. Supported and partial rows should compile successfully; diagnostic rows should assert the error shape or explicit warning behavior.
198
+
199
+ Create `test/conformance/docs.test.ts` for registry-to-docs alignment. It should validate existing heading anchors and prove that the public evidence matrix matches generated registry output.
200
+
201
+ Create `test/conformance/fixtures/` with one minimal WSDL per initial row. Keep each fixture synthetic, deterministic, and scoped to one capability.
202
+
203
+ Modify `package.json` to add `test:conformance` with `vitest run test/conformance`.
204
+
205
+ Modify `docs/supported-patterns.md` only when the registry reveals a real mismatch. Generate only the evidence matrix from the registry in Phase 1; do not rewrite the explanatory sections from registry data.
206
+
207
+ ## Phase 1 Type Contract
208
+
209
+ Use these internal test types as the starting point:
210
+
211
+ ```ts
212
+ export type CapabilityStatus = "supported" | "partial" | "diagnostic" | "unsupported" | "research";
213
+
214
+ export type CompileExpectation =
215
+ | { outcome: "success"; typeNames?: string[]; aliasNames?: string[]; operationNames?: string[]; diagnosticNotes?: string[] }
216
+ | { outcome: "error"; errorClass?: "WsdlCompilationError"; messageIncludes?: string[]; userMessageIncludes?: string[]; context?: Partial<WsdlErrorContext> }
217
+ | { outcome: "research"; reason: string };
218
+
219
+ export interface CapabilityCase {
220
+ id: string;
221
+ title: string;
222
+ status: CapabilityStatus;
223
+ featureTags: string[];
224
+ fixture: string;
225
+ docsAnchor?: string;
226
+ publicContract: string;
227
+ decision: CapabilityDecision;
228
+ decisionReason: string;
229
+ compile: CompileExpectation;
230
+ }
231
+ ```
232
+
233
+ `docsAnchor` values should use the same heading slug rules as the repository docs validator. Phase 1 may point rows to broad section anchors such as `fully-supported`, `partially-supported`, `not-yet-supported`, or `known-edge-cases`. Add feature-level headings to `docs/supported-patterns.md` only when a broad section anchor is too ambiguous for a row.
234
+
235
+ `error` expectations should assert `instanceof WsdlCompilationError` when `errorClass` is `WsdlCompilationError`. `messageIncludes` checks should inspect `error.message`, `userMessageIncludes` checks should inspect `error.toUserMessage()`, and `context` checks should inspect `error.context`.
236
+
237
+ `unsupported` rows should not silently pass. They should either use an `error` compile expectation or remain `research` until a diagnostic exists.
238
+
239
+ `partial` rows should compile successfully only when the limitation is explicitly documented. The row should include a `docsAnchor` and an assertion that proves the supported subset.
240
+
241
+ `research` rows should not pretend to validate support. They should load the fixture only if useful, then state the unresolved decision in the registry.
242
+
243
+ ## Phase 1 Conventions
244
+
245
+ Prefer committed fixture files over inline WSDL strings. Inline WSDL builders are useful for focused unit tests, but conformance cases should be inspectable as standalone artifacts.
246
+
247
+ Use the taxonomy path convention in [File Naming And Path Organization](../file-naming-and-path-organization.md) for reusable fixtures. Put imported schemas beside the root WSDL when a capability needs multiple files.
248
+
249
+ Use a runner-owned temporary directory per capability case. Do not share a module-level temp root across the suite, because conformance failures should leave case-local paths easy to inspect.
250
+
251
+ Assert catalog shape through stable names and metadata. Avoid full catalog snapshots in Phase 1 because the registry should describe capability contracts, not freeze incidental serialization details.
252
+
253
+ Assert diagnostics through `WsdlCompilationError` and catalog `diagnostics.notes`. Do not assert full formatted messages unless the exact text is part of the public contract.
254
+
255
+ Prefer adding feature-level headings in `docs/supported-patterns.md` when a broad section anchor would make the docs check too weak. Keep those headings short and user-facing.
256
+
98
257
  ## Fixture Strategy
99
258
 
100
259
  Fixtures should live under a dedicated conformance fixture directory, separate from the weather smoke fixture. Each fixture should be minimal, synthetic, deterministic, and focused on one capability unless the purpose is to prove a composition case.
@@ -142,12 +301,29 @@ The inspector should not be treated as proof that generation will succeed. It is
142
301
 
143
302
  Create the capability registry, fixture directory, and a Vitest runner for compile-stage expectations. Include the existing roadmap priority rows and keep unsupported rows diagnostic or research-only until behavior is proven.
144
303
 
304
+ Start with these capability IDs:
305
+
306
+ | ID | Status | Compile expectation |
307
+ |---|---|---|
308
+ | `choice-union-simple` | supported | success |
309
+ | `xs-union-simple-type` | supported | success |
310
+ | `abstract-complex-type` | diagnostic | error or research |
311
+ | `substitution-group-element` | diagnostic | error or research |
312
+ | `multi-binding-first-soap` | partial | success with documented behavior |
313
+ | `external-policy-reference` | partial | success with documented limitation |
314
+ | `deep-composition-sequence` | supported | success |
315
+ | `xs-anyattribute` | partial | success with metadata retention |
316
+ | `mtom-xop-attachment` | unsupported | error or research |
317
+
145
318
  Acceptance criteria:
146
319
 
147
320
  - The registry includes every priority row from the WSDL coverage slice.
148
321
  - Each row has a stable ID, status, fixture, and compile expectation.
149
322
  - `docs/supported-patterns.md` has matching capability IDs or anchors.
150
323
  - The runner works without network access.
324
+ - `npm run test:conformance` passes.
325
+ - `npm test` includes the conformance suite.
326
+ - No Phase 1 change expands the public API.
151
327
 
152
328
  ## Phase 2: Client And OpenAPI Evidence
153
329
 
@@ -206,14 +382,12 @@ Acceptance criteria:
206
382
 
207
383
  ## Open Decisions
208
384
 
209
- - Decide whether the first registry lives under `test/fixtures` or `test/conformance`.
210
- - Decide whether conformance should be a normal `npm test` suite or a separate script at first.
211
385
  - Decide how much generated output type-checking is acceptable in CI runtime.
212
386
  - Decide which inspector output format becomes public before `1.0.0`.
213
387
  - Decide whether docs should remain manually maintained or eventually generated from the registry.
214
388
 
215
389
  ## Release Implications
216
390
 
217
- This framework is 1.0 readiness infrastructure. It can ship incrementally in `0.28.x` or later patch releases as tests, docs, and diagnostics improve.
391
+ This framework is 1.0 readiness infrastructure. It can ship incrementally in `0.30.x` or later patch releases as tests, docs, and diagnostics improve.
218
392
 
219
393
  Do not block the first conformance slice on the WSDL inspector. The registry and runner create the durable foundation; the inspector should reuse that foundation after it proves useful.
@@ -41,7 +41,7 @@ This slice prevents later work from building on ambiguous behavior. Choice union
41
41
 
42
42
  ### Roadmap State
43
43
 
44
- `ROADMAP.md` must reflect the released `0.28.x` line. Choice union mode and JSON array streaming must be treated as shipped work, while WSDL coverage and release-candidate gates remain the active 1.0 work.
44
+ `ROADMAP.md` must reflect the current released `0.30.x` line. Choice union mode and JSON array streaming must be treated as shipped work, while capability conformance, WSDL coverage, and release-candidate gates remain the active 1.0 work.
45
45
 
46
46
  ### Release Metadata
47
47
 
@@ -63,7 +63,7 @@ Add negative tests only for newly identified contract gaps that a follow-up slic
63
63
 
64
64
  ## Acceptance Criteria
65
65
 
66
- - `ROADMAP.md` names released `0.28.x` work accurately.
66
+ - `ROADMAP.md` names released `0.30.x` work accurately.
67
67
  - `docs/roadmap/README.md` links every 1.0 slice.
68
68
  - CLI, API, and configuration docs agree on required 1.0 behavior.
69
69
  - Known contract gaps are linked to implementation slices.
@@ -33,13 +33,13 @@ Each matrix row should have a minimal fixture, an expected support status, and a
33
33
  | Feature | Expected 1.0 Status | Notes |
34
34
  |----------------------------|-------------------------|---------------------------------------|
35
35
  | `xs:choice` union mode | supported | Implemented in `0.26.0` |
36
- | `xs:union` | supported or diagnostic | Decide after fixture work |
36
+ | `xs:union` | supported | Simple unions implemented after fixture work |
37
37
  | Abstract types | diagnostic | Avoid silent concrete treatment |
38
38
  | Substitution groups | diagnostic | Avoid silent omission |
39
39
  | Multi-binding WSDLs | documented behavior | First binding or explicit selection |
40
40
  | External `PolicyReference` | partial or diagnostic | Inline policy already exists |
41
41
  | Deep composition | supported | Prove current recursion behavior |
42
- | `xs:anyAttribute` | diagnostic | Current support is not full |
42
+ | `xs:anyAttribute` | partial | Metadata retained; generated wildcard attributes deferred |
43
43
  | MTOM/XOP attachments | unsupported diagnostic | Keep out of 1.0 scope unless required |
44
44
 
45
45
  ## Manifest Shape
@@ -2,6 +2,24 @@
2
2
 
3
3
  This document lists the WSDL and XSD features handled by the generator, along with current limitations. For modeling details, see [Core Concepts](concepts.md).
4
4
 
5
+ ## Capability Evidence Matrix
6
+
7
+ The rows below are backed by committed conformance fixtures under `test/conformance/fixtures/`. Status means the current product contract, not the full standards surface.
8
+
9
+ <!-- support-matrix:start -->
10
+ | Capability ID | Status | Public contract |
11
+ |---|---|---|
12
+ | `choice-union-simple` | supported | `xs:choice` union mode retains choice metadata and drives generated TypeScript/OpenAPI constraints. |
13
+ | `xs-union-simple-type` | supported | Simple `xs:union` aliases compile to TypeScript unions and OpenAPI `oneOf` schemas. |
14
+ | `abstract-complex-type` | diagnostic | Abstract complex type semantics are not modeled yet; 1.0 should reject or warn instead of treating them as concrete. |
15
+ | `substitution-group-element` | diagnostic | Substitution groups are not expanded yet; 1.0 should avoid silent omission with a diagnostic. |
16
+ | `multi-binding-first-soap` | partial | Multiple bindings are deterministic: the first SOAP binding is selected and all ports are documented. |
17
+ | `external-policy-reference` | partial | Inline policy hints are detected; external `PolicyReference` documents are not fetched or resolved. |
18
+ | `deep-composition-sequence` | supported | Deep nested sequences compile into deterministic type metadata. |
19
+ | `xs-anyattribute` | partial | `xs:anyAttribute` is retained as catalog metadata, but generated wildcard attributes are not emitted. |
20
+ | `mtom-xop-attachment` | unsupported | MTOM/XOP binary attachment transport is outside the 1.0 typed SOAP-to-REST contract. |
21
+ <!-- support-matrix:end -->
22
+
5
23
  ## Fully Supported
6
24
 
7
25
  These patterns are handled end-to-end: WSDL parsing, TypeScript type generation, OpenAPI schema output, and gateway code generation.
@@ -9,6 +27,7 @@ These patterns are handled end-to-end: WSDL parsing, TypeScript type generation,
9
27
  - Complex types with `<xs:sequence>`, `<xs:all>`, and `<xs:choice>` compositors, including recursive nesting
10
28
  - Simple content with attributes using the `$value` pattern to preserve text content alongside attribute properties
11
29
  - Named simple type restrictions and enumerations emitted as TypeScript aliases and OpenAPI scalar schemas
30
+ - Named `xs:union` simple types emitted as TypeScript alias unions and OpenAPI `oneOf` schemas
12
31
  - Type inheritance through `<xs:extension>` and `<xs:restriction>` on both simple and complex content
13
32
  - Nested XSD imports across multiple schema files with relative and absolute URI resolution
14
33
  - Multiple namespaces with deterministic collision resolution via PascalCase uniqueness
@@ -21,7 +40,7 @@ These patterns are handled end-to-end: WSDL parsing, TypeScript type generation,
21
40
  - Multiple WSDL ports and bindings; the first SOAP binding is selected, all ports are documented in service metadata
22
41
  - SOAP 1.1 and SOAP 1.2 binding detection
23
42
  - Streamable SOAP responses, opt-in per operation via `--stream-config` (ADR-002): client exposes `AsyncIterable<RecordType>`, gateway emits NDJSON or JSON array streams with backpressure, OpenAPI advertises the record schema via `x-wsdl-tsc-stream`
24
- - `xs:any` wildcard particles retained on compiled types (they used to be dropped silently) — enables honest stream-candidate detection and companion-catalog shape resolution
43
+ - `xs:any` wildcard particles retained on compiled types for stream-candidate detection and companion-catalog shape resolution
25
44
 
26
45
  ### Named simple types and same-name elements
27
46
 
@@ -65,12 +84,19 @@ Groups are inlined into the parent type during schema compilation. The group ide
65
84
 
66
85
  List types with an `itemType` attribute are detected and generate array types (`${itemType}[]`). Lists defined with inline simple types are not handled.
67
86
 
87
+ ### xs:union
88
+
89
+ Union types with `memberTypes` or inline simple type members are detected and generate TypeScript alias unions. Mixed primitive and literal unions generate OpenAPI `oneOf` schemas.
90
+
91
+ ### xs:anyAttribute
92
+
93
+ Attribute wildcards are retained as catalog metadata on the enclosing compiled type. They are not emitted as typed attribute properties in generated TypeScript or OpenAPI schemas.
94
+
68
95
  ## Not Yet Supported
69
96
 
70
97
  These features are not currently handled. Contributions are welcome.
71
98
 
72
- - `xs:any` and `xs:anyAttribute`: unrecognized elements fall through to an untyped representation
73
- - `xs:union` types: only union members expressed as restriction enumerations are captured
99
+ - Full `xs:any` serialization: arbitrary wildcard content is not emitted as a typed contract
74
100
  - Abstract types: treated as regular concrete types without substitution logic
75
101
  - Substitution groups: not resolved during schema compilation
76
102
  - MTOM/XOP binary attachments: no support for binary part handling
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techspokes/typescript-wsdl-client",
3
- "version": "0.30.0",
3
+ "version": "0.30.3",
4
4
  "description": "Turn legacy WSDL/SOAP services into typed TypeScript clients, OpenAPI 3.1 specs, and production-ready Fastify REST gateways. Built for enterprise SOAP modernization.",
5
5
  "keywords": [
6
6
  "wsdl",
@@ -70,6 +70,7 @@
70
70
  "test:unit": "vitest run test/unit",
71
71
  "test:snap": "vitest run test/snapshot",
72
72
  "test:integration": "vitest run test/integration",
73
+ "test:conformance": "vitest run test/conformance",
73
74
  "test:watch": "vitest",
74
75
  "prepublishOnly": "npm run clean && npm run build && npm run package:validate",
75
76
  "smoke:reset": "npm run clean:tmp",
@@ -80,7 +81,9 @@
80
81
  "smoke:pipeline": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --init-app && tsc -p tsconfig.smoke.json",
81
82
  "smoke:app": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api && tsx src/cli.ts app --client-dir tmp/client --gateway-dir tmp/gateway --openapi-file tmp/openapi.json --app-dir tmp/app --port 8080 && tsc -p tsconfig.smoke.json",
82
83
  "maint:deps": "node scripts/maint-deps.mjs",
83
- "docs:validate": "node scripts/validate-docs.mjs",
84
+ "docs:support-matrix": "tsx scripts/generate-support-matrix.ts",
85
+ "docs:support-matrix:check": "tsx scripts/generate-support-matrix.ts --check",
86
+ "docs:validate": "node scripts/validate-docs.mjs && npm run docs:support-matrix:check",
84
87
  "skill:validate": "node scripts/validate-agent-skill.mjs",
85
88
  "skill:package": "node scripts/build-agent-skill.mjs",
86
89
  "package:validate": "node scripts/validate-npm-package.mjs",
@@ -90,7 +93,7 @@
90
93
  },
91
94
  "devDependencies": {
92
95
  "@types/js-yaml": "^4.0.9",
93
- "@types/node": "^26.0.0",
96
+ "@types/node": "^26.0.1",
94
97
  "@types/yargs": "^17.0.35",
95
98
  "fastify": "^5.8.5",
96
99
  "fastify-plugin": "^6.0.0",