@techspokes/typescript-wsdl-client 0.34.0 → 0.36.0

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
@@ -39,7 +39,7 @@ npm install --save-dev @techspokes/typescript-wsdl-client
39
39
  npm install soap
40
40
  ```
41
41
 
42
- Requirements: Node.js 20+ and the `soap` package as a runtime dependency.
42
+ Requirements: Node.js 24+ and the `soap` package as a runtime dependency.
43
43
 
44
44
  ## Quick Start
45
45
 
@@ -1 +1 @@
1
- {"version":3,"file":"generateTypes.d.ts","sourceRoot":"","sources":["../../src/client/generateTypes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAA0D,MAAM,+BAA+B,CAAC;AAG5H;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QAmRvE"}
1
+ {"version":3,"file":"generateTypes.d.ts","sourceRoot":"","sources":["../../src/client/generateTypes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAA0D,MAAM,+BAA+B,CAAC;AAI5H;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QAsSvE"}
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import fs from "node:fs";
16
16
  import { error } from "../util/cli.js";
17
+ import { hasAttributeWildcards, wildcardAttributeBagName } from "../util/attributeWildcards.js";
17
18
  /**
18
19
  * Generates TypeScript interfaces and type aliases from a compiled WSDL catalog
19
20
  *
@@ -65,6 +66,7 @@ export function generateTypes(outFile, compiled) {
65
66
  const isValidIdent = (name) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
66
67
  const emitPropName = (name) => (isValidIdent(name) ? name : JSON.stringify(name));
67
68
  const isChoiceUnionMode = compiled.options.choice === "union";
69
+ const wildcardBagName = wildcardAttributeBagName(compiled.options);
68
70
  const elementType = (e) => {
69
71
  const isArray = e.max === "unbounded" || (e.max > 1);
70
72
  return `${e.tsType}${isArray ? "[]" : ""}`;
@@ -123,6 +125,15 @@ export function generateTypes(outFile, compiled) {
123
125
  }
124
126
  lines.push(`${indent}${emitPropName(a.name)}${opt}: ${a.tsType};`);
125
127
  };
128
+ const emitWildcardAttributeBagProperty = (indent) => {
129
+ const annObj = {
130
+ kind: "attributeWildcard",
131
+ type: "xs:anyAttribute",
132
+ };
133
+ lines.push("");
134
+ lines.push(`${indent}/** @xsd ${JSON.stringify(annObj)} */`);
135
+ lines.push(`${indent}${emitPropName(wildcardBagName)}?: Record<string, string>;`);
136
+ };
126
137
  const isSyntheticAliasSelfWrapper = (t) => {
127
138
  const elems = t.elems || [];
128
139
  return aliasNames.has(t.name) &&
@@ -171,6 +182,9 @@ export function generateTypes(outFile, compiled) {
171
182
  }
172
183
  // Prepare lists: for complexContent extension use only local additions
173
184
  const attrsToEmit = complexBase ? (t.localAttrs || []) : (t.attrs || []);
185
+ const wildcardCarrier = complexBase
186
+ ? { attributeWildcards: t.localAttributeWildcards }
187
+ : { attributeWildcards: t.attributeWildcards };
174
188
  // Elements list similar
175
189
  let elementsToEmit = complexBase ? (t.localElems || []) : (t.elems || []);
176
190
  // SimpleContent extension special handling drops synthetic $value
@@ -205,6 +219,9 @@ export function generateTypes(outFile, compiled) {
205
219
  for (const a of attrsToEmit) {
206
220
  emitAttributeProperty(" ", a);
207
221
  }
222
+ if (hasAttributeWildcards(wildcardCarrier)) {
223
+ emitWildcardAttributeBagProperty(" ");
224
+ }
208
225
  if (0 < baseElements.length) {
209
226
  lines.push("");
210
227
  lines.push(" /**");
@@ -266,6 +283,9 @@ export function generateTypes(outFile, compiled) {
266
283
  for (const a of attrsToEmit) {
267
284
  emitAttributeProperty(" ", a);
268
285
  }
286
+ if (hasAttributeWildcards(wildcardCarrier)) {
287
+ emitWildcardAttributeBagProperty(" ");
288
+ }
269
289
  //
270
290
  // Elements — with JSDoc on every element
271
291
  //
@@ -71,6 +71,7 @@ export type CompiledChoiceGroup = {
71
71
  * @property {string} [base] - Base type name for extension/inheritance
72
72
  * @property {Array<Object>} [localAttrs] - Attributes added in extension (not inherited)
73
73
  * @property {Array<Object>} [localElems] - Elements added in extension (not inherited)
74
+ * @property {Array<Object>} [localAttributeWildcards] - Attribute wildcards added in extension
74
75
  * @property {Array<Object>} [wildcards] - xs:any wildcard particles retained on the type
75
76
  * @property {Array<Object>} [attributeWildcards] - xs:anyAttribute wildcards retained on the type
76
77
  */
@@ -114,6 +115,7 @@ export type CompiledType = {
114
115
  }>;
115
116
  wildcards?: CompiledWildcard[];
116
117
  attributeWildcards?: CompiledAttributeWildcard[];
118
+ localAttributeWildcards?: CompiledAttributeWildcard[];
117
119
  choiceGroups?: CompiledChoiceGroup[];
118
120
  localChoiceGroups?: CompiledChoiceGroup[];
119
121
  };
@@ -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":"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"}
@@ -433,6 +433,34 @@ export function compileCatalog(cat, options, streamConfig) {
433
433
  }
434
434
  return merged;
435
435
  };
436
+ const mergeWildcards = (into, list) => {
437
+ if (list.length === 0)
438
+ return into;
439
+ const merged = into ? [...into] : [];
440
+ const seen = new Set(merged.map((w) => JSON.stringify(w)));
441
+ for (const w of list) {
442
+ const key = JSON.stringify(w);
443
+ if (!seen.has(key)) {
444
+ seen.add(key);
445
+ merged.push(w);
446
+ }
447
+ }
448
+ return merged;
449
+ };
450
+ const mergeAttributeWildcards = (into, list) => {
451
+ if (list.length === 0)
452
+ return into;
453
+ const merged = into ? [...into] : [];
454
+ const seen = new Set(merged.map((w) => JSON.stringify(w)));
455
+ for (const w of list) {
456
+ const key = JSON.stringify(w);
457
+ if (!seen.has(key)) {
458
+ seen.add(key);
459
+ merged.push(w);
460
+ }
461
+ }
462
+ return merged;
463
+ };
436
464
  const collectAttributes = (node) => {
437
465
  const out = [];
438
466
  const attrs = getChildrenWithLocalName(node, "attribute");
@@ -655,12 +683,8 @@ export function compileCatalog(cat, options, streamConfig) {
655
683
  const newChoiceGroups = collectChoiceGroups(outName, cnode);
656
684
  mergeAttrs(present.attrs, newAttrs);
657
685
  mergeElems(present.elems, newElems);
658
- if (newWildcards.length > 0) {
659
- present.wildcards = [...(present.wildcards ?? []), ...newWildcards];
660
- }
661
- if (newAttributeWildcards.length > 0) {
662
- present.attributeWildcards = [...(present.attributeWildcards ?? []), ...newAttributeWildcards];
663
- }
686
+ present.wildcards = mergeWildcards(present.wildcards, newWildcards);
687
+ present.attributeWildcards = mergeAttributeWildcards(present.attributeWildcards, newAttributeWildcards);
664
688
  const mergedChoiceGroups = mergeChoiceGroups(present.choiceGroups, newChoiceGroups);
665
689
  if (mergedChoiceGroups && mergedChoiceGroups.length > 0) {
666
690
  present.choiceGroups = mergedChoiceGroups;
@@ -721,6 +745,7 @@ export function compileCatalog(cat, options, streamConfig) {
721
745
  localElems,
722
746
  ...(localWildcards.length > 0 ? { wildcards: localWildcards } : {}),
723
747
  ...(attributeWildcards.length > 0 ? { attributeWildcards } : {}),
748
+ ...(localAttributeWildcards.length > 0 ? { localAttributeWildcards } : {}),
724
749
  ...(choiceGroups.length > 0 ? { choiceGroups } : {}),
725
750
  ...(localChoiceGroups.length > 0 ? { localChoiceGroups } : {}),
726
751
  };
@@ -255,6 +255,10 @@ function canonicalizeType(t) {
255
255
  namespace: w.namespace ?? null,
256
256
  processContents: w.processContents ?? null,
257
257
  })),
258
+ localAttributeWildcards: (t.localAttributeWildcards ?? []).map((w) => ({
259
+ namespace: w.namespace ?? null,
260
+ processContents: w.processContents ?? null,
261
+ })),
258
262
  choiceGroups: (t.choiceGroups ?? []).map((g) => ({
259
263
  name: g.name,
260
264
  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;AAwPpD;;;;;;;;;;;;;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;AAGhG;;;;;;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;AA+PpD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,EAAE,IAAI,EAAE,sBAAsB,GAAG,iBAAiB,CA6D1G"}
@@ -1,3 +1,4 @@
1
+ import { hasAttributeWildcards, wildcardAttributeBagName, wildcardAttributeBagSchema } from "../util/attributeWildcards.js";
1
2
  function isLiteralUnion(ts) {
2
3
  // very naive: split by | and ensure each trimmed starts and ends with quotes
3
4
  const parts = ts.split("|").map(p => p.trim()).filter(Boolean);
@@ -99,7 +100,7 @@ function isSyntheticAliasSelfWrapper(t, aliasNames) {
99
100
  const e = t.elems[0];
100
101
  return e.name === "$value" && e.tsType === t.name;
101
102
  }
102
- function buildComplexSchema(t, closed, knownTypeNames, aliasNames, flattenWrappers, choiceUnionMode) {
103
+ function buildComplexSchema(t, closed, knownTypeNames, aliasNames, flattenWrappers, choiceUnionMode, attributesKey) {
103
104
  // Use knownTypeNames/aliasNames to validate $ref targets so we surface
104
105
  // compiler issues early instead of emitting dangling references in OpenAPI output.
105
106
  function refOrPrimitive(ts) {
@@ -156,6 +157,12 @@ function buildComplexSchema(t, closed, knownTypeNames, aliasNames, flattenWrappe
156
157
  if (a.use === "required")
157
158
  required.push(a.name);
158
159
  }
160
+ const wildcardCarrier = t.base
161
+ ? { attributeWildcards: t.localAttributeWildcards }
162
+ : { attributeWildcards: t.attributeWildcards };
163
+ if (hasAttributeWildcards(wildcardCarrier)) {
164
+ properties[attributesKey] = wildcardAttributeBagSchema();
165
+ }
159
166
  // elements
160
167
  for (const e of t.elems) {
161
168
  const baseSchema = refOrPrimitive(e.tsType);
@@ -258,6 +265,7 @@ export function generateSchemas(compiled, opts) {
258
265
  const schemas = {};
259
266
  const typeNames = new Set(compiled.types.map(t => t.name));
260
267
  const aliasNames = new Set(compiled.aliases.map(a => a.name));
268
+ const attributesKey = wildcardAttributeBagName(compiled.options);
261
269
  // Build alias schemas first so complex types can reference them
262
270
  for (const a of compiled.aliases) {
263
271
  schemas[a.name] = buildAliasSchema(a);
@@ -266,7 +274,7 @@ export function generateSchemas(compiled, opts) {
266
274
  if (isSyntheticAliasSelfWrapper(t, aliasNames)) {
267
275
  continue;
268
276
  }
269
- schemas[t.name] = buildComplexSchema(t, closed, typeNames, aliasNames, flattenWrappers, compiled.options.choice === "union");
277
+ schemas[t.name] = buildComplexSchema(t, closed, typeNames, aliasNames, flattenWrappers, compiled.options.choice === "union", attributesKey);
270
278
  }
271
279
  if (opts.pruneUnusedSchemas) {
272
280
  // Root references: operation type names when available, falling back to element local names.
@@ -1 +1 @@
1
- {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/test/generators.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAA0C,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAG5F,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AA6FrF;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAkBzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAgFR;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,UAAU,GACrB,MAAM,CAsCR;AAED;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CA8FR;AAED;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAiIR;AAED;;GAEG;AAEH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAuER;AAED;;GAEG;AAEH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,CAAC,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,eAAe,GACxB,MAAM,CAwDR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAChC,MAAM,CAgFR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAChC,MAAM,CAgDR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,OAAO,EAAE,eAAe,GACvB,MAAM,GAAG,IAAI,CAkEf"}
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/test/generators.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAA0C,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAG5F,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAsGrF;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAkBzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAgFR;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,UAAU,GACrB,MAAM,CAsCR;AAED;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CA8FR;AAED;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAiIR;AAED;;GAEG;AAEH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAuER;AAED;;GAEG;AAEH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,CAAC,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,eAAe,GACxB,MAAM,CAwDR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAChC,MAAM,CAgFR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAChC,MAAM,CAgDR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,OAAO,EAAE,eAAe,GACvB,MAAM,GAAG,IAAI,CAkEf"}
@@ -29,6 +29,13 @@ function isRecord(value) {
29
29
  function cloneRecord(value) {
30
30
  return JSON.parse(JSON.stringify(value));
31
31
  }
32
+ function formatInjectPayloadFields(value) {
33
+ if (value == null || typeof value !== "object") {
34
+ return ` headers: {"content-type": "application/json"},
35
+ payload: JSON.stringify(${JSON.stringify(value)}),`;
36
+ }
37
+ return ` payload: ${JSON.stringify(value, null, 4).replace(/\n/g, "\n ")},`;
38
+ }
32
39
  function mockChoiceBranchValue(branch, catalog) {
33
40
  const isArray = branch.max === "unbounded" || (typeof branch.max === "number" && branch.max > 1);
34
41
  const value = branch.tsType === "string" || branch.tsType === "number" || branch.tsType === "boolean"
@@ -253,7 +260,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
253
260
  const sortedOps = [...operations].sort((a, b) => a.operationId.localeCompare(b.operationId));
254
261
  const testCases = sortedOps.map((op) => {
255
262
  const mockData = mocks.get(op.operationId);
256
- const requestPayload = JSON.stringify(mockData?.request ?? {}, null, 4).replace(/\n/g, "\n ");
263
+ const requestPayloadFields = formatInjectPayloadFields(mockData?.request ?? {});
257
264
  const hint = formatOperationHint(op.summary, op.description);
258
265
  const hintComment = hint ? ` // ${hint}\n` : "";
