@techspokes/typescript-wsdl-client 0.9.2 → 0.9.4

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 (2) hide show
  1. package/README.md +727 -323
  2. package/package.json +13 -12
package/README.md CHANGED
@@ -9,58 +9,46 @@
9
9
  [![TechSpokes Org](https://img.shields.io/badge/org-techspokes-181717?logo=github)](https://github.com/techspokes)
10
10
  [![Sponsor](https://img.shields.io/badge/sponsor-GitHub-blue?logo=github-sponsors)](https://github.com/sponsors/TechSpokes)
11
11
 
12
- > **Mission**: Transform complex WSDL/XSD definitions into ergonomic, type-safe TypeScript SOAP clients with optional OpenAPI 3.1 specs and production-ready Fastify REST gateways — enabling confident integration with legacy enterprise services.
12
+ > **Transform complex WSDL/XSD definitions into type-safe TypeScript SOAP clients with optional OpenAPI 3.1 specs and production-ready REST gateways.**
13
13
 
14
- ---
14
+ ## Use This If You Need...
15
15
 
16
- ## Table of Contents
16
+ - **TypeScript-first SOAP clients** — Strongly typed, ergonomic client generation from WSDL
17
+ - ✅ **OpenAPI 3.1 specs** — Generate REST API documentation that mirrors your TypeScript types
18
+ - ✅ **REST gateway over SOAP** — Production-ready Fastify handlers with automatic request/response transformation
19
+ - ✅ **CI-friendly determinism** — Stable, diff-friendly output for safe regeneration in version control
20
+ - ✅ **Predictable modeling** — Flattened attributes, consistent `$value` convention, inheritance resolution
17
21
 
18
- - [1. Why This Project](#1-why-this-project-what-sets-it-apart)
19
- - [2. Installation](#2-installation)
20
- - [3. Quick Start](#3-quick-start)
21
- - [4. Commands Overview](#4-commands-overview)
22
- - [5. Command: `compile`](#5-command-compile)
23
- - [6. Command: `client`](#6-command-client)
24
- - [7. Command: `openapi`](#7-command-openapi)
25
- - [8. Command: `gateway`](#8-command-gateway)
26
- - [9. Command: `app`](#9-command-app)
27
- - [10. Command: `pipeline`](#10-command-pipeline)
28
- - [11. Working With Generated Clients](#11-working-with-generated-clients)
29
- - [12. OpenAPI Configuration](#12-openapi-configuration)
30
- - [13. Programmatic API](#13-programmatic-api)
31
- - [14. Advanced Topics](#14-advanced-topics)
32
- - [15. Troubleshooting](#15-troubleshooting)
33
- - [16. Contributing](#16-contributing)
34
- - [17. License](#17-license)
35
- - [18. Sponsors](#18-sponsors)
22
+ **Vendor**: [TechSpokes](https://www.techspokes.com) · **Maintainer**: Serge Liatko ([@sergeliatko](https://github.com/sergeliatko))
36
23
 
37
24
  ---
38
25
 
39
- ## 1. Why This Project (What Sets It Apart)
40
-
41
- Most WSDL generators produce loosely typed stubs or expose raw XML complexity to your application layer. This tool delivers **correct flattening, determinism, and multiple integration paths**:
42
-
43
- | Core Differentiator | What You Get |
44
- |--------------------------------------|------------------------------------------------------------------------------------------------------|
45
- | **Attribute + Element Flattening** | Attributes and child elements appear as peer properties (no nested wrapper noise). |
46
- | **`$value` Text Content Convention** | Simple text & mixed content always represented as a `$value` property (collision-safe & documented). |
47
- | **Inheritance Resolution** | `complexContent` and `simpleContent` extensions are merged or extended consistently. |
48
- | **Choice Strategy** | Predictable `all-optional` modeling today (future advanced discriminators planned). |
49
- | **WS-Policy Security Hints** | Inline scan of policies surfaces required auth hints (e.g. `usernameToken`, `https`). |
50
- | **Deterministic Output** | Sorted declarations and stable alias resolution for diff-friendly regeneration. |
51
- | **Primitive Mapping Controls** | Explicit flags for long / big integer / decimal / temporal families (string-first safety). |
52
- | **Catalog Introspection** | One JSON artifact (`catalog.json`) to drive further tooling (including OpenAPI & gateway). |
53
- | **OpenAPI 3.1 Bridge** | Mirrors the exact TypeScript model with no divergence between runtime and spec. |
54
- | **Standard Response Envelope** | Always-on, debuggable envelope structure (status, message, data, error) for REST gateways. |
55
- | **Fastify Gateway Generation** | Production-ready route handlers with SOAP client integration and standardized envelope responses. |
56
- | **Multi-format Output** | `--openapi-format json\|yaml\|both` with always-on validation (unless disabled). |
57
- | **One-Shot Pipeline** | Single pass (parse to TS to OpenAPI to Gateway) for CI & automation. |
26
+ ## Table of Contents
58
27
 
59
- **Vendor**: [TechSpokes](https://www.techspokes.com) · **Maintainer**: Serge Liatko ([@sergeliatko](https://github.com/sergeliatko))
28
+ - [Installation](#installation)
29
+ - [Quick Start (60 Seconds)](#quick-start-60-seconds)
30
+ - [What You Get (Outputs)](#what-you-get-outputs)
31
+ - [Core Concepts](#core-concepts)
32
+ - [Common Workflows](#common-workflows)
33
+ - [Command Reference](#command-reference)
34
+ - [pipeline (Recommended)](#command-pipeline-recommended)
35
+ - [client](#command-client)
36
+ - [openapi](#command-openapi)
37
+ - [gateway](#command-gateway)
38
+ - [app](#command-app)
39
+ - [compile (Advanced)](#command-compile-advanced)
40
+ - [Configuration Files](#configuration-files)
41
+ - [Working With Generated Clients](#working-with-generated-clients)
42
+ - [Production Concerns](#production-concerns)
43
+ - [Programmatic API](#programmatic-api)
44
+ - [Troubleshooting](#troubleshooting)
45
+ - [Contributing](#contributing)
46
+ - [License](#license)
47
+ - [Support](#support)
60
48
 
61
49
  ---
62
50
 
63
- ## 2. Installation
51
+ ## Installation
64
52
 
65
53
  ```bash
66
54
  npm install --save-dev @techspokes/typescript-wsdl-client
@@ -73,203 +61,557 @@ npm install soap # Runtime dependency for SOAP calls
73
61
 
74
62
  ---
75
63
 
76
- ## 3. Quick Start
64
+ ## Quick Start (60 Seconds)
77
65
 
78
- ### Generate TypeScript SOAP Client
66
+ Generate a complete SOAP-to-REST stack in one command:
79
67
 
80
68
  ```bash
81
- npx wsdl-tsc client --wsdl-source ./wsdl/Weather.wsdl --client-dir ./src/services/weather
69
+ # Generate client, OpenAPI spec, gateway, and runnable app
70
+ npx wsdl-tsc pipeline \
71
+ --wsdl-source examples/minimal/weather.wsdl \
72
+ --client-dir ./tmp/client \
73
+ --openapi-file ./tmp/openapi.json \
74
+ --gateway-dir ./tmp/gateway \
75
+ --gateway-service-name weather \
76
+ --gateway-version-prefix v1 \
77
+ --generate-app
82
78
  ```
83
79
 
84
- **Try with included example:**
80
+ **Start the server:**
85
81
 
86
82
  ```bash
87
- npx wsdl-tsc client --wsdl-source examples/minimal/weather.wsdl --client-dir ./tmp/weather
83
+ cd tmp/app
84
+ cp .env.example .env
85
+ # Edit .env to set WSDL_SOURCE if needed
86
+ npx tsx server.js
87
+ ```
88
+
89
+ **Test it:**
90
+
91
+ ```bash
92
+ # Health check
93
+ curl http://localhost:3000/health
94
+
95
+ # Get OpenAPI spec
96
+ curl http://localhost:3000/openapi.json | jq .
97
+
98
+ # Call a SOAP operation via REST
99
+ curl -X POST http://localhost:3000/get-weather-information \
100
+ -H "Content-Type: application/json" \
101
+ -d '{}'
102
+ ```
103
+
104
+ **What just happened?**
105
+ 1. Parsed the WSDL and compiled types
106
+ 2. Generated a TypeScript SOAP client with full type safety
107
+ 3. Created an OpenAPI 3.1 spec matching the client types
108
+ 4. Built Fastify gateway handlers that call SOAP and return JSON
109
+ 5. Created a runnable Express-style app with health/OpenAPI endpoints
110
+
111
+ ---
112
+
113
+ ## What You Get (Outputs)
114
+
115
+ ### TypeScript SOAP Client
116
+
117
+ ```
118
+ client/
119
+ ├── client.ts # Strongly-typed SOAP client wrapper with methods
120
+ ├── types.ts # Flattened interfaces, type aliases, and enums
121
+ ├── utils.ts # Runtime metadata for JSON→SOAP conversion
122
+ └── catalog.json # Compiled schema representation (reusable)
123
+ ```
124
+
125
+ **Example usage:**
126
+
127
+ ```typescript
128
+ import { Weather } from './client/client.js';
129
+
130
+ const client = new Weather({
131
+ source: 'https://example.com/weather.wsdl',
132
+ });
133
+
134
+ const result = await client.GetCityWeatherByZIP({ ZIP: '10001' });
135
+ console.log(result.GetCityWeatherByZIPResult);
136
+ ```
137
+
138
+ ### OpenAPI 3.1 Specification
139
+
140
+ ```
141
+ openapi.json # or .yaml — Complete REST API documentation
142
+ ```
143
+
144
+ - Mirrors exact TypeScript type structure
145
+ - All responses wrapped in standard envelope (status, message, data, error)
146
+ - Deterministic ordering for version control
147
+ - Validates with `swagger-parser` by default
148
+
149
+ ### Fastify REST Gateway
150
+
151
+ ```
152
+ gateway/
153
+ ├── schemas/
154
+ │ ├── models/ # JSON Schema components with URN IDs
155
+ │ └── operations/ # Request/response validation schemas
156
+ ├── routes/ # Route handlers (fully implemented)
157
+ ├── schemas.ts # Schema registration module
158
+ ├── routes.ts # Route aggregator
159
+ ├── runtime.ts # Envelope builders, error handlers
160
+ └── plugin.ts # Fastify plugin wrapper
161
+ ```
162
+
163
+ **Example integration:**
164
+
165
+ ```typescript
166
+ import Fastify from 'fastify';
167
+ import weatherGateway from './gateway/plugin.js';
168
+ import { Weather } from './client/client.js';
169
+
170
+ const app = Fastify({ logger: true });
171
+ const client = new Weather({ source: 'weather.wsdl' });
172
+
173
+ await app.register(weatherGateway, { client });
174
+ await app.listen({ port: 3000 });
175
+ ```
176
+
177
+ ### Runnable Application
178
+
179
+ ```
180
+ app/
181
+ ├── server.js # Main entry point
182
+ ├── config.js # Configuration with env var support
183
+ ├── .env.example # Environment template
184
+ ├── README.md # Usage instructions
185
+ └── openapi.json # OpenAPI spec (when --openapi-mode=copy)
186
+ ```
187
+
188
+ ### Standard Response Envelope
189
+
190
+ All gateway responses follow this structure:
191
+
192
+ **Success:**
193
+ ```json
194
+ {
195
+ "status": "SUCCESS",
196
+ "message": null,
197
+ "data": { /* SOAP response */ },
198
+ "error": null
199
+ }
200
+ ```
201
+
202
+ **Error:**
203
+ ```json
204
+ {
205
+ "status": "ERROR",
206
+ "message": "Request validation failed",
207
+ "data": null,
208
+ "error": {
209
+ "code": "VALIDATION_ERROR",
210
+ "message": "Request validation failed",
211
+ "details": { /* validation errors */ }
212
+ }
213
+ }
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Core Concepts
219
+
220
+ ### Flattening and `$value`
221
+
222
+ **Attributes and elements become peer properties** — No nested wrapper noise:
223
+
224
+ ```xml
225
+ <!-- WSDL -->
226
+ <xs:complexType name="Price">
227
+ <xs:simpleContent>
228
+ <xs:extension base="xs:decimal">
229
+ <xs:attribute name="currency" type="xs:string"/>
230
+ </xs:extension>
231
+ </xs:simpleContent>
232
+ </xs:complexType>
88
233
  ```
89
234
 
90
- ### Generate Everything (Pipeline)
235
+ ```typescript
236
+ // Generated TypeScript
237
+ interface Price {
238
+ currency?: string; // attribute
239
+ $value: string; // text content (decimal mapped to string by default)
240
+ }
241
+ ```
242
+
243
+ ### Primitive Mapping Defaults (String-First Safety)
244
+
245
+ Prevents precision loss and parsing errors at the cost of convenience:
246
+
247
+ | XSD Type | Default | Override Options | When to Override |
248
+ |---------------|----------|--------------------|----------------------------------------|
249
+ | `xs:long` | `string` | `number`, `bigint` | Use `number` if values fit JS range |
250
+ | `xs:integer` | `string` | `number` | Use `string` for arbitrary-size ints |
251
+ | `xs:decimal` | `string` | `number` | Use `string` for precise decimals |
252
+ | `xs:dateTime` | `string` | `Date` | Use `Date` if runtime parsing is okay |
253
+
254
+ **Override with flags:**
255
+ - `--client-int64-as number`
256
+ - `--client-decimal-as string`
257
+ - `--client-date-as Date`
258
+
259
+ ### Deterministic Generation
260
+
261
+ All output is **stable and diff-friendly** for CI/CD:
262
+
263
+ - ✅ Sorted type declarations
264
+ - ✅ Sorted OpenAPI paths, schemas, parameters
265
+ - ✅ Sorted JSON schema keys
266
+ - ✅ Stable alias resolution
267
+ - ✅ Consistent ordering of imports
268
+
269
+ Regenerate safely without spurious diffs in version control.
270
+
271
+ ### Catalog as Intermediate Artifact
272
+
273
+ `catalog.json` is the compiled representation of your WSDL:
274
+
275
+ - **Debuggable** — Inspect types, operations, and metadata as JSON
276
+ - **Cacheable** — Reuse across client/OpenAPI/gateway generation
277
+ - **Co-located** — Automatically placed alongside generated output
278
+
279
+ **Common locations:**
280
+ - `client` command: `{client-dir}/catalog.json`
281
+ - `openapi` command: `{openapi-dir}/catalog.json`
282
+ - `pipeline` command: First available output directory
283
+
284
+ ---
285
+
286
+ ## Common Workflows
287
+
288
+ ### Which Command Should I Run?
289
+
290
+ | I Want... | Use Command | Example |
291
+ |-----------------------------------------------|--------------|----------------------------------------------------------------------------------------------------------------------|
292
+ | **Everything (client + OpenAPI + gateway)** | `pipeline` | `npx wsdl-tsc pipeline --wsdl-source service.wsdl --client-dir ./client --openapi-file ./api.json --gateway-dir ./gateway --gateway-service-name svc --gateway-version-prefix v1` |
293
+ | **Only a TypeScript SOAP client** | `client` | `npx wsdl-tsc client --wsdl-source service.wsdl --client-dir ./client` |
294
+ | **Only OpenAPI spec (for docs or SDKs)** | `openapi` | `npx wsdl-tsc openapi --wsdl-source service.wsdl --openapi-file ./api.json` |
295
+ | **Only REST gateway (have OpenAPI already)** | `gateway` | `npx wsdl-tsc gateway --openapi-file ./api.json --client-dir ./client --gateway-dir ./gateway --gateway-service-name svc --gateway-version-prefix v1` |
296
+ | **Runnable server for testing** | `app` | `npx wsdl-tsc app --client-dir ./client --gateway-dir ./gateway --openapi-file ./api.json` |
297
+ | **Debug/inspect WSDL compilation** | `compile` | `npx wsdl-tsc compile --wsdl-source service.wsdl --catalog-file ./catalog.json` |
298
+
299
+ ### Workflow 1: Generate Everything (Recommended)
300
+
301
+ Use `pipeline` for complete stack generation:
91
302
 
92
303
  ```bash
93
304
  npx wsdl-tsc pipeline \
94
305
  --wsdl-source examples/minimal/weather.wsdl \
95
- --client-dir ./tmp/client \
96
- --openapi-file ./tmp/openapi.json \
97
- --gateway-dir ./tmp/gateway \
306
+ --client-dir ./src/services/weather \
307
+ --openapi-file ./docs/weather-api.json \
308
+ --gateway-dir ./src/gateway/weather \
98
309
  --gateway-service-name weather \
99
310
  --gateway-version-prefix v1
100
311
  ```
101
312
 
102
- **Output**: Generates client files in `tmp/client/`, OpenAPI spec at `tmp/openapi.json`, gateway code in `tmp/gateway/`, and catalog at `tmp/client/catalog.json`.
313
+ **Output:**
314
+ - Client: `./src/services/weather/client.ts`, `types.ts`, `utils.ts`, `catalog.json`
315
+ - OpenAPI: `./docs/weather-api.json`
316
+ - Gateway: `./src/gateway/weather/` (routes, schemas, plugin)
103
317
 
104
- ---
318
+ ### Workflow 2: SOAP Client Only
105
319
 
106
- ## 4. Commands Overview
320
+ Generate TypeScript client for direct SOAP integration:
107
321
 
108
- The tool provides **six commands** for different integration scenarios:
322
+ ```bash
323
+ npx wsdl-tsc client \
324
+ --wsdl-source ./wsdl/Hotel.wsdl \
325
+ --client-dir ./src/services/hotel
326
+ ```
109
327
 
110
- | Command | Purpose | Typical Use Case |
111
- |------------|----------------------------------------------------------------|-----------------------------------------------|
112
- | `compile` | Parse WSDL and emit `catalog.json` only | Debugging, inspection, or multi-stage builds |
113
- | `client` | Generate TypeScript SOAP client from WSDL or catalog | Standard SOAP integration (most common) |
114
- | `openapi` | Generate OpenAPI 3.1 spec from WSDL or catalog | Documentation, REST proxies, API gateways |
115
- | `gateway` | Generate Fastify gateway with full handlers from OpenAPI spec | Production REST gateway with SOAP integration |
116
- | `app` | Generate runnable Fastify app from client + gateway + OpenAPI | Local testing, quick iteration, demos |
117
- | `pipeline` | Run full pipeline: client + OpenAPI + gateway (+ app optional) | CI/CD automation, complete stack generation |
328
+ **Usage:**
118
329
 
119
- ---
330
+ ```typescript
331
+ import soap from 'soap';
332
+ import { Hotel } from './src/services/hotel/client.js';
120
333
 
121
- ## 5. Command: `compile`
334
+ const client = new Hotel({
335
+ source: 'https://example.com/hotel.wsdl',
336
+ security: new soap.WSSecurity('username', 'password'),
337
+ });
122
338
 
123
- **Purpose**: Parse WSDL and generate only the intermediate `catalog.json` representation without TypeScript client code.
339
+ const result = await client.SearchAvailableRooms({
340
+ checkIn: '2024-01-15',
341
+ checkOut: '2024-01-20',
342
+ guests: 2,
343
+ });
344
+ ```
124
345
 
125
- **When to use**:
126
- - Multi-stage builds where you want to cache the parsed WSDL
127
- - Debugging or inspecting the compiled schema structure
128
- - Sharing a compiled catalog across multiple generation targets
346
+ ### Workflow 3: OpenAPI for Documentation
129
347
 
130
- ### Usage
348
+ Generate OpenAPI spec for API documentation or SDK generation:
131
349
 
132
350
  ```bash
133
- npx wsdl-tsc compile --wsdl-source <file|url> --catalog-file <path> [options]
351
+ npx wsdl-tsc openapi \
352
+ --wsdl-source ./wsdl/Booking.wsdl \
353
+ --openapi-file ./docs/booking-api.yaml \
354
+ --openapi-format yaml \
355
+ --openapi-title "Hotel Booking API" \
356
+ --openapi-version "1.0.0" \
357
+ --openapi-servers https://api.example.com/v1
134
358
  ```
135
359
 
136
- ### Required Flags
360
+ **Use the spec:**
361
+ - Import into Postman, Insomnia, or Swagger UI
362
+ - Generate client SDKs with OpenAPI Generator
363
+ - Share as REST API documentation
137
364
 
138
- | Flag | Description |
139
- |---------------------|------------------------------------------|
140
- | `--wsdl-source` | Path or URL to the WSDL file |
141
- | `--catalog-file` | Output path for `catalog.json` |
365
+ ### Workflow 4: REST Gateway Over SOAP
142
366
 
143
- ### Optional Flags
367
+ Build a REST API layer over legacy SOAP services:
144
368
 
145
- | Flag | Default | Description |
146
- |------------------------------------|----------------|--------------------------------------------------------------|
147
- | `--import-extensions` | `js` | Import specifier style: `js`, `ts`, or `bare` |
148
- | `--client-attributes-key` | `$attributes` | Attribute bag key for runtime mapper |
149
- | `--client-class-name` | (derived) | Override generated client class name |
150
- | `--client-int64-as` | `string` | Map 64-bit integers: `string`, `number`, or `bigint` |
151
- | `--client-bigint-as` | `string` | Map arbitrary-size integers: `string` or `number` |
152
- | `--client-decimal-as` | `string` | Map `xs:decimal`: `string` or `number` |
153
- | `--client-date-as` | `string` | Map date/time types: `string` or `Date` |
154
- | `--client-choice-mode` | `all-optional` | Choice element strategy: `all-optional` or `union` |
155
- | `--client-fail-on-unresolved` | `false` | Fail build on unresolved type references |
156
- | `--client-nillable-as-optional` | `false` | Treat nillable elements as optional properties |
369
+ ```bash
370
+ # 1. Generate client + OpenAPI
371
+ npx wsdl-tsc pipeline \
372
+ --wsdl-source ./wsdl/Legacy.wsdl \
373
+ --client-dir ./src/services/legacy \
374
+ --openapi-file ./docs/legacy-api.json
157
375
 
158
- ### Examples
376
+ # 2. Generate gateway
377
+ npx wsdl-tsc gateway \
378
+ --openapi-file ./docs/legacy-api.json \
379
+ --client-dir ./src/services/legacy \
380
+ --gateway-dir ./src/gateway/legacy \
381
+ --gateway-service-name legacy \
382
+ --gateway-version-prefix v1
383
+ ```
159
384
 
160
- #### Basic Compilation
385
+ **Or in one command:**
161
386
 
162
387
  ```bash
163
- npx wsdl-tsc compile \
164
- --wsdl-source examples/minimal/weather.wsdl \
165
- --catalog-file tmp/catalog.json
388
+ npx wsdl-tsc pipeline \
389
+ --wsdl-source ./wsdl/Legacy.wsdl \
390
+ --client-dir ./src/services/legacy \
391
+ --openapi-file ./docs/legacy-api.json \
392
+ --gateway-dir ./src/gateway/legacy \
393
+ --gateway-service-name legacy \
394
+ --gateway-version-prefix v1
166
395
  ```
167
396
 
168
- #### With Custom Output Path
397
+ ### Workflow 5: CI/CD Integration
398
+
399
+ Cache compiled catalog for faster multi-stage builds:
169
400
 
170
401
  ```bash
402
+ # Stage 1: Compile catalog (cacheable)
171
403
  npx wsdl-tsc compile \
172
- --wsdl-source https://example.com/Hotel.wsdl \
173
- --catalog-file ./build/hotel-catalog.json \
174
- --client-int64-as number \
175
- --client-decimal-as string
404
+ --wsdl-source ./wsdl/Service.wsdl \
405
+ --catalog-file ./build/service-catalog.json
406
+
407
+ # Stage 2: Generate client from catalog
408
+ npx wsdl-tsc client \
409
+ --catalog-file ./build/service-catalog.json \
410
+ --client-dir ./src/services/service
411
+
412
+ # Stage 3: Generate OpenAPI from catalog
413
+ npx wsdl-tsc openapi \
414
+ --catalog-file ./build/service-catalog.json \
415
+ --openapi-file ./docs/service-api.json
176
416
  ```
177
417
 
178
- #### For Debugging
418
+ ### Workflow 6: Debugging Complex WSDL
419
+
420
+ Inspect compiled types and operations:
179
421
 
180
422
  ```bash
181
- # Compile to inspect types and operations
423
+ # Compile to catalog
182
424
  npx wsdl-tsc compile \
183
- --wsdl-source ./wsdl/ComplexService.wsdl \
184
- --catalog-file ./debug/catalog.json \
185
- --client-fail-on-unresolved false
425
+ --wsdl-source ./wsdl/Complex.wsdl \
426
+ --catalog-file ./debug/catalog.json
427
+
428
+ # Inspect types
429
+ cat ./debug/catalog.json | jq '.types'
430
+
431
+ # Inspect operations
432
+ cat ./debug/catalog.json | jq '.operations'
186
433
  ```
187
434
 
188
- ### Output
435
+ ---
189
436
 
190
- - `catalog.json` - Compiled schema representation including types, operations, and metadata
437
+ ## Command Reference
191
438
 
192
- ### Catalog Structure
439
+ The tool provides **six commands** for different integration scenarios. Commands are listed in **recommended order of use**:
193
440
 
194
- The catalog.json file contains the compiled WSDL representation:
441
+ | Command | Purpose | Typical Use Case |
442
+ |------------|----------------------------------------------------------------|-----------------------------------------------|
443
+ | `pipeline` | Run full pipeline: client + OpenAPI + gateway (+ app optional) | **CI/CD automation, complete stack generation (recommended)** |
444
+ | `client` | Generate TypeScript SOAP client from WSDL or catalog | Standard SOAP integration |
445
+ | `openapi` | Generate OpenAPI 3.1 spec from WSDL or catalog | Documentation, REST proxies, API gateways |
446
+ | `gateway` | Generate Fastify gateway with full handlers from OpenAPI spec | Production REST gateway with SOAP integration |
447
+ | `app` | Generate runnable Fastify app from client + gateway + OpenAPI | Local testing, quick iteration, demos |
448
+ | `compile` | Parse WSDL and emit `catalog.json` only | Debugging, inspection, or multi-stage builds (advanced) |
195
449
 
196
- ```json
197
- {
198
- "wsdlUri": "path/to/service.wsdl",
199
- "targetNamespace": "http://example.com/service",
200
- "serviceName": "WeatherService",
201
- "types": [
202
- {
203
- "name": "GetWeatherRequest",
204
- "properties": []
205
- }
206
- ],
207
- "operations": [
208
- {
209
- "name": "GetWeather",
210
- "input": "GetWeatherRequest",
211
- "output": "GetWeatherResponse"
212
- }
213
- ],
214
- "options": {
215
- "imports": "js",
216
- "catalog": true
217
- }
218
- }
450
+ ---
451
+
452
+ ### Command: `pipeline` (Recommended)
453
+
454
+ **Purpose**: Run the complete generation pipeline in a single pass: WSDL parsing → TypeScript client → OpenAPI spec → Fastify gateway (+ app optional).
455
+
456
+ **When to use**:
457
+ - CI/CD automation
458
+ - Complete stack generation
459
+ - Ensuring all artifacts are generated from the same WSDL parse
460
+ - One-command development workflows
461
+
462
+ #### Usage
463
+
464
+ ```bash
465
+ npx wsdl-tsc pipeline \
466
+ --wsdl-source <file|url> \
467
+ [--catalog-file <path>] \
468
+ [--client-dir <path>] \
469
+ [--openapi-file <path>] \
470
+ [--gateway-dir <path>] \
471
+ [options]
219
472
  ```
220
473
 
221
- **Key sections**:
222
- - `types` - All compiled type definitions with properties and inheritance
223
- - `operations` - SOAP operations with input/output type references
224
- - `options` - Compiler options used during generation
474
+ #### Required Flags
225
475
 
226
- This catalog can be reused with the `client` and `openapi` commands via `--catalog-file`.
476
+ | Flag | Description |
477
+ |---------------------|----------------------------------------------------------------------|
478
+ | `--wsdl-source` | Path or URL to WSDL file |
227
479
 
228
- ### Catalog File Organization
480
+ #### Output Flags
229
481
 
230
- **Default behavior**: Catalog files are **co-located** with their primary output files for better organization and discoverability.
482
+ | Flag | Default | Description |
483
+ |---------------------|---------------------------------------------|---------------------------------------------------|
484
+ | `--catalog-file` | Co-located with first output (see below) | Output path for `catalog.json` (always generated) |
231
485
 
232
- **Catalog Location by Command**:
233
- - `compile`: Always requires explicit `--catalog-file` (no default)
234
- - `client`: Defaults to `{client-dir}/catalog.json`
235
- - `openapi`: Defaults to `{openapi-file-dir}/catalog.json`
236
- - `pipeline`: Intelligent cascade - first available: `{client-dir}` > `{openapi-dir}` > `{gateway-dir}` > `tmp/`
486
+ **Catalog Default Location**: The catalog is automatically placed alongside the first available output:
487
+ - With `--client-dir`: `{client-dir}/catalog.json`
488
+ - With `--openapi-file` only: `{openapi-file-dir}/catalog.json`
489
+ - With `--gateway-dir` only: `{gateway-dir}/catalog.json`
237
490
 
238
- **Common patterns**:
491
+ **Note**: At least one of `--client-dir`, `--openapi-file`, or `--gateway-dir` must be provided.
239
492
 
240
- 1. **Co-located with client** (recommended for most projects):
241
- ```bash
242
- npx wsdl-tsc client --wsdl-source service.wsdl --client-dir src/services/weather
243
- ```
244
-
245
- Creates `src/services/weather/catalog.json` automatically.
246
-
247
- Result:
248
- ```
249
- src/services/weather/
250
- ├── client.ts
251
- ├── types.ts
252
- ├── utils.ts
253
- └── catalog.json
254
- ```
493
+ #### Generation Control Flags
255
494
 
256
- 2. **Pipeline with multiple outputs** (catalog in client directory):
257
- ```bash
258
- npx wsdl-tsc pipeline --wsdl-source service.wsdl --client-dir src/client --openapi-file docs/api.json
259
- ```
260
-
261
- Creates `src/client/catalog.json` (co-located with client).
495
+ | Flag | Description |
496
+ |-------------------------|------------------------------------------------|
497
+ | `--client-dir` | Generate TypeScript client in this directory |
498
+ | `--openapi-file` | Generate OpenAPI spec at this path |
499
+ | `--gateway-dir` | Generate Fastify gateway in this directory |
500
+ | `--generate-app` | Generate runnable app (requires gateway) |
501
+
502
+ #### Optional Flags
503
+
504
+ All flags from `client`, `openapi`, and `gateway` commands are supported. Key flags:
505
+
506
+ **Client Flags:**
507
+ - `--import-extensions` (default: `js`)
508
+ - `--client-attributes-key` (default: `$attributes`)
509
+ - `--client-class-name`
510
+ - `--client-int64-as` (default: `string`)
511
+ - `--client-bigint-as` (default: `string`)
512
+ - `--client-decimal-as` (default: `string`)
513
+ - `--client-date-as` (default: `string`)
514
+ - `--client-choice-mode` (default: `all-optional`)
515
+ - `--client-fail-on-unresolved` (default: `false`)
516
+ - `--client-nillable-as-optional` (default: `false`)
517
+
518
+ **OpenAPI Flags:**
519
+ - `--openapi-format` (default: `json`)
520
+ - `--openapi-title`
521
+ - `--openapi-version` (default: `0.0.0`)
522
+ - `--openapi-description`
523
+ - `--openapi-servers` (default: `/`)
524
+ - `--openapi-base-path`
525
+ - `--openapi-path-style` (default: `kebab`)
526
+ - `--openapi-method` (default: `post`)
527
+ - `--openapi-tag-style` (default: `default`)
528
+ - `--openapi-closed-schemas` (default: `false`)
529
+ - `--openapi-prune-unused-schemas` (default: `false`)
530
+ - `--openapi-envelope-namespace` (default: `ResponseEnvelope`)
531
+ - `--openapi-error-namespace` (default: `ErrorObject`)
532
+ - `--openapi-validate` (default: `true`)
533
+ - `--openapi-security-config-file`
534
+ - `--openapi-tags-file`
535
+ - `--openapi-ops-file`
536
+
537
+ **Gateway Flags:**
538
+ - `--gateway-service-name` (required if `--gateway-dir` provided)
539
+ - `--gateway-version-prefix` (required if `--gateway-dir` provided)
540
+ - `--gateway-default-status-codes`
541
+ - `--gateway-stub-handlers` (default: `false`)
542
+
543
+ #### Examples
544
+
545
+ **Complete Stack Generation:**
546
+
547
+ ```bash
548
+ npx wsdl-tsc pipeline \
549
+ --wsdl-source examples/minimal/weather.wsdl \
550
+ --client-dir tmp/client \
551
+ --openapi-file tmp/openapi.json \
552
+ --gateway-dir tmp/gateway \
553
+ --gateway-service-name weather \
554
+ --gateway-version-prefix v1
555
+ ```
556
+
557
+ **With App Generation:**
558
+
559
+ ```bash
560
+ npx wsdl-tsc pipeline \
561
+ --wsdl-source examples/minimal/weather.wsdl \
562
+ --client-dir tmp/client \
563
+ --openapi-file tmp/openapi.json \
564
+ --gateway-dir tmp/gateway \
565
+ --gateway-service-name weather \
566
+ --gateway-version-prefix v1 \
567
+ --generate-app
568
+ ```
569
+
570
+ **Client + OpenAPI Only:**
571
+
572
+ ```bash
573
+ npx wsdl-tsc pipeline \
574
+ --wsdl-source https://example.com/Hotel.wsdl \
575
+ --client-dir ./build/client \
576
+ --openapi-file ./docs/hotel-api.json \
577
+ --openapi-format both
578
+ ```
579
+
580
+ **With Full Configuration:**
581
+
582
+ ```bash
583
+ npx wsdl-tsc pipeline \
584
+ --wsdl-source ./wsdl/Booking.wsdl \
585
+ --client-dir ./build/client \
586
+ --openapi-file ./docs/booking-api \
587
+ --gateway-dir ./build/gateway \
588
+ --openapi-format both \
589
+ --openapi-servers https://api.example.com/v1 \
590
+ --openapi-base-path /booking \
591
+ --openapi-security-config-file ./config/security.json \
592
+ --gateway-service-name booking \
593
+ --gateway-version-prefix v1 \
594
+ --client-int64-as number \
595
+ --client-decimal-as string
596
+ ```
597
+
598
+ #### Pipeline Workflow
599
+
600
+ The pipeline command executes these steps in order:
601
+
602
+ 1. **Parse WSDL** → Load and validate WSDL document
603
+ 2. **Compile Catalog** → Generate intermediate representation
604
+ 3. **Emit Catalog** → Write `catalog.json` (always)
605
+ 4. **Generate Client** → Emit TypeScript client files (if `--client-dir`)
606
+ 5. **Generate OpenAPI** → Create OpenAPI spec (if `--openapi-file`)
607
+ 6. **Generate Gateway** → Create Fastify gateway code (if `--gateway-dir`)
608
+ 7. **Generate App** → Create runnable application (if `--generate-app`)
262
609
 
263
- 3. **Shared catalog for multiple commands** (custom location):
264
- ```bash
265
- npx wsdl-tsc compile --wsdl-source service.wsdl --catalog-file build/shared-catalog.json
266
- npx wsdl-tsc client --catalog-file build/shared-catalog.json --client-dir src/client
267
- npx wsdl-tsc openapi --catalog-file build/shared-catalog.json --openapi-file docs/api.json
268
- ```
610
+ All steps share the same parsed WSDL and compiled catalog, ensuring consistency.
269
611
 
270
612
  ---
271
613
 
272
- ## 6. Command: `client`
614
+ ### Command: `client`
273
615
 
274
616
  **Purpose**: Generate strongly-typed TypeScript SOAP client code from WSDL or a pre-compiled catalog.
275
617
 
@@ -384,7 +726,7 @@ npx wsdl-tsc client \
384
726
 
385
727
  ---
386
728
 
387
- ## 7. Command: `openapi`
729
+ ### Command: `openapi`
388
730
 
389
731
  **Purpose**: Generate OpenAPI 3.1 specification from WSDL or a pre-compiled catalog, mirroring the exact TypeScript type structure.
390
732
 
@@ -579,7 +921,7 @@ This ensures diff-friendly output for version control.
579
921
 
580
922
  ---
581
923
 
582
- ## 8. Command: `gateway`
924
+ ### Command: `gateway`
583
925
 
584
926
  **Purpose**: Generate a production-ready Fastify gateway with fully functional route handlers from an OpenAPI 3.1 specification. This creates a complete REST API layer over your SOAP client with automatic request/response transformation and standardized envelope responses.
585
927
 
@@ -866,7 +1208,7 @@ This generates minimal handler stubs that throw "Not implemented" errors, allowi
866
1208
 
867
1209
  ---
868
1210
 
869
- ## 9. Command: `app`
1211
+ ### Command: `app`
870
1212
 
871
1213
  **Purpose**: Generate a runnable Fastify application that integrates the generated client, gateway, and OpenAPI spec. This provides an immediately executable server for testing, development, and demonstrations.
872
1214
 
@@ -1048,185 +1390,148 @@ This generates all artifacts including the runnable app in a single command.
1048
1390
 
1049
1391
  ---
1050
1392
 
1051
- ## 10. Command: `pipeline`
1393
+ ### Command: `compile` (Advanced)
1052
1394
 
1053
- **Purpose**: Run the complete generation pipeline in a single pass: WSDL parsing → TypeScript client → OpenAPI spec → Fastify gateway.
1395
+ **Purpose**: Parse WSDL and generate only the intermediate `catalog.json` representation without TypeScript client code.
1054
1396
 
1055
- **When to use**:
1056
- - CI/CD automation
1057
- - Complete stack generation
1058
- - Ensuring all artifacts are generated from the same WSDL parse
1059
- - One-command development workflows
1397
+ **When to use**:
1398
+ - Multi-stage builds where you want to cache the parsed WSDL
1399
+ - Debugging or inspecting the compiled schema structure
1400
+ - Sharing a compiled catalog across multiple generation targets
1060
1401
 
1061
- ### Usage
1402
+ #### Usage
1062
1403
 
1063
1404
  ```bash
1064
- npx wsdl-tsc pipeline \
1065
- --wsdl-source <file|url> \
1066
- [--catalog-file <path>] \
1067
- [--client-dir <path>] \
1068
- [--openapi-file <path>] \
1069
- [--gateway-dir <path>] \
1070
- [options]
1405
+ npx wsdl-tsc compile --wsdl-source <file|url> --catalog-file <path> [options]
1071
1406
  ```
1072
1407
 
1073
- ### Required Flags
1074
-
1075
- | Flag | Description |
1076
- |---------------------|----------------------------------------------------------------------|
1077
- | `--wsdl-source` | Path or URL to WSDL file |
1078
-
1079
- ### Output Flags
1080
-
1081
- | Flag | Default | Description |
1082
- |---------------------|---------------------------------------------|---------------------------------------------------|
1083
- | `--catalog-file` | Co-located with first output (see below) | Output path for `catalog.json` (always generated) |
1084
-
1085
- **Catalog Default Location**: The catalog is automatically placed alongside the first available output:
1086
- - With `--client-dir`: `{client-dir}/catalog.json`
1087
- - With `--openapi-file` only: `{openapi-file-dir}/catalog.json`
1088
- - With `--gateway-dir` only: `{gateway-dir}/catalog.json`
1089
-
1090
- **Note**: At least one of `--client-dir`, `--openapi-file`, or `--gateway-dir` must be provided.
1091
-
1092
- ### Generation Control Flags
1093
-
1094
- | Flag | Description |
1095
- |-------------------------|------------------------------------------------|
1096
- | `--client-dir` | Generate TypeScript client in this directory |
1097
- | `--openapi-file` | Generate OpenAPI spec at this path |
1098
- | `--gateway-dir` | Generate Fastify gateway in this directory |
1099
-
1100
- ### Optional Flags
1101
-
1102
- All flags from `client`, `openapi`, and `gateway` commands are supported. Key flags:
1408
+ #### Required Flags
1103
1409
 
1104
- #### Client Flags
1105
- - `--import-extensions` (default: `js`)
1106
- - `--client-attributes-key` (default: `$attributes`)
1107
- - `--client-class-name`
1108
- - `--client-int64-as` (default: `string`)
1109
- - `--client-bigint-as` (default: `string`)
1110
- - `--client-decimal-as` (default: `string`)
1111
- - `--client-date-as` (default: `string`)
1112
- - `--client-choice-mode` (default: `all-optional`)
1113
- - `--client-fail-on-unresolved` (default: `false`)
1114
- - `--client-nillable-as-optional` (default: `false`)
1410
+ | Flag | Description |
1411
+ |---------------------|------------------------------------------|
1412
+ | `--wsdl-source` | Path or URL to the WSDL file |
1413
+ | `--catalog-file` | Output path for `catalog.json` |
1115
1414
 
1116
- #### OpenAPI Flags
1117
- - `--openapi-format` (default: `json`)
1118
- - `--openapi-title`
1119
- - `--openapi-version` (default: `0.0.0`)
1120
- - `--openapi-description`
1121
- - `--openapi-servers` (default: `/`)
1122
- - `--openapi-base-path`
1123
- - `--openapi-path-style` (default: `kebab`)
1124
- - `--openapi-method` (default: `post`)
1125
- - `--openapi-tag-style` (default: `default`)
1126
- - `--openapi-closed-schemas` (default: `false`)
1127
- - `--openapi-prune-unused-schemas` (default: `false`)
1128
- - `--openapi-envelope-namespace` (default: `ResponseEnvelope`)
1129
- - `--openapi-error-namespace` (default: `ErrorObject`)
1130
- - `--openapi-validate` (default: `true`)
1131
- - `--openapi-security-config-file`
1132
- - `--openapi-tags-file`
1133
- - `--openapi-ops-file`
1415
+ #### Optional Flags
1134
1416
 
1135
- #### Gateway Flags
1136
- - `--gateway-service-name` (required if `--gateway-dir` provided)
1137
- - `--gateway-version-prefix` (required if `--gateway-dir` provided)
1138
- - `--gateway-default-status-codes`
1417
+ | Flag | Default | Description |
1418
+ |------------------------------------|----------------|--------------------------------------------------------------|
1419
+ | `--import-extensions` | `js` | Import specifier style: `js`, `ts`, or `bare` |
1420
+ | `--client-attributes-key` | `$attributes` | Attribute bag key for runtime mapper |
1421
+ | `--client-class-name` | (derived) | Override generated client class name |
1422
+ | `--client-int64-as` | `string` | Map 64-bit integers: `string`, `number`, or `bigint` |
1423
+ | `--client-bigint-as` | `string` | Map arbitrary-size integers: `string` or `number` |
1424
+ | `--client-decimal-as` | `string` | Map `xs:decimal`: `string` or `number` |
1425
+ | `--client-date-as` | `string` | Map date/time types: `string` or `Date` |
1426
+ | `--client-choice-mode` | `all-optional` | Choice element strategy: `all-optional` or `union` |
1427
+ | `--client-fail-on-unresolved` | `false` | Fail build on unresolved type references |
1428
+ | `--client-nillable-as-optional` | `false` | Treat nillable elements as optional properties |
1139
1429
 
1140
- ### Examples
1430
+ #### Examples
1141
1431
 
1142
- #### Complete Stack Generation (Using Default Catalog Location)
1432
+ **Basic Compilation:**
1143
1433
 
1144
1434
  ```bash
1145
- npx wsdl-tsc pipeline \
1435
+ npx wsdl-tsc compile \
1146
1436
  --wsdl-source examples/minimal/weather.wsdl \
1147
- --client-dir tmp/client \
1148
- --openapi-file tmp/openapi.json \
1149
- --gateway-dir tmp/gateway \
1150
- --gateway-service-name weather \
1151
- --gateway-version-prefix v1
1437
+ --catalog-file tmp/catalog.json
1152
1438
  ```
1153
1439
 
1154
- **Output**: Catalog at `tmp/client/catalog.json`.
1155
-
1156
- #### Client + OpenAPI Only
1440
+ **With Custom Mapping Options:**
1157
1441
 
1158
1442
  ```bash
1159
- npx wsdl-tsc pipeline \
1443
+ npx wsdl-tsc compile \
1160
1444
  --wsdl-source https://example.com/Hotel.wsdl \
1161
- --client-dir ./build/client \
1162
- --openapi-file ./docs/hotel-api.json \
1163
- --openapi-format both
1445
+ --catalog-file ./build/hotel-catalog.json \
1446
+ --client-int64-as number \
1447
+ --client-decimal-as string
1164
1448
  ```
1165
1449
 
1166
- **Output**: Catalog at `./build/client/catalog.json`.
1167
-
1168
- #### OpenAPI + Gateway Only
1450
+ **For Debugging:**
1169
1451
 
1170
1452
  ```bash
1171
- npx wsdl-tsc pipeline \
1172
- --wsdl-source ./wsdl/Booking.wsdl \
1173
- --openapi-file ./docs/booking-api.json \
1174
- --gateway-dir ./build/gateway \
1175
- --gateway-service-name booking \
1176
- --gateway-version-prefix v1
1453
+ # Compile to inspect types and operations
1454
+ npx wsdl-tsc compile \
1455
+ --wsdl-source ./wsdl/ComplexService.wsdl \
1456
+ --catalog-file ./debug/catalog.json \
1457
+ --client-fail-on-unresolved false
1458
+
1459
+ # Inspect types
1460
+ cat ./debug/catalog.json | jq '.types'
1461
+
1462
+ # Inspect operations
1463
+ cat ./debug/catalog.json | jq '.operations'
1177
1464
  ```
1178
1465
 
1179
- **Output**: Catalog at `./docs/catalog.json`.
1466
+ #### Output
1180
1467
 
1181
- #### With Custom Catalog Path
1468
+ - `catalog.json` - Compiled schema representation including types, operations, and metadata
1182
1469
 
1183
- ```bash
1184
- npx wsdl-tsc pipeline \
1185
- --wsdl-source ./wsdl/Booking.wsdl \
1186
- --catalog-file ./build/shared/catalog.json \
1187
- --client-dir ./build/client \
1188
- --openapi-file ./docs/booking-api.json \
1189
- --gateway-dir ./build/gateway \
1190
- --gateway-service-name booking \
1191
- --gateway-version-prefix v1
1192
- ```
1470
+ #### Catalog Structure
1193
1471
 
1194
- #### With Full Configuration
1472
+ The catalog.json file contains the compiled WSDL representation:
1195
1473
 
1196
- ```bash
1197
- npx wsdl-tsc pipeline \
1198
- --wsdl-source ./wsdl/Booking.wsdl \
1199
- --client-dir ./build/client \
1200
- --openapi-file ./docs/booking-api \
1201
- --gateway-dir ./build/gateway \
1202
- --openapi-format both \
1203
- --openapi-servers https://api.example.com/v1 \
1204
- --openapi-base-path /booking \
1205
- --openapi-security-config-file ./config/security.json \
1206
- --gateway-service-name booking \
1207
- --gateway-version-prefix v1 \
1208
- --client-int64-as number \
1209
- --client-decimal-as string
1474
+ ```json
1475
+ {
1476
+ "wsdlUri": "path/to/service.wsdl",
1477
+ "targetNamespace": "http://example.com/service",
1478
+ "serviceName": "WeatherService",
1479
+ "types": [
1480
+ {
1481
+ "name": "GetWeatherRequest",
1482
+ "properties": []
1483
+ }
1484
+ ],
1485
+ "operations": [
1486
+ {
1487
+ "name": "GetWeather",
1488
+ "input": "GetWeatherRequest",
1489
+ "output": "GetWeatherResponse"
1490
+ }
1491
+ ],
1492
+ "options": {
1493
+ "imports": "js",
1494
+ "catalog": true
1495
+ }
1496
+ }
1210
1497
  ```
1211
1498
 
1212
- **Output**: Catalog at `./build/client/catalog.json`.
1499
+ **Key sections**:
1500
+ - `types` - All compiled type definitions with properties and inheritance
1501
+ - `operations` - SOAP operations with input/output type references
1502
+ - `options` - Compiler options used during generation
1213
1503
 
1214
- ### Pipeline Workflow
1504
+ This catalog can be reused with the `client` and `openapi` commands via `--catalog-file`.
1215
1505
 
1216
- The pipeline command executes these steps in order:
1506
+ #### Catalog Co-location
1217
1507
 
1218
- 1. **Parse WSDL** Load and validate WSDL document
1219
- 2. **Compile Catalog** → Generate intermediate representation
1220
- 3. **Emit Catalog** → Write `catalog.json` (always)
1221
- 4. **Generate Client** → Emit TypeScript client files (if `--client-dir`)
1222
- 5. **Generate OpenAPI** → Create OpenAPI spec (if `--openapi-file`)
1223
- 6. **Generate Gateway** → Create Fastify gateway code (if `--gateway-dir`)
1508
+ **Default behavior**: Catalog files are **co-located** with their primary output files for better organization and discoverability.
1224
1509
 
1225
- All steps share the same parsed WSDL and compiled catalog, ensuring consistency.
1510
+ **Catalog Location by Command**:
1511
+ - `compile`: Always requires explicit `--catalog-file` (no default)
1512
+ - `client`: Defaults to `{client-dir}/catalog.json`
1513
+ - `openapi`: Defaults to `{openapi-file-dir}/catalog.json`
1514
+ - `pipeline`: Intelligent cascade - first available: `{client-dir}` > `{openapi-dir}` > `{gateway-dir}` > `tmp/`
1515
+
1516
+ **Common patterns**:
1517
+
1518
+ 1. **Co-located with client** (recommended for most projects):
1519
+ ```bash
1520
+ npx wsdl-tsc client --wsdl-source service.wsdl --client-dir src/services/weather
1521
+ ```
1522
+
1523
+ Creates `src/services/weather/catalog.json` automatically.
1524
+
1525
+ 2. **Shared catalog for multiple commands** (custom location):
1526
+ ```bash
1527
+ npx wsdl-tsc compile --wsdl-source service.wsdl --catalog-file build/shared-catalog.json
1528
+ npx wsdl-tsc client --catalog-file build/shared-catalog.json --client-dir src/client
1529
+ npx wsdl-tsc openapi --catalog-file build/shared-catalog.json --openapi-file docs/api.json
1530
+ ```
1226
1531
 
1227
1532
  ---
1228
1533
 
1229
- ## 11. Working With Generated Clients
1534
+ ## Working With Generated Clients
1230
1535
 
1231
1536
  ### Client Construction
1232
1537
 
@@ -1293,7 +1598,7 @@ result.GetCityWeatherByZIPResult.Temperature; // number | string (depends on ma
1293
1598
 
1294
1599
  ---
1295
1600
 
1296
- ## 12. OpenAPI Configuration
1601
+ ## Configuration Files
1297
1602
 
1298
1603
  ### Security Configuration (`security.json`)
1299
1604
 
@@ -1352,7 +1657,106 @@ Per-operation overrides for method, summary, description, and deprecation:
1352
1657
 
1353
1658
  ---
1354
1659
 
1355
- ## 13. Programmatic API
1660
+ ## Production Concerns
1661
+
1662
+ ### Deterministic Output Guarantees
1663
+
1664
+ All generated code and specifications have **stable, deterministic ordering** for version control:
1665
+
1666
+ - ✅ **TypeScript files**: Sorted type declarations, imports, and exports
1667
+ - ✅ **OpenAPI specs**: Sorted paths, HTTP methods, schemas, parameters, security schemes, tags
1668
+ - ✅ **JSON Schemas**: Sorted property keys and component names
1669
+ - ✅ **Gateway routes**: Alphabetically organized route files
1670
+ - ✅ **Catalog JSON**: Consistent ordering of types and operations
1671
+
1672
+ **Benefit**: Safe regeneration in CI/CD without spurious diffs.
1673
+
1674
+ ### Validation Behavior
1675
+
1676
+ **OpenAPI Validation** (enabled by default):
1677
+ - Uses `@apidevtools/swagger-parser`
1678
+ - Validates schema structure
1679
+ - Resolves all `$ref` references
1680
+ - Catches missing schemas and circular dependencies
1681
+ - Disable with `--openapi-validate false`
1682
+
1683
+ **Gateway Contract Validation**:
1684
+ - All request/response bodies must use `$ref` to `components.schemas`
1685
+ - Every operation must have a default response with `application/json` content
1686
+ - All referenced schemas must exist in `components.schemas`
1687
+
1688
+ ### Error Handling
1689
+
1690
+ **Gateway Error Classification**:
1691
+
1692
+ | Error Type | HTTP Status | Error Code | When It Occurs |
1693
+ |-----------------------|-------------|-----------------------|---------------------------------------|
1694
+ | Validation errors | 400 | `VALIDATION_ERROR` | Request doesn't match JSON Schema |
1695
+ | SOAP faults | 502 | `SOAP_FAULT` | SOAP service returned a fault |
1696
+ | Connection refused | 503 | `SERVICE_UNAVAILABLE` | Cannot reach SOAP endpoint |
1697
+ | Timeout | 504 | `GATEWAY_TIMEOUT` | SOAP request exceeded timeout |
1698
+ | Other errors | 500 | `INTERNAL_ERROR` | Unexpected errors |
1699
+
1700
+ All errors are wrapped in the standard envelope format with `error` object populated.
1701
+
1702
+ ### SOAP Wire Logging
1703
+
1704
+ Enable SOAP request/response debugging:
1705
+
1706
+ ```bash
1707
+ NODE_DEBUG=soap node app.js
1708
+ ```
1709
+
1710
+ This logs full XML request/response payloads to console.
1711
+
1712
+ ### CI/CD Tips
1713
+
1714
+ **Caching Strategy:**
1715
+
1716
+ ```bash
1717
+ # Step 1: Compile catalog (cacheable artifact)
1718
+ npx wsdl-tsc compile \
1719
+ --wsdl-source ./wsdl/Service.wsdl \
1720
+ --catalog-file ./build/catalog.json
1721
+
1722
+ # Step 2: Generate code from cached catalog
1723
+ npx wsdl-tsc client --catalog-file ./build/catalog.json --client-dir ./src/client
1724
+ npx wsdl-tsc openapi --catalog-file ./build/catalog.json --openapi-file ./docs/api.json
1725
+ ```
1726
+
1727
+ **Recommended Build Script** (`package.json`):
1728
+
1729
+ ```json
1730
+ {
1731
+ "scripts": {
1732
+ "generate": "npx wsdl-tsc pipeline --wsdl-source ./wsdl/service.wsdl --client-dir ./src/client --openapi-file ./docs/api.json --gateway-dir ./src/gateway --gateway-service-name svc --gateway-version-prefix v1",
1733
+ "build": "npm run generate && tsc",
1734
+ "typecheck": "tsc --noEmit"
1735
+ }
1736
+ }
1737
+ ```
1738
+
1739
+ ### Known Limitations
1740
+
1741
+ **Choice Elements**:
1742
+ - Current strategy: `all-optional` (all branches optional)
1743
+ - Future: Discriminated union support (planned)
1744
+
1745
+ **Union Types**:
1746
+ - Experimental `--client-choice-mode union` available
1747
+ - May require manual refinement for complex patterns
1748
+
1749
+ **WS-Policy**:
1750
+ - Security hints extracted from policies
1751
+ - Custom policies may require manual security configuration
1752
+
1753
+ **Array Wrapper Flattening**:
1754
+ - Single-child sequences with `maxOccurs>1` become array schemas
1755
+ - Sequences with multiple children preserve wrapper
1756
+
1757
+ ---
1758
+
1759
+ ## Programmatic API
1356
1760
 
1357
1761
  All CLI commands are available as TypeScript functions for programmatic usage.
1358
1762
 
@@ -1619,7 +2023,7 @@ interface PipelineOptions {
1619
2023
 
1620
2024
  ---
1621
2025
 
1622
- ## 14. Advanced Topics
2026
+ ## Advanced Topics
1623
2027
 
1624
2028
  ### Primitive Mapping Philosophy
1625
2029
 
@@ -1694,7 +2098,7 @@ Disable with `--openapi-validate false` or `validate: false` in API.
1694
2098
 
1695
2099
  ---
1696
2100
 
1697
- ## 15. Troubleshooting
2101
+ ## Troubleshooting
1698
2102
 
1699
2103
  ### Common Issues
1700
2104
 
@@ -1775,7 +2179,7 @@ The catalog is automatically placed at `./src/services/hotel/catalog.json`.
1775
2179
 
1776
2180
  ---
1777
2181
 
1778
- ## 16. Contributing
2182
+ ## Contributing
1779
2183
 
1780
2184
  We welcome contributions! Here's how to get started:
1781
2185
 
@@ -1849,7 +2253,7 @@ See also: [CONTRIBUTING.md](CONTRIBUTING.md), [CODE_OF_CONDUCT.md](CODE_OF_CONDU
1849
2253
 
1850
2254
  ---
1851
2255
 
1852
- ## 17. License
2256
+ ## License
1853
2257
 
1854
2258
  MIT © TechSpokes
1855
2259
 
@@ -1859,7 +2263,7 @@ See [LICENSE](LICENSE) for full text.
1859
2263
 
1860
2264
  ---
1861
2265
 
1862
- ## 18. Sponsors
2266
+ ## Sponsors
1863
2267
 
1864
2268
  Support ongoing development and maintenance:
1865
2269
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@techspokes/typescript-wsdl-client",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "description": "TypeScript WSDL → SOAP client generator with full xs:attribute support, complex types, sequences, inheritance, and namespace-collision merging.",
5
5
  "keywords": [
6
6
  "wsdl",
@@ -45,21 +45,22 @@
45
45
  "LICENSE"
46
46
  ],
47
47
  "scripts": {
48
- "build": "tsc -p tsconfig.json",
49
- "clean": "rimraf dist",
50
- "clean:tmp": "rimraf tmp",
51
48
  "dev": "tsx src/cli.ts",
52
49
  "watch": "tsx watch src/cli.ts",
50
+ "clean": "rimraf dist",
51
+ "clean:tmp": "rimraf tmp",
52
+ "build": "tsc -p tsconfig.json",
53
53
  "typecheck": "tsc --noEmit",
54
+ "test": "npm run typecheck && npm run smoke:pipeline",
54
55
  "prepublishOnly": "npm run clean && npm run build",
55
- "test": "exit 0",
56
- "smoke:compile": "rimraf tmp && tsx src/cli.ts compile --wsdl-source examples/minimal/weather.wsdl --catalog-file tmp/catalog.json",
57
- "smoke:client": "rimraf tmp && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client && tsc -p tsconfig.smoke.json",
58
- "smoke:openapi": "rimraf tmp && tsx src/cli.ts openapi --wsdl-source examples/minimal/weather.wsdl --openapi-file tmp/openapi.json --openapi-format json && tsc -p tsconfig.smoke.json",
59
- "smoke:gateway": "rimraf tmp && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client && tsx src/cli.ts openapi --catalog-file tmp/client/catalog.json --openapi-file tmp/openapi.json --openapi-format json && tsx src/cli.ts gateway --openapi-file tmp/openapi.json --client-dir tmp/client --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 && tsc -p tsconfig.smoke.json",
60
- "smoke:app": "rimraf tmp && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api --generate-app && tsc -p tsconfig.smoke.json",
61
- "smoke:pipeline": "rimraf tmp && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api && tsc -p tsconfig.smoke.json",
62
- "ci": "npm run build && npm run typecheck && npm run smoke:app"
56
+ "smoke:reset": "npm run clean:tmp",
57
+ "smoke:compile": "npm run smoke:reset && tsx src/cli.ts compile --wsdl-source examples/minimal/weather.wsdl --catalog-file tmp/catalog.json",
58
+ "smoke:client": "npm run smoke:reset && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client && tsc -p tsconfig.smoke.json",
59
+ "smoke:openapi": "npm run smoke:reset && tsx src/cli.ts openapi --wsdl-source examples/minimal/weather.wsdl --openapi-file tmp/openapi.json --openapi-format json && tsc -p tsconfig.smoke.json",
60
+ "smoke:gateway": "npm run smoke:reset && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client && tsx src/cli.ts openapi --catalog-file tmp/client/catalog.json --openapi-file tmp/openapi.json --openapi-format json && tsx src/cli.ts gateway --openapi-file tmp/openapi.json --client-dir tmp/client --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 && tsc -p tsconfig.smoke.json",
61
+ "smoke:pipeline": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api --generate-app && tsc -p tsconfig.smoke.json",
62
+ "smoke:app": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api && tsx src/cli.ts app --client-dir tmp/client --gateway-dir tmp/gateway --openapi-file tmp/openapi.json --app-dir tmp/app && tsc -p tsconfig.smoke.json",
63
+ "ci": "npm run clean && npm run build && npm run typecheck && npm run smoke:pipeline"
63
64
  },
64
65
  "devDependencies": {
65
66
  "@types/js-yaml": "^4.0.9",