@techspokes/typescript-wsdl-client 0.15.2 → 0.17.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 +5 -0
- package/dist/app/generateApp.d.ts.map +1 -1
- package/dist/app/generateApp.js +4 -3
- package/dist/cli.js +46 -2
- package/dist/client/generateClient.d.ts.map +1 -1
- package/dist/client/generateClient.js +64 -8
- package/dist/client/generateOperations.d.ts.map +1 -1
- package/dist/client/generateOperations.js +29 -6
- package/dist/client/generateTypes.d.ts.map +1 -1
- package/dist/client/generateTypes.js +13 -0
- package/dist/compiler/schemaCompiler.d.ts +44 -11
- package/dist/compiler/schemaCompiler.d.ts.map +1 -1
- package/dist/compiler/schemaCompiler.js +102 -6
- package/dist/compiler/shapeResolver.d.ts +18 -0
- package/dist/compiler/shapeResolver.d.ts.map +1 -0
- package/dist/compiler/shapeResolver.js +280 -0
- package/dist/gateway/generateGateway.d.ts.map +1 -1
- package/dist/gateway/generateGateway.js +2 -1
- package/dist/gateway/generators.d.ts +13 -1
- package/dist/gateway/generators.d.ts.map +1 -1
- package/dist/gateway/generators.js +98 -13
- package/dist/gateway/helpers.d.ts +16 -0
- package/dist/gateway/helpers.d.ts.map +1 -1
- package/dist/gateway/helpers.js +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -4
- package/dist/openapi/generateOpenAPI.d.ts.map +1 -1
- package/dist/openapi/generateOpenAPI.js +30 -2
- package/dist/openapi/generatePaths.d.ts.map +1 -1
- package/dist/openapi/generatePaths.js +4 -2
- package/dist/openapi/generateSchemas.d.ts.map +1 -1
- package/dist/openapi/generateSchemas.js +20 -5
- package/dist/pipeline.d.ts +13 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +17 -1
- package/dist/runtime/ndjson.d.ts +24 -0
- package/dist/runtime/ndjson.d.ts.map +1 -0
- package/dist/runtime/ndjson.js +30 -0
- package/dist/runtime/streamXml.d.ts +45 -0
- package/dist/runtime/streamXml.d.ts.map +1 -0
- package/dist/runtime/streamXml.js +212 -0
- package/dist/test/generators.d.ts +2 -2
- package/dist/test/generators.d.ts.map +1 -1
- package/dist/test/generators.js +79 -26
- package/dist/test/mockData.d.ts +12 -2
- package/dist/test/mockData.d.ts.map +1 -1
- package/dist/test/mockData.js +17 -8
- package/dist/util/cli.d.ts +3 -0
- package/dist/util/cli.d.ts.map +1 -1
- package/dist/util/cli.js +6 -1
- package/dist/util/runtimeSource.d.ts +2 -0
- package/dist/util/runtimeSource.d.ts.map +1 -0
- package/dist/util/runtimeSource.js +38 -0
- package/dist/util/streamConfig.d.ts +59 -0
- package/dist/util/streamConfig.d.ts.map +1 -0
- package/dist/util/streamConfig.js +230 -0
- package/docs/README.md +1 -0
- package/docs/api-reference.md +146 -0
- package/docs/architecture.md +27 -5
- package/docs/cli-reference.md +30 -0
- package/docs/concepts.md +150 -11
- package/docs/configuration.md +40 -0
- package/docs/decisions/002-streamable-responses.md +308 -0
- package/docs/gateway-guide.md +37 -0
- package/docs/generated-code.md +21 -0
- package/docs/migration-playbook.md +33 -0
- package/docs/migration.md +31 -6
- package/docs/output-anatomy.md +49 -0
- package/docs/production.md +32 -0
- package/docs/start-here.md +33 -0
- package/docs/supported-patterns.md +29 -0
- package/docs/testing.md +14 -0
- package/docs/troubleshooting.md +18 -0
- package/package.json +9 -6
- package/src/runtime/clientStreamMethods.tpl.txt +183 -0
- package/src/runtime/ndjson.ts +32 -0
- package/src/runtime/operationsStreamHelper.tpl.txt +13 -0
- 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;
|
|
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"}
|
package/dist/app/generateApp.js
CHANGED
|
@@ -452,14 +452,15 @@ function generatePackageJson(appDir, force) {
|
|
|
452
452
|
dev: "tsx watch server.ts",
|
|
453
453
|
},
|
|
454
454
|
dependencies: {
|
|
455
|
-
fastify: "^5.8.
|
|
455
|
+
fastify: "^5.8.5",
|
|
456
456
|
"fastify-plugin": "^5.1.0",
|
|
457
|
-
|
|
457
|
+
saxes: "^6.0.0",
|
|
458
|
+
soap: "^1.9.1",
|
|
458
459
|
},
|
|
459
460
|
devDependencies: {
|
|
460
461
|
"@types/node": "^25.6.0",
|
|
461
462
|
tsx: "^4.21.0",
|
|
462
|
-
typescript: "^6.0.
|
|
463
|
+
typescript: "^6.0.3",
|
|
463
464
|
},
|
|
464
465
|
};
|
|
465
466
|
fs.writeFileSync(filePath, JSON.stringify(pkg, null, 2) + "\n", "utf-8");
|
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
|
|
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
|
-
|
|
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":"
|
|
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,13 +55,16 @@ 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)
|
|
59
64
|
? op.name
|
|
60
65
|
: `[${JSON.stringify(op.name)}]`;
|
|
61
|
-
const inTypeName = op.inputElement ? pascal(op.inputElement.local) : undefined;
|
|
62
|
-
const outTypeName = op.outputElement ? pascal(op.outputElement.local) : undefined;
|
|
66
|
+
const inTypeName = op.inputTypeName ?? (op.inputElement ? pascal(op.inputElement.local) : undefined);
|
|
67
|
+
const outTypeName = op.outputTypeName ?? (op.outputElement ? pascal(op.outputElement.local) : undefined);
|
|
63
68
|
if (!inTypeName && !outTypeName) {
|
|
64
69
|
warn(`Operation ${op.name} has no input or output type defined. Skipping method generation.`);
|
|
65
70
|
continue;
|
|
@@ -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 =
|
|
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 =
|
|
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;
|
|
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,9 +32,12 @@ 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
|
-
const inTypeName = op.inputElement ? pascal(op.inputElement.local) : undefined;
|
|
36
|
-
const outTypeName = op.outputElement ? pascal(op.outputElement.local) : undefined;
|
|
39
|
+
const inTypeName = op.inputTypeName ?? (op.inputElement ? pascal(op.inputElement.local) : undefined);
|
|
40
|
+
const outTypeName = op.outputTypeName ?? (op.outputElement ? pascal(op.outputElement.local) : undefined);
|
|
37
41
|
if (!inTypeName && !outTypeName) {
|
|
38
42
|
continue;
|
|
39
43
|
}
|
|
@@ -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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
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.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generateTypes.d.ts","sourceRoot":"","sources":["../../src/client/generateTypes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAAe,MAAM,+BAA+B,CAAC;AAGjF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"generateTypes.d.ts","sourceRoot":"","sources":["../../src/client/generateTypes.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,eAAe,EAAe,MAAM,+BAA+B,CAAC;AAGjF;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,QAsMvE"}
|
|
@@ -61,8 +61,17 @@ export function generateTypes(outFile, compiled) {
|
|
|
61
61
|
};
|
|
62
62
|
// Convenience lookups
|
|
63
63
|
const typeNames = new Set(compiled.types.map((t) => t.name));
|
|
64
|
+
const aliasNames = new Set(compiled.aliases.map((a) => a.name));
|
|
64
65
|
const isValidIdent = (name) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(name);
|
|
65
66
|
const emitPropName = (name) => (isValidIdent(name) ? name : JSON.stringify(name));
|
|
67
|
+
const isSyntheticAliasSelfWrapper = (t) => {
|
|
68
|
+
const elems = t.elems || [];
|
|
69
|
+
return aliasNames.has(t.name) &&
|
|
70
|
+
(t.attrs || []).length === 0 &&
|
|
71
|
+
elems.length === 1 &&
|
|
72
|
+
elems[0].name === "$value" &&
|
|
73
|
+
elems[0].tsType === t.name;
|
|
74
|
+
};
|
|
66
75
|
//
|
|
67
76
|
// 1) Named simple types (aliases) first
|
|
68
77
|
//
|
|
@@ -85,12 +94,16 @@ export function generateTypes(outFile, compiled) {
|
|
|
85
94
|
// sort types by name to ensure consistent order
|
|
86
95
|
compiled.types.sort((a, b) => a.name.localeCompare(b.name));
|
|
87
96
|
for (const t of compiled.types) {
|
|
97
|
+
if (isSyntheticAliasSelfWrapper(t)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
88
100
|
// Detect complexContent extension via compiled metadata or mis-mapped simpleContent extension
|
|
89
101
|
const complexBase = t.base;
|
|
90
102
|
// Detect mis-mapped simpleContent extension: single "$value" whose tsType is another named interface
|
|
91
103
|
const valueElems = (t.elems || []).filter((e) => e.name === "$value" &&
|
|
92
104
|
(e.max === 1 || e.max === undefined) &&
|
|
93
105
|
typeof e.tsType === "string" &&
|
|
106
|
+
e.tsType !== t.name &&
|
|
94
107
|
typeNames.has(e.tsType));
|
|
95
108
|
const isSimpleContentExtension = !complexBase && (t.elems?.length || 0) === 1 && valueElems.length === 1;
|
|
96
109
|
const baseName = complexBase ?? (isSimpleContentExtension ? valueElems[0].tsType : undefined);
|
|
@@ -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)
|
|
@@ -123,6 +141,29 @@ export type CompiledWsdlDocs = {
|
|
|
123
141
|
messages?: CompiledWsdlMessageDoc[];
|
|
124
142
|
services?: CompiledWsdlServiceDoc[];
|
|
125
143
|
};
|
|
144
|
+
export type CompiledDiagnostics = {
|
|
145
|
+
notes?: string[];
|
|
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
|
+
};
|
|
126
167
|
/**
|
|
127
168
|
* Complete compiled catalog with all types, aliases, operations and metadata
|
|
128
169
|
*
|
|
@@ -146,20 +187,12 @@ export type CompiledCatalog = {
|
|
|
146
187
|
childType: Record<string, Record<string, string>>;
|
|
147
188
|
propMeta: Record<string, Record<string, any>>;
|
|
148
189
|
};
|
|
149
|
-
operations:
|
|
150
|
-
name: string;
|
|
151
|
-
soapAction: string;
|
|
152
|
-
inputElement?: QName;
|
|
153
|
-
outputElement?: QName;
|
|
154
|
-
security?: string[];
|
|
155
|
-
inputTypeName?: string;
|
|
156
|
-
outputTypeName?: string;
|
|
157
|
-
doc?: string;
|
|
158
|
-
}>;
|
|
190
|
+
operations: CompiledOperation[];
|
|
159
191
|
wsdlTargetNS: string;
|
|
160
192
|
wsdlUri: string;
|
|
161
193
|
serviceName?: string;
|
|
162
194
|
wsdlDocs?: CompiledWsdlDocs;
|
|
195
|
+
diagnostics?: CompiledDiagnostics;
|
|
163
196
|
};
|
|
164
197
|
/**
|
|
165
198
|
* Compile a WSDL catalog into an internal representation (CompiledCatalog).
|
|
@@ -171,5 +204,5 @@ export type CompiledCatalog = {
|
|
|
171
204
|
* 4. Extract WSDL operations: pick the appropriate SOAP binding (v1.1 or v1.2), resolve its
|
|
172
205
|
* portType reference, then enumerate operations and their soapAction URIs.
|
|
173
206
|
*/
|
|
174
|
-
export declare function compileCatalog(cat: WsdlCatalog, options: CompilerOptions): CompiledCatalog;
|
|
207
|
+
export declare function compileCatalog(cat: WsdlCatalog, options: CompilerOptions, streamConfig?: StreamConfig): CompiledCatalog;
|
|
175
208
|
//# sourceMappingURL=schemaCompiler.d.ts.map
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"schemaCompiler.d.ts","sourceRoot":"","sources":["../../src/compiler/schemaCompiler.ts"],"names":[],"mappings":"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"}
|