@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 +1 -0
- package/dist/app/generateApp.js +1 -1
- package/dist/compiler/schemaCompiler.d.ts +6 -0
- package/dist/compiler/schemaCompiler.d.ts.map +1 -1
- package/dist/compiler/schemaCompiler.js +55 -1
- package/dist/compiler/shapeResolver.js +4 -0
- package/dist/openapi/generateSchemas.d.ts.map +1 -1
- package/dist/openapi/generateSchemas.js +36 -0
- package/docs/README.md +2 -0
- package/docs/file-naming-and-path-organization.md +207 -0
- package/docs/releases/v0.30.1.md +31 -0
- package/docs/releases/v0.30.2.md +30 -0
- package/docs/releases/v0.30.3.md +33 -0
- package/docs/roadmap/README.md +3 -3
- package/docs/roadmap/v1.0-capability-conformance-framework.md +177 -3
- package/docs/roadmap/v1.0-contract-audit.md +2 -2
- package/docs/roadmap/v1.0-wsdl-coverage-matrix.md +2 -2
- package/docs/supported-patterns.md +29 -3
- package/package.json +6 -3
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` |
|
package/dist/app/generateApp.js
CHANGED
|
@@ -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":"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,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
|
|
1
|
+
{"version":3,"file":"schemaCompiler.d.ts","sourceRoot":"","sources":["../../src/compiler/schemaCompiler.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
|
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;
|
|
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`.
|
package/docs/roadmap/README.md
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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` |
|
|
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
|
|
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`
|
|
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.
|
|
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:
|
|
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.
|
|
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",
|