@techspokes/typescript-wsdl-client 0.16.1 → 0.18.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.
Files changed (71) hide show
  1. package/README.md +5 -0
  2. package/dist/app/generateApp.d.ts.map +1 -1
  3. package/dist/app/generateApp.js +2 -1
  4. package/dist/cli.js +46 -2
  5. package/dist/client/generateClient.d.ts.map +1 -1
  6. package/dist/client/generateClient.js +62 -6
  7. package/dist/client/generateOperations.d.ts.map +1 -1
  8. package/dist/client/generateOperations.js +27 -4
  9. package/dist/compiler/schemaCompiler.d.ts +40 -11
  10. package/dist/compiler/schemaCompiler.d.ts.map +1 -1
  11. package/dist/compiler/schemaCompiler.js +81 -6
  12. package/dist/compiler/shapeResolver.d.ts +18 -0
  13. package/dist/compiler/shapeResolver.d.ts.map +1 -0
  14. package/dist/compiler/shapeResolver.js +280 -0
  15. package/dist/gateway/generateGateway.d.ts.map +1 -1
  16. package/dist/gateway/generateGateway.js +2 -1
  17. package/dist/gateway/generators.d.ts +13 -1
  18. package/dist/gateway/generators.d.ts.map +1 -1
  19. package/dist/gateway/generators.js +98 -13
  20. package/dist/gateway/helpers.d.ts +16 -0
  21. package/dist/gateway/helpers.d.ts.map +1 -1
  22. package/dist/gateway/helpers.js +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +16 -1
  26. package/dist/openapi/generateOpenAPI.d.ts.map +1 -1
  27. package/dist/openapi/generateOpenAPI.js +28 -0
  28. package/dist/pipeline.d.ts +13 -0
  29. package/dist/pipeline.d.ts.map +1 -1
  30. package/dist/pipeline.js +17 -1
  31. package/dist/runtime/ndjson.d.ts +24 -0
  32. package/dist/runtime/ndjson.d.ts.map +1 -0
  33. package/dist/runtime/ndjson.js +30 -0
  34. package/dist/runtime/streamXml.d.ts +45 -0
  35. package/dist/runtime/streamXml.d.ts.map +1 -0
  36. package/dist/runtime/streamXml.js +212 -0
  37. package/dist/test/generators.d.ts.map +1 -1
  38. package/dist/test/generators.js +50 -0
  39. package/dist/test/mockData.d.ts +6 -0
  40. package/dist/test/mockData.d.ts.map +1 -1
  41. package/dist/test/mockData.js +6 -2
  42. package/dist/util/cli.d.ts.map +1 -1
  43. package/dist/util/cli.js +3 -1
  44. package/dist/util/runtimeSource.d.ts +2 -0
  45. package/dist/util/runtimeSource.d.ts.map +1 -0
  46. package/dist/util/runtimeSource.js +38 -0
  47. package/dist/util/streamConfig.d.ts +59 -0
  48. package/dist/util/streamConfig.d.ts.map +1 -0
  49. package/dist/util/streamConfig.js +230 -0
  50. package/docs/README.md +1 -0
  51. package/docs/api-reference.md +146 -0
  52. package/docs/architecture.md +27 -5
  53. package/docs/cli-reference.md +30 -0
  54. package/docs/concepts.md +51 -0
  55. package/docs/configuration.md +40 -0
  56. package/docs/decisions/002-streamable-responses.md +308 -0
  57. package/docs/gateway-guide.md +37 -0
  58. package/docs/generated-code.md +21 -0
  59. package/docs/migration-playbook.md +33 -0
  60. package/docs/migration.md +31 -6
  61. package/docs/output-anatomy.md +49 -0
  62. package/docs/production.md +32 -0
  63. package/docs/start-here.md +33 -0
  64. package/docs/supported-patterns.md +2 -0
  65. package/docs/testing.md +14 -0
  66. package/docs/troubleshooting.md +18 -0
  67. package/package.json +9 -5
  68. package/src/runtime/clientStreamMethods.tpl.txt +183 -0
  69. package/src/runtime/ndjson.ts +32 -0
  70. package/src/runtime/operationsStreamHelper.tpl.txt +13 -0
  71. package/src/runtime/streamXml.ts +293 -0
package/README.md CHANGED
@@ -28,6 +28,7 @@ Most tools in this space stop at one layer: a SOAP runtime, type generation, or
28
28
  - Handles complex inheritance, `xs:attribute`, namespace collisions, nested XSD imports, and choice elements
29
29
  - Generated `operations.ts` interface enables testing without importing `soap` or calling a live service
30
30
  - OpenAPI is a first-class output, not an afterthought; types, schemas, and descriptions stay aligned
31
+ - Opt-in NDJSON streaming for large SOAP responses: client emits `AsyncIterable<RecordType>`, gateway flushes records incrementally, OpenAPI advertises the record schema via `x-wsdl-tsc-stream`
31
32
  - MIT licensed; generated code is yours with no attribution required
32
33
 
