@techspokes/typescript-wsdl-client
v0.9.7
Published
TypeScript WSDL → SOAP client generator with full xs:attribute support, complex types, sequences, inheritance, and namespace-collision merging.
Maintainers
Readme
TypeScript WSDL Client
Transform complex WSDL/XSD definitions into type-safe TypeScript SOAP clients with optional OpenAPI 3.1 specs and production-ready REST gateways.
Use This If You Need...
- ✅ TypeScript-first SOAP clients — Strongly typed, ergonomic client generation from WSDL
- ✅ OpenAPI 3.1 specs — Generate REST API documentation that mirrors your TypeScript types
- ✅ REST gateway over SOAP — Production-ready Fastify handlers with automatic request/response transformation
- ✅ CI-friendly determinism — Stable, diff-friendly output for safe regeneration in version control
- ✅ Predictable modeling — Flattened attributes, consistent
$valueconvention, inheritance resolution
Vendor: TechSpokes · Maintainer: Serge Liatko (@sergeliatko)
Table of Contents
- Installation
- Quick Start (60 Seconds)
- What You Get (Outputs)
- Core Concepts
- Common Workflows
- Command Reference
- Configuration Files
- Working With Generated Clients
- Production Concerns
- Programmatic API
- Troubleshooting
- Contributing
- License
- Support
Installation
npm install --save-dev @techspokes/typescript-wsdl-client
npm install soap # Runtime dependency for SOAP callsRequirements:
- Node.js 20.0.0 or later
soappackage (runtime dependency for generated clients)
Quick Start (60 Seconds)
Generate a complete SOAP-to-REST stack in one command:
# Generate client, OpenAPI spec, gateway, and runnable app
npx wsdl-tsc 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 \
--generate-appStart the server:
cd tmp/app
cp .env.example .env
# Edit .env to set WSDL_SOURCE if needed
npx tsx server.jsTest it:
# Health check
curl http://localhost:3000/health
# Get OpenAPI spec
curl http://localhost:3000/openapi.json | jq .
# Call a SOAP operation via REST
curl -X POST http://localhost:3000/get-weather-information \
-H "Content-Type: application/json" \
-d '{}'What just happened?
- Parsed the WSDL and compiled types
- Generated a TypeScript SOAP client with full type safety
- Created an OpenAPI 3.1 spec matching the client types
- Built Fastify gateway handlers that call SOAP and return JSON
- Created a runnable Express-style app with health/OpenAPI endpoints
What You Get (Outputs)
TypeScript SOAP Client
client/
├── client.ts # Strongly-typed SOAP client wrapper with methods
├── types.ts # Flattened interfaces, type aliases, and enums
├── utils.ts # Runtime metadata for JSON→SOAP conversion
└── catalog.json # Compiled schema representation (reusable)Example usage:
import { Weather } from './client/client.js';
const client = new Weather({
source: 'https://example.com/weather.wsdl',
});
const result = await client.GetCityWeatherByZIP({ ZIP: '10001' });
console.log(result.GetCityWeatherByZIPResult);OpenAPI 3.1 Specification
openapi.json # or .yaml — Complete REST API documentation- Mirrors exact TypeScript type structure
- All responses wrapped in standard envelope (status, message, data, error)
- Deterministic ordering for version control
- Validates with
swagger-parserby default
Fastify REST Gateway
gateway/
├── schemas/
│ ├── models/ # JSON Schema components with URN IDs
│ └── operations/ # Request/response validation schemas
├── routes/ # Route handlers (fully implemented)
├── schemas.ts # Schema registration module
├── routes.ts # Route aggregator
├── runtime.ts # Envelope builders, error handlers
└── plugin.ts # Fastify plugin wrapperExample integration:
import Fastify from 'fastify';
import weatherGateway from './gateway/plugin.js';
import { Weather } from './client/client.js';
const app = Fastify({ logger: true });
const client = new Weather({ source: 'weather.wsdl' });
await app.register(weatherGateway, { client });
await app.listen({ port: 3000 });Runnable Application
app/
├── server.js # Main entry point
├── config.js # Configuration with env var support
├── .env.example # Environment template
├── README.md # Usage instructions
└── openapi.json # OpenAPI spec (when --openapi-mode=copy)Standard Response Envelope
All gateway responses follow this structure:
Success:
{
"status": "SUCCESS",
"message": null,
"data": { /* SOAP response */ },
"error": null
}Error:
{
"status": "ERROR",
"message": "Request validation failed",
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": { /* validation errors */ }
}
}Core Concepts
Flattening and $value
Attributes and elements become peer properties — No nested wrapper noise:
<!-- WSDL -->
<xs:complexType name="Price">
<xs:simpleContent>
<xs:extension base="xs:decimal">
<xs:attribute name="currency" type="xs:string"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>// Generated TypeScript
interface Price {
currency?: string; // attribute
$value: string; // text content (decimal mapped to string by default)
}Primitive Mapping Defaults (String-First Safety)
Prevents precision loss and parsing errors at the cost of convenience:
| XSD Type | Default | Override Options | When to Override |
|---------------|----------|--------------------|----------------------------------------|
| xs:long | string | number, bigint | Use number if values fit JS range |
| xs:integer | string | number | Use string for arbitrary-size ints |
| xs:decimal | string | number | Use string for precise decimals |
| xs:dateTime | string | Date | Use Date if runtime parsing is okay |
Override with flags:
--client-int64-as number--client-decimal-as string--client-date-as Date
Deterministic Generation
All output is stable and diff-friendly for CI/CD:
- ✅ Sorted type declarations
- ✅ Sorted OpenAPI paths, schemas, parameters
- ✅ Sorted JSON schema keys
- ✅ Stable alias resolution
- ✅ Consistent ordering of imports
Regenerate safely without spurious diffs in version control.
Catalog as Intermediate Artifact
catalog.json is the compiled representation of your WSDL:
- Debuggable — Inspect types, operations, and metadata as JSON
- Cacheable — Reuse across client/OpenAPI/gateway generation
- Co-located — Automatically placed alongside generated output
Common locations:
clientcommand:{client-dir}/catalog.jsonopenapicommand:{openapi-dir}/catalog.jsonpipelinecommand: First available output directory
Common Workflows
Which Command Should I Run?
| I Want... | Use Command | Example |
|-----------------------------------------------|--------------|----------------------------------------------------------------------------------------------------------------------|
| 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 |
| Only a TypeScript SOAP client | client | npx wsdl-tsc client --wsdl-source service.wsdl --client-dir ./client |
| Only OpenAPI spec (for docs or SDKs) | openapi | npx wsdl-tsc openapi --wsdl-source service.wsdl --openapi-file ./api.json |
| 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 |
| Runnable server for testing | app | npx wsdl-tsc app --client-dir ./client --gateway-dir ./gateway --openapi-file ./api.json |
| Debug/inspect WSDL compilation | compile | npx wsdl-tsc compile --wsdl-source service.wsdl --catalog-file ./catalog.json |
Workflow 1: Generate Everything (Recommended)
Use pipeline for complete stack generation:
npx wsdl-tsc pipeline \
--wsdl-source examples/minimal/weather.wsdl \
--client-dir ./src/services/weather \
--openapi-file ./docs/weather-api.json \
--gateway-dir ./src/gateway/weather \
--gateway-service-name weather \
--gateway-version-prefix v1Output:
- Client:
./src/services/weather/client.ts,types.ts,utils.ts,catalog.json - OpenAPI:
./docs/weather-api.json - Gateway:
./src/gateway/weather/(routes, schemas, plugin)
Workflow 2: SOAP Client Only
Generate TypeScript client for direct SOAP integration:
npx wsdl-tsc client \
--wsdl-source ./wsdl/Hotel.wsdl \
--client-dir ./src/services/hotelUsage:
import soap from 'soap';
import { Hotel } from './src/services/hotel/client.js';
const client = new Hotel({
source: 'https://example.com/hotel.wsdl',
security: new soap.WSSecurity('username', 'password'),
});
const result = await client.SearchAvailableRooms({
checkIn: '2024-01-15',
checkOut: '2024-01-20',
guests: 2,
});Workflow 3: OpenAPI for Documentation
Generate OpenAPI spec for API documentation or SDK generation:
npx wsdl-tsc openapi \
--wsdl-source ./wsdl/Booking.wsdl \
--openapi-file ./docs/booking-api.yaml \
--openapi-format yaml \
--openapi-title "Hotel Booking API" \
--openapi-version "1.0.0" \
--openapi-servers https://api.example.com/v1Use the spec:
- Import into Postman, Insomnia, or Swagger UI
- Generate client SDKs with OpenAPI Generator
- Share as REST API documentation
Workflow 4: REST Gateway Over SOAP
Build a REST API layer over legacy SOAP services:
# 1. Generate client + OpenAPI
npx wsdl-tsc pipeline \
--wsdl-source ./wsdl/Legacy.wsdl \
--client-dir ./src/services/legacy \
--openapi-file ./docs/legacy-api.json
# 2. Generate gateway
npx wsdl-tsc gateway \
--openapi-file ./docs/legacy-api.json \
--client-dir ./src/services/legacy \
--gateway-dir ./src/gateway/legacy \
--gateway-service-name legacy \
--gateway-version-prefix v1Or in one command:
npx wsdl-tsc pipeline \
--wsdl-source ./wsdl/Legacy.wsdl \
--client-dir ./src/services/legacy \
--openapi-file ./docs/legacy-api.json \
--gateway-dir ./src/gateway/legacy \
--gateway-service-name legacy \
--gateway-version-prefix v1Workflow 5: CI/CD Integration
Cache compiled catalog for faster multi-stage builds:
# Stage 1: Compile catalog (cacheable)
npx wsdl-tsc compile \
--wsdl-source ./wsdl/Service.wsdl \
--catalog-file ./build/service-catalog.json
# Stage 2: Generate client from catalog
npx wsdl-tsc client \
--catalog-file ./build/service-catalog.json \
--client-dir ./src/services/service
# Stage 3: Generate OpenAPI from catalog
npx wsdl-tsc openapi \
--catalog-file ./build/service-catalog.json \
--openapi-file ./docs/service-api.jsonWorkflow 6: Debugging Complex WSDL
Inspect compiled types and operations:
# Compile to catalog
npx wsdl-tsc compile \
--wsdl-source ./wsdl/Complex.wsdl \
--catalog-file ./debug/catalog.json
# Inspect types
cat ./debug/catalog.json | jq '.types'
# Inspect operations
cat ./debug/catalog.json | jq '.operations'Command Reference
The tool provides six commands for different integration scenarios. Commands are listed in recommended order of use:
| Command | Purpose | Typical Use Case |
|------------|----------------------------------------------------------------|-----------------------------------------------|
| pipeline | Run full pipeline: client + OpenAPI + gateway (+ app optional) | CI/CD automation, complete stack generation (recommended) |
| client | Generate TypeScript SOAP client from WSDL or catalog | Standard SOAP integration |
| openapi | Generate OpenAPI 3.1 spec from WSDL or catalog | Documentation, REST proxies, API gateways |
| gateway | Generate Fastify gateway with full handlers from OpenAPI spec | Production REST gateway with SOAP integration |
| app | Generate runnable Fastify app from client + gateway + OpenAPI | Local testing, quick iteration, demos |
| compile | Parse WSDL and emit catalog.json only | Debugging, inspection, or multi-stage builds (advanced) |
Command: pipeline (Recommended)
Purpose: Run the complete generation pipeline in a single pass: WSDL parsing → TypeScript client → OpenAPI spec → Fastify gateway (+ app optional).
When to use:
- CI/CD automation
- Complete stack generation
- Ensuring all artifacts are generated from the same WSDL parse
- One-command development workflows
Usage
npx wsdl-tsc pipeline \
--wsdl-source <file|url> \
[--catalog-file <path>] \
[--client-dir <path>] \
[--openapi-file <path>] \
[--gateway-dir <path>] \
[options]Required Flags
| Flag | Description |
|---------------------|----------------------------------------------------------------------|
| --wsdl-source | Path or URL to WSDL file |
Output Flags
| Flag | Default | Description |
|---------------------|---------------------------------------------|---------------------------------------------------|
| --catalog-file | Co-located with first output (see below) | Output path for catalog.json (always generated) |
Catalog Default Location: The catalog is automatically placed alongside the first available output:
- With
--client-dir:{client-dir}/catalog.json - With
--openapi-fileonly:{openapi-file-dir}/catalog.json - With
--gateway-dironly:{gateway-dir}/catalog.json
Note: At least one of --client-dir, --openapi-file, or --gateway-dir must be provided.
Generation Control Flags
| Flag | Description |
|-------------------------|------------------------------------------------|
| --client-dir | Generate TypeScript client in this directory |
| --openapi-file | Generate OpenAPI spec at this path |
| --gateway-dir | Generate Fastify gateway in this directory |
| --generate-app | Generate runnable app (requires gateway) |
Optional Flags
All flags from client, openapi, and gateway commands are supported. Key flags:
Client Flags:
--import-extensions(default:js)--client-attributes-key(default:$attributes)--client-class-name--client-int64-as(default:string)--client-bigint-as(default:string)--client-decimal-as(default:string)--client-date-as(default:string)--client-choice-mode(default:all-optional)--client-fail-on-unresolved(default:false)--client-nillable-as-optional(default:false)
OpenAPI Flags:
--openapi-format(default:json)--openapi-title--openapi-version(default:0.0.0)--openapi-description--openapi-servers(default:/)--openapi-base-path--openapi-path-style(default:kebab)--openapi-method(default:post)--openapi-tag-style(default:default)--openapi-closed-schemas(default:false)--openapi-prune-unused-schemas(default:false)--openapi-envelope-namespace(default:ResponseEnvelope)--openapi-error-namespace(default:ErrorObject)--openapi-validate(default:true)--openapi-security-config-file--openapi-tags-file--openapi-ops-file
Gateway Flags:
--gateway-service-name(required if--gateway-dirprovided)--gateway-version-prefix(required if--gateway-dirprovided)--gateway-default-status-codes--gateway-stub-handlers(default:false)
Examples
Complete Stack Generation:
npx wsdl-tsc 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 v1With App Generation:
npx wsdl-tsc 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 \
--generate-appClient + OpenAPI Only:
npx wsdl-tsc pipeline \
--wsdl-source https://example.com/Hotel.wsdl \
--client-dir ./build/client \
--openapi-file ./docs/hotel-api.json \
--openapi-format bothWith Full Configuration:
npx wsdl-tsc pipeline \
--wsdl-source ./wsdl/Booking.wsdl \
--client-dir ./build/client \
--openapi-file ./docs/booking-api \
--gateway-dir ./build/gateway \
--openapi-format both \
--openapi-servers https://api.example.com/v1 \
--openapi-base-path /booking \
--openapi-security-config-file ./config/security.json \
--gateway-service-name booking \
--gateway-version-prefix v1 \
--client-int64-as number \
--client-decimal-as stringPipeline Workflow
The pipeline command executes these steps in order:
- Parse WSDL → Load and validate WSDL document
- Compile Catalog → Generate intermediate representation
- Emit Catalog → Write
catalog.json(always) - Generate Client → Emit TypeScript client files (if
--client-dir) - Generate OpenAPI → Create OpenAPI spec (if
--openapi-file) - Generate Gateway → Create Fastify gateway code (if
--gateway-dir) - Generate App → Create runnable application (if
--generate-app)
All steps share the same parsed WSDL and compiled catalog, ensuring consistency.
Command: client
Purpose: Generate strongly-typed TypeScript SOAP client code from WSDL or a pre-compiled catalog.
When to use:
- Standard SOAP integration (most common use case)
- When you need TypeScript types and client methods for SOAP operations
- When building applications that consume SOAP services
Usage
npx wsdl-tsc client --wsdl-source <file|url> --client-dir <path> [options]
# OR
npx wsdl-tsc client --catalog-file <path> --client-dir <path> [options]Required Flags
| Flag | Description |
|------------------|-------------------------------------------------|
| --wsdl-source | Path or URL to WSDL file (see note below) |
| --client-dir | Output directory for generated TypeScript files |
Optional Input Flags
| Flag | Default | Description |
|------------------|-----------------------------|----------------------------------------------------------------------|
| --catalog-file | {client-dir}/catalog.json | Path to pre-compiled catalog.json (when not using --wsdl-source) |
Note: Provide either --wsdl-source (to compile from WSDL) or --catalog-file (to use pre-compiled catalog). When using --wsdl-source, the catalog is automatically generated in the client directory unless you override with --catalog-file.
Generated Files
| File | Purpose |
|----------------|------------------------------------------------------------------------------|
| client.ts | Strongly-typed SOAP client wrapper with one method per operation |
| types.ts | Flattened TypeScript interfaces, type aliases, and enums |
| utils.ts | Runtime metadata for JSON to SOAP conversion (attribute mapping, occurrence) |
| catalog.json | (When using --wsdl-source) Generated in client directory by default |
Optional Flags
All flags from compile command, plus:
| Flag | Default | Description |
|---------------------------------|----------------|-------------------------------------|
| --import-extensions | js | Import style: js, ts, or bare |
| --client-attributes-key | $attributes | Attribute bag key |
| --client-class-name | (derived) | Override client class name |
| --client-int64-as | string | Map 64-bit integers |
| --client-bigint-as | string | Map arbitrary-size integers |
| --client-decimal-as | string | Map xs:decimal |
| --client-date-as | string | Map date/time types |
| --client-choice-mode | all-optional | Choice element strategy |
| --client-fail-on-unresolved | false | Fail on unresolved references |
| --client-nillable-as-optional | false | Treat nillable as optional |
Examples
Basic Generation (Default Catalog Location)
npx wsdl-tsc client \
--wsdl-source examples/minimal/weather.wsdl \
--client-dir tmp/clientOutput: Generates client files and catalog at tmp/client/catalog.json.
With Custom Catalog Path
npx wsdl-tsc client \
--wsdl-source examples/minimal/weather.wsdl \
--client-dir tmp/client \
--catalog-file build/shared-catalog.jsonWith Custom Numeric Mappings
npx wsdl-tsc client \
--wsdl-source https://example.com/Hotel.wsdl \
--client-dir ./src/integrations/soap/hotel \
--client-int64-as number \
--client-decimal-as string \
--client-date-as stringOutput: Catalog generated at ./src/integrations/soap/hotel/catalog.json.
From Pre-compiled Catalog
# First compile the catalog
npx wsdl-tsc compile --wsdl-source https://example.com/Hotel.wsdl --catalog-file build/hotel-catalog.json
# Then generate client from catalog
npx wsdl-tsc client \
--catalog-file build/hotel-catalog.json \
--client-dir ./src/services/hotelKey Modeling Rules
- Attributes & elements become peer properties (flattened)
- Text content becomes
$valueproperty - Required attributes:
use!="optional"; elementsminOccurs>=1 - Multiplicity:
maxOccurs>1orunboundedbecome arrays - Nillable:
nillable="true"preserved (optionally model as optional with--client-nillable-as-optional) - Inheritance: extensions merged or emitted as
extends; simpleContent base collapsed logically
Command: openapi
Purpose: Generate OpenAPI 3.1 specification from WSDL or a pre-compiled catalog, mirroring the exact TypeScript type structure.
When to use:
- Creating REST API documentation for SOAP services
- Building API gateways or proxies
- Enabling REST-style access to SOAP operations
- Generating client SDKs in other languages
Usage
npx wsdl-tsc openapi --wsdl-source <file|url> --openapi-file <path> [options]
# OR
npx wsdl-tsc openapi --catalog-file <path> --openapi-file <path> [options]Required Flags
| Flag | Description |
|---------------------|----------------------------------------------------|
| --openapi-file | Output path for OpenAPI specification |
Input Source Flags (Mutually Exclusive)
| Flag | Default | Description |
|---------------------|--------------------------------------|----------------------------------------------------|
| --wsdl-source | (none) | Path or URL to WSDL file |
| --catalog-file | {openapi-file-dir}/catalog.json | Path to pre-compiled catalog.json |
Note: Provide either --wsdl-source or --catalog-file. When neither is provided, defaults to reading from the OpenAPI output directory. When using --wsdl-source, the catalog is automatically written to the OpenAPI output directory unless overridden.
Core Optional Flags
| Flag | Default | Description |
|-------------------------------|-----------|----------------------------------------------------------|
| --openapi-format | json | Output format: json, yaml, or both |
| --openapi-title | (derived) | API title in info section |
| --openapi-version | 0.0.0 | API version in info.version |
| --openapi-description | (empty) | API description in info section |
| --openapi-servers | / | Comma-separated server URLs |
| --openapi-base-path | (empty) | Base path prefix (e.g., /v1/soap) |
| --openapi-validate | true | Validate spec with swagger-parser |
Path & Schema Customization
| Flag | Default | Description |
|----------------------------------|-----------|--------------------------------------------------|
| --openapi-path-style | kebab | Path transformation: kebab, asis, or lower |
| --openapi-method | post | Default HTTP method for operations |
| --openapi-tag-style | default | Tag inference: default, service, or first |
| --openapi-closed-schemas | false | Add additionalProperties: false to all schemas |
| --openapi-prune-unused-schemas | false | Emit only schemas referenced by operations |
Response Envelope Customization
| Flag | Default | Description |
|--------------------------------|--------------------|---------------------------------------------|
| --openapi-envelope-namespace | ResponseEnvelope | Override envelope component name suffix |
| --openapi-error-namespace | ErrorObject | Override error object component name suffix |
Configuration Files
| Flag | Description |
|-----------------------------------|-------------------------------------------------------|
| --openapi-security-config-file | Path to security.json (schemes, headers, overrides) |
| --openapi-tags-file | Path to tags.json (explicit operation → tag map) |
| --openapi-ops-file | Path to ops.json (per-operation overrides) |
Examples
Basic JSON Output
npx wsdl-tsc openapi \
--wsdl-source examples/minimal/weather.wsdl \
--openapi-file ./docs/weather-api.jsonMulti-Format with Validation
npx wsdl-tsc openapi \
--wsdl-source https://example.com/Hotel.wsdl \
--openapi-file ./docs/hotel-api \
--openapi-format both \
--openapi-servers https://api.example.com/v1,https://api-staging.example.com/v1 \
--openapi-base-path /soapFrom Pre-compiled Catalog
npx wsdl-tsc openapi \
--catalog-file ./artifacts/hotel-catalog.json \
--openapi-file ./docs/hotel-api.json \
--openapi-format jsonWith Custom Configuration
npx wsdl-tsc openapi \
--wsdl-source ./wsdl/Booking.wsdl \
--openapi-file ./docs/booking-api.yaml \
--openapi-format yaml \
--openapi-title "Hotel Booking API" \
--openapi-version "1.2.0" \
--openapi-description "REST API for hotel booking SOAP service" \
--openapi-security-config-file ./config/security.json \
--openapi-tags-file ./config/tags.json \
--openapi-path-style kebab \
--openapi-method post \
--openapi-tag-style serviceStandard Response Envelope
All responses are wrapped in a standard envelope for consistency and debuggability (always-on since 0.7.1):
Base Envelope Structure
{
status: string; // e.g., "SUCCESS", "FAILURE", "PENDING"
message: string | null; // diagnostic message (not for end-user UI)
data: T | null; // operation payload (typed per operation)
error: ErrorObject | null; // populated on failures
}Error Object Structure
{
code: string; // stable machine error code
message: string; // brief description
details: object | null; // arbitrary extra info
}Naming Rules
- Base envelope:
${serviceName}ResponseEnvelope(override with--openapi-envelope-namespace) - Error object:
${serviceName}ErrorObject(override with--openapi-error-namespace) - Per-operation extension:
<PayloadType|OperationName><EnvelopeNamespace>(refinesdatafield)
Collision Avoidance
If the payload type already ends with the namespace prefix, an underscore is inserted:
- Payload
WeatherResponse+ defaultResponseEnvelope→WeatherResponse_ResponseEnvelope - Payload
Booking+ defaultResponseEnvelope→BookingResponseEnvelope
Example
npx wsdl-tsc openapi \
--wsdl-source ./wsdl/Hotel.wsdl \
--openapi-file ./docs/hotel-api.json \
--openapi-envelope-namespace ApiEnvelope \
--openapi-error-namespace ApiErrorProduces components:
HotelApiEnvelope(base)<Payload>ApiEnvelopeextension schemas (alphabetically sorted)HotelApiError(error object)- Domain schemas
Tag Inference Strategies
| Strategy | Behavior |
|-----------|------------------------------------------------------------------------------------|
| default | Single tag = service name (fallback SOAP) |
| service | Always service name (even if operation prefix differs) |
| first | First lexical segment of CamelCase operation (e.g., GetCityWeatherByZIP → Get) |
Use --openapi-tags-file for explicit mapping when heuristics are insufficient.
Output Determinism
All generated OpenAPI specs have deterministic ordering:
- Path keys (alphabetically sorted)
- HTTP methods within paths (alphabetically sorted)
- Component schema names (alphabetically sorted)
- Security schemes (alphabetically sorted)
- Parameters (alphabetically sorted)
- Operation tag arrays (alphabetically sorted)
This ensures diff-friendly output for version control.
Command: gateway
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.
When to use:
- Building a REST API gateway for legacy SOAP services
- Creating a modern HTTP/JSON interface for SOAP operations
- Setting up request/response validation with JSON Schema
- Establishing Fastify routing structure with full handler implementations
What it generates:
- Fastify route registration files with complete handler implementations
- JSON Schema models with URN-based IDs
- Operation schemas (request/response validation)
- Schema and route registration modules
- Runtime utilities (envelope builders, error handlers)
- Fastify plugin wrapper for simplified integration
Usage
npx wsdl-tsc gateway \
--openapi-file <path> \
--client-dir <path> \
--gateway-dir <path> \
--gateway-service-name <slug> \
--gateway-version-prefix <slug> \
[options]Required Flags
| Flag | Description |
|----------------------------|--------------------------------------------------------------------------|
| --openapi-file | Path to OpenAPI 3.1 JSON or YAML file |
| --client-dir | Path to client directory (where client.ts is located) |
| --gateway-dir | Output directory for generated gateway code |
| --gateway-service-name | Service identifier for URN generation (e.g., weather, booking) |
| --gateway-version-prefix | Version prefix for URN generation (e.g., v1, v2, urn:1.0.2:schema) |
Optional Flags
| Flag | Default | Description |
|----------------------------------|---------------------------------------------------|-------------------------------------------------------------|
| --import-extensions | js | Import style: js, ts, or bare |
| --gateway-default-status-codes | 200,400,401,403,404,409,422,429,500,502,503,504 | Comma-separated status codes to backfill |
| --catalog-file | (none) | Path to catalog.json for operation metadata |
| --gateway-client-class-name | (auto-detected) | Override SOAP client class name |
| --gateway-decorator-name | {serviceSlug}Client | Fastify decorator name for client instance |
| --gateway-stub-handlers | false | Generate stub handlers instead of full implementations |
| --gateway-skip-plugin | false | Skip generating plugin.ts wrapper |
| --gateway-skip-runtime | false | Skip generating runtime.ts utilities |
Note: Route URLs are derived from the OpenAPI document paths, which already include any base path configured during OpenAPI generation (via
--openapi-base-path). There is no separate route prefix option for the gateway.
Generated Output Structure
{gateway-dir}/
├── schemas/
│ ├── models/ # JSON Schema components with URN IDs
│ │ ├── <schema1>.json
│ │ ├── <schema2>.json
│ │ └── ...
│ └── operations/ # Fastify operation schemas
│ ├── <operation1>.json
│ ├── <operation2>.json
│ └── ...
├── routes/ # Route registration files with full handlers
│ ├── <route1>.ts
│ ├── <route2>.ts
│ └── ...
├── schemas.ts # Schema registration module
├── routes.ts # Route aggregator module
├── runtime.ts # Envelope builders and error handler
└── plugin.ts # Fastify plugin wrapper (recommended entry point)URN-Based Schema IDs
All generated JSON Schemas use deterministic URN identifiers:
urn:services:{serviceSlug}:{versionSlug}:schemas:{models|operations}:{schemaSlug}Example: urn:services:weather:v1:schemas:models:getcityweatherbyzipresponse
Contract Assumptions
The gateway generator enforces strict OpenAPI contract validation:
- All request/response bodies must use
$reftocomponents.schemas(no inline schemas) - Every operation must have a default response with
application/jsoncontent - All schemas referenced by operations must exist in
components.schemas
Examples
Basic Gateway Generation
npx wsdl-tsc gateway \
--openapi-file ./docs/weather-api.json \
--client-dir ./src/services/weather \
--gateway-dir ./src/gateway/weather \
--gateway-service-name weather \
--gateway-version-prefix v1With Custom Status Codes
npx wsdl-tsc gateway \
--openapi-file ./docs/hotel-api.json \
--client-dir ./src/services/hotel \
--gateway-dir ./src/gateway/hotel \
--gateway-service-name hotel \
--gateway-version-prefix v2 \
--gateway-default-status-codes 200,400,401,404,500From YAML OpenAPI
npx wsdl-tsc gateway \
--openapi-file ./docs/booking-api.yaml \
--client-dir ./src/services/booking \
--gateway-dir ./src/gateway/booking \
--gateway-service-name booking \
--gateway-version-prefix v1Integration Pattern
The generated gateway provides a Fastify plugin for simplified integration.
Prerequisites
Your host application needs these dependencies:
npm install fastify fastify-pluginUsing the Generated Plugin (Recommended)
import Fastify from 'fastify';
import weatherGateway from './gateway/plugin.js';
import { Weather } from './client/client.js';
const app = Fastify({ logger: true });
// Create and configure SOAP client
const weatherClient = new Weather({
source: 'https://example.com/weather.wsdl',
// security: new soap.WSSecurity('user', 'pass'), // if needed
});
// Register gateway plugin with client
await app.register(weatherGateway, {
client: weatherClient,
// Note: Route paths are determined by --openapi-base-path during generation.
// The prefix option here adds an ADDITIONAL runtime prefix on top of generated paths.
// Only use if you need to mount routes under a different sub-path at runtime.
});
await app.listen({ port: 3000 });The plugin automatically:
- Decorates Fastify with the SOAP client (
fastify.weatherClient) - Registers all JSON schemas for validation
- Installs a centralized error handler
- Registers all routes with full handler implementations
Using Individual Components (Advanced)
For more control, you can use the individual modules:
import Fastify from 'fastify';
import { registerSchemas_v1_weather } from './gateway/schemas.js';
import { registerRoutes_v1_weather } from './gateway/routes.js';
import { createGatewayErrorHandler_v1_weather } from './gateway/runtime.js';
import { Weather } from './client/client.js';
const app = Fastify({ logger: true });
// Manual setup
const weatherClient = new Weather({ source: 'weather.wsdl' });
app.decorate('weatherClient', weatherClient);
// Register schemas
await registerSchemas_v1_weather(app);
// Install error handler
app.setErrorHandler(createGatewayErrorHandler_v1_weather());
// Register routes (paths already include --openapi-base-path if configured)
await registerRoutes_v1_weather(app);
await app.listen({ port: 3000 });Generated Handler Implementation
Route handlers are fully implemented and call the SOAP client automatically:
// Generated: routes/get-city-forecast-by-zip.ts
import type { FastifyInstance } from "fastify";
import schema from "../schemas/operations/getcityforecastbyzip.json" with { type: "json" };
import { buildSuccessEnvelope } from "../runtime.js";
export async function registerRoute_v1_weather_getcityforecastbyzip(fastify: FastifyInstance) {
fastify.route({
method: "POST",
url: "/get-city-forecast-by-zip",
schema,
handler: async (request) => {
const client = fastify.weatherClient;
const result = await client.GetCityForecastByZIP(request.body);
return buildSuccessEnvelope(result.response);
},
});
}Response Envelope
All responses are wrapped in a standard envelope format:
Success Response:
{
"status": "SUCCESS",
"message": null,
"data": { /* SOAP response data */ },
"error": null
}Error Response:
{
"status": "ERROR",
"message": "Request validation failed",
"data": null,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"details": { /* validation errors */ }
}
}Error Handling
The centralized error handler (runtime.ts) automatically classifies errors:
| Error Type | HTTP Status | Error Code |
|-----------------------|-------------|-----------------------|
| Validation errors | 400 | VALIDATION_ERROR |
| SOAP faults | 502 | SOAP_FAULT |
| Connection refused | 503 | SERVICE_UNAVAILABLE |
| Timeout | 504 | GATEWAY_TIMEOUT |
| Other errors | 500 | INTERNAL_ERROR |
Stub Handler Mode (Backward Compatible)
If you prefer to implement handler logic manually or need custom transformation logic beyond the standard SOAP-to-REST mapping, use stub mode:
npx wsdl-tsc gateway \
--openapi-file ./docs/weather-api.json \
--client-dir ./src/services/weather \
--gateway-dir ./src/gateway/weather \
--gateway-service-name weather \
--gateway-version-prefix v1 \
--gateway-stub-handlersThis generates minimal handler stubs that throw "Not implemented" errors, allowing you to implement fully custom logic while keeping the routing and validation infrastructure.
Command: app
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.
When to use:
- Local testing and development
- Quick iteration on gateway configurations
- Demonstrating the generated API
- CI smoke testing
Usage
npx wsdl-tsc app \
--client-dir <path> \
--gateway-dir <path> \
--openapi-file <path> \
[--catalog-file <path>] \
[--app-dir <path>] \
[options]Required Flags
| Flag | Description |
|------------------|----------------------------------------------------------|
| --client-dir | Path to client directory (where client.ts is located) |
| --gateway-dir | Path to gateway directory (where plugin.ts is located) |
| --openapi-file | Path to OpenAPI specification file |
Optional Flags
| Flag | Default | Description |
|-----------------------|-------------------------------|---------------------------------------------------|
| --catalog-file | {client-dir}/catalog.json | Path to catalog.json (for metadata extraction) |
| --app-dir | {gateway-dir}/../app | Output directory for generated app |
| --import-extensions | Inferred from catalog or js | Import-extension mode: js, ts, or bare |
| --host | 127.0.0.1 | Default server host |
| --port | 3000 | Default server port |
| --prefix | "" (empty) | Route prefix |
| --logger | true | Enable Fastify logger |
| --openapi-mode | copy | How to handle OpenAPI file: copy or reference |
Examples
Generate App After Pipeline
# First generate client, OpenAPI, and gateway
npx wsdl-tsc pipeline \
--wsdl-source weather.wsdl \
--client-dir ./client \
--openapi-file ./openapi.json \
--gateway-dir ./gateway \
--gateway-service-name weather \
--gateway-version-prefix v1
# Then generate runnable app
npx wsdl-tsc app \
--client-dir ./client \
--gateway-dir ./gateway \
--openapi-file ./openapi.json \
--app-dir ./appGenerate App with Custom Configuration
npx wsdl-tsc app \
--client-dir ./client \
--gateway-dir ./gateway \
--openapi-file ./openapi.json \
--app-dir ./my-app \
--host 0.0.0.0 \
--port 8080 \
--prefix /api/v1Generated App Structure
The app command generates the following files:
app/
├── server.js (or .ts) # Main application entry point
├── config.js (or .ts) # Configuration loader with env support
├── .env.example # Environment variable template
├── README.md # Usage instructions
└── openapi.json # OpenAPI spec (when --openapi-mode=copy)Running the Generated App
# Copy environment template
cd app
cp .env.example .env
# Edit .env to configure WSDL source and other settings
# vim .env
# Run the server
npx tsx server.js # For TypeScript files
# or
node server.js # For JavaScript filesConfiguration
The generated app loads configuration from environment variables with the following precedence:
- Environment variables (runtime overrides)
- Catalog defaults (from generation-time)
- Hard defaults (in config file)
Environment Variables
| Variable | Default (from catalog or flags) | Description |
|-----------------|---------------------------------|--------------------------------------|
| WSDL_SOURCE | From catalog or required | WSDL URL or local file path |
| HOST | 127.0.0.1 | Server bind address |
| PORT | 3000 | Server listen port |
| PREFIX | "" (empty) | Route prefix |
| LOGGER | true | Enable Fastify logger |
Endpoints
The generated app serves the following endpoints:
Health Check
GET /healthReturns: { "ok": true }
OpenAPI Specification
GET /openapi.jsonReturns: Complete OpenAPI 3.1 specification
Gateway Routes
All SOAP operations are exposed as REST endpoints. See the OpenAPI spec for complete API documentation.
Example Usage
# Start the server
cd app
npx tsx server.js
# Test health endpoint
curl http://localhost:3000/health
# Get OpenAPI spec
curl http://localhost:3000/openapi.json | jq .
# Call a gateway operation (example)
curl -X POST http://localhost:3000/get-weather-information \
-H "Content-Type: application/json" \
-d '{}'Integration with Pipeline
The app command can also be used via the pipeline with the --generate-app flag:
npx wsdl-tsc pipeline \
--wsdl-source weather.wsdl \
--client-dir ./client \
--openapi-file ./openapi.json \
--gateway-dir ./gateway \
--gateway-service-name weather \
--gateway-version-prefix v1 \
--generate-appThis generates all artifacts including the runnable app in a single command.
Command: compile (Advanced)
Purpose: Parse WSDL and generate only the intermediate catalog.json representation without TypeScript client code.
When to use:
- Multi-stage builds where you want to cache the parsed WSDL
- Debugging or inspecting the compiled schema structure
- Sharing a compiled catalog across multiple generation targets
Usage
npx wsdl-tsc compile --wsdl-source <file|url> --catalog-file <path> [options]Required Flags
| Flag | Description |
|---------------------|------------------------------------------|
| --wsdl-source | Path or URL to the WSDL file |
| --catalog-file | Output path for catalog.json |
Optional Flags
| Flag | Default | Description |
|------------------------------------|----------------|--------------------------------------------------------------|
| --import-extensions | js | Import specifier style: js, ts, or bare |
| --client-attributes-key | $attributes | Attribute bag key for runtime mapper |
| --client-class-name | (derived) | Override generated client class name |
| --client-int64-as | string | Map 64-bit integers: string, number, or bigint |
| --client-bigint-as | string | Map arbitrary-size integers: string or number |
| --client-decimal-as | string | Map xs:decimal: string or number |
| --client-date-as | string | Map date/time types: string or Date |
| --client-choice-mode | all-optional | Choice element strategy: all-optional or union |
| --client-fail-on-unresolved | false | Fail build on unresolved type references |
| --client-nillable-as-optional | false | Treat nillable elements as optional properties |
Examples
Basic Compilation:
npx wsdl-tsc compile \
--wsdl-source examples/minimal/weather.wsdl \
--catalog-file tmp/catalog.jsonWith Custom Mapping Options:
npx wsdl-tsc compile \
--wsdl-source https://example.com/Hotel.wsdl \
--catalog-file ./build/hotel-catalog.json \
--client-int64-as number \
--client-decimal-as stringFor Debugging:
# Compile to inspect types and operations
npx wsdl-tsc compile \
--wsdl-source ./wsdl/ComplexService.wsdl \
--catalog-file ./debug/catalog.json \
--client-fail-on-unresolved false
# Inspect types
cat ./debug/catalog.json | jq '.types'
# Inspect operations
cat ./debug/catalog.json | jq '.operations'Output
catalog.json- Compiled schema representation including types, operations, and metadata
Catalog Structure
The catalog.json file contains the compiled WSDL representation:
{
"wsdlUri": "path/to/service.wsdl",
"targetNamespace": "http://example.com/service",
"serviceName": "WeatherService",
"types": [
{
"name": "GetWeatherRequest",
"properties": []
}
],
"operations": [
{
"name": "GetWeather",
"input": "GetWeatherRequest",
"output": "GetWeatherResponse"
}
],
"options": {
"imports": "js",
"catalog": true
}
}Key sections:
types- All compiled type definitions with properties and inheritanceoperations- SOAP operations with input/output type referencesoptions- Compiler options used during generation
This catalog can be reused with the client and openapi commands via --catalog-file.
Catalog Co-location
Default behavior: Catalog files are co-located with their primary output files for better organization and discoverability.
Catalog Location by Command:
compile: Always requires explicit--catalog-file(no default)client: Defaults to{client-dir}/catalog.jsonopenapi: Defaults to{openapi-file-dir}/catalog.jsonpipeline: Intelligent cascade - first available:{client-dir}>{openapi-dir}>{gateway-dir}>tmp/
Common patterns:
Co-located with client (recommended for most projects):
npx wsdl-tsc client --wsdl-source service.wsdl --client-dir src/services/weatherCreates
src/services/weather/catalog.jsonautomatically.Shared catalog for multiple commands (custom location):
npx wsdl-tsc compile --wsdl-source service.wsdl --catalog-file build/shared-catalog.json npx wsdl-tsc client --catalog-file build/shared-catalog.json --client-dir src/client npx wsdl-tsc openapi --catalog-file build/shared-catalog.json --openapi-file docs/api.json
Working With Generated Clients
Client Construction
import soap from "soap";
import { Weather } from "./src/services/weather/client.js";
const client = new Weather({
source: "https://example.com/WeatherService?wsdl",
security: new soap.WSSecurity("username", "password")
});Calling Operations
// Operation with input
const forecast = await client.GetCityForecastByZIP({
ZIP: "10001"
});
console.log(forecast.GetCityForecastByZIPResult.Success);
console.log(forecast.GetCityForecastByZIPResult.ForecastResult);
// Operation without input
const info = await client.GetWeatherInformation({});
console.log(info.GetWeatherInformationResult.WeatherDescriptions);Attributes & Text Content
When an element has both attributes and text content, use the $value convention:
const price = {
currencyCode: "USD", // attribute
$value: "123.45" // text content
};Working With Arrays
Repeated elements are automatically typed as arrays:
interface ForecastReturn {
Forecast: Forecast[]; // maxOccurs > 1
}Type Safety
All operations and types are fully typed:
// TypeScript knows the exact shape
const result: GetCityWeatherByZIPResponse = await client.GetCityWeatherByZIP({
ZIP: "10001"
});
// Autocomplete and type checking work
result.GetCityWeatherByZIPResult.Temperature; // number | string (depends on mapping)Configuration Files
Security Configuration (security.json)
Define security schemes, headers, and per-operation overrides:
{
"global": {
"scheme": "bearer",
"bearer": { "bearerFormat": "JWT" },
"headers": [
{
"name": "X-Correlation-Id",
"required": false,
"schema": { "type": "string" }
}
]
},
"overrides": {
"CancelBooking": { "scheme": "apiKey" }
}
}Supported schemes: none, basic, bearer, apiKey, oauth2
Tags Configuration (tags.json)
Explicit operation → tag mapping:
{
"GetCityWeatherByZIP": ["Weather", "Forecast"],
"GetWeatherInformation": ["Weather", "Info"],
"CancelBooking": ["Booking", "Cancellation"]
}Operations Configuration (ops.json)
Per-operation overrides for method, summary, description, and deprecation:
{
"GetCityWeatherByZIP": {
"method": "get",
"summary": "Get weather forecast by ZIP code",
"description": "Returns a detailed weather forecast for the specified US ZIP code",
"deprecated": false
},
"LegacyOperation": {
"deprecated": true
}
}Production Concerns
Deterministic Output Guarantees
All generated code and specifications have stable, deterministic ordering for version control:
- ✅ TypeScript files: Sorted type declarations, imports, and exports
- ✅ OpenAPI specs: Sorted paths, HTTP methods, schemas, parameters, security schemes, tags
- ✅ JSON Schemas: Sorted property keys and component names
- ✅ Gateway routes: Alphabetically organized route files
- ✅ Catalog JSON: Consistent ordering of types and operations
Benefit: Safe regeneration in CI/CD without spurious diffs.
Validation Behavior
OpenAPI Validation (enabled by default):
- Uses
@apidevtools/swagger-parser - Validates schema structure
- Resolves all
$refreferences - Catches missing schemas and circular dependencies
- Disable with
--openapi-validate false
Gateway Contract Validation:
- All request/response bodies must use
$reftocomponents.schemas - Every operation must have a default response with
application/jsoncontent - All referenced schemas must exist in
components.schemas
Error Handling
Gateway Error Classification:
| Error Type | HTTP Status | Error Code | When It Occurs |
|-----------------------|-------------|-----------------------|---------------------------------------|
| Validation errors | 400 | VALIDATION_ERROR | Request doesn't match JSON Schema |
| SOAP faults | 502 | SOAP_FAULT | SOAP service returned a fault |
| Connection refused | 503 | SERVICE_UNAVAILABLE | Cannot reach SOAP endpoint |
| Timeout | 504 | GATEWAY_TIMEOUT | SOAP request exceeded timeout |
| Other errors | 500 | INTERNAL_ERROR | Unexpected errors |
All errors are wrapped in the standard envelope format with error object populated.
SOAP Wire Logging
Enable SOAP request/response debugging:
NODE_DEBUG=soap node app.jsThis logs full XML request/response payloads to console.
CI/CD Tips
Caching Strategy:
# Step 1: Compile catalog (cacheable artifact)
npx wsdl-tsc compile \
--wsdl-source ./wsdl/Service.wsdl \
--catalog-file ./build/catalog.json
# Step 2: Generate code from cached catalog
npx wsdl-tsc client --catalog-file ./build/catalog.json --client-dir ./src/client
npx wsdl-tsc openapi --catalog-file ./build/catalog.json --openapi-file ./docs/api.jsonRecommended Build Script (package.json):
{
"scripts": {
"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",
"build": "npm run generate && tsc",
"typecheck": "tsc --noEmit"
}
}Known Limitations
Choice Elements:
- Current strategy:
all-optional(all branches optional) - Future: Discriminated union support (planned)
Union Types:
- Experimental
--client-choice-mode unionavailable - May require manual refinement for complex patterns
WS-Policy:
- Security hints extracted from policies
- Custom policies may require manual security configuration
Array Wrapper Flattening:
- Single-child sequences with
maxOccurs>1become array schemas - Sequences with multiple children preserve wrapper
Programmatic API
All CLI commands are available as TypeScript functions for programmatic usage.
compileWsdlToProject
Generate TypeScript SOAP client from WSDL.
import { compileWsdlToProject } from "@techspokes/typescript-wsdl-client";
await compileWsdlToProject({
wsdl: "./wsdl/Hotel.wsdl",
outDir: "./src/services/hotel",
options: {
imports: "js",
catalog: true,
primitive: {
int64As: "number",
bigIntegerAs: "string",
decimalAs: "string",
dateAs: "string"
},
choice: "all-optional",
clientName: "HotelClient",
nillableAsOptional: false
}
});Type Signature:
// noinspection JSAnnotator
function compileWsdlToProject(input: {
wsdl: string;
outDir: string;
options?: Partial<CompilerOptions>;
}): Promise<void>;Options (CompilerOptions):
interface CompilerOptions {
wsdl: string;
out: string;
imports: "js" | "ts" | "bare";
catalog: boolean;
primitive: PrimitiveOptions;
choice?: "all-optional" | "union";
failOnUnresolved?: boolean;
attributesKey?: string;
clientName?: string;
nillableAsOptional?: boolean;
}
interface PrimitiveOptions {
int64As?: "string" | "number" | "bigint";
bigIntegerAs?: "string" | "number";
decimalAs?: "string" | "number";
dateAs?: "string" | "Date";
}generateOpenAPI
Generate OpenAPI 3.1 specification from WSDL or catalog.
import { generateOpenAPI } from "@techspokes/typescript-wsdl-client";
const { doc, jsonPath, yamlPath } = await generateOpenAPI({
wsdl: "./wsdl/Hotel.wsdl",
outFile: "./docs/hotel-api",
format: "both",
title: "Hotel Booking API",
version: "1.0.0",
servers: ["https://api.example.com/v1"],
basePath: "/booking",
pathStyle: "kebab",
tagStyle: "service",
validate: true
});Type Signature:
// noinspection JSAnnotator
function generateOpenAPI(opts: GenerateOpenAPIOptions): Promise<{
doc: any;
jsonPath?: string;
yamlPath?: string;
}>;Options (GenerateOpenAPIOptions):
interface GenerateOpenAPIOptions {
// Input sources (mutually exclusive)
wsdl?: string;
catalogFile?: string;
compiledCatalog?: CompiledCatalog;
// Output
outFile?: string;
format?: "json" | "yaml" | "both";
// Metadata
title?: string;
version?: string;
description?: string;
servers?: string[];
// Path configuration
basePath?: string;
pathStyle?: "kebab" | "asis" | "lower";
defaultMethod?: string;
// Schema configuration
closedSchemas?: boolean;
pruneUnusedSchemas?: boolean;
// Tag configuration
tagStyle?: "default" | "first" | "service";
tagsFile?: string;
// Security & operations
securityConfigFile?: string;
opsFile?: string;
// Envelope customization
envelopeNamespace?: string;
errorNamespace?: string;
// Validation
validate?: boolean;
skipValidate?: boolean;
// Deprecated
asYaml?: boolean;
}generateGateway
Generate Fastify gateway code from OpenAPI specification.
import { generateGateway } from "@techspokes/typescript-wsdl-client";
await generateGateway({
openapiFile: "./docs/hotel-api.json",
outDir: "./src/gateway/hotel",
clientDir: "./src/services/hotel",
versionSlug: "v1",
serviceSlug: "hotel",
defaultResponseStatusCodes: [200, 400, 401, 403, 404, 409, 422, 429, 500, 502, 503, 504],
imports: "js"
});Type Signature:
// noinspection JSAnnotator
function generateGateway(opts: GenerateGatewayOptions): Promise<void>;Options (GenerateGatewayOptions):
interface GenerateGatewayOptions {
// Input sources (mutually exclusive)
openapiFile?: string;
openapiDocument?: any;
// Output
outDir: string;
// Client integration
clientDir?: string;
// URN configuration
versionSlug?: string;
serviceSlug?: string;
// Schema configuration
defaultResponseStatusCodes?: number[];
// Import style
imports?: "js" | "ts" | "bare";
}runGenerationPipeline
Run complete pipeline: client + OpenAPI + gateway in one pass.
import { runGenerationPipeline } from "@techspokes/typescript-wsdl-client";
const { compiled, openapiDoc } = await runGenerationPipeline({
wsdl: "./wsdl/Hotel.wsdl",
catalogOut: "./build/hotel-catalog.json",
clientOutDir: "./src/services/hotel",
compiler: {
imports: "js",
primitive: {
int64As: "number",
decimalAs: "string"
}
},
openapi: {
outFile: "./docs/hotel-api.json",
format: "both",
servers: ["https://api.example.com/v1"],
tagStyle: "service"
},
gateway: {
outDir: "./src/gateway/hotel",
versionSlug: "v1",
serviceSlug: "hotel"
}
});Type Signature:
// noinspection JSAnnotator
function runGenerationPipeline(opts: PipelineOptions): Promise<{
compiled: CompiledCatalog;
openapiDoc?: any;
}>;Options (PipelineOptions):
interface PipelineOptions {
// Input
wsdl: string;
// Catalog (always generated)
catalogOut: string;
// Client generation (optional)
clientOutDir?: string;
compiler?: Partial<CompilerOptions>;
// OpenAPI generation (optional)
openapi?: Omit<GenerateOpenAPIOptions, "wsdl" | "catalogFile" | "compiledCatalog"> & 