259
266
  if (op.stream?.format === "json-array") {
@@ -264,7 +271,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
264
271
  const res = await app.inject({
265
272
  method: "${op.method.toUpperCase()}",
266
273
  url: "${op.path}",
267
- payload: ${requestPayload},
274
+ ${requestPayloadFields}
268
275
  });
269
276
  expect(res.statusCode).toBe(200);
270
277
  expect(String(res.headers["content-type"] ?? "")).toContain(${JSON.stringify(op.stream.mediaType)});
@@ -287,7 +294,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
287
294
  const res = await app.inject({
288
295
  method: "${op.method.toUpperCase()}",
289
296
  url: "${op.path}",
290
- payload: ${requestPayload},
297
+ ${requestPayloadFields}
291
298
  });
292
299
  expect(res.statusCode).toBe(200);
293
300
  expect(String(res.headers["content-type"] ?? "")).toContain(${JSON.stringify(op.stream.mediaType)});
@@ -308,7 +315,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
308
315
  const res = await app.inject({
309
316
  method: "${op.method.toUpperCase()}",
310
317
  url: "${op.path}",
311
- payload: ${requestPayload},
318
+ ${requestPayloadFields}
312
319
  });
313
320
  expect(res.statusCode).toBe(200);
314
321
  const body = res.json();
@@ -354,7 +361,7 @@ export function emitErrorsTest(testDir, importsMode, operations, mocks) {
354
361
  if (!op)
355
362
  return "// No operations found\n";
356
363
  const mockData = mocks.get(op.operationId);
357
- const requestPayload = JSON.stringify(mockData?.request ?? {}, null, 4).replace(/\n/g, "\n ");
364
+ const requestPayloadFields = formatInjectPayloadFields(mockData?.request ?? {});
358
365
  return `/**
359
366
  * Gateway Error Handling Tests
360
367
  *
@@ -379,7 +386,7 @@ describe("gateway routes — error handling", () => {
379
386
  const res = await app.inject({
380
387
  method: "${op.method.toUpperCase()}",
381
388
  url: "${op.path}",
382
- payload: ${requestPayload},
389
+ ${requestPayloadFields}
383
390
  });
384
391
  expect(res.statusCode).toBe(500);
385
392
  const body = res.json();
@@ -413,7 +420,7 @@ describe("gateway routes — error handling", () => {
413
420
  const res = await app.inject({
414
421
  method: "${op.method.toUpperCase()}",
415
422
  url: "${op.path}",
416
- payload: ${requestPayload},
423
+ ${requestPayloadFields}
417
424
  });
418
425
  expect(res.statusCode).toBe(502);
419
426
  const body = res.json();
@@ -436,7 +443,7 @@ describe("gateway routes — error handling", () => {
436
443
  const res = await app.inject({
437
444
  method: "${op.method.toUpperCase()}",
438
445
  url: "${op.path}",
439
- payload: ${requestPayload},
446
+ ${requestPayloadFields}
440
447
  });
441
448
  expect(res.statusCode).toBe(503);
442
449
  const body = res.json();
@@ -459,7 +466,7 @@ describe("gateway routes — error handling", () => {
459
466
  const res = await app.inject({
460
467
  method: "${op.method.toUpperCase()}",
461
468
  url: "${op.path}",
462
- payload: ${requestPayload},
469
+ ${requestPayloadFields}
463
470
  });
464
471
  expect(res.statusCode).toBe(504);
465
472
  const body = res.json();
@@ -486,7 +493,7 @@ export function emitEnvelopeTest(testDir, importsMode, operations, mocks) {
486
493
  if (!op)
487
494
  return "// No operations found\n";
488
495
  const mockData = mocks.get(op.operationId);
489
- const requestPayload = JSON.stringify(mockData?.request ?? {}, null, 4).replace(/\n/g, "\n ");
496
+ const requestPayloadFields = formatInjectPayloadFields(mockData?.request ?? {});
490
497
  return `/**
491
498
  * Gateway Envelope Structure Tests
492
499
  *
@@ -505,7 +512,7 @@ describe("gateway — envelope structure", () => {
505
512
  const res = await app.inject({
506
513
  method: "${op.method.toUpperCase()}",
507
514
  url: "${op.path}",
508
- payload: ${requestPayload},
515
+ ${requestPayloadFields}
509
516
  });
510
517
  expect(res.statusCode).toBe(200);
511
518
  const body = res.json();
@@ -530,7 +537,7 @@ describe("gateway — envelope structure", () => {
530
537
  const res = await app.inject({
531
538
  method: "${op.method.toUpperCase()}",
532
539
  url: "${op.path}",
533
- payload: ${requestPayload},
540
+ ${requestPayloadFields}
534
541
  });
535
542
  expect(res.statusCode).toBe(500);
536
543
  const body = res.json();
@@ -9,6 +9,7 @@ export interface MockDataOptions {
9
9
  */
10
10
  export interface CatalogForMocks {
11
11
  options?: {
12
+ attributesKey?: string;
12
13
  choice?: "all-optional" | "union";
13
14
  };
14
15
  meta?: {
@@ -41,6 +42,10 @@ export interface CatalogForMocks {
41
42
  name: string;
42
43
  max: number | "unbounded";
43
44
  }>;
45
+ attributeWildcards?: Array<{
46
+ namespace?: string;
47
+ processContents?: "lax" | "strict" | "skip";
48
+ }>;
44
49
  choiceGroups?: Array<{
45
50
  name: string;
46
51
  min: number;
@@ -1 +1 @@
1
- {"version":3,"file":"mockData.d.ts","sourceRoot":"","sources":["../../src/test/mockData.ts"],"names":[],"mappings":"AAWA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC;KACnC,CAAC;IACF,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAClD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACnD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE;YACvC,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,GAAG,CAAC,EAAE,MAAM,CAAC;YACb,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;YAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;SACpB,CAAC,CAAC,CAAC;KACL,CAAC;IACF,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE;YACP,MAAM,EAAE,QAAQ,GAAG,YAAY,CAAC;YAChC,SAAS,EAAE,MAAM,CAAC;YAClB,cAAc,EAAE,MAAM,CAAC;YACvB,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;KACH,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC/B,KAAK,EAAE,KAAK,CAAC;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;SAAE,CAAC,CAAC;QAC1D,YAAY,CAAC,EAAE,KAAK,CAAC;YACnB,IAAI,EAAE,MAAM,CAAC;YACb,GAAG,EAAE,MAAM,CAAC;YACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;YAC1B,WAAW,EAAE,MAAM,CAAC;YACpB,QAAQ,EAAE,KAAK,CAAC;gBACd,IAAI,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,MAAM,CAAC;gBACf,GAAG,EAAE,MAAM,CAAC;gBACZ,GAAG,EAAE,MAAM,GAAG,WAAW,CAAC;gBAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;gBACnB,YAAY,EAAE,MAAM,CAAC;gBACrB,GAAG,CAAC,EAAE,MAAM,CAAC;gBACb,WAAW,EAAE,MAAM,CAAC;aACrB,CAAC,CAAC;SACJ,CAAC,CAAC;KACJ,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAwCjG;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,eAAe,EACxB,IAAI,CAAC,EAAE,eAAe,EACtB,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAoEzB;AAWD;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,eAAe,EACxB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CA+BtD"}
1
+ {"version":3,"file":"mockData.d.ts","sourceRoot":"","sources":["../../src/test/mockData.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@
8
8
  * Pure logic — no I/O or side effects.
9
9
  */
10
10
  import { detectArrayWrappers, flattenMockPayload } from "../util/catalogMeta.js";
11
+ import { hasAttributeWildcards, wildcardAttributeBagName } from "../util/attributeWildcards.js";
11
12
  /**
12
13
  * Generates a mock primitive value based on the TypeScript type and property name.
13
14
  * Uses contextual defaults based on common property names.
@@ -93,14 +94,15 @@ export function generateMockData(typeName, catalog, opts, visited, depth) {
93
94
  }
94
95
  const childTypes = catalog.meta?.childType?.[typeName];
95
96
  const attrTypes = catalog.meta?.attrType?.[typeName];
96
- if ((!childTypes || Object.keys(childTypes).length === 0) && !attrTypes) {
97
+ const typeMeta = catalog.types?.find((t) => t.name === typeName);
98
+ const hasWildcardAttributes = hasAttributeWildcards(typeMeta);
99
+ if ((!childTypes || Object.keys(childTypes).length === 0) && !attrTypes && !hasWildcardAttributes) {
97
100
  return {};
98
101
  }
99
102
  const propMeta = catalog.meta?.propMeta?.[typeName] ?? {};
100
103
  const newVisited = new Set(currentVisited);
101
104
  newVisited.add(typeName);
102
105
  const result = {};
103
- const typeMeta = catalog.types?.find((t) => t.name === typeName);
104
106
  const choiceGroups = catalog.options?.choice === "union" ? (typeMeta?.choiceGroups ?? []) : [];
105
107
  const choiceBranchNames = new Set(choiceGroups.flatMap((group) => group.branches.map((branch) => branch.name)));
106
108
  const selectedChoiceBranchNames = new Set(choiceGroups
@@ -143,6 +145,14 @@ export function generateMockData(typeName, catalog, opts, visited, depth) {
143
145
  }
144
146
  }
145
147
  }
148
+ if (hasWildcardAttributes) {
149
+ const attributesKey = wildcardAttributeBagName(catalog.options);
150
+ if (!(attributesKey in result)) {
151
+ result[attributesKey] = {
152
+ "extra:trace": "sample",
153
+ };
154
+ }
155
+ }
146
156
  return result;
147
157
  }
148
158
  function generateOperationPayload(typeName, catalog) {
@@ -0,0 +1,16 @@
1
+ export declare const DEFAULT_ATTRIBUTE_BAG_KEY = "$attributes";
2
+ export interface AttributeWildcardCarrier {
3
+ attributeWildcards?: readonly unknown[];
4
+ }
5
+ export interface AttributeWildcardOptions {
6
+ attributesKey?: string;
7
+ }
8
+ export declare function hasAttributeWildcards(value: AttributeWildcardCarrier | undefined): boolean;
9
+ export declare function wildcardAttributeBagName(options: AttributeWildcardOptions | undefined): string;
10
+ export declare function wildcardAttributeBagSchema(): {
11
+ type: "object";
12
+ additionalProperties: {
13
+ type: "string";
14
+ };
15
+ };
16
+ //# sourceMappingURL=attributeWildcards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attributeWildcards.d.ts","sourceRoot":"","sources":["../../src/util/attributeWildcards.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB,gBAAgB,CAAC;AAEvD,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,wBAAwB,GAAG,SAAS,GAAG,OAAO,CAE1F;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,wBAAwB,GAAG,SAAS,GAAG,MAAM,CAG9F;AAED,wBAAgB,0BAA0B,IAAI;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,oBAAoB,EAAE;QAAC,IAAI,EAAE,QAAQ,CAAA;KAAC,CAAA;CAAC,CAKrG"}
@@ -0,0 +1,14 @@
1
+ export const DEFAULT_ATTRIBUTE_BAG_KEY = "$attributes";
2
+ export function hasAttributeWildcards(value) {
3
+ return Array.isArray(value?.attributeWildcards) && value.attributeWildcards.length > 0;
4
+ }
5
+ export function wildcardAttributeBagName(options) {
6
+ const configured = options?.attributesKey?.trim();
7
+ return configured && configured.length > 0 ? configured : DEFAULT_ATTRIBUTE_BAG_KEY;
8
+ }
9
+ export function wildcardAttributeBagSchema() {
10
+ return {
11
+ type: "object",
12
+ additionalProperties: { type: "string" },
13
+ };
14
+ }
package/docs/migration.md CHANGED
@@ -18,6 +18,7 @@ These steps apply to every version upgrade:
18
18
 
19
19
  | wsdl-tsc | Node.js | TypeScript | soap | Fastify | saxes |
20
20
  |----------|---------|------------|------|---------|-------|
21
+ | 0.35.x and later | >= 24.0 | >= 6.0 | >= 1.9 | >= 5.8 | >= 6.0 |
21
22
  | 0.17.x | >= 20.0 | >= 6.0 | >= 1.9 | >= 5.8 | >= 6.0 |
22
23
  | 0.16.x | >= 20.0 | >= 6.0 | >= 1.9 | >= 5.8 | N/A |
23
24
  | 0.15.x | >= 20.0 | >= 6.0 | >= 1.8 | >= 5.4 | N/A |
@@ -40,6 +40,7 @@ No special upgrade steps.
40
40
  - CI passed.
41
41
  - NPM package contents were validated.
42
42
  - Agent skill artifact was validated and packaged.
43
+ - Release preflight passed against the target tag.
43
44
 
44
45
  ## Notes
45
46
 
@@ -0,0 +1,33 @@
1
+ # TypeScript WSDL Client v0.35.0
2
+
3
+ ## Baseline Conformance And Node Policy
4
+
5
+ This release expands the WSDL conformance baseline and raises the supported runtime floor to Node 24.
6
+
7
+ ## What This Improves
8
+
9
+ Maintainers now have fixture-backed evidence for the common WSDL and XSD patterns that already form the everyday generation baseline: the canonical weather WSDL, complex sequences, simple type restrictions and lists, same-name simple type aliases, simple content with attributes, documentation propagation, SOAP binding detection, and relative XSD imports.
10
+
11
+ The conformance harness also keeps its XML evidence self-contained under `test/conformance/fixtures/`, which makes the public support matrix easier to trust during release review. CI now covers Node 24 as the supported floor and Node 26 as the current line, while release workflows run on Node 24.
12
+
13
+ ## Highlights
14
+
15
+ - Adds baseline WSDL and XSD conformance rows across compile, client, OpenAPI, gateway, generated-test, and app stages.
16
+ - Raises the package engine floor to Node 24 and release-gates Node 24 and Node 26 CI coverage.
17
+ - Keeps repository-owned temporary outputs in classified `tmp/` subfolders for smoke, conformance, preflight, npm cache, and generated-test workspaces.
18
+ - Hardens generated gateway tests for scalar JSON payloads.
19
+
20
+ ## Upgrade Notes
21
+
22
+ Consumers should run Node 24 or newer.
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.35.0`.
@@ -0,0 +1,32 @@
1
+ # TypeScript WSDL Client v0.36.0
2
+
3
+ ## Wildcard Attribute Contracts
4
+
5
+ This release promotes `xs:anyAttribute` from metadata-only partial support to generated contract support.
6
+
7
+ ## What This Improves
8
+
9
+ Generated TypeScript, OpenAPI, gateway, app, and generated-test artifacts now represent wildcard XML attributes through a configured attribute bag. Known XML attributes still remain flattened as peer properties, while unknown wildcard attributes stay in the bag to avoid collisions with child elements or known attributes.
10
+
11
+ ## Highlights
12
+
13
+ - `xs:anyAttribute` emits an optional attribute bag named by the configured attributes key, defaulting to `$attributes`.
14
+ - OpenAPI schemas describe wildcard attribute bags as objects with string values.
15
+ - Generated gateway and generated-test evidence now exercise the modeled wildcard attribute bag.
16
+ - GitHub push and PR CI now runs faster hosted checks while local release preflight remains the full release gate.
17
+ - Roadmap and support documentation now reflect the `0.35.0` baseline and the `xs:anyAttribute` pre-1.0 slice.
18
+
19
+ ## Upgrade Notes
20
+
21
+ No special upgrade steps.
22
+
23
+ ## Validation
24
+
25
+ - CI passed.
26
+ - NPM package contents were validated.
27
+ - Agent skill artifact was validated and packaged.
28
+ - Release preflight passed against the target tag.
29
+
30
+ ## Notes
31
+
32
+ Release tag: `v0.36.0`.
@@ -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.30.x` line to a stable `1.0.0` release.
3
+ Detailed plan for moving `@techspokes/typescript-wsdl-client` from the current `0.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, JSON array streaming is shipped, and the conformance framework is wired into validation gates. The remaining readiness work is to resolve any explicit conformance deferrals and run 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, JSON array streaming is shipped, and the conformance framework is wired into validation gates. The remaining readiness work is to review the explicit partial, diagnostic, and unsupported capability decisions, then run the final release candidate gate pass.
12
12
 
13
13
  ## Route Summary
14
14
 
@@ -19,7 +19,8 @@ The plan is optimized for preserving quality. The contract and compatibility bas
19
19
  | Choice union mode | [Choice Union Mode](v1.0-choice-union-mode.md) | complete | Implemented in `0.26.0` |
20
20
  | JSON array streaming | [JSON Array Streaming](v1.0-json-array-streaming.md) | complete | Implemented in `0.28.0` |
21
21
  | Conformance framework | [Capability Conformance Framework](v1.0-capability-conformance-framework.md) | gate wired | Pipeline claims are test-backed |
22
- | WSDL coverage matrix | [WSDL Coverage Matrix](v1.0-wsdl-coverage-matrix.md) | gate wired | Feature support is test-backed |
22
+ | WSDL coverage matrix | [WSDL Coverage Matrix](v1.0-wsdl-coverage-matrix.md) | baseline complete | Public support is test-backed |
23
+ | `xs:anyAttribute` bag | [`xs:anyAttribute` Wildcard Bag](v1.0-xs-anyattribute-wildcard-bag.md) | planned | Attribute wildcard bag emitted |
23
24
  | Release candidate | [Release Candidate Gates](v1.0-release-candidate-gates.md) | next | 1.0 release is repeatable |
24
25
 
25
26
  ## Execution Order
@@ -42,20 +43,24 @@ JSON array streaming is complete in `0.28.0`. The default `ndjson` format remain
42
43
 
43
44
  ### Slice 5: Capability Conformance Framework
44
45
 
45
- The registry, fixture strategy, compile runner, client evidence, OpenAPI evidence, gateway runtime evidence, generated-test evidence, app evidence, documentation drift check, generated support matrix, and validation-gate wiring are shipped. Keep `npm run test:conformance` as the focused local command while broad Vitest discovery covers conformance in `npm test`, `npm run ci`, and release preflight.
46
+ The registry, fixture strategy, compile runner, client evidence, OpenAPI evidence, gateway runtime evidence, generated-test evidence, app evidence, documentation drift check, generated support matrix, and validation-gate wiring are shipped. The registry is the public baseline support source, while examples remain demos. Keep `npm run test:conformance` as the focused local command while broad Vitest discovery covers conformance in `npm test`, `npm run ci`, and release preflight.
46
47
 
47
48
  ### Slice 6: WSDL Coverage Matrix
48
49
 
49
- The first WSDL matrix rows now exist as conformance registry entries with compile, client, OpenAPI, gateway runtime, generated-test, app, documentation, and release-gate evidence. The next work is to keep those rows current while release candidate gates are prepared.
50
+ The WSDL matrix rows now exist as conformance registry entries with compile, client, OpenAPI, gateway runtime, generated-test, app, documentation, and release-gate evidence. The next work is to keep those rows current, confirm the non-supported rows are accepted 1.0 decisions, and prepare release candidate gates.
50
51
 
51
- ### Slice 7: Release Candidate Gates
52
+ ### Slice 7: xs:anyAttribute Wildcard Bag
53
+
54
+ The [`xs:anyAttribute` wildcard bag plan](v1.0-xs-anyattribute-wildcard-bag.md) is the selected scoped pre-1.0 fix. It promotes the current metadata-only partial row to supported by emitting a configured wildcard attribute bag through TypeScript, OpenAPI, gateway, generated-test, app, and documentation evidence.
55
+
56
+ ### Slice 8: Release Candidate Gates
52
57
 
53
58
  Run the release candidate gates after feature work and documentation have converged. This slice validates docs, tests, generated examples, package contents, skill artifact, release notes, and provenance workflow readiness.
54
59
 
55
60
  ## Remaining Before 1.0
56
61
 
57
- - Turn remaining unsupported, diagnostic, or partial matrix rows into diagnostics, documentation, or scoped fixes.
58
- - Confirm `docs/supported-patterns.md` matches the matrix.
62
+ - Confirm each partial, diagnostic, and unsupported matrix row is an accepted 1.0 decision or select one scoped fix.
63
+ - Confirm `docs/supported-patterns.md` still matches the generated matrix.
59
64
  - Run the release-candidate gates.
60
65
 
61
66
  ## Quality Principles
@@ -85,6 +90,7 @@ Run the release candidate gates after feature work and documentation have conver
85
90
 
86
91
  - A capability conformance matrix runs under broad Vitest test automation.
87
92
  - Release preflight verifies the focused conformance command and CI wiring.
93
+ - Release preflight verifies CI covers Node 24 and Node 26 and release workflows use Node 24.
88
94
  - Each matrix entry has a fixture, status, and stage expectations.
89
95
  - Unsupported features fail loudly or are documented as deliberately unsupported.
90
96