33
34
  ## Installation
@@ -103,6 +104,7 @@ See [Output Anatomy](docs/output-anatomy.md) for a detailed walkthrough of each
103
104
  - You want OpenAPI documentation that stays in sync with WSDL changes
104
105
  - You need deterministic codegen output safe for CI/CD regeneration
105
106
  - You are modernizing a legacy SOAP integration incrementally
107
+ - You have SOAP operations that return large payloads and need to stream records incrementally instead of buffering
106
108
 
107
109
  ## When NOT to Use This
108
110
 
@@ -137,6 +139,7 @@ Platform API gateways solve governance, policy, and multi-language SDK generatio
137
139
  | REST gateway generation | no | no | no | yes |
138
140
  | Runnable app scaffolding | no | no | no | yes |
139
141
  | Mockable operations interface | no | no | no | yes |
142
+ | Streaming large responses (NDJSON) | no | no | no | yes |
140
143
 
141
144
  Data as of April 2026.
142
145
 
@@ -152,6 +155,7 @@ Real-world WSDL/XSD files are rarely clean. This generator handles patterns that
152
155
  - Correct optionality for nillable fields in both TypeScript and OpenAPI output
153
156
  - The `$value` pattern for simple content with attributes, preserving text content alongside attribute properties
154
157
  - `ArrayOf*` wrapper types, unwrapped automatically in OpenAPI with runtime bridging
158
+ - `xs:any` wildcard payloads mapped to concrete record shapes from a companion WSDL, enabling streaming over responses that the primary WSDL describes only as opaque wrappers
155
159
 
156
160
  See [Core Concepts](docs/concepts.md) and [Supported Patterns](docs/supported-patterns.md) for details.
157
161
 
@@ -226,6 +230,7 @@ See [CLI Reference](docs/cli-reference.md) for all flags and examples.
226
230
  | [Programmatic API](docs/api-reference.md) | TypeScript functions for build tools |
227
231
  | [Core Concepts](docs/concepts.md) | Flattening, $value, primitives, determinism |
228
232
  | [Architecture](docs/architecture.md) | Internal pipeline for contributors |
233
+ | [Streamable Responses (ADR-002)](docs/decisions/002-streamable-responses.md) | Opt-in streaming: client `AsyncIterable`, gateway NDJSON, `x-wsdl-tsc-stream` |
229
234
  | [Version Migration](docs/migration.md) | Upgrading between package versions |
230
235
 
231
236
  ## Why This Exists
