@techspokes/typescript-wsdl-client 0.18.0 → 0.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/app/generateApp.d.ts +1 -0
- package/dist/app/generateApp.d.ts.map +1 -1
- package/dist/app/generateApp.js +73 -6
- package/dist/cli.js +12 -2
- package/dist/gateway/helpers.js +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/openapi/casing.d.ts +0 -14
- package/dist/openapi/casing.d.ts.map +1 -1
- package/dist/openapi/casing.js +3 -3
- package/dist/openapi/generateOpenAPI.d.ts.map +1 -1
- package/dist/openapi/generateOpenAPI.js +3 -0
- package/dist/openapi/security.d.ts +1 -81
- package/dist/openapi/security.d.ts.map +1 -1
- package/dist/openapi/security.js +1 -146
- package/dist/pipeline.d.ts +1 -0
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +1 -0
- package/dist/test/generateTests.js +2 -2
- package/dist/util/builder.js +1 -1
- package/dist/util/runtimeSource.d.ts +1 -0
- package/dist/util/runtimeSource.d.ts.map +1 -1
- package/dist/util/runtimeSource.js +4 -0
- package/dist/util/securityConfig.d.ts +115 -0
- package/dist/util/securityConfig.d.ts.map +1 -0
- package/dist/util/securityConfig.js +274 -0
- package/dist/util/tools.d.ts +8 -0
- package/dist/util/tools.d.ts.map +1 -1
- package/dist/util/tools.js +16 -0
- package/docs/README.md +2 -2
- package/docs/api-reference.md +28 -4
- package/docs/architecture.md +1 -1
- package/docs/cli-reference.md +4 -1
- package/docs/configuration.md +33 -18
- package/docs/gateway-guide.md +8 -8
- package/docs/generated-code.md +7 -0
- package/docs/migration-playbook.md +14 -5
- package/docs/troubleshooting.md +1 -1
- package/package.json +1 -1
- package/src/runtime/appSecurity.tpl.txt +108 -0
package/docs/gateway-guide.md
CHANGED
|
@@ -122,13 +122,13 @@ terminating zero-chunk.
|
|
|
122
122
|
|
|
123
123
|
The centralized error handler (runtime.ts) automatically classifies errors:
|
|
124
124
|
|
|
125
|
-
| Error Type
|
|
126
|
-
|
|
127
|
-
| Validation errors
|
|
128
|
-
| SOAP faults
|
|
129
|
-
| Connection refused | 503
|
|
130
|
-
| Timeout
|
|
131
|
-
| Other errors
|
|
125
|
+
| Error Type | HTTP Status | Error Code |
|
|
126
|
+
|--------------------|-------------|---------------------|
|
|
127
|
+
| Validation errors | 400 | VALIDATION_ERROR |
|
|
128
|
+
| SOAP faults | 502 | SOAP_FAULT |
|
|
129
|
+
| Connection refused | 503 | SERVICE_UNAVAILABLE |
|
|
130
|
+
| Timeout | 504 | GATEWAY_TIMEOUT |
|
|
131
|
+
| Other errors | 500 | INTERNAL_ERROR |
|
|
132
132
|
|
|
133
133
|
All errors are wrapped in the standard envelope format. See [Concepts](concepts.md) for the envelope structure.
|
|
134
134
|
|
|
@@ -186,7 +186,7 @@ await app.register(async (scope) => {
|
|
|
186
186
|
await app.listen({ port: 3000 });
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
See [`examples/fastify-gateway
|
|
189
|
+
See [`examples/fastify-gateway`](../examples/fastify-gateway/README.md) for a complete example.
|
|
190
190
|
|
|
191
191
|
## Contract Assumptions
|
|
192
192
|
|
package/docs/generated-code.md
CHANGED
|
@@ -18,6 +18,13 @@ const client = new Weather({
|
|
|
18
18
|
|
|
19
19
|
The `source` parameter accepts a URL or local file path to the WSDL.
|
|
20
20
|
|
|
21
|
+
When generating a runnable app with a security config, the scaffold can create
|
|
22
|
+
`security.ts` to build `soap.IOptions` and `soap.ISecurity` from environment
|
|
23
|
+
variables. The generated helper supports common `node-soap` profiles such as
|
|
24
|
+
Basic auth, bearer auth, WS-Security UsernameToken, TLS client certificates,
|
|
25
|
+
X509 signing, and NTLM. Secrets are read at runtime and are not embedded in
|
|
26
|
+
generated source.
|
|
27
|
+
|
|
21
28
|
## Calling Operations
|
|
22
29
|
|
|
23
30
|
```typescript
|
|
@@ -126,9 +126,16 @@ Create a security configuration file to add authentication to the OpenAPI spec a
|
|
|
126
126
|
|
|
127
127
|
```json
|
|
128
128
|
{
|
|
129
|
-
"
|
|
130
|
-
"
|
|
131
|
-
|
|
129
|
+
"gateway": {
|
|
130
|
+
"global": {
|
|
131
|
+
"scheme": "bearer",
|
|
132
|
+
"bearer": { "bearerFormat": "JWT" }
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"upstream": {
|
|
136
|
+
"profile": "ws-security-username-token",
|
|
137
|
+
"usernameEnv": "SOAP_USERNAME",
|
|
138
|
+
"passwordEnv": "SOAP_PASSWORD"
|
|
132
139
|
}
|
|
133
140
|
}
|
|
134
141
|
```
|
|
@@ -142,11 +149,13 @@ npx wsdl-tsc pipeline \
|
|
|
142
149
|
...
|
|
143
150
|
```
|
|
144
151
|
|
|
145
|
-
See [Configuration](configuration.md) for all options including per-operation overrides and
|
|
152
|
+
See [Configuration](configuration.md) for all options including per-operation overrides, custom headers, and upstream SOAP security profiles.
|
|
146
153
|
|
|
147
154
|
### Custom middleware
|
|
148
155
|
|
|
149
|
-
Add middleware in your application code, not in the generated gateway files. The generated app scaffold (`
|
|
156
|
+
Add middleware in your application code, not in the generated gateway files. The generated app scaffold (`server.ts`) is the right place for auth verification, logging, CORS, and other cross-cutting concerns.
|
|
157
|
+
|
|
158
|
+
The security config describes gateway authentication in OpenAPI and can scaffold upstream SOAP credentials for `node-soap`. It does not validate JWTs, OAuth tokens, or API keys for inbound REST requests. Use Fastify hooks, platform middleware, or your API gateway for that enforcement.
|
|
150
159
|
|
|
151
160
|
```typescript
|
|
152
161
|
import Fastify from "fastify";
|
package/docs/troubleshooting.md
CHANGED
|
@@ -12,7 +12,7 @@ See [README](../README.md) for quick start and [CLI Reference](cli-reference.md)
|
|
|
12
12
|
| Unresolved type references | Re-run with --client-fail-on-unresolved=false to inspect partial graph |
|
|
13
13
|
| Missing schema in OpenAPI | Ensure the global element exists (catalog shows compiled symbols) |
|
|
14
14
|
| Wrong array modeling | Check maxOccurs in WSDL; tool only arrays when maxOccurs>1 or unbounded |
|
|
15
|
-
| Authentication errors | Provide proper soap.ISecurity instance
|
|
15
|
+
| Authentication errors | Provide proper upstream security config or `soap.ISecurity` instance |
|
|
16
16
|
| Date/time confusion | Use --client-date-as Date for runtime Date objects |
|
|
17
17
|
| TypeScript compilation errors | Check --import-extensions matches your tsconfig moduleResolution |
|
|
18
18
|
| Gateway validation failures | Ensure OpenAPI has valid $ref paths and all schemas in components.schemas |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techspokes/typescript-wsdl-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.2",
|
|
4
4
|
"description": "Turn legacy WSDL/SOAP services into typed TypeScript clients, OpenAPI 3.1 specs, and production-ready Fastify REST gateways. Built for enterprise SOAP modernization.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wsdl",
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upstream SOAP Security
|
|
3
|
+
*
|
|
4
|
+
* Builds node-soap runtime options from environment variables referenced by
|
|
5
|
+
* the generation-time security config. Secrets are intentionally read at
|
|
6
|
+
* runtime and are never embedded in generated source.
|
|
7
|
+
*
|
|
8
|
+
* Scaffolded by wsdl-tsc. Customize freely.
|
|
9
|
+
*/
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import soap from "soap";
|
|
12
|
+
|
|
13
|
+
const upstream: any = __UPSTREAM_JSON__;
|
|
14
|
+
|
|
15
|
+
export interface SoapRuntimeConfig {
|
|
16
|
+
options?: soap.IOptions;
|
|
17
|
+
security?: soap.ISecurity;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function buildSoapRuntimeConfig(): SoapRuntimeConfig {
|
|
21
|
+
const options: soap.IOptions = {};
|
|
22
|
+
const wsdlHeaders = buildHeaders(upstream.wsdlHeaders, upstream.wsdlHeaderEnv);
|
|
23
|
+
if (Object.keys(wsdlHeaders).length) {
|
|
24
|
+
options.wsdl_headers = wsdlHeaders;
|
|
25
|
+
}
|
|
26
|
+
const requestHeaders = buildHeaders(upstream.requestHeaders, upstream.requestHeaderEnv);
|
|
27
|
+
if (Object.keys(requestHeaders).length) {
|
|
28
|
+
options.extraHeaders = requestHeaders;
|
|
29
|
+
}
|
|
30
|
+
if (upstream.endpointEnv) {
|
|
31
|
+
const endpoint = process.env[upstream.endpointEnv];
|
|
32
|
+
if (endpoint) options.endpoint = endpoint;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const security = buildSoapSecurity();
|
|
36
|
+
return {
|
|
37
|
+
...(Object.keys(options).length ? { options } : {}),
|
|
38
|
+
...(security ? { security } : {}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function buildSoapSecurity(): soap.ISecurity | undefined {
|
|
43
|
+
const soapRuntime = soap as any;
|
|
44
|
+
switch (upstream.profile ?? "none") {
|
|
45
|
+
case "none":
|
|
46
|
+
return undefined;
|
|
47
|
+
case "basic":
|
|
48
|
+
return new soapRuntime.BasicAuthSecurity(requiredEnv(upstream.usernameEnv, "upstream.usernameEnv"), requiredEnv(upstream.passwordEnv, "upstream.passwordEnv"));
|
|
49
|
+
case "bearer":
|
|
50
|
+
return new soapRuntime.BearerSecurity(requiredEnv(upstream.tokenEnv, "upstream.tokenEnv"));
|
|
51
|
+
case "ws-security-username-token":
|
|
52
|
+
return new soapRuntime.WSSecurity(
|
|
53
|
+
requiredEnv(upstream.usernameEnv, "upstream.usernameEnv"),
|
|
54
|
+
requiredEnv(upstream.passwordEnv, "upstream.passwordEnv"),
|
|
55
|
+
upstream.wsSecurity ?? {},
|
|
56
|
+
);
|
|
57
|
+
case "ntlm":
|
|
58
|
+
return new soapRuntime.NTLMSecurity({
|
|
59
|
+
username: requiredEnv(upstream.usernameEnv, "upstream.usernameEnv"),
|
|
60
|
+
password: requiredEnv(upstream.passwordEnv, "upstream.passwordEnv"),
|
|
61
|
+
domain: envValue(upstream.domainEnv),
|
|
62
|
+
workstation: envValue(upstream.workstationEnv),
|
|
63
|
+
});
|
|
64
|
+
case "client-ssl":
|
|
65
|
+
return new soapRuntime.ClientSSLSecurity(
|
|
66
|
+
readFileFromEnv(upstream.keyFileEnv, "upstream.keyFileEnv"),
|
|
67
|
+
readFileFromEnv(upstream.certFileEnv, "upstream.certFileEnv"),
|
|
68
|
+
upstream.caFileEnv ? readFileFromEnv(upstream.caFileEnv, "upstream.caFileEnv") : undefined,
|
|
69
|
+
);
|
|
70
|
+
case "client-ssl-pfx":
|
|
71
|
+
return new soapRuntime.ClientSSLSecurityPFX(
|
|
72
|
+
readFileFromEnv(upstream.pfxFileEnv, "upstream.pfxFileEnv"),
|
|
73
|
+
envValue(upstream.passphraseEnv),
|
|
74
|
+
);
|
|
75
|
+
case "x509":
|
|
76
|
+
return new soapRuntime.WSSecurityCert(
|
|
77
|
+
readFileFromEnv(upstream.keyFileEnv, "upstream.keyFileEnv"),
|
|
78
|
+
readFileFromEnv(upstream.certFileEnv, "upstream.certFileEnv"),
|
|
79
|
+
envValue(upstream.passphraseEnv) ?? "",
|
|
80
|
+
);
|
|
81
|
+
case "custom":
|
|
82
|
+
throw new Error("upstream.profile=custom requires editing security.ts to return a soap.ISecurity implementation.");
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function buildHeaders(staticHeaders?: Record<string, string>, envHeaders?: Record<string, string>): Record<string, string> {
|
|
87
|
+
const headers: Record<string, string> = {...(staticHeaders ?? {})};
|
|
88
|
+
for (const [headerName, envName] of Object.entries(envHeaders ?? {})) {
|
|
89
|
+
const value = process.env[envName];
|
|
90
|
+
if (value) headers[headerName] = value;
|
|
91
|
+
}
|
|
92
|
+
return headers;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function requiredEnv(envName: string | undefined, label: string): string {
|
|
96
|
+
if (!envName) throw new Error(`${label} must name an environment variable.`);
|
|
97
|
+
const value = process.env[envName];
|
|
98
|
+
if (!value) throw new Error(`${envName} environment variable is required for upstream SOAP security.`);
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function envValue(envName: string | undefined): string | undefined {
|
|
103
|
+
return envName ? process.env[envName] : undefined;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function readFileFromEnv(envName: string | undefined, label: string): Buffer {
|
|
107
|
+
return fs.readFileSync(requiredEnv(envName, label));
|
|
108
|
+
}
|