@@ -1 +1 @@
1
- {"version":3,"file":"generateApp.d.ts","sourceRoot":"","sources":["../../src/app/generateApp.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA4kBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDzE"}
1
+ {"version":3,"file":"generateApp.d.ts","sourceRoot":"","sources":["../../src/app/generateApp.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA6kBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDzE"}
@@ -454,10 +454,11 @@ function generatePackageJson(appDir, force) {
454
454
  dependencies: {
455
455
  fastify: "^5.8.5",
456
456
  "fastify-plugin": "^5.1.0",
457
+ saxes: "^6.0.0",
457
458
  soap: "^1.9.1",
458
459
  },
459
460
  devDependencies: {
460
- "@types/node": "^25.6.0",
461
+ "@types/node": "^25.7.0",
461
462
  tsx: "^4.21.0",
462
463
  typescript: "^6.0.3",
463
464
  },
package/dist/cli.js CHANGED
@@ -25,6 +25,25 @@ import { runGenerationPipeline } from "./pipeline.js";
25
25
  import { resolveCompilerOptions } from "./config.js";
26
26
  import { emitClientArtifacts, handleCLIError, parseServers, parseStatusCodes, reportCompilationStats, reportOpenApiSuccess, success, validateGatewayRequirements, } from "./util/cli.js";
27
27
  import { buildCompilerOptionsFromArgv, buildOpenApiOptionsFromArgv } from "./util/builder.js";
28
+ import { loadStreamConfigFile, StreamConfigError } from "./util/streamConfig.js";
29
+ /**
30
+ * Load and parse a stream-config file, or call the shared CLI error handler
31
+ * (which prints the structured message and exits). Returns `undefined` when
32
+ * `filePath` is falsy so callers can chain with `argv["stream-config"]`.
33
+ */
34
+ function loadStreamConfigOrExit(filePath) {
35
+ if (!filePath)
36
+ return undefined;
37
+ try {
38
+ return loadStreamConfigFile(filePath);
39
+ }
40
+ catch (err) {
41
+ if (err instanceof StreamConfigError) {
42
+ handleCLIError(err);
43
+ }
44
+ throw err;
45
+ }
46
+ }
28
47
  // Process command line arguments, removing the first two elements (node executable and script path)
29
48
  const rawArgs = hideBin(process.argv);
30
49
  // Available commands
@@ -75,6 +94,7 @@ if (rawArgs[0] === "compile") {
75
94
  .option("client-choice-mode", { type: "string", choices: ["all-optional", "union"], default: "all-optional" })
76
95
  .option("client-fail-on-unresolved", { type: "boolean", default: false })
77
96
  .option("client-nillable-as-optional", { type: "boolean", default: false })
97
+ .option("stream-config", { type: "string", desc: "Path to a stream configuration JSON file (ADR-002)." })
78
98
  .strict()
79
99
  .help()
80
100
  .parse();
@@ -89,7 +109,17 @@ if (rawArgs[0] === "compile") {
89
109
  wsdl: String(compileArgv["wsdl-source"]),
90
110
  out: path.dirname(catalogOut),
91
111
  });
92
- const compiled = compileCatalog(wsdlCatalog, compilerOptions);
112
+ const streamConfig = compileArgv["stream-config"]
113
+ ? loadStreamConfigOrExit(String(compileArgv["stream-config"]))
114
+ : undefined;
115
+ const compiled = compileCatalog(wsdlCatalog, compilerOptions, streamConfig);
116
+ if (streamConfig) {
117
+ const { applyShapeCatalogs } = await import("./compiler/shapeResolver.js");
118
+ const shapeBaseDir = compileArgv["stream-config"]
119
+ ? path.dirname(path.resolve(String(compileArgv["stream-config"])))
120
+ : path.dirname(path.resolve(String(compileArgv["wsdl-source"])));
121
+ await applyShapeCatalogs(compiled, streamConfig, { baseDir: shapeBaseDir });
122
+ }
93
123
  // Report compilation statistics
94
124
  reportCompilationStats(wsdlCatalog, compiled);
95
125
  // Ensure output directory exists
@@ -136,6 +166,7 @@ if (rawArgs[0] === "client") {
136
166
  .option("client-choice-mode", { type: "string", choices: ["all-optional", "union"], default: "all-optional" })
137
167
  .option("client-fail-on-unresolved", { type: "boolean", default: false })
138
168
  .option("client-nillable-as-optional", { type: "boolean", default: false })
169
+ .option("stream-config", { type: "string", desc: "Path to a stream configuration JSON file (ADR-002). Only applied when compiling from WSDL." })
139
170
  .strict()
140
171
  .help()
141
172
  .parse();
@@ -175,7 +206,15 @@ if (rawArgs[0] === "client") {
175
206
  wsdl: String(clientArgv["wsdl-source"]),
176
207
  out: clientOutDir,
177
208
  });
178
- compiled = compileCatalog(wsdlCatalog, compilerOptions);
209
+ const clientStreamConfig = loadStreamConfigOrExit(clientArgv["stream-config"]);
210
+ compiled = compileCatalog(wsdlCatalog, compilerOptions, clientStreamConfig);
211
+ if (clientStreamConfig) {
212
+ const { applyShapeCatalogs } = await import("./compiler/shapeResolver.js");
213
+ const shapeBaseDir = clientArgv["stream-config"]
214
+ ? path.dirname(path.resolve(String(clientArgv["stream-config"])))
215
+ : path.dirname(path.resolve(String(clientArgv["wsdl-source"])));
216
+ await applyShapeCatalogs(compiled, clientStreamConfig, { baseDir: shapeBaseDir });
217
+ }
179
218
  // Report compilation statistics
180
219
  reportCompilationStats(wsdlCatalog, compiled);
181
220
  // Emit catalog
@@ -675,6 +714,10 @@ if (rawArgs[0] === "pipeline") {
675
714
  type: "boolean",
676
715
  default: false,
677
716
  desc: "Overwrite existing test files when using --test-dir"
717
+ })
718
+ .option("stream-config", {
719
+ type: "string",
720
+ desc: "Path to a stream configuration JSON file (ADR-002). Applied to every stage that consumes the compiled catalog."
678
721
  })
679
722
  .strict()
680
723
  .help()
@@ -764,6 +807,7 @@ if (rawArgs[0] === "pipeline") {
764
807
  clientOutDir: clientOut ? path.resolve(clientOut) : undefined,
765
808
  catalogOut,
766
809
  compiler: compilerOptions,
810
+ streamConfigFile: pipelineArgv["stream-config"],
767
811
  openapi: openApiOptions ? {
768
812
  ...openApiOptions,
769
813
  outFile: path.resolve(openapiOut),
@@ -1 +1 @@
1
- {"version":3,"file":"generateClient.d.ts","sourceRoot":"","sources":["../../src/client/generateClient.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAInE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QA+WxE"}
1
+ {"version":3,"file":"generateClient.d.ts","sourceRoot":"","sources":["../../src/client/generateClient.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAKnE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QAsaxE"}
@@ -13,8 +13,10 @@
13
13
  * - Consistent error handling and client configuration
14
14
  */
15
15
  import fs from "node:fs";
16
+ import path from "node:path";
16
17
  import { deriveClientName, pascal, pascalToSnakeCase } from "../util/tools.js";
17
18
  import { error, warn } from "../util/cli.js";
19
+ import { loadRuntimeSource } from "../util/runtimeSource.js";
18
20
  /**
19
21
  * Generates a TypeScript SOAP client class from a compiled WSDL catalog
20
22
  *
@@ -53,6 +55,9 @@ export function generateClient(outFile, compiled) {
53
55
  // get the class name for the client
54
56
  const clientName = deriveClientName(compiled);
55
57
  const clientConstant = pascalToSnakeCase(clientName).toUpperCase();
58
+ // Track whether any operation opts into streaming, so we can emit the
59
+ // supporting runtime helpers only when they're actually used.
60
+ let anyStream = false;
56
61
  // Build the dynamic methods for the client class
57
62
  for (const op of compiled.operations) {
58
63
  const m = isValidIdent(op.name) && !reserved.has(op.name)
@@ -70,6 +75,38 @@ export function generateClient(outFile, compiled) {
70
75
  const opDocLines = op.doc ? normalizeDocLines(op.doc) : [];
71
76
  const opDocStr = opDocLines.length ? `\n *\n${opDocLines.map(line => ` * ${line}`).join("\n")}` : "";
72
77
  const secHintsStr = secHints.length ? `\n *\n * Security (WSDL policy hint): ${secHints.join(", ")}` : "";
78
+ if (op.stream) {
79
+ anyStream = true;
80
+ const recordTs = op.stream.recordTypeName;
81
+ const inputElementLocal = op.inputElement?.local ?? op.name;
82
+ const inputElementNs = op.inputElement?.ns ?? compiled.wsdlTargetNS;
83
+ const methodTemplate = `
84
+
85
+ /**
86
+ * Streams records from the ${m} operation of the ${clientName}.${opDocStr}${secHintsStr}
87
+ *
88
+ * @param args - The request arguments for the ${m} operation.
89
+ * @returns A promise resolving to a streaming response whose \`records\` is an
90
+ * async iterable of ${recordTs} objects parsed from the SOAP body as
91
+ * chunks arrive. Iteration pulls bytes on demand.
92
+ */
93
+ async ${m}<HeadersType = Record<string, string>>(
94
+ args: ${inTs}
95
+ ): Promise<StreamOperationResponse<T.${recordTs}, HeadersType>> {
96
+ return this.callStream<${inTs}, T.${recordTs}, HeadersType>(
97
+ args,
98
+ ${JSON.stringify(m)},
99
+ ${inTypeName ? JSON.stringify(inTypeName) : "undefined"},
100
+ ${JSON.stringify(recordTs)},
101
+ ${JSON.stringify(inputElementLocal)},
102
+ ${JSON.stringify(inputElementNs)},
103
+ ${JSON.stringify(op.soapAction ?? "")},
104
+ ${JSON.stringify(op.stream.recordPath)}
105
+ );
106
+ }`;
107
+ methods.push(methodTemplate);
108
+ continue;
109
+ }
73
110
  const methodTemplate = `
74
111
 
75
112
  /**
@@ -91,6 +128,11 @@ export function generateClient(outFile, compiled) {
91
128
  methods.push(methodTemplate);
92
129
  }
93
130
  const methodsBody = methods.join("\n");
131
+ // The streaming transport + envelope builders are carried in a sibling
132
+ // *.tpl file so the IDE does not try to parse their content as code nested
133
+ // inside this template literal (which would flag `this`, `await`, `yield`
134
+ // outside-of-function false positives).
135
+ const streamMethodsBlock = anyStream ? "\n" + loadRuntimeSource("clientStreamMethods.tpl.txt") : "";
94
136
  // noinspection JSFileReferences,JSUnresolvedReference,CommaExpressionJS,JSDuplicatedDeclaration,ReservedWordAsName,JSCommentMatchesSignature,JSValidateTypes,JSIgnoredPromiseFromCall,BadExpressionStatementJS,ES6UnusedImports,JSUnnecessarySemicolon,UnreachableCodeJS,JSUnusedLocalSymbols
95
137
  const classTemplate = `// noinspection JSAnnotator
96
138
 
@@ -101,7 +143,9 @@ export function generateClient(outFile, compiled) {
101
143
  import * as soap from "soap";
102
144
  import type * as T from "./types${suffix}";
103
145
  import type {${clientName}DataTypes} from "./utils${suffix}";
104
- import {${clientConstant}_DATA_TYPES} from "./utils${suffix}";
146
+ import {${clientConstant}_DATA_TYPES} from "./utils${suffix}";${anyStream ? `
147
+ import {parseRecords, type RecordParseSpec} from "./streamXml${suffix}";
148
+ import type {StreamOperationResponse} from "./operations${suffix}";` : ""}
105
149
 
106
150
  /**
107
151
  * Represents the response structure for ${clientName} operations.
@@ -287,7 +331,7 @@ ${methodsBody}
287
331
 
288
332
  // Get metadata for this specific type to know which props are attributes
289
333
  const attributesList = (typeName && this.dataTypes?.Attributes?.[typeName]) || [];
290
- const childrenTypes = (typeName && this.dataTypes?.ChildrenTypes?.[typeName]) || {};
334
+ const childrenTypes: Readonly<Record<string, string>> = (typeName && this.dataTypes?.ChildrenTypes?.[typeName]) || {};
291
335
 
292
336
  const out: any = {};
293
337
  const attributesBag: Record<string, any> = {};
@@ -320,7 +364,7 @@ ${methodsBody}
320
364
  }
321
365
 
322
366
  // Everything else becomes a child element, recursively processed
323
- const childType = (childrenTypes as any)[k] as string | undefined;
367
+ const childType: string | undefined = childrenTypes[k];
324
368
  out[k] = Array.isArray(v)
325
369
  ? v.map(node => this.toSoapArgs(node, childType))
326
370
  : this.toSoapArgs(v, childType);
@@ -356,7 +400,7 @@ ${methodsBody}
356
400
  }
357
401
 
358
402
  // Get child type mapping for recursive processing with correct types
359
- const childrenTypes = (typeName && this.dataTypes?.ChildrenTypes?.[typeName]) || {};
403
+ const childrenTypes: Readonly<Record<string, string>> = (typeName && this.dataTypes?.ChildrenTypes?.[typeName]) || {};
360
404
  const result: any = {};
361
405
 
362
406
  // Preserve text content for mixed XML elements
@@ -379,14 +423,14 @@ ${methodsBody}
379
423
  continue;
380
424
  }
381
425
  // Recursively convert child elements with their specific type info
382
- const childType = (childrenTypes as any)[k] as string | undefined;
426
+ const childType: string | undefined = childrenTypes[k];
383
427
  result[k] = Array.isArray(v)
384
428
  ? v.map(node => this.fromSoapResult(node, childType))
385
429
  : this.fromSoapResult(v, childType);
386
430
  }
387
431
 
388
432
  return result;
389
- }
433
+ }${streamMethodsBlock}
390
434
  }
391
435
  `;
392
436
  try {
@@ -395,4 +439,16 @@ ${methodsBody}
395
439
  catch (e) {
396
440
  error(`Failed to write client to ${outFile}`);
397
441
  }
442
+ // If any operation opted into streaming, drop the runtime XML parser
443
+ // alongside the client so the generated class can import it without
444
+ // depending on a `@techspokes/typescript-wsdl-client/runtime/...` subpath.
445
+ if (anyStream) {
446
+ try {
447
+ const streamXmlOut = path.join(path.dirname(outFile), "streamXml.ts");
448
+ fs.writeFileSync(streamXmlOut, loadRuntimeSource("streamXml.ts"), "utf-8");
449
+ }
450
+ catch (e) {
451
+ error(`Failed to emit streamXml.ts next to ${outFile}: ${e instanceof Error ? e.message : String(e)}`);
452
+ }
453
+ }
398
454
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generateOperations.d.ts","sourceRoot":"","sources":["../../src/client/generateOperations.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAIrE;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAsEnF"}
1
+ {"version":3,"file":"generateOperations.d.ts","sourceRoot":"","sources":["../../src/client/generateOperations.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAKrE;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CA8FnF"}
@@ -8,6 +8,7 @@
8
8
  import fs from "node:fs";
9
9
  import { deriveClientName, pascal } from "../util/tools.js";
10
10
  import { error } from "../util/cli.js";
11
+ import { loadRuntimeSource } from "../util/runtimeSource.js";
11
12
  /**
12
13
  * Generates an operations.ts file with a fully-typed interface for all SOAP operations
13
14
  *
@@ -31,6 +32,9 @@ export function generateOperations(outFile, compiled) {
31
32
  // Collect type names used in method signatures for the import statement
32
33
  const importedTypes = new Set();
33
34
  const methods = [];
35
+ // Does any operation opt into streaming? If so we also emit the
36
+ // StreamOperationResponse helper type below.
37
+ let anyStream = false;
34
38
  for (const op of compiled.operations) {
35
39
  const inTypeName = op.inputTypeName ?? (op.inputElement ? pascal(op.inputElement.local) : undefined);
36
40
  const outTypeName = op.outputTypeName ?? (op.outputElement ? pascal(op.outputElement.local) : undefined);
@@ -47,15 +51,34 @@ export function generateOperations(outFile, compiled) {
47
51
  const docBlock = docLines.length > 0
48
52
  ? ` /**\n${docLines.map(line => ` * ${line}`).join("\n")}\n */\n`
49
53
  : "";
50
- methods.push(`${docBlock} ${op.name}(\n` +
51
- ` args: ${inTs}\n` +
52
- ` ): Promise<{ response: ${outTs}; headers: unknown }>;\n`);
54
+ if (op.stream) {
55
+ anyStream = true;
56
+ const recordTs = op.stream.recordTypeName;
57
+ importedTypes.add(recordTs);
58
+ methods.push(`${docBlock} ${op.name}(\n` +
59
+ ` args: ${inTs}\n` +
60
+ ` ): Promise<StreamOperationResponse<${recordTs}>>;\n`);
61
+ }
62
+ else {
63
+ methods.push(`${docBlock} ${op.name}(\n` +
64
+ ` args: ${inTs}\n` +
65
+ ` ): Promise<{ response: ${outTs}; headers: unknown }>;\n`);
66
+ }
53
67
  }
54
68
  // Build sorted import list for deterministic output
55
69
  const sortedImports = Array.from(importedTypes).sort();
56
70
  const typeImport = sortedImports.length > 0
57
71
  ? `import type {\n${sortedImports.map((t) => ` ${t},`).join("\n")}\n} from "./types${suffix}";\n\n`
58
72
  : "";
73
+ // Emit the StreamOperationResponse helper type iff at least one operation
74
+ // is stream-configured. Kept inside operations.ts so that mocks and gateway
75
+ // code can import it without pulling in the SOAP runtime. The raw template
76
+ // lives in a sibling .tpl file so the IDE does not try to parse embedded
77
+ // TypeScript type-parameter defaults (HeadersType = Record<...>) as
78
+ // JavaScript assignment expressions.
79
+ const streamHelper = anyStream
80
+ ? loadRuntimeSource("operationsStreamHelper.tpl.txt").replace(/__CLIENT_NAME__/g, clientName)
81
+ : "";
59
82
  const content = `/**
60
83
  * Typed operations interface for the ${clientName} service.
61
84
  *
@@ -64,7 +87,7 @@ export function generateOperations(outFile, compiled) {
64
87
  *
65
88
  * Auto-generated - do not edit manually.
66
89
  */
67
- ${typeImport}/**
90
+ ${typeImport}${streamHelper}/**
68
91
  * All operations exposed by the ${clientName} SOAP service.
69
92
  *
70
93
  * The concrete ${clientName} class satisfies this interface.
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import type { CompilerOptions } from "../config.js";
13
13
  import type { WsdlCatalog } from "../loader/wsdlLoader.js";
14
+ import type { OperationStreamMetadata, StreamConfig } from "../util/streamConfig.js";
14
15
  /**
15
16
  * Qualified name with namespace and local part
16
17
  *
@@ -22,6 +23,21 @@ export type QName = {
22
23
  ns: string;
23
24
  local: string;
24
25
  };
26
+ /**
27
+ * Represents an xs:any wildcard particle retained on a complex type.
28
+ *
29
+ * The base compiler previously dropped wildcards silently. Keeping them as
30
+ * explicit markers lets downstream tools (stream-candidate detection,
31
+ * streaming XML converter) reason honestly about types whose payload lives
32
+ * outside the statically-typed schema — e.g. Escapia's content-service
33
+ * stream wrappers that mix an xs:schema marker with an xs:any payload.
34
+ */
35
+ export type CompiledWildcard = {
36
+ min: number;
37
+ max: number | "unbounded";
38
+ namespace?: string;
39
+ processContents?: "lax" | "strict" | "skip";
40
+ };
25
41
  /**
26
42
  * Represents a compiled complex type with attributes and elements
27
43
  *
@@ -34,6 +50,7 @@ export type QName = {
34
50
  * @property {string} [base] - Base type name for extension/inheritance
35
51
  * @property {Array<Object>} [localAttrs] - Attributes added in extension (not inherited)
36
52
  * @property {Array<Object>} [localElems] - Elements added in extension (not inherited)
53
+ * @property {Array<Object>} [wildcards] - xs:any wildcard particles retained on the type
37
54
  */
38
55
  export type CompiledType = {
39
56
  name: string;
@@ -73,6 +90,7 @@ export type CompiledType = {
73
90
  declaredType: string;
74
91
  doc?: string;
75
92
  }>;
93
+ wildcards?: CompiledWildcard[];
76
94
  };
77
95
  /**
78
96
  * Represents a compiled type alias (simple type or restricted type)
@@ -126,6 +144,26 @@ export type CompiledWsdlDocs = {
126
144
  export type CompiledDiagnostics = {
127
145
  notes?: string[];
128
146
  };
147
+ /**
148
+ * Compiled SOAP operation shape. Extracted so that extended fields (stream
149
+ * metadata, future delivery modes) live in one named type instead of being
150
+ * buried inline on CompiledCatalog.operations.
151
+ */
152
+ export type CompiledOperation = {
153
+ name: string;
154
+ soapAction: string;
155
+ inputElement?: QName;
156
+ outputElement?: QName;
157
+ security?: string[];
158
+ inputTypeName?: string;
159
+ outputTypeName?: string;
160
+ doc?: string;
161
+ /**
162
+ * Stream delivery metadata; populated from a StreamConfig when the operation
163
+ * is opted in. Absent for ordinary buffered operations.
164
+ */
165
+ stream?: OperationStreamMetadata;
166
+ };
129
167
  /**
130
168
  * Complete compiled catalog with all types, aliases, operations and metadata
131
169
  *
@@ -149,16 +187,7 @@ export type CompiledCatalog = {
149
187
  childType: Record<string, Record<string, string>>;
150
188
  propMeta: Record<string, Record<string, any>>;
151
189
  };
152
- operations: Array<{
153
- name: string;
154
- soapAction: string;
155
- inputElement?: QName;
156
- outputElement?: QName;
157
- security?: string[];
158
- inputTypeName?: string;
159
- outputTypeName?: string;
160
- doc?: string;
161
- }>;
190
+ operations: CompiledOperation[];
162
191
  wsdlTargetNS: string;
163
192
  wsdlUri: string;
164
193
  serviceName?: string;
@@ -175,5 +204,5 @@ export type CompiledCatalog = {
175
204
  * 4. Extract WSDL operations: pick the appropriate SOAP binding (v1.1 or v1.2), resolve its
176
205
  * portType reference, then enumerate operations and their soapAction URIs.
177
206
  */
178
- export declare function compileCatalog(cat: WsdlCatalog, options: CompilerOptions): CompiledCatalog;
207
+ export declare function compileCatalog(cat: WsdlCatalog, options: CompilerOptions, streamConfig?: StreamConfig): CompiledCatalog;
179
208
  //# sourceMappingURL=schemaCompiler.d.ts.map
@@ -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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"}
@@ -153,7 +153,7 @@ function extractAnnotationDocumentation(node) {
153
153
  * 4. Extract WSDL operations: pick the appropriate SOAP binding (v1.1 or v1.2), resolve its
154
154
  * portType reference, then enumerate operations and their soapAction URIs.
155
155
  */
156
- export function compileCatalog(cat, options) {
156
+ export function compileCatalog(cat, options, streamConfig) {
157
157
  // symbol tables discovered across all schemas
158
158
  const complexTypes = new Map();
159
159
  const simpleTypes = new Map();
@@ -353,6 +353,33 @@ export function compileCatalog(cat, options) {
353
353
  }
354
354
  return out;
355
355
  };
356
+ // Walks the same compositor structure as collectParticles and returns any
357
+ // xs:any wildcard particles found. Kept as a sibling to avoid reshaping
358
+ // collectParticles' return type at the three call sites below.
359
+ const collectWildcards = (node) => {
360
+ const out = [];
361
+ const recurse = (groupNode) => {
362
+ for (const a of getChildrenWithLocalName(groupNode, "any")) {
363
+ const min = a["@_minOccurs"] ? Number(a["@_minOccurs"]) : 1;
364
+ const maxAttr = a["@_maxOccurs"];
365
+ const max = maxAttr === "unbounded" ? "unbounded" : maxAttr ? Number(maxAttr) : 1;
366
+ const pc = a["@_processContents"];
367
+ out.push({
368
+ min,
369
+ max,
370
+ ...(a["@_namespace"] ? { namespace: a["@_namespace"] } : {}),
371
+ ...(pc === "lax" || pc === "strict" || pc === "skip" ? { processContents: pc } : {}),
372
+ });
373
+ }
374
+ for (const comp of ["sequence", "all", "choice"]) {
375
+ for (const sub of getChildrenWithLocalName(groupNode, comp)) {
376
+ recurse(sub);
377
+ }
378
+ }
379
+ };
380
+ recurse(node);
381
+ return out;
382
+ };
356
383
  const collectParticles = (ownerTypeName, node) => {
357
384
  const out = [];
358
385
  // process a compositor or element container recursively
@@ -424,8 +451,12 @@ export function compileCatalog(cat, options) {
424
451
  // On duplicate definitions, merge new attributes and elements
425
452
  const newAttrs = collectAttributes(cnode);
426
453
  const newElems = collectParticles(outName, cnode);
454
+ const newWildcards = collectWildcards(cnode);
427
455
  mergeAttrs(present.attrs, newAttrs);
428
456
  mergeElems(present.elems, newElems);
457
+ if (newWildcards.length > 0) {
458
+ present.wildcards = [...(present.wildcards ?? []), ...newWildcards];
459
+ }
429
460
  if (!present.doc && typeDoc) {
430
461
  present.doc = typeDoc;
431
462
  }
@@ -460,6 +491,7 @@ export function compileCatalog(cat, options) {
460
491
  // collect local additions/overrides
461
492
  const locals = collectAttributes(node);
462
493
  const localElems = collectParticles(outName, node);
494
+ const localWildcards = collectWildcards(node);
463
495
  attrs.push(...locals);
464
496
  elems.push(...localElems);
465
497
  const result = {
@@ -470,7 +502,8 @@ export function compileCatalog(cat, options) {
470
502
  doc: typeDoc,
471
503
  base: baseName,
472
504
  localAttrs: locals,
473
- localElems
505
+ localElems,
506
+ ...(localWildcards.length > 0 ? { wildcards: localWildcards } : {}),
474
507
  };
475
508
  compiledMap.set(key, result);
476
509
  inProgress.delete(key);
@@ -513,7 +546,15 @@ export function compileCatalog(cat, options) {
513
546
  // Attributes + particles
514
547
  mergeAttrs(attrs, collectAttributes(cnode));
515
548
  mergeElems(elems, collectParticles(outName, cnode));
516
- const result = { name: outName, ns: schemaNS, attrs, elems, doc: typeDoc };
549
+ const wildcards = collectWildcards(cnode);
550
+ const result = {
551
+ name: outName,
552
+ ns: schemaNS,
553
+ attrs,
554
+ elems,
555
+ doc: typeDoc,
556
+ ...(wildcards.length > 0 ? { wildcards } : {}),
557
+ };
517
558
  compiledMap.set(key, result);
518
559
  inProgress.delete(rawKey);
519
560
  return result;
@@ -832,7 +873,7 @@ export function compileCatalog(cat, options) {
832
873
  .filter((x) => x != null)
833
874
  .sort((a, b) => a.name.localeCompare(b.name));
834
875
  // build operations list
835
- const ops = (pOps
876
+ const ops = pOps
836
877
  .map(po => {
837
878
  const name = po?.["@_name"];
838
879
  if (!name)
@@ -845,9 +886,18 @@ export function compileCatalog(cat, options) {
845
886
  // Derive TypeScript type names from element local names
846
887
  const inputTypeName = inputElement ? pascal(inputElement.local) : undefined;
847
888
  const outputTypeName = outputElement ? pascal(outputElement.local) : undefined;
848
- return { name, soapAction: bOps.get(name) || "", inputElement, outputElement, inputTypeName, outputTypeName, doc };
889
+ const op = {
890
+ name,
891
+ soapAction: bOps.get(name) || "",
892
+ ...(inputElement ? { inputElement } : {}),
893
+ ...(outputElement ? { outputElement } : {}),
894
+ ...(inputTypeName ? { inputTypeName } : {}),
895
+ ...(outputTypeName ? { outputTypeName } : {}),
896
+ ...(doc ? { doc } : {}),
897
+ };
898
+ return op;
849
899
  })
850
- .filter((x) => x != null));
900
+ .filter((x) => x != null);
851
901
  // --- WS-Policy: scan for security requirements (inline policies only) ---
852
902
  const bindingPolicies = getChildrenWithLocalName(soapBinding || {}, "Policy");
853
903
  const bindingSec = collectSecurityFromPolicyNodes(bindingPolicies);
@@ -858,6 +908,31 @@ export function compileCatalog(cat, options) {
858
908
  const secSet = new Set([...bindingSec, ...opSec]);
859
909
  op.security = Array.from(secSet);
860
910
  }
911
+ // --- Stream config application ---
912
+ // A stream-configured operation is matched by name against the WSDL's
913
+ // portType operations. Unknown operation names are fatal so that consumers
914
+ // find out about stale configs at generation time, not at runtime.
915
+ if (streamConfig) {
916
+ const opByName = new Map(ops.map((op) => [op.name, op]));
917
+ for (const [opName, meta] of Object.entries(streamConfig.operations)) {
918
+ const op = opByName.get(opName);
919
+ if (!op) {
920
+ throw new WsdlCompilationError(`Stream config references operation "${opName}" but the WSDL portType does not declare it.`, {
921
+ element: opName,
922
+ suggestion: `Remove the entry under "operations.${opName}" in the stream config, or correct the operation name to match one defined in the WSDL.`,
923
+ });
924
+ }
925
+ op.stream = {
926
+ mode: meta.mode,
927
+ format: meta.format,
928
+ mediaType: meta.mediaType,
929
+ recordPath: [...meta.recordPath],
930
+ recordTypeName: meta.recordTypeName,
931
+ ...(meta.shapeCatalogName ? { shapeCatalogName: meta.shapeCatalogName } : {}),
932
+ ...(op.outputTypeName ? { sourceOutputTypeName: op.outputTypeName } : {}),
933
+ };
934
+ }
935
+ }
861
936
  // --- Service discovery (for client naming) ---
862
937
  let serviceName;
863
938
  const soapBindingName = soapBinding?.["@_name"];
@@ -0,0 +1,18 @@
1
+ import { type CompiledCatalog } from "./schemaCompiler.js";
2
+ import type { StreamConfig } from "../util/streamConfig.js";
3
+ export interface ApplyShapeCatalogsOptions {
4
+ /** Directory against which relative `catalogFile`/`wsdlSource` paths resolve. Defaults to process.cwd(). */
5
+ baseDir?: string;
6
+ }
7
+ /**
8
+ * Apply a parsed StreamConfig to a compiled catalog:
9
+ * 1. Verify every opted-in operation's record type is resolvable.
10
+ * 2. For each operation that names a shapeCatalog, load the companion
11
+ * catalog (once, cached) and copy the reachable record-type graph.
12
+ *
13
+ * Mutates `compiled` in place. Safe to call with a StreamConfig that has
14
+ * zero shapeCatalogs — it will still validate record-type presence against
15
+ * the current catalog.
16
+ */
17
+ export declare function applyShapeCatalogs(compiled: CompiledCatalog, streamConfig: StreamConfig, options?: ApplyShapeCatalogsOptions): Promise<void>;
18
+ //# sourceMappingURL=shapeResolver.d.ts.map